@w6w/ui 0.2.54 → 0.2.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-app-meta-ZCPakGjD.js","sources":["../src/app-categories.ts","../src/flow-types.ts","../src/app-pages.ts","../src/theme.ts","../src/components/AppIcon.tsx","../src/provider.tsx","../src/AppPicker.tsx","../src/Markdown.tsx","../src/note-markdown.ts","../src/CanvasLayer.tsx","../src/editor-theme.ts","../src/script-completions.ts","../src/CodeEditor.tsx","../src/JsonEditor.tsx","../src/components/Combobox.tsx","../src/types.ts","../src/components/expression-template.ts","../src/resolve-params.ts","../src/resolved-json.ts","../src/components/IconButton.tsx","../src/components/Modal.tsx","../src/components/expression-authoring.ts","../src/components/expression-dom.ts","../src/components/json-compose.ts","../src/components/ExpressionEditorModal.tsx","../src/components/ExpressionOptions.tsx","../src/components/ExpressionInput.tsx","../src/script-bindings.ts","../src/components/ScriptCodeField.tsx","../src/dynamic-fields.ts","../src/use-dynamic-fields.ts","../src/ParamsForm.tsx","../src/condition-editor.ts","../src/ConditionEditor.tsx","../src/RetryPolicyFields.tsx","../src/NodeConfigForm.tsx","../src/param-customization.ts","../src/ParamCustomization.tsx","../src/components/AuthFieldsForm.tsx","../src/components/CredentialPicker.tsx","../src/oauth-popup.ts","../src/use-enter-submit.ts","../src/AddConnectionModal.tsx","../src/components/DeleteButton.tsx","../src/RouterEditor.tsx","../src/StepNameEditor.tsx","../src/StopEditor.tsx","../src/components/HtmlPreview.tsx","../src/components/JsonTree.tsx","../src/components/result-format.ts","../src/components/ResultViewer.tsx","../src/WebhookListenPanel.tsx","../src/trigger-fields.ts","../src/test-inputs.ts","../src/use-test-input.tsx","../src/TriggerFillForm.tsx","../src/WaitEditor.tsx","../src/components/AnchoredFlyout.tsx","../src/step-problems.ts","../src/workflow-connections.ts","../src/WorkflowConnections.tsx","../src/components/ApiCallsPanel.tsx","../src/components/EventbriteTriggerPicker.tsx","../src/components/InternalIcon.tsx","../src/eventbrite-trigger-selection.ts","../src/flow-loop.ts","../src/flow-connect.ts","../src/flow-utils.ts","../src/output-shape.ts","../src/step-preview-state.ts","../src/use-seed-sources.ts","../src/StepBuilderModal.tsx","../src/PropertyEntryForm.tsx","../src/components/ConfirmModal.tsx","../src/node-samples.ts","../src/connection-app-meta.ts"],"sourcesContent":["/**\n * Pure category-derivation + label logic for `AppPicker`'s opt-in category\n * filter (T1.1.1). No React import — usable from a plain unit test and from\n * the real-browser `test/picker-layout` gate's bundle alike.\n *\n * Two things are MIRRORED, not imported (`ui` sits upstream of both `studio`\n * and `frontend` in the package dependency graph, so neither is reachable):\n *\n * - filter LOGIC — `packages/studio/src/pages/AppsPage.tsx:110-197`:\n * `selectedCats: string[]`, empty array means \"all\", OR-across-selected\n * membership (an app matches if it carries ANY selected slug).\n * - label ALGORITHM — `packages/frontend/packages/web/src/lib/categories.ts:65-74`:\n * split on `[-_\\s]+`, capitalize each word, join with spaces.\n *\n * D-4 (project DECISIONS.md): no 31-slug transcription of `rfcs/categories.md`.\n * Only the handful of acronyms/irregulars the mechanical algorithm gets wrong\n * carry an explicit override; every other slug — including one the RFC's own\n * vocabulary doesn't list, e.g. the live `sales` value — falls through to the\n * algorithm and renders as a readable (if unofficial) label, never a throw.\n */\nimport type { AppSummary } from \"./types.ts\";\n\n/**\n * Slugs where hyphen/underscore-split + per-word title-case produces the\n * wrong reading (an acronym, or a mid-word capital). Exactly the five the\n * live catalog needs (`building-blocks.md` §3) — not a transcription of the\n * RFC's full label table.\n */\nconst LABEL_OVERRIDES: Readonly<Record<string, string>> = {\n ai: \"AI\",\n cms: \"CMS\",\n crm: \"CRM\",\n hr: \"HR\",\n devops: \"DevOps\",\n};\n\n/**\n * Display label for a category slug. A known override wins; otherwise the\n * slug is split on `-`/`_`/whitespace and each word is capitalized. Never\n * throws — an empty/non-string slug renders as `\"\"`, and any out-of-\n * vocabulary slug still gets a readable (title-cased) label.\n *\n * @example\n * categoryLabel(\"crm\"); // \"CRM\" (override)\n * categoryLabel(\"project-management\"); // \"Project Management\"\n * categoryLabel(\"sales\"); // \"Sales\" (out-of-vocabulary, still safe)\n */\nexport function categoryLabel(slug: string): string {\n if (typeof slug !== \"string\" || slug.trim() === \"\") return \"\";\n const known = LABEL_OVERRIDES[slug];\n if (known) return known;\n return slug\n .split(/[-_\\s]+/)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n}\n\n/** One category chip's derived data — a slug, its display label, and how\n * many of the supplied apps carry it. */\nexport interface CategoryChip {\n slug: string;\n label: string;\n count: number;\n}\n\n/**\n * Distinct category slugs present across `apps`, each with its app count.\n * Ordered by count DESCENDING; ties break on the derived LABEL, ascending\n * (a deterministic order — never insertion/slug order, which would vary with\n * the catalog's own listing order).\n *\n * Derive from the caller's already-visible catalog (post any `filter` prop),\n * never from the full RFC vocabulary — a category with nothing behind it in\n * the current list is a dead end (D-1a).\n */\nexport function deriveCategories(apps: readonly AppSummary[]): CategoryChip[] {\n const counts = new Map<string, number>();\n for (const app of apps) {\n for (const slug of app.categories ?? []) {\n counts.set(slug, (counts.get(slug) ?? 0) + 1);\n }\n }\n return [...counts.entries()]\n .map(([slug, count]) => ({ slug, label: categoryLabel(slug), count }))\n .sort(\n (a, b) =>\n b.count - a.count || a.label.localeCompare(b.label, undefined, { sensitivity: \"base\" }),\n );\n}\n\n/**\n * Whether `app` matches a set of selected category slugs. An EMPTY selection\n * means \"all\" (every app matches); a non-empty selection is OR-across-\n * selected — the app matches if it carries ANY of the selected slugs. Mirrors\n * `AppsPage.tsx`'s `cats.size === 0 ? … : appCats.some((c) => cats.has(c))`.\n */\nexport function matchesCategories(app: AppSummary, selected: readonly string[]): boolean {\n if (selected.length === 0) return true;\n const cats = app.categories ?? [];\n return selected.some((slug) => cats.includes(slug));\n}\n","/**\n * Minimal Workflow shape the flow editor operates on. Deliberately a subset of\n * `@w6w/workflow-types` so the ui lib doesn't pin partners to a specific engine\n * package version — consumers who already have `Workflow` from\n * `@w6w/workflow-types` are structurally compatible.\n */\n\nimport type { StateWriteConfig } from \"@w6w/expr\";\nimport type { FlowCanvas } from \"./canvas-types.ts\";\n// T1.1.1 — `edgeVisuals`'s run-state argument; see `run-visuals.ts`.\nimport type { EdgeRunState } from \"./run-visuals.ts\";\n\nexport interface FlowStep {\n id: string;\n uses: {\n app: string;\n action: string;\n connection?: string | null;\n connectionRef?: string;\n /** An app TRIGGER node (`action` is the trigger key): behaves like a built-in trigger on the canvas. */\n trigger?: true;\n };\n /**\n * Declared connection-port cardinality for this step (see core\n * `rfcs/node-types.md` · Ports & cardinality). Omitted fields fall through field-wise to the catalog action, the internal def, then `{ in: 1, out: \"many\" }`.\n * A persisted value wins over the node's default. Only `in: 0` binds (no entry\n * port); any `in >= 1` accepts any number of inbound edges (core node-types ·\n * Alternate entries).\n */\n ports?: PortsDecl;\n with?: Record<string, unknown>;\n retry?: {\n maxAttempts: number;\n backoff?: \"fixed\" | \"exponential\";\n delayMs?: number;\n };\n /**\n * What to do when this step errors:\n * - `fail` — stop the run (default)\n * - `continue` — swallow the error and keep going\n * - `continue-record` — keep going, but record the error into the run's end state\n */\n onError?: \"fail\" | \"continue\" | \"continue-record\";\n /** Free-form author notes for this step. Not executed. */\n notes?: string;\n /**\n * How this step's outgoing edges in one lane run when there are two or more:\n * `parallel` runs them concurrently; omitted (never written as `\"sequential\"`)\n * runs them one after another.\n */\n fanOut?: \"sequential\" | \"parallel\";\n /** Write to state (`Node.state`, core/rfcs/workflow.md). Absent = the default: Off, or Merge at root for `@w6w/data` set. */\n state?: StateWriteConfig;\n /**\n * Authoring-time canvas coordinate for this step, in this editor's own\n * coordinate space (core `rfcs/workflow.md` · \"Amendment — 2026-07-29:\n * authoring presentation (`Step.position`, `Workflow.settings`)\" — the spec\n * pins no unit, origin or grid). Declarative only: the engine ignores it\n * exactly as it ignores `notes`.\n *\n * **Omitted ⇒ the editor computes a layout** from the graph alone, exactly as\n * before this field existed, so it is additive and backward-compatible.\n * Partial coverage is valid: `workflowToFlow` places the steps that declare a\n * `position` and computes a slot for the rest.\n *\n * Rename-safe by construction — the coordinate travels *with* the step, so\n * there is no workflow-level `id → {x,y}` map to fix up on rename (D-I0-2).\n *\n * Mirrors `Step.position` in `@w6w/workflow-types` by hand — see the header\n * note: these types are deliberately a structural subset with no compiler\n * tie, so the spelling here must stay identical to the engine's.\n */\n position?: { x: number; y: number };\n /**\n * Disabled: skipped in EVERY run, published and triggered included — the node does not\n * execute and its outgoing edges are skipped, so a node that depends only on it does not run\n * either. An engine semantic (mirrors `Node.disabled` in `@w6w/workflow-types`). Written as\n * `true` or absent, never `false`.\n */\n disabled?: true;\n /**\n * Editor-only metadata; the engine ignores it. `paused`: a test run started from a node's ▶\n * stops BEFORE this node (it does not execute). Never affects a published or triggered run.\n * Absent when empty, never `{}`.\n */\n ui?: { paused?: true };\n}\n\nexport interface FlowEdge {\n from: string;\n to: string;\n route?: string;\n /**\n * Which outcome of the `from` step this edge carries (core\n * `rfcs/workflow.md` · \"Amendment — 2026-07-29: failure-conditioned edges\n * (`Edge.when`)\"). **Omitted ⇒ `\"success\"`**, so every pre-existing edge is a\n * success edge and needs no migration.\n * - `\"success\"` — activates when `from` succeeds. Per the house\n * omit-the-default idiom it is written as **absent**, never spelled out:\n * this editor emits no `when` for a success edge, which is what keeps an\n * untouched definition byte-identical across a load/save cycle.\n * - `\"error\"` — activates when `from` fails, and overrides that step's\n * `onError`.\n *\n * Mirrors `Edge.when` in `@w6w/workflow-types` by hand — see the header note:\n * these types are deliberately a structural subset, with no compiler tie, so\n * the spelling here must stay identical to the engine's.\n */\n when?: \"success\" | \"error\";\n}\n\n/**\n * The React Flow presentation for an edge lane — **the one place** the error\n * look is spelled out.\n *\n * Three callers need it and they run at different times: `workflowToFlow` stamps\n * a *stored* edge on load, `setEdgeWhen` (`flow-connect.ts`) stamps an edge the\n * author re-lanes **live**, before any save, and a live-run repaint effect\n * (`WorkflowFlowEditor.tsx`, T1.1.1) restyles an edge as a run polls in. Spelled\n * out more than once, the copies drift and a freshly marked error edge stops\n * looking like a reloaded one. The className is what `styles.css`'s\n * `.w6w-edge-error`/`.w6w-edge-taken`/`.w6w-edge-skipped` blocks paint from\n * `--w6w-danger`/`--w6w-success`/`--w6w-muted`; no custom edge component is\n * involved (D-T1-7).\n *\n * `runState` (T1.1.1) is the edge's OWN taken/skipped verdict (see\n * `run-visuals.ts`'s `edgeRunState`) — omitted (or `undefined`) when there is no\n * run in progress, or the run hasn't decided this edge's fate yet, in which case\n * this returns exactly what it always has. `workflowToFlow`'s and `setEdgeWhen`'s\n * call sites deliberately never have a live run's state available (a *stored*\n * load and a live *re-lane* are never mid-run), so both pass no `runState` at\n * all — only the new repaint-effect call site does.\n *\n * A `\"success\"`/absent lane with no `runState` returns an **empty object** — not\n * `{ className: \"\" }` — so an untouched success edge carries neither key and a\n * definition round-trips unchanged. That makes it a trap for a *re-laning*\n * caller: spreading `{}` over an edge that already carries the error class\n * leaves the class in place, so `setEdgeWhen` assigns both keys explicitly\n * rather than spreading.\n */\nexport function edgeVisuals(\n when: CanvasLane | undefined,\n runState?: EdgeRunState,\n): {\n className?: string;\n label?: string;\n} {\n const lane: { className?: string; label?: string } =\n when === \"error\"\n ? { className: \"w6w-edge-error\", label: \"on error\" }\n : when === \"each\"\n ? { className: \"w6w-edge-each\" }\n : {};\n if (!runState) return lane;\n const runClass = runState === \"taken\" ? \"w6w-edge-taken\" : \"w6w-edge-skipped\";\n return {\n className: lane.className ? `${lane.className} ${runClass}` : runClass,\n ...(lane.label ? { label: lane.label } : {}),\n };\n}\n\n/**\n * The React Flow handle id a step/control node's **error exit port** carries\n * (T1.1.1). Internal to `@w6w/ui` — not re-exported from `flow.ts` / `index.ts`\n * (D-P2), since no consumer outside this package needs it.\n */\nexport const ERROR_SOURCE_HANDLE = \"out-error\";\n\n/**\n * The handle id of a For each's **Each item** exit port. The `each` lane derives\n * `with.body` on save; its link to the first body step is also saved as a\n * {@link FOREACH_EACH_ROUTE} edge so a reader sees which port it leaves.\n */\nexport const EACH_SOURCE_HANDLE = \"out-each\";\n\n/**\n * `Edge.route` of a For each's **Done** port (the engine's `FOREACH_DONE_ROUTE`): the\n * success edge that runs once, after every iteration. An unrouted For each success\n * edge — the shape saved before the port had an id — is read as Done.\n */\nexport const FOREACH_DONE_ROUTE = \"done\";\n\n/** `Edge.route` of a For each's Each item link to `with.body[0]` (engine `FOREACH_EACH_ROUTE`). */\nexport const FOREACH_EACH_ROUTE = \"each\";\n\n/**\n * A lane on the CANVAS. `\"each\"` is canvas-only (a For each → body-step edge);\n * the persisted {@link FlowEdge}`[\"when\"]` deliberately stays `\"success\" | \"error\"`.\n */\nexport type CanvasLane = \"success\" | \"error\" | \"each\";\n\n/**\n * The `sourceHandle` a minted/re-laned/loaded edge carries for a given lane —\n * the inverse of {@link laneForSourceHandle}. `undefined` for `\"success\"`/\n * absent is **load-bearing, not stylistic**: React Flow anchors a handle-less\n * edge to the node's sole *unnamed* handle, which is the exit every\n * already-saved workflow's edges implicitly use. An empty string would not do\n * this — an empty string is a real, if degenerate, handle id.\n */\nexport function sourceHandleForLane(when: CanvasLane | undefined): string | undefined {\n return when === \"error\" ? ERROR_SOURCE_HANDLE : when === \"each\" ? EACH_SOURCE_HANDLE : undefined;\n}\n\n/**\n * The lane a drag started from, read off the handle id React Flow reports.\n * **The one canonicalisation point** every minting/re-laning site calls\n * (`onConnect`, `onConnectEnd`) so the handle-id spelling is decided once and\n * both drag gestures provably agree — two inline comparisons is the shape\n * where one gesture silently drifts. Exactly {@link ERROR_SOURCE_HANDLE} is\n * `\"error\"`; everything else — a near-miss id, `null`, `undefined` — is\n * `\"success\"`.\n */\nexport function laneForSourceHandle(handleId: string | null | undefined): CanvasLane {\n return handleId === ERROR_SOURCE_HANDLE\n ? \"error\"\n : handleId === EACH_SOURCE_HANDLE\n ? \"each\"\n : \"success\";\n}\n\nexport interface FlowWorkflow {\n manifestVersion: string;\n id: string;\n name: string;\n displayName?: string;\n description?: string;\n variables?: Array<{ key: string; type?: string; required?: boolean; default?: unknown }>;\n /** Starting data (`Workflow.initialState`): a literal JSON object that seeds the run's state tree. */\n initialState?: Record<string, unknown>;\n nodes: FlowStep[];\n connections?: Record<string, { app: string; connection: string | null }>;\n edges?: FlowEdge[];\n canvas?: FlowCanvas;\n /**\n * Authoring-time presentation and preferences for this workflow (core\n * `rfcs/workflow.md` · \"Amendment — 2026-07-29: authoring presentation\n * (`Step.position`, `Workflow.settings`)\"). Declarative only — the engine\n * ignores it, exactly like `FlowStep.notes` and `FlowStep.position`.\n * `viewport` sits *inside* `settings` deliberately, so exactly one new\n * top-level key enters the portable workflow document. `settings` is itself\n * optional; when the object is absent every member below still takes its own\n * default.\n *\n * ⚠️ **`autoSave` and `savePosition` default to `true` when omitted.** That is\n * *deliberately unlike* the `ports`/`onError` rule (\"omitted reproduces the\n * status quo\") — here it does not. Read them as `?? true` / `!== false`, never\n * `?? false` and never `=== true`. The consequence, stated plainly: **a\n * workflow that has never been saved by the new editor starts persisting step\n * coordinates the first time it is saved.** That is intended (the product\n * requires both features on by default); only an explicit `false` turns one\n * off.\n *\n * HITL-6 asked whether a workflow's arrangement and its auto-save preference\n * belong to *the workflow* or to *the person looking at it*; the amendment\n * takes the **workflow** answer, so everyone who opens a workflow sees the\n * same arrangement. HITL-6 is still open — a viewer-owned answer would move\n * these fields out of the document and re-contract this shape.\n *\n * Mirrors `Workflow.settings` in `@w6w/workflow-types` by hand (structural\n * subset, no compiler tie — the spelling must stay identical).\n */\n settings?: {\n /**\n * Whether an authoring tool persists edits without an explicit save action.\n * Omitted ⇒ **true** — auto-save is ON. Not read by this module; the editor\n * and its host own it (T3.3.2 / T4.1.x).\n */\n autoSave?: boolean;\n /**\n * Whether an authoring tool persists step coordinates (`FlowStep.position`)\n * and `settings.viewport` when it saves. Omitted ⇒ **true** — positions ARE\n * persisted. When explicitly `false`, `flowToWorkflow` writes no `position`;\n * any value already stored is **left as it is, never erased**.\n */\n savePosition?: boolean;\n /**\n * The camera position the author last left the canvas at, so reopening the\n * workflow restores the view. **No default** — a workflow with no `viewport`\n * opens at whatever view the editor computes, exactly as today. Written by\n * the component (T3.3.2), not by `flowToWorkflow`, whose signature cannot\n * see a viewport.\n */\n viewport?: { x: number; y: number; zoom: number };\n };\n}\n\n/**\n * What `workflowToFlow` accepts: a definition in either shape — the canonical\n * `nodes[]` or the legacy `steps[]`. Both present is refused at read time.\n */\nexport type FlowWorkflowInput = Omit<FlowWorkflow, \"nodes\"> &\n ({ nodes: FlowStep[] } | { steps: FlowStep[] });\n\nimport type { ActionParam } from \"./types.ts\";\n\n// ── Internal pseudo-app nodes (see core rfcs/node-types.md) ─────────────────\n//\n// A node's kind + processor are derived from `uses.app`. The reserved `@w6w/*`\n// namespace holds internal pseudo-apps the platform runs itself: `@w6w/control`\n// (engine-native flow control), `@w6w/script`/`@w6w/data` (host-run compute),\n// and `@w6w/trigger` (the entry node). They render as rounded-rect cards\n// (`ControlNodeCard`); a trigger renders as a half-pill (`.w6w-node-trigger`).\n// All configure through the same dynamic form as apps.\n\n/** Reserved namespace for internal pseudo-apps. */\nexport const INTERNAL_APP_PREFIX = \"@w6w/\";\n/** Engine-native flow control (if/foreach/parallel/wait). */\nexport const CONTROL_APP = \"@w6w/control\";\n/** Host-run inline JS. */\nexport const SCRIPT_APP = \"@w6w/script\";\n/** Host-run typed key/value data. */\nexport const DATA_APP = \"@w6w/data\";\n/** The workflow's entry/trigger node. */\nexport const TRIGGER_APP = \"@w6w/trigger\";\n/** Host-run outbound HTTP(S) request. */\nexport const HTTP_APP = \"@w6w/http\";\n/** Inbound HTTP(S) webhook trigger (entry node; provisions a receive URL). */\nexport const WEBHOOK_APP = \"@w6w/webhook\";\n/** Time-based scheduler trigger (entry node; fires the workflow on a schedule). */\nexport const SCHEDULER_APP = \"@w6w/scheduler\";\n/** \"Respond to Webhook\" — shapes the HTTP response for `responseMode: responseNode`. */\nexport const RESPOND_APP = \"@w6w/respond\";\n/**\n * Sub-workflow / Function caller (core rfcs/node-types.md · F-3). The host runs\n * this node itself: it resolves `with.target` to a project-scoped `CallableRef` (a\n * Function or a Workflow) and invokes it through `ctx.invokeCallable`, honoring\n * the per-node `with.wait` flag. The engine never loads the target.\n */\nexport const CALL_APP = \"@w6w/call\";\n/**\n * Read a stored JSON document by key (core rfcs/node-types.md · F-3 amendment,\n * \"Reserved internal pseudo-app\"). Host node: `runInternalNode` short-circuits\n * this id before the registry loads a module — the run's own project is bound\n * host-side, so there is no `project` param (C-6).\n */\nexport const DOCUMENT_APP = \"@w6w/document\";\n/**\n * Call a model through a named route / read a connection's models and\n * allowance. Host node, like {@link DOCUMENT_APP}; the params mirror the\n * `@w6w/model` internal-app manifest (pinned by `model-node-parity.test.ts`).\n */\nexport const MODEL_APP = \"@w6w/model\";\n/**\n * Render Handlebars text or JSON string values against a resolved `values` object\n * (core rfcs/node-types.md · F-3 amendment, \"the `@w6w/template` host node\").\n * Host node: `runInternalNode` short-circuits this id before the registry\n * loads a module — it needs no privileged host resource (no DB, no\n * tenant/project scope), and runs host-side only because the template\n * compiles to a JS function, the same risk shape `@w6w/script` has.\n */\nexport const TEMPLATE_APP = \"@w6w/template\";\n/** Host-run regular-expression operations. */\nexport const REGEX_APP = \"@w6w/regex\";\n/**\n * Read, write, count, list and query the entries of a named data store (core\n * rfcs/node-types.md, the `@w6w/store` amendment). Host node, like\n * {@link DOCUMENT_APP}: the run's own account and project are bound host-side, so\n * there is no scope param — a store is addressed by NAME. The params mirror the\n * `@w6w/store` internal-app manifest (pinned by `store-node-parity.test.ts`).\n */\nexport const STORE_APP = \"@w6w/store\";\n/** End the whole workflow successfully when its optional condition matches. */\nexport const STOP_APP = \"@w6w/stop\";\nexport const ROUTER_APP = \"@w6w/router\";\nexport const RACE_APP = \"@w6w/race\";\nexport const RACE_DESCRIPTION =\n \"Continue once with the first arriving path’s output. Later arrivals are ignored for this run. Other paths keep running.\";\n\nexport interface RouterRoute {\n id: string;\n label?: string;\n condition?: unknown;\n default?: boolean;\n}\n\nexport function routesForStep(step: FlowStep): RouterRoute[] {\n if (step.uses.app !== ROUTER_APP || !Array.isArray(step.with?.routes)) return [];\n return step.with.routes.filter(\n (r): r is RouterRoute => !!r && typeof r === \"object\" && typeof r.id === \"string\",\n );\n}\n\nexport const routeHandle = (id: string): string => `route:${id}`;\nexport const routeFromHandle = (handle: string | null | undefined): string | undefined =>\n handle?.startsWith(\"route:\") ? handle.slice(6) : undefined;\n\n/** Route ports the Router card's right edge holds at its natural height. */\nexport const ROUTER_PORTS_AT_BASE_HEIGHT = 3;\n/** Card height (px, border-box) added per route port past the third. */\nexport const ROUTER_PORT_STEP = 16;\n\nexport interface RouterPort {\n id: string;\n /** Absent for an If's True port: the unnamed handle a route-less edge anchors to. */\n handleId?: string;\n label: string;\n /** Handle position along its edge, as a CSS `top` (right-edge ports only). */\n top?: string;\n}\n\n/**\n * Where a Router's ports sit (human report, 2026-10-31: \"they need to be\n * attached to the router\"). Condition routes go on the card's right edge,\n * evenly spaced; the fallback route takes the bottom edge, the slot every\n * other node gives its error port. Up to three right-edge ports fit the\n * card's natural height; each one past that adds a fixed step, so five\n * routes make a slightly taller card. Handle ids stay `route:<id>`, so\n * saved edges keep resolving.\n */\nexport interface PortLayout {\n right: RouterPort[];\n bottom?: RouterPort;\n minHeight?: number;\n}\n\nexport function routerPortLayout(routes: RouterRoute[]): PortLayout {\n const fallback = routes.find((r) => r.default);\n const port = (r: RouterRoute): RouterPort => ({\n id: r.id,\n handleId: routeHandle(r.id),\n label: r.default ? \"Fallback\" : r.label || r.id,\n });\n const side = routes.filter((r) => r !== fallback);\n return {\n right: side.map((r, i) => ({ ...port(r), top: `${((i + 0.5) / side.length) * 100}%` })),\n ...(fallback ? { bottom: port(fallback) } : {}),\n ...(side.length > ROUTER_PORTS_AT_BASE_HEIGHT\n ? { minHeight: side.length * ROUTER_PORT_STEP }\n : {}),\n };\n}\n\n/**\n * `Edge.route` of an If's false branch (the engine's `IF_FALSE_ROUTE`). The true\n * branch is an edge with no route, which is what every If edge saved before the\n * False port existed already is.\n */\nexport const IF_FALSE_ROUTE = \"false\";\n\nexport function isIfStep(step: FlowStep): boolean {\n return step.uses.app === CONTROL_APP && step.uses.action === \"if\";\n}\n\n/**\n * An If's ports, laid out the way {@link routerPortLayout} lays out a Router's\n * (human report, 2026-10-31: \"should not have error, it should have: true port\n * and false port\"). True takes the right edge; False takes the bottom edge, the\n * slot every other node gives its error port, so an If has no error port. True\n * keeps the unnamed handle, so saved If edges stay on it; False is `route:false`.\n */\nexport function ifPortLayout(): PortLayout & { bottom: RouterPort } {\n return {\n right: [{ id: \"true\", label: \"True\", top: \"50%\" }],\n bottom: { id: IF_FALSE_ROUTE, handleId: routeHandle(IF_FALSE_ROUTE), label: \"False\" },\n };\n}\n\n/** True when `app` is a reserved internal pseudo-app id (`@w6w/*`). */\nexport function isInternalApp(app: string): boolean {\n return app.startsWith(INTERNAL_APP_PREFIX);\n}\n\n/** True when a node is an engine-native flow-control node (can't run standalone). */\nexport function isControlApp(app: string): boolean {\n return app === CONTROL_APP || app === RACE_APP;\n}\n\n/**\n * Whether a step is an entry/trigger node — the one predicate, shared by the\n * step editor's Test tab and the canvas ▶ collect phase. A trigger's configured\n * `fields` are *definitions*, so both surfaces project them into a fillable form\n * and send the filled values as `{ input }` rather than running the raw config.\n */\nexport function isTriggerApp(app: string): boolean {\n return app === TRIGGER_APP || app === WEBHOOK_APP || app === SCHEDULER_APP;\n}\n\n/**\n * Whether a step is a trigger NODE: one of the built-in triggers, or an app\n * trigger node (`uses.trigger === true`). Canvas chrome, wiring and editing key\n * on this; {@link isTriggerApp} stays for readers that mean the built-in\n * `@w6w/*` triggers only (a callable workflow's input fields).\n */\nexport function isTriggerStep(uses: { app: string; trigger?: true }): boolean {\n return isTriggerApp(uses.app) || uses.trigger === true;\n}\n\n/** A palette entry for an internal node: its id, label, group, and config schema. */\nexport interface InternalNodeDef {\n app: string;\n action: string;\n label: string;\n /**\n * Human display name (mirrors an app's `displayName`). Defaults conceptually\n * to `label`; kept explicit so internal pseudo-apps carry the same info an app\n * does. Shown wherever an app's name would be.\n */\n displayName: string;\n /** Show one app entry in the palette and choose its action in configuration. */\n groupActions?: boolean;\n group: \"trigger\" | \"control\" | \"compute\" | \"request\";\n /**\n * Inline SVG *inner* markup (paths / circles / polylines) for this primitive's\n * glyph — internal pseudo-apps have no icon asset dir, so the glyph is bundled\n * here. Drawn on a 24×24 `viewBox`, stroked with `currentColor` (theme-aware),\n * so both app nodes and internal nodes display a consistent icon on the canvas.\n */\n icon: string;\n /**\n * Hidden from every palette list but still resolvable by `internalNodeDef`, so\n * a workflow already using the node keeps rendering and editing.\n */\n hidden?: boolean;\n /**\n * Connection ports: whether this node has an entry (`in >= 1` takes any number\n * of inbound edges; `in: 0` takes none) and how many outbound (exit) connections\n * it allows. A port is the ability to receive/emit a connection —\n * rendered as a React Flow Handle. Defaults to one of each (`{ in: 1, out: 1 }`)\n * when omitted; a trigger overrides to `{ in: 0, out: 1 }` (nothing flows into\n * the entry node). Fixed for now — not user-editable.\n */\n ports?: PortsDecl;\n /** Config schema (same `ActionParam[]` shape apps declare) rendered by ParamsForm. */\n params: ActionParam[];\n /**\n * This node's static output field keys, when its shape is known ahead of any\n * run — same shape as `ExpressionStepSource.outputs`\n * (`components/ExpressionOptions.tsx`), fed verbatim by `projectStepSources`\n * (`step-preview-state.ts`) so the expression rail can offer\n * `steps.<id>.output.<key>` for a step using this node. Omitted (not `[]`)\n * when the node's output is not statically knowable (e.g. `@w6w/document ·\n * get`, whose shape is whatever JSON the referenced document holds).\n */\n output?: { key: string; label?: string }[];\n}\n\n/** A declared port count: a number, or `\"many\"` (unbounded). */\nexport type PortCount = number | \"many\";\n\n/** A (possibly partial) port declaration, as an author / catalog / def writes it. */\nexport interface PortsDecl {\n in?: PortCount;\n out?: PortCount;\n}\n\n/** Resolved inbound (entry) and outbound (exit) connection-port counts; `\"many\"` is `Infinity`. */\nexport interface NodePorts {\n in: number;\n out: number;\n}\n\n/** The default a node gets when nothing declares ports: 1 in, unbounded out. */\nexport const DEFAULT_NODE_PORTS: NodePorts = { in: 1, out: Number.POSITIVE_INFINITY };\n\nfunction portCount(v: PortCount | undefined): number | undefined {\n if (v === \"many\") return Number.POSITIVE_INFINITY;\n return typeof v === \"number\" ? v : undefined;\n}\n\n/** Field-wise resolution: first declared value per field wins, else the default. */\nexport function resolvePorts(...layers: (PortsDecl | undefined)[]): NodePorts {\n let inn: number | undefined;\n let out: number | undefined;\n for (const l of layers) {\n inn ??= portCount(l?.in);\n out ??= portCount(l?.out);\n }\n return { in: inn ?? DEFAULT_NODE_PORTS.in, out: out ?? DEFAULT_NODE_PORTS.out };\n}\n\n/** Catalog lookup of an action's declared ports, passed as an argument (never stamped on a step). */\nexport type PortsLookup = (app: string, action: string) => PortsDecl | undefined;\n\n/**\n * Resolve a node's connection ports from its internal def only (triggers drop the\n * entry port); everything else gets the default.\n */\nexport function nodePorts(app: string, action: string): NodePorts {\n return resolvePorts(internalNodeDef(app, action)?.ports);\n}\n\n/**\n * Resolve a *step's* ports field-wise: `step.ports` → catalog action (via `lookup`)\n * → internal def → default `{ in: 1, out: Infinity }`. The catalog is read through\n * the `lookup` argument and never written onto the step, so it never serializes.\n */\nexport function nodePortsForStep(step: FlowStep, lookup?: PortsLookup): NodePorts {\n if (step.uses.app === ROUTER_APP) return { in: 1, out: routesForStep(step).length };\n const { app, action } = step.uses;\n // An app trigger node is an entry: nothing flows into it (like the built-in triggers).\n const appTriggerPorts: PortsDecl | undefined = step.uses.trigger ? { in: 0, out: 1 } : undefined;\n return resolvePorts(\n step.ports,\n lookup?.(app, action),\n internalNodeDef(app, action)?.ports ?? appTriggerPorts,\n );\n}\n\n// Feather-style 24×24 stroked glyphs (inner markup only; the card supplies the\n// <svg> wrapper). One clean, recognizable glyph per internal primitive.\n/** Lightning bolt — a trigger firing. */\nconst ICON_TRIGGER = '<polygon points=\"13 2 3 14 12 14 11 22 21 10 12 10 13 2\" />';\n/** Git-branch — a conditional split. */\nconst ICON_IF =\n '<line x1=\"6\" y1=\"3\" x2=\"6\" y2=\"15\" /><circle cx=\"18\" cy=\"6\" r=\"3\" /><circle cx=\"6\" cy=\"18\" r=\"3\" /><path d=\"M18 9a9 9 0 0 1-9 9\" />';\n/** Repeat arrows — iterate over items. */\nconst ICON_FOREACH =\n '<polyline points=\"17 1 21 5 17 9\" /><path d=\"M3 11V9a4 4 0 0 1 4-4h14\" /><polyline points=\"7 23 3 19 7 15\" /><path d=\"M21 13v2a4 4 0 0 1-4 4H3\" />';\n/** Concurrent lanes — parallel execution. */\nconst ICON_PARALLEL =\n '<line x1=\"6\" y1=\"4\" x2=\"6\" y2=\"20\" /><line x1=\"12\" y1=\"4\" x2=\"12\" y2=\"20\" /><line x1=\"18\" y1=\"4\" x2=\"18\" y2=\"20\" />';\n/** Clock — a timed wait. */\nconst ICON_WAIT = '<circle cx=\"12\" cy=\"12\" r=\"9\" /><polyline points=\"12 7 12 12 15 14\" />';\n/** Angle brackets — inline code. */\nconst ICON_SCHEDULER =\n '<rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" /><line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\" />' +\n '<line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\" /><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\" />' +\n '<polyline points=\"12 13 12 16 14 17\" />';\nconst ICON_SCRIPT = '<polyline points=\"16 18 22 12 16 6\" /><polyline points=\"8 6 2 12 8 18\" />';\n/** Database cylinder — typed data. */\nconst ICON_DATA =\n '<ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\" /><path d=\"M21 12c0 1.66-4 3-9 3s-9-1.34-9-3\" /><path d=\"M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5\" />';\n/** Globe — an outbound HTTP(S) request. */\nconst ICON_HTTP =\n '<circle cx=\"12\" cy=\"12\" r=\"10\" /><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\" /><path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\" />';\n/** Connected nodes — an inbound webhook. */\nconst ICON_WEBHOOK =\n '<circle cx=\"18\" cy=\"5\" r=\"3\" /><circle cx=\"6\" cy=\"12\" r=\"3\" /><circle cx=\"18\" cy=\"19\" r=\"3\" /><line x1=\"8.59\" y1=\"13.51\" x2=\"15.42\" y2=\"17.49\" /><line x1=\"15.41\" y1=\"6.51\" x2=\"8.59\" y2=\"10.49\" />';\n/** Reply arrow — respond to the caller. */\nconst ICON_RESPOND = '<polyline points=\"9 17 4 12 9 7\" /><path d=\"M20 18v-2a4 4 0 0 0-4-4H4\" />';\n/** Funnel — many inbound branches joined into one. */\nconst ICON_AGGREGATE = '<polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\" />';\n/** External-link box — delegate out to another Workflow / Function. */\nconst ICON_CALL =\n '<path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" /><polyline points=\"15 3 21 3 21 9\" /><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />';\n/** Dog-eared page with lines — a stored JSON document. */\nconst ICON_DOCUMENT =\n '<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" /><polyline points=\"14 2 14 8 20 8\" /><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\" /><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\" /><polyline points=\"10 9 9 9 8 9\" />';\n/** Chip — a model. */\nconst ICON_MODEL =\n '<rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" /><rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" /><line x1=\"9\" y1=\"1\" x2=\"9\" y2=\"4\" /><line x1=\"15\" y1=\"1\" x2=\"15\" y2=\"4\" /><line x1=\"9\" y1=\"20\" x2=\"9\" y2=\"23\" /><line x1=\"15\" y1=\"20\" x2=\"15\" y2=\"23\" /><line x1=\"20\" y1=\"9\" x2=\"23\" y2=\"9\" /><line x1=\"20\" y1=\"14\" x2=\"23\" y2=\"14\" /><line x1=\"1\" y1=\"9\" x2=\"4\" y2=\"9\" /><line x1=\"1\" y1=\"14\" x2=\"4\" y2=\"14\" />';\n/** Braces — a compiled placeholder template. */\nconst ICON_TEMPLATE =\n '<path d=\"M8 3H7a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2 2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h1\" /><path d=\"M16 3h1a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2 2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-1\" />';\n\n/** Cylinder — a data store. */\nconst ICON_STORE =\n '<ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\" /><path d=\"M3 5v14c0 1.66 4.03 3 9 3s9-1.34 9-3V5\" /><path d=\"M3 12c0 1.66 4.03 3 9 3s9-1.34 9-3\" />';\n\n/** Regular-expression utility actions; mirrored in the internal-app manifest. */\nconst REGEX_NODES: InternalNodeDef[] = [\n {\n app: REGEX_APP,\n action: \"match\",\n label: \"Extract\",\n displayName: \"Regex\",\n groupActions: true,\n group: \"compute\",\n icon: '<circle cx=\"6\" cy=\"17\" r=\"1\"/><path d=\"M16 4v12M11 7l10 6M11 13l10-6\"/>',\n params: [\n {\n key: \"text\",\n label: \"Text\",\n type: \"string\",\n config: { multiline: true },\n default: \"\",\n hint: \"Text to process. Empty text is allowed.\",\n },\n {\n key: \"pattern\",\n label: \"Pattern\",\n type: \"string\",\n default: \"\",\n hint: \"Enter a regular expression without enclosing / delimiters. The extracted value is the first capture group, or the full match if there are no capture groups.\",\n },\n {\n key: \"flags\",\n label: \"Flags\",\n type: \"string\",\n default: \"\",\n hint: \"Optional flags: d, g, i, m, s, u, v, y. Use g for all matches or replacements; u and v cannot be combined.\",\n },\n ],\n output: [\n { key: \"value\", label: \"Extracted value\" },\n {\n key: \"matched\",\n label: \"Matched\",\n },\n {\n key: \"matches\",\n label: \"Matches\",\n },\n ],\n },\n {\n app: REGEX_APP,\n action: \"test\",\n label: \"Test\",\n displayName: \"Regex\",\n groupActions: true,\n group: \"compute\",\n icon: '<circle cx=\"6\" cy=\"17\" r=\"1\"/><path d=\"M16 4v12M11 7l10 6M11 13l10-6\"/>',\n params: [\n {\n key: \"text\",\n label: \"Text\",\n type: \"string\",\n config: { multiline: true },\n default: \"\",\n hint: \"Text to process. Empty text is allowed.\",\n },\n {\n key: \"pattern\",\n label: \"Pattern\",\n type: \"string\",\n default: \"\",\n hint: \"JavaScript regular expression without / delimiters. An empty pattern matches an empty string.\",\n },\n {\n key: \"flags\",\n label: \"Flags\",\n type: \"string\",\n default: \"\",\n hint: \"Optional flags: d, g, i, m, s, u, v, y. Use g for all matches or replacements; u and v cannot be combined.\",\n },\n ],\n output: [\n {\n key: \"matched\",\n label: \"Matched\",\n },\n ],\n },\n {\n app: REGEX_APP,\n action: \"replace\",\n label: \"Replace\",\n displayName: \"Regex\",\n groupActions: true,\n group: \"compute\",\n icon: '<circle cx=\"6\" cy=\"17\" r=\"1\"/><path d=\"M16 4v12M11 7l10 6M11 13l10-6\"/>',\n params: [\n {\n key: \"text\",\n label: \"Text\",\n type: \"string\",\n config: { multiline: true },\n default: \"\",\n hint: \"Text to process. Empty text is allowed.\",\n },\n {\n key: \"pattern\",\n label: \"Pattern\",\n type: \"string\",\n default: \"\",\n hint: \"JavaScript regular expression without / delimiters. An empty pattern matches an empty string.\",\n },\n {\n key: \"flags\",\n label: \"Flags\",\n type: \"string\",\n default: \"\",\n hint: \"Optional flags: d, g, i, m, s, u, v, y. Use g for all matches or replacements; u and v cannot be combined.\",\n },\n {\n key: \"replacement\",\n label: \"Replacement\",\n type: \"string\",\n config: { multiline: true },\n default: \"\",\n hint: \"Replacement text; supports $1, $<name>, $&, $$, $` and $'. Leave empty to remove matches.\",\n },\n ],\n output: [\n {\n key: \"result\",\n label: \"Result\",\n },\n ],\n },\n {\n app: REGEX_APP,\n action: \"split\",\n label: \"Split\",\n displayName: \"Regex\",\n groupActions: true,\n group: \"compute\",\n icon: '<circle cx=\"6\" cy=\"17\" r=\"1\"/><path d=\"M16 4v12M11 7l10 6M11 13l10-6\"/>',\n params: [\n {\n key: \"text\",\n label: \"Text\",\n type: \"string\",\n config: { multiline: true },\n default: \"\",\n hint: \"Text to process. Empty text is allowed.\",\n },\n {\n key: \"pattern\",\n label: \"Pattern\",\n type: \"string\",\n default: \"\",\n hint: \"JavaScript regular expression without / delimiters. An empty pattern matches an empty string.\",\n },\n {\n key: \"flags\",\n label: \"Flags\",\n type: \"string\",\n default: \"\",\n hint: \"Optional flags: d, g, i, m, s, u, v, y. Use g for all matches or replacements; u and v cannot be combined.\",\n },\n ],\n output: [\n {\n key: \"parts\",\n label: \"Parts\",\n },\n ],\n },\n];\n\n/** The built-in internal nodes, in palette order. */\nexport const INTERNAL_NODES: InternalNodeDef[] = [\n ...REGEX_NODES,\n {\n app: RACE_APP,\n action: \"race\",\n label: \"Race\",\n displayName: \"Race\",\n group: \"control\",\n icon: '<path d=\"M3 5h4l5 7h9M3 19h4l5-7\" /><polyline points=\"17 8 21 12 17 16\" />',\n ports: { in: \"many\", out: 1 },\n params: [],\n },\n {\n app: ROUTER_APP,\n action: \"route\",\n label: \"Router\",\n displayName: \"Router\",\n group: \"control\",\n icon: ICON_IF,\n params: [\n {\n key: \"routes\",\n label: \"Routes\",\n type: \"json\",\n required: true,\n default: [\n { id: \"route_1\", label: \"Route 1\", condition: false },\n { id: \"default\", label: \"Default\", default: true },\n ],\n },\n ],\n output: [{ key: \"route\", label: \"Selected route\" }],\n },\n {\n app: STOP_APP,\n action: \"stop\",\n label: \"Stop workflow\",\n displayName: \"Stop workflow\",\n group: \"control\",\n icon: '<rect x=\"5\" y=\"5\" width=\"14\" height=\"14\" rx=\"2\" />',\n params: [\n {\n key: \"condition\",\n label: \"Condition\",\n type: \"json\",\n default: true,\n hint: \"Stop when this condition is true. Omit it to always stop.\",\n },\n ],\n output: [{ key: \"stopped\", label: \"Stopped\" }],\n },\n {\n app: TRIGGER_APP,\n action: \"manual\",\n label: \"Manual trigger\",\n displayName: \"Manual trigger\",\n group: \"trigger\",\n icon: ICON_TRIGGER,\n ports: { in: 0, out: 1 },\n params: [\n {\n key: \"fields\",\n label: \"Fields\",\n type: \"array\",\n default: [],\n hint: \"The fields this trigger emits into the run. Reference them downstream as {{ nodes.<trigger>.output.<key> }}.\",\n item: {\n type: \"object\",\n fields: [\n { key: \"key\", label: \"Key\", type: \"string\", placeholder: \"e.g. email\" },\n {\n key: \"type\",\n label: \"Type\",\n type: \"select\",\n default: \"string\",\n options: [\n { value: \"string\", label: \"String\" },\n { value: \"number\", label: \"Number\" },\n { value: \"boolean\", label: \"Boolean\" },\n { value: \"json\", label: \"JSON\" },\n ],\n },\n { key: \"default\", label: \"Default\", type: \"string\", placeholder: \"optional\" },\n { key: \"required\", label: \"Required\", type: \"boolean\", default: false },\n ],\n },\n },\n ],\n },\n {\n app: WEBHOOK_APP,\n action: \"webhook\",\n label: \"Webhook\",\n displayName: \"Webhook\",\n group: \"trigger\",\n icon: ICON_WEBHOOK,\n ports: { in: 0, out: 1 },\n params: [\n {\n key: \"methods\",\n label: \"HTTP Methods\",\n type: \"multiselect\",\n required: true,\n default: [\"POST\"],\n hint: \"Which HTTP methods this webhook accepts.\",\n options: [\n { value: \"GET\", label: \"GET\" },\n { value: \"POST\", label: \"POST\" },\n { value: \"PUT\", label: \"PUT\" },\n { value: \"PATCH\", label: \"PATCH\" },\n { value: \"DELETE\", label: \"DELETE\" },\n { value: \"HEAD\", label: \"HEAD\" },\n ],\n },\n {\n key: \"auth\",\n label: \"Authentication\",\n type: \"select\",\n default: \"none\",\n hint: \"How incoming requests are authenticated.\",\n options: [\n { value: \"none\", label: \"None\" },\n { value: \"basic\", label: \"Basic auth\" },\n { value: \"header\", label: \"Header auth\" },\n { value: \"jwt\", label: \"JWT (HMAC)\" },\n ],\n },\n {\n key: \"basicUser\",\n label: \"Username\",\n type: \"string\",\n row: \"basic-auth\",\n showIf: { field: \"auth\", equals: \"basic\" },\n },\n {\n key: \"basicPassword\",\n label: \"Password\",\n type: \"secret\",\n row: \"basic-auth\",\n showIf: { field: \"auth\", equals: \"basic\" },\n },\n {\n key: \"headerName\",\n label: \"Header name\",\n type: \"string\",\n row: \"header-auth\",\n placeholder: \"e.g. X-Api-Key\",\n showIf: { field: \"auth\", equals: \"header\" },\n },\n {\n key: \"headerValue\",\n label: \"Header value\",\n type: \"secret\",\n row: \"header-auth\",\n showIf: { field: \"auth\", equals: \"header\" },\n },\n {\n key: \"jwtSecret\",\n label: \"JWT secret\",\n type: \"secret\",\n showIf: { field: \"auth\", equals: \"jwt\" },\n },\n {\n key: \"responseMode\",\n label: \"Respond\",\n type: \"select\",\n default: \"onReceived\",\n hint: \"When and how to respond to the caller.\",\n options: [\n { value: \"onReceived\", label: \"Immediately (ASAP)\" },\n { value: \"lastNode\", label: \"When the run finishes\" },\n { value: \"responseNode\", label: \"Using a Response node\" },\n { value: \"streaming\", label: \"Streaming\" },\n ],\n },\n {\n key: \"responseCode\",\n label: \"Response status code\",\n type: \"number\",\n default: 200,\n showIf: { field: \"responseMode\", notIn: [\"responseNode\"] },\n },\n {\n key: \"responseData\",\n label: \"Response body (immediate)\",\n type: \"text\",\n hint: 'Body for \"Immediately\" responses. Empty = { \"runId\": \"run_…\", \"status\": \"started\" }. Write {{ runId }} to include the run id.',\n showIf: { field: \"responseMode\", equals: \"onReceived\" },\n },\n { key: \"rawBody\", label: \"Raw body\", type: \"boolean\", default: false, advanced: true },\n { key: \"ignoreBots\", label: \"Ignore bots\", type: \"boolean\", default: false, advanced: true },\n {\n key: \"ipAllowList\",\n label: \"IP allow list\",\n type: \"array\",\n advanced: true,\n item: { type: \"string\", placeholder: \"e.g. 203.0.113.4\" },\n hint: \"Client IPs allowed to call this webhook. Empty = allow all.\",\n },\n { key: \"binaryPropertyName\", label: \"Binary field name\", type: \"string\", advanced: true },\n { key: \"cors\", label: \"CORS allowed origin\", type: \"string\", advanced: true },\n {\n key: \"responseHeaders\",\n label: \"Response headers\",\n type: \"array\",\n default: [],\n advanced: true,\n item: {\n type: \"object\",\n fields: [\n { key: \"name\", label: \"Name\", type: \"string\" },\n { key: \"value\", label: \"Value\", type: \"string\" },\n ],\n },\n },\n ],\n },\n {\n app: SCHEDULER_APP,\n action: \"schedule\",\n label: \"Schedule\",\n displayName: \"Scheduler\",\n group: \"trigger\",\n icon: ICON_SCHEDULER,\n // An entry node: nothing flows in, one branch flows out.\n ports: { in: 0, out: 1 },\n params: [\n {\n key: \"mode\",\n label: \"Mode\",\n type: \"select\",\n required: true,\n default: \"cron\",\n hint: \"How the schedule fires.\",\n options: [\n { value: \"once\", label: \"Once\" },\n { value: \"cron\", label: \"Cron\" },\n { value: \"interval\", label: \"Interval\" },\n ],\n },\n {\n key: \"cron\",\n label: \"Cron expression\",\n type: \"string\",\n placeholder: \"e.g. 0 9 * * 1-5\",\n showIf: { field: \"mode\", equals: \"cron\" },\n },\n {\n key: \"runAt\",\n label: \"Run at\",\n type: \"string\",\n placeholder: \"e.g. 2026-01-01T09:00:00Z\",\n showIf: { field: \"mode\", equals: \"once\" },\n },\n {\n key: \"intervalSeconds\",\n label: \"Interval (seconds)\",\n type: \"number\",\n showIf: { field: \"mode\", equals: \"interval\" },\n },\n {\n key: \"timezone\",\n label: \"Timezone\",\n type: \"string\",\n default: \"UTC\",\n advanced: true,\n },\n ],\n },\n {\n app: CONTROL_APP,\n action: \"if\",\n label: \"If\",\n displayName: \"If\",\n group: \"control\",\n icon: ICON_IF,\n params: [\n {\n key: \"condition\",\n type: \"json\",\n label: \"Condition\",\n required: true,\n default: true,\n hint: \"A boolean, or an expression like {{ nodes.x.output.ok }}.\",\n },\n ],\n },\n {\n app: CONTROL_APP,\n action: \"foreach\",\n label: \"For each\",\n displayName: \"For each\",\n group: \"control\",\n icon: ICON_FOREACH,\n params: [\n {\n key: \"items\",\n type: \"json\",\n label: \"Items\",\n required: true,\n whole: true,\n hint: \"An array to iterate, or an expression binding to one.\",\n },\n {\n key: \"body\",\n type: \"json\",\n label: \"Body\",\n hidden: true,\n hint: \"Step ids run per item. The canvas owns it; the engine requires it at run time.\",\n },\n {\n key: \"parallelism\",\n type: \"number\",\n label: \"Parallelism\",\n hidden: true,\n hint: \"Concurrent iterations. The engine clamps it to 1.\",\n },\n ],\n },\n {\n app: CONTROL_APP,\n action: \"parallel\",\n label: \"Parallel\",\n displayName: \"Parallel\",\n group: \"control\",\n icon: ICON_PARALLEL,\n params: [],\n },\n {\n app: CONTROL_APP,\n action: \"wait\",\n label: \"Wait\",\n displayName: \"Wait\",\n group: \"control\",\n icon: ICON_WAIT,\n params: [\n {\n key: \"duration\",\n type: \"string\",\n label: \"Duration\",\n default: \"1s\",\n hint: \"Use 30s, 1h30m30s, or 3d30s. Units: w, d, h, m, s; uppercase also works.\",\n },\n ],\n },\n {\n app: SCRIPT_APP,\n action: \"run\",\n label: \"Run script\",\n displayName: \"Run script\",\n group: \"compute\",\n icon: ICON_SCRIPT,\n params: [\n {\n key: \"language\",\n label: \"Language\",\n type: \"select\",\n default: \"javascript\",\n options: [\n { value: \"javascript\", label: \"JavaScript\" },\n { value: \"typescript\", label: \"TypeScript\" },\n { value: \"python\", label: \"Python\" },\n ],\n hint: \"Execution language for this step's code. TypeScript types are erased before it runs, not checked. Python runs CPython-on-WASM with no network.\",\n },\n {\n key: \"code\",\n type: \"code\",\n label: \"Script\",\n required: true,\n scriptReads: true,\n default: \"// Runs as a function body. Return the step's output.\\nreturn input;\",\n hint: \"Return the step's output. Read data from state, vars and consts; {{ }} isn't substituted in code. digest(value) returns a stable SHA-256 hex (await it in JavaScript or TypeScript).\",\n },\n {\n // Empty, the script's `input` is the run `state`, so most scripts never open this.\n key: \"custom_input\",\n type: \"section\",\n section: \"collapsible\",\n title: \"Custom input (advanced)\",\n openWhenSet: true,\n children: [\n {\n key: \"input\",\n type: \"json\",\n label: \"Input\",\n whole: true,\n hint: \"Replaces what the script reads as `input` (by default, the run state). Each bound value keeps its type; a secret goes here, since state never holds one.\",\n },\n ],\n },\n ],\n },\n {\n app: TEMPLATE_APP,\n action: \"render\",\n label: \"Render template\",\n displayName: \"Template\",\n group: \"compute\",\n icon: ICON_TEMPLATE,\n // Static output shape (core rfcs/node-types.md:582): the already-rendered\n // string or JSON, host-side Handlebars having run — an ordinary `var` ref, not the\n // `resolveRenderPart` mechanism.\n output: [{ key: \"result\" }],\n params: [\n {\n key: \"template\",\n label: \"Template\",\n type: \"json\",\n required: true,\n whole: true,\n hint:\n 'Enter a JSON string (\"Hello {{name}}\") or object, or bind one with ƒx. ' +\n \"String values render recursively; other values stay unchanged. \" +\n \"{{name}} is HTML-escaped; use {{{name}}} for raw output.\",\n },\n {\n key: \"values\",\n label: \"Values\",\n type: \"vars\",\n required: true,\n whole: true,\n default: {},\n hint:\n \"Enter a JSON object, or use ƒx to bind data from workflow state or variables. \" +\n \"Each key becomes a top-level placeholder root.\",\n },\n ],\n },\n {\n app: DATA_APP,\n action: \"set\",\n label: \"Data\",\n displayName: \"Data set\",\n group: \"compute\",\n icon: ICON_DATA,\n params: [\n {\n // `required` surfaces the table in the form directly (not hidden under\n // the optional disclosure). The value may be an empty array — a Data\n // node with no vars yet is valid.\n key: \"vars\",\n type: \"vars\",\n label: \"Variables\",\n required: true,\n default: [],\n hint: \"Set values for downstream steps using individual fields or a JSON object.\",\n },\n ],\n },\n {\n app: DATA_APP,\n action: \"update\",\n label: \"Update object\",\n displayName: \"Update object\",\n group: \"compute\",\n icon: ICON_DATA,\n params: [\n {\n key: \"object\",\n type: \"json\",\n label: \"Starting object\",\n required: true,\n whole: true,\n hint: \"Use ƒx to choose an object from state or a previous step. The original stays unchanged.\",\n },\n {\n key: \"vars\",\n type: \"vars\",\n label: \"Fields to set\",\n required: true,\n default: [],\n hint: \"Set one or more fields. Use dot paths for nested fields, such as address.city.\",\n },\n ],\n },\n {\n app: HTTP_APP,\n action: \"request\",\n label: \"HTTP request\",\n displayName: \"HTTP\",\n group: \"request\",\n icon: ICON_HTTP,\n // Static output shape: `packages/server/packages/api/internal-nodes.ts:317-322`'s\n // `runHttpRequest` literally returns these five fields on every response.\n output: [\n { key: \"status\" },\n { key: \"statusText\" },\n { key: \"ok\" },\n { key: \"headers\" },\n { key: \"body\" },\n ],\n params: [\n {\n key: \"method\",\n type: \"string\",\n label: \"Method\",\n required: true,\n default: \"GET\",\n options: [\n { value: \"GET\", label: \"GET\" },\n { value: \"POST\", label: \"POST\" },\n { value: \"PUT\", label: \"PUT\" },\n { value: \"PATCH\", label: \"PATCH\" },\n { value: \"DELETE\", label: \"DELETE\" },\n ],\n hint: \"HTTP method for the request.\",\n },\n {\n key: \"url\",\n type: \"string\",\n label: \"URL\",\n required: true,\n default: \"\",\n hint: \"Full request URL, e.g. https://api.example.com/v1/things.\",\n },\n {\n key: \"headers\",\n type: \"json\",\n label: \"Headers\",\n default: {},\n hint: \"Object of header name → value.\",\n },\n {\n key: \"query\",\n type: \"json\",\n label: \"Query params\",\n default: {},\n hint: \"Object of query-string name → value, appended to the URL.\",\n },\n {\n key: \"body\",\n type: \"text\",\n label: \"Body\",\n default: \"\",\n hint: \"Request body (raw text or a JSON string). Ignored for GET/HEAD.\",\n },\n ],\n },\n {\n app: RESPOND_APP,\n action: \"respond\",\n label: \"Respond to Webhook\",\n displayName: \"Respond to Webhook\",\n group: \"request\",\n icon: ICON_RESPOND,\n params: [\n {\n key: \"respondWith\",\n label: \"Respond with\",\n type: \"select\",\n default: \"json\",\n hint: \"Shape of the response returned to the webhook caller.\",\n options: [\n { value: \"json\", label: \"JSON\" },\n { value: \"text\", label: \"Text\" },\n { value: \"noData\", label: \"No body\" },\n ],\n },\n { key: \"responseCode\", label: \"Response status code\", type: \"number\", default: 200 },\n {\n key: \"responseBody\",\n label: \"Response body\",\n type: \"json\",\n default: {},\n hint: \"Body to return (object for JSON, string for Text).\",\n },\n {\n key: \"responseHeaders\",\n label: \"Response headers\",\n type: \"array\",\n default: [],\n item: {\n type: \"object\",\n fields: [\n { key: \"name\", label: \"Name\", type: \"string\" },\n { key: \"value\", label: \"Value\", type: \"string\" },\n ],\n },\n },\n ],\n },\n {\n app: CONTROL_APP,\n action: \"aggregate\",\n label: \"Aggregate\",\n displayName: \"Aggregate\",\n group: \"control\",\n icon: ICON_AGGREGATE,\n hidden: true,\n // Fan-in join: accepts several inbound branches and emits one combined\n // output. `in > 1` renders the multi-input handle (every entry already takes\n // many edges — core rfcs/node-types.md · Alternate entries); `out: 1` is a single exit.\n ports: { in: 10, out: 1 },\n params: [\n {\n key: \"mode\",\n label: \"Mode\",\n type: \"select\",\n default: \"array\",\n hint: \"How to combine the inbound branch outputs: an array of results, or an object keyed by source step.\",\n options: [\n { value: \"array\", label: \"Array\" },\n { value: \"object\", label: \"Object\" },\n ],\n },\n ],\n },\n {\n app: CONTROL_APP,\n action: \"merge\",\n label: \"Merge\",\n displayName: \"Merge\",\n group: \"control\",\n icon: ICON_AGGREGATE,\n // Fan-in join with named entries: any number of inbound branches, one output\n // built from `entries` (key → expression), as an array or an object.\n ports: { in: \"many\", out: 1 },\n params: [\n {\n key: \"mode\",\n label: \"Mode\",\n type: \"select\",\n default: \"array\",\n hint: \"Combine the entries into an array, or into an object keyed by each entry's key.\",\n options: [\n { value: \"array\", label: \"Array\" },\n { value: \"object\", label: \"Object\" },\n ],\n },\n {\n key: \"entries\",\n label: \"Entries\",\n type: \"array\",\n default: [],\n hint: \"Each entry's value may be an expression (ƒx) over the inbound branches' outputs.\",\n item: {\n type: \"object\",\n fields: [\n { key: \"key\", label: \"Key\", type: \"string\" },\n { key: \"value\", label: \"Value\", type: \"string\" },\n ],\n },\n },\n ],\n },\n {\n app: CALL_APP,\n action: \"call\",\n label: \"Call workflow\",\n displayName: \"Call\",\n group: \"compute\",\n icon: ICON_CALL,\n // Internal host node: invokes a project-scoped CallableRef (a Function or a\n // Workflow) via `ctx.invokeCallable` (core rfcs/node-types.md · F-3). One\n // inbound, one outbound — the sub-run is a single downstream continuation.\n ports: { in: 1, out: 1 },\n params: [\n {\n // The target's discriminant (HITL-D: resolved within the same project).\n // A populated target picker is a deferred follow-up (FOLLOWUPS.md); v1\n // pairs this kind with a plain id field below.\n key: \"targetKind\",\n label: \"Target kind\",\n type: \"select\",\n required: true,\n default: \"workflow\",\n hint: \"Whether this node calls another Workflow or a Function.\",\n options: [\n { value: \"workflow\", label: \"Workflow\" },\n { value: \"function\", label: \"Function\" },\n ],\n },\n {\n key: \"targetId\",\n label: \"Target id\",\n type: \"string\",\n required: true,\n default: \"\",\n placeholder: \"e.g. wf_… or fn_…\",\n hint: \"Id of the Workflow (wf_…) or Function (fn_…) to call, within this project.\",\n },\n {\n // SEAM PIN: the key is `inputs` (plural) — it maps to the engine's\n // `InvokeCallableRequest.inputs` (the target's canonical inputs). Do\n // NOT rename to `input`.\n key: \"inputs\",\n label: \"Inputs\",\n type: \"json\",\n default: {},\n hint: \"Payload passed to the target — an object keyed by the callee's declared inputs. Values may be expressions.\",\n },\n {\n // HITL-5: wait/no-wait is a per-node choice, independent of the target\n // kind. `true` ⇒ block for the sub-run's output; `false` ⇒ return a run\n // handle ({ runId }) and continue the parent graph.\n key: \"wait\",\n label: \"Wait for completion\",\n type: \"boolean\",\n default: true,\n hint: \"On: block until the sub-run finishes and expose its output. Off: return a run handle and continue.\",\n },\n ],\n },\n {\n app: DOCUMENT_APP,\n action: \"get\",\n label: \"Get document\",\n displayName: \"Document\",\n group: \"compute\",\n icon: ICON_DOCUMENT,\n // Host node: reads a stored JSON document by key (core rfcs/node-types.md\n // · F-3 amendment, \"Reserved internal pseudo-app\"). One inbound, one\n // outbound — a single read step. No `project` param: the run's own\n // project is bound host-side (C-6).\n ports: { in: 1, out: 1 },\n params: [\n {\n key: \"key\",\n label: \"Key\",\n type: \"string\",\n required: true,\n default: \"\",\n hint: \"Document key to read — may be an expression, e.g. a step output.\",\n },\n ],\n },\n {\n app: MODEL_APP,\n action: \"complete\",\n label: \"Complete with model\",\n displayName: \"Model\",\n group: \"compute\",\n icon: ICON_MODEL,\n // Host node: one completion through a named model route (or a direct\n // connection + model). `route` is `type: \"string\"` in the manifest (core\n // `ParamType` has no `model-route`); the ui renders it as a route picker —\n // the same ui-only precedent as `vars` <-> `json`.\n ports: { in: 1, out: 1 },\n params: [\n {\n key: \"route\",\n label: \"Route\",\n type: \"model-route\",\n hint:\n \"Name of a model route (Models → Routes). Use this, or the model + connection pair \" +\n \"below — never both.\",\n },\n {\n key: \"model\",\n label: \"Model\",\n type: \"string\",\n advanced: true,\n hint:\n \"Catalog id of a model (`mdl_…`, Models → Catalog), called through `connection`. \" +\n \"Ignored when `route` is set.\",\n },\n {\n key: \"connection\",\n label: \"Connection\",\n type: \"string\",\n advanced: true,\n hint:\n \"Id of a model-provider connection on this account. Required by `model`; ignored \" +\n \"when `route` is set.\",\n },\n {\n key: \"input\",\n label: \"Input\",\n type: \"json\",\n required: true,\n default: {},\n hint:\n 'The request body handed to the provider — e.g. { \"messages\": [{ \"role\": \"user\", ' +\n '\"content\": \"hi\" }] }, or the provider\\'s native payload.',\n },\n {\n key: \"dialect\",\n label: \"Dialect\",\n type: \"select\",\n advanced: true,\n hint: \"Rewrite the result into this wire dialect; bridge keeps the baseline unprojected. Leave unset to keep the provider's own.\",\n placeholder: \"Provider native\",\n options: [\n { value: \"bridge\", label: \"Bridge (unprojected)\" },\n { value: \"openai\", label: \"OpenAI\" },\n { value: \"anthropic\", label: \"Anthropic\" },\n { value: \"ollama\", label: \"Ollama\" },\n ],\n },\n {\n key: \"response\",\n label: \"Response\",\n type: \"select\",\n advanced: true,\n hint:\n \"Output: the dialect-shaped result. Raw: the provider's own response. Leave unset to \" +\n \"carry both.\",\n placeholder: \"Both\",\n options: [\n { value: \"output\", label: \"Output\" },\n { value: \"raw\", label: \"Raw\" },\n ],\n },\n ],\n },\n {\n app: MODEL_APP,\n action: \"list-models\",\n label: \"List models\",\n displayName: \"Model\",\n group: \"compute\",\n icon: ICON_MODEL,\n ports: { in: 1, out: 1 },\n params: [\n {\n key: \"connection\",\n label: \"Connection\",\n type: \"string\",\n required: true,\n hint: \"Connection id of the provider to list models for.\",\n },\n ],\n },\n {\n app: MODEL_APP,\n action: \"allowance\",\n label: \"Model allowance\",\n displayName: \"Model\",\n group: \"compute\",\n icon: ICON_MODEL,\n ports: { in: 1, out: 1 },\n params: [\n {\n key: \"connection\",\n label: \"Connection\",\n type: \"string\",\n required: true,\n hint: \"Connection id of the provider to read the allowance of.\",\n },\n ],\n },\n {\n app: STORE_APP,\n action: \"get\",\n label: \"Get entry\",\n displayName: \"Store\",\n group: \"compute\",\n icon: ICON_STORE,\n // Host node: the run's own account and project are bound host-side, so there is no\n // scope param (`project`, `tenant`, ...) — the store is addressed by NAME alone.\n // `store` is `type: \"string\"` in the manifest (core `ParamType` has no `data-store`);\n // every entry's `store` param is the ui-only `data-store`, rendered as a store-name\n // picker when the host supplies `listDataStores` — the same precedent as `model-route`.\n // Likewise `key` (get/set/delete/increment) is the ui-only `data-store-key`: a searchable\n // picker of that store's entries when the host supplies `listDataStoreEntries`.\n ports: { in: 1, out: 1 },\n params: [\n {\n key: \"store\",\n label: \"Store\",\n type: \"data-store\",\n required: true,\n hint: \"Name of a data store in this account and project.\",\n },\n {\n key: \"key\",\n label: \"Key\",\n type: \"data-store-key\",\n required: true,\n hint: \"Entry key — search the store's entries, type a key, or bind an expression.\",\n },\n {\n key: \"required\",\n label: \"Required\",\n type: \"boolean\",\n default: false,\n hint: \"Fail the step when the key is missing instead of returning found: false.\",\n },\n ],\n output: [\n { key: \"found\" },\n { key: \"key\" },\n { key: \"value\" },\n { key: \"version\" },\n { key: \"expiresAt\" },\n ],\n },\n {\n app: STORE_APP,\n action: \"set\",\n label: \"Set entry\",\n displayName: \"Store\",\n group: \"compute\",\n icon: ICON_STORE,\n ports: { in: 1, out: 1 },\n params: [\n {\n key: \"store\",\n label: \"Store\",\n type: \"data-store\",\n required: true,\n hint: \"Name of a data store in this account and project.\",\n },\n {\n key: \"key\",\n label: \"Key\",\n type: \"data-store-key\",\n required: true,\n hint: \"Entry key — search the store's entries, type a key, or bind an expression.\",\n },\n {\n key: \"value\",\n label: \"Value\",\n type: \"json\",\n required: true,\n hint: \"The JSON value to store.\",\n },\n {\n key: \"ifVersion\",\n label: \"If version\",\n type: \"number\",\n hint: \"Write only when the stored version equals this number.\",\n },\n {\n key: \"ttlSeconds\",\n label: \"TTL (seconds)\",\n type: \"number\",\n hint: \"Expire the entry after this many seconds. Omit to keep it.\",\n },\n ],\n output: [{ key: \"key\" }, { key: \"value\" }, { key: \"version\" }, { key: \"expiresAt\" }],\n },\n {\n app: STORE_APP,\n action: \"delete\",\n label: \"Delete entry\",\n displayName: \"Store\",\n group: \"compute\",\n icon: ICON_STORE,\n ports: { in: 1, out: 1 },\n params: [\n {\n key: \"store\",\n label: \"Store\",\n type: \"data-store\",\n required: true,\n hint: \"Name of a data store in this account and project.\",\n },\n {\n key: \"key\",\n label: \"Key\",\n type: \"data-store-key\",\n required: true,\n hint: \"Entry key — search the store's entries, type a key, or bind an expression.\",\n },\n ],\n output: [{ key: \"key\" }, { key: \"deleted\" }],\n },\n {\n app: STORE_APP,\n action: \"increment\",\n label: \"Increment counter\",\n displayName: \"Store\",\n group: \"compute\",\n icon: ICON_STORE,\n ports: { in: 1, out: 1 },\n params: [\n {\n key: \"store\",\n label: \"Store\",\n type: \"data-store\",\n required: true,\n hint: \"Name of a data store in this account and project.\",\n },\n {\n key: \"key\",\n label: \"Key\",\n type: \"data-store-key\",\n required: true,\n hint: \"Entry key — search the store's entries, type a key, or bind an expression.\",\n },\n {\n key: \"by\",\n label: \"By\",\n type: \"number\",\n default: 1,\n hint: \"Amount to add; may be negative.\",\n },\n ],\n output: [{ key: \"key\" }, { key: \"value\" }, { key: \"version\" }],\n },\n {\n app: STORE_APP,\n action: \"list\",\n label: \"List entries\",\n displayName: \"Store\",\n group: \"compute\",\n icon: ICON_STORE,\n ports: { in: 1, out: 1 },\n params: [\n {\n key: \"store\",\n label: \"Store\",\n type: \"data-store\",\n required: true,\n hint: \"Name of a data store in this account and project.\",\n },\n {\n key: \"prefix\",\n label: \"Prefix\",\n type: \"string\",\n hint: \"Only entries whose key starts with this.\",\n },\n {\n key: \"cursor\",\n label: \"Cursor\",\n type: \"string\",\n hint: \"The nextCursor of a previous page.\",\n },\n {\n key: \"limit\",\n label: \"Limit\",\n type: \"number\",\n default: 50,\n hint: \"Page size, at most 200.\",\n },\n ],\n output: [{ key: \"items\" }, { key: \"nextCursor\" }],\n },\n {\n app: STORE_APP,\n action: \"query\",\n label: \"Query rows\",\n displayName: \"Store\",\n group: \"compute\",\n icon: ICON_STORE,\n ports: { in: 1, out: 1 },\n params: [\n {\n key: \"store\",\n label: \"Store\",\n type: \"data-store\",\n required: true,\n hint: \"Name of a data store in this account and project.\",\n },\n {\n key: \"where\",\n label: \"Where\",\n type: \"json\",\n hint: \"Column equality filter.\",\n },\n {\n key: \"order\",\n label: \"Order\",\n type: \"string\",\n hint: \"Column to order by; prefix with - for descending.\",\n },\n {\n key: \"limit\",\n label: \"Limit\",\n type: \"number\",\n hint: \"Maximum rows to return.\",\n },\n ],\n output: [{ key: \"items\" }],\n },\n {\n app: STORE_APP,\n action: \"insert\",\n label: \"Insert row\",\n displayName: \"Store\",\n group: \"compute\",\n icon: ICON_STORE,\n ports: { in: 1, out: 1 },\n params: [\n {\n key: \"store\",\n label: \"Store\",\n type: \"data-store\",\n required: true,\n hint: \"Name of a data store in this account and project.\",\n },\n {\n key: \"row\",\n label: \"Row\",\n type: \"json\",\n required: true,\n hint: \"The row, keyed by column name.\",\n },\n {\n key: \"ttlSeconds\",\n label: \"TTL (seconds)\",\n type: \"number\",\n hint: \"Expire the entry after this many seconds. Omit to keep it.\",\n },\n ],\n output: [{ key: \"key\" }, { key: \"value\" }, { key: \"version\" }],\n },\n];\n\n/** Look up an internal node's definition by its (app, action) pair. */\nexport function internalNodeDef(app: string, action: string): InternalNodeDef | undefined {\n return INTERNAL_NODES.find((n) => n.app === app && n.action === action);\n}\n\n/** The label the editor shows for an internal node (falls back to the action key). */\nexport function internalNodeLabel(app: string, action: string): string {\n return internalNodeDef(app, action)?.label ?? action;\n}\n\n/**\n * The inline SVG glyph markup for an internal node (empty when unknown). Lets a\n * node retrieve its icon from just the (app, action) pair — same lookup path as\n * `internalNodeLabel`.\n */\nexport function internalNodeIcon(app: string, action: string): string {\n return internalNodeDef(app, action)?.icon ?? \"\";\n}\n\n/** The config schema for an internal node (empty when unknown). */\nexport function internalNodeParams(app: string, action: string): ActionParam[] {\n return internalNodeDef(app, action)?.params ?? [];\n}\n\n/** Build an internal node's default `with` from its param schema defaults. */\nexport function internalNodeDefaults(app: string, action: string): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const p of internalNodeParams(app, action)) {\n if (p.default !== undefined) out[p.key] = p.default;\n }\n return out;\n}\n","/**\n * Pure state/normalization helpers behind the bounded app-picker paths\n * (`AppPicker`'s paged mode, `StepBuilderModal`'s Apps/AI/Triggers tabs and\n * its \"Ready to use\" connected-id batching). No React, no fetch, no I/O — a\n * `.ts` module so `node --test` loads it with no JSX/browser harness, per\n * this task's contract.\n *\n * Two independent state machines live here, because the two loading shapes\n * are genuinely different problems:\n *\n * - {@link AppsPageState} / {@link appsPageReducer} — ONE outstanding\n * server-paged request at a time (search / category / \"load more\"),\n * generation-guarded so a late response from an abandoned query can never\n * overwrite a newer one.\n * - {@link nextIdBatch} / {@link mergeResolvedApps} — bounded, order-stable\n * resolution of a fixed id LIST (connected app ids), a few ids per batch,\n * with no cursor at all.\n */\nimport { isInternalApp } from \"./flow-types.ts\";\nimport type { AppSummary } from \"./types.ts\";\n\n// ── Paged search/category/load-more state machine ──────────────────────────\n\n/** The user-controlled inputs that identify a distinct page fetch. */\nexport interface AppsPageQuery {\n /** Trimmed search text; `\"\"` means no search term. */\n q: string;\n /** Server-side category filter (e.g. `\"ai\"` for the AI tab), or absent. */\n category?: string;\n /** Server-side id allow-list, or absent. */\n ids?: string[];\n}\n\n/**\n * Two queries are the same fetch target when both fields match exactly\n * (empty-string `q` included) — used to short-circuit a reducer action that\n * would otherwise restart an identical in-flight query.\n */\nexport function sameAppsPageQuery(a: AppsPageQuery, b: AppsPageQuery): boolean {\n return (\n a.q === b.q &&\n (a.category ?? \"\") === (b.category ?? \"\") &&\n (a.ids ?? []).join(\",\") === (b.ids ?? []).join(\",\")\n );\n}\n\nexport type AppsPageStatus = \"loading\" | \"loading-more\" | \"ready\" | \"error\";\n\nexport interface AppsPageState {\n query: AppsPageQuery;\n /**\n * Bumped every time the query changes (new search/category/tab). A\n * response tagged with an older generation is stale and MUST be dropped by\n * the caller before dispatching — {@link isStalePageGeneration} is the\n * check; the reducer itself also refuses a stale `page-loaded`/`page-failed`\n * defensively, so a caller that forgets the check still cannot corrupt state.\n */\n generation: number;\n status: AppsPageStatus;\n /** Every app fetched so far for the CURRENT query, in server order, deduped by id. */\n apps: AppSummary[];\n /** Cursor to send on the NEXT \"load more\"; absent once the server has no more pages. */\n cursor?: string;\n hasMore: boolean;\n /** The server's total for the current query, once a page has carried it. */\n total?: number;\n error?: string;\n}\n\nexport function initialAppsPageState(query: AppsPageQuery, generation = 0): AppsPageState {\n return { query, generation, status: \"loading\", apps: [], hasMore: false };\n}\n\nexport type AppsPageAction =\n /** A new search/category/tab was selected — resets `apps`/`cursor` and starts a fresh fetch. */\n | { type: \"query-changed\"; query: AppsPageQuery; generation: number }\n /** The user asked for more results on the CURRENT query. No-op unless `status===\"ready\" && hasMore`. */\n | { type: \"load-more\" }\n /**\n * The user pressed Retry after a failure. Only meaningful from `\"error\"`:\n * back to `\"loading\"` when nothing is shown yet, `\"loading-more\"` when a\n * list is already on screen (apps and cursor kept, so the retry resends the\n * SAME cursor). No-op in any other status.\n */\n | { type: \"retry\" }\n /**\n * One page arrived. `requestedCursor` is the cursor that page was fetched\n * WITH (undefined for a first page) — compared against the server's own\n * `nextCursor` to catch a server that echoes back the same cursor forever\n * (a repeated/non-advancing cursor is treated as \"no more pages\", never\n * retried, so it can neither loop nor duplicate a request).\n */\n | {\n type: \"page-loaded\";\n generation: number;\n apps: AppSummary[];\n nextCursor?: string;\n requestedCursor?: string;\n total?: number;\n }\n | { type: \"page-failed\"; generation: number; error: string };\n\n/**\n * Dedupe-append: every app in `incoming` not already present (by `id`) in\n * `existing`, in `incoming`'s own order, appended after `existing`.\n * Immutable — always returns a new array, and existing entries in `existing`\n * are shared references, never mutated, so a caller that kept the old array\n * around still sees the original values (copy-safety for cache reads).\n */\nexport function dedupeAppend(existing: AppSummary[], incoming: AppSummary[]): AppSummary[] {\n const seen = new Set(existing.map((a) => a.id));\n const added: AppSummary[] = [];\n for (const app of incoming) {\n if (seen.has(app.id)) continue;\n seen.add(app.id);\n added.push(app);\n }\n return added.length === 0 ? existing : [...existing, ...added];\n}\n\n/**\n * The paged-picker reducer. Every transition is a pure function of\n * `(state, action)` — no timers, no fetch; the caller performs the actual\n * request and feeds the result back in as `page-loaded`/`page-failed`.\n */\nexport function appsPageReducer(state: AppsPageState, action: AppsPageAction): AppsPageState {\n switch (action.type) {\n case \"query-changed\": {\n if (action.generation === state.generation && sameAppsPageQuery(action.query, state.query)) {\n return state;\n }\n return initialAppsPageState(action.query, action.generation);\n }\n case \"load-more\": {\n if (state.status !== \"ready\" || !state.hasMore) return state;\n return { ...state, status: \"loading-more\" };\n }\n case \"retry\": {\n if (state.status !== \"error\") return state;\n return { ...state, status: state.apps.length === 0 ? \"loading\" : \"loading-more\" };\n }\n case \"page-loaded\": {\n // A late arrival from an abandoned generation is dropped outright — the\n // reducer is the last line of defense even if a caller forgot to check\n // `isStalePageGeneration` before dispatching.\n if (action.generation !== state.generation) return state;\n const apps = dedupeAppend(state.apps, action.apps);\n // A server that echoes the same cursor back (or a caller that mistakenly\n // resends the current cursor) can never advance — treat it as terminal\n // rather than retrying it, which is the one shape that would loop.\n const nonAdvancing =\n action.nextCursor !== undefined && action.nextCursor === action.requestedCursor;\n const hasMore = Boolean(action.nextCursor) && !nonAdvancing;\n return {\n ...state,\n status: \"ready\",\n apps,\n cursor: hasMore ? action.nextCursor : undefined,\n hasMore,\n total: typeof action.total === \"number\" ? action.total : state.total,\n error: undefined,\n };\n }\n case \"page-failed\": {\n if (action.generation !== state.generation) return state;\n // Errors keep whatever was already loaded (retry-in-place), and are\n // distinguished from \"loaded zero results\" by `status === \"error\"` plus\n // a non-empty `error`, never by an empty `apps` array alone.\n return { ...state, status: \"error\", error: action.error };\n }\n default:\n return state;\n }\n}\n\n/** Whether a response tagged `generation` is stale against `state` — check before dispatching. */\nexport function isStalePageGeneration(state: AppsPageState, generation: number): boolean {\n return generation !== state.generation;\n}\n\n/**\n * Reserved `@w6w/*` pseudo-apps are never a pickable catalog entry (mirrors\n * `AppPicker`'s existing exclusion) — factored out so the paged path and the\n * id-batch path apply the exact same rule.\n */\nexport function excludeInternalApps(apps: readonly AppSummary[]): AppSummary[] {\n return apps.filter((a) => !isInternalApp(a.id));\n}\n\n// ── Bounded id-batch resolution (connected/\"Ready to use\" apps) ────────────\n\n/**\n * The next batch of ids to resolve: up to `batchSize` entries from `ids`,\n * preserving `ids`' own order, skipping anything already in `requested`.\n * Returns `[]` once every id has been requested — the caller's signal to stop\n * showing \"load more\". Never re-requests an id already in `requested`, even\n * across repeated calls with a growing `requested` set (idempotent given the\n * same two inputs).\n */\nexport function nextIdBatch(\n ids: readonly string[],\n requested: ReadonlySet<string>,\n batchSize: number,\n): string[] {\n if (batchSize <= 0) return [];\n const batch: string[] = [];\n for (const id of ids) {\n if (requested.has(id)) continue;\n batch.push(id);\n if (batch.length >= batchSize) break;\n }\n return batch;\n}\n\n/**\n * Merge a batch of resolved summaries into the accumulated visible list,\n * preserving `ids`' overall order (not fetch-arrival order) and silently\n * dropping any id with no entry in `resolved` — the caller's contract for a\n * missing/404 id (see `useReadyToUse`'s id-batch rewrite): omitted, not shown\n * as an error.\n */\nexport function mergeResolvedApps(\n ids: readonly string[],\n resolved: ReadonlyMap<string, AppSummary>,\n): AppSummary[] {\n const out: AppSummary[] = [];\n for (const id of ids) {\n const app = resolved.get(id);\n if (app) out.push(app);\n }\n return out;\n}\n","import { createContext, useContext, useEffect, useState } from \"react\";\nimport type { ThemeMode } from \"./types.ts\";\n\n/**\n * Set by `<W6WUIProvider theme={...}>` (`provider.tsx`) — the HOST's\n * explicit theme choice for an EMBEDDED `@w6w/ui`, threaded through context\n * so every JS-side theme-aware component resolves the SAME value the\n * provider's own `data-theme` DOM wrapper sets for the CSS side (below),\n * without each component separately re-deriving it from `<html>`.\n * `undefined` when no `<W6WUIProvider>` is in the tree, or one that didn't\n * pass `theme` — every consumer then falls through to the pre-existing\n * `data-theme`-on-`<html>` / OS-preference chain unchanged. See\n * `docs/theming.md`.\n */\nexport const ProvidedThemeCtx = createContext<ThemeMode | undefined>(undefined);\n\n/**\n * Resolve the effective light/dark mode. Priority: explicit prop >\n * `<W6WUIProvider theme>` > `data-theme` on <html> > `prefers-color-scheme`.\n * The `data-theme` step matches the CSS defaults in `styles.css`, so\n * components and stylesheet agree even without a provider `theme` — see\n * `docs/theming.md` for why relying on that alone is a trap for an embedded\n * host, though.\n */\nexport function detectTheme(explicit: ThemeMode | undefined, provided?: ThemeMode): ThemeMode {\n if (explicit) return explicit;\n if (provided) return provided;\n if (typeof document === \"undefined\") return \"light\";\n const attr = document.documentElement.getAttribute(\"data-theme\");\n if (attr === \"dark\" || attr === \"light\") return attr;\n return window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\";\n}\n\n/**\n * Reactive `detectTheme`: reads `<W6WUIProvider theme>` from context, and —\n * when that's unset — subscribes to `data-theme` mutations on <html> and OS\n * `prefers-color-scheme` changes, so a runtime theme toggle (e.g. studio's\n * ThemeToggle, or a host re-rendering `<W6WUIProvider theme>` with a new\n * value) is reflected without a remount. Shared by every ui component that\n * needs the mode in JS (AppIcon, CodeEditor, JsonEditor, WorkflowFlowEditor)\n * so they never drift from each other or from the CSS.\n */\nexport function useEffectiveTheme(explicit?: ThemeMode): ThemeMode {\n const provided = useContext(ProvidedThemeCtx);\n const [mode, setMode] = useState<ThemeMode>(() => detectTheme(explicit, provided));\n\n useEffect(() => {\n if (explicit) {\n setMode(explicit);\n return;\n }\n if (provided) {\n setMode(provided);\n return;\n }\n if (typeof window === \"undefined\") return;\n\n const update = () => setMode(detectTheme(undefined, provided));\n\n const mql = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mql.addEventListener(\"change\", update);\n\n const observer = new MutationObserver(update);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"data-theme\"],\n });\n\n // Re-sync once in case the attribute changed between the initial render and\n // this effect running.\n update();\n\n return () => {\n mql.removeEventListener(\"change\", update);\n observer.disconnect();\n };\n }, [explicit, provided]);\n\n return mode;\n}\n","import { useState } from \"react\";\nimport { useEffectiveTheme } from \"../theme.ts\";\nimport type { ThemeMode } from \"../types.ts\";\n\ninterface Props {\n /** Data URI or absolute URL for the light-mode icon. Falsy → render an initials tile. */\n src?: string;\n /** Optional dark-mode variant; used when `theme === \"dark\"`. */\n srcDark?: string;\n /** Background color when falling back to the initials tile. */\n brandColor?: string;\n /** Display name used to produce initials when there's no image. */\n name?: string;\n /** Square px size. Defaults to 32. */\n size?: number;\n /**\n * Explicit theme. If omitted, reads `data-theme` from `<html>` and falls\n * back to `prefers-color-scheme` — matches how most theme systems work.\n */\n theme?: ThemeMode;\n}\n\n/**\n * Renders an app's icon. Prefers the inlined SVG served by the w6w server;\n * falls back to a small initials tile when no icon is provided or when both\n * light and dark variants are missing.\n */\nexport function AppIcon({ src, srcDark, brandColor, name, size = 32, theme }: Props) {\n const effective = useEffectiveTheme(theme);\n const displaySrc = effective === \"dark\" ? (srcDark ?? src) : src;\n // An icon ref that failed to inline server-side (asset-inliner.ts) can persist\n // as a raw, unresolvable path string rather than a data: URI — that never\n // renders, so `<img>` needs an escape hatch to the initials tile too. Stores\n // the src it failed on (not just a bool) so a later, different src retries\n // instead of staying stuck on the fallback.\n const [brokenSrc, setBrokenSrc] = useState<string | undefined>(undefined);\n\n if (displaySrc && displaySrc !== brokenSrc) {\n return (\n <img\n src={displaySrc}\n width={size}\n height={size}\n alt=\"\"\n onError={() => setBrokenSrc(displaySrc)}\n style={{\n width: size,\n height: size,\n borderRadius: 6,\n flexShrink: 0,\n // `contain` (not `cover`) keeps the whole glyph visible; the small\n // inset + border-box keep square/edge-to-edge icons from clipping\n // the rounded frame, without eating so much of the box that the\n // glyph reads as a stamp inside a swatch.\n objectFit: \"contain\",\n padding: Math.max(1, Math.round(size * 0.06)),\n boxSizing: \"border-box\",\n // A real icon SVG carries its own colors — painting `brandColor`\n // behind it double-tints the glyph and, for icons with built-in\n // transparent margin, reads as a thick brand-colored border rather\n // than an icon. Always the neutral swatch here; `brandColor` stays\n // reserved for the initials-tile fallback below, where it IS the\n // glyph's only color.\n background: \"var(--w6w-icon-swatch, var(--w6w-panel-2))\",\n }}\n />\n );\n }\n\n const initials = (name ?? \"?\")\n .split(/\\s+/)\n .slice(0, 2)\n .map((s) => s[0]?.toUpperCase() ?? \"\")\n .join(\"\");\n\n return (\n <span\n aria-hidden=\"true\"\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: size,\n height: size,\n borderRadius: 6,\n background: brandColor ?? \"var(--w6w-accent)\",\n color: \"#fff\",\n fontWeight: 700,\n fontSize: Math.round(size * 0.42),\n flexShrink: 0,\n }}\n >\n {initials}\n </span>\n );\n}\n","/**\n * Provider + hook that give every component a single, typed w6w API client.\n *\n * Consumers wrap their app once and every component under it can grab the\n * client via `useW6WApi()` — no more per-component callback prop drilling.\n *\n * const api = createW6WApi({ baseUrl: \"/api\", token });\n * <W6WUIProvider api={api}>...</W6WUIProvider>\n *\n * Embedding inside a host app that has its own theme? Pass `theme` too — see\n * this file's `W6WUIProviderProps.theme` doc and `docs/theming.md`.\n */\nimport { type ReactNode, createContext, useContext } from \"react\";\nimport type { NodeSample } from \"./node-samples.ts\";\nimport type { NodeTestInput } from \"./test-inputs.ts\";\nimport { ProvidedThemeCtx } from \"./theme.ts\";\nimport type {\n ActionDef,\n ApiCallRecord,\n AppSummary,\n AuthDef,\n ConnectionBinding,\n ConnectionSummary,\n CreateConnectionBody,\n CredentialDependents,\n CredentialSummary,\n CredentialTestResult,\n FunctionDetail,\n FunctionSummary,\n ResolveFieldsBody,\n ResolveFieldsResult,\n SavedTest,\n SubscriptionSummary,\n ThemeMode,\n TriggerSummary,\n WebhookListenSession,\n WorkflowDetail,\n WorkflowSummary,\n} from \"./types.ts\";\n\n/**\n * A single tester-run summary from the unified `run_log` ledger, keyed to a\n * connection. Thin by design — the full result payload stays server-side in\n * `saved_test_runs`; this is the history row shown in the test screens.\n * `summary` is null when the run recorded no summary; `occurredAt` is ISO.\n */\nexport interface TestRunSummary {\n id: string;\n actionKey: string;\n ok: boolean;\n summary: string | null;\n occurredAt: string;\n}\n\n/**\n * Which app, version, action and connection a step ran with. A local structural\n * copy of the engine's `StepMeta` (`@w6w/workflow-types`); the server sanitizes it.\n */\nexport interface StepMeta {\n app: string;\n version: string;\n action: string;\n connectionId: string | null;\n}\n\n/**\n * A saved per-step test fixture — a reusable, project-owned named capture of a\n * workflow step's resolved incoming state (`input`) and its params (`with`),\n * keyed by `(workflowId, stepId)`. Mirrors the connection-scoped `SavedTest`,\n * re-keyed to a workflow step. `lastRun*` denormalizes the most recent run.\n */\nexport interface StepTest {\n id: string;\n workflowId: string;\n stepId: string;\n name: string | null;\n input: Record<string, unknown>;\n with: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n /** When this fixture was last run (ISO), or null/undefined if never run. */\n lastRunAt?: string | null;\n /** The most recent run's status (e.g. `succeeded`/`failed`), or null. */\n lastRunStatus?: string | null;\n /** The most recent run's error payload, or null when it succeeded/never ran. */\n lastRunError?: unknown;\n /** The most recent run's captured output, or null. */\n lastRunOutput?: unknown;\n /** The most recent run's step metadata; omitted when the server has none. */\n lastRunMeta?: StepMeta | null;\n}\n\n/**\n * The **start state** a single-step invoke may carry — the RFC's third\n * `executeNode(workflow, nodeId, startState)` argument\n * (`core/rfcs/node-types.md`), sent as the invoke body's `state` field.\n *\n * Structurally the server's `StartStateInput`\n * (`server/packages/api/ambient-scope.ts`): `steps` seeds `steps.<id>.output`\n * and `trigger.event` seeds `trigger.event`, so a `with` block written as\n * `{{ steps.<id>.output.<field> }}` resolves instead of concatenating as `\"\"`.\n * Anything else in it is ignored server-side — `vars`, `documents` and\n * `secrets` are host-owned and loaded from the caller's authenticated scope, so\n * a start state can only echo back data the caller already had.\n *\n * ⚠️ It is honoured by the **single-step** invoke route only. A full run\n * (`POST /workflows/:id/run`) builds its own scope and takes nothing from here.\n */\nexport interface StepStartState {\n /** Outputs of steps that already ran, keyed by step id → `steps.<id>.output`. */\n steps?: Record<string, { output?: unknown; meta?: StepMeta }>;\n /** Trigger context; only `event` is honoured → `trigger.event`. */\n trigger?: { event?: unknown };\n /**\n * The iteration scope of a step inside a For each body → `foreach.item` / `foreach.index`\n * (on the wire `state.foreach = { item, index }`, index defaulting to 0).\n */\n foreach?: { item?: unknown; index?: number };\n}\n\n/**\n * A caller-supplied override merged into an app action's outbound request at\n * the wire — the escape hatch for a vendor field the Action's own `params`\n * don't declare (`.claude/docs/overrides.md`). Rides on the invocation\n * envelope beside `params`, never inside it; `resolveParams` never sees it.\n * Mirrors the server's `RequestOverrides`\n * (`core/packages/types/src/overrides.ts`) structurally.\n */\nexport interface RequestOverrides {\n /** Merged over the request body — deep-merges objects, index-merges arrays. */\n body?: Record<string, unknown>;\n /** Merged into the URL's query string; `null` removes a key the action set. */\n query?: Record<string, string | number | boolean | null>;\n /** Added to the request headers; applied before the auth `sign` hook, so it can't hijack it. */\n headers?: Record<string, string>;\n /** Which outbound request receives the overrides. Defaults to `\"first\"`. */\n target?: \"first\" | \"first-write\" | \"all\";\n /** Restrict the merge to requests whose URL contains this substring. */\n match?: string;\n}\n\n/**\n * The surface every w6w-io component may call. Grows as we add components;\n * new members are added at the end so consumer implementations only need to\n * grow when they want to use the new component.\n */\n/**\n * Options for {@link W6WApi.listAppsPage} — one bounded, server-paged\n * request. Every member is optional; an omitted member is a host-defined\n * default (usually \"no filter\"/\"first page\"), never a client-side guess.\n */\nexport interface ListAppsPageOptions {\n /** Full-text search term, forwarded to the server verbatim. */\n q?: string;\n /** Server-side category filter (e.g. `\"ai\"`). */\n category?: string;\n /** Server-side filter to apps declaring at least one trigger (`GET /apps?hasTriggers=true`); `total` is then the filtered total. */\n hasTriggers?: boolean;\n /** Server-side id allow-list (`GET /apps?ids=a,b`); `total` is then the filtered total. */\n ids?: string[];\n /** Opaque pagination cursor from a prior {@link AppsPageResult.nextCursor}. */\n cursor?: string;\n /** Page size; a host may clamp this to its own bounds. */\n limit?: number;\n /** Ask the host for a bounded picker-summary projection (heavy fields like inline icons may be trimmed). */\n compact?: boolean;\n /** Abort this request. Local request control only; never a wire field. */\n signal?: AbortSignal;\n /** Snapshot id from a prior {@link AppsPageResult.snapshot}. Navigation normally uses `cursor` alone. */\n snapshot?: string;\n /** Absolute offset into the snapshot. */\n offset?: number;\n}\n\n/** One page of apps, as returned by {@link W6WApi.listAppsPage}. */\nexport interface AppsPageResult {\n apps: AppSummary[];\n /** Present unless this is the last page. */\n nextCursor?: string;\n snapshot?: string;\n total?: number;\n offset?: number;\n limit?: number;\n expiresAt?: string;\n}\n\n/**\n * One page of a data store's entries for the `data-store-key` picker\n * ({@link W6WApi.listDataStoreEntries}). `value` is the stored JSON, which the\n * picker shortens to a one-line preview; `updatedAt` is an ISO timestamp.\n */\nexport interface DataStoreEntryOptions {\n items: { key: string; value?: unknown; updatedAt?: string }[];\n /** True when further matching entries exist past this page. */\n more?: boolean;\n}\n\nexport interface W6WApi {\n /**\n * List registered apps to pick from in the connection modal.\n *\n * OPTIONAL: the legacy, full-catalog counterpart to {@link listAppsPage}\n * and {@link listAppsByIds} — `createW6WApi.ts`'s own implementation still\n * provides it, and every bounded seam above is preferred wherever a host\n * implements it. Callers MUST guard on `typeof api.listApps === \"function\"`\n * before invoking it: a host with neither this nor a bounded seam settles\n * into that call site's own existing empty state instead of making a\n * request, never a crash.\n */\n listApps?(): Promise<AppSummary[]>;\n\n /**\n * Fetch ONE bounded, server-paged slice of the app catalog — the seam every\n * bounded picker UI (`AppPicker`'s paged mode, `StepBuilderModal`'s\n * Apps/AI/Triggers tabs) prefers over {@link listApps} when a host\n * implements it. OPTIONAL and ADDITIVE: an older/imported provider that\n * only implements `listApps` still typechecks and simply keeps the\n * eager-list behavior everywhere this member is absent — and a host with\n * neither this nor `listApps` settles into each caller's own existing empty\n * state instead of ever requesting a catalog.\n */\n listAppsPage?(options?: ListAppsPageOptions): Promise<AppsPageResult>;\n\n /**\n * Resolve a bounded, explicit set of app ids to their summaries — the seam\n * behind the \"Ready to use\" tab's connected-app batching and\n * `AddConnectionModal`'s `initialAppId` resolution: a caller that already\n * knows exactly which ids it needs never has to fetch (or filter) the whole\n * catalog to find them. OPTIONAL, like {@link listAppsPage}: absent, a\n * caller falls back to its pre-existing `listApps`-based resolution; absent\n * too, that caller settles into its own not-found/empty outcome instead of\n * ever calling an undefined function.\n * Missing/404 ids are simply omitted from the result, never an error for\n * the whole batch.\n */\n listAppsByIds?(ids: readonly string[], options?: { signal?: AbortSignal }): Promise<AppSummary[]>;\n\n /**\n * OPTIONAL: the tenant's model routes, for the `model-route` step-param\n * picker (`@w6w/model` `complete`). Absent, the param renders as a plain text\n * input and this is never called. A `broken` route is still selectable.\n * `project` is the editor's own project (`WorkflowProjectProvider`) when it\n * has one — a host should list THAT project's routes, not guess one from its\n * URL; `undefined` leaves the choice to the host.\n */\n listModelRoutes?(\n project?: string,\n ): Promise<{ name: string; model: string; status: \"active\" | \"broken\" }[]>;\n\n /**\n * OPTIONAL: the project's data stores, for the `data-store` step-param\n * picker (`@w6w/store`). Absent, the param renders as a plain text input and\n * this is never called. Archived stores are not listed by the host.\n * `project` is the editor's own project (`WorkflowProjectProvider`) when it\n * has one — a host should list THAT project's stores, not guess one from its\n * URL; `undefined` leaves the choice to the host.\n */\n listDataStores?(project?: string): Promise<{ name: string; kind: string }[]>;\n\n /**\n * OPTIONAL: ONE page of a data store's entries, for the `data-store-key`\n * step-param picker (`@w6w/store` get/set/delete/increment). Absent, the key\n * renders as a plain text input and this is never called.\n * `store` is the store's NAME (what the step's `store` param holds) — the\n * host resolves it to its own id. `prefix` is the server-side key search\n * (the host's `GET /data-stores/:id/entries?prefix=`); `limit` caps the page,\n * so a picker never loads a whole store. `more` is true when the store holds\n * further matches past this page. `project` follows the `listDataStores` rule.\n */\n listDataStoreEntries?(\n store: string,\n opts: { project?: string; prefix?: string; limit?: number; signal?: AbortSignal },\n ): Promise<DataStoreEntryOptions>;\n\n /**\n * OPTIONAL: resolve the choices of `options: { source: \"resolveFields\" }`\n * params from the current form (`POST` to the host). Absent, those params\n * render as plain inputs and this is never called.\n */\n resolveActionFields?(\n appId: string,\n actionKey: string,\n body: ResolveFieldsBody,\n opts?: { signal?: AbortSignal },\n ): Promise<ResolveFieldsResult>;\n\n /** Load auth methods declared by an app's manifest, with availability flags. */\n getAppAuth(appId: string): Promise<AuthDef[]>;\n\n /** Create a non-OAuth connection with a user-supplied credential. */\n createConnection(appId: string, body: CreateConnectionBody): Promise<ConnectionSummary>;\n\n /**\n * Rename a connection and/or replace some of its credential fields (`PATCH /connections/:id`).\n * Send only the fields being changed: the server merges a partial `credential` over the stored\n * one. Optional: when absent, `EditConnectionModal` shows no Save button (a one-line notice\n * instead) and hosts should not offer an Edit action. It never throws for the absence.\n */\n updateConnection?(\n id: string,\n body: {\n displayName?: string;\n binding?: ConnectionBinding;\n credentialId?: string;\n credential?: Record<string, unknown>;\n },\n ): Promise<ConnectionSummary>;\n\n // Stored credentials (all optional). The credential UI is hidden unless the methods it needs are\n // present, so an older adapter keeps working and keeps the inline-credential form.\n\n /** List stored credentials, optionally narrowed (`GET /credentials`). */\n listCredentials?(filter?: {\n contract?: string;\n appId?: string;\n authKey?: string;\n }): Promise<CredentialSummary[]>;\n /** Store a new credential (`POST /credentials`). `source` is the auth's field-value record. */\n createCredential?(body: {\n name: string;\n contract: string;\n source: Record<string, unknown>;\n }): Promise<CredentialSummary>;\n getCredential?(id: string): Promise<CredentialSummary>;\n /** Replace a credential's secret (`POST /credentials/:id/rotate`). */\n rotateCredential?(\n id: string,\n body: { source: Record<string, unknown> },\n ): Promise<CredentialSummary>;\n /** Disable (`/disable`) or re-enable (`/enable`) a credential. */\n setCredentialStatus?(id: string, status: \"active\" | \"disabled\"): Promise<CredentialSummary>;\n /** Mint-level health check; distinct from a connection's app-access test. */\n testCredential?(id: string): Promise<CredentialTestResult>;\n credentialDependents?(id: string): Promise<CredentialDependents>;\n /** Rejects with `ApiError` code `credential_in_use` (body.error.dependents) when in use. */\n deleteCredential?(id: string): Promise<void>;\n\n /**\n * Start an OAuth 2.0 flow. Server builds the provider's authorize URL and\n * returns it; the caller opens it in a popup and awaits the server's\n * callback message (see `startOAuthPopup`).\n */\n startAppOAuthFlow(\n appId: string,\n authKey: string,\n body: { displayName?: string },\n ): Promise<{ authorizationUrl: string }>;\n\n /** List the actions an app exposes, to pick from in the step builder. */\n getAppActions(appId: string): Promise<ActionDef[]>;\n\n /** List the connections that already exist for a given app. */\n listConnectionsForApp(appId: string): Promise<ConnectionSummary[]>;\n\n /** List every connection across apps — drives the \"Connected apps\" tab. */\n listConnections(): Promise<ConnectionSummary[]>;\n\n /**\n * Invoke a single action — used to test-run one step from the visual editor.\n * Pass `connectionId` to run with a stored connection's credential. Pass\n * `project` to resolve document expressions against the workflow's selected\n * project (omitted → the scope's default/starter project). Pass `state` — the\n * {@link StepStartState} — so `{{ steps.<id>.output.<field> }}` in the params\n * resolves against what those upstream steps last produced; omitted, every\n * such reference resolves to the empty string.\n *\n * `apiCalls` carries the outbound HTTP calls the action made (redacted); a\n * failed invoke rejects with an `ApiError` whose `body ?? raw` holds the same\n * field (ui's own class carries it on `body`, `@w6w/sdk`'s on `raw`).\n *\n * Pass `overrides` — a {@link RequestOverrides} — to reach a vendor field the\n * action's own params don't declare. It rides on the invocation envelope,\n * never merged into `params`; an absent or empty envelope is a no-op.\n */\n invokeAction(\n appId: string,\n actionKey: string,\n params: Record<string, unknown>,\n opts?: {\n connectionId?: string;\n project?: string;\n state?: StepStartState;\n overrides?: RequestOverrides;\n /**\n * The workflow the step belongs to, so the host resolves `nodes.<id>.config` (e.g. a\n * webhook node's `url`) as on a run. The host reads only the caller's own workflows.\n */\n workflowId?: string;\n },\n ): Promise<{\n value: unknown;\n logs?: string[];\n apiCalls?: ApiCallRecord[];\n meta?: StepMeta;\n }>;\n\n /** List the saved action-test inputs stored against a connection. */\n listSavedTests(connectionId: string): Promise<SavedTest[]>;\n\n /** Save a new set of action-test inputs against a connection. */\n createSavedTest(\n connectionId: string,\n body: { actionKey: string; name: string; values: Record<string, unknown> },\n ): Promise<SavedTest>;\n\n /** Rename a saved test or replace its stored input values. */\n updateSavedTest(\n connectionId: string,\n id: string,\n patch: { name?: string; values?: Record<string, unknown> },\n ): Promise<SavedTest>;\n\n /** Delete a saved test by id. */\n deleteSavedTest(connectionId: string, id: string): Promise<void>;\n\n /**\n * Record the outcome of an action-test run against a connection. Appends a\n * run-log row server-side; when `savedTestId` is present the saved test's\n * `lastRun*` fields are updated too. POSTs to `/connections/:connId/test-runs`.\n */\n recordTestRun(\n connId: string,\n body: {\n savedTestId?: string | null;\n actionKey: string;\n ok: boolean;\n summary?: string;\n result?: unknown;\n },\n ): Promise<void>;\n\n /**\n * List a connection's recent tester-run history from the unified `run_log`\n * ledger (`GET /connections/:connId/test-runs` → the `.runs` array). Powers\n * the run-history list in the test screens, complementing the per-test\n * `lastRun*` badge with the full ledger.\n *\n * OPTIONAL: consumers that don't render history (or haven't wired it up yet)\n * may omit it, so a missing member never poisons their typecheck. Callers\n * MUST guard on its presence before invoking.\n */\n listTestRuns?(connectionId: string): Promise<TestRunSummary[]>;\n\n /**\n * Save a reusable per-step test fixture against a workflow step. Captures the\n * resolved incoming state (`input`) and the step's params (`with`); the server\n * stores both verbatim, project-owned. Mirrors `createSavedTest`, re-keyed from\n * a connection to a `(workflowId, stepId)`. POSTs to\n * `/workflows/:workflowId/steps/:stepId/tests`.\n */\n saveStepTest(\n workflowId: string,\n stepId: string,\n body: { name?: string; input: Record<string, unknown>; with: Record<string, unknown> },\n ): Promise<StepTest>;\n\n /**\n * Record the outcome of a step-test run so every run (saved or ad-hoc) is\n * logged authoritatively server-side. The run row mirrors `node_executions`\n * (status/input/output/error). When `stepTestId` is present the fixture's\n * `lastRun*` fields are updated too. Mirrors `recordTestRun`, re-keyed to a\n * workflow step. POSTs to `/workflows/:workflowId/steps/:stepId/test-runs`.\n */\n recordStepTestRun(\n workflowId: string,\n stepId: string,\n body: {\n stepTestId?: string | null;\n status: string;\n input?: unknown;\n output?: unknown;\n error?: unknown;\n meta?: unknown;\n },\n ): Promise<void>;\n\n /**\n * List the saved test fixtures for a workflow step (project-owned, not\n * subject-filtered). Added now so the ui-only incoming-state picker and\n * test-gate tasks need no further studio change. Mirrors `listSavedTests`,\n * re-keyed to a `(workflowId, stepId)`. GETs\n * `/workflows/:workflowId/steps/:stepId/tests`.\n */\n listStepTests(workflowId: string, stepId: string): Promise<StepTest[]>;\n\n /**\n * OPTIONAL. The workflow's persisted node samples — each node's last output shape (and value,\n * when kept) from a step Test, a node run or a full run, written server-side on every one of\n * them. The flow editor loads them once per workflow so upstream keys survive a reload\n * (`node-samples.ts`); a host without it behaves exactly as before. GETs\n * `/workflows/:workflowId/node-samples` → `{ nodeSamples }`.\n */\n loadNodeSamples?(workflowId: string): Promise<NodeSample[]>;\n\n /**\n * OPTIONAL. The test input each node of the workflow last ran with in the editor (a trigger's\n * filled fields, any other node's incoming state) — so the Run node modal, the Test tabs and the\n * header Run reopen prefilled (`test-inputs.ts`). Server-side, never in the workflow definition.\n * GETs `/workflows/:workflowId/test-inputs` → `{ testInputs }`. A host without it falls back to\n * the latest step-test fixture, as before.\n */\n loadTestInputs?(workflowId: string): Promise<NodeTestInput[]>;\n\n /**\n * OPTIONAL. Remember the node's test input (newest wins; `{}` is a CLEAR). The server drops\n * sealed envelopes; the caller drops literal secrets first (`rememberableInput`). PUTs\n * `/workflows/:workflowId/nodes/:nodeId/test-input` `{ input }`.\n */\n saveTestInput?(workflowId: string, nodeId: string, input: Record<string, unknown>): Promise<void>;\n\n /**\n * List the caller's registered Functions (core rfcs/function.md) — drives\n * the step builder's Functions tab (F-2.0). GETs `/functions`.\n */\n listFunctions(): Promise<FunctionSummary[]>;\n\n /**\n * Load one Function's canonical interface (`inputs`), so the Functions tab\n * can render its Configure stage's `ParamsForm`. GETs `/functions/:id`.\n */\n getFunction(id: string): Promise<FunctionDetail>;\n\n /**\n * Invoke a Function directly — the Functions tab's Test stage\n * (`CallableStepConfig`), NOT the `@w6w/call` node's own run-time path (that\n * goes through `ctx.invokeCallable`, host-side). Returns the raw output —\n * `unknown`, not an invocation envelope — matching the committed\n * `studio/src/repos/functions.ts`. POSTs `/functions/:id/invoke`.\n */\n invokeFunction(id: string, inputs: Record<string, unknown>): Promise<unknown>;\n\n /**\n * List the caller's registered Workflows — drives the step builder's\n * Workflows tab (F-2.0). GETs `/workflows`.\n */\n listWorkflows(): Promise<WorkflowSummary[]>;\n\n /**\n * Load one Workflow's full definition, so the Workflows tab can derive its\n * entry/trigger step's declared `with.fields` for the Configure stage's\n * `ParamsForm`. GETs `/workflows/:id`.\n */\n getWorkflow(id: string): Promise<WorkflowDetail>;\n\n /**\n * Run a Workflow synchronously — the Workflows tab's Test stage (D-11/\n * D-15(c)): the SAME `?wait=true` path the saved `@w6w/call` step takes at\n * run time, never a client-side enqueue-and-poll. `terminal` is derived from\n * the response's HTTP status (`200` ⇒ `true`, the server's own `202`\n * synchronous-wait timeout ⇒ `false` — a legitimate \"still running\" outcome,\n * not an error). POSTs `/workflows/:id/run?wait=true`.\n */\n runWorkflow(\n id: string,\n opts?: { variables?: Record<string, unknown>; input?: Record<string, unknown> },\n ): Promise<{\n runId: string;\n status: string;\n output?: unknown;\n error?: unknown;\n terminal: boolean;\n }>;\n\n /**\n * List apps that declare at least one trigger — the Triggers tab's\n * Apps filtered by `triggerCount > 0`. UNUSED by the step builder: the Triggers\n * tab resolves connected apps via `listAppsByIds` and searches via\n * `listAppsPage({ hasTriggers: true })`. The member stays on the public surface.\n *\n * OPTIONAL, like `listTestRuns?` above.\n */\n listTriggerApps?(): Promise<AppSummary[]>;\n\n /**\n * List one app's declared triggers. GETs `/apps/:id/triggers`.\n */\n getAppTriggers?(appId: string): Promise<TriggerSummary[]>;\n\n /**\n * List the Subscriptions bound to one workflow (rfcs/trigger.md). Powers\n * the webhook-URL panel's get-or-create check (I-2) — GETs\n * `/workflows/:id/subscriptions`.\n */\n listSubscriptionsForWorkflow?(workflowId: string): Promise<SubscriptionSummary[]>;\n\n /**\n * \"Listen for test event\" on a `@w6w/webhook` subscription: opens a short-lived session in\n * which the receive URL captures the next request, even for an unpublished workflow. POSTs\n * `/subscriptions/:id/listen`.\n */\n startWebhookListen?(\n subscriptionId: string,\n ): Promise<{ session: WebhookListenSession; webhookUrl: string }>;\n\n /**\n * Long-poll a listen session (`GET /subscriptions/:id/listen/:sessionId?wait=`). Resolves as\n * soon as a request is captured or the session expires, else after `waitSeconds` (max 25).\n */\n pollWebhookListen?(\n subscriptionId: string,\n sessionId: string,\n opts?: { waitSeconds?: number; signal?: AbortSignal },\n ): Promise<WebhookListenSession>;\n\n /** Stop listening (`DELETE /subscriptions/:id/listen/:sessionId`). */\n stopWebhookListen?(subscriptionId: string, sessionId: string): Promise<void>;\n\n /**\n * Retry a failed trigger registration. POSTs\n * `/subscriptions/:id/retry-registration`; resolves the updated Subscription.\n * Absent => the trigger node offers no Retry.\n */\n retrySubscriptionRegistration?(subscriptionId: string): Promise<SubscriptionSummary>;\n\n /**\n * Create a Subscription binding an app trigger to a workflow — the one\n * explicit user action both the Triggers-tab app section (T-0) and the\n * webhook-URL panel (I-2) call, per DECISIONS.md HITL-1. POSTs\n * `/apps/:id/triggers/:key/subscriptions`.\n */\n createSubscription?(\n appId: string,\n triggerKey: string,\n input: {\n workflowId: string;\n connectionId?: string | null;\n params?: Record<string, unknown>;\n /** Poll triggers only, in milliseconds. */\n intervalMs?: number;\n },\n ): Promise<SubscriptionSummary>;\n}\n\nconst Ctx = createContext<W6WApi | null>(null);\n\nexport interface W6WUIProviderProps {\n api: W6WApi;\n /**\n * Force the theme every `@w6w/ui` component resolves to — both the CSS\n * tokens (`styles.css`'s `:where([data-theme=...])` blocks; `color-scheme` is\n * declared on component roots, never on the host `<html>`) and the\n * JS-side theme-aware components (`AppIcon`, `CodeEditor`, `JsonEditor`,\n * `WorkflowFlowEditor`, via `useEffectiveTheme`) — instead of each one\n * independently falling back to `data-theme` on `<html>` or the visitor's\n * OS `prefers-color-scheme`.\n *\n * Omit to keep that pre-existing default — the right choice for `@w6w/ui`'s\n * own app (studio), which already manages `data-theme` on `<html>` itself.\n * But it's a silent trap for a HOST embedding these components inside its\n * own page: without this prop, `@w6w/ui` resolves its theme from the\n * visitor's OS setting, independently of whatever theme the host's own\n * page is using — a visitor with a dark-mode OS preference gets `@w6w/ui`\n * components rendered in ITS dark palette sitting inside an otherwise-light\n * host page (or vice versa). Pass your host's own resolved theme here to\n * make `@w6w/ui` follow it instead. See `docs/theming.md`.\n */\n theme?: ThemeMode;\n children: ReactNode;\n}\n\n/**\n * Provides the w6w API client to every component under it, and — when\n * `theme` is given — forces `@w6w/ui`'s theme to match it (see\n * `W6WUIProviderProps.theme` above). Setting `theme` wraps `children` in a\n * `data-theme` DOM node: CSS custom properties cascade to every descendant\n * regardless of specificity, so this alone is enough for every `@w6w/ui`\n * stylesheet rule to resolve correctly — no need to also set the attribute\n * on `<html>` yourself. `display: contents` keeps that wrapper invisible to\n * layout (flex/grid gap, `:nth-child`, etc. all behave as if it weren't\n * there).\n */\nexport function W6WUIProvider({ api, theme, children }: W6WUIProviderProps) {\n const content = (\n <Ctx.Provider value={api}>\n <ProvidedThemeCtx.Provider value={theme}>{children}</ProvidedThemeCtx.Provider>\n </Ctx.Provider>\n );\n if (!theme) return content;\n return (\n <div data-theme={theme} style={{ display: \"contents\" }}>\n {content}\n </div>\n );\n}\n\n/**\n * Access the w6w API client. Throws a helpful error if used outside a\n * `<W6WUIProvider>` — the common mistake is forgetting to wrap the app root.\n */\nexport function useW6WApi(): W6WApi {\n const api = useContext(Ctx);\n if (!api) {\n throw new Error(\n \"useW6WApi must be used inside <W6WUIProvider>. \" +\n \"Wrap your app root with <W6WUIProvider api={api}>...</W6WUIProvider>.\",\n );\n }\n return api;\n}\n\n/**\n * Like {@link useW6WApi} but returns `undefined` outside a provider instead of\n * throwing — for optional enhancements (e.g. the `model-route` picker).\n */\nexport function useOptionalW6WApi(): W6WApi | undefined {\n return useContext(Ctx) ?? undefined;\n}\n\n/**\n * The workflow's currently-selected project id, provided by the editor so an\n * ad-hoc test-invoke resolves document expressions against that project (not the\n * scope's default/starter project). `undefined` — no project provided — keeps the\n * server's default-project behavior. Deliberately not throwing when absent: test\n * panels render outside the editor too (e.g. connection screens).\n */\nconst WorkflowProjectCtx = createContext<string | undefined>(undefined);\n/** The edited workflow's id, so a test-invoke can name it (`nodes.<id>.config`). */\nconst WorkflowIdCtx = createContext<string | undefined>(undefined);\n\n/**\n * Scopes test-invokes under it to `project`, and names `workflowId` on them; the editor wraps\n * its body with this.\n */\nexport function WorkflowProjectProvider({\n project,\n workflowId,\n children,\n}: {\n project?: string;\n workflowId?: string;\n children: ReactNode;\n}) {\n return (\n <WorkflowProjectCtx.Provider value={project}>\n <WorkflowIdCtx.Provider value={workflowId}>{children}</WorkflowIdCtx.Provider>\n </WorkflowProjectCtx.Provider>\n );\n}\n\n/** The selected workflow project id in scope, or `undefined` outside the editor. */\nexport function useWorkflowProject(): string | undefined {\n return useContext(WorkflowProjectCtx);\n}\n\n/** The edited workflow's id in scope, or `undefined` outside the editor. */\nexport function useWorkflowId(): string | undefined {\n return useContext(WorkflowIdCtx);\n}\n","import { type ReactNode, useCallback, useEffect, useReducer, useRef, useState } from \"react\";\nimport { deriveCategories, matchesCategories } from \"./app-categories.ts\";\nimport {\n type AppsPageQuery,\n appsPageReducer,\n excludeInternalApps,\n initialAppsPageState,\n} from \"./app-pages.ts\";\nimport { AppIcon } from \"./components/AppIcon.tsx\";\nimport { useW6WApi } from \"./provider.tsx\";\nimport type { AppSummary, ThemeMode } from \"./types.ts\";\n\n/**\n * Category-filter chip row collapse budget (D-1a: \"collapsed to a fixed\n * count budget with a `+N more` toggle\", \"≈2 rows\"). An implementation\n * constant, not part of the public API.\n */\nconst CHIP_VISIBLE_BUDGET = 8;\n\n/**\n * Default bounded page size for the paged loading path (T2.1.1 A2: \"Apps/AI\n * request one page (limit at most 60)\"). Also the default for any other\n * paged-mode caller of this component that does not override `pageLimit`.\n */\nconst DEFAULT_PAGE_LIMIT = 60;\n\n/** How long to wait after the last keystroke before firing a server search. */\nconst SEARCH_DEBOUNCE_MS = 300;\n\n/**\n * The app's declared model-provider designation, or `null` when it declares\n * none (A01). PRESENCE of `modelProvider` is the ONLY test — this never\n * consults `categories`, so a category-`ai` app without a designation is not\n * a provider and must never be surfaced as one.\n */\nexport function modelProviderOf(app: AppSummary): NonNullable<AppSummary[\"modelProvider\"]> | null {\n const provider = app.modelProvider;\n if (!provider || typeof provider !== \"object\") return null;\n return provider;\n}\n\n/**\n * The bridge-support chip content for one card, or `null` when the host's\n * lookup carries no entry for that app — \"unknown\" renders nothing rather\n * than guessing, exactly like an undesignated app has no provider badge.\n * A blank `reason` is treated as absent (a wire value may be `\"\"`).\n */\nfunction bridgeSupportChip(\n entry: { supported: boolean; reason?: string } | undefined,\n): { text: string; title: string } | null {\n if (!entry) return null;\n if (entry.supported) return { text: \"Bridge supported\", title: \"Bridge supported\" };\n const reason = typeof entry.reason === \"string\" ? entry.reason.trim() : \"\";\n return {\n text: reason === \"\" ? \"unsupported\" : `unsupported — ${reason}`,\n title: reason === \"\" ? \"Bridge not supported\" : reason,\n };\n}\n\nexport interface AppPickerProps {\n /** Fired when the user picks an app card. */\n onSelectApp: (app: AppSummary) => void;\n theme?: ThemeMode;\n /**\n * Optional pre-filter over the app list (e.g. only connectable apps).\n * Applied CLIENT-side, on top of whatever page/list was fetched — never\n * widens a fetch, only narrows what's shown. Because the server counted the\n * apps this filter may then hide, a narrowing filter also removes the paged\n * footer's denominator: the count reads `N apps`, never `N of total`.\n * Prefer {@link ids} / {@link category} when the server can do the narrowing.\n */\n filter?: (app: AppSummary) => boolean;\n /** Search-box placeholder. Defaults to \"Search apps…\". */\n searchPlaceholder?: string;\n /** Message shown when the (filtered) app list is empty. */\n emptyMessage?: string;\n /** Render the search input. Defaults to `true`; the connected-apps list opts out. */\n search?: boolean;\n /** Controlled query for a shared search field outside the picker. */\n searchValue?: string;\n onSearchChange?: (value: string) => void;\n /** Rendered beneath `emptyMessage` in the empty state (e.g. a \"Browse all apps\" button). */\n emptyAction?: ReactNode;\n /**\n * Supply the catalog instead of letting the picker fetch it. For a caller\n * that already holds the list — and, more to the point, that decides\n * membership from fields this package's {@link AppSummary} does not carry\n * (`supportsOAuth`, `owner`): passing the decided list keeps ONE list and one\n * loading/error state, where `filter` would mean a second `listApps()` whose\n * result can disagree with the caller's. `null` is \"still loading\" and\n * renders the same placeholder the internal fetch does. Supplying a list\n * (including `null`) always suppresses BOTH the legacy eager fetch and the\n * bounded paged fetch below.\n */\n apps?: AppSummary[] | null;\n /**\n * Render an opt-in category-filter chip row, derived from the VISIBLE\n * catalog's own `categories` values (never the full RFC vocabulary — see\n * `app-categories.ts`). Defaults to `false`. Only {@link AddConnectionModal}\n * turns this on today — both `StepBuilderModal` picker call sites already\n * narrow their catalog through `filter`, so a second filter layer there\n * would be redundant.\n */\n categoryFilter?: boolean;\n /**\n * Render an opt-in model-provider filter BESIDE the category chips (crit 1,\n * A01/A02): one toggle that narrows the list to apps carrying a\n * `modelProvider` designation. It filters on the PRESENCE of `modelProvider`\n * only — never on categories — so an undesignated category-`ai` app is never\n * surfaced by it. Defaults to `false`, so no existing call site's behavior\n * changes; the toggle itself is hidden when nothing in the visible catalog\n * declares a provider (no dead-end filter, same rule as the category chips).\n */\n providerFilter?: boolean;\n /**\n * Opt-in bridge-support lookup, keyed by app id — the HOST passes this in,\n * because this package never fetches (`GET /models/providers` carries\n * `operations.complete` support and its `reasons`, and the host already\n * holds that descriptor). Presence of an entry adds a chip beside the\n * model-provider badge: \"Bridge supported\" when `supported`, else an\n * \"unsupported\" chip carrying the entry's `reason` as both its text and its\n * `title`. Omitting the prop (or an app having no entry) renders no chip at\n * all, so every existing call site and snapshot is unchanged.\n */\n bridgeSupport?: ReadonlyMap<string, { supported: boolean; reason?: string }>;\n /**\n * Server-side `category` param for the bounded paged fetch (e.g. `\"ai\"` for\n * the AI tab) — sent to `W6WApi.listAppsPage`, never applied client-side.\n * Ignored when `apps` is supplied or the host has no `listAppsPage`.\n */\n category?: string;\n /**\n * Server-side \"declares at least one trigger\" filter for the bounded paged\n * fetch (`GET /apps?hasTriggers=true`), forwarded to `listAppsPage` exactly\n * like {@link category}: the page `total` is the FILTERED total, so the footer\n * reads the server's `N of M`. Part of the query identity — changing it\n * restarts the fetch. Ignored when `apps` is supplied or via a custom `loadPage`.\n */\n hasTriggers?: boolean;\n /**\n * Server-side id allow-list (`GET /apps?ids=a,b&paged=true`) for the bounded\n * paged fetch: the page `total` is the FILTERED total, so the footer reads\n * `N of N`. Sent to `listAppsPage`/`loadPage`; ignored when `apps` is supplied.\n */\n ids?: string[];\n /** Bounded page size for the paged fetch. Defaults to {@link DEFAULT_PAGE_LIMIT} (60). */\n pageLimit?: number;\n /**\n * Optional page loader that takes precedence over `W6WApi.listAppsPage` and\n * turns on the paged mode by itself (ignored when `apps` is supplied). It\n * is called with exactly `{ q, cursor, limit, signal }` — never `category`\n * or `compact` — and reuses the picker's debounce, stale-response guard,\n * abort, Load more and Retry. Held in a ref: its identity may change every\n * render without causing a request.\n */\n loadPage?: (options: {\n q?: string;\n cursor?: string;\n limit: number;\n ids?: string[];\n signal: AbortSignal;\n }) => Promise<{ apps: AppSummary[]; nextCursor?: string; total?: number }>;\n}\n\n/**\n * Searchable grid of app cards (icon + name + id + version) — the shared app picker used\n * by both the step builder and the add-connection modal.\n *\n * **Three loading modes**, chosen automatically and mutually exclusive:\n *\n * 1. `apps` supplied (including `null`) — the caller owns loading; this\n * component only renders.\n * 2. `apps` omitted and the host implements `W6WApi.listAppsPage` — bounded\n * server-paged loading: one page per search/category, explicit\n * \"Load more\", debounced search, cancellation on query change/unmount\n * (T2.1.1 A2). This is the path every current call site in this package\n * reaches once its host wires the optional method.\n * 3. `apps` omitted and the host has ONLY the legacy `W6WApi.listApps` —\n * unchanged eager full-catalog fetch, preserved byte-for-byte for\n * backward compatibility with an older/imported provider (C6). A host\n * with neither `listAppsPage` nor `listApps` settles into this same\n * mode's existing empty state — no request, no throw.\n */\nexport function AppPicker({\n onSelectApp,\n theme,\n filter,\n searchPlaceholder,\n emptyMessage,\n search = true,\n searchValue,\n onSearchChange,\n emptyAction,\n apps: providedApps,\n categoryFilter = false,\n providerFilter = false,\n bridgeSupport,\n category,\n hasTriggers,\n ids,\n pageLimit = DEFAULT_PAGE_LIMIT,\n loadPage,\n}: AppPickerProps) {\n const api = useW6WApi();\n // `undefined` means \"not supplied\" — a supplied `null` is a caller whose own\n // fetch has not resolved yet, which must NOT start a second one.\n const supplied = providedApps !== undefined;\n // Capability detection is `typeof === \"function\"` ONLY — never inferred\n // from a runtime response shape. A response this component cannot use (not\n // an array of apps), on a first page or a load-more alike, is a retryable\n // safe error (A6), never evidence that the optional method \"isn't really\n // implemented\": that conflation previously let one transiently-malformed\n // response permanently and silently revert a genuinely bounded host to the\n // unbounded `listApps()` for the rest of the component's lifetime, tainting\n // every tab sharing this mounted instance (T2.1.1 ROUND 2). A host that\n // truly lacks `listAppsPage` must answer `undefined` for it, not a callable\n // stub that returns the wrong shape — see the fixed test fixtures this\n // package's own suites now use (`StepBuilderModal.connection-only/\n // homepage-tabs/template-node.test.ts`) rather than working around a\n // stub's shape in production semantics.\n const idsKey = ids && ids.length > 0 ? ids.join(\",\") : \"\";\n const paged = !supplied && (loadPage !== undefined || typeof api.listAppsPage === \"function\");\n const loadPageRef = useRef(loadPage);\n loadPageRef.current = loadPage;\n\n // ── Mode 3: legacy eager full-catalog fetch (unchanged, plus the fallback above) ──\n const [fetchedApps, setFetchedApps] = useState<AppSummary[] | null>(null);\n const [legacyError, setLegacyError] = useState<string | null>(null);\n\n useEffect(() => {\n if (supplied || paged) return;\n const listApps = api.listApps;\n // A host with neither `listAppsPage` (checked above, via `paged`) nor\n // `listApps` settles here into the empty catalog — not a permanent\n // \"Loading apps…\" and not a call to an undefined function — exactly the\n // pre-existing empty-state branch below (`base.length === 0`).\n if (typeof listApps !== \"function\") {\n setFetchedApps([]);\n return;\n }\n let canceled = false;\n listApps()\n .then((r) => !canceled && setFetchedApps(r))\n .catch((e) => !canceled && setLegacyError((e as Error).message));\n return () => {\n canceled = true;\n };\n }, [api, supplied, paged]);\n\n // ── Mode 2: bounded paged fetch ────────────────────────────────────────────\n const [pageState, dispatch] = useReducer(\n appsPageReducer,\n initialAppsPageState({ q: \"\", category, ids }, 0),\n );\n const [localQuery, setLocalQuery] = useState(\"\");\n const inputValue = searchValue ?? localQuery;\n const setInputValue = (value: string) => {\n if (searchValue === undefined) setLocalQuery(value);\n onSearchChange?.(value);\n };\n const [debouncedQuery, setDebouncedQuery] = useState(inputValue.trim());\n // Mirrors `pageState.generation` synchronously — an async `.then`/`.catch`\n // callback closes over the generation IT was issued with, and compares\n // against this ref (not the React state, which the callback's own closure\n // cannot see update) to decide whether its own result is still wanted.\n const generationRef = useRef(0);\n const abortRef = useRef<AbortController | null>(null);\n\n const fetchPage = useCallback(\n (query: AppsPageQuery, generation: number, cursor: string | undefined) => {\n const custom = loadPageRef.current;\n const listAppsPage = api.listAppsPage;\n if (!custom && !listAppsPage) return;\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n // A loader that throws synchronously must land in the same error/Retry\n // state as a rejected promise (and not defer the call: request-shape\n // timing is observable).\n let request: ReturnType<NonNullable<typeof custom>>;\n try {\n request = custom\n ? custom({\n q: query.q || undefined,\n cursor,\n limit: pageLimit,\n ...(query.ids ? { ids: query.ids } : {}),\n signal: controller.signal,\n })\n : (listAppsPage as NonNullable<typeof listAppsPage>)({\n q: query.q || undefined,\n category: query.category,\n ...(hasTriggers ? { hasTriggers: true } : {}),\n ...(query.ids ? { ids: query.ids } : {}),\n cursor,\n limit: pageLimit,\n compact: true,\n signal: controller.signal,\n });\n } catch (e) {\n request = Promise.reject(e);\n }\n request\n .then((page) => {\n if (generationRef.current !== generation) return; // stale: a newer query/unmount won\n if (!page || !Array.isArray((page as { apps?: unknown }).apps)) {\n // A6: a malformed envelope — first page or \"load more\" alike — is\n // always a safe, retryable error, never a crash and never treated\n // as proof the optional method \"isn't really implemented\" (that\n // capability question is `typeof api.listAppsPage === \"function\"`\n // alone, checked once above `paged`'s definition). Already-shown\n // apps (if any) are preserved.\n dispatch({\n type: \"page-failed\",\n generation,\n error: \"The server returned a malformed apps page.\",\n });\n return;\n }\n dispatch({\n type: \"page-loaded\",\n generation,\n apps: page.apps,\n nextCursor: page.nextCursor,\n requestedCursor: cursor,\n total: typeof page.total === \"number\" ? page.total : undefined,\n });\n })\n .catch((e: unknown) => {\n if (generationRef.current !== generation) return;\n // Our own cancellation (query change / unmount) — not a user-facing\n // error; the newer request (or nothing, on unmount) owns the state.\n if (e instanceof Error && e.name === \"AbortError\") return;\n // The snapshot behind our cursor is gone (410 and 404 alike to a\n // token holder). Detected structurally: the host's loader throws its\n // own error class (the SDK's), never ui's `ApiError`. Reset and\n // restart from page 1, once; a cursorless failure is a real error.\n const code = (e as { code?: unknown } | null)?.code;\n if (\n cursor !== undefined &&\n (code === \"snapshot_expired\" || code === \"unknown_snapshot\")\n ) {\n const next = ++generationRef.current;\n dispatch({ type: \"query-changed\", query, generation: next });\n fetchPage(query, next, undefined);\n return;\n }\n dispatch({ type: \"page-failed\", generation, error: (e as Error).message });\n });\n },\n [api, pageLimit, hasTriggers],\n );\n\n // Debounce the search box; cancelled on every keystroke and on unmount.\n useEffect(() => {\n if (!paged) return;\n const t = setTimeout(() => setDebouncedQuery(inputValue.trim()), SEARCH_DEBOUNCE_MS);\n return () => clearTimeout(t);\n }, [inputValue, paged]);\n\n // A new debounced query or a new `category` (e.g. the AI tab reusing this\n // same mounted component after Apps→AI) starts a fresh bounded fetch and\n // aborts whatever the previous one was still waiting on.\n useEffect(() => {\n if (!paged) return;\n const generation = ++generationRef.current;\n const query: AppsPageQuery = {\n q: debouncedQuery,\n category,\n ...(idsKey ? { ids: idsKey.split(\",\") } : {}),\n };\n dispatch({ type: \"query-changed\", query, generation });\n fetchPage(query, generation, undefined);\n return () => {\n abortRef.current?.abort();\n };\n }, [paged, debouncedQuery, category, idsKey, fetchPage]);\n\n // Abort any still-pending request when the component itself unmounts (tab\n // switch away, modal close) even if no new query/category fired above.\n useEffect(() => {\n if (!paged) return;\n return () => abortRef.current?.abort();\n }, [paged]);\n\n const loadMore = () => {\n if (!paged || pageState.status !== \"ready\" || !pageState.hasMore) return;\n const generation = generationRef.current;\n dispatch({ type: \"load-more\" });\n fetchPage(pageState.query, generation, pageState.cursor);\n };\n\n const retry = () => {\n if (!paged || pageState.status !== \"error\") return;\n dispatch({ type: \"retry\" });\n fetchPage(pageState.query, generationRef.current, pageState.cursor);\n };\n\n const [selectedCats, setSelectedCats] = useState<string[]>([]);\n const [catsExpanded, setCatsExpanded] = useState(false);\n // The model-provider filter is a single presence toggle (crit 1): on = show\n // only apps that declare a `modelProvider`. Off by default.\n const [onlyProviders, setOnlyProviders] = useState(false);\n\n // Single layout owner for all exits below, so the panel never resizes\n // between error/loading/empty and the loaded list — see `.w6w-apppicker-host`.\n const host = (body: ReactNode) => <div className=\"w6w-apppicker-host\">{body}</div>;\n\n // ── Resolve the raw app list for the active mode ───────────────────────────\n let rawApps: AppSummary[] | null;\n let fatalError: string | null = null;\n let loadingMore = false;\n let hasMore = false;\n let pageError: string | null = null;\n // Paged-only: true while a query change (search/category, INCLUDING the\n // very first mount) has reset `apps` and is awaiting its first page. Unlike\n // the non-paged modes' one-time `rawApps === null`, this must NOT hide the\n // search box/chip row on every subsequent search — only the initial mount\n // has no shell to preserve; every later keystroke should keep the input (and\n // whatever was already on screen) interactive while the new page loads.\n let pagedInitialLoading = false;\n\n if (supplied) {\n rawApps = providedApps ?? null;\n } else if (paged) {\n rawApps = pageState.apps;\n pagedInitialLoading = pageState.status === \"loading\";\n loadingMore = pageState.status === \"loading-more\";\n hasMore = pageState.hasMore;\n if (pageState.status === \"error\") {\n if (pageState.apps.length === 0) fatalError = pageState.error ?? \"Failed to load apps.\";\n else pageError = pageState.error ?? \"Failed to load apps.\";\n }\n } else {\n rawApps = fetchedApps;\n fatalError = legacyError;\n }\n\n if (!paged && fatalError) return host(<div className=\"w6w-result w6w-error\">{fatalError}</div>);\n if (!paged && rawApps === null) {\n return host(<p className=\"w6w-muted w6w-small\">Loading apps…</p>);\n }\n rawApps ??= [];\n\n // Reserved `@w6w/*` pseudo-apps are added via the builder's \"Controls\" tab, not\n // as connectable apps — keep them out of this grid even after they register.\n const connectable = excludeInternalApps(rawApps);\n const base = filter ? connectable.filter(filter) : connectable;\n\n // Non-paged modes (supplied / legacy eager fetch) preserve the ORIGINAL,\n // pre-T2.1.1 behavior byte-for-byte: a truly empty candidate list is an\n // early return with no search box at all — there is nothing a search could\n // ever surface. Paged mode never takes this branch: a bounded first page\n // that filtered down to nothing may still have more pages behind a search\n // or \"Load more\", so the search box (and the rest of the shell) must stay\n // reachable — see the `visible.length === 0` branches below instead.\n if (!paged && base.length === 0) {\n return host(\n <div className=\"w6w-stack\">\n <p className=\"w6w-muted w6w-small\">\n {emptyMessage ?? \"No apps registered yet. Register one from the Apps page first.\"}\n </p>\n {emptyAction}\n </div>,\n );\n }\n\n // Category chips (opt-in — P4/P6): derived from `base`, the VISIBLE\n // catalog post the `filter` prop and pre-search, never from the raw `apps`\n // fetch and never from the RFC's full slug vocabulary — a category with no\n // apps behind it here is a dead end. In paged mode this is necessarily\n // scoped to the currently-loaded page(s), not the whole catalog. Chips over\n // the collapse budget stay hidden unless already selected (P5), so toggling\n // a selection never makes its own chip disappear.\n const chips = categoryFilter ? deriveCategories(base) : [];\n const withinBudget = chips.slice(0, CHIP_VISIBLE_BUDGET);\n const pinnedOverflow = chips\n .slice(CHIP_VISIBLE_BUDGET)\n .filter((c) => selectedCats.includes(c.slug));\n const collapsedChips = [...withinBudget, ...pinnedOverflow];\n const hiddenChipCount = chips.length - collapsedChips.length;\n const displayedChips = catsExpanded ? chips : collapsedChips;\n const toggleCat = (slug: string) =>\n setSelectedCats((prev) =>\n prev.includes(slug) ? prev.filter((s) => s !== slug) : [...prev, slug],\n );\n const clearCats = () => setSelectedCats([]);\n\n // Model-provider filter (crit 1, A01/A02): derived from `base`, the visible\n // catalog post-`filter`, exactly like the category chips — and offered only\n // when something in it actually declares a provider, so the toggle is never\n // a dead end. Matching is on the PRESENCE of `modelProvider`, never on\n // `categories`: a category-`ai` app with no designation is not a provider\n // and never appears under this filter (nor carries a badge below).\n const designatedCount = base.filter((a) => modelProviderOf(a) !== null).length;\n const providerToggleVisible = providerFilter && designatedCount > 0;\n // A selection that outlives its own apps (the catalog changed under a\n // supplied list) falls back to \"all\" rather than stranding an empty list.\n const providerActive = providerToggleVisible && onlyProviders;\n const providerFiltered = providerActive ? base.filter((a) => modelProviderOf(a) !== null) : base;\n\n // Composition order (P4): the `filter` prop already ran (-> `base`); the\n // model-provider toggle and the category-chip selection compose next; the\n // search query runs last —\n // except in paged mode, where the search already happened server-side and\n // re-filtering locally on the (possibly stale, mid-debounce) input value\n // would just hide correct results for a beat.\n const catFiltered =\n categoryFilter && selectedCats.length > 0\n ? providerFiltered.filter((a) => matchesCategories(a, selectedCats))\n : providerFiltered;\n\n const sorted = paged\n ? catFiltered\n : [...catFiltered].sort((a, b) =>\n a.displayName.localeCompare(b.displayName, undefined, { sensitivity: \"base\" }),\n );\n // `q` drives LOCAL filtering only — empty in paged mode, since the server\n // already applied `inputValue` as its own `q` param. `searchActive` drives\n // message text and is always the user's real input, in every mode.\n const q = paged ? \"\" : inputValue.trim().toLowerCase();\n const searchActive = inputValue.trim().length > 0;\n const visible = q\n ? sorted.filter(\n (a) => a.displayName.toLowerCase().includes(q) || a.id.toLowerCase().includes(q),\n )\n : sorted;\n // A1 (U1/S3) — a CLIENT-side narrowing can drop cards the SERVER already\n // counted in `total`. There are exactly three such narrowings: the `filter`\n // prop, the model-provider toggle and a category-chip selection. None of\n // them reach the fetch, so `pageState.total` still includes what they hide,\n // and `N of total` would claim apps that are not on screen. When one of them\n // actually drops a card from the loaded pages, the footer reports the card\n // count alone — no denominator, no total that disagrees with the grid.\n //\n // Server-side narrowing (`ids`, `category`, `q`) needs none of this: the\n // page arrives already filtered, so `total` is the filtered total and the\n // footer reads `N of N`. The reserved-`@w6w/*` exclusion is deliberately not\n // counted here either — the footer's numerator is pinned to the page's own\n // app count (T3.1.1 A5), internal apps included.\n const clientFilterDroppedCards =\n (filter !== undefined && base.length !== connectable.length) ||\n (providerActive && providerFiltered.length !== base.length) ||\n (categoryFilter && selectedCats.length > 0 && catFiltered.length !== providerFiltered.length);\n // A7: a category and/or provider selection narrowed the list to nothing,\n // distinct from the search-only empty state below (and distinct from either\n // alone: the message names whichever of the two is actually active).\n const filtersEmpty =\n ((categoryFilter && selectedCats.length > 0) || providerActive) && visible.length === 0;\n const onlyProviderFilterActive = providerActive && selectedCats.length === 0;\n const clearAllFilters = () => {\n setSelectedCats([]);\n setOnlyProviders(false);\n setInputValue(\"\");\n };\n\n return host(\n <div className=\"w6w-stepbuilder-apps\">\n {search && (\n <input\n type=\"text\"\n className=\"w6w-stepbuilder-search\"\n placeholder={searchPlaceholder ?? \"Search apps…\"}\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n aria-label=\"Search apps\"\n />\n )}\n {(providerToggleVisible || (categoryFilter && chips.length > 0)) && (\n <div className=\"w6w-apppicker-cats\">\n {providerToggleVisible && (\n <button\n type=\"button\"\n className=\"w6w-apppicker-chip w6w-apppicker-provider-toggle\"\n aria-pressed={onlyProviders}\n aria-label=\"Filter to model providers\"\n onClick={() => setOnlyProviders((prev) => !prev)}\n >\n Model providers <span className=\"w6w-muted\">({designatedCount})</span>\n </button>\n )}\n {categoryFilter && chips.length > 0 && (\n <>\n {displayedChips.map((c) => (\n <button\n key={c.slug}\n type=\"button\"\n className=\"w6w-apppicker-chip\"\n aria-pressed={selectedCats.includes(c.slug)}\n aria-label={`Filter by ${c.label}`}\n onClick={() => toggleCat(c.slug)}\n >\n {c.label} <span className=\"w6w-muted\">({c.count})</span>\n </button>\n ))}\n {!catsExpanded && hiddenChipCount > 0 && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n onClick={() => setCatsExpanded(true)}\n >\n +{hiddenChipCount} more\n </button>\n )}\n {catsExpanded && chips.length > CHIP_VISIBLE_BUDGET && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n onClick={() => setCatsExpanded(false)}\n >\n Show less\n </button>\n )}\n {selectedCats.length > 0 && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n onClick={clearCats}\n >\n Clear\n </button>\n )}\n </>\n )}\n </div>\n )}\n {paged && pagedInitialLoading ? (\n <p className=\"w6w-muted w6w-small\">Loading apps…</p>\n ) : paged && fatalError ? (\n <div className=\"w6w-result w6w-error\">\n {fatalError}{\" \"}\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\" onClick={retry}>\n Retry\n </button>\n </div>\n ) : visible.length === 0 && !hasMore ? (\n filtersEmpty ? (\n <div className=\"w6w-stack\">\n <p className=\"w6w-muted w6w-small\">\n {onlyProviderFilterActive\n ? searchActive\n ? `No model providers match “${inputValue}”.`\n : \"No apps declare a model provider.\"\n : searchActive\n ? `No apps match “${inputValue}” in the selected categories.`\n : \"No apps match the selected categories.\"}\n </p>\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n onClick={clearAllFilters}\n >\n Clear filters\n </button>\n </div>\n ) : !paged ? (\n // Original, unchanged text: reachable here only with a non-empty\n // query (an empty-query empty result was already handled by the\n // `base.length === 0` early return above, for this non-paged path).\n <p className=\"w6w-muted w6w-small\">No apps match “{inputValue}”.</p>\n ) : (\n <div className=\"w6w-stack\">\n <p className=\"w6w-muted w6w-small\">\n {searchActive\n ? `No apps match “${inputValue}”.`\n : (emptyMessage ??\n \"No apps registered yet. Register one from the Apps page first.\")}\n </p>\n {!searchActive && emptyAction}\n </div>\n )\n ) : (\n <>\n {visible.length === 0 && hasMore ? (\n // A page loaded but every entry was filtered out client-side\n // (internal/rejected/non-trigger/etc.) — never auto-drain the\n // next page to fill this in; the user's own \"Load more\" click is\n // the only thing allowed to fetch further.\n <p className=\"w6w-muted w6w-small\">\n No matching apps on this page yet — try “Load more”.\n </p>\n ) : (\n <div className=\"w6w-stepbuilder-list w6w-apppicker-grid w6w-stepbuilder-scroll\">\n {visible.map((a) => {\n const bridgeEntry = bridgeSupport?.get(a.id);\n const bridge = bridgeSupportChip(bridgeEntry);\n return (\n <button\n key={a.id}\n type=\"button\"\n className=\"w6w-stepbuilder-item w6w-apppicker-card\"\n onClick={() => onSelectApp(a)}\n >\n <AppIcon\n src={a.iconSvg}\n srcDark={a.iconSvgDark}\n brandColor={a.brandColor}\n name={a.displayName}\n theme={theme}\n size={24}\n />\n <span className=\"w6w-stepbuilder-item-main\">\n <strong>{a.displayName}</strong>\n {/* The id is secondary metadata under the NAME, and it is the one\n field on this card with no length bound (`vendor-app-…`, a\n `@`-scoped id, a long slug), so it truncates rather than\n widening the card or wrapping to a second line — the tile's\n geometry is fixed by the grid, not by its longest id. */}\n <code className=\"w6w-apppicker-card-id\">{a.id}</code>\n {a.version && (\n <span className=\"w6w-apppicker-card-version\">v{a.version}</span>\n )}\n {/* Bridge-support chip (A6): host-supplied, one entry per\n app id — nothing is derived from `designation` or\n `adapter` here, because the host owns the descriptor\n and this package never fetches. No entry, no chip. */}\n {bridge && (\n <span\n className={\n bridgeEntry?.supported\n ? \"w6w-chip w6w-apppicker-card-bridge\"\n : \"w6w-chip w6w-apppicker-card-bridge w6w-apppicker-card-bridge-unsupported\"\n }\n title={bridge.title}\n >\n {bridge.text}\n </span>\n )}\n </span>\n </button>\n );\n })}\n </div>\n )}\n {paged && typeof pageState.total === \"number\" && (\n <div className=\"w6w-small w6w-apppicker-count\">\n {clientFilterDroppedCards\n ? `${visible.length} ${visible.length === 1 ? \"app\" : \"apps\"}`\n : `${pageState.apps.length} of ${pageState.total}`}\n </div>\n )}\n {paged && pageError && (\n <div className=\"w6w-result w6w-error w6w-small\">\n {pageError}{\" \"}\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\" onClick={retry}>\n Retry\n </button>\n </div>\n )}\n {paged && hasMore && !pageError && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm w6w-apppicker-load-more\"\n onClick={loadMore}\n disabled={loadingMore}\n >\n {loadingMore ? \"Loading more…\" : \"Load more\"}\n </button>\n )}\n </>\n )}\n </div>,\n );\n}\n","import type { ComponentProps } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\n\nexport interface MarkdownProps {\n content: string;\n className?: string;\n}\n\n/** The only link protocols a note may carry. An allowlist — never a blocklist. */\nconst ALLOWED_PROTOCOLS = new Set([\"http:\", \"https:\", \"mailto:\"]);\n\n/**\n * Pass a URL through only when its *parsed* protocol is allowlisted; relative,\n * unparseable and every other scheme (javascript:, data:, vbscript:, any casing\n * or whitespace trick the URL parser normalises) collapse to \"\".\n */\nexport function safeUrl(url: string): string {\n try {\n return ALLOWED_PROTOCOLS.has(new URL(url).protocol) ? url : \"\";\n } catch {\n return \"\";\n }\n}\n\nconst DISALLOWED_ELEMENTS = [\"img\"];\n\nfunction SafeLink({\n node: _node,\n href,\n children,\n ...rest\n}: ComponentProps<\"a\"> & { node?: unknown }) {\n return (\n <a {...rest} href={href || undefined} target=\"_blank\" rel=\"noopener noreferrer nofollow\">\n {children}\n </a>\n );\n}\n\n/**\n * A leading `---` YAML block and the Markdown after it. Rendered as Markdown the block would\n * come out as a rule plus a heading; it is metadata, so `Markdown` shows it in a collapsed\n * section instead. Kept as text, not parsed — this package carries no YAML parser.\n */\nexport function splitFrontmatter(text: string): { frontmatter: string | null; body: string } {\n const m = /^\\uFEFF?---\\r?\\n([\\s\\S]*?)\\r?\\n---[ \\t]*(?:\\r?\\n|$)/.exec(text);\n if (!m) return { frontmatter: null, body: text };\n return { frontmatter: m[1], body: text.slice(m[0].length) };\n}\n\n/** Collapsed by default: metadata about the document, not part of what it says. */\nfunction Frontmatter({ yaml }: { yaml: string }) {\n return (\n <details className=\"w6w-md-frontmatter\" data-testid=\"md-frontmatter\">\n <summary>Frontmatter</summary>\n <pre>\n <code>{yaml}</code>\n </pre>\n </details>\n );\n}\n\n/**\n * Renders imported, attacker-controllable note content. No `rehype-raw`: raw HTML\n * is dropped (`skipHtml`), images are not rendered, and links are protocol-allowlisted.\n * A leading YAML frontmatter block becomes a collapsed section above the body.\n */\nexport function Markdown({ content, className }: MarkdownProps) {\n const { frontmatter, body } = splitFrontmatter(content);\n return (\n <div className={className}>\n {frontmatter?.trim() && <Frontmatter yaml={frontmatter} />}\n <ReactMarkdown\n skipHtml\n urlTransform={safeUrl}\n disallowedElements={DISALLOWED_ELEMENTS}\n unwrapDisallowed\n components={{ a: SafeLink }}\n >\n {body}\n </ReactMarkdown>\n </div>\n );\n}\n","/**\n * The note editor's Markdown round-trip. A note is edited in place as a `contentEditable` block\n * (no textarea); these two functions convert between its stored Markdown and that editable DOM.\n *\n * The editable model is line-based and covers exactly what the note toolbar writes: a heading\n * level per line (`#`…`######`) and `**bold**` runs. Everything else (links, lists, `code`, …) is\n * kept as literal text while editing and rendered by `Markdown` when not, so a line the toolbar\n * never touched round-trips byte-for-byte.\n *\n * The DOM is built with `createElement` + text nodes only — note content is imported,\n * attacker-controllable text and must never reach `innerHTML`.\n */\n\ninterface Run {\n text: string;\n bold: boolean;\n}\ninterface Line {\n level: number;\n runs: Run[];\n}\n\nconst HEADING = /^(#{1,6})\\s+(.*)$/;\nconst BOLD = /\\*\\*(?=\\S)(.+?)(?<=\\S)\\*\\*/g;\n\n/** Build the editable DOM for `content` into `root` (its children are replaced). */\nexport function renderEditable(root: HTMLElement, content: string): void {\n const doc = root.ownerDocument;\n root.replaceChildren();\n for (const raw of content.split(\"\\n\")) {\n const m = HEADING.exec(raw);\n const block = doc.createElement(m ? `h${m[1].length}` : \"div\");\n const text = m ? m[2] : raw;\n let at = 0;\n for (const b of text.matchAll(BOLD)) {\n if (b.index > at) block.append(doc.createTextNode(text.slice(at, b.index)));\n const strong = doc.createElement(\"strong\");\n strong.textContent = b[1];\n block.append(strong);\n at = b.index + b[0].length;\n }\n if (at < text.length) block.append(doc.createTextNode(text.slice(at)));\n if (!block.firstChild) block.append(doc.createElement(\"br\"));\n root.append(block);\n }\n}\n\nfunction weight(el: HTMLElement): boolean | undefined {\n const w = el.style?.fontWeight;\n if (!w) return undefined;\n if (w === \"bold\" || w === \"bolder\") return true;\n const n = Number(w);\n return Number.isFinite(n) ? n >= 600 : false;\n}\n\nfunction runText(runs: Run[]): string {\n const merged: Run[] = [];\n for (const r of runs) {\n const last = merged[merged.length - 1];\n if (last && last.bold === r.bold) last.text += r.text;\n else merged.push({ ...r });\n }\n return merged\n .map(({ text, bold }) => {\n const core = text.trim();\n if (!bold || !core) return text;\n const lead = text.slice(0, text.indexOf(core));\n const trail = text.slice(lead.length + core.length);\n return `${lead}**${core}**${trail}`;\n })\n .join(\"\");\n}\n\n/** Serialize the editable DOM under `root` back to Markdown. */\nexport function editableToMarkdown(root: HTMLElement): string {\n const lines: Line[] = [];\n let cur: Line | null = null;\n const open = (level: number) => {\n cur = { level, runs: [] };\n lines.push(cur);\n return cur;\n };\n const walk = (node: Node, level: number, bold: boolean) => {\n if (node.nodeType === 3) {\n const t = (node.textContent ?? \"\").replace(/ /g, \" \").replace(/\\n/g, \"\");\n if (t) (cur ?? open(level)).runs.push({ text: t, bold });\n return;\n }\n if (node.nodeType !== 1) return;\n const el = node as HTMLElement;\n const tag = el.tagName.toLowerCase();\n if (tag === \"br\") {\n if (!cur) open(level);\n cur = null;\n return;\n }\n const heading = /^h([1-6])$/.exec(tag);\n const block = heading || [\"div\", \"p\", \"li\", \"ul\", \"ol\", \"blockquote\", \"pre\"].includes(tag);\n if (block) cur = null;\n const lvl = heading ? Number(heading[1]) : level;\n const b = tag === \"b\" || tag === \"strong\" ? true : (weight(el) ?? bold);\n for (const child of el.childNodes) walk(child, lvl, b);\n if (block) cur = null;\n };\n for (const child of root.childNodes) walk(child, 0, false);\n const out = lines.map((l) => {\n const text = runText(l.runs);\n return l.level > 0 ? `${\"#\".repeat(l.level)} ${text.trimStart()}` : text;\n });\n while (out.length && out[out.length - 1].trim() === \"\") out.pop();\n return out.join(\"\\n\");\n}\n\n/**\n * The content handed to `Markdown` for display. A note is typed line by line, so a single\n * newline must show as a line break — Markdown would fold it into a space. A soft break between\n * two non-empty lines becomes a hard break (two trailing spaces); the stored content is untouched.\n */\nexport function noteDisplayMarkdown(content: string): string {\n return content.replace(/([^\\n])\\n(?=[^\\n])/g, \"$1 \\n\");\n}\n","import { useStore } from \"@xyflow/react\";\nimport {\n type CSSProperties,\n type PointerEvent as ReactPointerEvent,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Markdown } from \"./Markdown.tsx\";\nimport type { CanvasNote, CanvasSection, FlowCanvas } from \"./canvas-types.ts\";\nimport { Icon } from \"./components/Icon.tsx\";\nimport { editableToMarkdown, noteDisplayMarkdown, renderEditable } from \"./note-markdown.ts\";\n\nexport interface CanvasLayerProps {\n canvas: FlowCanvas;\n savePosition?: boolean;\n /** Fired ONCE per finished edit (drop / blur / colour pick / format), never per frame. */\n onChange?: (canvas: FlowCanvas) => void;\n /**\n * Fired once when a section is dropped after a drag, so the host can move the members by the\n * same delta. When omitted, only the section's own position changes (via `onChange`).\n */\n onSectionDrop?: (id: string, delta: { dx: number; dy: number }) => void;\n /** Ask the host to confirm-then-delete a note or section (the layer never deletes itself). */\n onRequestDelete?: (kind: \"note\" | \"section\", id: string) => void;\n /** Hides every control and disables drag. */\n readOnly?: boolean;\n /** Flow zoom, to turn screen-pixel drags into flow units. Resolved from the store in a flow. */\n zoom?: number;\n className?: string;\n /**\n * The element to portal into. Omit inside a React Flow: the enclosing flow's\n * `.react-flow__viewport` is resolved from its DOM ref. Pass explicitly (tests, stories).\n */\n viewport?: Element | null;\n}\n\nexport const SECTIONS_Z_INDEX = -2;\nexport const NOTES_Z_INDEX = -1;\n/** The selected note's or section's toolbar sits above nodes and edges, unlike the box itself. */\nexport const NOTE_TOOLBAR_Z_INDEX = 1000;\n\n/** The note colour palette offered by the toolbar (a custom colour is still accepted). */\nexport const NOTE_COLORS = [\n \"#facc15\",\n \"#fb923c\",\n \"#f87171\",\n \"#f472b6\",\n \"#a78bfa\",\n \"#60a5fa\",\n \"#2dd4bf\",\n \"#4ade80\",\n \"#9ca3af\",\n];\n\n/** Text sizes the toolbar writes, as Markdown heading levels (0 = body text). */\nconst TEXT_SIZES = [\n { level: 1, label: \"Title\" },\n { level: 2, label: \"Heading\" },\n { level: 3, label: \"Subheading\" },\n { level: 0, label: \"Body\" },\n];\n\nconst MIN_W = 80;\nconst MIN_H = 48;\nconst TOOLBAR_GAP = 10;\nconst LABEL_GAP = 4;\nconst stop = (e: { stopPropagation: () => void }) => e.stopPropagation();\n\ntype Geo = { x: number; y: number; w: number; h: number };\ntype Drag = {\n kind: \"note\" | \"section\";\n id: string;\n mode: \"move\" | \"resize\";\n sx: number;\n sy: number;\n base: Geo;\n dx: number;\n dy: number;\n};\n\n/** Select the whole editable so a toolbar format applies to the entire note. */\nfunction selectAll(el: HTMLElement) {\n const sel = el.ownerDocument.getSelection();\n if (!sel) return;\n const range = el.ownerDocument.createRange();\n range.selectNodeContents(el);\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\nfunction caretToEnd(el: HTMLElement) {\n const sel = el.ownerDocument.getSelection();\n if (!sel) return;\n const range = el.ownerDocument.createRange();\n range.selectNodeContents(el);\n range.collapse(false);\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\nfunction Layers({\n canvas,\n className,\n viewport,\n readOnly,\n zoom = 1,\n onChange,\n onSectionDrop,\n onRequestDelete,\n}: CanvasLayerProps & { viewport: Element | null }) {\n const [live, setLive] = useState<Record<string, Geo>>({});\n const [selectedNote, setSelectedNote] = useState<string | null>(null);\n const [selectedSection, setSelectedSection] = useState<string | null>(null);\n const [editingNote, setEditingNote] = useState<string | null>(null);\n const [menu, setMenu] = useState<\"color\" | \"size\" | null>(null);\n const drag = useRef<Drag | null>(null);\n const editor = useRef<HTMLElement | null>(null);\n // A format picked while NOT editing: run once the editor has mounted, over the whole note.\n const pendingFormat = useRef<(() => void) | null>(null);\n\n // A press anywhere outside the selected note or section and its toolbar deselects it.\n useEffect(() => {\n if (!selectedNote && !selectedSection) return;\n const inside = selectedNote\n ? `[data-note-id=\"${selectedNote}\"], [data-note-toolbar=\"${selectedNote}\"]`\n : `[data-section-label=\"${selectedSection}\"], [data-section-toolbar=\"${selectedSection}\"]`;\n const onDown = (e: PointerEvent) => {\n const t = e.target as Element | null;\n if (t?.closest?.(inside)) return;\n // The toolbar unmounts before focus moves, so commit a title being typed first.\n const active = document.activeElement as HTMLElement | null;\n if (active?.closest?.(\"[data-section-toolbar]\")) active.blur();\n setSelectedNote(null);\n setSelectedSection(null);\n setMenu(null);\n };\n window.addEventListener(\"pointerdown\", onDown, true);\n return () => window.removeEventListener(\"pointerdown\", onDown, true);\n }, [selectedNote, selectedSection]);\n\n if (!viewport) return null;\n const editable = !readOnly && !!onChange;\n const sections: CanvasSection[] = canvas.sections ?? [];\n const notes: CanvasNote[] = canvas.notes ?? [];\n const geoOf = (b: CanvasNote | CanvasSection): Geo =>\n live[b.id] ?? { x: b.position.x, y: b.position.y, w: b.size.width, h: b.size.height };\n const boxStyle = (b: CanvasNote | CanvasSection): CSSProperties => {\n const g = geoOf(b);\n return {\n left: g.x,\n top: g.y,\n width: g.w,\n height: g.h,\n [\"--w6w-canvas-color\" as string]: b.color,\n };\n };\n const patchNote = (id: string, patch: Partial<CanvasNote>) =>\n onChange?.({ ...canvas, notes: notes.map((n) => (n.id === id ? { ...n, ...patch } : n)) });\n const patchSection = (id: string, patch: Partial<CanvasSection>) =>\n onChange?.({\n ...canvas,\n sections: sections.map((s) => (s.id === id ? { ...s, ...patch } : s)),\n });\n\n // Write the editor's Markdown back, when it differs from what is stored.\n const commitNote = (id: string) => {\n const el = editor.current;\n const note = notes.find((n) => n.id === id);\n if (!el?.isConnected || !note) return;\n const md = editableToMarkdown(el);\n if (md !== note.content) patchNote(id, { content: md });\n };\n const selectNote = (id: string) => {\n setSelectedSection(null);\n setSelectedNote(id);\n };\n const selectSection = (id: string) => {\n setSelectedNote(null);\n setSelectedSection(id);\n };\n const startEdit = (id: string, then?: () => void) => {\n pendingFormat.current = then ?? null;\n selectNote(id);\n setEditingNote(id);\n setMenu(null);\n };\n // Mounts the editable once per edit session: the DOM is owned by the browser while editing,\n // so React renders the element empty and never reconciles its children.\n const editorRef = (n: CanvasNote) => (el: HTMLDivElement | null) => {\n if (!el || el.dataset.ready === \"1\") return;\n el.dataset.ready = \"1\";\n editor.current = el;\n renderEditable(el, n.content);\n el.focus();\n const then = pendingFormat.current;\n pendingFormat.current = null;\n if (then) {\n selectAll(el);\n then();\n commitNote(n.id);\n } else caretToEnd(el);\n };\n /** Apply a `document.execCommand` format to the note — its selection, or all of it. */\n const format = (id: string, command: string, arg?: string) => {\n setMenu(null);\n const run = () => document.execCommand(command, false, arg);\n if (editingNote === id && editor.current?.isConnected) {\n run();\n commitNote(id);\n } else startEdit(id, run);\n };\n\n const frame = (d: Drag): Geo =>\n d.mode === \"move\"\n ? { ...d.base, x: d.base.x + d.dx, y: d.base.y + d.dy }\n : { ...d.base, w: Math.max(MIN_W, d.base.w + d.dx), h: Math.max(MIN_H, d.base.h + d.dy) };\n\n const begin = (\n e: ReactPointerEvent,\n b: CanvasNote | CanvasSection,\n kind: Drag[\"kind\"],\n mode: Drag[\"mode\"],\n ) => {\n if (!editable || e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n const d: Drag = {\n kind,\n id: b.id,\n mode,\n sx: e.clientX,\n sy: e.clientY,\n base: geoOf(b),\n dx: 0,\n dy: 0,\n };\n drag.current = d;\n const move = (ev: PointerEvent) => {\n d.dx = (ev.clientX - d.sx) / (zoom || 1);\n d.dy = (ev.clientY - d.sy) / (zoom || 1);\n setLive((l) => ({ ...l, [d.id]: frame(d) }));\n };\n const up = () => {\n window.removeEventListener(\"pointermove\", move);\n window.removeEventListener(\"pointerup\", up);\n drag.current = null;\n setLive((l) => {\n const { [d.id]: _gone, ...rest } = l;\n return rest;\n });\n if (d.dx === 0 && d.dy === 0) return;\n const g = frame(d);\n const geo = {\n position: { x: g.x, y: g.y },\n size: { width: g.w, height: g.h },\n };\n if (d.kind === \"section\" && d.mode === \"move\" && onSectionDrop) {\n onSectionDrop(d.id, { dx: d.dx, dy: d.dy });\n } else if (d.kind === \"note\") patchNote(d.id, geo);\n else patchSection(d.id, geo);\n };\n window.addEventListener(\"pointermove\", move);\n window.addEventListener(\"pointerup\", up);\n };\n\n const cls = className ? ` ${className}` : \"\";\n const noInteract = \"nopan nodrag nowheel\";\n const toolbarNote = editable ? notes.find((n) => n.id === selectedNote) : undefined;\n const toolbarSection = editable ? sections.find((s) => s.id === selectedSection) : undefined;\n const z = zoom || 1;\n const toolbarStyle = (n: CanvasNote): CSSProperties => {\n const g = geoOf(n);\n // Anchored at the note's top-centre in flow units, then counter-scaled so the toolbar keeps\n // its screen size at every zoom (scaling about its own bottom-centre keeps it anchored).\n return {\n left: g.x + g.w / 2,\n top: g.y,\n transform: `translate(-50%, calc(-100% - ${TOOLBAR_GAP / z}px)) scale(${1 / z})`,\n transformOrigin: \"50% 100%\",\n [\"--w6w-canvas-color\" as string]: n.color,\n };\n };\n // A section's label and its toolbar share one spot: just above the frame's top-left corner,\n // counter-scaled the same way about their bottom-left.\n const aboveFrame = (s: CanvasSection, gap: number): CSSProperties => {\n const g = geoOf(s);\n return {\n left: g.x,\n top: g.y,\n transform: `translate(0, calc(-100% - ${gap / z}px)) scale(${1 / z})`,\n transformOrigin: \"0 100%\",\n [\"--w6w-canvas-color\" as string]: s.color,\n };\n };\n const colorMenu = (\n current: string,\n label: string,\n testid: string,\n pick: (color: string) => void,\n ) => (\n <div className=\"w6w-note-menu w6w-note-menu-colors\" role=\"menu\">\n {NOTE_COLORS.map((c) => (\n <button\n key={c}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={c === current}\n aria-label={`Colour ${c}`}\n title={c}\n className={`w6w-note-swatch-btn${c === current ? \" active\" : \"\"}`}\n style={{ [\"--w6w-canvas-color\" as string]: c }}\n data-testid={`${testid}-option`}\n data-color={c}\n onClick={() => {\n setMenu(null);\n if (c !== current) pick(c);\n }}\n />\n ))}\n <label className=\"w6w-note-swatch-btn w6w-note-swatch-custom\" title=\"Custom\">\n <input\n type=\"color\"\n aria-label={`Custom ${label} colour`}\n data-testid={`${testid}-input`}\n value={current}\n onChange={(e) => pick(e.currentTarget.value)}\n />\n </label>\n </div>\n );\n // Every press on a toolbar is kept from taking focus (so a note format applies to the editor's\n // own selection instead of blurring it away), except in its inputs.\n const keepFocus = (e: { target: EventTarget; preventDefault: () => void }) => {\n if (!(e.target as Element).closest(\"input\")) e.preventDefault();\n };\n return createPortal(\n <>\n <div\n className={`w6w-canvas-layer w6w-canvas-sections${cls}`}\n style={{ zIndex: SECTIONS_Z_INDEX }}\n data-testid=\"w6w-canvas-sections\"\n >\n {sections.map((s) => (\n <div\n key={s.id}\n className={`w6w-canvas-section${selectedSection === s.id ? \" selected\" : \"\"}`}\n style={boxStyle(s)}\n data-section-id={s.id}\n data-testid=\"section\"\n >\n {editable && (\n <div\n className={`w6w-note-resize ${noInteract}`}\n data-testid=\"section-resize\"\n onPointerDown={(e) => begin(e, s, \"section\", \"resize\")}\n />\n )}\n </div>\n ))}\n {/* The label sits outside its frame, above the top-left corner; the toolbar takes its\n place while the section is selected. */}\n {sections.map((s) =>\n toolbarSection?.id === s.id ? null : (\n <div\n key={s.id}\n className={`w6w-canvas-section-title${editable ? ` editable ${noInteract}` : \"\"}`}\n style={aboveFrame(s, LABEL_GAP)}\n data-section-label={s.id}\n data-testid=\"section-label\"\n title={editable ? \"Click to edit · drag to move\" : undefined}\n onPointerDown={\n editable\n ? (e) => {\n selectSection(s.id);\n begin(e, s, \"section\", \"move\");\n }\n : undefined\n }\n >\n {s.title || (editable ? \"Untitled section\" : \"\")}\n </div>\n ),\n )}\n </div>\n <div\n className={`w6w-canvas-layer w6w-canvas-notes${cls}`}\n style={{ zIndex: NOTES_Z_INDEX }}\n data-testid=\"w6w-canvas-notes\"\n >\n {notes.map((n) => {\n const editing = editable && editingNote === n.id;\n return (\n <div\n key={n.id}\n className={`w6w-canvas-note${selectedNote === n.id ? \" selected\" : \"\"}`}\n style={boxStyle(n)}\n data-note-id={n.id}\n data-testid=\"note\"\n >\n {/* Distinct keys: the editor's DOM is browser-owned, so it must never be a node React\n reuses for the rendered view (or the other way round). */}\n {editing ? (\n <div\n key=\"editor\"\n ref={editorRef(n)}\n className={`w6w-canvas-note-body w6w-canvas-note-editor ${noInteract}`}\n contentEditable\n suppressContentEditableWarning\n role=\"textbox\"\n tabIndex={0}\n aria-multiline=\"true\"\n aria-label=\"Note content\"\n data-testid=\"note-content\"\n onPointerDown={stop}\n onBlur={() => {\n commitNote(n.id);\n editor.current = null;\n setEditingNote(null);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") e.currentTarget.blur();\n }}\n onPaste={(e) => {\n // Plain text only: pasted HTML would bring markup the Markdown can't hold.\n e.preventDefault();\n document.execCommand(\n \"insertText\",\n false,\n e.clipboardData.getData(\"text/plain\"),\n );\n }}\n />\n ) : (\n <div\n key=\"view\"\n className={`w6w-canvas-note-body ${noInteract}`}\n data-testid=\"note-view\"\n style={editable ? { cursor: \"grab\", touchAction: \"none\" } : undefined}\n onPointerDown={\n editable\n ? (e) => {\n selectNote(n.id);\n begin(e, n, \"note\", \"move\");\n }\n : undefined\n }\n onDoubleClick={editable ? () => startEdit(n.id) : undefined}\n >\n {n.content.trim() ? (\n <Markdown content={noteDisplayMarkdown(n.content)} />\n ) : (\n editable && <span className=\"w6w-canvas-note-empty\">Double-click to write</span>\n )}\n </div>\n )}\n {editable && (\n <div\n className={`w6w-note-resize ${noInteract}`}\n data-testid=\"note-resize\"\n onPointerDown={(e) => begin(e, n, \"note\", \"resize\")}\n />\n )}\n </div>\n );\n })}\n </div>\n {toolbarSection && (\n <div\n className={`w6w-canvas-layer${cls}`}\n style={{ zIndex: NOTE_TOOLBAR_Z_INDEX }}\n data-testid=\"w6w-canvas-overlay\"\n >\n <div\n className={`w6w-note-toolbar w6w-section-toolbar ${noInteract}`}\n role=\"toolbar\"\n aria-label=\"Section\"\n data-testid=\"section-toolbar\"\n data-section-toolbar={toolbarSection.id}\n style={aboveFrame(toolbarSection, TOOLBAR_GAP)}\n onPointerDown={stop}\n onMouseDown={keepFocus}\n >\n <button\n type=\"button\"\n className=\"w6w-icon-btn w6w-note-grip\"\n aria-label=\"Move section\"\n title=\"Drag to move\"\n data-testid=\"section-drag\"\n onPointerDown={(e) => begin(e, toolbarSection, \"section\", \"move\")}\n >\n <Icon name=\"grip\" />\n </button>\n <input\n type=\"text\"\n className=\"w6w-section-title-input\"\n aria-label=\"Section title\"\n placeholder=\"Untitled section\"\n data-testid=\"section-title\"\n defaultValue={toolbarSection.title}\n key={`${toolbarSection.id}:${toolbarSection.title}`}\n size={Math.max(8, Math.min(32, toolbarSection.title.length + 1))}\n onBlur={(e) => {\n const v = e.currentTarget.value;\n if (v !== toolbarSection.title) patchSection(toolbarSection.id, { title: v });\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \"Escape\") e.currentTarget.blur();\n }}\n />\n <span className=\"w6w-note-toolbar-sep\" />\n <div className=\"w6w-note-toolbar-group\">\n <button\n type=\"button\"\n className={`w6w-icon-btn${menu === \"color\" ? \" active\" : \"\"}`}\n aria-label=\"Section colour\"\n aria-expanded={menu === \"color\"}\n title=\"Colour\"\n data-testid=\"section-color\"\n onClick={() => setMenu(menu === \"color\" ? null : \"color\")}\n >\n <span className=\"w6w-note-swatch\" />\n <Icon name=\"chevron-down\" size={12} />\n </button>\n {menu === \"color\" &&\n colorMenu(toolbarSection.color, \"section\", \"section-color\", (c) =>\n patchSection(toolbarSection.id, { color: c }),\n )}\n </div>\n <span className=\"w6w-note-toolbar-sep\" />\n <button\n type=\"button\"\n className=\"w6w-icon-btn w6w-note-delete\"\n aria-label=\"Delete section\"\n title=\"Delete section\"\n data-testid=\"section-delete\"\n onClick={() => {\n setMenu(null);\n onRequestDelete?.(\"section\", toolbarSection.id);\n }}\n >\n <Icon name=\"trash\" />\n </button>\n </div>\n </div>\n )}\n {toolbarNote && (\n <div\n className={`w6w-canvas-layer${cls}`}\n style={{ zIndex: NOTE_TOOLBAR_Z_INDEX }}\n data-testid=\"w6w-canvas-overlay\"\n >\n <div\n className={`w6w-note-toolbar ${noInteract}`}\n role=\"toolbar\"\n aria-label=\"Note\"\n data-testid=\"note-toolbar\"\n data-note-toolbar={toolbarNote.id}\n style={toolbarStyle(toolbarNote)}\n onPointerDown={stop}\n onMouseDown={keepFocus}\n >\n <button\n type=\"button\"\n className=\"w6w-icon-btn w6w-note-grip\"\n aria-label=\"Move note\"\n title=\"Drag to move\"\n data-testid=\"note-drag\"\n onPointerDown={(e) => begin(e, toolbarNote, \"note\", \"move\")}\n >\n <Icon name=\"grip\" />\n </button>\n <span className=\"w6w-note-toolbar-sep\" />\n <div className=\"w6w-note-toolbar-group\">\n <button\n type=\"button\"\n className={`w6w-icon-btn${menu === \"color\" ? \" active\" : \"\"}`}\n aria-label=\"Note colour\"\n aria-expanded={menu === \"color\"}\n title=\"Colour\"\n data-testid=\"note-color\"\n onClick={() => setMenu(menu === \"color\" ? null : \"color\")}\n >\n <span className=\"w6w-note-swatch\" />\n <Icon name=\"chevron-down\" size={12} />\n </button>\n {menu === \"color\" &&\n colorMenu(toolbarNote.color, \"note\", \"note-color\", (c) =>\n patchNote(toolbarNote.id, { color: c }),\n )}\n </div>\n <span className=\"w6w-note-toolbar-sep\" />\n <div className=\"w6w-note-toolbar-group\">\n <button\n type=\"button\"\n className={`w6w-icon-btn w6w-note-size-btn${menu === \"size\" ? \" active\" : \"\"}`}\n aria-label=\"Text size\"\n aria-expanded={menu === \"size\"}\n title=\"Text size\"\n data-testid=\"note-size\"\n onClick={() => setMenu(menu === \"size\" ? null : \"size\")}\n >\n Aa\n <Icon name=\"chevron-down\" size={12} />\n </button>\n {menu === \"size\" && (\n <div className=\"w6w-note-menu w6w-note-menu-sizes\" role=\"menu\">\n {TEXT_SIZES.map((s) => (\n <button\n key={s.level}\n type=\"button\"\n role=\"menuitem\"\n className={`w6w-note-menu-item w6w-note-size-${s.level}`}\n data-testid={`note-size-${s.level}`}\n onClick={() =>\n format(toolbarNote.id, \"formatBlock\", s.level ? `<h${s.level}>` : \"<div>\")\n }\n >\n {s.label}\n </button>\n ))}\n </div>\n )}\n </div>\n <button\n type=\"button\"\n className=\"w6w-icon-btn\"\n aria-label=\"Bold\"\n title=\"Bold\"\n data-testid=\"note-bold\"\n onClick={() => format(toolbarNote.id, \"bold\")}\n >\n <Icon name=\"bold\" />\n </button>\n <span className=\"w6w-note-toolbar-sep\" />\n <button\n type=\"button\"\n className=\"w6w-icon-btn w6w-note-delete\"\n aria-label=\"Delete note\"\n title=\"Delete note\"\n data-testid=\"note-delete\"\n onClick={() => {\n setMenu(null);\n onRequestDelete?.(\"note\", toolbarNote.id);\n }}\n >\n <Icon name=\"trash\" />\n </button>\n </div>\n </div>\n )}\n </>,\n viewport,\n );\n}\n\nfunction FlowResolved(props: CanvasLayerProps) {\n const viewport = useStore((s) => s.domNode?.querySelector(\".react-flow__viewport\") ?? null);\n const zoom = useStore((s) => s.transform[2]);\n return <Layers {...props} zoom={props.zoom ?? zoom} viewport={viewport} />;\n}\n\n/**\n * Sections (z -2) and notes (z -1) rendered behind edges/nodes, inside the flow viewport; the\n * selected note's or section's toolbar floats above everything.\n */\nexport function CanvasLayer(props: CanvasLayerProps) {\n if (props.viewport !== undefined) {\n return <Layers {...props} viewport={props.viewport} />;\n }\n return <FlowResolved {...props} />;\n}\n","/**\n * The ONE `EditorView.theme` spec shared by the three CodeMirror editors\n * (`JsonEditor`, `CodeEditor`, `YamlEditor`) — previously copy-pasted verbatim\n * into each of them.\n *\n * Plain object, **no imports**, so `node --test` asserts it directly. Every\n * colour/spacing value is a `--w6w-*` custom property so the editors inherit\n * the consumer's palette.\n *\n * Focus mirrors `styles/_fields.scss` (`.w6w-field input:focus { outline: none;\n * border-color: var(--w6w-accent) }`) instead of drawing an accent ring. The\n * rule must STAY with an explicit `outline: \"none\"` — deleting it falls back to\n * CodeMirror's base theme (`outline: 1px dotted #212121` in\n * `@codemirror/view`), which is still an outline.\n *\n * `\".cm-scroller\"`'s `borderRadius: \"7px\"` (8px − the 1px `\"&\"` border) clips\n * the gutters and active line to the rounded border. `\"&\"` never gets\n * `overflow: hidden`, which would clip lint/hover tooltips mounted inside the\n * editor.\n *\n * `\".cm-content\"` only sets the vertical longhands: `styles/_fx.scss` owns\n * `padding-right` while the ƒx/copy overlay is present.\n */\nexport const EDITOR_THEME_SPEC: Record<string, Record<string, string>> = {\n \"&\": {\n fontSize: \"13px\",\n fontFamily: \"ui-monospace, SFMono-Regular, Menlo, monospace\",\n backgroundColor: \"var(--w6w-panel-2)\",\n color: \"var(--w6w-text)\",\n border: \"1px solid var(--w6w-border)\",\n borderRadius: \"8px\",\n },\n \"&.cm-focused\": { outline: \"none\", borderColor: \"var(--w6w-accent)\" },\n \".cm-gutters\": {\n backgroundColor: \"var(--w6w-panel)\",\n color: \"var(--w6w-muted)\",\n border: \"none\",\n borderRight: \"1px solid var(--w6w-border)\",\n },\n \".cm-scroller\": { overflow: \"auto\", borderRadius: \"7px\" },\n \".cm-content\": {\n paddingTop: \"var(--w6w-sp-2)\",\n paddingBottom: \"var(--w6w-sp-2)\",\n },\n \".cm-line\": { paddingLeft: \"var(--w6w-sp-2)\" },\n};\n","import type { CompletionContext, CompletionResult } from \"@codemirror/autocomplete\";\nimport { javascriptLanguage } from \"@codemirror/lang-javascript\";\nimport { ViewPlugin } from \"@codemirror/view\";\nimport type { ScriptSuggestion } from \"./script-completion-service.ts\";\n\n/** Per-editor lazy worker; compiling suggestions never blocks typing or runs the script. */\nexport function scriptCompletions() {\n let worker: Worker | undefined;\n let nextId = 0;\n let destroyed = false;\n const pending = new Map<number, (options: ScriptSuggestion[]) => void>();\n const finish = () => {\n worker?.terminate();\n worker = undefined;\n for (const resolve of pending.values()) resolve([]);\n pending.clear();\n };\n const source = async (context: CompletionContext): Promise<CompletionResult | null> => {\n const word = context.matchBefore(/[\\w$]*/);\n if (\n destroyed ||\n !word ||\n (!context.explicit &&\n word.from === word.to &&\n context.state.sliceDoc(context.pos - 1, context.pos) !== \".\")\n )\n return null;\n if (!worker) {\n worker = new Worker(new URL(\"./script-completion.worker.ts\", import.meta.url), {\n type: \"module\",\n });\n worker.onmessage = (event: MessageEvent<{ id: number; options: ScriptSuggestion[] }>) => {\n pending.get(event.data.id)?.(event.data.options);\n pending.delete(event.data.id);\n };\n worker.onerror = finish;\n }\n const options = await new Promise<ScriptSuggestion[]>((resolve) => {\n const id = ++nextId;\n pending.set(id, resolve);\n context.addEventListener(\n \"abort\",\n () => {\n pending.delete(id);\n resolve([]);\n },\n { onDocChange: true },\n );\n worker?.postMessage({ id, code: context.state.doc.toString(), position: context.pos });\n });\n return context.aborted || !options.length ? null : { from: word.from, options };\n };\n return [\n javascriptLanguage.data.of({ autocomplete: source }),\n ViewPlugin.define(() => {\n destroyed = false;\n return {\n destroy() {\n destroyed = true;\n finish();\n },\n };\n }),\n ];\n}\n","import { javascript } from \"@codemirror/lang-javascript\";\nimport { python } from \"@codemirror/lang-python\";\nimport type { Extension } from \"@codemirror/state\";\nimport { EditorView } from \"@codemirror/view\";\nimport CodeMirror from \"@uiw/react-codemirror\";\nimport { useMemo } from \"react\";\nimport { EDITOR_THEME_SPEC } from \"./editor-theme.ts\";\nimport { scriptCompletions } from \"./script-completions.ts\";\nimport { useEffectiveTheme } from \"./theme.ts\";\nimport type { ThemeMode } from \"./types.ts\";\n\n/**\n * A CodeMirror *editing* mode for `<CodeEditor>` — a distinct concept from the\n * Prism *display-highlighting* grammar name a sibling module exports for\n * rendered snippets. Deliberately its own type, not shared with that one.\n */\nexport type ScriptLanguage = \"javascript\" | \"typescript\" | \"python\";\n\n// Exhaustive over every `ScriptLanguage` member, with no fallback arm — a\n// third value added to the union fails to compile here instead of silently\n// falling through (house idiom, see `StepBuilderModal.tsx`'s glyph maps /\n// `doc-format.ts`'s total switch).\nfunction languageExtension(language: ScriptLanguage): Extension {\n switch (language) {\n case \"javascript\":\n return javascript();\n case \"typescript\":\n return javascript({ typescript: true });\n case \"python\":\n return python();\n }\n}\n\nexport interface CodeEditorProps {\n value: string;\n onChange: (value: string) => void;\n /** Placeholder text shown when value is empty. */\n placeholder?: string;\n /** Minimum editor height. Defaults to \"160px\". */\n minHeight?: string;\n /** Maximum editor height before scrolling. Defaults to no cap. */\n maxHeight?: string;\n /** Explicit editor height. Pass `\"100%\"` to fill a flex parent. */\n height?: string;\n /** Read-only mode. */\n readOnly?: boolean;\n /**\n * Explicit theme. If omitted, auto-detects `data-theme` on `<html>` and falls\n * back to `prefers-color-scheme` — same behavior as `<JsonEditor>`.\n */\n theme?: ThemeMode;\n /**\n * CodeMirror editing mode (syntax highlighting + language-aware editing).\n * Omitted ⇒ today's exact plain-text behavior, unchanged.\n */\n language?: ScriptLanguage;\n /** Accessible label for the editor. */\n \"aria-label\"?: string;\n /** Called with the CodeMirror view once it exists — for inserting at the caret. */\n onCreateEditor?: (view: EditorView) => void;\n}\n\n/**\n * Plain-text-by-default code editor built on CodeMirror 6 — the same surface as\n * `<JsonEditor>` minus JSON language/linting, for editing snippets (e.g. an\n * inline script). Line numbers, bracket matching, and `--w6w-*` theming so it\n * inherits the consumer's palette. Pass `language` to opt into a CodeMirror\n * language pack (JavaScript/Python); omit it for the original dependency-free\n * plain-text mode.\n */\nexport function CodeEditor(props: CodeEditorProps) {\n const theme = useEffectiveTheme(props.theme);\n const extensions = useMemo(\n () => [\n ...(props.language ? [languageExtension(props.language)] : []),\n ...(props.language === \"javascript\" || props.language === \"typescript\"\n ? [scriptCompletions()]\n : []),\n EditorView.theme(EDITOR_THEME_SPEC),\n ],\n [props.language],\n );\n\n return (\n <div className=\"w6w-code-editor\" aria-label={props[\"aria-label\"] ?? \"Code editor\"}>\n <CodeMirror\n value={props.value}\n onChange={props.onChange}\n extensions={extensions}\n placeholder={props.placeholder}\n readOnly={props.readOnly}\n theme={theme}\n height={props.height}\n minHeight={props.minHeight ?? \"160px\"}\n maxHeight={props.maxHeight}\n onCreateEditor={props.onCreateEditor}\n basicSetup={{\n lineNumbers: true,\n foldGutter: false,\n highlightActiveLine: !props.readOnly,\n bracketMatching: true,\n closeBrackets: true,\n }}\n />\n </div>\n );\n}\n","import { json, jsonParseLinter } from \"@codemirror/lang-json\";\nimport { lintGutter, linter } from \"@codemirror/lint\";\nimport { EditorView } from \"@codemirror/view\";\nimport CodeMirror from \"@uiw/react-codemirror\";\nimport { type ReactNode, useMemo } from \"react\";\nimport { CheckGlyph, CopyGlyph } from \"./components/Copyable.tsx\";\nimport { useCopyToClipboard } from \"./components/use-copy.ts\";\nimport { EDITOR_THEME_SPEC } from \"./editor-theme.ts\";\nimport { useEffectiveTheme } from \"./theme.ts\";\nimport type { ThemeMode } from \"./types.ts\";\n\nexport interface JsonEditorProps {\n value: string;\n onChange: (value: string) => void;\n /**\n * Fired whenever the current value parses as JSON, with the parsed value.\n * Never fires while the value is invalid — pair it with a validity flag if\n * you want to react to invalidation too (e.g., disable a Save button).\n */\n onValidChange?: (parsed: unknown) => void;\n /** Optional callback fired on every keystroke with parse validity + error. */\n onValidityChange?: (result: { valid: boolean; error?: string }) => void;\n\n /** Placeholder text shown when value is empty. */\n placeholder?: string;\n /** Minimum editor height. Defaults to \"240px\". */\n minHeight?: string;\n /** Maximum editor height before scrolling. Defaults to no cap. */\n maxHeight?: string;\n /**\n * Explicit editor height. Pass `\"100%\"` to fill a flex parent (the whole-config\n * \"code\" view). Omit to let the editor grow with its content between\n * `minHeight` and `maxHeight` — an inline JSON/group field wants this.\n */\n height?: string;\n\n /**\n * Receives the CodeMirror view once it exists — for a host that inserts text at the caret\n * (the JSON compose pane of `ExpressionEditorModal`).\n */\n onCreateEditor?: (view: EditorView) => void;\n /** Fired when the editor loses focus. */\n onBlur?: () => void;\n /** Fired when the editor gains focus. */\n onFocus?: () => void;\n /** Show JSON syntax diagnostics. Defaults to true; forms can defer them until blur. */\n showDiagnostics?: boolean;\n\n /** Read-only mode — useful for previewing a stored definition. */\n readOnly?: boolean;\n\n /**\n * Explicit theme. If omitted, the editor auto-detects `data-theme` on\n * `<html>` and falls back to `prefers-color-scheme` — same behavior as\n * `<AppIcon>`. Uses CodeMirror's built-in one-dark for dark mode.\n */\n theme?: ThemeMode;\n\n /** Accessible label for the editor. */\n \"aria-label\"?: string;\n\n /**\n * Render an in-box copy-to-clipboard button, a direct child of this\n * component's own `.w6w-json-editor` wrapper (sibling to the CodeMirror\n * mount — no extra DOM node). Copies the current `value` verbatim.\n *\n * Off by default: the other five `<JsonEditor>` mounts in this tree are\n * not step-JSON config views and must render byte-identically to before\n * this prop existed.\n */\n copyable?: boolean;\n\n /**\n * Content overlaid inside the editor box at its top-right corner, a direct\n * child of `.w6w-json-editor` (same overlay mechanism as `copyable`). The\n * `ParamsForm` json field puts its `ƒx` here. Text keeps right padding so\n * line 1 is not covered.\n */\n overlay?: ReactNode;\n}\n\n/**\n * An empty (or whitespace-only) document is not an error: there is nothing to\n * validate yet, and required-ness is the form's job on submit. Wraps\n * `jsonParseLinter()` so empty yields no diagnostics; anything else defers to it.\n */\nfunction lintJsonUnlessEmpty() {\n const parse = jsonParseLinter();\n return (view: EditorView) => (view.state.doc.toString().trim() === \"\" ? [] : parse(view));\n}\n\n/**\n * JSON editor built on CodeMirror 6. Syntax highlighting, folding, gutter with\n * lint markers for invalid JSON. Themed with the `--w6w-*` custom properties so\n * it inherits from the consumer's palette.\n *\n * ```tsx\n * <JsonEditor value={text} onChange={setText}\n * onValidChange={(parsed) => setDefinition(parsed)}\n * minHeight=\"320px\" />\n * ```\n */\nexport function JsonEditor(props: JsonEditorProps) {\n const theme = useEffectiveTheme(props.theme);\n // Only mounted when `copyable` is on, but the hook itself must run\n // unconditionally (Rules of Hooks) — it is inert (no button, no listener)\n // until `copy()` is actually invoked from the button below.\n const { copied, copy } = useCopyToClipboard(props.value);\n const extensions = useMemo(\n () => [\n json(),\n ...(props.showDiagnostics === false ? [] : [linter(lintJsonUnlessEmpty()), lintGutter()]),\n EditorView.theme(EDITOR_THEME_SPEC),\n ],\n [props.showDiagnostics],\n );\n\n function handleChange(next: string) {\n props.onChange(next);\n if (!props.onValidChange && !props.onValidityChange) return;\n if (next.trim().length === 0) {\n props.onValidityChange?.({ valid: false, error: \"Empty\" });\n return;\n }\n try {\n const parsed = JSON.parse(next);\n props.onValidChange?.(parsed);\n props.onValidityChange?.({ valid: true });\n } catch (e) {\n props.onValidityChange?.({ valid: false, error: (e as Error).message });\n }\n }\n\n return (\n <div className=\"w6w-json-editor\" aria-label={props[\"aria-label\"] ?? \"JSON editor\"}>\n <CodeMirror\n value={props.value}\n onChange={handleChange}\n extensions={extensions}\n placeholder={props.placeholder}\n readOnly={props.readOnly}\n // `readOnly` alone only blocks CodeMirror's own transactions\n // (`EditorState.readOnly`) — it leaves the content DOM\n // `contenteditable=\"true\"`, so a screen reader / a11y test still sees\n // it as an editable field. `editable` is the separate switch that\n // actually sets `contenteditable` (`EditorView.editable`); tying it to\n // `readOnly` here makes the prop mean what its name says.\n editable={!props.readOnly}\n theme={theme}\n height={props.height}\n minHeight={props.minHeight ?? \"240px\"}\n maxHeight={props.maxHeight}\n onCreateEditor={props.onCreateEditor}\n onBlur={props.onBlur}\n onFocus={props.onFocus}\n basicSetup={{\n lineNumbers: true,\n foldGutter: true,\n highlightActiveLine: !props.readOnly,\n autocompletion: true,\n bracketMatching: true,\n closeBrackets: true,\n }}\n />\n {props.overlay}\n {props.copyable && (\n <>\n <button\n type=\"button\"\n className={`w6w-icon-btn w6w-copyable-btn${copied ? \" is-copied\" : \"\"}`}\n aria-label=\"Copy\"\n onClick={() => void copy()}\n >\n {copied ? <CheckGlyph /> : <CopyGlyph />}\n </button>\n {/* Same live-region convention as `Copyable.tsx:141-147`: the\n button's accessible name stays constant, so this announces the\n result. */}\n <span className=\"w6w-copyable-status\" aria-live=\"polite\">\n {copied ? \"Copied\" : \"\"}\n </span>\n </>\n )}\n </div>\n );\n}\n","import { type CSSProperties, useEffect, useId, useMemo, useRef, useState } from \"react\";\n\nexport interface ComboboxOption {\n value: string;\n label: string;\n /** A muted second line under the label (e.g. a value preview); never matched by the filter. */\n detail?: string;\n}\n\nexport interface ComboboxProps {\n options: ComboboxOption[];\n value: string;\n onChange: (value: string) => void;\n placeholder?: string;\n disabled?: boolean;\n \"aria-label\"?: string;\n /** `auto` picks a native `<select>` for short lists, a combobox for long ones. */\n mode?: \"select\" | \"combobox\" | \"auto\";\n /** true (default): typing only filters; value changes by picking. false: free text is a value. */\n forceSelection?: boolean;\n /** Estimated option height in px, used by `auto` mode. Default 32. */\n optionHeight?: number;\n /**\n * Cap for the open list, in px — the list scrolls past it instead of growing.\n * Default 240 (the shared value). A host inside an already-scrolling container\n * (a modal body) passes a smaller one so the popup cannot add a second scroller.\n */\n listMaxHeight?: number;\n className?: string;\n /**\n * Called with the typed text on every edit — for a host that searches server-side and\n * passes the results back as `options`. The local filter still narrows what is shown.\n */\n onInputChange?: (text: string) => void;\n /** Shown in the open list when no option matches. Default \"No matches\". */\n emptyText?: string;\n /** A muted line at the foot of the open list (e.g. \"More entries — type to narrow\"). */\n footer?: string;\n}\n\n/** Combobox is chosen when the list would take more than 60% of the viewport. */\nexport function shouldUseCombobox(\n count: number,\n optionHeight: number,\n viewportHeight: number,\n): boolean {\n return count * optionHeight > 0.6 * viewportHeight;\n}\n\n/** Case-insensitive substring match on label and value. */\nexport function filterOptions(options: ComboboxOption[], query: string): ComboboxOption[] {\n const q = query.trim().toLowerCase();\n if (!q) return options;\n return options.filter(\n (o) => o.label.toLowerCase().includes(q) || o.value.toLowerCase().includes(q),\n );\n}\n\nexport const DEFAULT_LIST_MAX_HEIGHT = 240;\n\nconst DETAIL_STYLE: CSSProperties = {\n display: \"block\",\n fontSize: \"0.85em\",\n opacity: 0.65,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n};\n\n/** Everything but the height cap, which is per-instance (`listMaxHeight`). */\nconst LIST_STYLE: CSSProperties = {\n position: \"absolute\",\n zIndex: 50,\n left: 0,\n right: 0,\n top: \"100%\",\n overflowY: \"auto\",\n // The list is its own scroller; stop its scroll from chaining into the\n // surrounding modal/page once it hits either end.\n overscrollBehavior: \"contain\",\n margin: 0,\n padding: 4,\n listStyle: \"none\",\n background: \"var(--w6w-panel)\",\n color: \"var(--w6w-text)\",\n border: \"1px solid var(--w6w-border)\",\n borderRadius: 6,\n boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\",\n};\n\nexport function Combobox({\n options,\n value,\n onChange,\n placeholder,\n disabled,\n \"aria-label\": ariaLabel,\n mode = \"auto\",\n forceSelection = true,\n optionHeight = 32,\n listMaxHeight = DEFAULT_LIST_MAX_HEIGHT,\n className,\n onInputChange,\n emptyText = \"No matches\",\n footer,\n}: ComboboxProps) {\n const useBox =\n mode === \"combobox\" ||\n (mode === \"auto\" &&\n shouldUseCombobox(\n options.length,\n optionHeight,\n typeof window === \"undefined\" ? 0 : window.innerHeight,\n ));\n\n const id = useId();\n const selectedLabel =\n options.find((o) => o.value === value)?.label ?? (forceSelection ? \"\" : value);\n const [text, setText] = useState(selectedLabel);\n const [open, setOpen] = useState(false);\n const [filtering, setFiltering] = useState(false);\n const [active, setActive] = useState(0);\n const rootRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n setText(selectedLabel);\n }, [selectedLabel]);\n\n const shown = useMemo(\n () => (filtering ? filterOptions(options, text) : options),\n [options, text, filtering],\n );\n const listStyle = useMemo<CSSProperties>(\n () => ({ ...LIST_STYLE, maxHeight: listMaxHeight }),\n [listMaxHeight],\n );\n\n if (!useBox) {\n return (\n <select\n className={className}\n value={value}\n disabled={disabled}\n aria-label={ariaLabel}\n onChange={(e) => onChange(e.target.value)}\n >\n {placeholder !== undefined && value === \"\" && (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n )}\n {options.map((o) => (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n ))}\n </select>\n );\n }\n\n const optId = (i: number) => `${id}-opt-${i}`;\n\n const close = () => {\n setOpen(false);\n setFiltering(false);\n };\n\n const pick = (o: ComboboxOption) => {\n setText(o.label);\n onChange(o.value);\n close();\n };\n\n const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n if (!open) setOpen(true);\n else setActive((a) => Math.min(a + 1, shown.length - 1));\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n if (!open) setOpen(true);\n else setActive((a) => Math.max(a - 1, 0));\n } else if (e.key === \"Enter\") {\n if (open && shown[active]) {\n e.preventDefault();\n pick(shown[active]);\n } else if (!forceSelection) {\n if (text !== selectedLabel) onChange(text);\n close();\n }\n } else if (e.key === \"Escape\") {\n if (open) e.stopPropagation();\n setText(selectedLabel);\n close();\n }\n };\n\n const onBlur = () => {\n if (forceSelection) setText(selectedLabel);\n else if (text !== selectedLabel) onChange(text);\n close();\n };\n\n return (\n <div ref={rootRef} className=\"w6w-combobox\" style={{ position: \"relative\" }}>\n <input\n type=\"text\"\n role=\"combobox\"\n className={className}\n value={text}\n disabled={disabled}\n placeholder={placeholder}\n aria-label={ariaLabel}\n aria-expanded={open}\n aria-controls={`${id}-list`}\n aria-autocomplete=\"list\"\n aria-activedescendant={open && shown[active] ? optId(active) : undefined}\n autoComplete=\"off\"\n onFocus={() => setOpen(true)}\n onChange={(e) => {\n setText(e.target.value);\n onInputChange?.(e.target.value);\n setFiltering(true);\n setActive(0);\n setOpen(true);\n }}\n onKeyDown={onKeyDown}\n onBlur={onBlur}\n />\n {open && (\n <div\n id={`${id}-list`}\n // biome-ignore lint/a11y/useFocusableInteractive lint/a11y/useSemanticElements: ARIA popup, focus stays on the input via aria-activedescendant\n role=\"listbox\"\n tabIndex={-1}\n aria-label={ariaLabel}\n style={listStyle}\n >\n {shown.map((o, i) => (\n <div\n key={o.value}\n id={optId(i)}\n // biome-ignore lint/a11y/useFocusableInteractive lint/a11y/useSemanticElements: ARIA popup, focus stays on the input via aria-activedescendant\n role=\"option\"\n tabIndex={-1}\n aria-selected={o.value === value}\n style={{\n padding: \"6px 8px\",\n cursor: \"pointer\",\n borderRadius: 4,\n background: i === active ? \"var(--w6w-panel-2)\" : undefined,\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n pick(o);\n }}\n onMouseEnter={() => setActive(i)}\n >\n {o.label}\n {o.detail !== undefined && (\n <span className=\"w6w-combobox-detail\" style={DETAIL_STYLE}>\n {o.detail}\n </span>\n )}\n </div>\n ))}\n {shown.length === 0 && (\n <div role=\"presentation\" style={{ padding: \"6px 8px\", opacity: 0.6 }}>\n {emptyText}\n </div>\n )}\n {footer !== undefined && (\n <div\n role=\"presentation\"\n className=\"w6w-combobox-footer\"\n style={{ padding: \"6px 8px\", opacity: 0.6, fontSize: \"0.85em\" }}\n >\n {footer}\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n","/**\n * Wire types the components consume. These mirror the shapes the w6w server\n * returns over HTTP. They are intentionally a local copy so consumers who\n * don't use `@w6w/types` (partners, non-TypeScript backends) don't need it.\n */\n\nimport type { ParamWhen } from \"@w6w/expr\";\n\n/** Summary of a registered app as returned by GET /apps. */\nexport interface AppSummary {\n id: string;\n displayName: string;\n version?: string;\n description?: string;\n categories?: string[];\n sourceRef?: string;\n importedAt?: string;\n /** Inlined data: URI (or absolute URL) for the app's icon. */\n iconSvg?: string;\n /** Optional dark-mode variant. */\n iconSvgDark?: string;\n brandColor?: string;\n brandColorDark?: string;\n versionCount?: number;\n maturity?: string;\n visibility?: string;\n successor?: string;\n /** Model-provider designation; absent when the app does not declare one. */\n modelProvider?: { modelTypes: string[]; modelFamilies?: string[] };\n /**\n * True when the calling tenant has zero-credential access flagged for this\n * app — usable with no connection step at all (server-computed per caller;\n * `packages/server/packages/api/wire-summary.ts`'s `zeroCredential`).\n */\n zeroCredential?: boolean;\n /** Number of triggers the app declares (wire already carries it). */\n triggerCount?: number;\n}\n\n/** One trigger an app declares, as returned by GET /apps/:id/triggers. */\nexport interface TriggerSummary {\n key: string;\n /** The trigger's human label. REQUIRED — the wire type calls it `title`, not\n * `displayName`; do not rename it. */\n title: string;\n description?: string;\n requiresAuth?: boolean;\n /** `\"poll\"` triggers are fetched on an interval; absent or `\"webhook\"` receive pushes. */\n type?: \"webhook\" | \"poll\" | \"protocol\";\n /** Host floor for a poll trigger's interval, in milliseconds. */\n minIntervalMs?: number;\n /** The trigger's declared parameters (the route returns the full declaration). */\n params?: readonly unknown[];\n /** The event's declared fields (an `OutputField[]`) — keys for `trigger.event.<key>`. */\n output?: unknown;\n /** A representative event payload the app declares (never fabricated). */\n sample?: unknown;\n}\n\n/** A Subscription (rfcs/trigger.md) as returned by the console subscription routes. */\nexport interface SubscriptionSummary {\n id: string;\n appId: string;\n triggerKey: string;\n workflowId: string;\n connectionId: string | null;\n /** Present only for `appId === \"@w6w/webhook\"` — the server's own computed receive URL. */\n webhookUrl?: string;\n type?: \"webhook\" | \"poll\" | \"protocol\";\n status?: SubscriptionStatus;\n /** Poll interval in milliseconds; null for webhook subscriptions. */\n intervalMs?: number | null;\n lastError?: { code: string; message: string } | null;\n /** The workflow trigger node this subscription is bound to; null for a workflow-level one. */\n nodeId?: string | null;\n /** When registration with the app succeeded; null until it has. */\n registeredAt?: string | null;\n /** When the subscription last fired; null/absent when it never has. */\n lastFireAt?: string | null;\n}\n\n/**\n * A \"Listen for test event\" session on a `@w6w/webhook` subscription\n * (`POST /subscriptions/:id/listen`). `request` is the captured, credential-masked call —\n * exactly what a real run's webhook trigger emits as its output.\n */\nexport interface WebhookListenSession {\n id: string;\n subscriptionId: string;\n nodeId: string | null;\n expiresAt: string;\n status: \"waiting\" | \"captured\" | \"expired\";\n request?: {\n method: string;\n path: string;\n query: Record<string, string>;\n headers: Record<string, string>;\n body: unknown;\n };\n receivedAt?: string;\n}\n\n/** Registration state of a Subscription (rfcs/trigger-protocol.md §Lifecycle). */\nexport type SubscriptionStatus = \"pending\" | \"registered\" | \"failed\" | \"paused\" | \"destroying\";\n\n/** One field on an Auth method's connection form. Drives the input widgets. */\nexport interface AuthField {\n key: string;\n label: string;\n type: \"string\" | \"number\" | \"boolean\" | \"secret\" | string;\n required?: boolean;\n default?: unknown;\n hint?: string;\n /** Masks the input like a `secret` field whatever its `type` (e.g. a `json` key file). */\n secret?: boolean;\n}\n\n/**\n * One declared parameter of an action, as returned by GET /apps/:id (the\n * `actions[].params` array). Drives the guided step-builder form. Same shape as\n * an app manifest's action param — a superset of `AuthField` (adds `text`/`json`\n * widget types).\n */\nexport interface ActionParam {\n key: string;\n label?: string;\n /**\n * Widget to render for this param. Beyond the scalar types, `text` is a\n * textarea, `json`/`group` an inline JSON editor, `code` a code editor, and\n * `vars` a dynamic typed key/value table.\n */\n type:\n | \"string\"\n | \"text\"\n | \"number\"\n | \"boolean\"\n | \"select\"\n | \"multiselect\"\n | \"array\"\n | \"json\"\n | \"group\"\n | \"secret\"\n | \"code\"\n | \"vars\"\n | \"section\"\n | string;\n required?: boolean;\n default?: unknown;\n hint?: string;\n /** Render hint; multiselect supports \"checkboxes\" or the default chip picker. */\n ui?: string;\n /** Placeholder text for the input (e.g. the trailing prompt on a multiselect). */\n placeholder?: string;\n /**\n * Move this (optional) param under the collapsed \"Additional parameters\"\n * section. Required + non-advanced params show up front. Ignored for required\n * params (they always show).\n */\n advanced?: boolean;\n /**\n * The field holds ONE value or expression, never a composed container: in the JSON-binding\n * editor, picking a reference into an empty draft (or a bare `[]` / `{}`) stores the bare\n * whole-value ref `\"{{ ref }}\"`, not `[ref]`. A literal still can be typed.\n */\n whole?: boolean;\n /**\n * The param is declared on the action but never rendered by any param form, and never gates\n * the required check. Its stored value is preserved untouched (e.g. a canvas-owned `body`).\n * Not the entry-level `InternalNodeDef.hidden` (a palette hide).\n */\n hidden?: boolean;\n /**\n * Lay this param out on a shared row with adjacent params carrying the same\n * `row` id — e.g. a username/password pair side by side.\n */\n row?: string;\n /**\n * Allow multiple values (array of `type`). Renders as an add/remove list via\n * the same `ArrayField` a `type: \"array\"` param uses, with a synthesized\n * `item` — sugar for `type: \"array\"`; see rfcs/param.md's `repeat` amendment.\n * Mirrors `@w6w/types`' `Param.repeat`.\n */\n repeat?: boolean;\n /** Element schema when `type: \"array\"` (a scalar list or a list of objects). */\n item?: ParamArrayItem;\n /**\n * Conditional visibility — the param renders only when this predicate holds\n * against a sibling field's value. Lets a schema declare conditional sections\n * (e.g. Basic-auth fields shown only when `auth` is `\"basic\"`).\n */\n showIf?: ParamCondition;\n /**\n * Conditional overlay: the first entry whose `if` holds overlays\n * label/hint/required/ui/options onto this param (see `effectiveParam` in\n * `@w6w/expr`). Mirrors `@w6w/types`' `Param.when`.\n */\n when?: ParamWhen<ParamOption[] | DynamicOptions>[];\n /**\n * Constrained choices. Renders as a single-select dropdown for `select` (or any\n * param with options), and as a multi-select pill picker for `multiselect`.\n */\n options?: ParamOption[] | DynamicOptions;\n /** Type-specific render/behavior options. */\n config?: ParamConfig;\n /**\n * Nested params, walked by the renderer for `type: \"group\"` (nested object)\n * and `type: \"section\"` (layout-only container whose children write to the\n * ENCLOSING form values, not under this param's key).\n */\n children?: ActionParam[];\n /**\n * `type: \"section\"` only — the container behavior. `\"collapsible\"` renders a\n * titled, collapsed-by-default disclosure; `\"group\"` a `layout` row/stack.\n */\n section?: \"collapsible\" | \"group\";\n /** `section: \"collapsible\"` only — the `<summary>` heading. */\n title?: string;\n /** `section: \"collapsible\"` only — an optional secondary summary line. */\n subtitle?: string;\n /** `section: \"group\"` only — `\"row\"` side by side, `\"stack\"` vertical (default). */\n layout?: \"row\" | \"stack\";\n /** `section: \"collapsible\"` only — start collapsed (default `true`). */\n collapsed?: boolean;\n /** `section: \"collapsible\"` only — start open when any child already holds a value. */\n openWhenSet?: boolean;\n /**\n * `type: \"code\"` only — a Run script's code, which reads run data from its `state` / `vars` /\n * `consts` globals: its insert actions write code reads, never `{{ }}` (the host does not\n * substitute in code).\n */\n scriptReads?: boolean;\n}\n\n/** A single choice for a param rendered as a dropdown. */\nexport interface ParamOption {\n value: string | number;\n label: string;\n description?: string;\n}\n\n/** Host-resolved options (mirrors @w6w/types `DynamicOptions`). */\nexport interface DynamicOptions {\n source: string;\n searchable?: boolean;\n cache?: \"session\" | \"none\";\n refreshOn?: string[];\n}\n\n/** True for the form-resolved arm: a non-array object with `source === \"resolveFields\"`. */\nexport function isFormResolvedOptions(o: unknown): o is DynamicOptions {\n return (\n typeof o === \"object\" &&\n o !== null &&\n !Array.isArray(o) &&\n (o as { source?: unknown }).source === \"resolveFields\"\n );\n}\n\n/** Body of `W6WApi.resolveActionFields`. */\nexport interface ResolveFieldsBody {\n connectionId: string;\n version?: string;\n reason: \"init\" | \"change\";\n form: Record<string, unknown>;\n previous?: Record<string, unknown>;\n changed?: string[];\n fields: string[];\n unresolved: string[];\n}\n\n/** Result of `W6WApi.resolveActionFields`. */\nexport interface ResolveFieldsResult {\n fields: Record<string, { options?: ParamOption[]; error?: string }>;\n}\n\n/**\n * The element schema for a `type: \"array\"` param. Either a scalar list\n * (`type: \"string\" | \"number\"`, each item a single value) or a list of objects\n * (`type: \"object\"` with `fields`, each item a `{ [key]: value }` record whose\n * fields render side by side).\n */\nexport interface ParamArrayItem {\n type: \"string\" | \"number\" | \"object\" | string;\n /** For object items — the fields of each element (rendered inline in a row). */\n fields?: ActionParam[];\n /** Placeholder for a scalar item's input. */\n placeholder?: string;\n /** For a scalar item — constrained choices, carried over from a `repeat: true`\n * param's own `options` (a `repeat` scalar with `options` still needs them). */\n options?: ParamOption[];\n}\n\n/**\n * A conditional-visibility predicate tested against a sibling param's value.\n * Exactly one of `equals` / `in` / `notIn` / `truthy` is used (checked in that\n * order). The compared value falls back to the sibling's `default` when unset.\n */\nexport interface ParamCondition {\n /** Sibling param key whose value is tested. */\n field: string;\n /** Visible when the field's value strictly equals this. */\n equals?: string | number | boolean;\n /** Visible when the field's value is one of these. */\n in?: Array<string | number | boolean>;\n /** Visible when the field's value is NOT one of these. */\n notIn?: Array<string | number | boolean>;\n /** Visible when the field's value is truthy (`true`) or falsy (`false`). */\n truthy?: boolean;\n}\n\n/** Type-specific render/behavior options for a param. */\nexport interface ParamConfig {\n /** Render as a multi-line textarea. Implied by `type: \"text\"`. */\n multiline?: boolean;\n /** With options: accept a value not in the list (Combobox `forceSelection` off). */\n allowCustom?: boolean;\n /** Multiselect storage format. Defaults to an array; CSV preserves string-based API inputs. */\n valueFormat?: \"array\" | \"csv\";\n}\n\n/** Summary of an action an app exposes, as returned by GET /apps/:id. */\nexport interface ActionDef {\n key: string;\n type?: string;\n title?: string;\n description?: string;\n params?: ActionParam[];\n /**\n * The declared output shape — `OutputField[]` (`{ key, type, label }`, a dot\n * key for a nested path) or a `DynamicOutput` (`{ source }`) the editor does\n * not resolve. Read by `output-shape.ts`, so a later step can pick fields.\n */\n output?: unknown;\n /** An example output value; used for the field shape when `output` is absent. */\n sample?: unknown;\n /** Declared connection ports; `\"many\"` is unbounded. Absent fields fall through to defaults. */\n ports?: { in?: number | \"many\"; out?: number | \"many\" };\n}\n\n/**\n * Summary of a registered Function, as returned by GET /functions (core\n * rfcs/function.md). `valid` mirrors the server's `isFunctionValid` — false for\n * a draft Function (no `impl`, or an incomplete one) — the picker's list stage\n * doesn't gate on it (an invalid Function still shows up; the server's own\n * invoke route is what refuses it).\n */\nexport interface FunctionSummary {\n id: string;\n key: string;\n displayName?: string;\n description?: string;\n updatedAt?: string;\n valid: boolean;\n}\n\n/**\n * A Function's canonical interface, as returned by GET /functions/:id — enough\n * to render its `inputs` form (core rfcs/function.md). `inputs` reuses the\n * wire-mirror `ActionParam[]` shape verbatim, exactly as an app action's own\n * declared `params` do.\n */\nexport interface FunctionDetail {\n id: string;\n key: string;\n displayName?: string;\n description?: string;\n inputs: ActionParam[];\n valid: boolean;\n}\n\n/** Summary of a registered Workflow, as returned by GET /workflows. */\nexport interface WorkflowSummary {\n id: string;\n name: string;\n displayName?: string;\n description?: string;\n status?: string;\n updatedAt?: string;\n}\n\n/** One step of a Workflow, as returned by GET /workflows/:id — the minimal\n * shape the picker's Configure stage needs to find the entry/trigger step's\n * own declared `with.fields` (core rfcs/node-types.md's trigger node). */\nexport interface WorkflowStepSummary {\n id: string;\n uses: { app: string; action: string };\n with?: Record<string, unknown>;\n}\n\n/**\n * Full Workflow definition, as returned by GET /workflows/:id — enough to\n * derive the trigger's declared input fields for the Functions/Workflows\n * picker's Configure stage. A deliberately smaller mirror than `FlowWorkflow`\n * (`flow-types.ts`) — these wire types stay independent of the flow-editor's\n * own type, matching this file's own \"local copy\" convention.\n */\nexport interface WorkflowDetail {\n id: string;\n name: string;\n displayName?: string;\n description?: string;\n /** The canonical (manifest v2) step list. */\n nodes?: WorkflowStepSummary[];\n /** The legacy (v1) step list; a definition carries one or the other. */\n steps?: WorkflowStepSummary[];\n}\n\n/** A `serviceAccount` auth's declaration: the credential contract it accepts and its binding. */\nexport interface ServiceAccountConfig {\n /** Credential contract ids this auth accepts; the first one is used to list/create. */\n accepts: string[];\n /** Scopes the binding requests by default (shown read-only; the server applies them). */\n scopes: string[];\n /** Whether a connection must/may name an impersonated user (`delegatedUser`). */\n impersonation: \"none\" | \"optional\" | \"required\";\n /** Extra per-connection (binding) fields; each lands in `binding.settings`. */\n bindingFields?: AuthField[];\n}\n\nexport type CredentialStatus = \"active\" | \"disabled\" | \"revoked\";\n\n/** A stored credential as the API lists it. Never carries the secret payload. */\nexport interface CredentialSummary {\n id: string;\n name: string;\n contract: string;\n status: CredentialStatus | string;\n revision: number;\n /** Non-secret display values (e.g. the service account's email). */\n display: Record<string, string>;\n private: boolean;\n connectionCount: number;\n createdAt: string;\n updatedAt: string;\n}\n\n/** The connections that use a credential. */\nexport interface CredentialDependents {\n connections: Array<{\n id: string;\n appId: string;\n authKey: string;\n displayName?: string | null;\n }>;\n}\n\nexport interface CredentialTestResult {\n ok: boolean;\n code?: string;\n message?: string;\n}\n\n/** Per-connection settings applied on top of a shared credential. */\nexport interface ConnectionBinding {\n scopes?: string[];\n /** The user the credential impersonates (Google domain-wide delegation). */\n delegatedUser?: string;\n settings?: Record<string, string | number | boolean>;\n}\n\n/** Body of `createConnection`: an inline credential XOR a reference to a stored one. */\nexport type CreateConnectionBody =\n | {\n authKey: string;\n credential: Record<string, unknown>;\n credentialId?: never;\n displayName?: string;\n profile?: Record<string, unknown>;\n }\n | {\n authKey: string;\n credentialId: string;\n credential?: never;\n binding?: ConnectionBinding;\n displayName?: string;\n profile?: never;\n };\n\n/** Auth method declaration as exposed by an app's manifest. */\nexport interface AuthDef {\n key: string;\n type:\n | \"oauth2\"\n | \"apiKey\"\n | \"basic\"\n | \"bearer\"\n | \"custom\"\n | \"tenantAuth\"\n | \"jit\"\n | \"serviceAccount\"\n | string;\n displayName?: string;\n description?: string;\n connectionLabel?: string;\n fields?: AuthField[];\n /** Present when `type === \"serviceAccount\"`: what credential it accepts and how it binds. */\n serviceAccount?: ServiceAccountConfig;\n /** OAuth2 endpoints (only present when type === \"oauth2\"). */\n oauth2?: Record<string, unknown>;\n /**\n * False when the method requires per-host configuration that hasn't been\n * provided yet (e.g. an oauth2 method with no client credentials set up).\n * The picker hides entries with `available === false`.\n */\n available?: boolean;\n /** Names of host-side config keys this method needs, when applicable. */\n requiresHostConfig?: string[];\n /**\n * Present only on a `tenantAuth`/`jit` entry: `true` when the operator has\n * flagged this method as zero-credential for the calling scope's tenant, so\n * the server resolves a connection automatically at invoke time. This is\n * NOT `available` — `available` means \"this method can be picked at all\";\n * `autoSatisfied` means \"the user does not have to pick anything for it\".\n */\n autoSatisfied?: boolean;\n /**\n * `true` on the one method the server marks as the tenant's default for this\n * app. The connect modal preselects it (among the available methods).\n */\n default?: boolean;\n}\n\n/** Public summary of a stored connection — never carries the credential. */\n/** The display meta the server inlines on each {@link ConnectionSummary} (`app`). */\nexport interface ConnectionAppMeta {\n displayName: string;\n iconSvg?: string;\n iconSvgDark?: string;\n brandColor?: string;\n brandColorDark?: string;\n}\n\nexport interface ConnectionSummary {\n id: string;\n appId: string;\n authKey: string;\n /** The stored credential this connection uses, when it has one. */\n credentialId?: string | null;\n /** The owning tenant. The server sends `tenant`/`subject`, never `owner`. */\n tenant?: string;\n /** The owning subject (the partner's user id). */\n subject?: string;\n /**\n * The connection's app, inline: just enough to draw its card. `null` when the\n * app is no longer in the catalog; absent from servers that don't send it.\n */\n app?: ConnectionAppMeta | null;\n displayName?: string;\n state?: \"pending\" | \"connected\" | \"needs_refresh\" | \"broken\" | \"revoked\" | string;\n profile?: Record<string, unknown>;\n createdAt?: string;\n updatedAt?: string;\n /**\n * True for the server's synthetic \"no credential needed\" rows. They have no stored credential,\n * so the server 404s get/test/delete on their ids; the connection UI offers nothing on them.\n * Detect with this flag only, never an id prefix.\n */\n builtIn?: boolean;\n /** The last test result: `false` = failed, `null`/absent = never tested. */\n lastTestOk?: boolean | null;\n}\n\n/** A saved set of action-test input values, scoped to a connection + action. */\nexport interface SavedTest {\n id: string;\n connectionId: string;\n appId: string;\n actionKey: string;\n name: string;\n values: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n /** When this saved test was last run (ISO), or null/undefined if never run. */\n lastRunAt?: string | null;\n /** Whether the most recent run succeeded, or null/undefined if never run. */\n lastRunOk?: boolean | null;\n /** Short headline for the most recent run's outcome, or null/undefined if never run. */\n lastRunSummary?: string | null;\n}\n\n/**\n * One outbound HTTP call an action made while running — the exact (redacted)\n * request that went to the third-party API and the response that came back.\n * Returned alongside an invoke's value/error and persisted server-side, so a\n * run can be debugged and evaluated against the vendor's documented API.\n */\nexport interface ApiCallRecord {\n host: string;\n method: string;\n /** 0 when the request never produced a response (`error` says why). */\n status: number;\n url?: string;\n requestHeaders?: Record<string, string>;\n /** `null` on a persisted row that captured no body. */\n requestBody?: string | null;\n responseHeaders?: Record<string, string>;\n responseBody?: string | null;\n responseBytes?: number;\n durationMs?: number;\n /** A captured body hit the size cap and was cut. */\n truncated?: boolean;\n error?: string | null;\n}\n\n/** Effective theme hint passed to icon components to pick a light/dark variant. */\nexport type ThemeMode = \"light\" | \"dark\";\n\n/*\n * ---------------------------------------------------------------------------\n * Value model — the multipart/expression + secret envelopes for a step's\n * `with` block. Mirrored (shape-for-shape) from `@w6w/types` `value.ts` so\n * consumers who don't depend on `@w6w/types` don't have to. Keep in sync with\n * core: packages/core/packages/types/src/value.ts.\n * ---------------------------------------------------------------------------\n */\n\n/** The segment kinds an {@link ExprValue} part can take. */\nexport type ExprPartKind = \"text\" | \"var\" | \"secret\" | \"expr\" | \"render\";\n\n/**\n * One segment of an {@link ExprValue}. The populated field depends on `kind`:\n * - `text` → `value` holds a literal string chunk.\n * - `var` → `ref` names a project variable.\n * - `secret` → `ref` names a vault secret (surfaced via the secret picker).\n * - `expr` → `expr` holds inline JSONLogic evaluated against the run scope.\n */\nexport interface ExprPart {\n kind: ExprPartKind;\n /** Literal chunk, for `kind: \"text\"`. */\n value?: string;\n /** Name of the referenced variable/secret, for `kind: \"var\" | \"secret\"`. */\n ref?: string;\n /** Inline JSONLogic, for `kind: \"expr\"`. */\n expr?: unknown;\n}\n\n/**\n * A multipart value: an ordered list of {@link ExprPart} segments that\n * concatenate to a string at resolve time.\n */\nexport interface ExprValue {\n type: \"expr\";\n parts: ExprPart[];\n}\n\n/**\n * The at-rest form of a secret-typed scalar field: AES-GCM ciphertext + IV\n * (both base64). Decrypted server-side; never decrypted in the client — the UI\n * renders it as `***`.\n */\nexport interface SecretValue {\n type: \"secret\";\n ciphertext: string;\n iv: string;\n}\n\n/** `true` if `v` is an {@link ExprValue} envelope. Safe on `unknown`. */\nexport function isExprValue(v: unknown): v is ExprValue {\n return (\n typeof v === \"object\" &&\n v !== null &&\n !Array.isArray(v) &&\n (v as { type?: unknown }).type === \"expr\" &&\n Array.isArray((v as { parts?: unknown }).parts)\n );\n}\n\n/** `true` if `v` is a {@link SecretValue} envelope. Safe on `unknown`. */\nexport function isSecretValue(v: unknown): v is SecretValue {\n return (\n typeof v === \"object\" &&\n v !== null &&\n !Array.isArray(v) &&\n (v as { type?: unknown }).type === \"secret\" &&\n typeof (v as { ciphertext?: unknown }).ciphertext === \"string\" &&\n typeof (v as { iv?: unknown }).iv === \"string\"\n );\n}\n","import {\n type TemplateEscape,\n coalesceOperandRefs,\n hasRefusedChainToken,\n parseTemplate,\n serializeTemplate,\n} from \"@w6w/expr\";\nimport {\n type ExprPart,\n type ExprValue,\n type SecretValue,\n isExprValue,\n isSecretValue,\n} from \"../types.ts\";\n\n/**\n * `ui`'s view of the one `{{ }}` inline-expression grammar. The parser and the\n * serializer live in `@w6w/expr` (`core/packages/expr/src/template.ts`) so the\n * engine and the editor read the SAME grammar rather than two copies that must\n * agree forever; this module re-exports them and keeps the editor-only helpers\n * below (`renderResult` masks secrets as `•••` — a preview policy that must not\n * enter the engine's package).\n *\n * Grammar, modes, and the secret fence (D-8) are documented at the definition.\n *\n * `parseTemplate` itself builds every `{{ }}` marker unconditionally — it has\n * no opinion on whether a marker is a W6W expression or a vendor placeholder\n * (Mailjet's `{{var:name}}`, Metabase's `{{tag}}`, …). {@link\n * parseRootAnchoredTemplate} below adds that opinion (root-anchored parsing,\n * CONDUCTOR AMENDMENT 2026-08-14) and is what `valueToParts` and the chip-ify\n * commit paths call — never `parseTemplate` directly on untrusted text.\n */\nexport { parseTemplate, serializeTemplate };\n\n/** Strip editor-only noise, keeping only the wire fields each kind carries. */\nfunction toWirePart(p: ExprPart): ExprPart {\n if (p.kind === \"text\") return { kind: \"text\", value: p.value ?? \"\" };\n if (p.kind === \"expr\") return { kind: \"expr\", expr: p.expr };\n return { kind: p.kind, ref: p.ref ?? \"\" }; // var | secret\n}\n\n/**\n * Serialize parts to the value that is saved: the `{{ }}` template STRING — exactly what the\n * author sees (core Workflow RFC amendment, 2026-10-29). Text parts are source text, kept\n * verbatim (an escaped `\\{{ var.x }}` stays escaped). The one exception is a `render` part,\n * which has no `{{ }}` spelling by design (RFC, *The `render` part kind*): a value holding one\n * is saved as an `ExprValue` envelope. Shared by the inline field and the expression editor\n * modal.\n */\nexport function partsToValue(parts: ExprPart[]): ExprValue | string {\n const cleaned = parts.filter((p) => p.kind !== \"text\" || (p.value ?? \"\") !== \"\");\n if (cleaned.length === 0) return \"\";\n if (cleaned.some((p) => p.kind === \"render\")) {\n return { type: \"expr\", parts: cleaned.map(toWirePart) };\n }\n let out = \"\";\n for (const p of cleaned) {\n if (p.kind === \"text\") {\n out += p.value ?? \"\";\n continue;\n }\n // A literal backslash typed right before a chip would escape it once saved as text:\n // double it, so it stays a backslash and the chip stays a reference.\n if (trailingBackslashCount(out) % 2 === 1) out += \"\\\\\";\n out += serializeTemplate([toWirePart(p)]);\n }\n return out;\n}\n\nfunction trailingBackslashCount(s: string): number {\n let n = 0;\n while (n < s.length && s[s.length - 1 - n] === \"\\\\\") n += 1;\n return n;\n}\n\n/**\n * Mirrors the engine's `RunScope` (`w6w-workflow/packages/engine/src/expr.ts:42`)\n * — the roots a `{{ }}` marker's first path segment must land in for the\n * marker to be treated as a W6W expression rather than literal vendor\n * placeholder text (CONDUCTOR AMENDMENT 2026-08-14 on this project's T1.2.2\n * contract). `ui` must not depend on `@w6w/workflow` — the import-map graph\n * runs `core -> w6w-workflow -> server`, and `ui -> studio` only — so this is\n * a LOCAL mirror, kept in sync BY HAND, deliberately and permanently: T1.5.1\n * already landed (`.ai/projects/done/26-08-13-00-fixes/`) and its `HITL-12`\n * considered — and declined — putting this predicate in `@w6w/expr` instead\n * of duplicating it, precisely because `ui` cannot depend on `@w6w/workflow`.\n * What IS shared is the chain-shape walk (`parseCoalesceChain` /\n * `coalesceOperandRefs` / `hasRefusedChainToken`, all `@w6w/expr`) — both\n * sites call the same predicates over their own local root set, so they\n * cannot silently drift on what a chain IS, only on which roots they accept.\n */\ninterface LocalRunScope {\n /** Project vars. `vars` is its permanent alias (engine `evalRoot`). */\n var: unknown;\n vars: unknown;\n /** The run's workflow state tree — the same object as `var`/`vars` (R17: a root of its own). */\n state?: unknown;\n steps: unknown;\n nodes?: unknown;\n trigger: unknown;\n foreach?: unknown;\n inputs?: unknown;\n output?: unknown;\n secrets?: unknown;\n documents?: unknown;\n /** Account constants. */\n const?: unknown;\n}\n\n/**\n * The root set, DERIVED from `LocalRunScope`'s keys rather than written out by\n * hand: this object literal is typed `Record<keyof LocalRunScope, true>`, so\n * adding a root to `LocalRunScope` without adding it here is a `tsc` error\n * (missing property) — the set cannot silently drift from the type it mirrors.\n */\nconst RUN_SCOPE_ROOTS: Record<keyof LocalRunScope, true> = {\n var: true,\n vars: true,\n state: true,\n steps: true,\n nodes: true,\n trigger: true,\n foreach: true,\n inputs: true,\n output: true,\n secrets: true,\n documents: true,\n const: true,\n};\n\n/** Every root name, for tests that pin the derived set without reaching into the type. */\nexport const RUN_SCOPE_ROOT_NAMES: readonly string[] = Object.freeze(Object.keys(RUN_SCOPE_ROOTS));\n\nconst isRunScopeRoot = (segment: string): boolean =>\n Object.prototype.hasOwnProperty.call(RUN_SCOPE_ROOTS, segment);\n\n/** The three spellings of the one workflow-state tree (`state` = `var` = `vars`). */\nconst STATE_ROOTS = [\"state\", \"var\", \"vars\"] as const;\n\n/**\n * THE alias rule for the state tree: `state`, `var` and `vars` are one object. For a ref whose\n * root is one of them (followed by `.` or end of string) this gives the lookup spellings in order:\n * the ref exactly as written, then `state.<rest>`, `var.<rest>`, `vars.<rest>` (deduplicated).\n * Any other root gives only the ref itself (`steps`/`nodes` are NOT aliased here).\n */\nexport function stateAliasSpellings(ref: string): string[] {\n for (const root of STATE_ROOTS) {\n if (ref === root || ref.startsWith(`${root}.`)) {\n const rest = ref.slice(root.length);\n return [...new Set([ref, ...STATE_ROOTS.map((r) => r + rest)])];\n }\n }\n return [ref];\n}\n\n/** The first `.`-delimited segment of a ref, e.g. `\"steps\"` for `\"steps.a.output\"`. */\nfunction firstSegment(ref: string): string {\n const i = ref.indexOf(\".\");\n return i === -1 ? ref : ref.slice(0, i);\n}\n\n/**\n * Root-anchored parse (CONDUCTOR AMENDMENT 2026-08-14): builds every marker in\n * `s` via `parseTemplate` (never a second `{{ }}` scanner), then requires:\n * - a `var` marker: `hasRefusedChainToken` must be false (a `||`/`??` the\n * chain grammar refused — mixed operators, a `secrets.` operand, … — is\n * never treated as an ordinary path) AND its first path segment must be a\n * `RUN_SCOPE_ROOTS` member;\n * - an `expr` marker recognised by `coalesceOperandRefs` as a `||`/`??`\n * chain: EVERY operand ref's first path segment must be a\n * `RUN_SCOPE_ROOTS` member — a chain is a first-class citizen here, not\n * the opaque escape hatch below;\n * - any other `expr` marker (`=<jsonlogic>`, or a `{{ }}` chip inserted from\n * the rail) or a `secret` marker (`secrets.NAME`): unambiguous by its OWN\n * syntax, no separate check.\n * One unrooted marker/operand reverts the WHOLE string to a single literal\n * `text` part (byte-identical to the input) — all-or-nothing, because the\n * grammar has no escape syntax and a mixed string can't half-chip. This is\n * what keeps `{{ vars.a }}` and `{{ vars.a || \"x\" }}` chips while Mailjet's\n * `{{var:name}}`, Mandrill's Handlebars, and Metabase's `{{tag}}` stay literal\n * text forever (121 spellings surveyed across `packages/apps`, 116 of them\n * vendor placeholders with no root of their own).\n */\nexport function parseRootAnchoredTemplate(s: string): ExprPart[] {\n const parts = parseTemplate(s, \"editor\", EDIT_ESCAPE);\n return parts.every(isOurPart) ? parts : [{ kind: \"text\", value: s }];\n}\n\n/** The per-marker rule: rooted `var`, rooted chain, any other `expr`, `secret`, `text`. */\nfunction isOurPart(p: ExprPart): boolean {\n if (p.kind === \"var\") {\n const ref = p.ref ?? \"\";\n return !hasRefusedChainToken(ref) && isRunScopeRoot(firstSegment(ref));\n }\n if (p.kind === \"expr\") {\n const refs = coalesceOperandRefs(p.expr);\n if (refs === null) return true; // not a chain — the `=` escape hatch: always ours.\n return refs.every((ref) => isRunScopeRoot(firstSegment(ref)));\n }\n return true; // `secret` / `text`\n}\n\n/**\n * `\\{{` before one of OUR markers keeps it literal (vendor `\\{{name}}` is untouched). The\n * editor keeps the backslash in the text part — what the author typed is what is saved.\n */\nconst EDIT_ESCAPE: TemplateEscape = { isOurs: isOurPart, backslash: \"keep\" };\n/** The same escape as the engine applies at run time: the backslash is consumed. */\nconst RESOLVE_ESCAPE: TemplateEscape = { isOurs: isOurPart, backslash: \"strip\" };\n\n/**\n * True when `v` holds a reference the run resolves — an `ExprValue` envelope, or a string with\n * at least one live marker of ours. Since the editor saves template STRINGS, this (not\n * `isExprValue`) is the test for \"this field is an expression\".\n */\nexport function holdsExpression(v: unknown): boolean {\n if (isExprValue(v)) return true;\n return (\n typeof v === \"string\" &&\n v.includes(\"{{\") &&\n parseRootAnchoredTemplate(v).some((p) => p.kind !== \"text\")\n );\n}\n\n/**\n * Parse a string the way the engine resolves a `with` string (`parseResolvableTemplate`):\n * parts with escapes consumed, or `null` when the engine would pass it through untouched (no\n * marker of ours, or one marker that is not ours). For previews.\n */\nexport function parseResolvableText(s: string): ExprPart[] | null {\n if (!s.includes(\"{{\")) return null;\n const parts = parseTemplate(s, \"editor\", RESOLVE_ESCAPE);\n if (!parts.every(isOurPart)) return null;\n if (parts.some((p) => p.kind !== \"text\")) return parts;\n return parts.map((p) => p.value ?? \"\").join(\"\") !== s ? parts : null;\n}\n\n/** A text part's source with its `\\{{` escapes consumed — what the run sends. */\nfunction unescapeText(text: string): string {\n if (!text.includes(\"{{\")) return text;\n return parseTemplate(text, \"editor\", RESOLVE_ESCAPE)\n .map((p) => (p.kind === \"text\" ? (p.value ?? \"\") : serializeTemplate([p])))\n .join(\"\");\n}\n\n/**\n * Parse an incoming value into editable parts (+ any sealed secret to display).\n * The inverse of {@link partsToValue} for the editable forms; a sealed\n * `SecretValue` has no parts (it's shown as a masked chip, never decrypted).\n *\n * The string arm root-anchor-parses (see {@link parseRootAnchoredTemplate}):\n * a hand-typed, pasted, re-opened, or SDK/MCP-written `\"{{ vars.x }}\"` now\n * chip-ifies identically to a rail insertion, while a vendor placeholder like\n * `\"{{name}}\"` stays literal text forever — it never had a root to lose.\n */\nexport function valueToParts(value: ExprValue | string | SecretValue | undefined): {\n parts: ExprPart[];\n sealed: SecretValue | null;\n} {\n if (isSecretValue(value)) return { parts: [], sealed: value };\n if (isExprValue(value)) return { parts: value.parts.map((p) => ({ ...p })), sealed: null };\n const s = typeof value === \"string\" ? value : \"\";\n return { parts: s ? parseRootAnchoredTemplate(s) : [], sealed: null };\n}\n\n/**\n * Render parts to their preview text for the expression editor's Result pane:\n * `text` parts concatenate literally, a `var` part resolves against `samples`\n * (keyed by full ref) or renders `\"\"` when unresolved — never the raw\n * `{{ ref }}` template token — and a `secret` part always masks as `•••`.\n *\n * A `render` part resolves through the exact SAME flat `samples` lookup as\n * `var` (A4c) — it does NOT additionally substitute `{{ }}` markers inside the\n * resolved value. That substitution is the engine's `resolveRenderPart`\n * (`packages/w6w-workflow/packages/engine/src/expr.ts`, out of scope), which\n * runs against a real run scope; this design-time preview has no run scope to\n * substitute against, so it shows the field's raw template text verbatim, same\n * as `var` would. Without at least the flat-lookup half, the new\n * insert-as-render action's very first click would leave the Result pane\n * blank, which reads as broken.\n *\n * No client-side evaluator for `expr` parts (see the TODO in\n * `ExpressionEditorModal.tsx`) — those fall back to their `{{ }}` template\n * form.\n */\nexport function renderResult(parts: ExprPart[], samples: Record<string, string>): string {\n let out = \"\";\n for (const p of parts) {\n switch (p.kind) {\n case \"text\":\n out += unescapeText(p.value ?? \"\");\n break;\n case \"var\":\n case \"render\": {\n const hit = stateAliasSpellings(p.ref ?? \"\").find((s) => s in samples);\n out += hit === undefined ? \"\" : samples[hit];\n break;\n }\n case \"secret\":\n out += \"•••\";\n break;\n case \"expr\":\n // No client-side evaluator (see TODO above) — show the template form.\n out += serializeTemplate([p]);\n break;\n }\n }\n return out;\n}\n","/**\n * Resolve a step's configured param VALUES against a test scope — the\n * \"what will this expression actually produce\" the Test tab shows, distinct\n * from `ParamsForm`/`ExpressionInput` which only ever EDIT the stored value.\n *\n * Greenfield by contract: `components/expression-template.ts`'s `renderResult`\n * is the only existing \"resolve a var ref against sample values\" function, but\n * it collapses \"ref not in scope\" and \"ref resolved to an empty value\" to the\n * same `out += \"\"` INSIDE its per-part loop — the distinction this module\n * exists to preserve is already gone by the time it returns. This file shares\n * no code with it and is not imported by it (0 lines touched there, verified\n * by `git diff --numstat` in the result).\n *\n * No React, no JSX — a pure, `node --test`-covered module, mirroring the\n * `step-preview-state.ts` / `trigger-fields.ts` precedent. `StepStartState` is\n * imported type-only (erased at runtime, same idiom `step-preview-state.ts:16`\n * already uses), so this file never actually loads `provider.tsx`'s React\n * import.\n */\nimport { parseResolvableText, stateAliasSpellings } from \"./components/expression-template.ts\";\nimport type { StepMeta, StepStartState } from \"./provider.tsx\";\nimport { type ExprPart, type ExprValue, isExprValue, isSecretValue } from \"./types.ts\";\n\n/**\n * Per-segment resolution outcome. Every value that can contain a `var`/`expr`\n * part resolves to an ARRAY of these (one per part of a multipart `ExprValue`,\n * or one for a single top-level marker/literal) — never a bare `string`, which\n * is exactly the shape `renderResult` collapses to and loses the distinction.\n *\n * `value` on `\"resolved\"` is `unknown` and explicitly INCLUDES `null` / `\"\"` /\n * `false` / `0` — those are real, present values, not absence. `\"unresolved\"`\n * carries no `value` at all (there is nothing to show) and always carries the\n * `ref` that failed to resolve, so a caller can render \"this ref, unresolved\"\n * without ever falling back to rendering the ref as if it WERE the value.\n */\nexport type ResolvedSegment =\n | { status: \"resolved\"; ref?: string; value: unknown }\n | { status: \"unresolved\"; ref: string }\n /**\n * A `nodes.<id>.meta.config.<key>` (alias `nodes.<id>.config.<key>`) ref this client cannot\n * know — a key no node configures here, or one the host fills only at run time — or a\n * `nodes.<id>.meta.<key>` its static meta lacks (a `version` the canvas does not know). Neutral, not a failure: the engine\n * resolves it on the run.\n */\n | { status: \"at-run\"; ref: string }\n | { status: \"not-evaluated\"; ref?: string }\n | { status: \"masked\"; ref?: string };\n\n/**\n * The scope a param's `var` refs resolve against. Built by {@link buildResolveScope}\n * from the SAME two things `StepEditModal` already computes: `testStartState`\n * (for `steps.*`/`trigger.*` — the object literally sent as the test's `state`)\n * and `sampleValues` (for `var.*`/`documents.*`/`const.*`).\n *\n * The fields mirror the engine's `RunScope` (`vars`, `constants`); the roots a ref\n * names are what the engine's data root exposes — `var.*` (with `vars.*` as its\n * permanent alias) and `const.*`. {@link resolveRef} maps one onto the other.\n */\nexport interface ResolveScope {\n vars: Record<string, unknown>;\n /** The SAME object as {@link vars}: `state`, `var` and `vars` are one tree (optional: hand-built scopes omit it). */\n state?: Record<string, unknown>;\n documents: Record<string, unknown>;\n /** Account constants, read as `const.<name>`. */\n constants?: Record<string, unknown>;\n steps: Record<string, { output?: unknown; meta?: StepMeta }>;\n /** `nodes.<id>…` root — the SAME object as `steps` (one state, two roots). */\n nodes?: Record<string, { output?: unknown; meta?: StepMeta }>;\n trigger: { event?: unknown };\n /**\n * The For each iteration scope (`foreach.item` / `foreach.index`), present only when\n * `sampleValues` carries a `foreach.*` key. Mirrors the engine's inner scope.\n */\n foreach?: { item?: unknown; index?: number };\n /**\n * The original flat `sampleValues` map, keyed by full ref string — checked\n * BEFORE the nested walk in {@link resolveRef}. `documentSampleValues`\n * (`document-sources.ts`) emits a document field's sample as its OWN\n * complete flat entry (`\"documents.<key>.<field>\"`), not as a nested value\n * living under the shorter `\"documents.<key>\"` entry — so the one-hop strip\n * below reconstructs `documents[\"<key>.<field>\"]` (one key, a literal dot\n * in it) instead of `documents[\"<key>\"][\"<field>\"]`, and a real\n * `\"<key>\"` entry (the whole document's raw content, a string) already\n * occupies that slot besides. `walkPath`'s segment-by-segment walk can\n * never reach either shape. An exact flat-key hit here resolves any ref\n * `sampleValues` names directly, regardless of how many segments it has;\n * the nested walk stays the fallback for a ref whose own reconstructed\n * value happens to be an object (`var.address` = `{ city: \"X\" }`, walking\n * into it for `var.address.city`), which is a value shape `sampleValues`\n * never produces a matching flat key for in the first place.\n *\n * Optional: a `ResolveScope` built by hand (as most tests in\n * `resolve-params.test.ts` do, to exercise the walk directly) has no flat\n * map to check and falls straight through to `walkPath` — only\n * `buildResolveScope` populates it.\n */\n flat?: Record<string, unknown>;\n /**\n * Each node's static configuration ({@link ExpressionOptions.nodeConfig}), laid over `nodes`\n * at `meta.config` and the `config` alias exactly as the engine's `withConfig` does.\n */\n config?: Record<string, Record<string, unknown>>;\n /**\n * Each node's static metadata ({@link ExpressionOptions.nodeMeta}), laid under the state's own\n * `meta` (which wins key by key) exactly as the engine's `withConfig` does.\n */\n meta?: Record<string, Record<string, unknown>>;\n}\n\nconst VAR_PREFIX = \"var.\";\n/** The permanent alias of {@link VAR_PREFIX}, still read (engine `evalRoot`). */\nconst LEGACY_VARS_PREFIX = \"vars.\";\nconst DOCUMENTS_PREFIX = \"documents.\";\nconst CONST_PREFIX = \"const.\";\n\nconst STATE_PREFIX = \"state.\";\n\n/** `vars.<x>`/`state.<x>` → `var.<x>` (bare `vars`/`state` → `var`); every other ref unchanged. */\nfunction canonicalRef(ref: string): string {\n if (ref === \"state\" || ref === \"vars\") return \"var\";\n if (ref.startsWith(LEGACY_VARS_PREFIX)) return VAR_PREFIX + ref.slice(LEGACY_VARS_PREFIX.length);\n if (ref.startsWith(STATE_PREFIX)) return VAR_PREFIX + ref.slice(STATE_PREFIX.length);\n return ref;\n}\n\n/** Collision rank of a sample key's spelling in the one state tree: `state.` > `var.` > `vars.`. */\nfunction stateSpellingRank(rawRef: string): number {\n if (rawRef.startsWith(STATE_PREFIX)) return 3;\n if (rawRef.startsWith(VAR_PREFIX)) return 2;\n return 1;\n}\n\ninterface StateSampleTree {\n children: Map<string, StateSampleTree>;\n rank: number;\n value?: unknown;\n}\n\n/** Whole objects are authoritative; descendant samples only index their fields for the picker. */\nfunction stateSampleValue(tree: StateSampleTree): unknown {\n if (tree.rank > 0) return tree.value;\n return Object.fromEntries(\n Array.from(tree.children, ([key, child]) => [key, stateSampleValue(child)]),\n );\n}\n\n/**\n * Build a {@link ResolveScope} from the two sources scope fidelity requires\n * they come from separately:\n *\n * - `steps`/`trigger` come from `testStartState` — the exact object the test\n * invoke sends as `state`, so a `steps.<id>.output.<field>` ref resolves to\n * what the test will ACTUALLY see, not a design-time sample.\n * - `vars`/`documents`/`constants` come from `sampleValues` (`useExpressionOptions()`), a\n * FLAT map keyed by full ref (`\"var.from_email\"`, `\"documents.<key>\"`, `\"const.<name>\"`).\n * State paths are reconstructed into one nested tree; whole-object samples\n * take precedence over their indexed descendants. The original flat map\n * remains available for exact field lookups, including parsed document fields.\n */\nexport function buildResolveScope(\n sampleValues: Record<string, unknown> | undefined,\n testStartState: StepStartState | undefined,\n config?: Record<string, Record<string, unknown>>,\n meta?: Record<string, Record<string, unknown>>,\n): ResolveScope {\n const stateSamples: StateSampleTree = { children: new Map(), rank: 0 };\n const documents: Record<string, unknown> = {};\n const constants: Record<string, unknown> = {};\n for (const [rawRef, value] of Object.entries(sampleValues ?? {})) {\n const ref = canonicalRef(rawRef);\n if (ref.startsWith(VAR_PREFIX)) {\n const key = ref.slice(VAR_PREFIX.length);\n const rank = stateSpellingRank(rawRef);\n let branch = stateSamples;\n for (const segment of key.split(\".\")) {\n let child = branch.children.get(segment);\n if (!child) {\n child = { children: new Map(), rank: 0 };\n branch.children.set(segment, child);\n }\n branch = child;\n }\n if (rank >= branch.rank) {\n branch.value = value;\n branch.rank = rank;\n }\n } else if (ref.startsWith(DOCUMENTS_PREFIX))\n documents[ref.slice(DOCUMENTS_PREFIX.length)] = value;\n else if (ref.startsWith(CONST_PREFIX)) constants[ref.slice(CONST_PREFIX.length)] = value;\n }\n const vars = stateSampleValue(stateSamples) as Record<string, unknown>;\n const steps =\n (testStartState?.steps as Record<string, { output?: unknown; meta?: StepMeta }>) ?? {};\n // `foreach.item` is the whole element; `foreach.item.<k>` flat keys are the same value\n // walked, so only the whole-element key (and the index) are read.\n const sv = sampleValues ?? {};\n const hasItem = Object.hasOwn(sv, \"foreach.item\");\n const hasIndex = typeof sv[\"foreach.index\"] === \"number\";\n // A seeded `testStartState.foreach` is what the invoke is SENT, so it wins whole — exactly as\n // `steps` come only from `testStartState` — and the flat sample keys are never mixed in.\n const seeded = testStartState?.foreach;\n const foreach = seeded\n ? { ...seeded }\n : hasItem || hasIndex\n ? {\n ...(hasItem ? { item: sv[\"foreach.item\"] } : {}),\n ...(hasIndex ? { index: sv[\"foreach.index\"] as number } : {}),\n }\n : undefined;\n return {\n ...(foreach ? { foreach } : {}),\n vars,\n state: vars,\n documents,\n constants,\n steps,\n nodes: steps,\n trigger: testStartState?.trigger ?? {},\n flat: sampleValues ?? {},\n ...(config ? { config } : {}),\n ...(meta ? { meta } : {}),\n };\n}\n\n/**\n * `getVar`-style dot-path walk (mirrors `packages/core/packages/expr/src/jsonlogic.ts`'s\n * `getVar`: `String(path).split(\".\")`, `cur = cur[part]`), but — the one\n * deliberate improvement a design-time PREVIEW can make that the run-time\n * engine cannot — it reports PRESENCE as a first-class result instead of\n * collapsing \"path absent\" and \"path present but null\" to the same fallback.\n * A hop into `null`/a non-object with segments still remaining is \"absent\",\n * never a value to keep walking into.\n */\nfunction walkPath(\n root: Record<string, unknown>,\n path: string,\n): { present: boolean; value: unknown } {\n const parts = path.split(\".\");\n let cur: unknown = root;\n for (const part of parts) {\n if (cur === null || typeof cur !== \"object\") return { present: false, value: undefined };\n if (!(part in (cur as Record<string, unknown>))) return { present: false, value: undefined };\n cur = (cur as Record<string, unknown>)[part];\n }\n return { present: true, value: cur };\n}\n\n/** `nodes.<id>.meta.config…` / `nodes.<id>.config…` (and the `steps.` spelling). */\nconst CONFIG_REF = /^(?:nodes|steps)\\.[^.]+\\.(?:meta\\.)?config(?:\\.|$)/;\n/** `nodes.<id>.meta…` (and the `steps.` spelling), capturing the node id. */\nconst META_REF = /^(?:nodes|steps)\\.([^.]+)\\.meta(?:\\.|$)/;\n\n/**\n * A `nodes` map with each node's static meta and config laid over its entry — the static meta\n * under the entry's own meta (which wins), the config at `meta.config` and at the `config` alias\n * — the engine's `withConfig` (`@w6w/workflow` `expr.ts`). A copy.\n */\nfunction withConfig(\n nodes: ResolveScope[\"steps\"],\n config: ResolveScope[\"config\"],\n meta?: ResolveScope[\"meta\"],\n): ResolveScope[\"steps\"] {\n if (!config && !meta) return nodes;\n const out: Record<string, unknown> = { ...nodes };\n for (const id of new Set([...Object.keys(meta ?? {}), ...Object.keys(config ?? {})])) {\n const c = config?.[id];\n out[id] = {\n ...nodes[id],\n meta: { ...meta?.[id], ...nodes[id]?.meta, ...(c ? { config: c } : {}) },\n ...(c ? { config: c } : {}),\n };\n }\n return out as ResolveScope[\"steps\"];\n}\n\n/** Resolve a single `var`/`$`-marker ref against the scope. */\nfunction resolveRef(ref: string, scope: ResolveScope): ResolvedSegment {\n const path = canonicalRef(ref);\n // A `var.*`/`documents.*`/`const.*` ref that `sampleValues` already names directly\n // (any number of segments) resolves exactly, before the nested walk below\n // ever gets a chance to misreconstruct it — see `ResolveScope.flat`'s doc.\n if (\n scope.flat &&\n (path.startsWith(VAR_PREFIX) ||\n path.startsWith(DOCUMENTS_PREFIX) ||\n path.startsWith(CONST_PREFIX))\n ) {\n const key = stateAliasSpellings(ref).find((k) => Object.hasOwn(scope.flat as object, k));\n if (key !== undefined) return { status: \"resolved\", ref, value: scope.flat[key] };\n }\n // The engine's data root: `var`/`const` over the `vars`/`constants` fields, and\n // `nodes.<id>…`/`steps.<id>…` as two roots over one state object.\n const { vars, constants, config, meta, ...rest } = scope;\n const nodes = withConfig(scope.nodes ?? scope.steps, config, meta);\n const root: Record<string, unknown> = {\n ...rest,\n var: vars,\n ...(constants ? { const: constants } : {}),\n nodes,\n steps: nodes,\n };\n const walked = walkPath(root, path);\n if (walked.present) return { status: \"resolved\", ref, value: walked.value };\n // A node's config is read on every run whether or not the node runs, and the host adds keys\n // (a webhook's `url`) the client may not have: unknown here is \"the run fills it\", not a failure.\n if (CONFIG_REF.test(path)) return { status: \"at-run\", ref };\n // …and a meta key a node's static meta lacks (an unknown `version`) is reported by its run.\n const metaOf = META_REF.exec(path)?.[1];\n if (metaOf !== undefined && meta?.[metaOf]) return { status: \"at-run\", ref };\n return { status: \"unresolved\", ref };\n}\n\n/** Resolve one {@link ExprPart} of a multipart `ExprValue`. */\nfunction resolvePart(part: ExprPart, scope: ResolveScope): ResolvedSegment {\n switch (part.kind) {\n case \"text\":\n return { status: \"resolved\", value: part.value ?? \"\" };\n case \"var\":\n return resolveRef(part.ref ?? \"\", scope);\n case \"secret\":\n // A named secret reference is ALWAYS masked — never looked up, never\n // shown, regardless of whether the name is \"in scope\". Mirrors the\n // engine/editor precedent: the plaintext never reaches the client at\n // all, so there is nothing to resolve here, only something to hide.\n return { status: \"masked\", ref: part.ref };\n case \"expr\":\n // Raw JSONLogic — no client-side evaluator exists anywhere in `ui`\n // (confirmed by the gap analysis). Labeled \"not evaluated\": a distinct\n // status from \"unresolved\", never rendered as if it were a value.\n return { status: \"not-evaluated\" };\n case \"render\":\n // The resolved ref is itself parsed as a `{{ }}` template and rendered\n // against the run scope — that needs the run's own resolver (T2.1.1),\n // not this design-time preview. Same honest answer as `expr` above;\n // without this arm the `default:` below reports a render part as\n // RESOLVED with `undefined`, i.e. a blank that looks correct.\n return { status: \"not-evaluated\" };\n default:\n return { status: \"resolved\", value: undefined };\n }\n}\n\n/** A hand-authored whole-value path marker: `{ \"$\": \"<path>\" }`, exactly one key. */\nexport function isDollarPath(v: unknown): v is { $: unknown } {\n return (\n typeof v === \"object\" &&\n v !== null &&\n !Array.isArray(v) &&\n Object.keys(v as object).length === 1 &&\n \"$\" in (v as object)\n );\n}\n\n/** A hand-authored whole-value JSONLogic marker: `{ \"$expr\": <logic> }`, exactly one key. */\nexport function isDollarExpr(v: unknown): v is { $expr: unknown } {\n return (\n typeof v === \"object\" &&\n v !== null &&\n !Array.isArray(v) &&\n Object.keys(v as object).length === 1 &&\n \"$expr\" in (v as object)\n );\n}\n\n/**\n * Resolve one configured param VALUE (or one `vars`-row's `value`, per A5 — the\n * same function, called again per row) against `scope`. Returns one segment\n * per part of a multipart `ExprValue`, or a single segment for anything else:\n * a `SecretValue` at-rest envelope (`masked`), a hand-authored `{\"$\":…}` /\n * `{\"$expr\":…}` marker (resolved as a ref lookup / not-evaluated — NOT as a\n * literal object, per the acceptance pin), or a plain literal (`resolved`,\n * `value` as-is, no `ref`).\n */\nexport function resolveParamValue(value: unknown, scope: ResolveScope): ResolvedSegment[] {\n if (isSecretValue(value)) return [{ status: \"masked\" }];\n if (isExprValue(value)) return (value as ExprValue).parts.map((p) => resolvePart(p, scope));\n // A `{{ }}` template string resolves exactly as the engine resolves it (escapes consumed);\n // one marker alone folds to the typed value (`foldResolvedSegments`).\n if (typeof value === \"string\") {\n const parts = parseResolvableText(value);\n if (parts) return parts.map((p) => resolvePart(p, scope));\n }\n if (isDollarPath(value)) return [resolveRef(String((value as { $: unknown }).$), scope)];\n if (isDollarExpr(value)) return [{ status: \"not-evaluated\" }];\n return [{ status: \"resolved\", value }];\n}\n\n/**\n * Structural deep-equality over JSON-shaped values (primitives, arrays, plain\n * objects, recursively) — no new dependency. Used by the Test tab's \"unchanged\n * from default\" filter (D-1/A1): equality, not presence, so a value the\n * hand-editable JSON view baked in explicitly is still recognized as\n * unchanged when it matches the declared default. `a === b` covers primitives\n * (including `undefined === undefined`, so a param with neither a value nor a\n * declared default is \"equal\" too) and short-circuits identical references\n * before the recursive object/array walk.\n */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (a === null || b === null || typeof a !== \"object\") return false;\n const aArr = Array.isArray(a);\n const bArr = Array.isArray(b as object);\n if (aArr !== bArr) return false;\n if (aArr) {\n const arrA = a as unknown[];\n const arrB = b as unknown[];\n return arrA.length === arrB.length && arrA.every((v, i) => deepEqual(v, arrB[i]));\n }\n const objA = a as Record<string, unknown>;\n const objB = b as Record<string, unknown>;\n const keysA = Object.keys(objA);\n const keysB = Object.keys(objB);\n return (\n keysA.length === keysB.length && keysA.every((k) => k in objB && deepEqual(objA[k], objB[k]))\n );\n}\n","/**\n * Fold a param's resolved {@link ResolvedSegment}s into the one JSON value the\n * Test tab's code view shows (A6). Distinct from both existing serializers:\n * `resolve-params.ts` stops at the per-segment array (what `ResolvedParams`\n * renders as chips + badges), and `flow-utils.ts`'s `stepToJson`/`paramsToJson`\n * serialize the raw stored step/`with` — the schema-shaped envelope this view\n * must never leak (a `{type:\"expr\",parts:[…]}` blob, or worse, `ciphertext`).\n *\n * No React, no JSX — a pure, `node --test`-covered module, mirroring the\n * `resolve-params.ts` precedent this sits beside.\n */\nimport { type ResolveScope, type ResolvedSegment, resolveParamValue } from \"./resolve-params.ts\";\n\n/**\n * Fold ONE segment into its JSON token. `value === undefined` on a `resolved`\n * segment folds to `\"<not set>\"`, never to an omitted key — `JSON.stringify`\n * drops `undefined` keys on its own, and a silently missing key is exactly the\n * D-6 defect (blank-indistinguishable-from-null) this module exists to avoid.\n */\nfunction foldOne(seg: ResolvedSegment): unknown {\n switch (seg.status) {\n case \"resolved\":\n return seg.value === undefined ? \"<not set>\" : seg.value;\n case \"unresolved\":\n return `<unresolved: ${seg.ref}>`;\n case \"at-run\":\n return `<resolved at run: ${seg.ref}>`;\n case \"not-evaluated\":\n return \"<not evaluated>\";\n case \"masked\":\n return seg.ref ? `<masked: ${seg.ref}>` : \"<masked>\";\n }\n}\n\n/** Render one segment as TEXT for the multi-segment concatenation case. */\nfunction foldOneAsText(seg: ResolvedSegment): string {\n if (seg.status === \"resolved\" && seg.value !== undefined) {\n return typeof seg.value === \"string\" ? seg.value : JSON.stringify(seg.value);\n }\n return String(foldOne(seg));\n}\n\n/**\n * Fold a param's full segment array (the shape {@link resolveParamValue}\n * returns) into ONE JSON value, per A6's pinned table: a single segment folds\n * to its own token/value; multiple segments (a multipart `ExprValue`)\n * concatenate into one string, each `resolved` part contributing its text\n * (strings as-is, non-strings `JSON.stringify`d) and every other part\n * contributing its placeholder token.\n */\nexport function foldResolvedSegments(segments: ResolvedSegment[]): unknown {\n if (segments.length === 1) return foldOne(segments[0]);\n return segments.map(foldOneAsText).join(\"\");\n}\n\n/** Resolve + fold one param VALUE against `scope` in a single call. */\nexport function resolveParamJson(value: unknown, scope: ResolveScope): unknown {\n return foldResolvedSegments(resolveParamValue(value, scope));\n}\n\n/**\n * A `vars`-typed param's configured rows, folded into one object keyed by\n * each row's own `key` (`\"(no key)\"` when blank — mirrors `ResolvedVarsRow`'s\n * fallback), each row's `value` folded by the same rules as any other param.\n */\nexport function resolveVarsJson(\n rows: Array<{ key?: string; value: unknown }>,\n scope: ResolveScope,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const row of rows) {\n out[row.key || \"(no key)\"] = resolveParamJson(row.value, scope);\n }\n return out;\n}\n","import { type ReactNode, forwardRef } from \"react\";\nimport { Icon } from \"./Icon.tsx\";\nimport type { IconName } from \"./icons.tsx\";\n\nexport interface IconButtonProps {\n /** Accessible name — ALWAYS rendered as `aria-label`. Required: an icon-only\n * button with no name has no safe default (unlike `Copyable`'s `label`,\n * which is always \"Copy\"). */\n label: string;\n /** The glyph, as caller-supplied markup. Still the primary path — pass this\n * or `icon` (both given ⇒ `children` wins). */\n children?: ReactNode;\n /** The glyph, by name from the shared set (`./icons.tsx`) — e.g. `\"history\"`.\n * Renders `<Icon name={icon} size={iconSize ?? 16} />`, decorative, so this\n * button's `label` stays the only thing announced. */\n icon?: IconName;\n /** Size handed to `Icon`. Default 16. No effect without `icon`. */\n iconSize?: number;\n /** Tooltip override. Defaults to `label`; `aria-label` is ALWAYS `label`, so\n * the two may legitimately differ (see the docblock). */\n title?: string;\n /** Required — an icon-only button that can't fire has no reason to exist. */\n onClick: () => void;\n disabled?: boolean;\n className?: string;\n /** Caller opts into danger styling; `IconButton` itself has no \"delete\" concept. */\n danger?: boolean;\n /** Passed straight through, for a toggle button. */\n \"aria-pressed\"?: boolean;\n /** Passed straight through, for a disclosure button. */\n \"aria-expanded\"?: boolean;\n /** Passed straight through, for a disclosure button naming the region it controls. */\n \"aria-controls\"?: string;\n \"data-testid\"?: string;\n}\n\n/**\n * The primitive icon-only button: a caller-supplied glyph, a required\n * accessible name, native `disabled`, and a merged `className`.\n *\n * `EditButton`/`DeleteButton` build on this and bundle one canonical glyph\n * each — this component itself carries no glyph and no \"edit\"/\"delete\"\n * meaning, only the `danger` styling hook.\n *\n * The glyph comes from one of two places. `children` is the original path and\n * still works unchanged; `icon` names one from the shared set (`./icons.tsx`)\n * and is rendered through `Icon`, so a caller no longer has to redraw (or\n * import) an SVG for a glyph the set already holds. Given both, `children`\n * wins — the named prop is the convenience, never a way to hide a caller's own\n * markup.\n *\n * `label` is always the accessible name, and `title` overrides ONLY the\n * tooltip. The two legitimately differ: studio's history button is named\n * \"Execution history\" while, with nothing executed yet, its tooltip reads \"No\n * executions yet\" — the tooltip says why the control is inert to a sighted\n * user, the name stays the action, and a screen reader must keep hearing the\n * latter.\n *\n * `ref` reaches the `<button>` itself (`forwardRef` — React 18, so the\n * ref-as-prop syntax is not available), which is what a caller needs to move\n * focus or measure the control.\n */\nexport const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(\n function IconButton(props, ref) {\n const {\n label,\n children,\n icon,\n iconSize,\n title,\n onClick,\n disabled,\n className,\n danger,\n ...rest\n } = props;\n const glyph = children ?? (icon ? <Icon name={icon} size={iconSize ?? 16} /> : null);\n return (\n <button\n ref={ref}\n type=\"button\"\n className={[\"w6w-icon-button\", danger ? \"w6w-icon-button-danger\" : \"\", className ?? \"\"]\n .filter(Boolean)\n .join(\" \")}\n title={title ?? label}\n aria-label={label}\n aria-pressed={rest[\"aria-pressed\"]}\n aria-expanded={rest[\"aria-expanded\"]}\n aria-controls={rest[\"aria-controls\"]}\n disabled={disabled}\n onClick={onClick}\n data-testid={rest[\"data-testid\"]}\n >\n {glyph}\n </button>\n );\n },\n);\n\nIconButton.displayName = \"IconButton\";\n","import { type ReactNode, useEffect, useRef } from \"react\";\n\ninterface ModalProps {\n /** Title row content. A plain string also seeds the dialog's `aria-label`. */\n title: ReactNode;\n /** Accessible name for the dialog; defaults to `title` when it's a string. */\n ariaLabel?: string;\n onClose: () => void;\n children: ReactNode;\n /**\n * Dialog width. `\"wide\"` fits a sidebar + content layout; `\"xl\"` is a large\n * work surface (e.g. the app picker); `\"full\"` is a near-fullscreen work\n * surface (e.g. the expression editor) that fills most of the viewport;\n * `\"fullscreen\"` is edge-to-edge 100vw x 100vh with no visible backdrop.\n *\n * `\"fullscreen\"` leaves NO backdrop to click, so outside-click dismissal is\n * unreachable by construction — a caller using it must give the user a\n * visible way out via {@link ModalProps.headerRight} (Esc alone is not a\n * discoverable affordance).\n */\n size?: \"default\" | \"wide\" | \"xl\" | \"full\" | \"fullscreen\";\n /** Optional node rendered next to the title (e.g. an app icon). */\n titleIcon?: ReactNode;\n /** Optional muted meta rendered after the title (e.g. an app's id + version). */\n subtitle?: ReactNode;\n /** Optional node rendered at the far right of the title row (e.g. a back button). */\n headerRight?: ReactNode;\n}\n\n/**\n * Small dialog modal. Built on the native `<dialog>` element so it gets focus\n * trapping, Esc-dismiss, and accessibility semantics for free. A button\n * positioned over the backdrop catches outside-clicks to close.\n */\nconst SIZE_CLASS: Record<NonNullable<ModalProps[\"size\"]>, string> = {\n default: \"\",\n wide: \" w6w-modal-wide\",\n xl: \" w6w-modal-xl\",\n full: \" w6w-modal-full\",\n fullscreen: \" w6w-modal-fullscreen\",\n};\n\nexport function Modal({\n title,\n ariaLabel,\n onClose,\n children,\n size = \"default\",\n titleIcon,\n subtitle,\n headerRight,\n}: ModalProps) {\n const ref = useRef<HTMLDialogElement>(null);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n if (!el.open) el.showModal();\n const onCancel = (e: Event) => {\n e.preventDefault();\n onClose();\n };\n // A `showModal()` dialog and its ::backdrop live in the browser's top layer,\n // above any sibling overlay — so an overlay button can't catch outside\n // clicks. Backdrop clicks are dispatched with the dialog as target, so\n // treat a click landing outside the dialog's box as a dismiss.\n const onClick = (e: MouseEvent) => {\n if (e.target !== el) return;\n const r = el.getBoundingClientRect();\n const outside =\n e.clientX < r.left || e.clientX > r.right || e.clientY < r.top || e.clientY > r.bottom;\n if (outside) onClose();\n };\n el.addEventListener(\"cancel\", onCancel);\n el.addEventListener(\"click\", onClick);\n return () => {\n el.removeEventListener(\"cancel\", onCancel);\n el.removeEventListener(\"click\", onClick);\n };\n }, [onClose]);\n\n return (\n <div className=\"w6w-modal-backdrop\">\n <dialog\n ref={ref}\n className={`w6w-modal${SIZE_CLASS[size]}`}\n aria-label={ariaLabel ?? (typeof title === \"string\" ? title : undefined)}\n >\n <div className=\"w6w-modal-header\">\n <h3 className=\"w6w-modal-title\">\n {titleIcon}\n <span>{title}</span>\n {subtitle && <span className=\"w6w-modal-subtitle\">{subtitle}</span>}\n </h3>\n {headerRight}\n </div>\n {children}\n </dialog>\n </div>\n );\n}\n","import {\n evaluate,\n expressionReferences,\n formatReadableExpression,\n parseReadableExpression,\n} from \"@w6w/expr\";\nimport type { ExprPart } from \"../types.ts\";\nimport type { ExpressionOptions } from \"./ExpressionOptions.tsx\";\nimport {\n parseRootAnchoredTemplate,\n renderResult,\n serializeTemplate,\n} from \"./expression-template.ts\";\n\nconst ROOTS = new Set([\n \"nodes\",\n \"steps\",\n \"state\",\n \"var\",\n \"vars\",\n \"const\",\n \"inputs\",\n \"output\",\n \"trigger\",\n \"foreach\",\n \"documents\",\n]);\nconst OPERATOR = /[=<>]|!=|&&|\\|\\||\\?\\?/;\nconst hasOperator = (source: string) => OPERATOR.test(source) || /^\\s*\\(*\\s*!/.test(source);\nconst hasComparisonRefs = (expr: unknown) => expressionReferences(expr).some(hasOperator);\n\nfunction resolveAuthorRef(ref: string, options: ExpressionOptions): string {\n const [first, ...rest] = ref.split(\".\");\n if (first === \"secrets\")\n throw new Error(\"Secrets can be inserted into text, but cannot be used in comparisons.\");\n if (ROOTS.has(first)) return ref;\n const candidates = [\n ...(options.steps?.some((step) => step.id === first) ? [`nodes.${first}.output`] : []),\n ...(options.vars?.includes(first) ? [`var.${first}`] : []),\n ...(options.constants?.includes(first) ? [`const.${first}`] : []),\n ];\n if (candidates.length > 1)\n throw new Error(`“${first}” is ambiguous. Select the field from the sources.`);\n if (candidates.length === 0)\n throw new Error(`Unknown field “${first}”. Select a source, or put text values in quotes.`);\n return [candidates[0], ...rest].join(\".\");\n}\n\n/** Compile an entire condition, including picker chips followed by typed operators. Plain\n * text/templates stay unchanged. The persisted value uses the existing JSONLogic wire format. */\nexport function compileAuthoredParts(\n original: ExprPart[],\n options: ExpressionOptions,\n): { parts: ExprPart[]; error: string | null } {\n const unchanged = { parts: original, error: null };\n const parts = original.flatMap((part) =>\n part.kind === \"text\" ? parseRootAnchoredTemplate(part.value ?? \"\") : [part],\n );\n if (parts.some((part) => part.kind === \"render\")) return unchanged;\n // Already compiled: keep its exact AST (including legacy operators outside this syntax).\n if (parts.length === 1 && parts[0].kind === \"expr\" && !hasComparisonRefs(parts[0].expr))\n return { parts, error: null };\n let source = parts\n .map((part) => {\n if (part.kind === \"text\") return part.value ?? \"\";\n if (part.kind === \"secret\") return `{{ secrets.${part.ref ?? \"\"} }}`;\n if (part.kind === \"expr\") {\n // The older marker parser may have treated comparisons in a fallback chain\n // as variable names. Recover its infix text before compiling the condition.\n if (hasComparisonRefs(part.expr)) {\n const marker = serializeTemplate([part]);\n if (!marker.startsWith(\"{{ =\")) return `(${marker.slice(2, -2).trim()})`;\n }\n const readable = formatReadableExpression(part.expr);\n return readable === null ? serializeTemplate([part]) : `(${readable})`;\n }\n // Repair old chips that accidentally stored the whole comparison as a field path.\n return hasOperator(part.ref ?? \"\") ? (part.ref ?? \"\") : `{{ ${part.ref ?? \"\"} }}`;\n })\n .join(\"\")\n .trim();\n if (!hasOperator(source)) return unchanged;\n const wrapped = /^\\{\\{([^{}]+)\\}\\}$/.exec(source);\n if (wrapped && hasOperator(wrapped[1])) source = wrapped[1].trim();\n const start = source.replace(/^[\\s(!]+/, \"\");\n const first = /^(?:\\{\\{\\s*)?([A-Za-z_$][\\w$-]*)/.exec(start)?.[1];\n const knownStart =\n start.startsWith(\"{{\") ||\n (first !== undefined &&\n (ROOTS.has(first) ||\n first === \"secrets\" ||\n options.steps?.some((step) => step.id === first) ||\n options.vars?.includes(first) ||\n options.constants?.includes(first)));\n // Do not reinterpret ordinary prose/HTML that contains a reference and punctuation.\n if (!knownStart && !/^(?:[\"']|-?\\d|true\\b|false\\b|null\\b)/.test(start)) return unchanged;\n if (knownStart && !/^\\s*\\(*\\s*!/.test(source)) {\n const operand = /^(?:\\{\\{[^{}]+\\}\\}|[A-Za-z_$][\\w$-]*(?:\\.[\\w$-]+)*)/.exec(start)?.[0];\n if (operand) {\n const after = start.slice(operand.length).replace(/^[\\s)]+/, \"\");\n // A selected field can also start a URL or a text template. Only a directly\n // following operator begins a condition; later punctuation is ordinary text.\n if (!/^(?:[=<>(]|!=|&&|\\|\\||\\?\\?)/.test(after) || /^<\\/?[A-Za-z][^>]*>/.test(after))\n return unchanged;\n }\n }\n try {\n const expr = parseReadableExpression(source, (ref) => resolveAuthorRef(ref, options));\n return { parts: [{ kind: \"expr\", expr }], error: null };\n } catch (error) {\n return { parts, error: error instanceof Error ? error.message : \"Check the expression.\" };\n }\n}\n\n/** Sample fields include those inside comparisons, not just standalone reference chips. */\nexport function authoredReferences(parts: ExprPart[]): string[] {\n return [\n ...new Set(\n parts.flatMap((part) =>\n part.kind === \"expr\"\n ? expressionReferences(part.expr)\n : (part.kind === \"var\" || part.kind === \"render\") && part.ref\n ? [part.ref]\n : [],\n ),\n ),\n ];\n}\n\nfunction canonical(ref: string): string {\n return ref.replace(/^(?:vars|state)(?=\\.|$)/, \"var\").replace(/^steps(?=\\.|$)/, \"nodes\");\n}\n\nfunction sampleRoot(samples: Record<string, unknown>): Record<string, unknown> {\n const root: Record<string, unknown> = Object.create(null);\n // Parents first, then explicit leaf samples override them. Copy each path before writing;\n // never mutate the host's test outputs. Secrets never enter the evaluator's sample scope.\n for (const [ref, value] of Object.entries(samples).sort(\n ([a], [b]) => a.split(\".\").length - b.split(\".\").length,\n )) {\n const keys = canonical(ref).split(\".\");\n if (\n !ROOTS.has(keys[0]) ||\n keys.some((key) => [\"__proto__\", \"constructor\", \"prototype\"].includes(key))\n )\n continue;\n let target = root;\n for (const key of keys.slice(0, -1)) {\n const previous = target[key];\n const next = previous && typeof previous === \"object\" ? { ...previous } : {};\n target[key] = next;\n target = next;\n }\n target[keys[keys.length - 1]] = value;\n }\n root.steps = root.nodes;\n root.vars = root.var;\n root.state = root.var;\n return root;\n}\n\n/** Evaluate supported conditions with the same evaluator as workflow execution. Other legacy\n * expression forms keep their existing template preview. Explicit samples preserve JSON types. */\nexport function previewAuthoredParts(\n parts: ExprPart[],\n seeds: Record<string, unknown> = {},\n overrides: Record<string, string> = {},\n): string {\n const samples = { ...seeds };\n for (const [ref, text] of Object.entries(overrides)) {\n try {\n samples[ref] = JSON.parse(text);\n } catch {\n samples[ref] = text;\n }\n }\n const root = sampleRoot(samples);\n const textSamples = Object.fromEntries(\n Object.entries(samples).map(([ref, value]) => [\n ref,\n typeof value === \"string\" ? value : JSON.stringify(value),\n ]),\n );\n return parts\n .map((part) => {\n if (part.kind !== \"expr\" || formatReadableExpression(part.expr) === null)\n return renderResult([part], textSamples);\n const refs = expressionReferences(part.expr);\n if (refs.some((ref) => !ref || ref.split(\".\")[0] === \"secrets\")) return \"••••\";\n const value = evaluate(part.expr, root);\n return typeof value === \"string\" ? value : (JSON.stringify(value) ?? \"\");\n })\n .join(\"\");\n}\n","import { type CoalesceChain, formatReadableExpression, parseCoalesceChain } from \"@w6w/expr\";\nimport type { ExprPart } from \"../types.ts\";\nimport { parseRootAnchoredTemplate, serializeTemplate } from \"./expression-template.ts\";\n\n/**\n * DOM helpers for the inline / modal expression editors: they render a value's\n * parts as editable text with atomic, non-editable CHIPS (tags) inline in the\n * flow, and read the parts back out of the contentEditable DOM. Shared so the\n * inline field and the full editor modal agree on chip markup and parsing.\n */\n\n/**\n * A step-output ref: `steps.<id>.output` optionally followed by `.<field…>`.\n *\n * The id is one dot-free segment (`[^.]+`): a step id may not contain `.`, so a\n * dotted ref such as `steps.my.step.output.email` is NOT a step ref and falls\n * through to {@link varLabel}'s verbatim branch.\n */\nconst STEP_OUTPUT_REF = /^(?:nodes|steps)\\.([^.]+)\\.output(?:\\.(.+))?$/;\n\n/** `steps.<id>.meta.<key>` for exactly the four metadata keys; the output form is tried first. */\nconst STEP_META_REF = /^(?:nodes|steps)\\.([^.]+)\\.meta\\.(app|version|action|connectionId)$/;\n\n/**\n * The name a source or chip DISPLAYS. Never the ref it SAVES.\n *\n * A saved ref is always canonical and engine-resolvable — the run scope offers\n * exactly `var.* · steps.<id>.output.* · steps.<id>.meta.* · trigger.* · secrets.* · documents.* · const.* ·\n * inputs.* · foreach.* · output.*` (`core/rfcs/workflow.md` §Expressions, built\n * in `w6w-workflow/packages/engine/src/run.ts`). Those read long in a field, so\n * the label drops the root the chip's sigil and colour already imply:\n *\n * | ref | label |\n * |-----------------------------|----------------|\n * | `var.from_email` | `from_email` |\n * | `steps.gate_1.output` | `gate_1` |\n * | `steps.gate_1.output.email` | `gate_1.email` |\n * | `steps.gate_1.meta.version` | `gate_1 meta · version` |\n * | anything else | verbatim |\n *\n * **`gate_1.email` is a LABEL ONLY — it is not an expression.** There is no\n * `gate_1` key at the run-scope root, so a chip that STORED the short form would\n * render perfectly in the editor and resolve to empty at run time, silently and\n * untraceably. `makeChip` keeps the two apart deliberately: the chip's stored\n * attribute carries the ref, this function only ever feeds `label.textContent`.\n */\nexport const varLabel = (ref: string): string => {\n if (ref.startsWith(\"var.\")) return ref.slice(\"var.\".length);\n if (ref.startsWith(\"vars.\")) return ref.slice(\"vars.\".length);\n if (ref.startsWith(\"const.\")) return ref.slice(\"const.\".length);\n const m = STEP_OUTPUT_REF.exec(ref);\n if (m) return m[2] ? `${m[1]}.${m[2]}` : m[1];\n const meta = STEP_META_REF.exec(ref);\n if (meta) return `${meta[1]} meta · ${meta[2]}`;\n return ref;\n};\n\n/** `v`'s `var` ref if `v` is a single-key `{ var: <string> }` object, else `undefined`. Mirrors\n * `@w6w/expr`'s own private `asVarOperand` (`core/packages/expr/src/template.ts`) — not exported,\n * so this repeats the shape check `parseCoalesceChain` already validated, purely to tell a `var`\n * operand from a literal one when rendering; it does not re-derive whether `part.expr` IS a chain. */\nfunction chainOperandVarRef(v: unknown): string | undefined {\n if (v === null || typeof v !== \"object\" || Array.isArray(v)) return undefined;\n const keys = Object.keys(v as Record<string, unknown>);\n if (keys.length !== 1 || keys[0] !== \"var\") return undefined;\n const ref = (v as Record<string, unknown>).var;\n return typeof ref === \"string\" ? ref : undefined;\n}\n\n/**\n * A recognised `||`/`??` chain's chip LABEL (D-2) — mirrors {@link varLabel}'s split between what\n * a chip DISPLAYS and what it SAVES: `data-expr` (in {@link makeChip}) is the stored JSONLogic\n * untouched; this is display-only, built from the chain's own operands rather than truncated raw\n * JSON. A `{ var: ref }` operand renders through `varLabel` (the short form); any other operand (a\n * JSON primitive literal) renders through `JSON.stringify`. Do NOT call `varLabel` on the whole\n * chain — only on each `var` operand, same as a standalone `var` chip would.\n */\nfunction chainLabel(chain: CoalesceChain): string {\n const token = chain.op === \"or\" ? \"||\" : \"??\";\n const text = chain.operands\n .map((operand) => {\n const ref = chainOperandVarRef(operand);\n return ref !== undefined ? varLabel(ref) : JSON.stringify(operand);\n })\n .join(` ${token} `);\n return text.length > 40 ? `${text.slice(0, 40)}…` : text;\n}\n\n/**\n * A key that cannot survive the trip from picker to engine, by CHARACTER.\n *\n * - `.` — JSONLogic's `var` splits its path on \".\" with **no escape and no\n * bracket form** (`core/packages/expr/src/jsonlogic.ts` `getVar`:\n * `String(path).split(\".\")`), so a key `a.b` becomes the lookup\n * `output → a → b` and yields `null`. There is no spelling that reaches it.\n * - `{` / `}` — they collide with the `{{ … }}` template grammar\n * (`expression-template.ts`), so the ref does not survive the text round trip.\n *\n * Interior whitespace is deliberately NOT here: `output[\"first name\"]` is a\n * plain property lookup that `getVar` performs correctly, and\n * `{{ steps.g.output.first name }}` round-trips (only the OUTER pad is trimmed).\n * Leading/trailing whitespace IS rejected, below — that pad is what gets eaten.\n */\nconst UNREACHABLE_KEY_CHARS = /[.{}]/;\n\n/**\n * Whether a declared output key can become a ref the engine actually resolves.\n *\n * A key that fails this would still produce a chip that renders perfectly and\n * evaluates to **empty at run time, silently** — the same failure mode the\n * label/ref split exists to avoid — so the picker must not offer it at all. The\n * step's WHOLE output (`steps.<id>.output`) is still offered, which remains the\n * author's route to such a field via an explicit `=` JSONLogic expression.\n */\nexport function isRefSafeKey(key: string): boolean {\n if (key === \"\" || key !== key.trim()) return false;\n return !UNREACHABLE_KEY_CHARS.test(key);\n}\n\n/**\n * Whether a declared output PATH (`start.utc` — an app action's `OutputField`\n * key, where `.` means nesting, not a literal character) can become a ref the\n * engine resolves: the same `getVar` split that makes a literal `a.b` key\n * unreachable is what walks a path, so each SEGMENT must pass\n * {@link isRefSafeKey} on its own.\n */\nexport function isRefSafePath(path: string): boolean {\n return path.split(\".\").every(isRefSafeKey);\n}\n\n/**\n * Lay a step's flat output fields out as a tree for the picker: each row shows only its OWN\n * name, nested under the nearest listed ancestor. `event`, `event.tz`, `event.start.utc` read as\n * `event` › `tz`, `start.utc` — the step id and the shared prefix are what truncated every row to\n * the same `eventbrite_to_cohost_1.event.…`. A literal key (no `path`) is one name at depth 0.\n * Display only: the ref is still built from the verbatim `key`.\n */\nexport function outputFieldTree<F extends { key: string; path?: boolean }>(\n fields: F[],\n): { field: F; depth: number; name: string }[] {\n const paths = new Set(fields.filter((f) => f.path).map((f) => f.key));\n return fields.map((field) => {\n if (!field.path) return { field, depth: 0, name: field.key };\n const segs = field.key.split(\".\");\n let depth = 0;\n let cut = 0;\n for (let i = 1; i < segs.length; i++) {\n if (paths.has(segs.slice(0, i).join(\".\"))) {\n depth++;\n cut = i;\n }\n }\n return { field, depth, name: segs.slice(cut).join(\".\") };\n });\n}\n\n/**\n * Build the non-editable inline chip (tag) DOM node for a part.\n *\n * `renderToggle` is opt-in and defaults OFF: `makeChip` is shared through\n * {@link paintParts} by every editing surface, including the inline\n * `ExpressionInput` (`ExpressionInput.tsx`), which has no handler for the\n * flip control at all. A painter must not decide who gets an affordance —\n * only `ExpressionEditorModal` (the one surface with a click delegate for\n * `[data-render-toggle]`) passes `true`. Round 2 fix for F-2: before this,\n * every `var`/`render` chip everywhere painted the toggle unconditionally,\n * so it leaked into every inline expression field in studio as a dead,\n * screen-reader-announced control.\n */\nexport function makeChip(\n doc: Document,\n part: ExprPart,\n { renderToggle }: { renderToggle?: boolean } = {},\n): HTMLElement {\n const span = doc.createElement(\"span\");\n span.contentEditable = \"false\";\n span.className = `w6w-expr-chip w6w-expr-chip-${part.kind}`;\n span.setAttribute(\"data-kind\", part.kind);\n\n const sigil = doc.createElement(\"span\");\n sigil.className = \"w6w-expr-chip-sigil\";\n const label = doc.createElement(\"span\");\n label.className = \"w6w-expr-chip-label\";\n\n if (part.kind === \"var\") {\n span.setAttribute(\"data-ref\", part.ref ?? \"\");\n // A small, quiet marker (accent colour carries the \"variable\" meaning) —\n // never the literal `{x}`, which read as noise crowding the field.\n sigil.textContent = \"◆\";\n label.textContent = varLabel(part.ref ?? \"\");\n span.title = `Variable: ${part.ref ?? \"\"}`;\n } else if (part.kind === \"render\") {\n span.setAttribute(\"data-ref\", part.ref ?? \"\");\n // A visually distinct sigil from a plain `var` chip: this ref's RESOLVED\n // value is itself parsed as a `{{ }}` template and rendered (the amendment\n // in `core/rfcs/workflow.md`). Same label rule — `varLabel` doesn't\n // depend on kind.\n sigil.textContent = \"▤\";\n label.textContent = varLabel(part.ref ?? \"\");\n span.title = `Render as template: ${part.ref ?? \"\"}`;\n } else if (part.kind === \"secret\") {\n span.setAttribute(\"data-ref\", part.ref ?? \"\");\n sigil.textContent = \"🔒\";\n label.textContent = part.ref ?? \"\"; // the NAME — never the value\n span.title = `Secret: ${part.ref ?? \"\"}`;\n } else {\n const raw = typeof part.expr === \"string\" ? part.expr : JSON.stringify(part.expr ?? \"\");\n span.setAttribute(\"data-expr\", raw); // display-only label below; the stored JSONLogic is unchanged.\n sigil.textContent = \"ƒ\";\n const chain = parseCoalesceChain(part.expr);\n if (chain) {\n label.textContent = chainLabel(chain);\n span.title = `Expression: ${serializeTemplate([part])}`;\n } else {\n const readable = formatReadableExpression(part.expr, varLabel);\n label.textContent = readable ?? (raw.length > 24 ? `${raw.slice(0, 24)}…` : raw || \"expr\");\n span.title = `Expression: ${readable ?? raw}`;\n }\n }\n\n span.append(sigil, label);\n\n if ((part.kind === \"var\" || part.kind === \"render\") && renderToggle) {\n // The render affordance: flip THIS chip between \"insert this ref\" (var)\n // and \"insert this ref, then render its resolved value as a `{{ }}`\n // template\" (render) — never a second, free-text ref-construction path.\n // The modal's click delegate handles the flip by rebuilding the chip via\n // `makeChip` from the SAME `data-ref`, never a re-derived string.\n const toggle = doc.createElement(\"span\");\n toggle.className = \"w6w-expr-chip-toggle\";\n toggle.setAttribute(\"data-render-toggle\", \"1\");\n toggle.setAttribute(\"role\", \"button\");\n const toggleLabel =\n part.kind === \"render\" ? \"Stop rendering as a template\" : \"Render this as a template\";\n toggle.setAttribute(\"aria-label\", toggleLabel);\n toggle.title = toggleLabel;\n toggle.textContent = \"⇄\";\n span.append(toggle);\n }\n\n const x = doc.createElement(\"span\");\n x.className = \"w6w-expr-chip-x\";\n x.setAttribute(\"data-x\", \"1\");\n x.setAttribute(\"role\", \"button\");\n x.setAttribute(\"aria-label\", \"Remove\");\n x.textContent = \"×\";\n span.append(x);\n return span;\n}\n\n/**\n * Elements `contentEditable` builds one-per-line. A block child means \"the\n * content before me ended a line\", so it contributes an implicit newline.\n */\nconst BLOCK_TAGS = new Set([\"div\", \"p\"]);\n\n/**\n * Decode a chip element back into the part it represents — the one and only\n * decode in the file. Hoisted out of {@link readParts}'s inline `var` /\n * `secret` / `render` (`data-ref`) and `expr` (`data-expr` JSON) arms so\n * {@link chipToText} can reuse the exact same logic rather than re-deriving\n * it; `readParts` itself now calls this instead of carrying its own copy.\n * `null` for any element that isn't a chip (`data-kind` absent or not one of\n * the four kinds) — the caller falls through to its other element handling.\n */\nexport function chipToPart(el: HTMLElement): ExprPart | null {\n const kind = el.getAttribute(\"data-kind\");\n if (kind === \"var\" || kind === \"secret\" || kind === \"render\") {\n return { kind, ref: el.getAttribute(\"data-ref\") ?? \"\" };\n }\n if (kind === \"expr\") {\n const raw = el.getAttribute(\"data-expr\") ?? \"\";\n let expr: unknown = raw;\n try {\n expr = JSON.parse(raw);\n } catch {\n expr = raw;\n }\n return { kind: \"expr\", expr };\n }\n return null;\n}\n\n/**\n * Reconstruct parts from an editor's DOM (the source of truth while editing).\n *\n * The walk is **recursive**: a native Enter wraps the caret's line in a `<div>`\n * (or drops a `<br>`), and anything nested inside it — chips included — must\n * survive. Reading `textContent` at that point would flatten a chip to its\n * label and silently destroy the reference it carries, so every unrecognised\n * element is descended into instead. `<br>` and block children map to a literal\n * `\"\\n\"`; `pushText` coalesces those into the surrounding text part.\n *\n * One `<br>` is deliberately NOT a newline: a FILLER one, closing its block —\n * see `walk` and {@link ensureFillerBreak}.\n */\nexport function readParts(root: HTMLElement): ExprPart[] {\n const parts: ExprPart[] = [];\n const pushText = (t: string) => {\n if (!t) return;\n const last = parts[parts.length - 1];\n if (last && last.kind === \"text\") last.value = (last.value ?? \"\") + t;\n else parts.push({ kind: \"text\", value: t });\n };\n\n /** `lastInBlock`: this node is the final child of the root, a `div` or a `p`. */\n const walk = (node: Node, lastInBlock: boolean) => {\n if (node.nodeType === Node.TEXT_NODE) {\n pushText(node.textContent ?? \"\");\n return;\n }\n if (node.nodeType !== Node.ELEMENT_NODE) return;\n const el = node as HTMLElement;\n\n const part = chipToPart(el);\n if (part) {\n parts.push(part);\n return;\n }\n\n // Browsers report `BR` / `DIV` uppercase for HTML documents.\n const tag = (el.tagName ?? \"\").toLowerCase();\n if (tag === \"br\") {\n // A <br> CLOSING its block is a FILLER, not a line the author made: it\n // exists so an otherwise-empty last line has a box for the caret to land\n // in. Three things produce one, all measured in Chromium\n // (`artifacts/T3.1.2-browser-check.sh`):\n // 1. {@link ensureFillerBreak}, after we insert our own \"\\n\";\n // 2. a PASTED blank line — `<div><br></div>`, where the block already\n // carries the break and the <br> only fills it. Counting both\n // inflates one blank line into two;\n // 3. the browser itself, after a `contentEditable=\"false\"` chip.\n // A <br> the author really made has content (or another line) after it\n // inside its block, so it is never the block's last child.\n if (!lastInBlock) pushText(\"\\n\");\n return;\n }\n // A *leading* block is the first line, not a break after something.\n const isBlock = BLOCK_TAGS.has(tag);\n if (isBlock && parts.length > 0) pushText(\"\\n\");\n walkChildren(el, isBlock);\n };\n\n const walkChildren = (parent: Node, isBlockParent: boolean) => {\n const children = Array.from(parent.childNodes);\n children.forEach((child, i) => walk(child, isBlockParent && i === children.length - 1));\n };\n\n walkChildren(root, true);\n return parts;\n}\n\n/**\n * Is this the filler `<br>` closing a block — the caret's landing pad, never\n * part of the value? Callers only ever ask it about a block's LAST child, which\n * is what makes \"a `<br>` here\" and \"a filler\" the same question (`readParts`\n * skips exactly this node).\n *\n * The test is deliberately narrower than \"is an element\": a block ending in a\n * CHIP is also ending in an element, and a chip is `contentEditable=\"false\"`, so\n * it gives the caret nowhere to land and still needs a filler after it.\n */\nconst isFillerBreak = (node: Node | null): boolean =>\n !!node && ((node as HTMLElement).tagName ?? \"\").toLowerCase() === \"br\";\n\n/**\n * Append the filler `<br>` that lets a `\"\\n\"` ENDING this block render.\n *\n * Idempotent — a block already closed by a `<br>` is left alone. That guard is\n * load-bearing, not tidiness: a second filler would no longer be the block's\n * last child, so `readParts` would read it as a real newline and the value would\n * grow a blank line per keystroke-that-triggers-a-fill.\n */\nfunction fillBlock(block: HTMLElement): void {\n if (isFillerBreak(block.lastChild)) return;\n block.appendChild(block.ownerDocument.createElement(\"br\"));\n}\n\n/**\n * The block the caret currently sits in, within `editor` — the editor itself\n * when the caret is at its top level, or is not inside it at all.\n *\n * The filler has to go in the SAME block as the newline it exists to render.\n * After a paste, the caret's line is an inner `<div>` (`one<div>three</div>`),\n * so filling the root instead would leave the `\"\\n\"` trailing inside the div\n * with nothing to render it — the very failure the filler exists to prevent.\n */\nfunction caretBlock(editor: HTMLElement): HTMLElement {\n const sel = editor.ownerDocument.getSelection();\n const range = sel?.rangeCount ? sel.getRangeAt(0) : null;\n // `editor.contains(...)`: a selection somewhere ELSE in the document must not\n // make us walk up into a foreign `div`/`p` and append a filler there. Nothing\n // reaches it today — `ensureFillerBreak`'s only callers are the two keydown\n // handlers, where the caret is inside the editor by construction — so no probe\n // can distinguish it from its absence (T3.1.2 eval, R2-5). It is kept because\n // the barrier is the CALL SITES, and the first non-keydown caller arms it.\n if (!range || !editor.contains(range.endContainer)) return editor;\n let node: Node | null = range.endContainer;\n while (node && node !== editor) {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const el = node as HTMLElement;\n if (BLOCK_TAGS.has((el.tagName ?? \"\").toLowerCase())) return el;\n }\n node = node.parentNode;\n }\n return editor;\n}\n\n/**\n * Give a line break at the very END of the caret's line somewhere to render.\n *\n * A `\"\\n\"` that is the last thing in a `white-space: pre-wrap` block paints\n * nothing, and the caret cannot land past it — the author presses Enter, sees no\n * break, and their next keystroke lands on the *previous* line (observed in\n * Chromium; see `artifacts/T3.1.2-browser-check.sh`). Browsers solve this for\n * their own line breaks with a FILLER `<br>` as the block's last child, so ours\n * uses the same device. `readParts` skips exactly that node — the two are one\n * fact, kept in one file.\n */\nexport function ensureFillerBreak(editor: HTMLElement): void {\n fillBlock(caretBlock(editor));\n}\n\n/**\n * Does this editing host render more than one line?\n *\n * Read from the host's OWN `aria-multiline`, which both editors set from the\n * same `multiline` prop that decides whether Enter inserts anything\n * (`ExpressionInput.tsx`, `ExpressionEditorModal.tsx`) — so the attribute is not\n * a proxy for the flag, it *is* the flag, already on the node this file is\n * handed. Threading a second copy of it down as an argument would make the two\n * editors' call sites the only source of truth and leave the DOM free to\n * disagree with it.\n *\n * Absent ⇒ multiline: a host that never declared itself single-line keeps the\n * pre-existing behaviour, and the two real editors always declare.\n */\nconst isMultilineHost = (el: HTMLElement): boolean => el.getAttribute(\"aria-multiline\") !== \"false\";\n\n/**\n * Paint an editor's DOM from parts (text nodes + chips).\n *\n * `opts` passes straight through to {@link makeChip} — `renderToggle`\n * defaults off, so a caller that never opts in (`ExpressionInput.tsx`) paints\n * no toggle at all, and only `ExpressionEditorModal` turns it on.\n */\nexport function paintParts(\n el: HTMLElement,\n parts: ExprPart[],\n opts?: { renderToggle?: boolean },\n): void {\n const doc = el.ownerDocument;\n el.textContent = \"\";\n for (const p of parts) {\n if (p.kind === \"text\") {\n if (p.value) el.appendChild(doc.createTextNode(p.value));\n } else {\n el.appendChild(makeChip(doc, p, opts));\n }\n }\n // A painted value ENDING in a newline needs the filler just as much as a\n // freshly typed one does — this is the same block, rebuilt from parts. Without\n // it the break survives the round trip in the VALUE but not on SCREEN, and the\n // author's next keystroke lands before it: \"a\\n\" + typing \"b\" saved \"ab\\n\".\n //\n // …but only where a break can be rendered at all. A SINGLE-LINE field can\n // still hold a value ending in \"\\n\" (paste it in — neither editor has an\n // `onPaste` handler), and there the filler gives it a second line box: the\n // field silently doubles in height for a break the author can never reach,\n // since Enter is swallowed on that path. The value is identical either way —\n // `readParts` skips the filler — so this is purely about what is painted.\n const last = parts[parts.length - 1];\n if (last?.kind === \"text\" && last.value?.endsWith(\"\\n\") && isMultilineHost(el)) fillBlock(el);\n}\n\n/**\n * Put the caret at the end of the editor.\n *\n * Deliberately NOT special-cased for a trailing filler `<br>`: a caret placed\n * past the filler is a position Chromium normalises straight back into the\n * content, so the next character still lands before the filler. That was\n * measured, not assumed — a version of this function that skipped the filler\n * explicitly could not be distinguished from this one by any probe in\n * `T3.1.2-browser-check.sh`, including §K, which exists to try. What DOES have\n * to respect the filler is the node insertion itself (see `insertNodeAtCaret`).\n */\nexport function placeCaretAtEnd(el: HTMLElement): void {\n const sel = el.ownerDocument.getSelection();\n if (!sel) return;\n const range = el.ownerDocument.createRange();\n range.selectNodeContents(el);\n range.collapse(false);\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\n/** Insert a node at the caret (or at the end if the caret isn't in the editor). */\nexport function insertNodeAtCaret(editor: HTMLElement, node: Node): void {\n const doc = editor.ownerDocument;\n const sel = doc.getSelection();\n const range = sel?.rangeCount ? sel.getRangeAt(0) : null;\n if (range && editor.contains(range.commonAncestorContainer)) {\n range.deleteContents();\n range.insertNode(node);\n const after = doc.createRange();\n after.setStartAfter(node);\n after.collapse(true);\n sel?.removeAllRanges();\n sel?.addRange(after);\n } else {\n // No caret in the editor (e.g. a source clicked in the modal's left pane\n // before the editor was ever focused). Insert at the end of the CONTENT —\n // which is before a trailing filler, not after it: appending past the filler\n // would stop it being the block's last child and `readParts` would then read\n // it as a real newline (\"a\\n\" + a chip saved \"a\\n\\n{{ … }}\").\n if (isFillerBreak(editor.lastChild)) editor.insertBefore(node, editor.lastChild);\n else editor.appendChild(node);\n placeCaretAtEnd(editor);\n }\n editor.focus();\n}\n\n/**\n * D-3 (binding): promote a just-closed `{{ … }}` marker to a chip at the\n * keystroke that closes it — the caret-safe surgery an `onInput` handler can\n * call directly, with NO `paintGen` bump (see the warning at the top of\n * `ExpressionEditorModal.tsx` and `G-typing` in `expr-template-guards.test.cjs`:\n * a repaint here resets the caret and reorders every subsequent keystroke).\n *\n * Returns `false`, doing nothing, unless ALL of:\n * - the selection is collapsed inside a text node `editor` contains;\n * - the two characters immediately before the caret are `}}`;\n * - there is a `{{` earlier in THAT SAME text node (a marker interrupted by\n * a chip — i.e. split across text nodes — is not a marker, deliberately);\n * - `parseRootAnchoredTemplate` of the text from that `{{` to the caret\n * parses to exactly ONE part that is not `kind: \"text\"` (an unrooted\n * marker, or one that isn't a single complete part, stays literal).\n *\n * On success: deletes exactly that span and inserts the chip in its place —\n * the same `Range` surgery `insertNodeAtCaret` performs, mirrored rather than\n * reused because the span here is a slice of an EXISTING text node, not the\n * live selection — then collapses the caret just after the chip.\n */\nexport function promoteCompletedMarkerAtCaret(\n editor: HTMLElement,\n opts: { renderToggle?: boolean } = {},\n): boolean {\n const doc = editor.ownerDocument;\n const sel = doc.getSelection();\n if (!sel || sel.rangeCount === 0 || !sel.isCollapsed) return false;\n const range = sel.getRangeAt(0);\n const node = range.startContainer;\n if (node.nodeType !== Node.TEXT_NODE || !editor.contains(node)) return false;\n\n const offset = range.startOffset;\n const text = node.textContent ?? \"\";\n if (offset < 2 || text.slice(offset - 2, offset) !== \"}}\") return false;\n const openIdx = text.lastIndexOf(\"{{\", offset - 2);\n if (openIdx === -1) return false;\n\n const marker = text.slice(openIdx, offset);\n const parsed = parseRootAnchoredTemplate(marker);\n if (parsed.length !== 1 || parsed[0].kind === \"text\") return false;\n // `\\{{ … }}` is an escaped, literal marker — it stays text (`\\\\{{` does not escape).\n let slashes = 0;\n while (openIdx - 1 - slashes >= 0 && text[openIdx - 1 - slashes] === \"\\\\\") slashes += 1;\n if (slashes % 2 === 1) return false;\n\n const markerRange = doc.createRange();\n markerRange.setStart(node, openIdx);\n markerRange.setEnd(node, offset);\n markerRange.deleteContents();\n const chip = makeChip(doc, parsed[0], opts);\n markerRange.insertNode(chip);\n\n const after = doc.createRange();\n after.setStartAfter(chip);\n after.collapse(true);\n sel.removeAllRanges();\n sel.addRange(after);\n return true;\n}\n\n/**\n * D-3: the reverse of {@link promoteCompletedMarkerAtCaret} — a chip back to\n * its editable `{{ … }}` text, in place. `chipToPart` is the SAME decode\n * `readParts` uses, so what comes back is exactly what the chip carries, and\n * `serializeTemplate` is the SAME serializer the round trip already goes\n * through everywhere else in this file. `null` for an element that isn't a\n * chip. The caller collapses the caret at the returned node's end — this\n * function only performs the DOM swap, mirroring `chip.replaceWith` being the\n * whole of the \"remove\" arm (`onClick`'s `[data-x]` handler) in both editors.\n */\nexport function chipToText(chip: HTMLElement): Text | null {\n const part = chipToPart(chip);\n if (!part) return null;\n const readable =\n part.kind === \"expr\" && !parseCoalesceChain(part.expr)\n ? formatReadableExpression(part.expr)\n : null;\n const text = chip.ownerDocument.createTextNode(readable ?? serializeTemplate([part]));\n chip.replaceWith(text);\n return text;\n}\n","/**\n * Helpers for composing a `json`/`group` param's value out of literal JSON and references.\n *\n * A reference inside a JSON value is a `{{ }}` template STRING, the one syntax the author sees\n * everywhere (core Workflow RFC amendment, 2026-10-29), resolved at any depth of a `with`\n * value (`w6w-workflow` engine `expr.ts`, `resolveRecorded`):\n *\n * - `\"{{ <ref> }}\"` — exactly one marker: the referenced value itself, type intact (an object\n * stays an object);\n * - `\"… {{ <ref> }} …\"` — anything more: interpolated as text.\n *\n * So the composer inserts `\"{{ ref }}\"` (quoted) where a JSON value goes, and `{{ ref }}`\n * inside a string literal. A legacy `{ \"$\": \"<ref>\" }` binding is still read.\n */\n\nimport type { StepMeta, StepStartState } from \"../provider.tsx\";\nimport type { ExprValue } from \"../types.ts\";\nimport { parseResolvableText, parseRootAnchoredTemplate } from \"./expression-template.ts\";\n\n/** True when `pos` sits inside a JSON string literal of `text` (after its opening quote). */\nexport function insideJsonString(text: string, pos: number): boolean {\n let inString = false;\n for (let i = 0; i < pos && i < text.length; i++) {\n const ch = text[i];\n if (inString && ch === \"\\\\\") {\n i++; // skip the escaped character\n continue;\n }\n if (ch === '\"') inString = !inString;\n }\n return inString;\n}\n\n/** The text to insert for `ref` at `pos` of `text`: a marker in a string, else a quoted one. */\nexport function refInsertion(text: string, pos: number, ref: string): string {\n const marker = `{{ ${ref} }}`;\n return insideJsonString(text, pos) ? marker : JSON.stringify(marker);\n}\n\n/**\n * The property name a reference gets when it is added to an object: its last meaningful\n * segment — `var.region` → `region`, `nodes.get_event.output.id` → `id`,\n * `nodes.get_event.output` → `get_event`, `nodes.get_event.meta` → `get_event_meta`.\n */\nexport function keyForRef(ref: string): string {\n const segs = ref.split(\".\").filter((s) => s !== \"\");\n const last = segs[segs.length - 1] ?? \"value\";\n if ((last === \"output\" || last === \"meta\") && segs.length >= 3) {\n return last === \"meta\" ? `${segs[segs.length - 2]}_meta` : segs[segs.length - 2];\n }\n return last;\n}\n\n/** The innermost unclosed `{`/`[` before `pos` (strings skipped), or `null` at top level. */\nfunction openerBefore(text: string, pos: number): \"{\" | \"[\" | null {\n const stack: string[] = [];\n let inString = false;\n for (let i = 0; i < pos && i < text.length; i++) {\n const ch = text[i];\n if (inString) {\n if (ch === \"\\\\\") i++;\n else if (ch === '\"') inString = false;\n continue;\n }\n if (ch === '\"') inString = true;\n else if (ch === \"{\" || ch === \"[\") stack.push(ch);\n else if (ch === \"}\" || ch === \"]\") stack.pop();\n }\n const top = stack[stack.length - 1];\n return top === \"{\" || top === \"[\" ? top : null;\n}\n\n/** A key not already used in `obj`: `key`, then `key_2`, `key_3`, … */\nfunction freeKey(obj: Record<string, unknown> | null, key: string): string {\n if (!obj || !Object.hasOwn(obj, key)) return key;\n let n = 2;\n while (Object.hasOwn(obj, `${key}_${n}`)) n++;\n return `${key}_${n}`;\n}\n\n/**\n * Add a reference to a draft the author is working on — never replacing it. `pos` is the caret.\n *\n * - Inside a JSON string: `{{ ref }}`, interpolated.\n * - Where a value goes (after `:`, after `[`, or after `,` in an array): `\"{{ ref }}\"`.\n * - Where a property goes (after `{`, or after `,` in an object): `\"key\": \"{{ ref }}\"`.\n * - Anywhere else (the caret is not somewhere a value fits — e.g. it was never placed): a draft\n * that is an object gets a new property at its end, an array a new element at its end.\n * Otherwise the quoted marker goes at the caret.\n *\n * With `literal`, the same placement inserts that VALUE instead of the reference (a literal-JSON\n * field such as a workflow's starting state, where no `{{ }}` marker is ever evaluated): as JSON\n * where a value goes, as its text inside a string. The key is still named after `ref`.\n *\n * Returns the new text and the caret after the inserted reference.\n */\nexport function addRefToDraft(\n text: string,\n pos: number,\n ref: string,\n literal?: { value: unknown },\n): { text: string; caret: number } {\n const literalJson = literal ? (JSON.stringify(literal.value) ?? \"null\") : \"\";\n const marker = literal\n ? JSON.stringify(typeof literal.value === \"string\" ? literal.value : literalJson).slice(1, -1)\n : `{{ ${ref} }}`;\n const quoted = literal ? literalJson : JSON.stringify(marker);\n const at = (i: number, insert: string) => ({\n text: text.slice(0, i) + insert + text.slice(i),\n caret: i + insert.length,\n });\n if (insideJsonString(text, pos)) return at(pos, marker);\n\n let parsed: unknown;\n let ok = true;\n try {\n parsed = JSON.parse(text);\n } catch {\n ok = false;\n }\n const obj =\n ok && parsed !== null && typeof parsed === \"object\" && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : null;\n const prop = () => `${JSON.stringify(freeKey(obj, keyForRef(ref)))}: ${quoted}`;\n\n const before = text.slice(0, pos).trimEnd();\n const prev = before[before.length - 1];\n const next = text.slice(pos).trimStart()[0];\n const opener = openerBefore(text, pos);\n if (prev === \":\" || prev === \"[\" || (prev === \",\" && opener === \"[\")) {\n return at(pos, quoted + (prev !== \":\" && next !== undefined && next !== \"]\" ? \", \" : \"\"));\n }\n if (prev === \"{\" || (prev === \",\" && opener === \"{\")) {\n const sep = next !== undefined && next !== \"}\" ? \", \" : \"\";\n return at(pos, (prev === \",\" ? \" \" : \"\") + prop() + sep);\n }\n\n if (ok && (obj || Array.isArray(parsed))) {\n const close = text.lastIndexOf(obj ? \"}\" : \"]\");\n const head = text.slice(0, close).trimEnd();\n const empty = head.endsWith(obj ? \"{\" : \"[\");\n const item = obj ? prop() : quoted;\n const gap = text.slice(head.length, close);\n if (gap.includes(\"\\n\")) {\n // Multi-line JSON: the new entry gets its own line, indented like its siblings.\n const indent = empty\n ? `${gap.slice(gap.lastIndexOf(\"\\n\") + 1)} `\n : (/^\\s*/.exec(head.slice(head.lastIndexOf(\"\\n\") + 1))?.[0] ?? \"\");\n const insert = `${empty ? \"\" : \",\"}\\n${indent}${item}`;\n return { text: head + insert + text.slice(head.length), caret: head.length + insert.length };\n }\n const insert = `${empty ? \"\" : \",\"} ${item} `;\n const i = head.length;\n return { text: text.slice(0, i) + insert + text.slice(close), caret: i + insert.length - 1 };\n }\n return at(pos, quoted);\n}\n\n/**\n * A whole field typed as one bare `{{ ref }}` marker (not valid JSON, the quotes are missing)\n * — the template string `\"{{ ref }}\"` it means, or `null`. The ref must start at a known\n * run-scope root, the same set the engine resolves.\n */\nconst BARE_REF =\n /^\\{\\{\\s*((?:var|vars|const|steps|nodes|trigger|foreach|inputs|output|documents)(?:\\.[^\\s{}]+)?)\\s*\\}\\}$/;\nexport function bareRefBinding(text: string): string | null {\n const m = BARE_REF.exec(text.trim());\n return m ? `{{ ${m[1]} }}` : null;\n}\n\n/**\n * The ref a whole-value binding names — `\"{{ ref }}\"` (exactly one `var` marker, nothing\n * else), or a legacy `{ \"$\": \"ref\" }` — else `null`.\n */\nexport function wholeValueRef(value: unknown): string | null {\n if (typeof value === \"string\") {\n if (!value.includes(\"{{\")) return null;\n const parts = parseRootAnchoredTemplate(value);\n return parts.length === 1 && parts[0].kind === \"var\" ? (parts[0].ref ?? null) : null;\n }\n if (\n value !== null &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n Object.keys(value).length === 1 &&\n typeof (value as { $?: unknown }).$ === \"string\"\n ) {\n return (value as { $: string }).$;\n }\n return null;\n}\n\n/**\n * The `steps` start state a preview resolves against, rebuilt from the host's flat sample\n * values: `steps.<id>.output` / `nodes.<id>.output` keys give a step's output, and\n * `steps.<id>.meta.<field>` keys its metadata.\n */\nexport function sampleStepsState(\n sampleValues: Record<string, unknown> | undefined,\n): StepStartState {\n const steps: Record<string, { output?: unknown; meta?: StepMeta }> = {};\n for (const [ref, value] of Object.entries(sampleValues ?? {})) {\n const out = /^(?:steps|nodes)\\.([^.]+)\\.output$/.exec(ref);\n if (out) {\n steps[out[1]] = { ...steps[out[1]], output: value };\n continue;\n }\n const meta = /^(?:steps|nodes)\\.([^.]+)\\.meta\\.([^.]+)$/.exec(ref);\n if (meta) {\n steps[meta[1]] ??= {};\n const s = steps[meta[1]];\n // A preview may know only some of the four fields; the resolver reads them by path.\n s.meta = { ...s.meta, [meta[2]]: value } as StepMeta;\n }\n }\n return { steps };\n}\n\n/**\n * Resolve a composed value the way the engine resolves a `with` value: a `{ \"$\": ref }` object\n * and a string holding rooted `{{ ref }}` markers are resolved by `resolveLeaf` wherever they\n * sit; other arrays and objects are walked. A string whose markers are not all rooted stays\n * literal, as in the engine. `resolveLeaf` is the ui's top-level resolver\n * (`resolveParamJson` against a scope), which reads only the value it is handed.\n */\nexport function resolveComposed(value: unknown, resolveLeaf: (leaf: unknown) => unknown): unknown {\n if (typeof value === \"string\") {\n const parts = parseResolvableText(value);\n if (!parts) return value;\n // Exactly one marker is the value itself, typed — as the engine resolves it.\n if (parts.length === 1 && parts[0].kind === \"var\") return resolveLeaf({ $: parts[0].ref });\n return resolveLeaf({ type: \"expr\", parts } satisfies ExprValue);\n }\n if (Array.isArray(value)) return value.map((v) => resolveComposed(v, resolveLeaf));\n if (value !== null && typeof value === \"object\") {\n const keys = Object.keys(value);\n if (keys.length === 1 && keys[0] === \"$\" && typeof (value as { $: unknown }).$ === \"string\") {\n return resolveLeaf(value);\n }\n return Object.fromEntries(\n Object.entries(value).map(([k, v]) => [k, resolveComposed(v, resolveLeaf)]),\n );\n }\n return value;\n}\n","import type { EditorView } from \"@codemirror/view\";\nimport { Fragment, type ReactNode, useId, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { JsonEditor } from \"../JsonEditor.tsx\";\nimport { isInternalApp } from \"../flow-types.ts\";\nimport { buildResolveScope } from \"../resolve-params.ts\";\nimport { resolveParamJson } from \"../resolved-json.ts\";\nimport type { ExprPart, ExprValue, SecretValue } from \"../types.ts\";\nimport { Copyable } from \"./Copyable.tsx\";\nimport type { ExpressionOptions, ExpressionStepSource } from \"./ExpressionOptions.tsx\";\nimport { IconButton } from \"./IconButton.tsx\";\nimport { Modal } from \"./Modal.tsx\";\nimport {\n authoredReferences,\n compileAuthoredParts,\n previewAuthoredParts,\n} from \"./expression-authoring.ts\";\nimport {\n chipToText,\n ensureFillerBreak,\n insertNodeAtCaret,\n isRefSafeKey,\n isRefSafePath,\n makeChip,\n outputFieldTree,\n paintParts,\n placeCaretAtEnd,\n promoteCompletedMarkerAtCaret,\n readParts,\n varLabel,\n} from \"./expression-dom.ts\";\nimport {\n parseRootAnchoredTemplate,\n partsToValue,\n serializeTemplate,\n valueToParts,\n} from \"./expression-template.ts\";\nimport { addRefToDraft, resolveComposed, sampleStepsState, wholeValueRef } from \"./json-compose.ts\";\n\n/**\n * A near-full-screen editor for an expression value. Left: the data sources in\n * scope (variables, secrets, and the workflow state leading to this step) — one\n * click inserts a colored TAG (chip) at the caret. Right: the expression editor\n * (top, where tags read distinctly from plain text) over the `{{ }}` template\n * form that gets saved plus a live Result pane (bottom) that previews the\n * expression against user-supplied sample values for the injected scope.\n *\n * The value it saves is the same `ExprValue | string` the inline field and the\n * engine already use (see `expression-template.ts` / `expression-dom.ts`).\n */\nexport interface ExpressionEditorModalProps {\n value: ExprValue | string | SecretValue | undefined;\n masked?: boolean;\n /**\n * The field being edited holds multi-line text (a `text`-typed param, or one\n * flagged `config.multiline`). Enter then inserts a literal `\"\\n\"` at the\n * caret instead of being swallowed, and `aria-multiline` follows. Omitted ⇒\n * single-line, as every existing consumer expects.\n */\n multiline?: boolean;\n options: ExpressionOptions;\n /** Field name shown in the modal title. */\n fieldLabel?: string;\n /** Expression mode's commit. Not used in `mode=\"json-binding\"` (see `onSaveJson`). */\n onSave?: (next: ExprValue | string) => void;\n onClose: () => void;\n /**\n * `\"json-binding\"`: the value of a whole `json`/`group` param, composed as JSON. The rail\n * shows Previous steps (each step's \"Entire output\", its fields and, for an app step, its\n * Metadata), Inputs and Variables — no Secrets or Documents. A click on a source into an empty\n * draft (or one holding only a reference) binds it: `onSaveJson(\"{{ ref }}\")` and close. Into a\n * draft being composed it ADDS the reference (`addRefToDraft`, `json-compose.ts`): at the caret\n * where a value or property fits, else as a new property/element at the end — never replacing\n * the draft. Save calls `onSaveJson` with the parsed JSON.\n * Absent ⇒ expression mode, unchanged.\n */\n mode?: \"json-binding\";\n /** json-binding mode: the field's current value, seeding the compose pane. */\n jsonValue?: unknown;\n /** json-binding mode: Save from the compose pane, with the parsed JSON. */\n onSaveJson?: (next: unknown) => void;\n /**\n * json-binding mode only: the field takes one whole value (`ActionParam.whole`). A source click\n * into an empty draft, or one parsing to exactly `[]` / `{}`, binds the bare ref. Any other\n * draft composes as usual.\n */\n whole?: boolean;\n /**\n * json-binding mode only: a workflow's starting state (`Workflow.initialState`), evaluated once\n * at run start. The rail has no Previous steps or State section (the state is blank then) and\n * no Secrets (a secret never enters state), but does list Documents. A toggle above it picks\n * what a source click inserts: its reference (default), or its current sample value as a\n * literal. A click always composes into the object, never binds the whole field. An empty\n * draft saves `undefined`; Save is refused while `jsonProblem` names a problem.\n */\n startingState?: boolean;\n /** Starting-state mode: why the draft text cannot be saved (`null` when it can). */\n jsonProblem?: (text: string) => string | null;\n /** The modal's title, in place of \"Edit JSON value\" / \"Edit expression\". */\n title?: string;\n}\n\nexport function ExpressionEditorModal({\n value,\n masked,\n multiline,\n options,\n fieldLabel,\n onSave,\n onClose,\n mode,\n jsonValue,\n onSaveJson,\n whole: wholeField,\n startingState: startingStateProp,\n jsonProblem,\n title,\n}: ExpressionEditorModalProps) {\n const jsonBinding = mode === \"json-binding\";\n const seedMode = jsonBinding && startingStateProp === true;\n // Starting-state mode: what a source click inserts — the reference, or its value now.\n const [insertAs, setInsertAs] = useState<\"ref\" | \"value\">(\"ref\");\n // json-binding mode's compose pane: the draft text, whether it parses, and the CodeMirror\n // view (for inserting at the caret).\n const [jsonText, setJsonText] = useState(() =>\n jsonValue === undefined ? \"\" : JSON.stringify(jsonValue, null, 2),\n );\n const jsonView = useRef<EditorView | null>(null);\n // Whether the author has worked in the JSON pane (focused it, so a caret is theirs). Until\n // then a source click REPLACES the draft — the seeded value's caret is just position 0, and\n // re-picking a bound field's reference is one click; after it, a click inserts at the caret.\n const jsonTouched = useRef(false);\n const jsonParsed = useMemo((): { ok: true; value: unknown } | { ok: false } => {\n if (jsonText.trim() === \"\") return { ok: false };\n try {\n return { ok: true, value: JSON.parse(jsonText) };\n } catch {\n return { ok: false };\n }\n }, [jsonText]);\n const seedProblem = seedMode ? (jsonProblem?.(jsonText) ?? null) : null;\n const canSaveJson = seedMode\n ? (jsonText.trim() === \"\" || jsonParsed.ok) && seedProblem === null\n : jsonParsed.ok;\n const sampleScope = () =>\n buildResolveScope(\n options.sampleValues,\n sampleStepsState(options.sampleValues),\n options.nodeConfig,\n options.nodeMeta,\n );\n const insertJsonRef = (ref: string) => {\n const view = jsonView.current;\n const doc = view ? view.state.doc.toString() : jsonText;\n if (seedMode) {\n // The starting state is an object: a click adds a key, never binds the whole field. As a\n // value, the source's current sample is copied in and no longer follows the source.\n const literal =\n insertAs === \"value\"\n ? { value: resolveParamJson(`{{ ${ref} }}`, sampleScope()) ?? null }\n : undefined;\n const base = doc.trim() === \"\" ? \"{}\" : doc;\n const pos = jsonTouched.current && view ? view.state.selection.main.head : base.length;\n const next = addRefToDraft(base, pos, ref, literal);\n if (!view) {\n setJsonText(next.text);\n return;\n }\n view.dispatch({\n changes: { from: 0, to: doc.length, insert: next.text },\n selection: { anchor: next.caret },\n });\n view.focus();\n return;\n }\n // An empty draft — or one that is only a reference (a bound field being re-picked) — is a\n // binding: the click saves that reference and closes, as a click does in expression mode.\n let whole: string | null = null;\n try {\n whole = doc.trim() === \"\" ? null : wholeValueRef(JSON.parse(doc));\n } catch {\n whole = null;\n }\n let emptyContainer = false;\n if (wholeField) {\n try {\n const parsed: unknown = JSON.parse(doc);\n emptyContainer = Array.isArray(parsed)\n ? parsed.length === 0\n : typeof parsed === \"object\" && parsed !== null && Object.keys(parsed).length === 0;\n } catch {\n emptyContainer = false;\n }\n }\n if (doc.trim() === \"\" || whole !== null || emptyContainer) {\n onSaveJson?.(`{{ ${ref} }}`);\n onClose();\n return;\n }\n if (!view) return;\n // Otherwise the author is composing: ADD the reference, never replace their JSON.\n const pos = jsonTouched.current ? view.state.selection.main.head : doc.length;\n const next = addRefToDraft(doc, pos, ref);\n view.dispatch({\n changes: { from: 0, to: doc.length, insert: next.text },\n selection: { anchor: next.caret },\n });\n view.focus();\n };\n const [parts, setParts] = useState<ExprPart[]>(\n () => compileAuthoredParts(valueToParts(value).parts, options).parts,\n );\n const authored = useMemo(() => compileAuthoredParts(parts, options), [parts, options]);\n // Bumped ONLY for programmatic repaints — mount, and committing template\n // text back into chips. Typing/insert mutate the DOM directly and sync out,\n // so the caret is never clobbered; NEVER bump this from `onInput`,\n // `insertPart`, the Enter handler, or a chip flip.\n const [paintGen, setPaintGen] = useState(0);\n const editorRef = useRef<HTMLDivElement>(null);\n // Set right before a programmatic paint that should also move focus/caret\n // into the chips editor — never on the mount paint.\n const focusChipsAfterPaint = useRef(false);\n // User-supplied sample values (keyed by var ref) that the Result pane previews\n // the expression against. Design-time only — never sent to the engine.\n const [samples, setSamples] = useState<Record<string, string>>({});\n // Which store's \"+ Add\" nested dialog is open, or none. Gated at render by\n // whether the host supplied the matching callback (`options.createVar` /\n // `.createSecret`) — see the rail below.\n const [adding, setAdding] = useState<\"var\" | \"secret\" | null>(null);\n // Rail sources with surviving child rows (a multi-field document, a step\n // with declared outputs) collapse by default — ONE mechanism, composite\n // keys (\"doc:<key>\" / \"step:<id>\"), serving both loops below.\n const [expanded, setExpanded] = useState<Set<string>>(() => new Set());\n const toggleExpanded = (key: string) => {\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n return next;\n });\n };\n // The rail's sections are an accordion: at most one open at a time. \"auto\" until the author\n // picks one — then the default (Previous steps, else the first section present) applies.\n const [openPick, setOpenPick] = useState<RailSectionKey | null | \"auto\">(\"auto\");\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: paint on `paintGen`, not on every `parts` change; edits otherwise flow through the DOM.\n useLayoutEffect(() => {\n const el = editorRef.current;\n if (!el) return;\n // renderToggle: true — the modal is the one surface with a click delegate\n // for `[data-render-toggle]` (below); `ExpressionInput.tsx` never opts in.\n paintParts(el, parts, { renderToggle: true });\n if (focusChipsAfterPaint.current) {\n focusChipsAfterPaint.current = false;\n placeCaretAtEnd(el);\n el.focus();\n }\n }, [paintGen]);\n\n const sync = () => {\n const el = editorRef.current;\n if (el) setParts(readParts(el));\n };\n\n const insertPart = (part: ExprPart) => {\n const el = editorRef.current;\n if (!el) return;\n insertNodeAtCaret(el, makeChip(el.ownerDocument, part, { renderToggle: true }));\n setParts(readParts(el));\n };\n\n // A render part can be authored two ways: flipping an EXISTING var chip\n // (below), or inserting one directly via a document field's \"insert as\n // render\" action (the Documents group's field sub-source loop, below) — so\n // this is derived from `parts` on every render, not computed once at mount:\n // either path must disable the control below immediately, and flipping the\n // toggled chip back must re-enable it.\n const hasRenderPart = parts.some((p) => p.kind === \"render\");\n\n // Adopt a text form as the parts and repaint the chips editor — the\n // chip-ify commit mechanism: root-anchor-parse `text` (never the naive\n // `parseTemplate` — a hand-typed vendor placeholder like `{{name}}` must\n // stay literal, see `expression-template.ts`'s `parseRootAnchoredTemplate`),\n // set it as the new `parts`, and bump `paintGen` so the `useLayoutEffect`\n // above repaints. `restoreFocus` is `false` from `onBlur` (the editor has\n // already lost focus; forcing it back would yank focus out of Save/Cancel —\n // caret position is moot there) and `true` for a caller that wants the\n // caret restored into the chips editor after the repaint.\n const adoptText = (text: string, { restoreFocus }: { restoreFocus: boolean }) => {\n setParts(compileAuthoredParts(parseRootAnchoredTemplate(text), options).parts);\n if (restoreFocus) focusChipsAfterPaint.current = true;\n setPaintGen((g) => g + 1);\n };\n\n const save = () => {\n const el = editorRef.current;\n const next = compileAuthoredParts(el ? readParts(el) : parts, options);\n if (next.error) return;\n onSave?.(partsToValue(next.parts));\n onClose();\n };\n\n // Close the nested \"+ Add\" dialog and return focus + caret to the chips\n // editor. `Modal.tsx` never calls `el.close()` on unmount, so React would\n // otherwise leave a still-`open` `<dialog>` for the browser to tear down and\n // restore focus to `<body>` — the author loses their insertion point right\n // when they come back to insert the value they just created. Reuse the same\n // programmatic-repaint mechanism `exitTemplate` used for the same problem.\n const closeAdding = () => {\n setAdding(null);\n focusChipsAfterPaint.current = true;\n setPaintGen((g) => g + 1);\n };\n\n const vars = options.vars ?? [];\n const constants = options.constants ?? [];\n const secrets = options.secrets ?? [];\n const inputs = options.inputs ?? [];\n const documents = options.documents ?? [];\n const steps = options.steps ?? [];\n const nodeConfigs = options.nodeConfigs ?? [];\n const loop = options.loop;\n // Every node's literal settings, offered inside its Metadata disclosure as\n // `config` (`nodes.<id>.meta.config.<key>`). A node that is not upstream still\n // gets a row, so its settings stay reachable.\n const configKeys = new Map(\n nodeConfigs\n .map((n) => [n.id, n.keys.filter(isRefSafeKey)] as const)\n .filter(([, keys]) => keys.length > 0),\n );\n // A node's Metadata leaves: the four app fields for an external app step (R-7), plus whichever\n // other static meta its node carries (a webhook trigger's subscription id and URL) — never a\n // key the node does not have, so a `@w6w/webhook` node offers no connection id.\n const nodeMeta = options.nodeMeta ?? {};\n const metaLeavesOf = (id: string) =>\n META_LEAVES.filter(([key]) =>\n APP_META_KEYS.has(key) ? isExternalAppNode(id) : Object.hasOwn(nodeMeta[id] ?? {}, key),\n );\n // An external app is an upstream step flagged `hasMeta` (R-7), or a node whose static meta\n // names an app that is not built in (a node that is not upstream has no `hasMeta`).\n const upstreamAppIds = steps.filter((st) => st.hasMeta === true).map((st) => st.id);\n const isExternalAppNode = (id: string) => {\n if (upstreamAppIds.includes(id)) return true;\n const app = nodeMeta[id]?.app;\n return typeof app === \"string\" && !isInternalApp(app);\n };\n const metaSources = (id: string) =>\n metaLeavesOf(id).map(([key, label]) =>\n source(label, { kind: \"var\", ref: `nodes.${id}.meta.${key}` }, \"w6w-exprmodal-field\", null),\n );\n // Previous steps is only what this node can read at run time — its upstream `steps`, its\n // trigger's event, its loop's item. Every node's static meta, other paths included, sits in\n // the separate Metadata section, keyed in node order (`nodeMeta`, then upstream app steps the\n // host gave no static meta for, then config-only nodes) — the one place a node's meta is offered.\n const metaIds = [...new Set([...Object.keys(nodeMeta), ...upstreamAppIds, ...configKeys.keys()])];\n const hasWorkflowState = steps.length > 0 || !!options.hasTrigger;\n const hasState = !seedMode && (hasWorkflowState || !!loop);\n // The merged workflow STATE (`state.<path>`, `state-shape.ts`): its own section, present only\n // when something is in it, so every other section keeps its place.\n const stateFields = seedMode\n ? []\n : (options.stateShape?.fields ?? []).filter((f) => isRefSafePath(f.key));\n const sections: RailSectionKey[] = [\n ...(hasState ? ([\"state\"] as const) : []),\n ...(stateFields.length > 0 ? ([\"runstate\"] as const) : []),\n ...(metaIds.length > 0 ? ([\"meta\"] as const) : []),\n ...(options.inputs !== undefined ? ([\"inputs\"] as const) : []),\n \"vars\",\n ...(constants.length > 0 ? ([\"consts\"] as const) : []),\n ...(!jsonBinding || seedMode ? ([\"docs\"] as const) : []),\n ...(!jsonBinding ? ([\"secrets\"] as const) : []),\n ];\n const openSection =\n openPick === \"auto\" || (openPick !== null && !sections.includes(openPick))\n ? (sections.find((k) => k !== \"meta\") ?? null)\n : openPick;\n // Opening a section closes the open one; clicking the open one collapses it.\n const sectionProps = (key: RailSectionKey) => ({\n open: openSection === key,\n onToggle: () => setOpenPick(openSection === key ? null : key),\n });\n const loopFields = (loop?.itemOutputs ?? []).filter((o) =>\n o.path ? isRefSafePath(o.key) : isRefSafeKey(o.key),\n );\n const eventFields = (options.eventOutputs ?? []).filter((o) =>\n o.path ? isRefSafePath(o.key) : isRefSafeKey(o.key),\n );\n const template = serializeTemplate(authored.parts);\n\n // The sample map the Result pane previews against: host-seeded defaults\n // (real project vars/documents, keyed by full ref) overlaid by anything the\n // author typed into the Sample values box, which takes precedence. Non-string\n // seeds are stringified for the text preview.\n const effectiveSamples = useMemo(() => {\n const seeded: Record<string, string> = {};\n for (const [ref, v] of Object.entries(options.sampleValues ?? {})) {\n seeded[ref] = typeof v === \"string\" ? v : JSON.stringify(v);\n }\n return { ...seeded, ...samples };\n }, [options.sampleValues, samples]);\n\n // The distinct var/render refs the current expression reads (first-seen\n // order) — the in-scope roots the author can supply sample values for. A\n // `render` part reads through the same sample lookup as `var` (A4c), so its\n // ref belongs here too — otherwise the Sample-values box never offers a row\n // for it and the Result pane's first click on the new insert-render action\n // reads as broken (blank output).\n const usedRefs = useMemo(() => authoredReferences(authored.parts), [authored.parts]);\n\n // Comparisons use the same JSONLogic evaluator as execution, with typed samples.\n const result = useMemo(() => {\n if (authored.error) return \"\";\n try {\n return previewAuthoredParts(authored.parts, options.sampleValues, samples);\n } catch {\n // Last-resort fallback — the pane must never throw.\n return template;\n }\n }, [authored, options.sampleValues, samples, template]);\n\n // Which non-fresh tiers the Result's substituted values came from (a value the author typed\n // into the Sample values box overrides the tier and is not noted).\n const resultNotes = useMemo(() => {\n const notes = new Set<string>();\n for (const ref of usedRefs) {\n if (samples[ref] !== undefined) continue;\n const tier = options.valueSources?.[ref];\n if (tier === \"sample\") notes.add(\"example from the app\");\n else if (tier === \"persisted\") notes.add(\"from last test\");\n }\n return [...notes];\n }, [usedRefs, samples, options.valueSources]);\n\n // `sigil: null` drops the glyph — a step row with fields renders its own\n // disclosure caret in that spot instead (see the Previous steps loop).\n //\n // Every source inserts and keeps the editor open so authors can append a comparison.\n const source = (\n label: string,\n part: ExprPart,\n cls: string,\n sigil: string | null,\n _composite = false,\n ariaLabel?: string,\n // `name` replaces `label` in the tooltip (a tree row shows a short label but\n // names its full ref on hover); `depth` indents a tree row.\n tree?: { name: string; depth: number; declaredOnly?: boolean; somePaths?: boolean },\n ) => (\n <div\n key={`${part.kind}:${part.ref ?? label}`}\n className=\"w6w-exprmodal-item\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n minWidth: 0,\n ...(tree && tree.depth > 0 ? { paddingLeft: tree.depth * 14 } : {}),\n }}\n >\n <button\n type=\"button\"\n className={`w6w-exprmodal-source ${cls}${tree?.declaredOnly ? \" is-declared-only\" : \"\"}`}\n style={{ flex: 1, minWidth: 0, ...(tree?.declaredOnly ? { opacity: 0.6 } : {}) }}\n title={`Insert ${tree?.name ?? label}`}\n aria-label={ariaLabel}\n onClick={() =>\n jsonBinding ? part.kind === \"var\" && insertJsonRef(part.ref ?? \"\") : insertPart(part)\n }\n >\n {sigil !== null && <span className=\"w6w-expr-chip-sigil\">{sigil}</span>}\n <span className=\"w6w-exprmodal-source-label\">{label}</span>\n {tree?.declaredOnly && (\n <span\n className=\"w6w-muted w6w-small\"\n data-testid=\"expr-declared-only\"\n style={{ marginLeft: 6 }}\n >\n declared by the app\n </span>\n )}\n {tree?.somePaths && (\n <span\n className=\"w6w-muted w6w-small\"\n data-testid=\"expr-state-some-paths\"\n title=\"Set on some paths into this step, not all\"\n style={{ marginLeft: 6 }}\n >\n some paths\n </span>\n )}\n </button>\n {!jsonBinding && (\n <IconButton\n icon=\"copy\"\n iconSize={14}\n label=\"Copy to expression editor\"\n data-testid=\"expr-copy-to-editor\"\n onClick={() => insertPart(part)}\n />\n )}\n </div>\n );\n\n const loopOpen = expanded.has(\"loop:item\");\n const currentItemBtn = source(\n \"Current item\",\n { kind: \"var\", ref: \"foreach.item\" },\n \"w6w-expr-chip-var\",\n \"↻\",\n );\n\n // Metadata's `config` entry: the node's static settings, collapsed until its\n // own toggle opens, each saving `nodes.<id>.meta.config.<key>`.\n const configEntry = (id: string, keys: string[]) => {\n if (keys.length === 0) return null;\n const open = expanded.has(`mcfg:${id}`);\n return (\n <>\n <div className=\"w6w-exprmodal-source-row\">\n <button\n type=\"button\"\n className=\"w6w-exprmodal-tree-toggle\"\n data-testid=\"expr-config-toggle\"\n aria-expanded={open}\n title={open ? \"Hide config\" : \"Show config\"}\n onClick={() => toggleExpanded(`mcfg:${id}`)}\n >\n <span className=\"w6w-exprmodal-tree-caret\" aria-hidden=\"true\">\n {open ? \"▾\" : \"▸\"}\n </span>\n config\n </button>\n </div>\n {open && (\n <div className=\"w6w-exprmodal-subsources\" data-testid=\"expr-config-fields\">\n {keys.map((k) =>\n source(\n k,\n { kind: \"var\", ref: `nodes.${id}.meta.config.${k}` },\n \"w6w-exprmodal-field\",\n null,\n ),\n )}\n </div>\n )}\n </>\n );\n };\n\n // A step's output fields as a tree of plain rows, each showing only its own\n // name (`outputFieldTree`). Each SAVES the canonical `nodes.<id>.output.<key>`\n // (the only form the engine resolves) — the key goes into the ref VERBATIM;\n // the short name and `o.label` are display data and never reach a ref.\n const fieldSources = (\n stepId: string,\n fields: { key: string; path?: boolean; declaredOnly?: true }[],\n rootRef = `nodes.${stepId}.output`,\n ) =>\n outputFieldTree(fields).map(({ field, depth, name }) => {\n const ref = `${rootRef}.${field.key}`;\n return source(name, { kind: \"var\", ref }, \"w6w-exprmodal-field\", null, false, undefined, {\n name: varLabel(ref),\n depth,\n declaredOnly: field.declaredOnly === true,\n });\n });\n\n // The step-level note on where a step's (or the trigger event's) fields came from. A test\n // shape (fresh or persisted) keeps the \"from the last test\" note; an app's own declaration\n // or sample says so.\n const shapeHint = (from: ExpressionStepSource[\"outputsFrom\"]) => {\n if (from === \"fresh\" || from === \"persisted\") {\n return (\n <span className=\"w6w-exprmodal-shape-note\" data-testid=\"expr-fields-from-test\">\n {from === \"fresh\" ? \"Fields from the last test run\" : \"Fields from last test\"}\n </span>\n );\n }\n if (from === \"declared\" || from === \"sample\") {\n return (\n <span className=\"w6w-exprmodal-shape-note\" data-testid={`expr-fields-from-${from}`}>\n {from === \"declared\" ? \"declared by the app\" : \"example from the app\"}\n </span>\n );\n }\n return null;\n };\n\n // A Metadata-section node: its id inserts the whole `nodes.<id>.meta`; the caret beside it\n // opens its leaves and its `config`, collapsed by default (`mnode:<id>`).\n const metaNode = (id: string) => {\n const key = `mnode:${id}`;\n const open = expanded.has(key);\n return (\n <Fragment key={key}>\n <div className=\"w6w-exprmodal-source-row\" data-testid=\"expr-metadata-node\">\n <button\n type=\"button\"\n className=\"w6w-exprmodal-caret-btn\"\n data-testid=\"expr-metadata-node-toggle\"\n aria-expanded={open}\n aria-label={open ? `Hide ${id} metadata` : `Show ${id} metadata`}\n title={open ? \"Hide metadata\" : \"Show metadata\"}\n onClick={() => toggleExpanded(key)}\n >\n {open ? \"▾\" : \"▸\"}\n </button>\n {source(\n id,\n { kind: \"var\", ref: `nodes.${id}.meta` },\n \"w6w-expr-chip-var w6w-exprmodal-node\",\n null,\n true,\n )}\n </div>\n {open && (\n <div className=\"w6w-exprmodal-subsources\" data-testid=\"expr-metadata-fields\">\n {metaSources(id)}\n {configEntry(id, configKeys.get(id) ?? [])}\n </div>\n )}\n </Fragment>\n );\n };\n\n return (\n <Modal\n title={title ?? (jsonBinding ? \"Edit JSON value\" : \"Edit expression\")}\n subtitle={fieldLabel ? <code>{fieldLabel}</code> : undefined}\n onClose={onClose}\n size=\"full\"\n headerRight={\n jsonBinding ? (\n <div className=\"w6w-exprmodal-actions\">\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost\" onClick={onClose}>\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"w6w-btn\"\n data-testid=\"expr-json-save\"\n disabled={!canSaveJson}\n title={\n canSaveJson\n ? \"Save the composed JSON\"\n : (seedProblem ?? \"Compose valid JSON to save\")\n }\n onClick={() => {\n if (!canSaveJson) return;\n onSaveJson?.(jsonParsed.ok ? jsonParsed.value : undefined);\n onClose();\n }}\n >\n Save\n </button>\n </div>\n ) : (\n <div className=\"w6w-exprmodal-actions\">\n {/* Take the field back OUT of expression mode. It saves the `{{ }}`\n TEXT form, so the content survives exactly as the old expr→text\n toggle made it — a lone text part collapses to a plain string in\n `partsToValue`, so the field renders its plain widget again.\n Hidden when `masked`: a sealed secret has no text form. */}\n {!masked && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n disabled={hasRenderPart}\n title={\n hasRenderPart\n ? \"Unavailable — a render part has no plain-text form. Flip it back to a variable first.\"\n : \"Close the expression and keep the text as a literal value\"\n }\n onClick={() => {\n onSave?.(serializeTemplate(parts));\n onClose();\n }}\n >\n Use a plain value\n </button>\n )}\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost\" onClick={onClose}>\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"w6w-btn\"\n onClick={save}\n data-testid=\"expr-save\"\n disabled={authored.error !== null}\n >\n Save\n </button>\n </div>\n )\n }\n >\n <div className=\"w6w-exprmodal\">\n {/* Left: the data sources in scope. */}\n <aside className=\"w6w-exprmodal-sources\">\n {/* First slot — context-specific, mutually exclusive in the real\n wiring (a Function supplies `inputs` and never `steps`; the flow\n editor supplies `steps`/`hasTrigger` and never `inputs`). Render\n Previous steps first should a host ever supply both. */}\n {seedMode && (\n <fieldset\n className=\"w6w-exprmodal-insert-as\"\n aria-label=\"Insert as\"\n style={{ display: \"flex\", gap: 4, alignItems: \"center\", marginBottom: 8 }}\n >\n <span className=\"w6w-muted w6w-small\">Insert as</span>\n {(\n [\n [\"ref\", \"Reference\", \"Insert {{ ref }}: resolved when each run starts\"],\n [\"value\", \"Value\", \"Insert the current value, copied in as it is now\"],\n ] as const\n ).map(([key, label, hint]) => (\n <button\n key={key}\n type=\"button\"\n aria-pressed={insertAs === key}\n data-testid={`expr-insert-as-${key}`}\n title={hint}\n className={`w6w-btn w6w-btn-sm${insertAs === key ? \"\" : \" w6w-btn-ghost\"}`}\n onClick={() => setInsertAs(key)}\n >\n {label}\n </button>\n ))}\n </fieldset>\n )}\n {jsonBinding && !seedMode && !hasState && (\n <span className=\"w6w-expr-menu-empty\">No upstream steps</span>\n )}\n {hasState && (\n <RailSection label=\"Previous steps\" {...sectionProps(\"state\")}>\n {loop && (\n <div className=\"w6w-exprmodal-subgroup\" data-testid=\"expr-loop-group\">\n <span className=\"w6w-exprmodal-shape-note\">Loop</span>\n {/* The item's keys nest under \"Current item\", collapsed behind the\n same \"N fields ›\" toggle a Previous steps step uses. */}\n {loopFields.length > 0 ? (\n <div className=\"w6w-exprmodal-source-row\">\n {currentItemBtn}\n <FieldsToggle\n count={loopFields.length}\n open={loopOpen}\n onToggle={() => toggleExpanded(\"loop:item\")}\n />\n </div>\n ) : (\n currentItemBtn\n )}\n {loopFields.length > 0 && loopOpen && (\n <div className=\"w6w-exprmodal-subsources\" data-testid=\"expr-loop-fields\">\n {loopFields.map((o) => {\n const ref = `foreach.item.${o.key}`;\n return source(o.key, { kind: \"var\", ref }, \"w6w-exprmodal-field\", null);\n })}\n </div>\n )}\n {source(\"Index\", { kind: \"var\", ref: \"foreach.index\" }, \"w6w-expr-chip-var\", \"#\")}\n </div>\n )}\n {options.hasTrigger &&\n (eventFields.length > 0 ? (\n <>\n <div className=\"w6w-exprmodal-source-row\">\n <button\n type=\"button\"\n className=\"w6w-exprmodal-caret-btn\"\n data-testid=\"expr-caret-event\"\n aria-expanded={expanded.has(\"event\")}\n aria-label={expanded.has(\"event\") ? \"Hide fields\" : \"Show fields\"}\n title={expanded.has(\"event\") ? \"Hide fields\" : \"Show fields\"}\n onClick={() => toggleExpanded(\"event\")}\n >\n {expanded.has(\"event\") ? \"▾\" : \"▸\"}\n </button>\n {source(\n \"trigger.event\",\n { kind: \"var\", ref: \"trigger.event\" },\n \"w6w-expr-chip-var w6w-exprmodal-node\",\n \"⚡\",\n true,\n )}\n </div>\n {expanded.has(\"event\") && (\n <div className=\"w6w-exprmodal-subsources\" data-testid=\"expr-event-fields\">\n {shapeHint(options.eventOutputsFrom)}\n {fieldSources(\"\", eventFields, \"trigger.event\")}\n </div>\n )}\n </>\n ) : (\n <div className=\"w6w-exprmodal-source-row\">\n <span className=\"w6w-exprmodal-caret-spacer\" aria-hidden=\"true\" />\n {source(\n \"trigger.event\",\n { kind: \"var\", ref: \"trigger.event\" },\n \"w6w-expr-chip-var w6w-exprmodal-node\",\n \"⚡\",\n )}\n </div>\n ))}\n {steps.map((st) => {\n // A node's meta (app, action, connection, config) is offered only in the\n // Metadata section below, never beside its output here.\n // Only keys that can become a ref the ENGINE resolves are\n // offered. The guard lives here, at the one place a ref is\n // built, so it holds for any host that supplies `steps` —\n // not only for the flow editor's own projection.\n const fields = (st.outputs ?? []).filter((o) =>\n o.path ? isRefSafePath(o.key) : isRefSafeKey(o.key),\n );\n const stepKey = `step:${st.id}`;\n const isOpen = expanded.has(stepKey);\n // The whole output — still a real, useful ref on its own, and\n // the author's route to a key the guard dropped. Its class,\n // label, sigil and inserted ref are unchanged from before.\n //\n // With fields, the `▸` is pulled OUT of the chip into its own\n // disclosure caret: authors read that arrow as \"expand\", and\n // inside the chip it inserted the whole output instead.\n const wholeBtn = source(\n st.label ?? st.id,\n { kind: \"var\", ref: `nodes.${st.id}.output` },\n \"w6w-expr-chip-var w6w-exprmodal-node\",\n null,\n fields.length > 0,\n );\n if (jsonBinding) {\n return (\n <Fragment key={st.id}>\n <span className=\"w6w-exprmodal-shape-note\">{st.label ?? st.id}</span>\n {source(\n \"Entire output\",\n { kind: \"var\", ref: `nodes.${st.id}.output` },\n \"w6w-expr-chip-var\",\n null,\n false,\n `Entire output of ${st.label ?? st.id}`,\n )}\n {st.needsTest && (\n <div className=\"w6w-exprmodal-subsources\">\n <span className=\"w6w-exprmodal-shape-note\" data-testid=\"expr-needs-test\">\n Run a test of this step to see its fields\n </span>\n </div>\n )}\n {fields.length > 0 && (\n <>\n <div className=\"w6w-exprmodal-source-row\">\n <button\n type=\"button\"\n className=\"w6w-exprmodal-caret-btn\"\n data-testid=\"expr-caret-fields\"\n aria-expanded={isOpen}\n aria-label={isOpen ? \"Hide fields\" : \"Show fields\"}\n title={isOpen ? \"Hide fields\" : \"Show fields\"}\n onClick={() => toggleExpanded(stepKey)}\n >\n {isOpen ? \"▾\" : \"▸\"}\n </button>\n <FieldsToggle\n count={fields.length}\n open={isOpen}\n onToggle={() => toggleExpanded(stepKey)}\n />\n </div>\n {isOpen && (\n <div className=\"w6w-exprmodal-subsources\">\n {shapeHint(st.outputsFrom)}\n {fieldSources(st.id, fields)}\n </div>\n )}\n </>\n )}\n </Fragment>\n );\n }\n return (\n <Fragment key={st.id}>\n {fields.length > 0 ? (\n <div className=\"w6w-exprmodal-source-row\">\n <button\n type=\"button\"\n className=\"w6w-exprmodal-caret-btn\"\n data-testid=\"expr-caret-fields\"\n aria-expanded={isOpen}\n aria-label={isOpen ? \"Hide fields\" : \"Show fields\"}\n title={isOpen ? \"Hide fields\" : \"Show fields\"}\n onClick={() => toggleExpanded(stepKey)}\n >\n {isOpen ? \"▾\" : \"▸\"}\n </button>\n {wholeBtn}\n <FieldsToggle\n count={fields.length}\n open={isOpen}\n onToggle={() => toggleExpanded(stepKey)}\n />\n </div>\n ) : (\n <div className=\"w6w-exprmodal-source-row\">\n <span className=\"w6w-exprmodal-caret-spacer\" aria-hidden=\"true\" />\n {wholeBtn}\n </div>\n )}\n {/* An app action that declares no output shape and has\n never been tested: nothing to offer but the whole\n output, so say how to get its fields. */}\n {st.needsTest && (\n <div className=\"w6w-exprmodal-subsources\">\n <span className=\"w6w-exprmodal-shape-note\" data-testid=\"expr-needs-test\">\n Run a test of this step to see its fields\n </span>\n </div>\n )}\n {/* …and one source per DECLARED output field, nested under\n it, collapsed until the toggle above is expanded\n (`fieldSources`). */}\n {fields.length > 0 && isOpen && (\n <div className=\"w6w-exprmodal-subsources\">\n {shapeHint(st.outputsFrom)}\n {fieldSources(st.id, fields)}\n </div>\n )}\n </Fragment>\n );\n })}\n </RailSection>\n )}\n {stateFields.length > 0 && (\n <RailSection label=\"State\" testId=\"expr-state-group\" {...sectionProps(\"runstate\")}>\n {/* The workflow state this step reads: starting data, variables and what upstream\n steps write. A field only some entry paths set says so. */}\n {source(\"state\", { kind: \"var\", ref: \"state\" }, \"w6w-expr-chip-var\", \"◇\", true)}\n <div className=\"w6w-exprmodal-subsources\" data-testid=\"expr-state-fields\">\n {outputFieldTree(stateFields).map(({ field, depth, name }) => {\n const ref = `state.${field.key}`;\n return source(\n name,\n { kind: \"var\", ref },\n \"w6w-exprmodal-field\",\n null,\n false,\n undefined,\n { name: varLabel(ref), depth, somePaths: field.paths === \"some\" },\n );\n })}\n </div>\n </RailSection>\n )}\n {metaIds.length > 0 && (\n <RailSection label=\"Metadata\" testId=\"expr-metadata-group\" {...sectionProps(\"meta\")}>\n {/* Every node in the workflow, other paths included: its static meta\n (`nodes.<id>.meta.*`) is readable from anywhere, unlike its data. */}\n {metaIds.map((id) => metaNode(id))}\n </RailSection>\n )}\n\n {/* Inputs and Variables in both modes; Documents in expression and starting-state mode; Secrets in expression mode only. */}\n <>\n {options.inputs !== undefined && (\n <RailSection label=\"Inputs\" {...sectionProps(\"inputs\")}>\n {inputs.length === 0 && <span className=\"w6w-expr-menu-empty\">No inputs</span>}\n {inputs.map((i) =>\n source(i, { kind: \"var\", ref: `inputs.${i}` }, \"w6w-expr-chip-var\", \"⇥\"),\n )}\n </RailSection>\n )}\n\n <RailSection\n label=\"Variables\"\n {...sectionProps(\"vars\")}\n action={\n options.createVar && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n data-testid=\"expr-add-var\"\n onClick={() => setAdding(\"var\")}\n >\n + Add\n </button>\n )\n }\n >\n {vars.length === 0 && <span className=\"w6w-expr-menu-empty\">No variables</span>}\n {vars.map((v) =>\n source(v, { kind: \"var\", ref: `var.${v}` }, \"w6w-expr-chip-var\", \"◆\"),\n )}\n </RailSection>\n\n {constants.length > 0 && (\n <RailSection\n label=\"Constants\"\n testId=\"expr-constants-group\"\n {...sectionProps(\"consts\")}\n >\n {constants.map((c) =>\n source(c, { kind: \"var\", ref: `const.${c}` }, \"w6w-expr-chip-var\", \"◈\"),\n )}\n </RailSection>\n )}\n </>\n {(!jsonBinding || seedMode) && (\n <RailSection label=\"Documents\" {...sectionProps(\"docs\")}>\n {documents.length === 0 && <span className=\"w6w-expr-menu-empty\">No documents</span>}\n {documents.map((d) => {\n // Same guard, same single render site, as the steps block above:\n // enumerated raw at the source (studio's `document-sources.ts`),\n // filtered exactly once, here, where the ref is built (A3, A4a).\n const fields = (d.fields ?? []).filter((f) => isRefSafeKey(f.key));\n const docKey = `doc:${d.key}`;\n const isOpen = expanded.has(docKey);\n // The whole document — unconditional, for every format, exactly\n // as before (A2). Its class, label, sigil and inserted ref are\n // unchanged from before.\n const wholeBtn = source(\n d.key,\n { kind: \"var\", ref: `documents.${d.key}` },\n \"w6w-expr-chip-var\",\n \"▦\",\n fields.length > 0,\n );\n return (\n <Fragment key={d.key}>\n {fields.length > 0 ? (\n <div className=\"w6w-exprmodal-source-row\">\n {wholeBtn}\n <FieldsToggle\n count={fields.length}\n open={isOpen}\n onToggle={() => toggleExpanded(docKey)}\n />\n </div>\n ) : (\n wholeBtn\n )}\n {/* …and one source per surviving top-level field, nested\n under it, collapsed until the toggle above is expanded.\n The label is the field key itself — the parent row above\n already shows `d.key` — never `varLabel(ref)`, which\n would spell out the whole dotted ref again. Each row\n additionally carries a SECOND, visible action (D-P1)\n that inserts the SAME ref as a `render` part, so the\n placeholder-substitution behaviour is discoverable at\n the moment of insertion — not only via the chip's own\n post-insertion ⇄ toggle. */}\n {fields.length > 0 && isOpen && (\n <div className=\"w6w-exprmodal-subsources\">\n {fields.map((f) => {\n const ref = `documents.${d.key}.${f.key}`;\n return (\n <div key={ref} className=\"w6w-exprmodal-subsource-row\">\n {source(f.key, { kind: \"var\", ref }, \"w6w-expr-chip-var\", \"·\")}\n {!jsonBinding && (\n <button\n type=\"button\"\n className=\"w6w-exprmodal-render-btn\"\n data-testid=\"expr-insert-render\"\n title={`Insert ${ref} and render its {{ }} placeholders`}\n aria-label={`Insert ${ref} and render its {{ }} placeholders`}\n onClick={() => insertPart({ kind: \"render\", ref })}\n >\n ▤\n </button>\n )}\n </div>\n );\n })}\n </div>\n )}\n </Fragment>\n );\n })}\n </RailSection>\n )}\n {!jsonBinding && (\n <RailSection\n label=\"Secrets\"\n {...sectionProps(\"secrets\")}\n action={\n options.createSecret && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n data-testid=\"expr-add-secret\"\n onClick={() => setAdding(\"secret\")}\n >\n + Add\n </button>\n )\n }\n >\n {secrets.length === 0 && <span className=\"w6w-expr-menu-empty\">No secrets</span>}\n {secrets.map((s) =>\n source(s, { kind: \"secret\", ref: s }, \"w6w-expr-chip-secret\", \"🔒\"),\n )}\n </RailSection>\n )}\n </aside>\n\n {/* Right (json-binding mode): the JSON compose pane over its resolved preview. */}\n {jsonBinding && (\n <div className=\"w6w-exprmodal-main\">\n <div className=\"w6w-exprmodal-editor\">\n <span className=\"w6w-exprmodal-pane-label\">\n JSON\n <span className=\"w6w-muted w6w-small\">\n {\" \"}\n — type JSON, or click a source on the left to insert it at the cursor\n </span>\n </span>\n <div\n className=\"w6w-exprmodal-json\"\n onFocus={() => {\n jsonTouched.current = true;\n }}\n >\n <JsonEditor\n value={jsonText}\n onChange={setJsonText}\n height=\"100%\"\n minHeight=\"0px\"\n aria-label=\"Compose JSON\"\n placeholder={\n seedMode\n ? '{ \"region\": \"us\", \"template\": \"{{ documents.welcome }}\" }'\n : '{ \"key\": \"{{ nodes.step_1.output }}\" }'\n }\n onCreateEditor={(view) => {\n jsonView.current = view;\n }}\n />\n </div>\n </div>\n <div className=\"w6w-exprmodal-preview w6w-exprmodal-result-pane\">\n <span className=\"w6w-exprmodal-pane-label\">\n Result\n <span className=\"w6w-muted w6w-small\">\n {\" \"}\n {seedMode\n ? \" — the state each run starts with, against the sample values\"\n : \" — live preview against the sample values\"}\n </span>\n </span>\n {seedProblem && (\n <span className=\"w6w-muted w6w-small\" role=\"alert\" data-testid=\"expr-json-problem\">\n {seedProblem}\n </span>\n )}\n <pre className=\"w6w-exprmodal-result\" data-testid=\"expr-json-result\">\n {jsonParsed.ok\n ? JSON.stringify(\n resolveComposed(jsonParsed.value, (leaf) =>\n resolveParamJson(leaf, sampleScope()),\n ),\n null,\n 2,\n )\n : jsonText.trim() === \"\"\n ? \"\"\n : \"Invalid JSON\"}\n </pre>\n </div>\n </div>\n )}\n\n {/* Right: editor over the saved {{ }} template. */}\n {!jsonBinding && (\n <div className=\"w6w-exprmodal-main\">\n <div className=\"w6w-exprmodal-editor\">\n <span className=\"w6w-exprmodal-pane-label\">\n Expression\n <span className=\"w6w-muted w6w-small\"> — click a source on the left, or type</span>\n </span>\n <div\n ref={editorRef}\n className={`w6w-exprmodal-chips${masked ? \" is-masked\" : \"\"}${\n parts.length === 0 ? \" is-empty\" : \"\"\n }`}\n contentEditable\n suppressContentEditableWarning\n role=\"textbox\"\n tabIndex={0}\n aria-multiline={multiline ? \"true\" : \"false\"}\n aria-label=\"Expression\"\n data-placeholder='Pick a field, then type == \"value\"'\n aria-invalid={authored.error !== null}\n aria-describedby={authored.error ? \"expression-problem\" : undefined}\n spellCheck={false}\n onInput={() => {\n // D-3: promote a just-closed `{{ … }}` marker to a chip AT\n // THE KEYSTROKE THAT CLOSES IT — caret-safe surgery on the\n // matched span only (see `promoteCompletedMarkerAtCaret`'s\n // own docstring). `sync()` unconditionally afterwards either\n // way: promoted or not, the DOM is the source of truth.\n // NEVER bump `paintGen` here — see the warning at the top of\n // this file and `G-typing` in `expr-template-guards.test.cjs`.\n const el = editorRef.current;\n if (el) promoteCompletedMarkerAtCaret(el, { renderToggle: true });\n sync();\n }}\n onDoubleClick={(e) => {\n // D-3, the reverse direction: double-click a chip back to its\n // editable `{{ … }}` text, in place. Mirrors the onClick\n // delegate's short-circuit order just below — data-x, then\n // data-render-toggle — so a precise double-click on either\n // still wins (in practice the FIRST of the two clicks that\n // make up a dblclick already removes/flips the chip via\n // onClick, so by the time this fires there is no\n // `.w6w-expr-chip` left to find; these checks are the\n // explicit guard for that intent).\n const target = e.target as HTMLElement;\n if (target.closest(\"[data-x]\")) return;\n if (target.closest(\"[data-render-toggle]\")) return;\n const chip = target.closest(\".w6w-expr-chip\") as HTMLElement | null;\n if (!chip) return;\n e.preventDefault();\n const node = chipToText(chip);\n if (node) {\n const doc = node.ownerDocument;\n const after = doc.createRange();\n after.setStartAfter(node);\n after.collapse(true);\n const sel = doc.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(after);\n }\n sync();\n }}\n onBlur={() => {\n // Discrete-event chip-ify commit #1: the editor just lost\n // focus, so any hand-typed `{{ … }}` left as raw text gets\n // one chance to become a chip. NEVER do this from `onInput`\n // above — see the `paintGen` warning at the top of this file\n // and G-typing in `expr-template-guards.test.cjs`.\n const el = editorRef.current;\n if (!el) return;\n adoptText(serializeTemplate(readParts(el)), { restoreFocus: false });\n }}\n onPaste={(e) => {\n // Discrete-event chip-ify commit #2. `insertNodeAtCaret` is\n // the SAME mechanism a rail click uses, so the caret is\n // preserved by construction — no bespoke caret-offset repaint\n // needed (out of scope by contract). No `setPaintGen`: each\n // part is inserted directly into the live DOM, exactly like a\n // rail insertion, so the existing chips are never re-painted.\n e.preventDefault();\n const el = editorRef.current;\n if (!el) return;\n const text = e.clipboardData?.getData(\"text/plain\") ?? \"\";\n for (const part of parseRootAnchoredTemplate(text)) {\n if (part.kind === \"text\") {\n insertNodeAtCaret(el, el.ownerDocument.createTextNode(part.value ?? \"\"));\n } else {\n insertNodeAtCaret(\n el,\n makeChip(el.ownerDocument, part, { renderToggle: true }),\n );\n }\n }\n sync();\n }}\n onClick={(e) => {\n const target = e.target as HTMLElement;\n const x = target.closest(\"[data-x]\");\n if (x) {\n e.preventDefault();\n x.closest(\".w6w-expr-chip\")?.remove();\n sync();\n return;\n }\n // The render affordance: flip a var⇄render chip IN PLACE. The\n // ref never changes — only `data-kind` (via a rebuilt chip\n // from the same `data-ref`, `makeChip`'s only construction\n // path) — and this does NOT bump `paintGen`, exactly like the\n // remove control above.\n const toggle = target.closest(\"[data-render-toggle]\");\n if (toggle) {\n e.preventDefault();\n const chip = toggle.closest(\".w6w-expr-chip\") as HTMLElement | null;\n if (chip) {\n const ref = chip.getAttribute(\"data-ref\") ?? \"\";\n const nextKind =\n chip.getAttribute(\"data-kind\") === \"render\" ? \"var\" : \"render\";\n chip.replaceWith(\n makeChip(\n chip.ownerDocument,\n { kind: nextKind, ref },\n { renderToggle: true },\n ),\n );\n }\n sync();\n }\n }}\n onKeyDown={(e) => {\n if (e.key !== \"Enter\") return;\n // ALWAYS suppressed — with or without Shift, multiline or not.\n // The browser's own line break (a wrapper <div>, or a <br>) is\n // markup we neither paint nor want to depend on.\n e.preventDefault();\n if (!multiline) return;\n const el = editorRef.current;\n if (!el) return;\n // Our own literal \"\\n\" text node, via the same caret helper the\n // source picker inserts chips with. `.w6w-exprmodal-chips` is\n // `pre-wrap`, so it renders as a break. The filler keeps a break\n // at the very END visible (and is skipped by `readParts`, so it\n // never reaches the value).\n insertNodeAtCaret(el, el.ownerDocument.createTextNode(\"\\n\"));\n ensureFillerBreak(el);\n sync();\n }}\n />\n <span className=\"w6w-muted w6w-small\">\n Pick a field, then type <code>== \"value\"</code>. Combine conditions with{\" \"}\n <code>&amp;&amp;</code> or <code>||</code>. Double-click a chip to edit it.\n </span>\n {authored.error && (\n <span id=\"expression-problem\" role=\"alert\" className=\"w6w-error\">\n {authored.error}\n </span>\n )}\n </div>\n {usedRefs.length > 0 && (\n <div className=\"w6w-exprmodal-preview\">\n <span className=\"w6w-exprmodal-pane-label\">\n Sample values\n <span className=\"w6w-muted w6w-small\">\n {\" \"}\n — try the expression against example data\n </span>\n </span>\n {usedRefs.map((ref) => (\n <label key={ref} className=\"w6w-field\">\n <span>{ref}</span>\n <input\n type=\"text\"\n value={samples[ref] ?? effectiveSamples[ref] ?? \"\"}\n placeholder=\"sample value\"\n onChange={(e) => setSamples((s) => ({ ...s, [ref]: e.target.value }))}\n />\n </label>\n ))}\n </div>\n )}\n <div className=\"w6w-exprmodal-preview w6w-exprmodal-result-pane\">\n <span className=\"w6w-exprmodal-pane-label\">\n Result\n <span className=\"w6w-muted w6w-small\">\n {\" \"}\n — live preview against the sample values\n </span>\n </span>\n <Copyable value={result} readOnly>\n <pre className=\"w6w-exprmodal-result\">{result || \" \"}</pre>\n </Copyable>\n {resultNotes.length > 0 && (\n <span className=\"w6w-muted w6w-small\" data-testid=\"expr-result-source\">\n {resultNotes.join(\" · \")}\n </span>\n )}\n </div>\n </div>\n )}\n </div>\n\n {/* Nested \"+ Add\" dialog — last child of this Modal, so its own\n <dialog> stacks over this one in the browser's top layer\n (structurally identical to StepBuilderModal's AddConnectionModal\n nesting). Gated the same way the rail button was, so state can\n never point at a store the host didn't wire a callback for. */}\n {adding === \"var\" && options.createVar && (\n <AddValueModal kind=\"var\" onCreate={options.createVar} onClose={closeAdding} />\n )}\n {adding === \"secret\" && options.createSecret && (\n <AddValueModal kind=\"secret\" onCreate={options.createSecret} onClose={closeAdding} />\n )}\n </Modal>\n );\n}\n\n/**\n * The disclosure beside a rail source that has child field rows (a step's\n * output fields, a document's top-level keys). It names what it reveals —\n * \"11 fields\" — because the source chip's own `▸`/`▦` sigil reads as an\n * expander but INSERTS the whole value; a bare 20px chevron next to it went\n * unnoticed, leaving authors no visible way to reach `get_event_1.name`.\n */\n/** The rail's accordion sections, in render order. */\ntype RailSectionKey =\n | \"state\"\n | \"runstate\"\n | \"meta\"\n | \"inputs\"\n | \"vars\"\n | \"consts\"\n | \"docs\"\n | \"secrets\";\n\n/**\n * One collapsible rail section. The header (and its `action`, e.g. \"+ Add\") always shows; the\n * body stays mounted and animates its height (`grid-template-rows` 0fr → 1fr), made `inert`\n * while closed so its rows leave the tab order.\n */\nfunction RailSection({\n label,\n open,\n onToggle,\n action,\n testId,\n children,\n}: {\n label: string;\n open: boolean;\n onToggle: () => void;\n action?: ReactNode;\n testId?: string;\n children: ReactNode;\n}) {\n const bodyId = useId();\n const bodyRef = useRef<HTMLDivElement>(null);\n // Set as a DOM property: React 18 and 19 disagree on how the `inert` attribute is spelled.\n useLayoutEffect(() => {\n if (bodyRef.current) bodyRef.current.inert = !open;\n }, [open]);\n return (\n <div\n className={`w6w-exprmodal-group${open ? \" is-open\" : \"\"}`}\n data-testid={testId}\n data-section-open={open ? \"true\" : \"false\"}\n >\n <div className=\"w6w-exprmodal-group-head\">\n <button\n type=\"button\"\n className=\"w6w-exprmodal-group-toggle\"\n data-testid=\"expr-section-toggle\"\n aria-expanded={open}\n aria-controls={bodyId}\n onClick={onToggle}\n >\n <span className=\"w6w-exprmodal-group-label\">{label}</span>\n <span className=\"w6w-exprmodal-group-caret\" aria-hidden=\"true\">\n ›\n </span>\n </button>\n {action}\n </div>\n <div id={bodyId} ref={bodyRef} className=\"w6w-exprmodal-group-body\" aria-hidden={!open}>\n <div className=\"w6w-exprmodal-group-inner\">{children}</div>\n </div>\n </div>\n );\n}\n\nfunction FieldsToggle({\n count,\n open,\n onToggle,\n}: { count: number; open: boolean; onToggle: () => void }) {\n return (\n <button\n type=\"button\"\n className=\"w6w-exprmodal-toggle-btn\"\n data-testid=\"expr-toggle-fields\"\n aria-expanded={open}\n title={open ? \"Hide fields\" : \"Show fields\"}\n onClick={onToggle}\n >\n {count} {count === 1 ? \"field\" : \"fields\"} {open ? \"⌄\" : \"›\"}\n </button>\n );\n}\n\n/** The fixed Metadata leaves (R-7): key under `steps.<id>.meta.`, and the label shown. */\nconst META_LEAVES: [string, string][] = [\n [\"app\", \"App\"],\n [\"version\", \"App version\"],\n [\"action\", \"Action\"],\n [\"connectionId\", \"Connection ID\"],\n [\"subscriptionId\", \"Subscription ID\"],\n [\"url\", \"Webhook URL\"],\n];\n/** The four leaves an external app step always offers (R-7); the rest only when known. */\nconst APP_META_KEYS = new Set([\"app\", \"version\", \"action\", \"connectionId\"]);\n\ninterface AddValueModalProps {\n kind: \"var\" | \"secret\";\n onCreate: (input: { name: string; value: string; description?: string }) => Promise<void>;\n onClose: () => void;\n}\n\n/**\n * The nested \"+ Add\" form. Same shape as `AddConnectionModal`'s\n * `ConnectionConfig` — `w6w-stack` body, one `w6w-field` label per input, an\n * inline `w6w-result w6w-error` block, ghost-Cancel + primary footer — but it\n * never fetches: `onCreate` (the host's `ExpressionOptions.createVar` /\n * `.createSecret`) is the only IO, so this mounts fine with no\n * `<W6WUIProvider>` around it (see `ExpressionEditorModal`'s own module\n * contract). A rejection leaves the dialog open with the message shown, name\n * hint copy matches studio's Vars/Vault pages.\n */\nfunction AddValueModal({ kind, onCreate, onClose }: AddValueModalProps) {\n const [name, setName] = useState(\"\");\n const [value, setValue] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [pending, setPending] = useState(false);\n\n const noun = kind === \"var\" ? \"variable\" : \"secret\";\n\n async function submit() {\n setError(null);\n setPending(true);\n try {\n await onCreate({ name, value, description: description || undefined });\n onClose();\n } catch (e) {\n setError((e as Error).message);\n } finally {\n setPending(false);\n }\n }\n\n return (\n <Modal title={`Add ${noun}`} onClose={onClose}>\n {/* Body + pinned footer (D-3): `.w6w-stack` stays intact INSIDE the body so\n the fields keep their own spacing; only the action row moved out. */}\n <div className=\"w6w-modal-body\">\n <div className=\"w6w-stack\">\n <label className=\"w6w-field\">\n <span>Name</span>\n <input\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={kind === \"var\" ? \"e.g. api_base_url\" : \"e.g. openai_api_key\"}\n autoComplete=\"off\"\n data-testid=\"expr-add-value-name\"\n // biome-ignore lint/a11y/noAutofocus: nested dialog opened on demand — showModal() already moved focus in, this just picks the first field.\n autoFocus\n />\n <span className=\"w6w-muted w6w-small\">\n Letters, digits, and underscores. Must start with a letter or underscore.\n Case-sensitive.\n </span>\n </label>\n\n <label className=\"w6w-field\">\n <span>Value</span>\n <input\n type={kind === \"secret\" ? \"password\" : \"text\"}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n autoComplete=\"off\"\n data-testid=\"expr-add-value-value\"\n />\n {kind === \"secret\" && (\n <span className=\"w6w-muted w6w-small\">\n Stored encrypted at rest. Once saved, it is not readable through the UI.\n </span>\n )}\n </label>\n\n <label className=\"w6w-field\">\n <span>Description</span>\n <input\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional\"\n autoComplete=\"off\"\n />\n </label>\n\n {error && <div className=\"w6w-result w6w-error\">{error}</div>}\n </div>\n </div>\n <div className=\"w6w-modal-actions\">\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n data-testid=\"expr-add-value-cancel\"\n onClick={onClose}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"w6w-btn\"\n data-testid=\"expr-add-value-save\"\n disabled={!name || !value || pending}\n onClick={submit}\n >\n {pending ? \"Saving…\" : \"Save\"}\n </button>\n </div>\n </Modal>\n );\n}\n","/**\n * Context that supplies the var/secret PICKER data to every `ExpressionInput`\n * under it (task 3.2). The editor tree is deep — a step's params render several\n * layers below the editor root (`WorkflowFlowEditor → StepEditModal/StepBuilder\n * → ParamsForm → ParamField → ExpressionInput`), so threading names as props\n * through each layer would be noisy. A context keeps the wiring at the two ends:\n * the editor provides the names once, the input consumes them where it renders.\n *\n * The data pattern stays intact — ui components remain pure (they never fetch);\n * the host (studio) fetches `/vars` + `/vault` and hands the NAMES in via the\n * editor's `exprOptions` prop, which feeds this provider. Only names/refs ever\n * cross this boundary — secret plaintext never reaches the client.\n *\n * ## The scope is PROGRESSIVE, and that is the point\n *\n * `ExpressionOptionsProvider` **layers over** whatever it inherits rather than\n * replacing it, so scope is assembled by the tree instead of by one exhaustive\n * object at each call site:\n *\n * ```\n * app shell ── vars · secrets · documents · sampleValues · sealSecret · create*\n * └ page ── + inputs (a Function's / Endpoint's declared input keys)\n * └ region ── + steps (the workflow state leading to one step)\n * ```\n *\n * Two properties fall out of that, and both are requirements rather than\n * conveniences:\n *\n * 1. **Position, not plumbing, decides scope.** An `ExpressionInput` rendered\n * anywhere under the page — a modal, a mapping row, a nested card — sees\n * the same rail, because it inherits it. Before this, scope travelled as an\n * `exprOptions` prop and a field the prop had not been threaded to opened\n * the editor with an empty rail: the `ƒx` toggles on an Implementation\n * card's mapping rows offered nothing, while the very same editor reached\n * through the card's \"Change\" button offered everything.\n * 2. **Narrower scope cannot leak outward.** `inputs` added by a Function page\n * is invisible to a sibling route and to anything above the provider,\n * because React context only flows down. Navigating away drops it with the\n * subtree — no teardown to remember and no chance of one page's `inputs.*`\n * appearing in another's picker.\n *\n * Merging is **shallow, per key**: a key present in `value` wins outright (a\n * provider narrowing `vars` replaces the inherited list, it does not union with\n * it), and a key absent from `value` is inherited. To *remove* an inherited key\n * for a subtree, pass it explicitly as `undefined` — `{ inputs: undefined }` —\n * which is a present key and therefore wins.\n */\nimport { type ReactNode, createContext, useContext, useMemo } from \"react\";\nimport type { SecretValue } from \"../types.ts\";\n\n/**\n * Drop the step being edited (or drafted, not yet persisted) from its own rail\n * sources — a step cannot reference its own output.\n */\nexport function excludeSelfStep(\n steps: ExpressionStepSource[],\n selfId: string | null | undefined,\n): ExpressionStepSource[] {\n return selfId ? steps.filter((s) => s.id !== selfId) : steps;\n}\n\n/** One pickable output field of a step / trigger event, as the rail lists it. */\nexport interface ExpressionFieldSource {\n key: string;\n label?: string;\n path?: boolean;\n /**\n * `true` for a key the app DECLARES but the step's real (fresh/persisted) shape lacks:\n * offered muted, \"declared by the app\".\n */\n declaredOnly?: true;\n}\n\n/** An upstream step whose output this field can reference (`nodes.<id>.output`). */\nexport interface ExpressionStepSource {\n /** Step id — the key under `steps` in the run scope. */\n id: string;\n /** Human label (defaults to the id). */\n label?: string;\n /**\n * The step's output field keys, when any are known (a manual trigger's\n * configured `fields`, a built-in node's static output, or an app action's\n * shape — see `outputsFrom`). Each entry feeds exactly one ref —\n * `nodes.<id>.output.<key>` — which is the canonical form the engine resolves (`steps.<id>…` is its compat alias)\n * (`RunScope.steps`; `core/rfcs/workflow.md` §\"Expressions\", `core/rfcs/node-types.md`\n * \"Executing a trigger node yields the run's start payload … which downstream\n * nodes read as `steps.<triggerId>.output`\").\n *\n * `key` is carried **verbatim**: a display-shortened key would build a ref\n * that renders fine in the editor and evaluates to empty at run time, with no\n * error. `label` is for display only and must never be substituted into a ref.\n *\n * **Omitted** (not `[]`) when the step declares no outputs, so a consumer can\n * tell \"nothing declared\" from \"declared none\" without a special case.\n */\n outputs?: ExpressionFieldSource[];\n /**\n * Where `outputs` came from, for an app-action step: a fresh test output, the persisted\n * test shape, the action's declared `output`, or its `sample` (`output-shape.ts`).\n * An entry with `path: true` is a dot path into nested output (`start.utc`),\n * checked segment by segment; without it the key is one literal key.\n */\n outputsFrom?: \"fresh\" | \"persisted\" | \"declared\" | \"sample\";\n /**\n * `true` when the step is an app action that declares no output shape and has\n * no test run yet — the picker tells the author to run a test to see fields.\n */\n needsTest?: boolean;\n /**\n * `true` for an EXTERNAL app-action step only (R-7): the picker then offers a fixed\n * Metadata group (`nodes.<id>.meta.app|version|action|connectionId`). **Omitted, not\n * `false`**, for triggers and every `@w6w/*` node. Carries no metadata VALUE: the static\n * values come from {@link ExpressionOptions.nodeMeta}.\n */\n hasMeta?: boolean;\n}\n\n/**\n * One field of the merged workflow STATE a step reads (`state-shape.ts`), offered as\n * `state.<key>` in the picker's \"State\" section. `paths` says whether every entry path into the\n * step sets it (`all`) or only some (`some` — e.g. one of two converging triggers writes it).\n */\nexport interface ExpressionStateField extends ExpressionFieldSource {\n paths: \"all\" | \"some\";\n}\n\n/**\n * The For each a step sits in the body of: offered as the rail's \"Loop\" group (Current item,\n * Index, one row per item field). Present only for a loop-body step.\n */\nexport interface ExpressionLoopSource {\n foreachId: string;\n /** Element [0] of the For each's resolved `items`. OMITTED (key absent) when unresolvable. */\n itemSample?: unknown;\n /** `inferOutputFields(itemSample)`. OMITTED when none. */\n itemOutputs?: { key: string; label?: string; path?: boolean }[];\n}\n\n/**\n * A document contributing pickable refs (`documents.<key>`, and one\n * `documents.<key>.<field>` per top-level field when it qualifies).\n *\n * A document contributes field sub-entries **iff**: `doc.format === \"json\"`\n * AND `JSON.parse(doc.content)` succeeds into a plain object, OR\n * `doc.format === \"yaml\"` AND npm `yaml`'s `parse(doc.content)` succeeds into\n * a plain object — where *plain object* means\n * `typeof v === \"object\" && v !== null && !Array.isArray(v)`. This mirrors\n * the engine's own gate: `documentsSeed`\n * (`packages/server/packages/api/run-seed.ts`, read-only, out of scope) is the\n * authority for each format — `format === \"json\"` or `format === \"yaml\"`,\n * then a `try/catch` parse, falling back to the raw content string on either\n * a non-matching format or a throw. `text`/`markdown`/`html` documents, and a\n * `json`/`yaml` document whose parse throws or yields a non-plain-object\n * (array/scalar), are excluded — offering a field ref outside this gate would\n * fail at run time with `render_ref_unresolved`, because the run scope itself\n * never parsed that document into an object.\n *\n * The two parsers (`@std/yaml` server-side, npm `yaml` here) are not\n * identical for every input — they diverge on tab-indented content and on an\n * unresolvable custom tag, both accepted, tested debt (D-3) — but agree on\n * everything else, including a plain JSON object (JSON is a subset of YAML).\n */\nexport interface ExpressionDocumentSource {\n /** Document key — the key under `documents` in the run scope. */\n key: string;\n /**\n * The document's top-level field keys, when the gate above holds. Each\n * entry feeds exactly one ref — `documents.<key>.<field>` — with `key`\n * carried **verbatim**: a display-shortened key would build a ref that\n * renders fine in the editor and evaluates to empty at run time, with no\n * error.\n *\n * **Omitted** (not `[]`) when the document contributes no fields, so a\n * consumer can tell \"nothing declared\" from \"declared none\" without a\n * special case — mirrors {@link ExpressionStepSource.outputs}'s own rule.\n */\n fields?: { key: string }[];\n}\n\n/** Known variable/secret names offered in an ExpressionInput's insert menu. */\nexport interface ExpressionOptions {\n vars?: string[];\n /**\n * Account-level constants (`const.<name>`): read-only, set by an\n * administrator, ordinary data (not secret). Offered as insertable chips\n * only — there is deliberately no create callback.\n */\n constants?: string[];\n secrets?: string[];\n /**\n * Function/run input keys in scope (`inputs.<name>`). Present when the field\n * is edited inside a Function (the engine resolves these from `RunScope.inputs`);\n * omitted for a standalone field.\n */\n inputs?: string[];\n /**\n * Documents in scope (`documents.<key>`, plus `documents.<key>.<field>` for\n * each document that qualifies — see {@link ExpressionDocumentSource}). A\n * store-independent affordance: whatever the host passes is offered as\n * insertable chips. Omitted when no documents are available.\n */\n documents?: ExpressionDocumentSource[];\n /**\n * The workflow state leading to this step: upstream steps whose output is in\n * scope (`nodes.<id>.output`). Present only in a workflow context; omitted for\n * a standalone field.\n */\n steps?: ExpressionStepSource[];\n /** The enclosing For each, when the field belongs to a loop-body step (`foreach.item` / `foreach.index`). */\n loop?: ExpressionLoopSource;\n /**\n * The merged workflow state this step reads (starting data, variables and upstream writers;\n * `state-shape.ts`). The picker lists it as the \"State\" section, only when non-empty.\n */\n stateShape?: { fields: ExpressionStateField[] };\n /** Whether a trigger event is in scope (`trigger.event`). */\n hasTrigger?: boolean;\n /**\n * The trigger event's fields, offered as `trigger.event.<key>` under the `trigger.event`\n * chip: the payload the entry trigger last ran with, else an app trigger's declared event\n * fields. Omitted when none are known.\n */\n eventOutputs?: ExpressionFieldSource[];\n /**\n * Where {@link eventOutputs} came from: a test this session (`fresh`), the server's remembered\n * sample (`persisted`), the trigger's declared `output`, or its `sample`.\n */\n eventOutputsFrom?: ExpressionStepSource[\"outputsFrom\"];\n /**\n * Which tier each value in {@link sampleValues} came from, keyed by the same full ref:\n * a fresh test output, the persisted test (`from last test`) or the app's declared\n * `sample` (`example from the app`). A ref absent here is not a step/event value.\n */\n valueSources?: Record<string, \"fresh\" | \"persisted\" | \"sample\">;\n /**\n * Every node's configuration keys, read as `nodes.<id>.config.<key>` on any run whether or not\n * the node runs — its literal settings, and a webhook trigger's `url`. Offered as the rail's\n * \"Node settings\" group, for every node, not only upstream ones. Workflow context only.\n */\n nodeConfigs?: { id: string; keys: string[] }[];\n /**\n * Each node's configuration VALUES, keyed by node id — what a run reads at\n * `nodes.<id>.meta.config` (`nodeConfigOf`): authored literal params (never a secret, never a\n * binding) plus a webhook trigger's `url` from its subscription. The Test tab and the Result\n * preview resolve config refs against it. Workflow context only.\n */\n nodeConfig?: Record<string, Record<string, unknown>>;\n /**\n * Each node's static metadata VALUES, keyed by node id — what a run reads at\n * `nodes.<id>.meta.<key>` whether or not the node ran (`nodeMetaOf`): `app`, `action`,\n * `connectionId`, the `version` the canvas labels it with, and a webhook trigger's\n * `subscriptionId` / `url`. Offered as Metadata leaves\n * in the picker and resolved by the previews. Workflow context only.\n */\n nodeMeta?: Record<string, Record<string, unknown>>;\n /**\n * Design-time sample values the Result preview substitutes for known refs,\n * keyed by FULL ref (`\"var.from_email\"`, `\"documents.test\"`). Seeded by the\n * host from the project's real vars/documents so the preview shows actual\n * values instead of the raw `{{ ref }}` template. Optional — a user-typed\n * Sample value still overrides, and unknown refs keep the raw fallback.\n */\n sampleValues?: Record<string, unknown>;\n /**\n * Seal a typed secret value into an at-rest `SecretValue` envelope via the\n * host (the client has no key). Provided by studio (`POST /vault/seal`); when\n * present, a secret-typed field encrypts on blur so its clear text never\n * lands in the workflow/config JSON. Absent → the value stays a plain string\n * and the server encrypts it on receive instead.\n */\n sealSecret?: (value: string) => Promise<SecretValue>;\n /**\n * Create a new named variable via the host (`POST /vars`-shaped: the host\n * persists it, `ui` never fetches). Powers the rail's \"+ Add\" control next\n * to the Variables group label. Absent ⇒ the control is not rendered.\n */\n createVar?: (input: { name: string; value: string; description?: string }) => Promise<void>;\n /**\n * Create a new named secret via the host (`POST /vault`-shaped, plaintext\n * value — the server encrypts it, `ui` never sees a key). Powers the rail's\n * \"+ Add\" control next to the Secrets group label. Absent ⇒ the control is\n * not rendered.\n */\n createSecret?: (input: { name: string; value: string; description?: string }) => Promise<void>;\n}\n\nconst ExpressionOptionsCtx = createContext<ExpressionOptions>({});\n\nexport interface ExpressionOptionsProviderProps {\n /**\n * The scope this level CONTRIBUTES — not the whole scope. Shallow-merged over\n * whatever is inherited (see the module doc): keys here win, keys absent are\n * inherited, and an explicit `undefined` removes an inherited key for this\n * subtree.\n */\n value: ExpressionOptions;\n children: ReactNode;\n}\n\n/**\n * Contribute expression scope to every `ExpressionInput` below.\n *\n * Layers over the inherited scope rather than replacing it, so an app shell can\n * provide vars/secrets/documents once and a page can add its `inputs` without\n * restating them — and without a field somewhere in the page missing the rail\n * because a prop was not threaded to it. See the module doc for the model.\n */\nexport function ExpressionOptionsProvider({ value, children }: ExpressionOptionsProviderProps) {\n const inherited = useContext(ExpressionOptionsCtx);\n // Memoised on the two inputs: a fresh object every render would re-render\n // every consumer below on every parent render, which on the workflow editor\n // is a repaint of each chip rail.\n const merged = useMemo(() => ({ ...inherited, ...value }), [inherited, value]);\n return <ExpressionOptionsCtx.Provider value={merged}>{children}</ExpressionOptionsCtx.Provider>;\n}\n\n/**\n * The scope in effect here — every contributing provider above, merged.\n *\n * Empty by default so a standalone `ExpressionInput` (no provider) still works\n * — authors just type names by hand.\n */\nexport function useExpressionOptions(): ExpressionOptions {\n return useContext(ExpressionOptionsCtx);\n}\n","import { useLayoutEffect, useRef, useState } from \"react\";\nimport type { ExprValue, SecretValue } from \"../types.ts\";\nimport { ExpressionEditorModal } from \"./ExpressionEditorModal.tsx\";\nimport { useExpressionOptions } from \"./ExpressionOptions.tsx\";\nimport { compileAuthoredParts } from \"./expression-authoring.ts\";\nimport {\n chipToText,\n ensureFillerBreak,\n insertNodeAtCaret,\n paintParts,\n placeCaretAtEnd,\n promoteCompletedMarkerAtCaret,\n readParts,\n} from \"./expression-dom.ts\";\nimport { holdsExpression, partsToValue, valueToParts } from \"./expression-template.ts\";\n\n/**\n * ExpressionInput — a single field that reads like a textbox but whose contents\n * are inline SEGMENTS: plain text plus var/secret/expr chips (Notion/Zapier\n * blocks). You can type directly; to browse the data sources in scope\n * (variables, secrets, upstream step outputs) and build a reference, open the\n * full editor via the ƒx button — see {@link ExpressionEditorModal}.\n *\n * Value in ↔ out: incoming `value` is a plain string, an `ExprValue`, or a\n * sealed `SecretValue`. `onChange` emits the leanest faithful form — a plain\n * string when pure-text, an `ExprValue` for mixed content, or a sealed\n * `SecretValue` once a masked field is encrypted.\n */\nexport interface ExpressionInputProps {\n value: ExprValue | string | SecretValue | undefined;\n onChange: (next: ExprValue | string | SecretValue) => void;\n placeholder?: string;\n /** Mask typed text as dots + seal on blur (used for secret-typed params). */\n masked?: boolean;\n /**\n * The underlying param holds multi-line text (a `text`-typed param, or one\n * flagged `config.multiline` — the same fields that render a `textarea`).\n * Enter then inserts a literal `\"\\n\"` at the caret instead of being swallowed,\n * and `aria-multiline` follows. Omitted ⇒ single-line, as every existing\n * consumer expects.\n */\n multiline?: boolean;\n readOnly?: boolean;\n /** Picker data; falls back to the nearest `ExpressionOptionsProvider`. */\n options?: { vars?: string[]; secrets?: string[] };\n \"aria-label\"?: string;\n}\n\nexport function ExpressionInput({\n value,\n onChange,\n placeholder,\n masked,\n multiline,\n readOnly,\n options,\n \"aria-label\": ariaLabel,\n}: ExpressionInputProps) {\n // Seed once and own the content thereafter — the parent re-keys this widget\n // per field, so we never fight our own onChange echoes.\n const [state, setState] = useState(() => valueToParts(value));\n const { parts, sealed } = state;\n const [paintGen, setPaintGen] = useState(0);\n const [sealing, setSealing] = useState(false);\n const [modalOpen, setModalOpen] = useState(false);\n const wantFocus = useRef(false);\n const editorRef = useRef<HTMLDivElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n const ctxOptions = useExpressionOptions();\n // Merge so an explicit `options` prop can override vars/secrets while the\n // richer context sources (steps, trigger, sealSecret) still flow through.\n const resolved = { ...ctxOptions, ...(options ?? {}) };\n const sealSecret = ctxOptions.sealSecret;\n\n // Paint the editor DOM from `parts` on programmatic changes only (mount,\n // modal save, seal/replace) — never on keystrokes (would clobber the caret).\n // biome-ignore lint/correctness/useExhaustiveDependencies: repaint is gated on paintGen, never on `parts`.\n useLayoutEffect(() => {\n const el = editorRef.current;\n if (!el || sealed) return;\n paintParts(el, parts);\n if (wantFocus.current || el.ownerDocument.activeElement === el) {\n el.focus();\n placeCaretAtEnd(el);\n wantFocus.current = false;\n }\n }, [paintGen, sealed]);\n\n const syncFromDom = () => {\n const el = editorRef.current;\n if (!el) return;\n const next = readParts(el);\n setState((s) => ({ ...s, parts: next }));\n const authored = compileAuthoredParts(next, resolved);\n onChange(partsToValue(authored.parts));\n };\n\n // A masked field must never leave clear text: seal a plain typed value into a\n // `{type:\"secret\"}` envelope via the host (the client has no key).\n const sealPlain = async (v: string) => {\n if (!sealSecret) return false;\n setSealing(true);\n try {\n const env = await sealSecret(v);\n wantFocus.current = false;\n setState({ parts: [], sealed: env });\n setPaintGen((g) => g + 1);\n onChange(env);\n return true;\n } catch {\n return false; // keep the value; the server still encrypts at rest on save\n } finally {\n setSealing(false);\n }\n };\n\n // Seal on blur — but not while the editor modal is open (focus moved there).\n //\n // Deliberate behaviour change (CONDUCTOR AMENDMENT 2026-08-14, T1.2.2):\n // a masked field holding a ROOTED `{{ var.x }}` / `{{ secrets.K }}` holds a\n // reference (`holdsExpression`), so it never seals (sealing would encrypt the\n // template text and permanently break resolution). A masked field holding\n // an UNROOTED placeholder like `{{name}}` still parses to a plain string\n // and still seals, exactly as before — see `expression-template.test.ts`'s\n // CA-4 tests for both arms.\n const onLeave = (e: React.FocusEvent) => {\n if (modalOpen || !masked || readOnly || sealing) return;\n const next = e.relatedTarget as Node | null;\n if (next && wrapperRef.current?.contains(next)) return;\n const v = partsToValue(parts);\n // A template string (`{{ secrets.K }}`) is a reference, not a value to seal.\n if (typeof v === \"string\" && v !== \"\" && !holdsExpression(v)) void sealPlain(v);\n };\n\n // Adopt a value from the modal: re-seed + repaint. For a masked field a plain\n // string is sealed instead of stored in the clear.\n const adopt = (next: ExprValue | string) => {\n if (masked && typeof next === \"string\" && next.trim() !== \"\" && !holdsExpression(next)) {\n void sealPlain(next);\n return;\n }\n wantFocus.current = false;\n setState(valueToParts(next));\n setPaintGen((g) => g + 1);\n onChange(next);\n };\n\n // A sealed at-rest secret: a single masked chip; ciphertext is never rendered.\n if (sealed) {\n return (\n <div className={`w6w-expr-sealed${readOnly ? \" is-readonly\" : \"\"}`} aria-label={ariaLabel}>\n <span className=\"w6w-expr-chip w6w-expr-chip-secret\" title=\"Encrypted secret\">\n <span className=\"w6w-expr-chip-sigil\">🔒</span>\n <span className=\"w6w-expr-chip-label\">••••••</span>\n </span>\n {!readOnly && (\n <button\n type=\"button\"\n className=\"w6w-expr-replace\"\n onClick={() => {\n wantFocus.current = true;\n setState({ parts: [], sealed: null });\n setPaintGen((g) => g + 1);\n onChange(\"\");\n }}\n >\n Replace\n </button>\n )}\n </div>\n );\n }\n\n return (\n <div className=\"w6w-expr\" ref={wrapperRef} onBlur={onLeave}>\n <div className=\"w6w-expr-field\">\n <div\n ref={editorRef}\n className={`w6w-expr-editor${masked ? \" is-masked\" : \"\"}${\n parts.length === 0 ? \" is-empty\" : \"\"\n }${readOnly ? \" is-readonly\" : \"\"}`}\n contentEditable={!readOnly}\n suppressContentEditableWarning\n role=\"textbox\"\n tabIndex={readOnly ? -1 : 0}\n aria-multiline={multiline ? \"true\" : \"false\"}\n aria-label={ariaLabel}\n data-placeholder={placeholder ?? \"\"}\n spellCheck={false}\n onInput={() => {\n // D-3: the more severe half — before this, a plain (unmasked)\n // inline field had NO promotion path at all (`onLeave` below\n // early-returns unless `masked`). Promote a just-closed\n // `{{ … }}` marker to a chip at the keystroke that closes it,\n // then sync unconditionally either way. NO `renderToggle` (R4 —\n // the toggle stays absent from this component), and NEVER bump\n // `paintGen`/repaint the field from here — see `G-typing`.\n const el = editorRef.current;\n if (el) promoteCompletedMarkerAtCaret(el);\n syncFromDom();\n }}\n onClick={(e) => {\n const x = (e.target as HTMLElement).closest(\"[data-x]\");\n if (!x) return;\n e.preventDefault();\n x.closest(\".w6w-expr-chip\")?.remove();\n syncFromDom();\n }}\n onDoubleClick={(e) => {\n // D-3, the reverse direction: double-click a chip back to its\n // editable `{{ … }}` text, in place. Mirrors the onClick\n // delegate immediately above — no render-toggle arm here, since\n // this component never paints one (R4).\n const target = e.target as HTMLElement;\n if (target.closest(\"[data-x]\")) return;\n const chip = target.closest(\".w6w-expr-chip\") as HTMLElement | null;\n if (!chip) return;\n e.preventDefault();\n const node = chipToText(chip);\n if (node) {\n const doc = node.ownerDocument;\n const after = doc.createRange();\n after.setStartAfter(node);\n after.collapse(true);\n const sel = doc.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(after);\n }\n syncFromDom();\n }}\n onKeyDown={(e) => {\n if (e.key !== \"Enter\") return;\n // ALWAYS suppressed — with or without Shift, multiline or not. Left\n // to itself the browser wraps the caret's line in a <div> (or drops\n // a <br>), which is markup we neither paint nor want to depend on.\n e.preventDefault();\n if (!multiline) return; // single-line value field\n const el = editorRef.current;\n if (!el) return;\n // The break is OUR literal \"\\n\" text node, inserted with the same\n // caret helper the chip picker uses. `.w6w-expr-editor` is\n // `pre-wrap`, so it renders as a break; `readParts` reads it back\n // verbatim. The filler keeps a break at the very END visible (and is\n // skipped by `readParts`, so it never reaches the value).\n insertNodeAtCaret(el, el.ownerDocument.createTextNode(\"\\n\"));\n ensureFillerBreak(el);\n syncFromDom();\n }}\n />\n {!readOnly && (\n <button\n type=\"button\"\n className=\"w6w-expr-edit\"\n title=\"Edit expression — browse variables, secrets & step outputs\"\n aria-label=\"Edit expression\"\n onClick={() => setModalOpen(true)}\n >\n ƒx\n </button>\n )}\n </div>\n\n {modalOpen && (\n <ExpressionEditorModal\n value={partsToValue(parts)}\n masked={masked}\n multiline={multiline}\n options={resolved}\n fieldLabel={ariaLabel}\n onSave={adopt}\n onClose={() => setModalOpen(false)}\n />\n )}\n </div>\n );\n}\n","/**\n * `{{ }}` inside a Run script's CODE. The host never templates `@w6w/script`'s `code` (the\n * engine's `LITERAL_PARAMS`, node-types RFC amendment 2026-10-30): a marker typed into the code\n * reaches the sandbox as literal text — `'{{ nodes.a.output.total }}'` is that exact string at\n * run time, never the value. JavaScript/TypeScript insert `$.get(root, ...keys)` reads;\n * Python inserts `ctx.get(root, *keys)` reads. Existing globals remain supported.\n *\n * {@link findCodeBindings} finds the markers that would run (strings and code, not comments),\n * {@link codeReadFor} spells one reference as that code read, and\n * {@link convertCodeBindingsToReads} rewrites every convertible marker in a script — what the\n * step editor does when a script opens, behind a visible note with Undo.\n */\n\nexport type ScriptLanguage = \"javascript\" | \"typescript\" | \"python\";\n\n/** Where a marker sits: plain code, or inside a string literal of the given quote. */\ntype Context = { kind: \"code\" } | { kind: \"string\"; quote: string; start: number; end: number };\n\nexport interface CodeBinding {\n /** Offset of the `{{` in the code. */\n start: number;\n /** Offset just past the `}}`. */\n end: number;\n /** The marker's inner text, trimmed — what Input binds (`{{ <ref> }}`). */\n ref: string;\n context: Context;\n}\n\nconst MARKER = /\\{\\{\\s*([^{}]*?)\\s*\\}\\}/g;\n\n/**\n * Every `{{ … }}` in `code` that is not inside a comment, with the string literal (if any)\n * around it. A small scanner, not a parser: it tracks `'…'`, `\"…\"` (and, in JavaScript,\n * `` `…` ``; in Python, triple quotes) and the language's comments, which is what deciding\n * \"would this marker run\" needs.\n */\nexport function findCodeBindings(\n code: string,\n language: ScriptLanguage = \"javascript\",\n): CodeBinding[] {\n const python = language === \"python\";\n // Map each offset to the literal (if any) it sits in; comments are recorded as null.\n const literals: { start: number; end: number; quote: string }[] = [];\n const comments: { start: number; end: number }[] = [];\n let i = 0;\n while (i < code.length) {\n const c = code[i];\n const two = code.slice(i, i + 2);\n const three = code.slice(i, i + 3);\n if ((python && c === \"#\") || (!python && two === \"//\")) {\n const nl = code.indexOf(\"\\n\", i);\n const end = nl === -1 ? code.length : nl;\n comments.push({ start: i, end });\n i = end;\n } else if (!python && two === \"/*\") {\n const close = code.indexOf(\"*/\", i + 2);\n const end = close === -1 ? code.length : close + 2;\n comments.push({ start: i, end });\n i = end;\n } else if (python && (three === '\"\"\"' || three === \"'''\")) {\n const close = code.indexOf(three, i + 3);\n const end = close === -1 ? code.length : close + 3;\n literals.push({ start: i, end, quote: three });\n i = end;\n } else if (c === \"'\" || c === '\"' || (!python && c === \"`\")) {\n let j = i + 1;\n while (j < code.length && code[j] !== c) {\n if (code[j] === \"\\\\\") j++;\n else if (c !== \"`\" && code[j] === \"\\n\") break;\n j++;\n }\n const end = Math.min(j + 1, code.length);\n literals.push({ start: i, end, quote: c });\n i = end;\n } else {\n i++;\n }\n }\n const out: CodeBinding[] = [];\n for (const m of code.matchAll(MARKER)) {\n const start = m.index ?? 0;\n const end = start + m[0].length;\n if (comments.some((c) => start >= c.start && start < c.end)) continue;\n const lit = literals.find((l) => start > l.start && start < l.end);\n out.push({\n start,\n end,\n ref: m[1],\n context: lit ? { kind: \"string\", ...lit } : { kind: \"code\" },\n });\n }\n return out;\n}\n\n/** A reference the converter understands: a root, then `.name`, `[0]` or `[\"key\"]` steps. */\nconst REF = /^[A-Za-z_$][\\w$]*(?:\\.[A-Za-z_$][\\w$-]*|\\[\\d+\\]|\\[\"[^\"\\\\]*\"\\]|\\['[^'\\\\]*'\\])*$/;\nconst STEP = /\\.([A-Za-z_$][\\w$-]*)|\\[(\\d+)\\]|\\[\"([^\"\\\\]*)\"\\]|\\['([^'\\\\]*)'\\]/g;\n\n/** Where each `{{ }}` root lives among a script's globals. */\nconst ROOTS: Record<string, string[]> = {\n nodes: [\"run\", \"nodes\"],\n steps: [\"run\", \"nodes\"],\n trigger: [\"run\", \"trigger\"],\n foreach: [\"run\", \"foreach\"],\n state: [\"state\"],\n var: [\"state\"],\n vars: [\"state\"],\n const: [\"consts\"],\n consts: [\"consts\"],\n};\n\n/**\n * Turn a reference into `$.get(root, ...keys)` (JavaScript/TypeScript) or\n * `ctx.get(root, *keys)` (Python). Unsupported roots (secrets, documents, Function inputs)\n * and non-path expressions return null. State always means the state tree without run aliases.\n */\nexport function codeReadFor(ref: string, language: ScriptLanguage = \"javascript\"): string | null {\n const text = ref.trim();\n if (!REF.test(text)) return null;\n const root = /^[A-Za-z_$][\\w$]*/.exec(text)?.[0] ?? \"\";\n const base = ROOTS[root];\n if (!base) return null;\n const path: (string | number)[] = [...base.slice(1)];\n for (const m of text.slice(root.length).matchAll(STEP)) {\n path.push(m[2] !== undefined ? Number(m[2]) : (m[1] ?? m[3] ?? m[4]));\n }\n const namespace = base[0] === \"run\" ? path.shift() : base[0];\n const context = language === \"python\" ? \"ctx\" : \"$\";\n return `${context}.get(${[namespace, ...path].map((key) => JSON.stringify(key)).join(\", \")})`;\n}\n\nexport interface ConvertResult {\n code: string;\n /** Markers rewritten to code reads. */\n converted: number;\n /** Markers left as they were: not a readable reference, or inside a string they can't leave. */\n left: number;\n}\n\n/**\n * Rewrite each running `{{ ref }}` in `code` to the code read {@link codeReadFor} gives:\n * - a marker that IS a whole string literal (`'{{ ref }}'`) becomes the read, keeping the\n * value's type;\n * - a bare marker in code becomes the read;\n * - inside a JavaScript template literal it becomes `${read}`;\n * - inside a longer `'…'`/`\"…\"` string it is spliced in by concatenation (`str(read)` in Python);\n * - anything else (a Python triple-quoted or prefixed string, a reference with no code read) is\n * left as it was and counted in `left`.\n */\nexport function convertCodeBindingsToReads(\n code: string,\n language: ScriptLanguage = \"javascript\",\n): ConvertResult {\n const python = language === \"python\";\n let out = \"\";\n let cursor = 0;\n let converted = 0;\n let left = 0;\n for (const b of findCodeBindings(code, language)) {\n const read = codeReadFor(b.ref, language);\n if (read === null) {\n left++;\n continue;\n }\n const ctx = b.context;\n if (ctx.kind === \"code\") {\n out += code.slice(cursor, b.start) + read;\n cursor = b.end;\n converted++;\n continue;\n }\n const q = ctx.quote;\n const atStart = b.start === ctx.start + q.length;\n const atEnd = b.end === ctx.end - q.length;\n if (atStart && atEnd) {\n out += code.slice(cursor, ctx.start) + read;\n cursor = ctx.end;\n converted++;\n } else if (!python && q === \"`\") {\n out += `${code.slice(cursor, b.start)}\\${${read}}`;\n cursor = b.end;\n converted++;\n } else if (q.length === 1 && !(python && /[A-Za-z]/.test(code[ctx.start - 1] ?? \"\"))) {\n const piece = python ? `str(${read})` : read;\n out += atStart\n ? `${code.slice(cursor, ctx.start)}${piece} + ${q}`\n : `${code.slice(cursor, b.start)}${q} + ${piece}`;\n if (atEnd) {\n cursor = ctx.end;\n } else {\n if (!atStart) out += ` + ${q}`;\n cursor = b.end;\n }\n converted++;\n } else {\n left++;\n }\n }\n out += code.slice(cursor);\n return { code: out, converted, left };\n}\n","import type { EditorView } from \"@codemirror/view\";\nimport { type ReactNode, useRef, useState } from \"react\";\nimport { CodeEditor } from \"../CodeEditor.tsx\";\nimport { type ScriptLanguage, codeReadFor } from \"../script-bindings.ts\";\nimport type { ActionParam } from \"../types.ts\";\nimport { ExpressionEditorModal } from \"./ExpressionEditorModal.tsx\";\nimport { useExpressionOptions } from \"./ExpressionOptions.tsx\";\nimport { wholeValueRef } from \"./json-compose.ts\";\n\n/** Script picker and node chips insert literal-key reads for every script language. */\nexport function ScriptCodeField({\n param,\n value,\n language,\n label,\n req,\n readOnly,\n onChange,\n}: {\n param: ActionParam;\n value: string;\n language: ScriptLanguage;\n label: string;\n req: ReactNode;\n readOnly?: boolean;\n onChange: (next: string) => void;\n}) {\n const view = useRef<EditorView | null>(null);\n const [pickerOpen, setPickerOpen] = useState(false);\n const exprOptions = useExpressionOptions();\n const steps = exprOptions.steps ?? [];\n const python = language === \"python\";\n\n const insert = (text: string) => {\n const v = view.current;\n if (!v) {\n onChange(value + text);\n return;\n }\n v.dispatch(v.state.replaceSelection(text));\n v.focus();\n };\n // The picker hands back `\"{{ ref }}\"`, or a composed JSON value holding such strings: insert\n // the code read, with each reference inside a composed value spelled the same way.\n const insertPicked = (picked: unknown) => {\n const ref = wholeValueRef(picked);\n if (ref !== null) {\n const read = codeReadFor(ref, language);\n if (read) insert(read);\n return;\n }\n if (picked === undefined || picked === \"\") return;\n insert(\n JSON.stringify(picked, null, 2).replace(\n /\"\\{\\{\\s*([^{}\"]*?)\\s*\\}\\}\"/g,\n (m, r: string) => codeReadFor(r, language) ?? m,\n ),\n );\n };\n\n const stepId = steps[0]?.id ?? \"<step-id>\";\n const context = python ? \"ctx\" : \"$\";\n const examples = [\n [`${context}.get(\"nodes\", ${JSON.stringify(stepId)}, \"output\")`, \"a step's output\"],\n [`${context}.get(\"state\", \"region\")`, \"a workflow state value\"],\n [`${context}.get(\"consts\", \"api_base\")`, \"a constant\"],\n ];\n const width = Math.max(...examples.map(([c]) => c.length));\n const comment = python ? \"#\" : \"//\";\n\n return (\n <div className=\"w6w-field w6w-script-code\">\n <span>\n {label}\n {req}\n </span>\n <CodeEditor\n value={value}\n readOnly={readOnly}\n minHeight=\"180px\"\n language={language}\n aria-label={`${param.key} code`}\n onChange={onChange}\n onCreateEditor={(v) => {\n view.current = v;\n }}\n />\n {!readOnly && (\n <div className=\"w6w-seed-chips w6w-script-insert\">\n <span className=\"w6w-muted w6w-small\">Insert</span>\n {steps.map((s) => {\n const read = codeReadFor(`nodes[${JSON.stringify(s.id)}].output`, language) ?? \"\";\n return (\n <button\n key={s.id}\n type=\"button\"\n className=\"w6w-chip w6w-seed-chip\"\n title={`Insert ${read}`}\n onClick={() => insert(read)}\n >\n <code>{s.id}</code>\n </button>\n );\n })}\n <button\n type=\"button\"\n className=\"w6w-chip w6w-seed-chip\"\n title=\"Pick a step field, variable or constant to insert as code\"\n aria-label={`Insert a value into ${label}`}\n onClick={() => setPickerOpen(true)}\n >\n ƒx\n </button>\n </div>\n )}\n {param.hint && <span className=\"w6w-hint\">{param.hint}</span>}\n <details className=\"w6w-script-help\">\n <summary className=\"w6w-muted w6w-small\">How to read data</summary>\n <pre className=\"w6w-script-help-examples\">\n {examples.map(([code, what]) => `${code.padEnd(width)} ${comment} ${what}`).join(\"\\n\")}\n </pre>\n <span className=\"w6w-hint\">\n <code>input</code> is the same as <code>run</code> unless you set Custom input.\n </span>\n <span className=\"w6w-hint\">\n {python ? (\n <>\n Use <code>ctx.state</code> and <code>ctx.nodes</code> directly, or{\" \"}\n <code>ctx.get(root, *keys)</code> for literal keys. Missing paths return{\" \"}\n <code>None</code>. Existing globals still work.\n </>\n ) : (\n <>\n Use <code>$.state</code> and <code>$.nodes</code> directly, or{\" \"}\n <code>$.get(root, ...keys)</code> for literal keys. Existing <code>run</code>,{\" \"}\n <code>state</code>, <code>vars</code> and <code>consts</code> reads still work. Type a\n dot for suggestions, or press Ctrl+Space.\n </>\n )}\n </span>\n </details>\n {pickerOpen && (\n <ExpressionEditorModal\n mode=\"json-binding\"\n value={undefined}\n jsonValue={undefined}\n options={exprOptions}\n fieldLabel={label}\n whole\n onSaveJson={insertPicked}\n onClose={() => setPickerOpen(false)}\n />\n )}\n </div>\n );\n}\n","import { holdsExpression } from \"./components/expression-template.ts\";\n/**\n * Pure decisions for form-resolved dynamic options (no React). The hook in\n * `use-dynamic-fields.ts` only sequences; everything decidable lives here.\n */\nimport {\n type ActionParam,\n type ParamOption,\n type ResolveFieldsBody,\n isFormResolvedOptions,\n isSecretValue,\n} from \"./types.ts\";\n\n/** Dynamic-field context a ParamsForm host passes. */\nexport interface DynamicContext {\n appId: string;\n actionKey: string;\n version?: string;\n connectionId?: string;\n appName?: string;\n}\n\n/** Form values split per D-5: resolvable go to `form`, expression/secret/`$`-object keys to `unresolved`. */\nexport interface FormSplit {\n form: Record<string, unknown>;\n unresolved: string[];\n}\n\n/** One planned call: the body minus `connectionId`/`version` (the hook adds them). */\nexport type PlannedRequest = Pick<\n ResolveFieldsBody,\n \"reason\" | \"form\" | \"previous\" | \"changed\" | \"fields\" | \"unresolved\"\n>;\n\n/** Outcome of reconciling a stored value against a returned option list. */\nexport interface Reconciled {\n action: \"keep\" | \"flag\" | \"clear\";\n /** Hint to show when `action === \"flag\"`. */\n message?: string;\n}\n\n/** Section children write flat at the enclosing level; other `children` are left alone. */\nfunction flat(list: ActionParam[]): ActionParam[] {\n const out: ActionParam[] = [];\n for (const p of list) {\n out.push(p);\n if (p.type === \"section\" && p.children) out.push(...flat(p.children));\n }\n return out;\n}\n\n/** D-5: expression, secret, or a plain object with own key `$` can't be sent as a literal. */\nexport function isUnresolvedValue(v: unknown): boolean {\n if (holdsExpression(v) || isSecretValue(v)) return true;\n return (\n typeof v === \"object\" &&\n v !== null &&\n !Array.isArray(v) &&\n Object.prototype.hasOwnProperty.call(v, \"$\")\n );\n}\n\nfunction allowCustomOf(p: ActionParam): boolean {\n return (p as { config?: { allowCustom?: boolean } }).config?.allowCustom === true;\n}\n\n/** Params that request form-resolved options (top level + sections only). */\nexport function dynamicParams(params: ActionParam[]): ActionParam[] {\n return flat(params).filter((p) => isFormResolvedOptions(p.options));\n}\n\nfunction refreshOnOf(p: ActionParam): string[] {\n return isFormResolvedOptions(p.options) ? (p.options.refreshOn ?? []) : [];\n}\n\n/**\n * Split flattened `values` (entered, else declared default) into `form` and\n * `unresolved` (expression, secret, or plain object with own key `$`).\n */\nexport function splitForm(params: ActionParam[], values: Record<string, unknown>): FormSplit {\n const form: Record<string, unknown> = {};\n const unresolved: string[] = [];\n for (const p of flat(params)) {\n if (p.type === \"section\") continue;\n const v = values[p.key] !== undefined ? values[p.key] : p.default;\n if (v === undefined) continue;\n if (isUnresolvedValue(v)) unresolved.push(p.key);\n else form[p.key] = v;\n }\n return { form, unresolved };\n}\n\n/**\n * Plan the call for `reason`. `init`: every resolveFields field whose\n * `refreshOn` keys are all resolved. `change`: only fields whose `refreshOn`\n * contains `changed[0]` (and whose keys are all resolved). Returns null when no call is due.\n * `previous` (raw pre-commit values) is split the same way and sent as `previous`.\n */\nexport function planRequests(\n params: ActionParam[],\n values: Record<string, unknown>,\n reason: \"init\" | \"change\",\n changed?: string[],\n previous?: Record<string, unknown>,\n): PlannedRequest | null {\n const { form, unresolved } = splitForm(params, values);\n const bad = new Set(unresolved);\n const fields = dynamicParams(params)\n .filter((p) => {\n const on = refreshOnOf(p);\n if (reason === \"change\" && !(changed ?? []).some((k) => on.includes(k))) return false;\n return on.every((k) => !bad.has(k));\n })\n .map((p) => p.key);\n if (fields.length === 0) return null;\n const req: PlannedRequest = { reason, form, fields, unresolved };\n if (reason === \"change\") {\n req.changed = [...(changed ?? [])];\n req.previous = splitForm(params, previous ?? {}).form;\n }\n return req;\n}\n\n/** Cache key `(app, version, action, connection, field, refreshOn values)`. */\nexport function cacheKey(\n ctx: DynamicContext,\n param: ActionParam,\n form: Record<string, unknown>,\n): string {\n return JSON.stringify([\n ctx.appId,\n ctx.version ?? null,\n ctx.actionKey,\n ctx.connectionId ?? null,\n param.key,\n refreshOnOf(param).map((k) => form[k] ?? null),\n ]);\n}\n\n/** Only `cache: \"none\"` opts out of the in-memory cache. */\nexport function isCacheable(param: ActionParam): boolean {\n return !(isFormResolvedOptions(param.options) && param.options.cache === \"none\");\n}\n\n/** True when two requests' `fields` share a key (the newer aborts the older). */\nexport function fieldsOverlap(a: readonly string[], b: readonly string[]): boolean {\n return a.some((k) => b.includes(k));\n}\n\n/**\n * Why a dynamic field is NOT requested (A6), with the hint to show, or null\n * when it is requestable.\n */\nexport function noFetchReason(\n param: ActionParam,\n params: ActionParam[],\n values: Record<string, unknown>,\n ctx: Pick<DynamicContext, \"connectionId\">,\n): { reason: \"no-connection\" | \"unresolved-dependency\"; hint: string } | null {\n if (!ctx.connectionId) {\n return { reason: \"no-connection\", hint: \"Connect an account to load choices\" };\n }\n const bad = new Set(splitForm(params, values).unresolved);\n const k = refreshOnOf(param).find((key) => bad.has(key));\n if (k === undefined) return null;\n const label = flat(params).find((p) => p.key === k)?.label ?? k;\n return {\n reason: \"unresolved-dependency\",\n hint: `Options unavailable while ${label} is an expression`,\n };\n}\n\n/** D-6: keep / flag / clear a stored value given the returned options. */\nexport function reconcileValue(\n value: unknown,\n options: ParamOption[],\n opts: { allowCustom: boolean; reason: \"init\" | \"change\"; appLabel: string },\n): Reconciled {\n if (value === undefined || value === null || value === \"\") return { action: \"keep\" };\n if (isUnresolvedValue(value)) return { action: \"keep\" };\n if (options.some((o) => o.value === value || String(o.value) === String(value))) {\n return { action: \"keep\" };\n }\n if (opts.reason === \"change\" && !opts.allowCustom) return { action: \"clear\" };\n return { action: \"flag\", message: `Not in the list returned by ${opts.appLabel}` };\n}\n\nexport { allowCustomOf };\n","/** React hook sequencing init/change calls to `W6WApi.resolveActionFields`. */\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n type DynamicContext,\n allowCustomOf,\n cacheKey,\n dynamicParams,\n fieldsOverlap,\n isCacheable,\n noFetchReason,\n planRequests,\n reconcileValue,\n} from \"./dynamic-fields.ts\";\nimport { useOptionalW6WApi } from \"./provider.tsx\";\nimport type { ActionParam, ParamOption } from \"./types.ts\";\n\n/** Per-field state the form renders from. */\nexport interface DynamicFieldState {\n options?: ParamOption[];\n loading: boolean;\n error?: string;\n /** Why the field is free text (no connection / unresolved refreshOn). */\n hint?: string;\n /** Flag for a kept value not in the returned list. */\n notInList?: string;\n}\n\nexport interface UseDynamicFields {\n fields: Record<string, DynamicFieldState>;\n /** A pick committed `value` for `key` (select/Combobox/checkbox): one change call if any field refreshes on it. */\n commit(key: string, value: unknown): void;\n /** Focus entered `key`: remember the pre-edit form (the `previous` of a later blur commit). */\n focus(key: string): void;\n /** Focus left `key`: commit a text edit made since focus (never per keystroke). */\n blur(key: string): void;\n retry(key: string): void;\n}\n\ninterface Remote {\n options?: ParamOption[];\n loading: boolean;\n error?: string;\n}\n\ninterface Inflight {\n fields: string[];\n controller: AbortController;\n}\n\nexport function useDynamicFields(\n params: ActionParam[],\n values: Record<string, unknown>,\n dynamic: DynamicContext | undefined,\n onChange: (next: Record<string, unknown>) => void,\n): UseDynamicFields {\n const resolve = useOptionalW6WApi()?.resolveActionFields;\n const active = Boolean(dynamic && resolve);\n const [remote, setRemote] = useState<Record<string, Remote>>({});\n // Latest props, read by async continuations (never a stale closure).\n const latest = useRef({ params, values, dynamic, onChange, resolve });\n latest.current = { params, values, dynamic, onChange, resolve };\n const cache = useRef(new Map<string, ParamOption[]>());\n const inflight = useRef<Inflight[]>([]);\n\n const run = useCallback(\n (\n reason: \"init\" | \"change\",\n changed?: string[],\n previous?: Record<string, unknown>,\n only?: string,\n next?: Record<string, unknown>,\n ) => {\n const { params: ps, values: cur, dynamic: ctx, resolve: call } = latest.current;\n const vs = next ?? cur;\n if (!ctx || !call || !ctx.connectionId) return;\n const plan = planRequests(ps, vs, reason, changed, previous);\n if (!plan) return;\n const byKey = new Map(dynamicParams(ps).map((p) => [p.key, p]));\n const cleared: string[] = [];\n const cached: Record<string, Remote> = {};\n const fields: string[] = [];\n const appLabel = ctx.appName ?? ctx.appId;\n const apply = (key: string, options: ParamOption[]) => {\n const p = byKey.get(key);\n if (!p) return;\n const r = reconcileValue(vs[key], options, {\n allowCustom: allowCustomOf(p),\n reason,\n appLabel,\n });\n if (r.action === \"clear\") cleared.push(key);\n };\n for (const key of plan.fields) {\n if (only !== undefined && key !== only) continue;\n const p = byKey.get(key);\n if (!p) continue;\n const hit =\n only === undefined && isCacheable(p)\n ? cache.current.get(cacheKey(ctx, p, plan.form))\n : undefined;\n if (hit) {\n cached[key] = { options: hit, loading: false };\n apply(key, hit);\n } else fields.push(key);\n }\n const flush = (sync = false) => {\n if (cleared.length === 0) return;\n // Sync (cache) path clears against the just-committed form; async against the live one.\n const out = { ...(sync ? vs : latest.current.values) };\n for (const k of cleared) delete out[k];\n latest.current.onChange(out);\n };\n if (Object.keys(cached).length > 0) setRemote((r) => ({ ...r, ...cached }));\n if (fields.length === 0) {\n flush(true);\n return;\n }\n for (const f of inflight.current) {\n if (fieldsOverlap(f.fields, fields)) f.controller.abort();\n }\n const controller = new AbortController();\n const entry: Inflight = { fields, controller };\n inflight.current = [...inflight.current.filter((f) => !f.controller.signal.aborted), entry];\n setRemote((r) => {\n const n = { ...r };\n for (const k of fields) n[k] = { options: r[k]?.options, loading: true };\n return n;\n });\n const body = {\n ...plan,\n fields,\n connectionId: ctx.connectionId,\n ...(ctx.version !== undefined ? { version: ctx.version } : {}),\n };\n const done = (patch: Record<string, Remote>) => {\n inflight.current = inflight.current.filter((f) => f !== entry);\n setRemote((r) => ({ ...r, ...patch }));\n };\n Promise.resolve()\n .then(() => call(ctx.appId, ctx.actionKey, body, { signal: controller.signal }))\n .then((res) => {\n if (controller.signal.aborted) return;\n const patch: Record<string, Remote> = {};\n for (const key of fields) {\n const out = res?.fields?.[key];\n const p = byKey.get(key);\n if (!out || !p) {\n patch[key] = { loading: false };\n } else if (out.error) {\n patch[key] = { loading: false, error: out.error };\n } else {\n const options = Array.isArray(out.options) ? out.options : [];\n patch[key] = { loading: false, options };\n if (isCacheable(p)) cache.current.set(cacheKey(ctx, p, plan.form), options);\n apply(key, options);\n }\n }\n done(patch);\n flush();\n })\n .catch((e: unknown) => {\n if (controller.signal.aborted) return;\n const msg = e instanceof Error ? e.message : String(e);\n const patch: Record<string, Remote> = {};\n for (const key of fields) patch[key] = { loading: false, error: msg || \"Request failed\" };\n done(patch);\n });\n },\n [],\n );\n\n const ctxKey = dynamic\n ? JSON.stringify([dynamic.appId, dynamic.actionKey, dynamic.version, dynamic.connectionId])\n : \"\";\n // biome-ignore lint/correctness/useExhaustiveDependencies: re-init only on a context change\n useEffect(() => {\n if (!active) return;\n setRemote({});\n run(\"init\");\n return () => {\n for (const f of inflight.current) f.controller.abort();\n inflight.current = [];\n };\n }, [ctxKey, active, run]);\n\n // Pre-edit form per focused key (a text edit commits on blur, against this).\n const snaps = useRef(new Map<string, Record<string, unknown>>());\n const commit = useCallback(\n (key: string, value: unknown) => {\n const previous = snaps.current.get(key) ?? latest.current.values;\n snaps.current.delete(key);\n run(\"change\", [key], previous, undefined, { ...latest.current.values, [key]: value });\n },\n [run],\n );\n const focus = useCallback((key: string) => {\n if (!snaps.current.has(key)) snaps.current.set(key, latest.current.values);\n }, []);\n const blur = useCallback(\n (key: string) => {\n const previous = snaps.current.get(key);\n snaps.current.delete(key);\n if (!previous) return;\n const now = latest.current.values;\n if (JSON.stringify(previous[key]) === JSON.stringify(now[key])) return;\n run(\"change\", [key], previous);\n },\n [run],\n );\n const retry = useCallback((key: string) => run(\"init\", undefined, undefined, key), [run]);\n\n const fields = useMemo(() => {\n const out: Record<string, DynamicFieldState> = {};\n if (!active || !dynamic) return out;\n const appLabel = dynamic.appName ?? dynamic.appId;\n for (const p of dynamicParams(params)) {\n const why = noFetchReason(p, params, values, dynamic);\n if (why) {\n out[p.key] = { loading: false, hint: why.hint };\n continue;\n }\n const r = remote[p.key] ?? { loading: true };\n const st: DynamicFieldState = { ...r };\n if (r.options) {\n const rec = reconcileValue(values[p.key], r.options, {\n allowCustom: allowCustomOf(p),\n reason: \"init\",\n appLabel,\n });\n if (rec.action === \"flag\") st.notInList = rec.message;\n }\n out[p.key] = st;\n }\n return out;\n }, [active, dynamic, params, values, remote]);\n\n return { fields, commit, focus, blur, retry };\n}\n","import { effectiveParam, matchesParamCondition } from \"@w6w/expr\";\nimport {\n type ReactNode,\n createContext,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { CodeEditor, type ScriptLanguage } from \"./CodeEditor.tsx\";\nimport { JsonEditor } from \"./JsonEditor.tsx\";\nimport { Combobox } from \"./components/Combobox.tsx\";\nimport { ExpressionEditorModal } from \"./components/ExpressionEditorModal.tsx\";\nimport { ExpressionInput } from \"./components/ExpressionInput.tsx\";\nimport { useExpressionOptions } from \"./components/ExpressionOptions.tsx\";\nimport { Icon } from \"./components/Icon.tsx\";\nimport { Modal } from \"./components/Modal.tsx\";\nimport { ScriptCodeField } from \"./components/ScriptCodeField.tsx\";\nimport { varLabel } from \"./components/expression-dom.ts\";\nimport { holdsExpression } from \"./components/expression-template.ts\";\nimport { bareRefBinding, wholeValueRef } from \"./components/json-compose.ts\";\nimport { type DynamicContext, allowCustomOf } from \"./dynamic-fields.ts\";\nimport { useOptionalW6WApi, useWorkflowProject } from \"./provider.tsx\";\nimport type { ActionParam, ExprValue, SecretValue } from \"./types.ts\";\nimport { type UseDynamicFields, useDynamicFields } from \"./use-dynamic-fields.ts\";\n\n/**\n * Evaluate a param's `showIf` predicate. `getValue` resolves a sibling field's\n * current value (falling back to its default). Params with no `showIf` always show.\n *\n * Exported so callers outside this form (e.g. `requiredParamsFilled`'s Test-gate)\n * can skip a `required` field that's currently hidden — otherwise `required` and\n * `showIf` can't safely combine: a field required only in one branch (e.g.\n * SendGrid's `contentValue`, moot once a dynamic template supplies the body)\n * would block the gate even while hidden.\n */\nexport function isParamVisible(param: ActionParam, getValue: (key: string) => unknown): boolean {\n if (param.hidden === true) return false;\n if (!param.showIf) return true;\n return matchesParamCondition(param.showIf, getValue);\n}\n\n/**\n * Render a param list, laying adjacent params that share a `row` id side by side\n * in a flex row; everything else stacks normally.\n */\n/**\n * Flatten a param list, descending into `section` children (which write their\n * values flat at the enclosing form level). Used to resolve declared defaults\n * for `showIf` across sections. Non-section `children` (e.g. a nested `group`\n * object) are left alone — those values live nested under the parent key.\n */\nexport function flattenParams(list: ActionParam[]): ActionParam[] {\n const out: ActionParam[] = [];\n for (const p of list) {\n out.push(p);\n if (p.type === \"section\" && p.children) out.push(...flattenParams(p.children));\n }\n return out;\n}\n\nfunction renderFieldRows(\n list: ActionParam[],\n renderOne: (p: ActionParam) => ReactNode,\n): ReactNode[] {\n const out: ReactNode[] = [];\n for (let i = 0; i < list.length; ) {\n const rowId = list[i].row;\n if (rowId) {\n const group: ActionParam[] = [];\n while (i < list.length && list[i].row === rowId) group.push(list[i++]);\n out.push(\n <div className=\"w6w-field-row\" key={`row:${rowId}`}>\n {group.map(renderOne)}\n </div>,\n );\n } else {\n out.push(renderOne(list[i]));\n i++;\n }\n }\n return out;\n}\n\n/**\n * Builds the `renderOne` dispatch a param list is rendered through: `section`\n * (layout-only, shares the caller's `values`/`set`/`effective`), `repeat: true`\n * (→ {@link RepeatField}, the existing `ArrayField` with a synthesized `item`),\n * `type: \"group\"` with a non-empty `children` (→ {@link GroupField}, a nested\n * form), else the plain {@link ParamField}. Factored out so {@link GroupField}\n * can build its OWN dispatch bound to its nested `values`/`set`/`effective` —\n * the one place a group's value-plumbing must differ from `SectionField`'s (see\n * `GroupField`'s own doc comment).\n */\nfunction makeRenderOne(\n values: Record<string, unknown>,\n set: (key: string, value: unknown) => void,\n effective: (key: string) => unknown,\n readOnly: boolean | undefined,\n): (p: ActionParam) => ReactNode {\n const renderOne = (p: ActionParam): ReactNode => {\n if (p.type === \"section\") {\n return <SectionField key={p.key} param={p} effective={effective} renderOne={renderOne} />;\n }\n // `repeat` is sugar for `type: \"array\"` (rfcs/param.md's amendment) — an\n // explicit `type: \"array\"` param already routes through `ParamField`'s own\n // `array` arm, so it's excluded here to avoid double-synthesizing `item`.\n if (p.repeat && p.type !== \"array\") {\n return (\n <RepeatField\n key={p.key}\n param={p}\n value={values[p.key]}\n onChange={set}\n readOnly={readOnly}\n />\n );\n }\n if (p.type === \"group\" && p.children && p.children.length > 0) {\n return (\n <GroupField\n key={p.key}\n param={p}\n value={values[p.key]}\n onChange={set}\n effective={effective}\n readOnly={readOnly}\n />\n );\n }\n return (\n <ParamField\n key={p.key}\n param={p}\n value={values[p.key]}\n onChange={set}\n effective={effective}\n readOnly={readOnly}\n />\n );\n };\n return renderOne;\n}\n\n/** Dynamic-field state for the top-level form; `null` inside group/repeat (untouched there). */\nconst DynamicFieldsCtx = createContext<UseDynamicFields | null>(null);\n\nexport interface ParamsFormProps {\n /** Declared params of the selected action. */\n params: ActionParam[];\n /** Current values, keyed by param `key`. Becomes the step's `with`. */\n values: Record<string, unknown>;\n /** Fired with the next values object on every edit. */\n onChange: (values: Record<string, unknown>) => void;\n readOnly?: boolean;\n /**\n * Opt-in context for `options: { source: \"resolveFields\" }` params. Absent (or\n * the host has no `resolveActionFields`) = those params render as plain inputs.\n */\n dynamic?: DynamicContext;\n}\n\n/**\n * Renders an action's declared params as a form. Required params are always\n * shown; optional ones collapse under a disclosure so the common path stays\n * tidy. Widget is chosen by `param.type` — same field-driven approach as\n * `AuthFieldsForm`, extended with `text` (textarea) and `json` (JsonEditor).\n *\n * Values are collected into a plain object suitable for a step's `with`. A field\n * bound to a reference holds a `{{ }}` template string (`\"{{ nodes.x.output.y }}\"`).\n */\nexport function ParamsForm({ params, values, onChange, readOnly, dynamic }: ParamsFormProps) {\n const dyn = useDynamicFields(params, values, dynamic, onChange);\n // Effective value of a field for `showIf` checks: the entered value, else the\n // field's declared default (so conditions hold before the user touches it).\n // Section/group children write flat at the enclosing level, so flatten them\n // too — otherwise a `showIf` referencing a section child sees `undefined` for\n // its declared default until the user edits it.\n const flat = flattenParams(params);\n const effective = (key: string) =>\n values[key] !== undefined ? values[key] : flat.find((p) => p.key === key)?.default;\n // `when` overlay (label/hint/required/ui/options) applied BEFORE the split so\n // an overlay-required param lands in the main area even when `advanced`.\n const visible = params\n .filter((p) => isParamVisible(p, effective))\n .map((p) => effectiveParam(p, effective));\n // Split by `advanced` (not by required): required + non-advanced show up front;\n // only fields flagged `advanced` collapse under \"Additional parameters\".\n const main = visible.filter((p) => p.required || !p.advanced);\n const additional = visible.filter((p) => !p.required && p.advanced);\n // A `language` change is the one edit that must also touch a SIBLING field:\n // any `code` param whose currently-stored value is still untouched\n // boilerplate (undefined, its own declared default, or the other\n // language's hardcoded default) swaps to the new language's default, in\n // the SAME compound `onChange` call — so there is no intermediate render\n // with a mismatched `language`/`code` pair (D-3, ROUND 2 / B3). This is the\n // one choke point every field edit passes through (`makeRenderOne`'s\n // `ParamField`/`GroupField`/`RepeatField` call sites all get this same\n // `set` as their `onChange`), so it's the right place to own the write.\n const set = (key: string, value: unknown) => {\n if (key === \"language\") {\n const next: Record<string, unknown> = { ...values, [key]: value };\n for (const p of flat) {\n if (p.type !== \"code\") continue;\n const current = values[p.key];\n const isUntouchedBoilerplate =\n current === undefined ||\n current === p.default ||\n current === PYTHON_CODE_DEFAULT ||\n LEGACY_CODE_DEFAULTS.includes(current as string);\n if (isUntouchedBoilerplate) {\n next[p.key] = value === \"python\" ? PYTHON_CODE_DEFAULT : p.default;\n }\n }\n onChange(next);\n return;\n }\n onChange({ ...values, [key]: value });\n };\n\n if (params.length === 0) {\n return <p className=\"w6w-muted w6w-small\">This action takes no parameters.</p>;\n }\n\n // A `section` is a layout-only container: it renders its children through this\n // SAME pipeline (so child `row`/`showIf`/nested sections still work) and —\n // crucially — passes the TOP-LEVEL `set`/`values` down, so section children\n // write to the enclosing form values, not nested under the section key. Note a\n // section IS the disclosure, so a child's `advanced` flag is not re-split here.\n const renderOne = makeRenderOne(values, set, effective, readOnly);\n\n return (\n <DynamicFieldsCtx.Provider value={dyn}>\n <div className=\"w6w-stack\">\n {renderFieldRows(main, renderOne)}\n {additional.length > 0 && (\n <details className=\"w6w-params-optional\">\n <summary className=\"w6w-muted w6w-small\">\n Additional parameters ({additional.length})\n </summary>\n <div className=\"w6w-stack\" style={{ marginTop: 8 }}>\n {renderFieldRows(additional, renderOne)}\n </div>\n </details>\n )}\n </div>\n </DynamicFieldsCtx.Provider>\n );\n}\n\n/**\n * A `section`-typed param — a layout-only container of `children`. Two shapes:\n * `section: \"collapsible\"` renders a titled, collapsed-by-default `<details>`\n * disclosure (the app-authored per-cluster disclosure, distinct from the single\n * global \"Additional parameters\" one); `section: \"group\"` lays the children out\n * per `layout` — `\"row\"` side by side (reusing `.w6w-field-row`), else stacked.\n *\n * Children render through the SAME `renderOne` pipeline the enclosing form uses,\n * so their values are written flat at the enclosing form level (a section does\n * NOT nest its value object), and child `row`/`showIf`/nested sections keep\n * working. A child's `advanced` flag is ignored inside a section — the section\n * itself is the disclosure, so children are shown inline within it.\n */\nfunction SectionField({\n param,\n effective,\n renderOne,\n}: {\n param: ActionParam;\n effective: (key: string) => unknown;\n renderOne: (p: ActionParam) => ReactNode;\n}) {\n const visibleChildren = (param.children ?? [])\n .filter((c) => isParamVisible(c, effective))\n .map((c) => effectiveParam(c, effective));\n\n if (param.section === \"collapsible\") {\n return (\n <details\n className=\"w6w-section\"\n open={\n param.collapsed === false ||\n (param.openWhenSet === true &&\n visibleChildren.some((c) => {\n const v = effective(c.key);\n return v !== undefined && v !== null && v !== \"\";\n }))\n }\n >\n <summary className=\"w6w-section-summary\">\n <span className=\"w6w-section-title\">{param.title ?? param.label ?? param.key}</span>\n {param.subtitle && <span className=\"w6w-section-subtitle\">{param.subtitle}</span>}\n </summary>\n <div className=\"w6w-stack w6w-section-body\">\n {renderFieldRows(visibleChildren, renderOne)}\n </div>\n </details>\n );\n }\n\n // group: side by side (`layout: \"row\"`) or stacked (default). The row wrapper\n // reuses the existing `.w6w-field-row` rule so each child `.w6w-field` sits\n // side by side; stack still honors child `row` grouping via renderFieldRows.\n if (param.layout === \"row\") {\n return <div className=\"w6w-field-row\">{visibleChildren.map(renderOne)}</div>;\n }\n return <div className=\"w6w-stack\">{renderFieldRows(visibleChildren, renderOne)}</div>;\n}\n\n/** Scalar-only types `ArrayItemInput` (`:795-850` below) actually renders — a\n * select, checkbox, number or text input. Anything else (a `secret`, or a\n * child carrying its own `children`) falls back to the JSON editor for the\n * whole group rather than half-rendering it (D-2, rfcs/param.md's amendment). */\nconst ARRAY_ITEM_SCALAR_TYPES = new Set([\"string\", \"text\", \"number\", \"boolean\", \"select\"]);\n\nfunction fitsArrayItemFields(fields: ActionParam[]): boolean {\n return (\n fields.length > 0 && fields.every((f) => ARRAY_ITEM_SCALAR_TYPES.has(f.type) && !f.children)\n );\n}\n\n/**\n * A `type: \"group\"` param with a non-empty `children` — a **nested** form.\n * Mirrors `SectionField`'s shape (a heading + `renderFieldRows` over the\n * visible children) with the ONE inversion a group requires: values write\n * NESTED under this param's own key (`onChange(param.key, {...current,\n * [childKey]: v})`), matching `resolveParams`' own nesting and\n * rfcs/param.md:190 — a section's children stay flat, a group's do not, so\n * this is deliberately a separate component rather than `SectionField`\n * parameterized to do both (that would conflate two value contracts in one\n * component's props).\n *\n * Bare container (D-1): `param.label`/`param.key` as a plain heading (reusing\n * the existing `.w6w-section-title`/`.w6w-section-body` type styles — no new\n * class, no border, no `<details>`), children stacked below.\n *\n * Group-local `showIf` (D-3): a child's `showIf` resolves against the group's\n * OWN children first, falling back to the enclosing form's `effective` for any\n * key the group doesn't declare — the same rule rfcs/param.md:256 already\n * states for `dependsOn`, extended here to `showIf`.\n */\nfunction GroupField({\n param,\n value,\n onChange,\n effective,\n readOnly,\n}: {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n /** The ENCLOSING form's `effective` — the fallback for a key this group\n * doesn't declare among its own (flattened) children. */\n effective: (key: string) => unknown;\n readOnly?: boolean;\n}) {\n const children = param.children ?? [];\n const groupValue = (value ?? {}) as Record<string, unknown>;\n const groupSet = (key: string, v: unknown) => onChange(param.key, { ...groupValue, [key]: v });\n // Flattened so a `section` nested inside this group (which writes flat at\n // the group's own level) still counts as \"the group's own\" for showIf\n // resolution — mirrors flattenParams' existing section-descent, reused as-is.\n const flatChildren = flattenParams(children);\n const groupEffective = (key: string): unknown => {\n const local = flatChildren.find((c) => c.key === key);\n if (!local) return effective(key);\n return groupValue[key] !== undefined ? groupValue[key] : local.default;\n };\n const visibleChildren = children\n .filter((c) => isParamVisible(c, groupEffective))\n .map((c) => effectiveParam(c, groupEffective));\n const groupRenderOne = makeRenderOne(groupValue, groupSet, groupEffective, readOnly);\n\n return (\n <DynamicFieldsCtx.Provider value={null}>\n <div className=\"w6w-stack\">\n <span className=\"w6w-section-title\">{param.label ?? param.key}</span>\n <div className=\"w6w-stack w6w-section-body\">\n {renderFieldRows(visibleChildren, groupRenderOne)}\n </div>\n </div>\n </DynamicFieldsCtx.Provider>\n );\n}\n\n/**\n * A `repeat: true` param — sugar for `type: \"array\"` with a synthesized `item`\n * (rfcs/param.md's amendment); routes to the SAME `ArrayField` an explicit\n * `type: \"array\"` param uses, never a second list component:\n * - scalar (`param.type` is not `group`/`section`/`array`): `item = { type:\n * param.type, options: param.options }`, passed explicitly because\n * `ArrayField`'s own fallback (`param.item ?? { type: \"string\" }`) is the\n * literal `\"string\"`, not `param.type`.\n * - `type: \"group\"` with scalar-only `children` (the D-2 ceiling above):\n * `item = { type: \"object\", fields: param.children }`.\n * - `type: \"group\"` with no `children`, or any child the ceiling excludes:\n * falls back to the JSON editor for the whole group.\n */\nfunction RepeatField({\n param,\n value,\n onChange,\n readOnly,\n}: {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n readOnly?: boolean;\n}) {\n if (param.type === \"group\") {\n const children = param.children ?? [];\n if (!fitsArrayItemFields(children)) {\n return <JsonParamField param={param} value={value} onChange={onChange} readOnly={readOnly} />;\n }\n const synthesized: ActionParam = { ...param, item: { type: \"object\", fields: children } };\n return <ArrayField param={synthesized} value={value} onChange={onChange} readOnly={readOnly} />;\n }\n const synthesized: ActionParam = {\n ...param,\n item: { type: param.type, options: Array.isArray(param.options) ? param.options : undefined },\n };\n return <ArrayField param={synthesized} value={value} onChange={onChange} readOnly={readOnly} />;\n}\n\n/** The Python default snippet for a `code` param when its sibling `language`\n * resolves to `\"python\"` (D-3) — a working `return input`-equivalent, same\n * shape/intent as `SCRIPT_APP`'s JS default in `flow-types.ts`. */\nconst PYTHON_CODE_DEFAULT = \"# Runs as a function body. Return the step's output.\\nreturn input\";\n\n/** Earlier script defaults (the ones that named `input`, then `vars`/`consts`/`state`) — still untouched\n * boilerplate a `language` switch may swap, on a step saved while that wording was current.\n * Recognition-only: these match text already saved, so they keep their old `state.nodes` wording\n * and are never offered as a default. */\nconst LEGACY_CODE_DEFAULTS = [\n \"// Read `input` (bound under Input), plus `vars`, `consts` and `state.nodes.<step-id>.output`.\\n// Runs as a function body. Return the step's output.\\nreturn input;\",\n '# Read `input` (bound under Input), plus `vars`, `consts` and `state[\"nodes\"][<step-id>][\"output\"]`.\\n# Runs as a function body. Return the step\\'s output.\\nreturn input',\n \"// `input` holds the data bound under Input (e.g. an upstream step's output).\\n// Runs as a function body. Return the step's output.\\nreturn input;\",\n \"# `input` holds the data bound under Input (e.g. an upstream step's output).\\n# Runs as a function body. Return the step's output.\\nreturn input\",\n];\n\nfunction ParamField(props: ParamFieldProps) {\n const dyn = useContext(DynamicFieldsCtx);\n const key = props.param.key;\n // A text edit commits on blur (never per keystroke); picks commit in ParamFieldBody.\n return (\n <div\n style={{ display: \"contents\" }}\n onFocusCapture={dyn ? () => dyn.focus(key) : undefined}\n onBlurCapture={dyn ? () => dyn.blur(key) : undefined}\n >\n <ParamFieldBody {...props} />\n </div>\n );\n}\n\ninterface ParamFieldProps {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n effective?: (key: string) => unknown;\n readOnly?: boolean;\n}\n\nfunction ParamFieldBody({\n param,\n value,\n onChange: rawOnChange,\n effective,\n readOnly,\n}: {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n /** Sibling-value getter (D-1/D-3) — only the `code` branch reads it, to pick\n * the editor's language mode and default snippet from a sibling `language`\n * param, when one exists. */\n effective?: (key: string) => unknown;\n readOnly?: boolean;\n}) {\n const listModelRoutes = useOptionalW6WApi()?.listModelRoutes;\n const listDataStores = useOptionalW6WApi()?.listDataStores;\n const listDataStoreEntries = useOptionalW6WApi()?.listDataStoreEntries;\n const workflowProject = useWorkflowProject();\n const dyn = useContext(DynamicFieldsCtx);\n const dynState = dyn?.fields[param.key];\n // A pick (select / Combobox / checkbox / multiselect) is a commit; a text edit is not.\n const pick = (k: string, v: unknown) => {\n rawOnChange(k, v);\n dyn?.commit(k, v);\n };\n const onChange = rawOnChange;\n const label = param.label ?? param.key;\n // A checkbox always carries a value (true/false), so \"required\" has no meaning\n // for it — don't decorate booleans with the required asterisk.\n const req = param.required && param.type !== \"boolean\" ? \" *\" : \"\";\n // Stable id so the INLINE variant's label can point at the control it names\n // (the label no longer wraps it — the ƒx sits between them).\n const controlId = useId();\n\n if (param.type === \"boolean\") {\n const current = Boolean(value ?? param.default ?? false);\n return (\n <FxField\n param={param}\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n label={label}\n req={req}\n // A checkbox does NOT fill the field box a text input fills, so it opts\n // out of that box HERE, at the seam — the wrapper renders a different\n // class rather than having the chrome clawed back off by a more\n // specific rule. Layout becomes the row: <checkbox> <ƒx> <label>.\n variant=\"inline\"\n controlId={controlId}\n >\n <input\n id={controlId}\n type=\"checkbox\"\n checked={current}\n disabled={readOnly}\n onChange={(e) => pick(param.key, e.target.checked)}\n />\n </FxField>\n );\n }\n\n // `json` and `group` params hold objects/arrays. Edit them as JSON so the\n // value round-trips faithfully instead of collapsing to \"[object Object]\".\n if (param.type === \"json\" || param.type === \"group\") {\n return <JsonParamField param={param} value={value} onChange={onChange} readOnly={readOnly} />;\n }\n\n // `code` — an inline script/snippet, edited in a real code editor. A sibling\n // `language` param (if one exists in this form) drives the editor's\n // CodeMirror mode. The default-snippet swap itself is no longer a render-time\n // guess (ROUND 1's approach): `ParamsForm`'s `set` (above) already writes the\n // swapped default into `values.code` the moment `language` changes (D-3,\n // ROUND 2 / B3), so by the time this renders, `value` is always the true\n // saved value — this is back to the same `value ?? fallbackDefault ?? \"\"`\n // shape the form used before `language` support existed, just with\n // `fallbackDefault` following the sibling language for the one case where\n // `value` is genuinely `undefined` (e.g. a `code` param that hasn't been\n // touched or seeded yet).\n if (param.type === \"code\") {\n const siblingLanguage = effective?.(\"language\");\n const language: ScriptLanguage | undefined =\n siblingLanguage === \"python\" ||\n siblingLanguage === \"javascript\" ||\n siblingLanguage === \"typescript\"\n ? siblingLanguage\n : undefined;\n const fallbackDefault = language === \"python\" ? PYTHON_CODE_DEFAULT : param.default;\n const current = (value ?? fallbackDefault ?? \"\") as string;\n if (param.scriptReads) {\n return (\n <ScriptCodeField\n param={param}\n value={String(current)}\n language={siblingLanguage === \"python\" ? \"python\" : \"javascript\"}\n label={label}\n req={req}\n readOnly={readOnly}\n onChange={(next) => onChange(param.key, next)}\n />\n );\n }\n return (\n <div className=\"w6w-field\">\n <span>\n {label}\n {req}\n </span>\n <CodeEditor\n value={String(current)}\n readOnly={readOnly}\n minHeight=\"180px\"\n language={language}\n aria-label={`${param.key} code`}\n onChange={(next) => onChange(param.key, next)}\n />\n {param.hint && <span className=\"w6w-hint\">{param.hint}</span>}\n </div>\n );\n }\n\n // `model-route` — a route picker when the host supplies `listModelRoutes`;\n // otherwise it falls through to the plain text input below (like `string`).\n if (param.type === \"model-route\" && listModelRoutes) {\n return (\n <ModelRouteField\n param={param}\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n label={label}\n req={req}\n listModelRoutes={listModelRoutes}\n project={workflowProject}\n />\n );\n }\n\n // `data-store` — a store-name picker when the host supplies `listDataStores`;\n // otherwise it falls through to the plain text input below (like `string`).\n if (param.type === \"data-store\" && listDataStores) {\n return (\n <StoreField\n param={param}\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n label={label}\n req={req}\n listDataStores={listDataStores}\n project={workflowProject}\n />\n );\n }\n\n // `data-store-key` — a searchable picker of the sibling `store`'s entries when the host\n // supplies `listDataStoreEntries` and `store` names a store literally; otherwise (no member,\n // no store yet, or a store bound to an expression) the plain text input below, as `string`.\n const storeName = effective?.(\"store\");\n if (\n param.type === \"data-store-key\" &&\n listDataStoreEntries &&\n typeof storeName === \"string\" &&\n storeName.trim() !== \"\"\n ) {\n return (\n <StoreKeyField\n param={param}\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n label={label}\n req={req}\n store={storeName}\n listDataStoreEntries={listDataStoreEntries}\n project={workflowProject}\n />\n );\n }\n\n // `vars` — a dynamic table of typed key/value variables.\n if (param.type === \"vars\") {\n return <VarsField param={param} value={value} onChange={onChange} readOnly={readOnly} />;\n }\n\n // Multi-line text: either the dedicated `text` type or any field the app\n // flagged `config.multiline` (e.g. a `string` message body as a textarea).\n if (param.type === \"text\" || param.config?.multiline) {\n const current = (value ?? param.default ?? \"\") as string;\n return (\n <FxField\n param={param}\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n label={label}\n req={req}\n >\n <textarea\n rows={3}\n value={String(current)}\n readOnly={readOnly}\n aria-label={label}\n onChange={(e) => onChange(param.key, e.target.value)}\n />\n </FxField>\n );\n }\n\n // Multi-select: pick several options from a dropdown; each becomes a removable\n // pill. Value is an array of the chosen option values.\n if (param.type === \"multiselect\") {\n return <MultiSelectField param={param} value={value} onChange={pick} readOnly={readOnly} />;\n }\n\n // `array` — a list control: a row per item (a scalar input, or an object's\n // fields side by side), with add/remove buttons.\n if (param.type === \"array\") {\n return <ArrayField param={param} value={value} onChange={onChange} readOnly={readOnly} />;\n }\n\n // Form-resolved options (host fetch) or static options + `allowCustom`: a\n // Combobox inside FxField. A no-fetch state (`hint`) falls through to the\n // plain input below, which shows the hint.\n if (dyn && dynState && !dynState.hint) {\n return (\n <ChoiceField\n param={param}\n value={value}\n onChange={pick}\n readOnly={readOnly}\n label={label}\n req={req}\n state={dynState}\n retry={() => dyn.retry(param.key)}\n />\n );\n }\n if (Array.isArray(param.options) && param.options.length > 0 && allowCustomOf(param)) {\n return (\n <ChoiceField\n param={param}\n value={value}\n onChange={pick}\n readOnly={readOnly}\n label={label}\n req={req}\n state={{ loading: false, options: param.options }}\n />\n );\n }\n\n // A constrained set of choices renders as a dropdown — even for a `string`\n // param (e.g. an HTTP method). Driven by `param.options` in the config.\n if (Array.isArray(param.options) && param.options.length > 0) {\n // An optional select with no default whose `placeholder` names the unset\n // state (e.g. \"Provider native\") gets a leading empty choice, so \"leave it\n // unset\" is selectable and shown — rather than displaying the first option\n // while nothing is actually stored.\n const unsetLabel =\n !param.required &&\n param.default === undefined &&\n typeof param.placeholder === \"string\" &&\n param.placeholder\n ? param.placeholder\n : undefined;\n const current =\n value ?? param.default ?? (unsetLabel !== undefined ? \"\" : param.options[0]?.value) ?? \"\";\n const isNumber = param.type === \"number\";\n return (\n <FxField\n param={param}\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n label={label}\n req={req}\n >\n <select\n value={String(current)}\n disabled={readOnly}\n aria-label={label}\n onChange={(e) => {\n const v = e.target.value;\n if (unsetLabel !== undefined && v === \"\") pick(param.key, undefined);\n else pick(param.key, isNumber ? Number(v) : v);\n }}\n >\n {unsetLabel !== undefined && <option value=\"\">{unsetLabel}</option>}\n {param.options.map((o) => (\n <option key={String(o.value)} value={String(o.value)}>\n {o.label}\n </option>\n ))}\n </select>\n </FxField>\n );\n }\n\n // `secret` — an encrypted / expression-capable field. Rendered via the\n // segmented ExpressionInput (masked): the value may be a plain string, an\n // `{type:\"expr\"}` envelope, or an at-rest `{type:\"secret\"}` (shown as `***`,\n // never the ciphertext). The var/secret picker data source is wired later\n // (task 3.2) via the `options` prop.\n //\n // General (non-secret) scalar fields get their own expression mode via the\n // `fx` toggle on {@link FxField} — the plain widget stays the default there.\n if (param.type === \"secret\") {\n const current = (value ?? param.default) as ExprValue | string | SecretValue | undefined;\n return (\n <div className=\"w6w-field\">\n <span>\n {label}\n {req}\n </span>\n <ExpressionInput\n value={current}\n masked\n readOnly={readOnly}\n aria-label={label}\n onChange={(next) => onChange(param.key, next)}\n />\n {param.hint && <span className=\"w6w-hint\">{param.hint}</span>}\n </div>\n );\n }\n\n // Plain text / number input for everything else.\n const inputType = param.type === \"number\" ? \"number\" : \"text\";\n const raw = value ?? param.default ?? \"\";\n // Guard against object/array values landing in a text field (they'd render as\n // \"[object Object]\"); show them JSON-stringified instead.\n const display = typeof raw === \"object\" && raw !== null ? JSON.stringify(raw) : String(raw ?? \"\");\n return (\n <FxField\n param={param}\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n label={label}\n req={req}\n >\n <input\n type={inputType}\n value={display}\n readOnly={readOnly}\n aria-label={label}\n autoComplete=\"off\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n data-1p-ignore=\"true\"\n data-lpignore=\"true\"\n data-bwignore=\"true\"\n data-form-type=\"other\"\n onChange={(e) =>\n onChange(param.key, param.type === \"number\" ? Number(e.target.value) : e.target.value)\n }\n />\n {dynState?.hint && <span className=\"w6w-hint\">{dynState.hint}</span>}\n </FxField>\n );\n}\n\n/**\n * A Combobox of host-resolved (or static + `allowCustom`) choices. Free text is a\n * value only with `allowCustom`; `aria-busy` while a request is in flight; a failed\n * request shows an alert line with a per-field Retry.\n */\nfunction ChoiceField({\n param,\n value,\n onChange,\n readOnly,\n label,\n req,\n state,\n retry,\n}: {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n readOnly?: boolean;\n label: string;\n req: string;\n state: import(\"./use-dynamic-fields.ts\").DynamicFieldState;\n retry?: () => void;\n}) {\n const raw = value ?? param.default ?? \"\";\n const current = typeof raw === \"string\" || typeof raw === \"number\" ? String(raw) : \"\";\n return (\n <FxField\n param={param}\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n label={label}\n req={req}\n >\n <div className=\"w6w-fx-grow\" aria-busy={state.loading ? \"true\" : \"false\"}>\n <Combobox\n mode=\"combobox\"\n forceSelection={!allowCustomOf(param)}\n aria-label={label}\n disabled={readOnly}\n value={current}\n placeholder={state.loading ? \"Loading…\" : (param.placeholder as string | undefined)}\n options={(state.options ?? []).map((o) => ({ value: String(o.value), label: o.label }))}\n onChange={(next) => onChange(param.key, next)}\n />\n </div>\n {state.notInList && <span className=\"w6w-hint\">{state.notInList}</span>}\n {state.error && (\n <span role=\"alert\" className=\"w6w-hint\">\n {state.error}\n {retry && (\n <button type=\"button\" onClick={retry}>\n Retry\n </button>\n )}\n </span>\n )}\n </FxField>\n );\n}\n\ntype ModelRouteList = NonNullable<import(\"./provider.tsx\").W6WApi[\"listModelRoutes\"]>;\n\n/**\n * The `model-route` picker: route NAMES in a {@link Combobox}. Free text is a\n * value (`forceSelection={false}`), a `broken` route is marked but selectable,\n * and an expression binds through the same {@link FxField} a `string` uses.\n */\nfunction ModelRouteField({\n param,\n value,\n onChange,\n readOnly,\n label,\n req,\n listModelRoutes,\n project,\n}: {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n readOnly?: boolean;\n label: string;\n req: string;\n listModelRoutes: ModelRouteList;\n /** The editor's project (`WorkflowProjectProvider`) — the routes listed are THIS project's. */\n project: string | undefined;\n}) {\n const [routes, setRoutes] = useState<Awaited<ReturnType<ModelRouteList>>>([]);\n useEffect(() => {\n let live = true;\n Promise.resolve()\n .then(() => listModelRoutes(project))\n .then((r) => live && setRoutes(Array.isArray(r) ? r : []))\n .catch(() => live && setRoutes([]));\n return () => {\n live = false;\n };\n }, [listModelRoutes, project]);\n const raw = value ?? param.default ?? \"\";\n const current = typeof raw === \"string\" ? raw : \"\";\n return (\n <FxField\n param={param}\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n label={label}\n req={req}\n >\n <Combobox\n mode=\"combobox\"\n forceSelection={false}\n aria-label={label}\n disabled={readOnly}\n value={current}\n placeholder=\"Select a route…\"\n options={routes.map((r) => ({\n value: r.name,\n label: r.status === \"broken\" ? `${r.name} (broken)` : r.name,\n }))}\n onChange={(next) => onChange(param.key, next)}\n />\n </FxField>\n );\n}\n\ntype DataStoreList = NonNullable<import(\"./provider.tsx\").W6WApi[\"listDataStores\"]>;\n\n/**\n * The `data-store` picker: store NAMES in a {@link Combobox}. Free text is a\n * value (`forceSelection={false}`) and an expression binds through the same\n * {@link FxField} a `string` uses.\n */\nfunction StoreField({\n param,\n value,\n onChange,\n readOnly,\n label,\n req,\n listDataStores,\n project,\n}: {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n readOnly?: boolean;\n label: string;\n req: string;\n listDataStores: DataStoreList;\n /** The editor's project (`WorkflowProjectProvider`) — the stores listed are THIS project's. */\n project: string | undefined;\n}) {\n const [stores, setStores] = useState<Awaited<ReturnType<DataStoreList>>>([]);\n useEffect(() => {\n let live = true;\n Promise.resolve()\n .then(() => listDataStores(project))\n .then((r) => live && setStores(Array.isArray(r) ? r : []))\n .catch(() => live && setStores([]));\n return () => {\n live = false;\n };\n }, [listDataStores, project]);\n const raw = value ?? param.default ?? \"\";\n const current = typeof raw === \"string\" ? raw : \"\";\n return (\n <FxField\n param={param}\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n label={label}\n req={req}\n >\n <Combobox\n mode=\"combobox\"\n forceSelection={false}\n aria-label={label}\n disabled={readOnly}\n value={current}\n placeholder=\"Select a store…\"\n options={stores.map((s) => ({ value: s.name, label: `${s.name} (${s.kind})` }))}\n onChange={(next) => onChange(param.key, next)}\n />\n </FxField>\n );\n}\n\ntype DataStoreEntryList = NonNullable<import(\"./provider.tsx\").W6WApi[\"listDataStoreEntries\"]>;\n\n/** Entries one picker request asks for: a page, never the whole store. */\nexport const STORE_KEY_PAGE = 25;\n/** Typing settles this long before the key search goes to the host. */\nconst STORE_KEY_DEBOUNCE_MS = 200;\nconst PREVIEW_CHARS = 60;\n\n/** One muted line under an entry's key: its value, shortened, and when it last changed. */\nexport function storeEntryDetail(entry: { value?: unknown; updatedAt?: string }): string {\n let text = \"\";\n if (entry.value !== undefined) {\n try {\n text = typeof entry.value === \"string\" ? entry.value : JSON.stringify(entry.value);\n } catch {\n text = String(entry.value);\n }\n text = text.replace(/\\s+/g, \" \");\n if (text.length > PREVIEW_CHARS) text = `${text.slice(0, PREVIEW_CHARS - 1)}…`;\n }\n const when =\n typeof entry.updatedAt === \"string\" && entry.updatedAt.length >= 16\n ? `updated ${entry.updatedAt.slice(0, 16).replace(\"T\", \" \")}`\n : \"\";\n return [text, when].filter(Boolean).join(\" · \");\n}\n\n/**\n * The `data-store-key` picker: the chosen store's entry KEYS in a {@link Combobox}, each with\n * a short value preview. Typing searches the host by key prefix (debounced, one page of\n * {@link STORE_KEY_PAGE}); free text is still a value (`forceSelection={false}`), so a key that\n * does not exist yet (a `set`) is typed as before, and an expression binds through the same\n * {@link FxField} a `string` uses.\n */\nfunction StoreKeyField({\n param,\n value,\n onChange,\n readOnly,\n label,\n req,\n store,\n listDataStoreEntries,\n project,\n}: {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n readOnly?: boolean;\n label: string;\n req: string;\n /** The sibling `store` param's literal NAME. */\n store: string;\n listDataStoreEntries: DataStoreEntryList;\n project: string | undefined;\n}) {\n const [query, setQuery] = useState(\"\");\n const [page, setPage] = useState<Awaited<ReturnType<DataStoreEntryList>>>({ items: [] });\n const [loading, setLoading] = useState(true);\n useEffect(() => {\n const ctrl = new AbortController();\n setLoading(true);\n const prefix = query.trim();\n const timer = setTimeout(\n () => {\n Promise.resolve()\n .then(() =>\n listDataStoreEntries(store, {\n project,\n prefix: prefix === \"\" ? undefined : prefix,\n limit: STORE_KEY_PAGE,\n signal: ctrl.signal,\n }),\n )\n .then((r) => {\n if (ctrl.signal.aborted) return;\n setPage(r && Array.isArray(r.items) ? r : { items: [] });\n setLoading(false);\n })\n .catch(() => {\n if (ctrl.signal.aborted) return;\n setPage({ items: [] });\n setLoading(false);\n });\n },\n prefix === \"\" ? 0 : STORE_KEY_DEBOUNCE_MS,\n );\n return () => {\n clearTimeout(timer);\n ctrl.abort();\n };\n }, [listDataStoreEntries, store, project, query]);\n const raw = value ?? param.default ?? \"\";\n const current = typeof raw === \"string\" ? raw : \"\";\n const typed = query.trim();\n return (\n <FxField\n param={param}\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n label={label}\n req={req}\n >\n <Combobox\n mode=\"combobox\"\n forceSelection={false}\n aria-label={label}\n disabled={readOnly}\n value={current}\n placeholder=\"Search entries or type a key…\"\n options={page.items.map((e) => ({\n value: e.key,\n label: e.key,\n detail: storeEntryDetail(e) || undefined,\n }))}\n onInputChange={setQuery}\n emptyText={\n loading\n ? \"Searching…\"\n : typed !== \"\"\n ? `No key starts with \"${typed}\" — Enter keeps it as typed`\n : \"No entries in this store\"\n }\n footer={page.more ? \"More entries — type to narrow by key\" : undefined}\n onChange={(next) => onChange(param.key, next)}\n />\n </FxField>\n );\n}\n\n/**\n * Wraps a general scalar field (text/number `input`, `textarea`, or an\n * `options` dropdown) with an `fx` affordance: a small ƒx at the end of the\n * field opens the {@link ExpressionEditorModal}, so an author can bind the field\n * to a variable/expression instead of a literal. Mirrors the `secret`-param\n * path, which already renders {@link ExpressionInput}.\n *\n * The plain widget is the DEFAULT: a number/select round-trips as its original\n * scalar until the author actually SAVES an expression from the modal (gap #6).\n * The engine's `resolveWith` accepts an `ExprValue` or a literal for any `with`\n * value, so a stored expression round-trips without an engine change.\n *\n * ONE ƒx, ONE click. Plain mode renders the plain widget plus the single ƒx\n * button below, which opens the modal WITHOUT writing to the form. Expression\n * mode renders `ExpressionInput`, whose own ƒx reopens the same modal — so the\n * field never shows two ƒx controls at once.\n *\n * TWO CHROME VARIANTS, picked by the CALLER from the control it is passing:\n * `\"boxed\"` (default) is the text-field box above — right for any widget that\n * FILLS the box (input, textarea, select, the multiselect chip box). `\"inline\"`\n * is for a widget that does not: a `boolean`'s ~13px checkbox left the rest of a\n * full-width panel empty. The inline variant renders a DIFFERENT wrapper class\n * (`.w6w-fx-inline`, which simply declares no chrome) instead of over-riding\n * `.w6w-fx-wrap` with a more specific rule, and lays the row out as the review\n * asked: `<checkbox> <ƒx> <label>`, with no stacked label above it.\n */\nfunction FxField({\n param,\n value,\n onChange,\n readOnly,\n label,\n req,\n bare,\n variant = \"boxed\",\n controlId,\n children,\n}: {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n readOnly?: boolean;\n label: string;\n req: string;\n /** Render only the toggle + widget (no label/hint chrome) — for compact\n * cells such as a `vars` row value that already live inside their own grid. */\n bare?: boolean;\n /** Chrome + layout of the wrapper. See the note above: `\"inline\"` is for a\n * control that does not fill a text-field box (today: a checkbox). */\n variant?: \"boxed\" | \"inline\";\n /** `id` of the control `children` renders, so the inline row's label can name\n * it (`htmlFor`) — the label is a sibling there, not a wrapper. */\n controlId?: string;\n children: ReactNode;\n}) {\n // Expression mode is DERIVED from the stored value — never a local flag.\n // Nothing turns a local boolean back off now that the value-mutating toggle is\n // gone, so it would drift: the field would read as an expression while holding\n // a plain string (or the reverse). Deriving makes control and value unable to\n // disagree BY CONSTRUCTION, and Cancel-leaves-the-field-plain falls out for\n // free — the modal's `onClose` writes nothing, so `value`, and therefore `fx`,\n // is unchanged. A value that arrives after mount (a saved test seeded into a\n // field that mounted empty) is picked up on the next render, no effect needed.\n const fx = holdsExpression(value);\n // Multi-line text fields keep their newlines in expression mode too: Enter\n // inserts a literal \"\\n\" instead of being swallowed. Same predicate the\n // textarea branch above renders on, so the two can never disagree.\n const multiline = param.type === \"text\" || !!param.config?.multiline;\n const [modalOpen, setModalOpen] = useState(false);\n // Picker data (vars/secrets/steps/…) — sourced exactly the way ExpressionInput\n // sources it, from the nearest ExpressionOptionsProvider.\n const exprOptions = useExpressionOptions();\n\n // The ƒx rides at the end of the input (an in-field decoration) rather than up\n // in the label row — so the affordance sits next to the value it governs. It\n // OPENS THE MODAL and writes nothing; the value only changes if the author\n // saves from there.\n //\n // `.w6w-fx-wrap` IS the field's box: it owns the border/background/radius and\n // the `:focus-within` ring, and the widget it holds is flattened by compound\n // selectors in styles.css — so widget + ƒx read as one box, not as a button\n // beside a field. A widget that owns a box itself (`.w6w-multiselect`, the\n // `.w6w-expr-field` inside ExpressionInput) is flattened there too.\n //\n // The inline variant applies to the PLAIN widget only: once the field holds\n // an expression it renders `ExpressionInput`, which IS a text-like control\n // that fills a box — so it goes back to the standard boxed field with its\n // label above, exactly like every other expression-bound field.\n const inline = variant === \"inline\" && !fx;\n const body = (\n <>\n <div className={inline ? \"w6w-fx-inline\" : `w6w-fx-wrap${fx ? \" is-fx\" : \"\"}`}>\n {fx ? (\n // Expression mode: ExpressionInput already carries the ONE ƒx here\n // (its own edit button), which reopens this same modal. Rendering a\n // second one would put two ƒx side by side — the bug the intake filed.\n <ExpressionInput\n value={value as ExprValue | string | undefined}\n multiline={multiline}\n readOnly={readOnly}\n aria-label={label}\n onChange={(next) => onChange(param.key, next)}\n />\n ) : (\n <>\n {children}\n {!readOnly && (\n <button\n type=\"button\"\n className=\"w6w-expr-fx\"\n title=\"Use an expression\"\n aria-label={`Use an expression for ${label}`}\n onClick={() => setModalOpen(true)}\n >\n ƒx\n </button>\n )}\n {/* Inline variant: the label rides HERE, after the ƒx — it is the\n field's ONLY label (the stacked one below is not rendered). */}\n {inline && (\n <label className=\"w6w-fx-inline-label\" htmlFor={controlId}>\n {label}\n {req}\n </label>\n )}\n </>\n )}\n </div>\n {modalOpen && (\n // The modal owns the whole round trip — it seeds itself from `value` and\n // commits through the shared template helpers in its own save. Nothing\n // is re-implemented here: this supplies the value and consumes `onSave`.\n <ExpressionEditorModal\n value={value as ExprValue | string | undefined}\n multiline={multiline}\n options={exprOptions}\n fieldLabel={label}\n onSave={(next) => onChange(param.key, next)}\n onClose={() => setModalOpen(false)}\n />\n )}\n </>\n );\n\n // Bare: just the toggle + widget, no label/hint chrome (the host cell owns them).\n if (bare) return body;\n\n return (\n <div className=\"w6w-field\">\n {/* Inline: the label lives INSIDE the row (above), so the stacked one is\n not rendered at all — one label per field, never two. */}\n {!inline && (\n <span>\n {label}\n {req}\n </span>\n )}\n {body}\n {param.hint && <span className=\"w6w-hint\">{param.hint}</span>}\n </div>\n );\n}\n\n/**\n * A `json`-typed param edited through the JsonEditor. Holds its own text state\n * (seeded from the incoming value) and only pushes back to the form when the\n * text parses — an invalid draft doesn't corrupt the collected values.\n */\nfunction JsonParamField({\n param,\n value,\n onChange,\n readOnly,\n headerActions,\n onValidityChange,\n}: {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n readOnly?: boolean;\n headerActions?: ReactNode;\n onValidityChange?: (valid: boolean) => void;\n}) {\n // \"Bound\" is DERIVED from the stored value on every render — never a local\n // flag — so control and value cannot disagree (same stance as `FxField`'s `fx`).\n // A whole-value binding: `\"{{ ref }}\"`, or a legacy `{ \"$\": ref }`.\n const boundRef = wholeValueRef(value) ?? \"\";\n const bound = boundRef !== \"\";\n const seed = value ?? param.default;\n // The draft is NEVER seeded from a binding (R-18a): Clear must be able to give\n // back the literal JSON the author had, or \"\" if there was none.\n const [text, setText] = useState(() =>\n bound || seed === undefined ? \"\" : JSON.stringify(seed, null, 2),\n );\n const [invalid, setInvalid] = useState(false);\n const [expanded, setExpanded] = useState(false);\n const [pickerOpen, setPickerOpen] = useState(false);\n const exprOptions = useExpressionOptions();\n const upstream = exprOptions.steps ?? [];\n\n // Re-seed when the field identity changes OR the incoming value changes to\n // something other than what the current draft already represents — i.e. an\n // external load (a saved test opened into an already-mounted JSON field), not\n // the echo of the user's own valid edit. Comparing against the parsed draft\n // avoids clobbering the cursor/formatting on every keystroke.\n // biome-ignore lint/correctness/useExhaustiveDependencies: `text` is read as the draft baseline but must NOT retrigger the effect (that would reseed mid-edit); reseed is keyed on the incoming value + param identity\n useEffect(() => {\n if (bound) return; // keep the held draft so Clear can restore it\n let current: unknown;\n try {\n current = text.trim() === \"\" ? undefined : JSON.parse(text);\n } catch {\n current = undefined; // invalid draft — let an external value win\n }\n if (JSON.stringify(current) !== JSON.stringify(seed)) {\n setText(seed === undefined ? \"\" : JSON.stringify(seed, null, 2));\n setInvalid(false);\n }\n }, [seed, param.key, bound]);\n\n const onEdit = (next: string) => {\n setText(next);\n };\n const onValid = (parsed: unknown) => {\n setInvalid(false);\n onValidityChange?.(true);\n onChange(param.key, parsed);\n };\n // Empty is not invalid: it clears the value (required-ness is enforced on\n // submit, not by this field). Only non-empty unparseable text is \"Invalid JSON\".\n const onValidity = ({ valid, error }: { valid: boolean; error?: string }) => {\n onValidityChange?.(valid || error === \"Empty\");\n if (!valid && error === \"Empty\") {\n setInvalid(false);\n onChange(param.key, undefined);\n return;\n }\n setInvalid(!valid);\n };\n // A whole field typed as one `{{ ref }}` is not JSON (no quotes), but it means exactly the\n // binding `\"{{ ref }}\"` the ƒx picker stores. Applied when the field loses focus, never per keystroke:\n // auto-closed braces make `{{ nodes}}` a complete marker halfway through typing a ref.\n const commitBareRef = () => {\n const binding = bareRefBinding(text);\n if (!binding) return;\n setInvalid(false);\n onChange(param.key, binding);\n };\n const label = param.label ?? param.key;\n\n // Clear: back to the literal JSON the editor still holds (undefined if the\n // draft is empty or does not parse). Exactly one onChange.\n const clear = () => {\n let restored: unknown;\n try {\n restored = text.trim() === \"\" ? undefined : JSON.parse(text);\n } catch {\n restored = undefined;\n }\n onChange(param.key, restored);\n };\n\n return (\n <div className=\"w6w-field\">\n <span className=\"w6w-field-labelrow\">\n <span>\n {label}\n {param.required ? \" *\" : \"\"}\n </span>\n {headerActions}\n {!bound && (\n <button\n type=\"button\"\n className=\"w6w-icon-btn w6w-btn-sm\"\n title=\"Open in full view\"\n aria-label={`Open ${label} in full view`}\n onClick={() => setExpanded(true)}\n >\n {/* `icons.tsx`'s `maximize` — Feather `maximize-2`'s diagonal expand arrows on a\n 24×24 viewBox, drawn at 14px. */}\n <Icon name=\"maximize\" size={14} />\n </button>\n )}\n </span>\n {/* Inline: content-sized, grows with content up to maxHeight, then scrolls\n internally (so it never overlaps the next field). Full view via button. */}\n {bound ? (\n // Bound: the reference reads exactly like an expression in a text field — one\n // var chip in the field box (same classes `ExpressionInput` paints), its × to\n // clear, and the ƒx to reopen the picker. No resolved preview.\n <div className=\"w6w-fx-wrap is-fx w6w-json-binding\">\n <div className=\"w6w-expr\">\n <div className=\"w6w-expr-field\">\n <div\n className={`w6w-expr-editor${readOnly ? \" is-readonly\" : \"\"}`}\n data-testid=\"json-binding-ref\"\n >\n <span\n className=\"w6w-expr-chip w6w-expr-chip-var\"\n data-kind=\"var\"\n data-ref={boundRef}\n title={`Variable: ${boundRef}`}\n >\n <span className=\"w6w-expr-chip-sigil\">◆</span>\n <span className=\"w6w-expr-chip-label\">{varLabel(boundRef)}</span>\n {!readOnly && (\n <button\n type=\"button\"\n className=\"w6w-expr-chip-x\"\n aria-label={`Remove the reference from ${label}`}\n // `.w6w-expr-chip-x` styles the glyph; reset only what a <button> adds.\n style={{ border: 0, padding: 0, font: \"inherit\" }}\n onClick={clear}\n >\n ×\n </button>\n )}\n </span>\n </div>\n {!readOnly && (\n <button\n type=\"button\"\n className=\"w6w-expr-edit\"\n title=\"Edit expression — browse step outputs, metadata & variables\"\n aria-label={`Edit expression for ${label}`}\n onClick={() => setPickerOpen(true)}\n >\n ƒx\n </button>\n )}\n </div>\n </div>\n </div>\n ) : (\n <JsonEditor\n value={text}\n onChange={onEdit}\n onBlur={commitBareRef}\n readOnly={readOnly}\n minHeight=\"34px\"\n maxHeight=\"260px\"\n aria-label={`${param.key} JSON`}\n onValidChange={onValid}\n onValidityChange={onValidity}\n overlay={\n readOnly ? undefined : (\n <button\n type=\"button\"\n className=\"w6w-expr-fx\"\n title=\"Use an expression\"\n aria-label={`Use an expression for ${label}`}\n onClick={() => setPickerOpen(true)}\n >\n ƒx\n </button>\n )\n }\n />\n )}\n {pickerOpen && (\n <ExpressionEditorModal\n mode=\"json-binding\"\n value={undefined}\n jsonValue={value}\n options={exprOptions}\n fieldLabel={label}\n whole={param.whole}\n onSaveJson={(next) => onChange(param.key, next)}\n onClose={() => setPickerOpen(false)}\n />\n )}\n {!bound && invalid && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n Invalid JSON\n </span>\n )}\n {/* One click binds the whole value to an upstream step's output — the binding the\n ƒx picker would store, without having to know the `nodes.<id>.output` spelling. */}\n {param.whole && !bound && !readOnly && upstream.length > 0 && (\n <div className=\"w6w-seed-chips w6w-json-quickbind\">\n <span className=\"w6w-muted w6w-small\">Use the output of</span>\n {upstream.map((s) => (\n <button\n key={s.id}\n type=\"button\"\n className=\"w6w-chip w6w-seed-chip\"\n title={`Bind ${label} to {{ nodes.${s.id}.output }}`}\n onClick={() => onChange(param.key, `{{ nodes.${s.id}.output }}`)}\n >\n <code>{s.id}</code>\n </button>\n ))}\n </div>\n )}\n {param.hint && <span className=\"w6w-hint\">{param.hint}</span>}\n\n {expanded && !bound && (\n <Modal\n title={label}\n subtitle={<code>JSON</code>}\n size=\"wide\"\n onClose={() => setExpanded(false)}\n >\n <div className=\"w6w-json-fullview\">\n <JsonEditor\n value={text}\n onChange={onEdit}\n readOnly={readOnly}\n height=\"100%\"\n minHeight=\"360px\"\n aria-label={`${param.key} JSON (full view)`}\n onValidChange={onValid}\n onValidityChange={onValidity}\n />\n </div>\n {invalid && (\n <span className=\"w6w-hint\" style={{ color: \"var(--w6w-danger)\" }}>\n Invalid JSON\n </span>\n )}\n </Modal>\n )}\n </div>\n );\n}\n\n/**\n * A `multiselect` param — a Material-style chips input: the chosen options render\n * as removable chips *inside* a single input-like box, followed by a dropdown\n * (reading as placeholder text) that appends more. Value is an array of the\n * chosen option values (or CSV with `config.valueFormat`); the dropdown only\n * lists options not already selected.\n */\nfunction MultiSelectField({\n param,\n value,\n onChange,\n readOnly,\n}: {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n readOnly?: boolean;\n}) {\n const options = Array.isArray(param.options) ? param.options : [];\n const csv = param.config?.valueFormat === \"csv\";\n const current = value ?? param.default;\n const selected: Array<string | number> = Array.isArray(current)\n ? (current as Array<string | number>)\n : csv && typeof current === \"string\"\n ? current\n .split(\",\")\n .map((v) => v.trim())\n .filter(Boolean)\n : [];\n const selectedKeys = new Set(selected.map(String));\n const available = options.filter((o) => !selectedKeys.has(String(o.value)));\n const labelFor = (v: string | number) =>\n options.find((o) => String(o.value) === String(v))?.label ?? String(v);\n const commit = (next: Array<string | number>) => onChange(param.key, csv ? next.join(\",\") : next);\n\n const add = (raw: string) => {\n if (!raw || selectedKeys.has(raw)) return;\n const opt = options.find((o) => String(o.value) === raw);\n commit([...selected, opt ? opt.value : raw]);\n };\n const remove = (v: string | number) => commit(selected.filter((x) => String(x) !== String(v)));\n\n const placeholder =\n typeof param.placeholder === \"string\" && param.placeholder ? param.placeholder : \"Select…\";\n const label = param.label ?? param.key;\n const req = param.required ? \" *\" : \"\";\n\n return (\n <FxField\n param={param}\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n label={label}\n req={req}\n >\n {param.ui === \"checkboxes\" ? (\n <div className=\"w6w-multiselect-checks w6w-fx-grow\">\n <div className=\"w6w-multiselect-checks-toolbar\">\n <span className=\"w6w-muted w6w-small\">{selected.length} selected</span>\n {!readOnly && (\n <>\n <button\n type=\"button\"\n className=\"w6w-linkbtn\"\n disabled={available.length === 0}\n onClick={() => commit([...selected, ...available.map((option) => option.value)])}\n >\n Select all\n </button>\n <button\n type=\"button\"\n className=\"w6w-linkbtn\"\n disabled={selected.length === 0}\n onClick={() => commit([])}\n >\n Clear\n </button>\n </>\n )}\n </div>\n <fieldset className=\"w6w-multiselect-checks-options\" aria-label={label}>\n {[\n ...options,\n ...selected\n .filter((v) => !options.some((o) => String(o.value) === String(v)))\n .map((v) => ({ value: v, label: String(v) })),\n ].map((option) => (\n <label key={String(option.value)} className=\"w6w-multiselect-check\">\n <input\n type=\"checkbox\"\n checked={selectedKeys.has(String(option.value))}\n disabled={readOnly}\n onChange={(event) =>\n event.target.checked ? add(String(option.value)) : remove(option.value)\n }\n />\n <span>{option.label}</span>\n </label>\n ))}\n </fieldset>\n </div>\n ) : (\n <>\n {/* One input-like box: chips inline, then the dropdown as the trailing\n placeholder — chips appear to live inside the field's boundaries. The\n ƒx toggle (via FxField) swaps the whole box for an expression. */}\n <div className={`w6w-multiselect${readOnly ? \" is-readonly\" : \"\"}`}>\n {selected.map((v) => (\n <span className=\"w6w-chip\" key={String(v)}>\n {labelFor(v)}\n {!readOnly && (\n <button\n type=\"button\"\n className=\"w6w-chip-x\"\n aria-label={`Remove ${labelFor(v)}`}\n title=\"Remove\"\n onClick={() => remove(v)}\n >\n ×\n </button>\n )}\n </span>\n ))}\n {!readOnly && (\n // Controlled to \"\" so it always reads as the trailing placeholder;\n // picking an option appends a chip and resets.\n <select\n className=\"w6w-multiselect-add\"\n value=\"\"\n disabled={available.length === 0}\n aria-label={`Add to ${param.label ?? param.key}`}\n onChange={(e) => add(e.target.value)}\n >\n <option value=\"\">\n {available.length > 0\n ? selected.length\n ? \"Add more…\"\n : placeholder\n : \"All selected\"}\n </option>\n {available.map((o) => (\n <option key={String(o.value)} value={String(o.value)}>\n {o.label}\n </option>\n ))}\n </select>\n )}\n </div>\n </>\n )}\n </FxField>\n );\n}\n\n/** A single input inside an `array` object-item row (placeholder = the field label). */\nfunction ArrayItemInput({\n field,\n value,\n onChange,\n readOnly,\n}: {\n field: ActionParam;\n value: unknown;\n onChange: (v: unknown) => void;\n readOnly?: boolean;\n}) {\n const ph = field.placeholder ?? field.label ?? field.key;\n if (Array.isArray(field.options) && field.options.length > 0) {\n return (\n <select\n className=\"w6w-array-input\"\n value={String(value ?? field.default ?? field.options[0]?.value ?? \"\")}\n disabled={readOnly}\n aria-label={field.label ?? field.key}\n onChange={(e) => onChange(e.target.value)}\n >\n {field.options.map((o) => (\n <option key={String(o.value)} value={String(o.value)}>\n {o.label}\n </option>\n ))}\n </select>\n );\n }\n if (field.type === \"boolean\") {\n return (\n <label className=\"w6w-array-check\" title={field.label ?? field.key}>\n <input\n type=\"checkbox\"\n checked={Boolean(value ?? field.default ?? false)}\n disabled={readOnly}\n aria-label={field.label ?? field.key}\n onChange={(e) => onChange(e.target.checked)}\n />\n <span>{field.label ?? field.key}</span>\n </label>\n );\n }\n const isNumber = field.type === \"number\";\n return (\n <input\n className=\"w6w-array-input\"\n type={isNumber ? \"number\" : \"text\"}\n value={String(value ?? field.default ?? \"\")}\n placeholder={ph}\n aria-label={field.label ?? field.key}\n readOnly={readOnly}\n onChange={(e) => onChange(isNumber ? Number(e.target.value) : e.target.value)}\n />\n );\n}\n\n/**\n * An `array`-typed param — a list control. Each row is either a single scalar\n * input (`item.type: \"string\" | \"number\"`) or an object's `fields` side by side\n * (`item.type: \"object\"`). \"+ Add\" appends a blank item; each row has an `×`.\n */\nfunction ArrayField({\n param,\n value,\n onChange,\n readOnly,\n}: {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n readOnly?: boolean;\n}) {\n const item = param.item ?? { type: \"string\" };\n const isObject = item.type === \"object\";\n const items: unknown[] = Array.isArray(value)\n ? value\n : Array.isArray(param.default)\n ? (param.default as unknown[])\n : [];\n const commit = (next: unknown[]) => onChange(param.key, next);\n const blank = (): unknown =>\n isObject\n ? Object.fromEntries((item.fields ?? []).map((f) => [f.key, f.default ?? \"\"]))\n : item.type === \"number\"\n ? 0\n : \"\";\n const patchAt = (idx: number, next: unknown) =>\n commit(items.map((it, j) => (j === idx ? next : it)));\n\n return (\n <div className=\"w6w-field\">\n <span>\n {param.label ?? param.key}\n {param.required ? \" *\" : \"\"}\n </span>\n <div className=\"w6w-array\">\n {items.length === 0 && <p className=\"w6w-muted w6w-small\">None yet — add one below.</p>}\n {items.map((it, idx) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: rows have no stable id; values are user-edited\n <div className=\"w6w-array-row\" key={idx}>\n {isObject ? (\n <div className=\"w6w-array-cells\">\n {(item.fields ?? []).map((f) => (\n <ArrayItemInput\n key={f.key}\n field={f}\n value={(it as Record<string, unknown>)?.[f.key]}\n readOnly={readOnly}\n onChange={(fv) =>\n patchAt(idx, { ...((it as Record<string, unknown>) ?? {}), [f.key]: fv })\n }\n />\n ))}\n </div>\n ) : (\n <input\n className=\"w6w-array-input\"\n type={item.type === \"number\" ? \"number\" : \"text\"}\n value={String(it ?? \"\")}\n placeholder={item.placeholder}\n readOnly={readOnly}\n onChange={(e) =>\n patchAt(idx, item.type === \"number\" ? Number(e.target.value) : e.target.value)\n }\n />\n )}\n {!readOnly && (\n <button\n type=\"button\"\n className=\"w6w-array-x\"\n aria-label=\"Remove item\"\n title=\"Remove\"\n onClick={() => commit(items.filter((_, j) => j !== idx))}\n >\n ×\n </button>\n )}\n </div>\n ))}\n {!readOnly && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm w6w-array-add\"\n onClick={() => commit([...items, blank()])}\n >\n + Add\n </button>\n )}\n </div>\n {param.hint && <span className=\"w6w-hint\">{param.hint}</span>}\n </div>\n );\n}\n\n/**\n * One typed key/value entry in a `vars` param. `type` is a real value type only:\n * `expression` is a binding *mode* (see {@link FxField}/`ExprValue`), not a value\n * type, so it is no longer offered in the dropdown. Each row value carries its own\n * ƒx toggle (via {@link FxField} in `bare` mode), so any declared type can be bound\n * to an expression; a legacy row persisted with `type:\"expression\"` (an `ExprValue`)\n * still round-trips — FxField opens it in expression mode from the stored value.\n */\nexport interface DataVar {\n key: string;\n type: \"string\" | \"number\" | \"boolean\" | \"json\";\n value: unknown;\n}\n\nconst DATA_VAR_TYPES: DataVar[\"type\"][] = [\"string\", \"number\", \"boolean\", \"json\"];\nconst EMPTY_DATA_VARS: DataVar[] = [];\n\n/** Rows for a literal object or the existing typed-row format; bindings stay in JSON mode. */\nexport function dataVarRows(value: unknown, previous: DataVar[] = []): DataVar[] | null {\n if (Array.isArray(value)) {\n return value.every((v) => v && typeof v === \"object\" && typeof v.key === \"string\")\n ? (value as DataVar[])\n : null;\n }\n if (\n !value ||\n typeof value !== \"object\" ||\n holdsExpression(value) ||\n wholeValueRef(value) ||\n \"$expr\" in value\n ) {\n return null;\n }\n return Object.entries(value).map(([key, item]) => {\n const old = previous.find((row) => row.key === key);\n const type = typeof item;\n return {\n key,\n type:\n old && JSON.stringify(old.value) === JSON.stringify(item)\n ? old.type\n : type === \"string\" || type === \"number\" || type === \"boolean\"\n ? type\n : \"json\",\n value: item,\n };\n });\n}\n\n/** Keep incomplete/duplicate-key rows as an array so opening JSON never drops an entry. */\nfunction dataVarsJson(value: unknown): unknown {\n const rows = Array.isArray(value) ? dataVarRows(value) : null;\n if (\n !rows ||\n rows.some((row) => !row.key) ||\n new Set(rows.map((row) => row.key)).size !== rows.length\n ) {\n return value;\n }\n return Object.fromEntries(rows.map((row) => [row.key, row.value]));\n}\n\n/** Coerce a text input into the variable's declared type (best-effort). */\nfunction coerceVarValue(type: DataVar[\"type\"], raw: string): unknown {\n if (type === \"number\") {\n if (raw.trim() === \"\") return \"\";\n const n = Number(raw);\n return Number.isNaN(n) ? raw : n;\n }\n if (type === \"boolean\") return raw === \"true\";\n if (type === \"json\") {\n try {\n return JSON.parse(raw);\n } catch {\n return raw;\n }\n }\n return raw;\n}\n\n/** Render a stored variable value back into an editable string. */\nfunction varValueToText(v: unknown): string {\n if (v === undefined || v === null) return \"\";\n if (typeof v === \"object\") return JSON.stringify(v);\n return String(v);\n}\n\n/**\n * A `vars`-typed param offers both typed rows and a JSON object/binding.\n */\nfunction VarsField({\n param,\n value,\n onChange,\n readOnly,\n}: {\n param: ActionParam;\n value: unknown;\n onChange: (key: string, value: unknown) => void;\n readOnly?: boolean;\n}) {\n const seed = value ?? param.default ?? EMPTY_DATA_VARS;\n const jsonValue = useMemo(() => dataVarsJson(seed), [seed]);\n const [mode, setMode] = useState<\"fields\" | \"json\">(() =>\n Array.isArray(seed) ? \"fields\" : \"json\",\n );\n const previousRows = useRef<DataVar[]>([]);\n const [invalidJson, setInvalidJson] = useState(false);\n const [jsonError, setJsonError] = useState<string | null>(null);\n const rows = dataVarRows(seed, previousRows.current);\n const vars = rows ?? [];\n const jsonMode = mode === \"json\" || rows === null;\n const label = param.label ?? param.key;\n const toggle = (\n <div className=\"w6w-view-toggle w6w-datavar-modes\">\n <button\n type=\"button\"\n className={`w6w-btn w6w-btn-sm w6w-btn-ghost${!jsonMode ? \" active\" : \"\"}`}\n aria-label={`Edit ${label} as fields`}\n aria-pressed={!jsonMode}\n disabled={invalidJson || !!jsonError || rows === null}\n title={\n rows === null\n ? \"Use a literal JSON object to edit individual fields\"\n : \"Edit individual fields\"\n }\n onClick={() => {\n if (!readOnly && !Array.isArray(seed)) onChange(param.key, vars);\n setMode(\"fields\");\n }}\n >\n Fields\n </button>\n <button\n type=\"button\"\n className={`w6w-btn w6w-btn-sm w6w-btn-ghost${jsonMode ? \" active\" : \"\"}`}\n aria-label={`Edit ${label} as JSON`}\n aria-pressed={jsonMode}\n onClick={() => {\n previousRows.current = vars;\n setMode(\"json\");\n }}\n >\n JSON\n </button>\n </div>\n );\n if (jsonMode) {\n return (\n <div className=\"w6w-datavar-json\">\n <JsonParamField\n param={{\n ...param,\n type: \"json\",\n whole: true,\n default: {},\n hint: \"Enter a JSON object or use ƒx to bind one. Switch to Fields to edit individual values.\",\n }}\n value={jsonValue}\n readOnly={readOnly}\n headerActions={toggle}\n onValidityChange={(valid) => setInvalidJson(!valid)}\n onChange={(key, next) => {\n if (\n next !== undefined &&\n dataVarRows(next) === null &&\n !wholeValueRef(next) &&\n !holdsExpression(next) &&\n !(next && typeof next === \"object\" && \"$expr\" in next)\n ) {\n setJsonError(\"Use a JSON object, a typed key/value array, or an object binding.\");\n return;\n }\n setJsonError(null);\n setInvalidJson(false);\n onChange(key, next);\n }}\n />\n {jsonError && (\n <span className=\"w6w-hint w6w-datavar-error\" aria-live=\"polite\">\n {jsonError}\n </span>\n )}\n </div>\n );\n }\n const commit = (next: DataVar[]) => onChange(param.key, next);\n const patch = (i: number, p: Partial<DataVar>) =>\n commit(vars.map((v, idx) => (idx === i ? { ...v, ...p } : v)));\n\n return (\n <div className=\"w6w-field\">\n <span className=\"w6w-field-labelrow\">\n <span>\n {label}\n {param.required ? \" *\" : \"\"}\n </span>\n {toggle}\n </span>\n <div className=\"w6w-stack\">\n {vars.length === 0 && (\n <p className=\"w6w-muted w6w-small\">No variables yet — add one below.</p>\n )}\n {vars.map((v, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: rows have no stable id; keys/values are user-edited\n <div className=\"w6w-datavar-row\" key={i}>\n <input\n type=\"text\"\n placeholder=\"key\"\n value={v.key}\n readOnly={readOnly}\n onChange={(e) => patch(i, { key: e.target.value })}\n />\n <select\n value={v.type}\n disabled={readOnly}\n onChange={(e) => {\n const type = e.target.value as DataVar[\"type\"];\n patch(i, { type, value: coerceVarValue(type, varValueToText(v.value)) });\n }}\n >\n {DATA_VAR_TYPES.map((t) => (\n <option key={t} value={t}>\n {t}\n </option>\n ))}\n </select>\n {/* Per-value ƒx toggle: any declared type can be bound to an\n expression (stored as an `{type:\"expr\"}` envelope, resolved\n against the run scope before the data node runs). A legacy\n `type:\"expression\"` row (an ExprValue) reopens in fx mode from\n its stored value. `bare` drops the field chrome so the widget\n fits the row's grid cell. */}\n <FxField\n bare\n param={param}\n value={v.value}\n onChange={(_key, next) => patch(i, { value: next })}\n readOnly={readOnly}\n label={v.key || \"value\"}\n req=\"\"\n >\n {v.type === \"boolean\" ? (\n <select\n value={v.value === true ? \"true\" : \"false\"}\n disabled={readOnly}\n onChange={(e) => patch(i, { value: e.target.value === \"true\" })}\n >\n <option value=\"true\">true</option>\n <option value=\"false\">false</option>\n </select>\n ) : (\n <input\n type={v.type === \"number\" ? \"number\" : \"text\"}\n placeholder=\"value\"\n value={varValueToText(v.value)}\n readOnly={readOnly}\n onChange={(e) => patch(i, { value: coerceVarValue(v.type, e.target.value) })}\n />\n )}\n </FxField>\n {!readOnly && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n aria-label={`Remove variable ${v.key || i + 1}`}\n title=\"Remove\"\n onClick={() => commit(vars.filter((_, idx) => idx !== i))}\n >\n ×\n </button>\n )}\n </div>\n ))}\n {!readOnly && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n onClick={() => commit([...vars, { key: \"\", type: \"string\", value: \"\" }])}\n >\n + Add variable\n </button>\n )}\n </div>\n {param.hint && <span className=\"w6w-hint\">{param.hint}</span>}\n </div>\n );\n}\n","import { parseResolvableText, serializeTemplate } from \"./components/expression-template.ts\";\nimport { type ExprValue, type SecretValue, isExprValue } from \"./types.ts\";\n\nconst object = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n/** The comparisons the condition builder offers, in menu order, with their labels. */\nexport const CONDITION_OPERATORS = [\n [\"is-true\", \"is true\"],\n [\"is-false\", \"is false\"],\n [\"===\", \"equals\"],\n [\"!==\", \"does not equal\"],\n [\">\", \"greater than\"],\n [\">=\", \"at least\"],\n [\"<\", \"less than\"],\n [\"<=\", \"at most\"],\n [\"in\", \"in\"],\n [\"includes\", \"includes value\"],\n [\"include-any\", \"includes any of (list)\"],\n [\"include-all\", \"includes all of (list)\"],\n] as const;\n/** Operand order for membership comparisons; shown on the selected operator and its options. */\nexport const CONDITION_OPERATOR_HINTS: Record<string, string> = {\n in: \"The right array contains the left value.\",\n includes: \"Check whether a list contains one value, or text contains a substring.\",\n \"include-any\":\n \"Compare two lists for any shared value. For one value on the right, use includes value.\",\n \"include-all\": \"Compare two lists: every value in the right list must be in the left list.\",\n};\nconst operators = new Set<string>(CONDITION_OPERATORS.map(([op]) => op));\nconst operatorLabels: Record<string, string> = {\n ...Object.fromEntries(CONDITION_OPERATORS),\n \"==\": \"equals\",\n \"!=\": \"does not equal\",\n in: \"is in\",\n};\n\n/** A comparison operator as the builder names it (`===` → \"equals\"); unknown ones as written. */\nexport function conditionOperatorLabel(op: string): string {\n if (op.startsWith(\"not:\")) return `Not (${operatorLabels[op.slice(4)] ?? op.slice(4)})`;\n return operatorLabels[op] ?? op;\n}\n\n/** One comparison row of the builder: `left <operator> right`. */\nexport interface ConditionComparison {\n left: unknown;\n operator: string;\n right: unknown;\n /** Invert this comparison before combining it with the other rows. */\n negated?: boolean;\n}\n\n/** How the builder joins its rows: all of (`and`), any of (`or`), exactly one of (`xor`). */\nexport type ConditionCombinator = \"and\" | \"or\" | \"xor\";\n\n/** The combinators the builder offers, in menu order, with their labels. `xor` is the\n * `@w6w/expr` extension (JSONLogic has none): true when exactly one row is. */\nexport const CONDITION_COMBINATORS = [\n [\"and\", \"All of (AND)\"],\n [\"or\", \"Any of (OR)\"],\n [\"xor\", \"Exactly one of (XOR)\"],\n] as const satisfies readonly (readonly [ConditionCombinator, string])[];\nconst combinatorLabels: Record<string, string> = Object.fromEntries(CONDITION_COMBINATORS);\n\n/** A combinator as the builder names it (`or` → \"Any of (OR)\"); unknown ones as written. */\nexport function conditionCombinatorLabel(combinator: string): string {\n return combinatorLabels[combinator] ?? combinator;\n}\n\n/** The builder's whole condition: flat rows joined by one combinator (no nested groups). */\nexport interface ConditionGroup {\n combinator: ConditionCombinator;\n rows: ConditionComparison[];\n}\n\nfunction comparisonOf(logic: unknown, allowNegation = true): ConditionComparison | undefined {\n if (!object(logic)) return;\n const entries = Object.entries(logic);\n if (entries.length !== 1) return;\n const [operator, args] = entries[0];\n if (allowNegation && operator === \"!\" && Array.isArray(args) && args.length === 1) {\n const inner = comparisonOf(args[0], false);\n // Keep nested negations in the full editor rather than silently rewriting them.\n if (!inner || inner.negated) return;\n return { ...inner, negated: true };\n }\n if (!operators.has(operator) || !Array.isArray(args) || args.length !== 2) return;\n if (operator === \"===\" && typeof args[1] === \"boolean\") {\n return {\n left: args[0],\n operator: args[1] ? \"is-true\" : \"is-false\",\n right: args[1],\n };\n }\n // These are editor choices, never JSONLogic operators.\n if (operator === \"is-true\" || operator === \"is-false\") return;\n return { left: args[0] as unknown, operator, right: args[1] as unknown };\n}\n\n/** Decode only two-operand comparisons; all other conditions keep the full editor. */\nexport function readComparison(value: unknown): ConditionComparison | undefined {\n if (!object(value) || Object.keys(value).length !== 1) return;\n return comparisonOf(value.$expr);\n}\n\n/**\n * Decode a condition the builder can show: one comparison, or an `and` / `or` / `xor` of\n * comparisons. Anything else (a nested group, another operator) is `undefined`, and the\n * editor keeps the code view for it.\n */\nexport function readConditionGroup(value: unknown): ConditionGroup | undefined {\n const single = readComparison(value);\n if (single) return { combinator: \"and\", rows: [single] };\n if (!object(value) || Object.keys(value).length !== 1 || !object(value.$expr)) return;\n const entries = Object.entries(value.$expr);\n if (entries.length !== 1) return;\n const [combinator, args] = entries[0];\n if (!Object.hasOwn(combinatorLabels, combinator) || !Array.isArray(args) || args.length === 0) {\n return;\n }\n const rows = args.map((arg) => comparisonOf(arg));\n if (rows.some((row) => row === undefined)) return;\n return {\n combinator: combinator as ConditionCombinator,\n rows: rows as ConditionComparison[],\n };\n}\n\n/**\n * The stored condition for a builder group. A row with no field is still being written and\n * is left out; no complete row is `false`, one is that comparison alone (the shape a\n * one-row condition always had), more are joined by the combinator.\n */\nexport function writeConditionGroup(group: ConditionGroup): unknown {\n const rows = group.rows\n .filter((row) => row.left !== \"\")\n .map((row) => {\n const comparison =\n row.operator === \"is-true\" || row.operator === \"is-false\"\n ? { \"===\": [row.left, row.operator === \"is-true\"] }\n : { [row.operator]: [row.left, row.right] };\n return row.negated ? { \"!\": [comparison] } : comparison;\n });\n if (rows.length === 0) return false;\n return { $expr: rows.length === 1 ? rows[0] : { [group.combinator]: rows } };\n}\n\n/** Typed scalar or JSON array input. Quotes preserve text that looks like a typed value. */\nexport function conditionOperandValue(value: string | ExprValue | SecretValue): unknown {\n if (typeof value === \"string\") {\n try {\n const parsed = JSON.parse(value);\n if (\n parsed === null ||\n Array.isArray(parsed) ||\n [\"string\", \"number\", \"boolean\"].includes(typeof parsed)\n )\n return parsed;\n } catch {\n /* Ordinary text is already a literal value. */\n }\n }\n const parts =\n typeof value === \"string\"\n ? parseResolvableText(value)\n : isExprValue(value)\n ? value.parts\n : null;\n if (parts) {\n const operands = parts.map((part) => {\n if (part.kind === \"expr\") return part.expr;\n if (part.kind === \"var\") return { var: part.ref };\n if (part.kind === \"secret\") return { var: `secrets.${part.ref}` };\n return part.value ?? \"\";\n });\n return operands.length === 1 ? operands[0] : { cat: operands };\n }\n\n return value;\n}\n\nexport function conditionOperandText(value: unknown): string {\n if (typeof value === \"string\") {\n // Escape strings that would otherwise be interpreted as a typed value or a reference.\n return conditionOperandValue(value) === value ? value : JSON.stringify(value);\n }\n if (object(value)) {\n if (Object.keys(value).length === 1 && typeof value.var === \"string\") {\n return serializeTemplate([{ kind: \"var\", ref: value.var }]);\n }\n return serializeTemplate([{ kind: \"expr\", expr: value }]);\n }\n return JSON.stringify(value) ?? \"\";\n}\n","import { useRef, useState } from \"react\";\nimport { ParamsForm } from \"./ParamsForm.tsx\";\nimport { ExpressionInput } from \"./components/ExpressionInput.tsx\";\nimport { useExpressionOptions } from \"./components/ExpressionOptions.tsx\";\nimport { Icon } from \"./components/Icon.tsx\";\nimport {\n CONDITION_COMBINATORS,\n CONDITION_OPERATORS,\n CONDITION_OPERATOR_HINTS,\n type ConditionCombinator,\n type ConditionComparison,\n type ConditionGroup,\n conditionOperandText,\n conditionOperandValue,\n readConditionGroup,\n writeConditionGroup,\n} from \"./condition-editor.ts\";\n\nconst EMPTY_ROW: ConditionComparison = {\n left: \"\",\n operator: \"is-true\",\n right: true,\n};\nconst EMPTY_GROUP: ConditionGroup = { combinator: \"and\", rows: [EMPTY_ROW] };\nconst same = (a: unknown, b: unknown) => JSON.stringify(a) === JSON.stringify(b);\n\n/**\n * The standard expression textbox on either side of each comparison row, the rows joined by\n * one combinator (all of / any of / exactly one of). A condition the rows cannot express\n * (a nested group, another operator) opens in the code view.\n */\nexport function ConditionEditor({\n values,\n onChange,\n readOnly,\n purpose = \"if\",\n}: {\n values: Record<string, unknown>;\n onChange: (values: Record<string, unknown>) => void;\n readOnly?: boolean;\n purpose?: \"if\" | \"stop\" | \"router\";\n}) {\n const options = useExpressionOptions();\n const condition = values.condition === undefined ? true : values.condition;\n const parsed = readConditionGroup(condition);\n const [advanced, setAdvanced] = useState(false);\n // The rows as edited. They can hold what the stored condition cannot (a row with no field\n // yet), so they stand in for it while they still compile to it; anything else changed the\n // condition from outside (the code view, undo) and is read back from the value.\n const [draft, setDraft] = useState<ConditionGroup>(parsed ?? EMPTY_GROUP);\n // Stable row keys, so removing a middle row never hands its neighbour's input state over.\n const nextKey = useRef(0);\n const [keys, setKeys] = useState<number[]>(() => draft.rows.map(() => nextKey.current++));\n const simple = parsed !== undefined || typeof condition === \"boolean\";\n const group = same(writeConditionGroup(draft), condition) ? draft : (parsed ?? EMPTY_GROUP);\n const rowKeys = group.rows.map((_, i) => keys[i] ?? -1 - i);\n const emit = (next: ConditionGroup, nextKeys = rowKeys) => {\n setDraft(next);\n setKeys(nextKeys);\n onChange({ ...values, condition: writeConditionGroup(next) });\n };\n const changeRow = (index: number, patch: Partial<ConditionComparison>) =>\n emit({\n ...group,\n rows: group.rows.map((row, i) => (i === index ? { ...row, ...patch } : row)),\n });\n const addRow = () =>\n emit({ ...group, rows: [...group.rows, EMPTY_ROW] }, [...rowKeys, nextKey.current++]);\n const removeRow = (index: number) =>\n emit(\n { ...group, rows: group.rows.filter((_, i) => i !== index) },\n rowKeys.filter((_, i) => i !== index),\n );\n const multiple = group.rows.length > 1;\n return (\n <div className=\"w6w-condition-editor\">\n {advanced || !simple ? (\n <ParamsForm\n params={[\n {\n key: \"condition\",\n label: \"Condition\",\n type: \"json\",\n required: true,\n },\n ]}\n values={values}\n onChange={onChange}\n readOnly={readOnly}\n />\n ) : (\n <div className=\"w6w-condition-rows\">\n {multiple && (\n <select\n className=\"w6w-condition-comparison w6w-condition-combinator\"\n aria-label=\"Combine conditions\"\n disabled={readOnly}\n value={group.combinator}\n onChange={(event) =>\n emit({\n ...group,\n combinator: event.target.value as ConditionCombinator,\n })\n }\n >\n {CONDITION_COMBINATORS.map(([combinator, label]) => (\n <option key={combinator} value={combinator}>\n {label}\n </option>\n ))}\n </select>\n )}\n {group.rows.map((row, index) => {\n const booleanCheck = row.operator === \"is-true\" || row.operator === \"is-false\";\n return (\n <div\n key={rowKeys[index]}\n className={`w6w-condition-row${multiple ? \" w6w-condition-row-removable\" : \"\"}${booleanCheck ? \" w6w-condition-row-boolean\" : \"\"}`}\n >\n <label className=\"w6w-condition-negate\" title=\"Reverse this condition's result\">\n <input\n type=\"checkbox\"\n aria-label={`Negate condition ${index + 1}`}\n checked={row.negated ?? false}\n disabled={readOnly}\n onChange={(event) => changeRow(index, { negated: event.target.checked })}\n />\n Not\n </label>\n <ExpressionInput\n value={conditionOperandText(row.left)}\n aria-label=\"Condition field\"\n placeholder=\"Field or expression\"\n readOnly={readOnly}\n onChange={(value) => changeRow(index, { left: conditionOperandValue(value) })}\n />\n <select\n className=\"w6w-condition-comparison\"\n aria-label=\"Condition comparison\"\n title={CONDITION_OPERATOR_HINTS[row.operator]}\n disabled={readOnly}\n value={row.operator}\n onChange={(event) =>\n changeRow(index, {\n operator: event.target.value,\n right:\n event.target.value === \"is-true\"\n ? true\n : event.target.value === \"is-false\"\n ? false\n : booleanCheck\n ? \"\"\n : row.right,\n })\n }\n >\n {CONDITION_OPERATORS.map(([op, label]) => (\n <option key={op} value={op} title={CONDITION_OPERATOR_HINTS[op]}>\n {label}\n </option>\n ))}\n </select>\n {!booleanCheck && (\n <ExpressionInput\n value={conditionOperandText(row.right)}\n aria-label=\"Condition value\"\n placeholder=\"Value or expression\"\n readOnly={readOnly}\n onChange={(value) => changeRow(index, { right: conditionOperandValue(value) })}\n />\n )}\n {multiple && !readOnly && (\n <button\n type=\"button\"\n className=\"w6w-icon-btn w6w-condition-remove\"\n title=\"Remove condition\"\n aria-label={`Remove condition ${index + 1}`}\n onClick={() => removeRow(index)}\n >\n <Icon name=\"trash\" size={14} />\n </button>\n )}\n </div>\n );\n })}\n {!readOnly && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm w6w-condition-add\"\n onClick={addRow}\n >\n + Add condition\n </button>\n )}\n <p className=\"w6w-muted w6w-small\">\n Not reverses a condition. Type true or false without quotes for booleans; use quotes for\n text.\n </p>\n {[...new Set(group.rows.map((row) => row.operator))].map((operator) =>\n CONDITION_OPERATOR_HINTS[operator] ? (\n <p key={operator} className=\"w6w-muted w6w-small\">\n {CONDITION_OPERATOR_HINTS[operator]}\n </p>\n ) : null,\n )}\n </div>\n )}\n {simple && (\n <button\n type=\"button\"\n className=\"w6w-icon-btn w6w-condition-mode\"\n title={advanced ? \"Use comparison fields\" : \"Edit condition expression\"}\n aria-label={advanced ? \"Use comparison fields\" : \"Edit condition expression\"}\n onClick={() => setAdvanced(!advanced)}\n >\n <Icon name={advanced ? \"form\" : \"code\"} size={14} />\n </button>\n )}\n {purpose !== \"router\" && (\n <p className=\"w6w-muted w6w-small\">\n {purpose === \"stop\"\n ? \"End the workflow when this condition is true.\"\n : options.loop\n ? \"When false, skip the remaining steps for this item.\"\n : \"Continue when this condition is true.\"}\n </p>\n )}\n </div>\n );\n}\n","import type { FlowStep } from \"./flow-types.ts\";\n\n/** Who this retry policy applies to — picks the helper line's wording. */\nexport type RetryTarget = \"step\" | \"function\" | \"endpoint\" | \"workflow\";\n\n/** The persisted retry shape (core `rfcs/node-types.md`), minus the `undefined` case. */\nexport type RetryPolicyValue = NonNullable<FlowStep[\"retry\"]>;\n\nconst HELPER_TEXT: Record<RetryTarget, string> = {\n step: \"Re-run this step if it fails, up to N attempts.\",\n function: \"Re-run this function call if it fails, up to N attempts.\",\n endpoint: \"Re-run this endpoint call if it fails, up to N attempts.\",\n workflow: \"Re-run the whole workflow run if it fails, up to N attempts.\",\n};\n\n/**\n * The \"Retry on failure\" checkbox + helper line + Attempts/Delay (ms)/Backoff\n * row — the one retry shape shared by every host that can offer a retry\n * policy (core rfcs/R-2 \"one retry shape everywhere\"). `value` is the\n * persisted policy or `undefined` for \"no retry\"; `target` only changes the\n * helper line's wording, never the behavior.\n */\nexport function RetryPolicyFields({\n value,\n onChange,\n readOnly,\n target = \"step\",\n}: {\n value: RetryPolicyValue | undefined;\n onChange: (next: RetryPolicyValue | undefined) => void;\n readOnly?: boolean;\n target?: RetryTarget;\n}) {\n const retryOn = !!value;\n const attempts = value?.maxAttempts ?? 3;\n const delayMs = value?.delayMs ?? 1000;\n const backoff = value?.backoff ?? \"fixed\";\n\n const setRetry = (patch: Partial<RetryPolicyValue>) =>\n onChange({ maxAttempts: attempts, delayMs, backoff, ...value, ...patch });\n\n return (\n <>\n <label className=\"w6w-field\">\n <span>\n <input\n type=\"checkbox\"\n checked={retryOn}\n disabled={readOnly}\n onChange={(e) =>\n onChange(e.target.checked ? { maxAttempts: attempts, delayMs, backoff } : undefined)\n }\n />{\" \"}\n Retry on failure\n </span>\n <span className=\"w6w-hint\">{HELPER_TEXT[target]}</span>\n </label>\n {retryOn && (\n <div className=\"w6w-field-row\">\n <label className=\"w6w-field\">\n <span>Attempts</span>\n <input\n type=\"number\"\n min={1}\n value={attempts}\n readOnly={readOnly}\n onChange={(e) => setRetry({ maxAttempts: Math.max(1, Number(e.target.value) || 1) })}\n />\n </label>\n <label className=\"w6w-field\">\n <span>Delay (ms)</span>\n <input\n type=\"number\"\n min={0}\n value={delayMs}\n readOnly={readOnly}\n onChange={(e) => setRetry({ delayMs: Math.max(0, Number(e.target.value) || 0) })}\n />\n </label>\n <label className=\"w6w-field\">\n <span>Backoff</span>\n <select\n value={backoff}\n disabled={readOnly}\n onChange={(e) => setRetry({ backoff: e.target.value as \"fixed\" | \"exponential\" })}\n >\n <option value=\"fixed\">Fixed</option>\n <option value=\"exponential\">Exponential</option>\n </select>\n </label>\n </div>\n )}\n </>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { RetryPolicyFields } from \"./RetryPolicyFields.tsx\";\nimport type { FlowStep } from \"./flow-types.ts\";\n\n/** The base, always-available node settings — independent of the action's params. */\nexport type NodeConfig = Pick<FlowStep, \"retry\" | \"onError\" | \"notes\">;\n\n/**\n * A stable reference over a Function or a Workflow (core rfcs/endpoint.md ·\n * CallableRef). Declared **locally** — structurally identical to\n * `@w6w/workflow-types`'s `CallableRef` — because `@w6w/ui` has no dependency edge\n * to that package and must not gain one (D-10).\n */\nexport type CallableRef =\n | { kind: \"function\"; function: string }\n | { kind: \"workflow\"; workflow: string };\n\n/**\n * Node settings form: retry-on-fail, error handling, and notes. Operates on a\n * plain {@link NodeConfig} so it's shared by the add-a-step config and the node\n * editor (all fields optional; absent = defaults).\n *\n * `hasGraph` and `reroute` are ADDITIVE (D-10, F-2.1): a graph-less host — a\n * Function or an Endpoint, which has no canvas and so can never author an\n * `Edge.when: \"error\"` — passes `hasGraph={false}` and supplies `reroute` so a\n * failure can still be redirected somewhere. Both are omitted by every\n * existing caller, so `NodeConfig` itself and every pre-existing render path\n * are unchanged.\n */\nexport function NodeConfigForm({\n config,\n onChange,\n readOnly,\n hasGraph = true,\n failureHandling = true,\n retryControls = true,\n reroute,\n}: {\n config: NodeConfig;\n onChange: (next: NodeConfig) => void;\n readOnly?: boolean;\n /**\n * `false` for a graph-less host. Swaps the \"outgoing error edge\" hint for a\n * sentence about the `reroute` field, and drops `continue-record` from the\n * `onError` select — `continue-record` writes to a run's `stepErrors`, which\n * a Function/Endpoint invocation has none of. Default `true` reproduces\n * today's behavior byte-identically.\n */\n hasGraph?: boolean;\n /**\n * `false` for a node that cannot fail on its own — today only a trigger,\n * which is the run's ENTRY rather than a step that acts: it emits the start\n * payload, makes no vendor call, and so has nothing to retry and no failure\n * to police (human report, 2026-09-01). Drops the retry and \"On error\"\n * controls; Notes stay. Default `true` reproduces today's behavior\n * byte-identically.\n */\n failureHandling?: boolean;\n /**\n * `false` omits only the \"Retry on failure\" block — \"On error\" and Notes are\n * unaffected. Used by a host whose step can never retry on its own (a\n * `@w6w/call`/`@w6w/control` step; core rfcs/workflow.md \"Retries come\n * first\"). Default `true` reproduces today's markup byte-identically.\n */\n retryControls?: boolean;\n /**\n * Failure re-dispatch — a `CallableRef`, rendered only when supplied. `value`/\n * `onChange` are the host's own state (so it can offer a \"clear\" affordance);\n * `picker` is a slot the host renders its own selection control into — this\n * component never reaches for anything outside `{retry, onError, notes,\n * reroute}`, so it still has no view of the app/workflow catalog itself.\n */\n reroute?: {\n value: CallableRef | undefined;\n onChange: (next: CallableRef | undefined) => void;\n picker: ReactNode;\n };\n}) {\n const onError = config.onError ?? \"fail\";\n\n return (\n <div className=\"w6w-stack\">\n {failureHandling && (\n <>\n {retryControls && (\n <RetryPolicyFields\n value={config.retry}\n onChange={(retry) => onChange({ ...config, retry })}\n readOnly={readOnly}\n />\n )}\n\n {/* Error handling */}\n <label className=\"w6w-field\">\n <span>On error</span>\n <select\n value={onError}\n disabled={readOnly}\n onChange={(e) => {\n const v = e.target.value as NonNullable<NodeConfig[\"onError\"]>;\n // \"fail\" is the default — store it as absent to keep the step clean.\n onChange({ ...config, onError: v === \"fail\" ? undefined : v });\n }}\n >\n <option value=\"fail\">Stop the run (default)</option>\n <option value=\"continue\">Continue to the next step</option>\n {hasGraph && (\n <option value=\"continue-record\">\n Continue to the next step &amp; record the error\n </option>\n )}\n </select>\n {hasGraph ? (\n // This select reads as if it had total authority over failure, and since\n // an error edge became authorable it no longer does: per D-T1-3 an\n // outgoing error edge OVERRIDES this policy. The honest fix is a static\n // hint — this form receives only `{ retry, onError, notes }` (plus the\n // additive `reroute` below) and has no view of the graph, so it cannot\n // know whether the step has such an edge, and giving it one just to\n // find out is out of scope.\n //\n // Ordering per rfcs/workflow.md's Amendment — 2026-07-29 (failure-\n // conditioned edges): retries come first (only a *finally* failed\n // attempt reaches this policy at all); Continue/Continue & record\n // both carry on down this step's normal outgoing edges despite the\n // failure; an outgoing error edge overrides all of the above. The\n // drag gesture named below is the SAME one `LANE_HINT` (T1.1.1)\n // describes for the error exit port — not re-derived here.\n <span className=\"w6w-muted w6w-small\">\n Retries run first: this policy is reached only once this step's retry attempts (if\n any) are exhausted — a run that succeeds on a later attempt continues down the\n normal path instead. Once reached, <strong>Continue</strong> and{\" \"}\n <strong>Continue &amp; record the error</strong> both carry on down this step's\n ordinary outgoing edges despite the failure. If this step has an outgoing{\" \"}\n <strong>error</strong> edge on the canvas, that edge decides what happens instead\n and this policy is not consulted — drawn by dragging from the step's error exit\n port.\n </span>\n ) : (\n // Graph-less host: there is no canvas and so no error edge to draw —\n // the reroute field below is this host's equivalent. Must not\n // contradict the graph arm above: retries still come first here too.\n <span className=\"w6w-muted w6w-small\">\n Retries run first: this policy (and reroute, below) is only reached once this step's\n retry attempts (if any) are exhausted — a run that succeeds on a later attempt\n continues normally. This step has no canvas of its own, so it can't carry an error\n edge. Set a <strong>reroute</strong> target below to send a failure somewhere else\n instead of stopping.\n </span>\n )}\n </label>\n </>\n )}\n\n {/* Reroute on failure — graph-less hosts only (additive; see `reroute`).\n A `<div>`, not a `<label>`: `picker` is the host's own control (of\n unknown shape), so there is no single form element to associate a\n label with here. */}\n {reroute && (\n <div className=\"w6w-field\">\n <span>Reroute on failure</span>\n <div className=\"w6w-field-row\">\n {reroute.picker}\n {reroute.value && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n disabled={readOnly}\n onClick={() => reroute.onChange(undefined)}\n >\n Clear\n </button>\n )}\n </div>\n <span className=\"w6w-hint\">\n Invoked once, after retry is exhausted, if this step still fails; its output becomes\n this step's output.\n </span>\n </div>\n )}\n\n {/* Notes — shown under the step's own card on the canvas (2026-08-30),\n not just here, so a description written once helps a reader orient\n without opening every step. */}\n <label className=\"w6w-field\">\n <span>Notes</span>\n <textarea\n rows={3}\n value={config.notes ?? \"\"}\n readOnly={readOnly}\n placeholder=\"A short description — shown under this step on the canvas. Not executed.\"\n onChange={(e) => onChange({ ...config, notes: e.target.value || undefined })}\n />\n </label>\n </div>\n );\n}\n","import { parseResolvableText } from \"./components/expression-template.ts\";\nimport { wholeValueRef } from \"./components/json-compose.ts\";\nimport { type ResolveScope, isDollarExpr, isDollarPath } from \"./resolve-params.ts\";\nimport { resolveParamJson } from \"./resolved-json.ts\";\nimport { isExprValue, isSecretValue } from \"./types.ts\";\n\n/** Authored JSON customization is kept apart from the editable form values. */\nexport function hasParamCustomization(values: Record<string, unknown>): boolean {\n return values.$merge !== undefined;\n}\n\n/** null: invalid; undefined: a binding whose fields can only be checked at runtime. */\nexport function customizedParamValues(\n values: Record<string, unknown>,\n): Record<string, unknown> | undefined | null {\n const custom = values.$merge;\n if (custom === undefined) return values;\n if (\n wholeValueRef(custom) ||\n isExprValue(custom) ||\n isDollarExpr(custom) ||\n (typeof custom === \"string\" && parseResolvableText(custom))\n )\n return undefined;\n if (\n custom &&\n typeof custom === \"object\" &&\n !Array.isArray(custom) &&\n !isSecretValue(custom) &&\n !(\"$merge\" in custom)\n ) {\n return { ...values, ...custom };\n }\n return null;\n}\n\n/** Resolve authored children only. A substituted object is data, not another template. */\nexport function previewCustomization(\n value: unknown,\n scope: ResolveScope,\n literalKeys: readonly string[] = [],\n): unknown {\n if (\n isExprValue(value) ||\n isSecretValue(value) ||\n isDollarPath(value) ||\n isDollarExpr(value) ||\n value === null ||\n typeof value !== \"object\"\n )\n return resolveParamJson(value, scope);\n const child = (v: unknown): unknown => previewCustomization(v, scope);\n if (Array.isArray(value)) return value.map(child);\n return Object.fromEntries(\n Object.entries(value).map(([key, v]) => [key, literalKeys.includes(key) ? v : child(v)]),\n );\n}\n","import { ParamsForm } from \"./ParamsForm.tsx\";\nimport { customizedParamValues, hasParamCustomization } from \"./param-customization.ts\";\n\nexport function ParamCustomization({\n values,\n onChange,\n readOnly,\n}: {\n values: Record<string, unknown>;\n onChange: (values: Record<string, unknown>) => void;\n readOnly?: boolean;\n}) {\n return (\n <div className=\"w6w-stack\">\n <p className=\"w6w-muted w6w-small\">\n Form values are applied first. This object adds or replaces top-level fields, including\n nested objects. Use ƒx to reuse an object from state or a previous step. You can still edit\n the form.\n </p>\n <ParamsForm\n params={[\n {\n key: \"$merge\",\n label: \"JSON customization\",\n type: \"json\",\n required: true,\n default: {},\n whole: true,\n },\n ]}\n values={values}\n onChange={onChange}\n readOnly={readOnly}\n />\n {customizedParamValues(values) === null && (\n <p role=\"alert\" className=\"w6w-field-error\">\n JSON customization must be an object or an expression that returns an object.\n </p>\n )}\n {!readOnly && hasParamCustomization(values) && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n onClick={() => {\n const { $merge: _customization, ...base } = values;\n onChange(base);\n }}\n >\n Remove JSON customization\n </button>\n )}\n </div>\n );\n}\n","import type { KeyboardEventHandler } from \"react\";\nimport type { AuthField } from \"../types.ts\";\n\ninterface Props {\n fields: AuthField[];\n values: Record<string, unknown>;\n onChange: (values: Record<string, unknown>) => void;\n /**\n * Spread onto every field's `<input>` — from the caller's own\n * `useEnterSubmit(submit, { enabled })`, so Enter in a credential field\n * submits the same way the form's primary button does. Optional so this\n * component still works with no submit-on-Enter wiring at all.\n */\n enterSubmitProps?: { onKeyDown: KeyboardEventHandler<HTMLElement> };\n /**\n * `\"create\"` (default) seeds each field from its manifest `default`. `\"edit\"` is for replacing\n * part of a stored credential: it never seeds `default`, gives secret inputs the placeholder\n * `•••••• (unchanged)`, and reports an emptied number input as `\"\"` (not `0`) so the caller can\n * treat blank as \"keep what is stored\".\n */\n mode?: \"create\" | \"edit\";\n}\n\n/**\n * Parses every filled `json` field of `values` (they are held as raw text while typing). Returns\n * the values with those fields parsed, or an `error` naming the offending field by label. The\n * error NEVER contains the typed text or the parser's message (which can quote it): a pasted key\n * file that is almost valid must not be echoed back into the page.\n */\nexport function parseJsonFields(\n fields: AuthField[],\n values: Record<string, unknown>,\n): { values: Record<string, unknown> } | { error: string } {\n const out: Record<string, unknown> = { ...values };\n for (const f of fields) {\n const v = values[f.key];\n if (f.type !== \"json\" || typeof v !== \"string\" || v.trim() === \"\") continue;\n try {\n out[f.key] = JSON.parse(v);\n } catch {\n return { error: `${f.label} is not valid JSON. Check it and try again.` };\n }\n }\n return { values: out };\n}\n\n/**\n * Renders the form for an Auth method's `fields` declaration. Field shape\n * comes from the app's manifest so no app-specific knowledge is needed here.\n */\nexport function AuthFieldsForm({\n fields,\n values,\n onChange,\n enterSubmitProps,\n mode = \"create\",\n}: Props) {\n const update = (key: string, value: unknown) => onChange({ ...values, [key]: value });\n\n return (\n <div className=\"w6w-stack\">\n {fields.length === 0 && (\n <p className=\"w6w-muted w6w-small\">\n This auth method declares no fields — nothing to fill in. The credential will be an empty\n object.\n </p>\n )}\n {fields.map((field) => {\n const edit = mode === \"edit\";\n const value = (values[field.key] ?? (edit ? undefined : field.default) ?? \"\") as\n | string\n | number\n | boolean;\n if (field.type === \"boolean\") {\n return (\n <label key={field.key} className=\"w6w-field\">\n <span>\n <input\n type=\"checkbox\"\n checked={Boolean(value)}\n onChange={(e) => update(field.key, e.target.checked)}\n {...enterSubmitProps}\n />\n {field.label}\n {field.required ? \" *\" : \"\"}\n </span>\n {field.hint && <span className=\"w6w-hint\">{field.hint}</span>}\n </label>\n );\n }\n const isSecret = field.type === \"secret\" || field.secret === true;\n if (field.type === \"json\" || field.type === \"text\") {\n // A plain textarea, deliberately not the step builder's JSON param editor, which offers\n // expression bindings, and a credential must never be bound to a run-time value. The raw\n // text is held as typed; callers parse `json` fields at submit (see `parseJsonFields`).\n // Enter inserts a newline, so it is not wired to submit.\n return (\n <label key={field.key} className=\"w6w-field\">\n <span>\n {field.label}\n {field.required ? \" *\" : \"\"}\n </span>\n <textarea\n className={isSecret ? \"w6w-secret-input\" : undefined}\n rows={field.type === \"json\" ? 6 : 3}\n value={String(value ?? \"\")}\n placeholder={edit && isSecret ? \"•••••• (unchanged)\" : undefined}\n onChange={(e) => update(field.key, e.target.value)}\n name={`w6w-cred-${field.key}`}\n autoComplete=\"off\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n data-1p-ignore=\"true\"\n data-lpignore=\"true\"\n data-bwignore=\"true\"\n data-form-type=\"other\"\n />\n {field.hint && <span className=\"w6w-hint\">{field.hint}</span>}\n </label>\n );\n }\n // Credentials (API keys, tokens) are NOT login passwords. Never use\n // `type=\"password\"` — that's the sole trigger for the browser's\n // \"save password?\" prompt and for suggesting saved passwords. Secrets are\n // plain text fields masked with CSS (`-webkit-text-security`) so they\n // still read as dots without ever being a password field.\n const inputType = field.type === \"number\" ? \"number\" : \"text\";\n return (\n <label key={field.key} className=\"w6w-field\">\n <span>\n {field.label}\n {field.required ? \" *\" : \"\"}\n </span>\n <input\n type={inputType}\n className={isSecret ? \"w6w-secret-input\" : undefined}\n value={String(value ?? \"\")}\n placeholder={edit && isSecret ? \"•••••• (unchanged)\" : undefined}\n onChange={(e) =>\n update(\n field.key,\n field.type === \"number\" && !(edit && e.target.value === \"\")\n ? Number(e.target.value)\n : e.target.value,\n )\n }\n // Belt-and-braces opt-out from browser autofill + password managers.\n name={`w6w-cred-${field.key}`}\n autoComplete=\"off\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n data-1p-ignore=\"true\"\n data-lpignore=\"true\"\n data-bwignore=\"true\"\n data-form-type=\"other\"\n {...enterSubmitProps}\n />\n {field.hint && <span className=\"w6w-hint\">{field.hint}</span>}\n </label>\n );\n })}\n </div>\n );\n}\n","import type {\n AuthField,\n ConnectionBinding,\n CredentialSummary,\n ServiceAccountConfig,\n} from \"../types.ts\";\n\nexport interface CredentialPickerProps {\n /** Credentials to offer. Pass them already filtered; this component renders them as given. */\n credentials: CredentialSummary[];\n /** `\"existing\"` picks one of `credentials`; `\"new\"` is for the caller's create form. */\n mode: \"existing\" | \"new\";\n onModeChange: (mode: \"existing\" | \"new\") => void;\n /** The chosen credential id (`\"\"` for none). Only used in `\"existing\"` mode. */\n selectedId: string;\n onSelect: (id: string) => void;\n /** False hides the \"Use existing\" choice (nothing to choose from). Default true. */\n canUseExisting?: boolean;\n /** The contract the credential must satisfy, shown as a hint. */\n contract?: string;\n}\n\n/**\n * The Use existing / Create new switch of a connection's Credential step, plus the list of stored\n * credentials. Presentational: no API access, no state of its own. Each option shows the\n * credential's name and its non-secret `display` values, never a payload. The \"Create new\" form\n * itself (name + fields) is the caller's, rendered beneath this.\n */\nexport function CredentialPicker({\n credentials,\n mode,\n onModeChange,\n selectedId,\n onSelect,\n canUseExisting = true,\n contract,\n}: CredentialPickerProps) {\n const label = (c: CredentialSummary) => {\n const shown = Object.values(c.display ?? {}).filter(Boolean);\n return shown.length > 0 ? `${c.name} (${shown.join(\", \")})` : c.name;\n };\n return (\n <div className=\"w6w-stack\">\n {canUseExisting && (\n <div className=\"w6w-field\" role=\"radiogroup\" aria-label=\"Credential\">\n <span>Credential{contract ? ` (${contract})` : \"\"}</span>\n <label>\n <input\n type=\"radio\"\n name=\"w6w-credential-mode\"\n checked={mode === \"existing\"}\n onChange={() => onModeChange(\"existing\")}\n />{\" \"}\n Use existing\n </label>\n <label>\n <input\n type=\"radio\"\n name=\"w6w-credential-mode\"\n checked={mode === \"new\"}\n onChange={() => onModeChange(\"new\")}\n />{\" \"}\n Create new\n </label>\n </div>\n )}\n {canUseExisting && mode === \"existing\" && (\n <label className=\"w6w-field\">\n <span>Stored credential</span>\n <select\n name=\"w6w-credential-id\"\n value={selectedId}\n onChange={(e) => onSelect(e.target.value)}\n >\n {credentials.map((c) => (\n <option key={c.id} value={c.id}>\n {label(c)}\n </option>\n ))}\n </select>\n </label>\n )}\n </div>\n );\n}\n\n/**\n * The binding fields a `serviceAccount` auth asks for on a connection. `delegatedUser` is always\n * labelled \"Impersonated user\" (the person the credential acts as, never the connection's owner),\n * is absent when impersonation is `\"none\"` even if declared, and is synthesised when impersonation\n * is allowed but the auth declares no such field.\n */\nexport function bindingFieldsFor(sa: ServiceAccountConfig): AuthField[] {\n const others = (sa.bindingFields ?? []).filter((f) => f.key !== \"delegatedUser\");\n if (sa.impersonation === \"none\") return others;\n const declared = (sa.bindingFields ?? []).find((f) => f.key === \"delegatedUser\");\n const delegated: AuthField = {\n ...(declared ?? { type: \"string\" }),\n key: \"delegatedUser\",\n label: \"Impersonated user\",\n type: \"string\",\n required: sa.impersonation === \"required\",\n };\n return [delegated, ...others];\n}\n\n/**\n * Maps typed binding values to the wire `binding`: `delegatedUser` stays top-level, every other key\n * goes under `settings`, blank values are dropped, and an empty result is `undefined`. `scopes` is\n * never sent (the server applies the auth's declared scopes).\n */\nexport function buildBinding(\n fields: AuthField[],\n values: Record<string, unknown>,\n): ConnectionBinding | undefined {\n const binding: ConnectionBinding = {};\n const settings: Record<string, string | number | boolean> = {};\n for (const f of fields) {\n const v = values[f.key];\n if (v === undefined || v === null || v === \"\") continue;\n if (f.key === \"delegatedUser\") binding.delegatedUser = String(v);\n else settings[f.key] = v as string | number | boolean;\n }\n if (Object.keys(settings).length > 0) binding.settings = settings;\n return Object.keys(binding).length > 0 ? binding : undefined;\n}\n","/**\n * Open an OAuth 2.0 authorize URL in a popup and resolve when the callback\n * page posts a `w6w: \"oauth-result\"` message back to the opener.\n *\n * The server-rendered callback page (see the w6w server) posts one of:\n * { w6w: \"oauth-result\", ok: true, connectionId: string }\n * { w6w: \"oauth-result\", ok: false, error: string }\n *\n * Rejects if:\n * - The popup was blocked (`window.open` returned null).\n * - The user closed the popup without completing the flow.\n * - The server signaled failure.\n */\nexport interface OAuthPopupResult {\n connectionId: string;\n}\n\nconst POPUP_FEATURES = \"width=560,height=720,menubar=no,toolbar=no,location=no\";\n\nexport function startOAuthPopup(authorizationUrl: string): Promise<OAuthPopupResult> {\n return new Promise((resolve, reject) => {\n const popup = window.open(authorizationUrl, \"w6w-oauth\", POPUP_FEATURES);\n if (!popup) {\n reject(new Error(\"Popup blocked — allow popups for this site and try again.\"));\n return;\n }\n\n let done = false;\n const cleanup = () => {\n done = true;\n window.removeEventListener(\"message\", onMessage);\n window.clearInterval(pollHandle);\n };\n\n const onMessage = (event: MessageEvent) => {\n const data = event.data as\n | { w6w?: string; ok?: boolean; connectionId?: string; error?: string }\n | undefined;\n if (data?.w6w !== \"oauth-result\") return;\n cleanup();\n try {\n popup.close();\n } catch {\n /* popup may already be closed */\n }\n if (data.ok && typeof data.connectionId === \"string\") {\n resolve({ connectionId: data.connectionId });\n } else {\n reject(new Error(data.error ?? \"OAuth flow failed.\"));\n }\n };\n window.addEventListener(\"message\", onMessage);\n\n // If the user closes the popup without completing the flow the message\n // never arrives; detect that with a low-freq poll and reject cleanly.\n const pollHandle = window.setInterval(() => {\n if (done) return;\n if (popup.closed) {\n cleanup();\n reject(new Error(\"OAuth popup was closed before the flow completed.\"));\n }\n }, 500);\n });\n}\n","import type { KeyboardEvent, KeyboardEventHandler } from \"react\";\n\n/**\n * HTML `<input>` types that are either a multi-line control (none are — that's\n * `<textarea>`) or not a plain single-line text control: a checkbox/radio has\n * no text to \"submit\", and a native picker (date, color, range, file, …) has\n * its own Enter semantics this hook must not override.\n */\nconst NON_TEXT_INPUT_TYPES = new Set([\n \"checkbox\",\n \"radio\",\n \"button\",\n \"submit\",\n \"reset\",\n \"file\",\n \"range\",\n \"color\",\n \"image\",\n \"hidden\",\n \"date\",\n \"datetime-local\",\n \"month\",\n \"week\",\n \"time\",\n]);\n\n/**\n * Whether `target` is (or sits inside) a `contenteditable` region — checked\n * via the attribute chain rather than the `isContentEditable` DOM property,\n * which some environments (including this package's own jsdom-based unit\n * suite) never compute; the attribute is what both a real browser and jsdom\n * actually see once React renders `contentEditable`.\n */\nfunction isWithinContentEditable(target: HTMLElement): boolean {\n return target.closest('[contenteditable]:not([contenteditable=\"false\"])') !== null;\n}\n\n/**\n * Enter-to-submit for a single-line text input, one implementation mounted by\n * every form instead of each surface hand-rolling its own `onKeyDown` — see\n * `studio/src/components/ApiServerSetting.tsx:75-80` for the ad-hoc version\n * this replaces (a bare `if (e.key === \"Enter\")` with no modifier guard and no\n * check that the target is actually a single-line text field). Spread the\n * returned object onto the input: `<input {...useEnterSubmit(save)} … />`.\n *\n * Deliberately narrow: fires only for a bare `Enter` (no Shift/Alt/Ctrl/Meta,\n * and not mid-IME-composition) on an `<input>` whose `type` is a plain\n * single-line text control — never a `<textarea>`, a `contenteditable` node,\n * or a non-text `<input>` (checkbox, date picker, …), each of which has its\n * own meaning for Enter (a newline, a native widget's own key handling) that\n * this hook must not steal. `opts.enabled` is a hard off switch: pass the same\n * boolean guarding the caller's own submit button so Enter can never do\n * something the button itself refuses to do.\n */\nexport function useEnterSubmit(\n onSubmit: () => void,\n opts?: { enabled?: boolean },\n): { onKeyDown: KeyboardEventHandler<HTMLElement> } {\n return {\n onKeyDown: (e: KeyboardEvent<HTMLElement>) => {\n if (opts?.enabled === false) return;\n if (e.key !== \"Enter\") return;\n if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) return;\n if (e.nativeEvent.isComposing) return;\n const target = e.target as HTMLElement;\n if (target.tagName === \"TEXTAREA\") return;\n if (isWithinContentEditable(target)) return;\n if (\n target.tagName === \"INPUT\" &&\n NON_TEXT_INPUT_TYPES.has((target as HTMLInputElement).type)\n ) {\n return;\n }\n e.preventDefault();\n onSubmit();\n },\n };\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { AppPicker } from \"./AppPicker.tsx\";\nimport { AppIcon } from \"./components/AppIcon.tsx\";\nimport { AuthFieldsForm, parseJsonFields } from \"./components/AuthFieldsForm.tsx\";\nimport {\n CredentialPicker,\n bindingFieldsFor,\n buildBinding,\n} from \"./components/CredentialPicker.tsx\";\nimport { Modal } from \"./components/Modal.tsx\";\nimport { startOAuthPopup } from \"./oauth-popup.ts\";\nimport { useW6WApi } from \"./provider.tsx\";\nimport type {\n AppSummary,\n AuthDef,\n AuthField,\n CreateConnectionBody,\n CredentialSummary,\n ThemeMode,\n} from \"./types.ts\";\nimport { useEnterSubmit } from \"./use-enter-submit.ts\";\n\nexport interface AddConnectionModalProps {\n onClose: () => void;\n /** Fired after a successful create (both API-key and OAuth paths). */\n onCreated: (result: { connectionId: string }) => void;\n /** Optional theme hint passed through to `AppIcon` (light/dark variant). */\n theme?: ThemeMode;\n /**\n * Pre-select an app and skip the picker — used when the modal is opened for a\n * specific app (e.g. from the step builder). Omit to let the user pick.\n */\n initialAppId?: string;\n}\n\n/**\n * Add-connection modal. Same shape as the step builder's \"add a step\" modal —\n * the shared {@link AppPicker} (searchable icon grid) for step one, then the\n * chosen app's connection fields for step two — minus the tabs. Pick an app →\n * pick an auth method → fill the fields (or run OAuth) → submit. The\n * `AuthDef.fields` array drives the form, so no app-specific knowledge is baked\n * in. Data + IO come from `useW6WApi()`.\n */\nexport function AddConnectionModal(props: AddConnectionModalProps) {\n const api = useW6WApi();\n const [selectedApp, setSelectedApp] = useState<AppSummary | null>(null);\n const [resolvingInitial, setResolvingInitial] = useState<boolean>(Boolean(props.initialAppId));\n\n // Opened for a specific app: resolve it to an AppSummary (for the header) and\n // go straight to the connection fields, skipping the picker. Prefers the\n // bounded `listAppsByIds([id])` seam (A3) over a full-catalog `listApps()`\n // scan. When `listAppsByIds` exists, its result is final — found resolves to\n // that app, a miss (empty result or rejection) resolves to not-found —\n // `listApps` is NEVER called alongside it: a bounded host's \"no such id\" is\n // a real answer, not evidence the seam \"isn't really implemented\" (mirrors\n // AppPicker/useReadyToUse's own no-silent-downgrade rule, T2.1.1 ROUND 2).\n // Only when `listAppsByIds` is itself absent does this fall back to\n // `listApps`-based full-list resolution (today's pre-existing behavior);\n // with neither seam present, it resolves to not-found without ever calling\n // an undefined function.\n useEffect(() => {\n const id = props.initialAppId;\n if (!id) return;\n let canceled = false;\n const finish = (app: AppSummary | null) => {\n if (canceled) return;\n setSelectedApp(app);\n setResolvingInitial(false);\n };\n const listAppsByIds = api.listAppsByIds;\n if (listAppsByIds) {\n listAppsByIds([id])\n .then((apps) => finish(apps.find((a) => a.id === id) ?? null))\n .catch(() => finish(null));\n return () => {\n canceled = true;\n };\n }\n const listApps = api.listApps;\n if (typeof listApps === \"function\") {\n listApps()\n .then((apps) => finish(apps.find((a) => a.id === id) ?? null))\n .catch(() => finish(null));\n } else {\n finish(null);\n }\n return () => {\n canceled = true;\n };\n }, [api, props.initialAppId]);\n\n // Step two: the chosen app's connection fields.\n if (selectedApp) {\n return (\n <Modal\n title={selectedApp.displayName}\n subtitle={\n <>\n <code>{selectedApp.id}</code>\n {selectedApp.version && ` · v${selectedApp.version}`}\n </>\n }\n onClose={props.onClose}\n size=\"xl\"\n titleIcon={\n <AppIcon\n src={selectedApp.iconSvg}\n srcDark={selectedApp.iconSvgDark}\n brandColor={selectedApp.brandColor}\n name={selectedApp.displayName}\n theme={props.theme}\n size={22}\n />\n }\n headerRight={\n props.initialAppId ? undefined : (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n onClick={() => setSelectedApp(null)}\n >\n ← Apps\n </button>\n )\n }\n >\n <ConnectionConfig app={selectedApp} onCreated={props.onCreated} onClose={props.onClose} />\n </Modal>\n );\n }\n\n // Resolving an initialAppId — don't flash the picker.\n if (resolvingInitial) {\n return (\n <Modal title=\"Add connection\" onClose={props.onClose} size=\"xl\">\n <div className=\"w6w-stepbuilder-content\">\n <p className=\"w6w-muted w6w-small\">Loading…</p>\n </div>\n </Modal>\n );\n }\n\n // Step one: the shared searchable app picker (icons + search).\n return (\n <Modal title=\"Add connection\" onClose={props.onClose} size=\"xl\">\n <div className=\"w6w-stepbuilder-content\">\n <AppPicker\n onSelectApp={setSelectedApp}\n theme={props.theme}\n searchPlaceholder=\"Search apps to connect…\"\n categoryFilter\n />\n </div>\n </Modal>\n );\n}\n\n/**\n * The chosen app's connection form: pick an auth method (when >1), name the\n * connection, fill the credential fields (or run OAuth), and submit.\n */\nfunction ConnectionConfig({\n app,\n onCreated,\n onClose,\n}: {\n app: AppSummary;\n onCreated: (result: { connectionId: string }) => void;\n onClose: () => void;\n}) {\n const api = useW6WApi();\n const [auths, setAuths] = useState<AuthDef[] | null>(null);\n const [authKey, setAuthKey] = useState<string>(\"\");\n const [displayName, setDisplayName] = useState(\"\");\n const [credential, setCredential] = useState<Record<string, unknown>>({});\n const [error, setError] = useState<string | null>(null);\n const [pending, setPending] = useState(false);\n // Credential step (serviceAccount auths only). `createdId` survives a failed connection call so a\n // retry attaches the credential already stored instead of storing a second copy.\n const [stored, setStored] = useState<CredentialSummary[] | null>(null);\n const [pickedMode, setPickedMode] = useState<\"existing\" | \"new\" | null>(null);\n const [selectedId, setSelectedId] = useState(\"\");\n const [credName, setCredName] = useState(\"\");\n const [bindingVals, setBindingVals] = useState<Record<string, unknown>>({});\n const createdId = useRef<string | null>(null);\n\n useEffect(() => {\n let canceled = false;\n setAuths(null);\n api\n .getAppAuth(app.id)\n // Hide methods the server flagged unavailable (e.g. oauth2 with no host creds).\n .then((a) => !canceled && setAuths(a.filter((x) => x.available !== false)))\n .catch((e) => !canceled && setError((e as Error).message));\n return () => {\n canceled = true;\n };\n }, [api, app.id]);\n\n const available = auths ?? [];\n // User's pick, else the server-flagged default (over the already-filtered\n // list, so an unavailable default falls through), else the first.\n const auth: AuthDef | undefined =\n available.find((a) => a.key === authKey) ??\n available.find((a) => a.default === true) ??\n available[0];\n const fields: AuthField[] = auth?.fields ?? [];\n const isOAuth = auth?.type === \"oauth2\";\n // The Credential step needs the auth to declare `serviceAccount` AND the host to supply both\n // credential methods; otherwise this is the plain inline-credential form.\n const sa = auth?.serviceAccount;\n const listCredentials = api.listCredentials;\n const createCredential = api.createCredential;\n const credentialStep =\n !isOAuth &&\n !!sa &&\n typeof listCredentials === \"function\" &&\n typeof createCredential === \"function\";\n const contract = sa?.accepts?.[0] ?? \"\";\n const usable = (stored ?? []).filter((c) => c.contract === contract && c.status === \"active\");\n const mode: \"existing\" | \"new\" = usable.length === 0 ? \"new\" : (pickedMode ?? \"existing\");\n const chosenId = usable.some((c) => c.id === selectedId) ? selectedId : (usable[0]?.id ?? \"\");\n const bindingFields = credentialStep && sa ? bindingFieldsFor(sa) : [];\n\n useEffect(() => {\n if (!credentialStep || !listCredentials) return;\n let canceled = false;\n setStored(null);\n setPickedMode(null);\n createdId.current = null;\n listCredentials\n .call(api, { contract })\n .then((list) => !canceled && setStored(list))\n .catch(() => !canceled && setStored([]));\n return () => {\n canceled = true;\n };\n // `credentialStep`/`contract` change only when the auth does; `api` is the host's stable object.\n }, [api, credentialStep, contract, listCredentials]);\n // The synthetic \"no connection needed\" entry `GET /apps/:id/auths` appends\n // for a zero-credential-flagged tenant (`admin/apps-catalog.ts`) — matched\n // by `key`, never `type` (its `type` is the existing `\"custom\"` value,\n // shared with real custom auth methods; `key: \"zero-credential\"` is the\n // one thing only this synthetic entry carries). Selecting it needs no\n // fields and no real `POST /apps/:id/connections` — the tenant is already\n // \"connected\" via the flag (`admin/connections.ts`'s own synthetic\n // `zerocred:<appId>` summary), so submitting here just reports that same\n // id back rather than creating a second, real row for nothing to store.\n const isZeroCred = auth?.key === \"zero-credential\";\n const blank = (v: unknown) => v === undefined || v === \"\";\n const requiredMissing =\n !isOAuth &&\n !isZeroCred &&\n (credentialStep\n ? stored === null ||\n bindingFields.some((f) => f.required && blank(bindingVals[f.key])) ||\n (mode === \"existing\"\n ? chosenId === \"\"\n : credName.trim() === \"\" || fields.some((f) => f.required && blank(credential[f.key])))\n : fields.some((f) => f.required && blank(credential[f.key])));\n // Hoisted once — shared by the primary button's `disabled` and the\n // enter-to-submit hook's `enabled`, so Enter can never do something the\n // button itself refuses to do.\n const submitDisabled = !auth || (!isOAuth && !isZeroCred && requiredMissing) || pending;\n\n async function submit() {\n if (!auth) return;\n setError(null);\n setPending(true);\n try {\n if (isZeroCred) {\n onCreated({ connectionId: `zerocred:${app.id}` });\n } else if (isOAuth) {\n const { authorizationUrl } = await api.startAppOAuthFlow(app.id, auth.key, {\n displayName: displayName || undefined,\n });\n const { connectionId } = await startOAuthPopup(authorizationUrl);\n onCreated({ connectionId });\n } else if (credentialStep && createCredential) {\n let credentialId = mode === \"existing\" ? chosenId : createdId.current;\n if (credentialId === null) {\n const parsed = parseJsonFields(fields, credential);\n if (\"error\" in parsed) {\n setError(parsed.error);\n return;\n }\n const made = await createCredential.call(api, {\n name: credName.trim(),\n contract,\n source: parsed.values,\n });\n createdId.current = made.id;\n credentialId = made.id;\n }\n const binding = buildBinding(bindingFields, bindingVals);\n const body: CreateConnectionBody = {\n authKey: auth.key,\n credentialId,\n ...(binding ? { binding } : {}),\n ...(displayName ? { displayName } : {}),\n };\n const conn = await api.createConnection(app.id, body);\n onCreated({ connectionId: conn.id });\n } else {\n const parsed = parseJsonFields(fields, credential);\n if (\"error\" in parsed) {\n setError(parsed.error);\n return;\n }\n const conn = await api.createConnection(app.id, {\n authKey: auth.key,\n credential: parsed.values,\n displayName: displayName || undefined,\n });\n onCreated({ connectionId: conn.id });\n }\n } catch (e) {\n setError((e as Error).message);\n } finally {\n setPending(false);\n }\n }\n\n const enterSubmit = useEnterSubmit(submit, { enabled: !submitDisabled });\n\n return (\n // `.w6w-stepconfig` frame + body + pinned footer (D-3) — the same shape the\n // step builder's own config pane uses, so only the form scrolls and\n // Cancel/Save never leave the dialog's bottom.\n <div className=\"w6w-stepconfig\">\n <div className=\"w6w-modal-body\">\n <div className=\"w6w-stack\">\n {auths === null && <p className=\"w6w-muted w6w-small\">Loading auth methods…</p>}\n\n {auths !== null && available.length === 0 && (\n <p className=\"w6w-muted w6w-small\">\n This app has no available auth methods. If it uses OAuth, its client credentials may\n not be configured on the server yet.\n </p>\n )}\n\n {available.length > 1 && (\n <label className=\"w6w-field\">\n <span>Auth method</span>\n <select\n value={auth?.key ?? \"\"}\n onChange={(e) => {\n setAuthKey(e.target.value);\n setCredential({});\n setBindingVals({});\n createdId.current = null;\n setError(null);\n }}\n >\n {available.map((a) => (\n <option key={a.key} value={a.key}>\n {a.displayName ?? a.key} ({a.type})\n </option>\n ))}\n </select>\n </label>\n )}\n\n {auth && (\n <>\n {!isZeroCred && (\n <label className=\"w6w-field\">\n <span>Display name</span>\n <input\n type=\"text\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n placeholder=\"e.g. Production API key\"\n maxLength={80}\n // A plain text field above a credential field gets treated as the\n // \"username\" of a login form and prefilled — opt it out.\n name=\"w6w-connection-label\"\n autoComplete=\"off\"\n data-1p-ignore=\"true\"\n data-lpignore=\"true\"\n data-bwignore=\"true\"\n data-form-type=\"other\"\n {...enterSubmit}\n />\n </label>\n )}\n {auth.description && <p className=\"w6w-muted w6w-small\">{auth.description}</p>}\n {isZeroCred ? null : isOAuth ? (\n <p className=\"w6w-muted w6w-small\">\n You'll be redirected to <strong>{auth.displayName ?? auth.key}</strong> to\n authorize this connection.\n </p>\n ) : credentialStep && sa ? (\n <>\n <CredentialPicker\n credentials={usable}\n mode={mode}\n onModeChange={(m) => {\n setPickedMode(m);\n createdId.current = null;\n }}\n selectedId={chosenId}\n onSelect={setSelectedId}\n canUseExisting={usable.length > 0}\n contract={contract}\n />\n {sa.scopes.length > 0 && (\n <p className=\"w6w-muted w6w-small\">\n Scopes: <code>{sa.scopes.join(\" \")}</code>\n </p>\n )}\n {bindingFields.length > 0 && (\n <AuthFieldsForm\n fields={bindingFields}\n values={bindingVals}\n onChange={setBindingVals}\n enterSubmitProps={enterSubmit}\n />\n )}\n {mode === \"new\" && (\n <>\n <label className=\"w6w-field\">\n <span>Credential name *</span>\n <input\n type=\"text\"\n value={credName}\n onChange={(e) => setCredName(e.target.value)}\n placeholder=\"e.g. Workspace automation\"\n maxLength={80}\n name=\"w6w-credential-name\"\n autoComplete=\"off\"\n data-1p-ignore=\"true\"\n data-lpignore=\"true\"\n data-bwignore=\"true\"\n data-form-type=\"other\"\n {...enterSubmit}\n />\n </label>\n <AuthFieldsForm\n fields={fields}\n values={credential}\n onChange={setCredential}\n enterSubmitProps={enterSubmit}\n />\n </>\n )}\n </>\n ) : (\n <AuthFieldsForm\n fields={fields}\n values={credential}\n onChange={setCredential}\n enterSubmitProps={enterSubmit}\n />\n )}\n </>\n )}\n\n {error && <div className=\"w6w-result w6w-error\">{error}</div>}\n </div>\n </div>\n <div className=\"w6w-modal-actions\">\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost\" onClick={onClose}>\n Cancel\n </button>\n <button type=\"button\" className=\"w6w-btn\" disabled={submitDisabled} onClick={submit}>\n {pending\n ? isZeroCred\n ? \"Saving…\"\n : isOAuth\n ? \"Waiting for authorization…\"\n : \"Saving…\"\n : isZeroCred\n ? \"Use this\"\n : isOAuth\n ? `Sign in with ${auth?.displayName ?? auth?.key ?? \"provider\"}`\n : \"Save connection\"}\n </button>\n </div>\n </div>\n );\n}\n","import { IconButton } from \"./IconButton.tsx\";\n\nexport interface DeleteButtonProps {\n label: string;\n onClick: () => void;\n disabled?: boolean;\n className?: string;\n \"data-testid\"?: string;\n}\n\n/**\n * An `IconButton` bundling the canonical trash glyph — `icons.tsx`'s `delete`,\n * the fuller 4-shape Feather `trash-2` — always `danger`-styled.\n *\n * Presentational only (HITL-1, binding): takes a plain `onClick`, never an\n * `onConfirm`, and never imports any confirm-dialog component — the call\n * site owns whether and which one gates the click.\n */\nexport function DeleteButton(props: DeleteButtonProps) {\n const { label, onClick, disabled, className, ...rest } = props;\n return (\n <IconButton\n label={label}\n onClick={onClick}\n disabled={disabled}\n className={className}\n danger\n icon=\"delete\"\n data-testid={rest[\"data-testid\"]}\n />\n );\n}\n","import { useState } from \"react\";\nimport { ConditionEditor } from \"./ConditionEditor.tsx\";\nimport { DeleteButton } from \"./components/DeleteButton.tsx\";\nimport { Icon } from \"./components/Icon.tsx\";\nimport { ROUTER_APP, type RouterRoute, internalNodeDefaults } from \"./flow-types.ts\";\n\nexport function RouterEditor({\n values,\n onChange,\n readOnly,\n}: {\n values: Record<string, unknown>;\n onChange: (values: Record<string, unknown>) => void;\n readOnly?: boolean;\n}) {\n const routes = (\n Array.isArray(values.routes) ? values.routes : internalNodeDefaults(ROUTER_APP, \"route\").routes\n ) as RouterRoute[];\n const conditions = routes.filter((r) => !r.default);\n const [dragged, setDragged] = useState<string | null>(null);\n const [dropTarget, setDropTarget] = useState<string | null>(null);\n const [renaming, setRenaming] = useState<string | null>(null);\n const [draftName, setDraftName] = useState(\"\");\n // Keep existing fallback IDs, so editing a route never disconnects its fallback edge.\n const save = (next: RouterRoute[]) =>\n onChange({\n ...values,\n routes: [...next, ...routes.filter((r) => r.default)],\n });\n const patch = (id: string, value: Partial<RouterRoute>) =>\n save(conditions.map((r) => (r.id === id ? { ...r, ...value } : r)));\n const move = (id: string, to: number) => {\n const from = conditions.findIndex((r) => r.id === id);\n if (from < 0 || to < 0 || to >= conditions.length || from === to) return;\n const next = [...conditions];\n const [route] = next.splice(from, 1);\n next.splice(to, 0, route);\n save(next);\n };\n const rename = (route: RouterRoute) => {\n if (draftName.trim()) patch(route.id, { label: draftName.trim() });\n setRenaming(null);\n };\n return (\n <div className=\"w6w-router-editor\">\n <p className=\"w6w-muted w6w-small\">First match wins. Drag routes to change their order.</p>\n <div className=\"w6w-router-routes\">\n {conditions.map((route, index) => (\n // Native drag events on the row accept drops from its keyboard-accessible grip.\n <div\n key={route.id}\n className={`w6w-router-route${dragged === route.id ? \" is-dragging\" : \"\"}${dropTarget === route.id ? \" is-drop-target\" : \"\"}`}\n data-route-id={route.id}\n onDragOver={(event) => {\n if (readOnly || !dragged || dragged === route.id) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = \"move\";\n setDropTarget(route.id);\n }}\n onDrop={(event) => {\n event.preventDefault();\n if (!readOnly && dragged) move(dragged, index);\n setDragged(null);\n setDropTarget(null);\n }}\n >\n <div className=\"w6w-router-route-heading\">\n <button\n type=\"button\"\n className=\"w6w-icon-btn w6w-router-grip\"\n draggable={!readOnly}\n disabled={readOnly}\n aria-label={`Reorder ${route.label || route.id}`}\n title=\"Drag to reorder · arrow keys to move\"\n onDragStart={(event) => {\n event.dataTransfer.effectAllowed = \"move\";\n event.dataTransfer.setData(\"text/plain\", route.id);\n const row = event.currentTarget.closest(\".w6w-router-route\");\n if (row) event.dataTransfer.setDragImage(row, 16, 16);\n setDragged(route.id);\n }}\n onDragEnd={() => {\n setDragged(null);\n setDropTarget(null);\n }}\n onKeyDown={(event) => {\n if (event.key !== \"ArrowUp\" && event.key !== \"ArrowDown\") return;\n event.preventDefault();\n move(route.id, index + (event.key === \"ArrowUp\" ? -1 : 1));\n }}\n >\n <Icon name=\"grip\" size={14} />\n </button>\n <span className=\"w6w-step-rename\">\n {renaming === route.id && !readOnly ? (\n <input\n // biome-ignore lint/a11y/noAutofocus: inline rename is explicitly opened by the user\n autoFocus\n aria-label=\"Route name\"\n value={draftName}\n onChange={(event) => setDraftName(event.target.value)}\n onBlur={() => rename(route)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") rename(route);\n if (event.key === \"Escape\") setRenaming(null);\n }}\n />\n ) : (\n <button\n type=\"button\"\n className=\"w6w-router-route-name\"\n disabled={readOnly}\n aria-label={`Rename ${route.label || route.id}`}\n onClick={() => {\n setDraftName(route.label || route.id);\n setRenaming(route.id);\n }}\n >\n {route.label || route.id}\n {!readOnly && <Icon name=\"edit\" size={12} />}\n </button>\n )}\n </span>\n <DeleteButton\n label={`Remove ${route.label || route.id}`}\n disabled={readOnly}\n onClick={() => save(conditions.filter((r) => r.id !== route.id))}\n />\n </div>\n <ConditionEditor\n values={{ condition: route.condition ?? false }}\n onChange={(next) => patch(route.id, { condition: next.condition })}\n readOnly={readOnly}\n purpose=\"router\"\n />\n </div>\n ))}\n </div>\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm w6w-router-add\"\n disabled={readOnly}\n onClick={() => {\n let n = 1;\n while (routes.some((r) => r.id === `route_${n}`)) n++;\n save([...conditions, { id: `route_${n}`, label: `Route ${n}`, condition: false }]);\n }}\n >\n <span aria-hidden=\"true\">+</span> Add route\n </button>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { Icon } from \"./components/Icon.tsx\";\n\n/**\n * A node's name (its step id) with a pencil to rename it — the one control both the step\n * editor and the add flow show. `onCommit` validates and applies a changed name, returning\n * why it was refused (shown inline, the input stays open) or `null`. Enter / blur commit,\n * Escape reverts.\n */\nexport function StepNameEditor({\n value,\n onCommit,\n readOnly,\n}: {\n value: string;\n onCommit: (id: string) => string | null;\n readOnly?: boolean;\n}) {\n const [renaming, setRenaming] = useState(false);\n const [draft, setDraft] = useState(value);\n const [error, setError] = useState<string | null>(null);\n const commit = () => {\n const id = draft.trim();\n const err = id && id !== value ? onCommit(id) : null;\n if (err) {\n setError(err);\n return;\n }\n setError(null);\n setRenaming(false);\n };\n return (\n <span className=\"w6w-step-rename\">\n {renaming && !readOnly ? (\n <input\n // biome-ignore lint/a11y/noAutofocus: rename input opened on demand\n autoFocus\n aria-label=\"Node name\"\n value={draft}\n onChange={(e) => {\n setDraft(e.target.value);\n setError(null);\n }}\n onBlur={commit}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") commit();\n if (e.key === \"Escape\") {\n setDraft(value);\n setError(null);\n setRenaming(false);\n }\n }}\n />\n ) : (\n <>\n <code>{value}</code>\n {!readOnly && (\n <button\n type=\"button\"\n className=\"w6w-icon-btn w6w-btn-sm\"\n title=\"Rename node\"\n aria-label=\"Rename node\"\n onClick={() => {\n setDraft(value);\n setRenaming(true);\n }}\n >\n <Icon name=\"edit\" size={15} />\n </button>\n )}\n </>\n )}\n {error && (\n <span className=\"w6w-hint\" role=\"alert\" style={{ color: \"var(--w6w-danger)\" }}>\n {error}\n </span>\n )}\n </span>\n );\n}\n","import { ConditionEditor } from \"./ConditionEditor.tsx\";\n\nexport function StopEditor({\n values,\n onChange,\n readOnly,\n}: {\n values: Record<string, unknown>;\n onChange: (values: Record<string, unknown>) => void;\n readOnly?: boolean;\n}) {\n const conditional = values.condition !== undefined && values.condition !== true;\n return (\n <div className=\"w6w-stack\">\n <label className=\"w6w-field\">\n <span>Stop when</span>\n <select\n aria-label=\"Stop when\"\n disabled={readOnly}\n value={conditional ? \"condition\" : \"always\"}\n onChange={(e) => {\n const next = e.target.value === \"condition\";\n onChange({ ...values, condition: !next });\n }}\n >\n <option value=\"always\">Always</option>\n <option value=\"condition\">A condition matches</option>\n </select>\n </label>\n {conditional ? (\n <ConditionEditor values={values} onChange={onChange} readOnly={readOnly} purpose=\"stop\" />\n ) : (\n <p className=\"w6w-muted w6w-small\">\n End the whole workflow successfully here, including any remaining loop iterations.\n </p>\n )}\n </div>\n );\n}\n","/** Vendor HTML is hostile. NEVER dangerouslySetInnerHTML it; this is the only render path. */\nexport const HTML_PREVIEW_CSP =\n \"default-src 'none'; style-src 'unsafe-inline'; img-src data:; base-uri 'none'; form-action 'none'\";\n\n/** The CSP meta is FIRST so it is parsed into <head> before any payload byte. */\nexport function htmlPreviewSrcDoc(html: string): string {\n return `<!doctype html><meta http-equiv=\"Content-Security-Policy\" content=\"${HTML_PREVIEW_CSP}\">${html}`;\n}\n\nexport function HtmlPreview({ html }: { html: string }) {\n return (\n <iframe\n title=\"HTML preview\"\n className=\"w6w-html-preview\"\n sandbox=\"\"\n referrerPolicy=\"no-referrer\"\n srcDoc={htmlPreviewSrcDoc(html)}\n />\n );\n}\n","/**\n * A read-only, dependency-free tree for a parsed JSON value.\n *\n * Deliberately NOT exported from `src/index.ts` (`T0.1.1` pin 2): the public\n * way to show a result is `ResultViewer`, which owns the format decision and\n * the toolbar. `JsonTree` is the piece `ResultViewer` composes for\n * `format: \"json\"`, so it stays private until a consumer needs a bare tree.\n *\n * Two properties everything here is built around:\n *\n * - **Nothing is injected.** Every key, every scalar and every brace reaches\n * the DOM as a React text child — there is no `dangerouslySetInnerHTML`\n * anywhere in this file. A property key such as `\"<img onerror=…>\"` is just\n * text, which is the whole point: the value came from a vendor API.\n * - **Collapsing is a native `<details>`.** The children are always rendered\n * and the browser hides them, so collapsed text stays in the DOM: it is\n * selectable, findable by the browser's find-in-page, and readable by a\n * test. Re-rendering the subtree \"only when open\" would silently make the\n * collapsed content unreachable.\n */\n\n/** The scalar kinds a leaf can be — the class suffix `w6w-json-<kind>`. */\ntype JsonKind = \"string\" | \"number\" | \"boolean\" | \"null\";\n\n/** `undefined`, functions and symbols cannot come out of `JSON.parse`, but a\n * caller can hand `ResultViewer` any JS value; they render as `null`, which\n * is what `JSON.stringify` would write for them inside an object. */\nfunction kindOf(value: unknown): JsonKind {\n if (typeof value === \"string\") return \"string\";\n if (typeof value === \"number\") return \"number\";\n if (typeof value === \"boolean\") return \"boolean\";\n return \"null\";\n}\n\n/** The printed form of a scalar. A string keeps its JSON quotes (and escapes\n * its newlines/quotes) so the tree cannot be confused with the surrounding\n * structure; `JSON.stringify` is also what makes a hostile string inert. */\nfunction scalarText(value: unknown): string {\n return kindOf(value) === \"string\" ? JSON.stringify(value) : String(value);\n}\n\nfunction isContainer(value: unknown): value is Record<string, unknown> | unknown[] {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction countLabel(isArray: boolean, n: number): string {\n const noun = isArray ? \"item\" : \"key\";\n return `${n} ${noun}${n === 1 ? \"\" : \"s\"}`;\n}\n\nexport interface JsonTreeProps {\n /** Any value; objects and arrays become collapsible nodes, the rest leaves. */\n value: unknown;\n /**\n * How many levels start open. A node at depth `d` (root `d = 0`) is open iff\n * `d < expandDepth`, so the default `2` opens the root and its children —\n * enough to see the shape of a response without scrolling. `Infinity` opens\n * everything; `1` leaves only the root open.\n */\n expandDepth?: number;\n}\n\nexport function JsonTree({ value, expandDepth = 2 }: JsonTreeProps) {\n return <JsonNode label={undefined} value={value} depth={0} expandDepth={expandDepth} />;\n}\n\n/** One node. A non-empty object/array is a `<details>`; everything else —\n * every scalar and every EMPTY object/array — is a one-line leaf, because an\n * empty container has nothing to collapse and a toggle that opens onto\n * nothing reads as a bug. */\nfunction JsonNode(props: {\n label: string | number | undefined;\n value: unknown;\n depth: number;\n expandDepth: number;\n}) {\n const { label, value, depth, expandDepth } = props;\n const container = isContainer(value);\n const isArray = Array.isArray(value);\n const entries: Array<[string | number, unknown]> = container\n ? isArray\n ? (value as unknown[]).map((v, i) => [i, v] as [number, unknown])\n : Object.entries(value as Record<string, unknown>)\n : [];\n\n const key = label === undefined ? null : <span className=\"w6w-json-key\">{label}</span>;\n\n if (container && entries.length > 0) {\n return (\n <details className=\"w6w-json-node\" open={depth < expandDepth}>\n {/* The count is its own span, so the summary needs an explicit space\n text node — otherwise it reads `{…}3 keys`. */}\n <summary>\n {key}\n {isArray ? \"[…]\" : \"{…}\"}{\" \"}\n <span className=\"w6w-json-count\">{countLabel(isArray, entries.length)}</span>\n </summary>\n {/* Always rendered: the browser collapses it, not us (`see above`). */}\n <div className=\"w6w-json-children\">\n {entries.map(([k, v]) => (\n <JsonNode\n key={String(k)}\n label={k}\n value={v}\n depth={depth + 1}\n expandDepth={expandDepth}\n />\n ))}\n </div>\n </details>\n );\n }\n\n // A leaf: a scalar, or an empty `{}` / `[]`. The root of a tree has no key,\n // so it also has no `key: ` separator in front of it.\n return (\n <div className=\"w6w-json-leaf\">\n {key}\n {key === null ? null : \": \"}\n <span className={`w6w-json-${container ? \"null\" : kindOf(value)}`}>\n {container ? (isArray ? \"[]\" : \"{}\") : scalarText(value)}\n </span>\n </div>\n );\n}\n","/** What a result pane is showing, decided once from the ROOT value (never per leaf). */\nexport type DetectedResult =\n | { format: \"json\"; data: unknown }\n | { format: \"xml\" | \"html\" | \"markdown\" | \"text\"; text: string };\n\n/** Above this many characters html/markdown are shown as source only, never rendered. */\nexport const RESULT_RENDER_MAX_CHARS = 262144;\n\nconst MD_HEADING = /^#{1,6}\\s+\\S/;\nconst MD_FENCE = /^```/;\nconst MD_LIST_ITEM = /^\\s*(?:[-*+]|\\d+\\.)\\s+\\S/;\nconst MD_LINK = /\\[[^\\]\\n]+\\]\\(https?:\\/\\/[^)\\s]+\\)/;\n\nexport function detectResultFormat(value: unknown): DetectedResult {\n if (value === undefined) return { format: \"text\", text: \"\" };\n if (typeof value !== \"string\") return { format: \"json\", data: value };\n const t = value.trim();\n if (t.startsWith(\"{\") || t.startsWith(\"[\")) {\n try {\n const parsed: unknown = JSON.parse(t);\n if (parsed !== null && typeof parsed === \"object\") return { format: \"json\", data: parsed };\n } catch {\n // not JSON — fall through to the text sniffers\n }\n }\n if (/^<!doctype html/i.test(t) || /^<html[\\s>]/i.test(t)) return { format: \"html\", text: value };\n if (t.startsWith(\"<\") && t.endsWith(\">\")) return { format: \"xml\", text: value };\n const lines = t.split(\"\\n\");\n if (\n lines.some((l) => MD_HEADING.test(l) || MD_FENCE.test(l)) ||\n lines.filter((l) => MD_LIST_ITEM.test(l)).length >= 2 ||\n MD_LINK.test(t)\n ) {\n return { format: \"markdown\", text: value };\n }\n return { format: \"text\", text: value };\n}\n\n/** The exact text the copy button writes: pretty JSON for a tree, else the raw string. */\nexport function resultCopyText(d: DetectedResult): string {\n return d.format === \"json\" ? (JSON.stringify(d.data, null, 2) ?? \"\") : d.text;\n}\n","import { type ReactNode, useMemo, useState } from \"react\";\nimport { CodeBlock } from \"../CodeBlock.tsx\";\nimport { Markdown } from \"../Markdown.tsx\";\nimport { Copyable } from \"./Copyable.tsx\";\nimport { HtmlPreview } from \"./HtmlPreview.tsx\";\nimport { JsonTree } from \"./JsonTree.tsx\";\nimport { RESULT_RENDER_MAX_CHARS, detectResultFormat, resultCopyText } from \"./result-format.ts\";\n\nexport interface ResultViewerProps {\n /** The result as the host received it: an already-parsed value, or a raw\n * response body string. The format is sniffed from this ROOT value only\n * (`detectResultFormat`); string leaves inside a JSON tree stay text. */\n value: unknown;\n /** Keep an already-parsed payload as JSON, including strings; default sniffs the format. */\n format?: \"auto\" | \"json\";\n /** Height cap of the scrolling body, in px. Default 320. */\n maxHeight?: number;\n /** Extra class on the root, for spacing in the consuming pane. */\n className?: string;\n}\n\n/** Which of the two views the reader is on. Only ever offered for `html` and\n * `markdown`, the two formats that have both a rendered and a source form. */\ntype Mode = \"rendered\" | \"source\";\n\n/**\n * Above this many characters a source view is plain wrapped text, not a\n * `CodeBlock`.\n *\n * Highlighting is not free and its cost is not bounded by the render cap: a\n * 4 MB xml body, or a 300 KB markdown source over `RESULT_RENDER_MAX_CHARS`,\n * took tens of seconds inside Prism — far slower than the raw `<pre>` this\n * component replaces, i.e. the size guard made things WORSE (T0.1.1 eval B1).\n * A `<pre>` is instant, and at 64 KB the reader is scrolling anyway, so the\n * colour carries nothing they can use.\n */\nconst RESULT_HIGHLIGHT_MAX_CHARS = 65536;\n\n/**\n * The source form of `text`: highlighted when it is small enough for the colour\n * to be worth its cost, plain wrapped text when it is not.\n *\n * EVERY source view goes through here — xml, the Rendered/Source toggle and\n * the over-limit fallback — so there is exactly one place that decides when\n * Prism is allowed to see a value.\n */\nfunction renderSource(text: string, language: \"markup\" | \"markdown\"): ReactNode {\n if (text.length > RESULT_HIGHLIGHT_MAX_CHARS) {\n return <pre className=\"w6w-result-viewer-text\">{text}</pre>;\n }\n return <CodeBlock code={text} language={language} copyable={false} wrap />;\n}\n\n/**\n * Read-only display of one result value, chosen by its format:\n *\n * | format | body |\n * | ---------- | ---------------------------------------------------------- |\n * | `json` | a collapsible `JsonTree`, with Expand all / Collapse all |\n * | `xml` | source (`CodeBlock`, `markup`, when small enough) |\n * | `html` | `HtmlPreview` — an empty-sandbox iframe — or source |\n * | `markdown` | `Markdown` — or source |\n * | `text` | a plain `<pre>` |\n *\n * Read-only means read-only: nothing here takes an `onChange`, and the one\n * interactive affordance besides the collapsers and the Rendered/Source\n * toggle is `Copyable`'s button, overlaying the top-right corner and revealed\n * on hover (`w6w-copyable--hover`).\n *\n * **Vendor HTML never touches this document.** The `html` format renders only\n * through `HtmlPreview` — an `<iframe sandbox=\"\">` whose `srcdoc` opens with a\n * restrictive CSP meta as its first element — so a hostile payload cannot run\n * script and cannot reach this page's origin or its data. Nothing in this\n * component is ever passed to `dangerouslySetInnerHTML`. Accepted residual: a\n * reader's CLICK on a link inside the preview navigates the frame itself (a\n * page load in a sandboxed, scriptless, cookie-less document) — nothing more.\n * Above `RESULT_RENDER_MAX_CHARS` even that path is skipped: an oversized\n * document is shown as source, with a note saying so. Source views are handed\n * to `renderSource`, which drops Prism above `RESULT_HIGHLIGHT_MAX_CHARS`.\n *\n * The copy button always writes `resultCopyText(detected)` — pretty-printed\n * JSON for a tree, the raw string for every other format — so what lands on\n * the clipboard is what the reader means by \"the result\", not the on-screen\n * rendering. If that computation throws (circular value, `BigInt`), the view\n * still renders and the button writes a best-effort string instead.\n */\nexport function ResultViewer(props: ResultViewerProps) {\n const { value, format = \"auto\", maxHeight = 320, className } = props;\n // Sniffed once per value: the format decides both the body and the bar, and\n // re-sniffing on every unrelated re-render would re-parse a big string.\n const d = useMemo(\n () =>\n format === \"json\" ? { format: \"json\" as const, data: value } : detectResultFormat(value),\n [value, format],\n );\n\n const [mode, setMode] = useState<Mode>(\"rendered\");\n // JSON only: the open depth Expand all / Collapse all switch to, plus the\n // counter used as `JsonTree`'s `key` — remounting is what re-applies\n // `open` to `<details>` elements the reader has toggled by hand.\n const [expandDepth, setExpandDepth] = useState(2);\n const [treeEpoch, setTreeEpoch] = useState(0);\n\n const text = d.format === \"json\" ? \"\" : d.text;\n const renderable = d.format === \"html\" || d.format === \"markdown\";\n const overLimit = renderable && text.length > RESULT_RENDER_MAX_CHARS;\n\n // The clipboard payload, computed once: `resultCopyText` runs `JSON.stringify`,\n // which THROWS on a circular value or a `BigInt`, and a throw here would\n // unmount the pane — the reader would lose the result they are looking at.\n // Degrade the copy text instead: a raw string as-is, anything else stringified\n // as best it can be.\n const copyText = useMemo(() => {\n try {\n return resultCopyText(d);\n } catch {\n return typeof value === \"string\" ? value : String(value);\n }\n }, [d, value]);\n\n let body: ReactNode;\n if (d.format === \"json\") {\n body = <JsonTree key={treeEpoch} value={d.data} expandDepth={expandDepth} />;\n } else if (d.format === \"xml\") {\n // XML is shown as source, never parsed or rendered: it can carry the same\n // hostile constructs as HTML, and there is no sandbox for an SVG/XML tree.\n body = renderSource(d.text, \"markup\");\n } else if (d.format === \"text\") {\n body = <pre className=\"w6w-result-viewer-text\">{d.text}</pre>;\n } else {\n const language = d.format === \"html\" ? \"markup\" : \"markdown\";\n if (overLimit) {\n // Too big to render: hand the reader the source rather than a 4 MB\n // iframe/DOM, and say why the Rendered view is not on offer.\n body = (\n <>\n <div className=\"w6w-muted w6w-small w6w-result-viewer-note\">\n Too large to render — showing source.\n </div>\n {renderSource(d.text, language)}\n </>\n );\n } else if (mode === \"source\") {\n body = renderSource(d.text, language);\n } else if (d.format === \"html\") {\n // The ONLY path that renders vendor HTML — see the component doc.\n body = <HtmlPreview html={d.text} />;\n } else {\n body = <Markdown content={d.text} />;\n }\n }\n\n let bar: ReactNode = null;\n if (d.format === \"json\") {\n bar = (\n <div className=\"w6w-result-viewer-bar\">\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n onClick={() => {\n setExpandDepth(Number.POSITIVE_INFINITY);\n setTreeEpoch((n) => n + 1);\n }}\n >\n Expand all\n </button>\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n onClick={() => {\n setExpandDepth(1);\n setTreeEpoch((n) => n + 1);\n }}\n >\n Collapse all\n </button>\n </div>\n );\n } else if (renderable && !overLimit) {\n bar = (\n <div className=\"w6w-result-viewer-bar\">\n <button\n type=\"button\"\n className={`w6w-btn w6w-btn-ghost${mode === \"rendered\" ? \" active\" : \"\"}`}\n data-mode=\"rendered\"\n aria-pressed={mode === \"rendered\"}\n onClick={() => setMode(\"rendered\")}\n >\n Rendered\n </button>\n <button\n type=\"button\"\n className={`w6w-btn w6w-btn-ghost${mode === \"source\" ? \" active\" : \"\"}`}\n data-mode=\"source\"\n aria-pressed={mode === \"source\"}\n onClick={() => setMode(\"source\")}\n >\n Source\n </button>\n </div>\n );\n }\n\n return (\n <div\n className={[\"w6w-result-viewer\", className ?? \"\"].filter(Boolean).join(\" \")}\n data-format={d.format}\n >\n {bar}\n <Copyable value={copyText} label=\"Copy result\" className=\"w6w-copyable--hover\">\n <div className=\"w6w-result-viewer-body\" style={{ maxHeight, overflow: \"auto\" }}>\n {body}\n </div>\n </Copyable>\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { Copyable } from \"./components/Copyable.tsx\";\nimport { ResultViewer } from \"./components/ResultViewer.tsx\";\nimport { WEBHOOK_APP } from \"./flow-types.ts\";\nimport { useW6WApi } from \"./provider.tsx\";\nimport type { SubscriptionSummary, WebhookListenSession } from \"./types.ts\";\n\n/** The captured call a webhook trigger emits as its output. */\nexport type CapturedWebhookRequest = NonNullable<WebhookListenSession[\"request\"]>;\n\n/**\n * The `@w6w/webhook` subscription that feeds `stepId`: the one bound to that node, else the\n * workflow's first webhook subscription (one not bound to any node — the URL panel's own pick).\n */\nexport function pickWebhookSubscription(\n subs: SubscriptionSummary[],\n stepId: string,\n): SubscriptionSummary | null {\n const hooks = subs.filter((s) => s.appId === WEBHOOK_APP);\n return hooks.find((s) => s.nodeId === stepId) ?? hooks.find((s) => !s.nodeId) ?? hooks[0] ?? null;\n}\n\n/** Header names whose values are never shown, on top of the server's own credential masking. */\nconst SECRET_HEADER_RE = /auth|token|secret|passw|cookie|api[-_]?key|signature|session/i;\nconst MASK = \"••••••\";\n\n/** Headers for display: secret-looking values masked. */\nexport function displayHeaders(headers: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(headers)) out[k] = SECRET_HEADER_RE.test(k) ? MASK : v;\n return out;\n}\n\n/** One long-poll's hold, in seconds (the server caps it at 25). */\nconst POLL_WAIT_S = 20;\n\ntype ListenState =\n | { phase: \"idle\" }\n | { phase: \"starting\" }\n | { phase: \"waiting\"; session: WebhookListenSession }\n | { phase: \"captured\"; session: WebhookListenSession; request: CapturedWebhookRequest }\n | { phase: \"expired\" }\n | { phase: \"error\"; message: string };\n\n/**\n * \"Listen for test event\" — the webhook trigger's primary Test action. Opens a short-lived listen\n * session on the node's webhook subscription, so the receive URL captures the next request even\n * while the workflow is unpublished (the caller gets a test acknowledgement and no run starts),\n * and long-polls it. A captured request is shown — method, time, query, headers (secret-looking\n * ones masked), pretty body — and **Use as test data** hands it to `onUse`, which makes it this\n * trigger's output and saved test.\n */\nexport function WebhookListenPanel({\n workflowId,\n stepId,\n stepWith,\n readOnly,\n onUse,\n using,\n}: {\n workflowId: string;\n stepId: string;\n /** The node's current config — the params a newly created subscription starts from. */\n stepWith: Record<string, unknown> | undefined;\n readOnly?: boolean;\n onUse: (request: CapturedWebhookRequest) => void;\n /** `onUse`'s save is in flight. */\n using?: boolean;\n}) {\n const api = useW6WApi();\n // `undefined` while the list is in flight; `null` once resolved with none.\n const [sub, setSub] = useState<SubscriptionSummary | null | undefined>(undefined);\n const [creating, setCreating] = useState(false);\n const [state, setState] = useState<ListenState>({ phase: \"idle\" });\n const [now, setNow] = useState(() => Date.now());\n // The live session and its poll's abort handle — refs, so unmount and Stop see the latest.\n const live = useRef<{ subId: string; sessionId: string; abort: AbortController } | null>(null);\n\n useEffect(() => {\n const list = api.listSubscriptionsForWorkflow;\n if (!list) return;\n let canceled = false;\n list(workflowId)\n .then((subs) => !canceled && setSub(pickWebhookSubscription(subs, stepId)))\n .catch((e) => !canceled && setState({ phase: \"error\", message: (e as Error).message }));\n return () => {\n canceled = true;\n };\n }, [api, workflowId, stepId]);\n\n const halt = useCallback(\n (remote: boolean) => {\n const cur = live.current;\n live.current = null;\n if (!cur) return;\n cur.abort.abort();\n if (remote) api.stopWebhookListen?.(cur.subId, cur.sessionId).catch(() => {});\n },\n [api],\n );\n\n // Leaving the Test tab (or closing the modal) stops listening on the server too.\n useEffect(() => () => halt(true), [halt]);\n\n // The countdown only ticks while waiting.\n useEffect(() => {\n if (state.phase !== \"waiting\") return;\n const t = setInterval(() => setNow(Date.now()), 1000);\n return () => clearInterval(t);\n }, [state.phase]);\n\n const createUrl = () => {\n const create = api.createSubscription;\n if (!create) return;\n setCreating(true);\n create(WEBHOOK_APP, \"webhook\", { workflowId, connectionId: null, params: stepWith ?? {} })\n .then((created) => setSub(created))\n .catch((e) => setState({ phase: \"error\", message: (e as Error).message }))\n .finally(() => setCreating(false));\n };\n\n const listen = async () => {\n const start = api.startWebhookListen;\n const poll = api.pollWebhookListen;\n if (!sub || !start || !poll) return;\n halt(true);\n setState({ phase: \"starting\" });\n let opened: WebhookListenSession;\n try {\n opened = (await start(sub.id)).session;\n } catch (e) {\n setState({ phase: \"error\", message: (e as Error).message });\n return;\n }\n const abort = new AbortController();\n const mine = { subId: sub.id, sessionId: opened.id, abort };\n live.current = mine;\n setNow(Date.now());\n setState({ phase: \"waiting\", session: opened });\n for (;;) {\n let s: WebhookListenSession;\n try {\n s = await poll(sub.id, opened.id, { waitSeconds: POLL_WAIT_S, signal: abort.signal });\n } catch (e) {\n if (live.current !== mine) return; // stopped / superseded / unmounted\n live.current = null;\n setState({ phase: \"error\", message: (e as Error).message });\n return;\n }\n if (live.current !== mine) return;\n if (s.status === \"captured\" && s.request) {\n live.current = null;\n setState({ phase: \"captured\", session: s, request: s.request });\n return;\n }\n if (s.status === \"expired\") {\n live.current = null;\n api.stopWebhookListen?.(sub.id, opened.id).catch(() => {});\n setState({ phase: \"expired\" });\n return;\n }\n }\n };\n\n const stop = () => {\n halt(true);\n setState({ phase: \"idle\" });\n };\n\n if (!api.startWebhookListen || !api.pollWebhookListen) return null;\n const url = sub?.webhookUrl;\n const left =\n state.phase === \"waiting\"\n ? Math.max(0, Math.ceil((Date.parse(state.session.expiresAt) - now) / 1000))\n : 0;\n\n return (\n <div className=\"w6w-stack w6w-listen\" data-testid=\"webhook-listen\">\n {sub === undefined ? (\n <p className=\"w6w-muted w6w-small\">Loading…</p>\n ) : !url ? (\n <div className=\"w6w-stack\">\n <p className=\"w6w-muted w6w-small\">\n This webhook has no URL yet. Create one, then listen for a test request.\n </p>\n {!readOnly && api.createSubscription && (\n <button type=\"button\" className=\"w6w-btn\" disabled={creating} onClick={createUrl}>\n {creating ? \"Creating…\" : \"Create webhook URL\"}\n </button>\n )}\n </div>\n ) : (\n <>\n <Copyable value={url} readOnly>\n <input type=\"text\" readOnly value={url} aria-label=\"Webhook URL\" />\n </Copyable>\n {state.phase === \"waiting\" || state.phase === \"starting\" ? (\n <div className=\"w6w-listen-waiting\">\n <span className=\"w6w-listen-pulse\" aria-hidden=\"true\" />\n <output className=\"w6w-small\">\n Waiting for a request to <code>{url}</code>…\n {state.phase === \"waiting\" && (\n <span className=\"w6w-muted\"> {formatLeft(left)} left</span>\n )}\n </output>\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost\" onClick={stop}>\n Stop\n </button>\n </div>\n ) : (\n <div className=\"w6w-steptest-bar\">\n <button\n type=\"button\"\n className=\"w6w-btn\"\n disabled={readOnly}\n onClick={() => void listen()}\n >\n {state.phase === \"captured\" ? \"Listen again\" : \"Listen for test event\"}\n </button>\n {state.phase === \"idle\" && (\n <span className=\"w6w-muted w6w-small\">\n Send a request to this URL — it works before you publish, and starts no run.\n </span>\n )}\n </div>\n )}\n </>\n )}\n\n {state.phase === \"expired\" && (\n <p className=\"w6w-muted w6w-small\">\n No request arrived in time. Listen again, then send the request.\n </p>\n )}\n {state.phase === \"error\" && <div className=\"w6w-result w6w-error\">{state.message}</div>}\n\n {state.phase === \"captured\" && (\n <CapturedRequest\n request={state.request}\n receivedAt={state.session.receivedAt}\n readOnly={readOnly}\n using={using}\n onUse={() => onUse(state.request)}\n stepId={stepId}\n />\n )}\n </div>\n );\n}\n\nfunction formatLeft(s: number): string {\n const m = Math.floor(s / 60);\n return m > 0 ? `${m}:${String(s % 60).padStart(2, \"0\")}` : `${s}s`;\n}\n\nfunction CapturedRequest({\n request,\n receivedAt,\n readOnly,\n using,\n onUse,\n stepId,\n}: {\n stepId: string;\n request: CapturedWebhookRequest;\n receivedAt?: string;\n readOnly?: boolean;\n using?: boolean;\n onUse: () => void;\n}) {\n const hasQuery = Object.keys(request.query ?? {}).length > 0;\n return (\n <div className=\"w6w-testout w6w-listen-captured\" data-testid=\"webhook-captured\">\n <div className=\"w6w-testout-label\">\n Request received\n {receivedAt && (\n <span className=\"w6w-muted\"> · {new Date(receivedAt).toLocaleTimeString()}</span>\n )}\n </div>\n <div className=\"w6w-small\">\n <code>{request.method}</code> <code>{request.path}</code>\n </div>\n {hasQuery && (\n <>\n <div className=\"w6w-testout-label\">Query</div>\n <ResultViewer value={request.query} maxHeight={120} />\n </>\n )}\n <div className=\"w6w-testout-label\">Headers</div>\n <ResultViewer value={displayHeaders(request.headers ?? {})} maxHeight={160} />\n <div className=\"w6w-testout-label\">Body</div>\n <ResultViewer value={request.body} maxHeight={240} />\n {!readOnly && (\n <div className=\"w6w-steptest-bar\">\n <button type=\"button\" className=\"w6w-btn\" disabled={using} onClick={onUse}>\n {using ? \"Saving…\" : \"Use as test data\"}\n </button>\n <span className=\"w6w-muted w6w-small\">\n Becomes this trigger's output, so later steps can use{\" \"}\n <code>{`{{ nodes.${stepId}.output.body… }}`}</code>.\n </span>\n </div>\n )}\n </div>\n );\n}\n","import type { ActionParam } from \"./types.ts\";\n\n/**\n * One field configured on a manual (`@w6w/trigger`) or webhook (`@w6w/webhook`)\n * trigger — the `fields` param stores an array of these *definitions*\n * (`{ key, type, default, required }`), not values. The Test tab derives a\n * fillable form from them (see `TriggerFillForm`).\n */\nexport interface TriggerFieldDef {\n key?: string;\n /** Declared value type — maps to an existing `ParamsForm` widget. */\n type?: string;\n /** Author-declared default (stored as text on the trigger config). */\n default?: unknown;\n required?: boolean;\n}\n\n/** Read a trigger's `fields` param value as an array of field definitions. */\nexport function asFieldDefs(fields: unknown): TriggerFieldDef[] {\n return Array.isArray(fields) ? (fields as TriggerFieldDef[]) : [];\n}\n\n/**\n * Map a field def's declared type onto one of the `ParamsForm` scalar\n * widgets. `object`/`array` (a `WorkflowVariable`'s type union,\n * `w6w-workflow/packages/types/mod.ts:40-45` — this seam is also reused for\n * T1.1.5's run-page form) render as the `json` widget, same as an explicit\n * `json` declaration: there is no dedicated object/array widget, and `json`\n * is the one that round-trips a structured value without flattening it to\n * text. Verified inert for the trigger `fields` editor itself: its type\n * `<select>` offers exactly `string|number|boolean|json`\n * (`flow-types.ts:343-353`), so no editor-authored trigger field can reach\n * these two arms — only a call site that hands in `WorkflowVariable.type`\n * can.\n */\nexport function fieldWidget(type: string | undefined): ActionParam[\"type\"] {\n if (type === \"object\" || type === \"array\") return \"json\";\n return type === \"number\" || type === \"boolean\" || type === \"json\" ? type : \"string\";\n}\n\n/**\n * Coerce a field's author-declared default into a value of the field's\n * declared type, so the derived form seeds a sensible starting value and the\n * required gate sees it as filled. Returns `undefined` for an empty/invalid\n * default (the operator then supplies the value).\n *\n * A trigger field's default is stored as **text** and needs parsing; a\n * `WorkflowVariable`'s default is stored as a **real JSON value already**\n * (T1.1.5) — coercing it through `String(...)` would flatten `{a:1}` to the\n * literal text `\"[object Object]\"` and `[1,2]` to `\"1,2\"`, and re-parsing\n * `String({a:1})` as JSON fails outright (`coerceDefault(\"json\", {a:1})` used\n * to return `undefined`, silently dropping the default). So an already-object\n * or already-array `raw` is returned unchanged, before any type-specific\n * branch runs — this holds regardless of `type`, because the value needs no\n * coercion either way.\n */\nexport function coerceDefault(type: string | undefined, raw: unknown): unknown {\n if (raw === undefined || raw === null || raw === \"\") return undefined;\n if (typeof raw === \"object\") return raw;\n if (type === \"number\") {\n const n = Number(raw);\n return Number.isFinite(n) ? n : undefined;\n }\n if (type === \"boolean\") return raw === true || raw === \"true\";\n if (type === \"json\") {\n try {\n return JSON.parse(String(raw));\n } catch {\n return undefined;\n }\n }\n return String(raw);\n}\n\n/**\n * Project a trigger's `fields` definitions into a `ParamsForm`-compatible param\n * list — one input per declared field, keyed by the field's `key`, rendered with\n * the existing per-type widget. Unnamed fields are skipped.\n */\nexport function fieldsToParams(defs: TriggerFieldDef[]): ActionParam[] {\n return defs\n .filter((f) => typeof f.key === \"string\" && f.key.trim() !== \"\")\n .map((f) => ({\n key: f.key as string,\n label: f.key as string,\n type: fieldWidget(f.type),\n required: !!f.required,\n }));\n}\n\n/** Seed the fill-form values from each declared field's (coerced) default. */\nexport function seedValues(defs: TriggerFieldDef[]): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const f of defs) {\n if (typeof f.key !== \"string\" || f.key.trim() === \"\") continue;\n const v = coerceDefault(f.type, f.default);\n if (v !== undefined) out[f.key] = v;\n }\n return out;\n}\n","/**\n * Remembered test inputs — what the editor last ran each workflow node with\n * (`GET /workflows/:id/test-inputs`, `node_test_inputs` 0160), so the Run node\n * modal, the step / trigger Test tabs and the header Run reopen PREFILLED after\n * a success, a reload, another browser or the embed. Stored server-side per\n * (workflow, node), never in the workflow definition: remembering one never\n * dirties or versions the workflow.\n *\n * One slot per node: a trigger's filled fields, or any other node's\n * incoming-state override — a node is one or the other, so every surface that\n * collects for a node reads and writes the same slot.\n *\n * Pure and JSX-free so `node --test` exercises it directly.\n */\nimport type { ActionParam } from \"./types.ts\";\nimport { isExprValue, isSecretValue } from \"./types.ts\";\n\n/** One remembered input (`GET /workflows/:id/test-inputs` → `testInputs[]`). */\nexport interface NodeTestInput {\n nodeId: string;\n input: Record<string, unknown>;\n /** ISO timestamp of the write. */\n updatedAt: string;\n}\n\n/**\n * The remembered input of `nodeId`: `undefined` when the node has no row (the\n * caller may fall back to an older source, e.g. the latest step-test fixture),\n * `{}` when it was CLEARED (stay on the declared defaults), else the values.\n */\nexport function findTestInput(\n rows: readonly NodeTestInput[] | undefined,\n nodeId: string,\n): Record<string, unknown> | undefined {\n const row = (rows ?? []).find((r) => r && r.nodeId === nodeId);\n if (!row) return undefined;\n const input = row.input;\n return input && typeof input === \"object\" && !Array.isArray(input) ? input : {};\n}\n\n/** `true` when `v` is a binding (an `{{ … }}` string or an expression value), not a literal. */\nfunction isBinding(v: unknown): boolean {\n return isExprValue(v) || (typeof v === \"string\" && v.includes(\"{{\"));\n}\n\n/**\n * What may be remembered of `values`: a literal typed into a `secret` param is\n * DROPPED (it must never be persisted in plain text — the operator re-enters\n * it), a binding to a secret is kept as the expression, and a sealed envelope\n * is dropped anywhere at the top level (the server strips nested ones too).\n */\nexport function rememberableInput(\n values: Record<string, unknown>,\n params: readonly ActionParam[] = [],\n): Record<string, unknown> {\n const secretKeys = new Set(params.filter((p) => p.type === \"secret\").map((p) => p.key));\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(values)) {\n if (v === undefined || isSecretValue(v)) continue;\n if (secretKeys.has(k) && !isBinding(v)) continue;\n out[k] = v;\n }\n return out;\n}\n\n/**\n * Remembered-input saves still on the wire. A save is fire-and-forget for the surface that made\n * it (an edited sample payload saves as it is typed and once more as its modal closes), so the\n * next READ — a Run modal opening, the header Run resolving its input — waits on them first\n * ({@link testInputSavesSettled}); otherwise a Run pressed right after closing could read the\n * payload from before the edit.\n */\nconst inFlightSaves = new Set<Promise<unknown>>();\n\n/** Track `save` until it settles (it never rejects into the tracker). Returns `save`. */\nexport function trackTestInputSave<T>(save: Promise<T>): Promise<T> {\n const settled = save.then(\n () => undefined,\n () => undefined,\n );\n inFlightSaves.add(settled);\n void settled.then(() => inFlightSaves.delete(settled));\n return save;\n}\n\n/** Resolves once every remembered-input save issued so far has settled (never rejects). */\nexport async function testInputSavesSettled(): Promise<void> {\n await Promise.all([...inFlightSaves]);\n}\n","/**\n * The React face of remembered test inputs (`test-inputs.ts`): read the node's\n * last-used input once per (workflow, node), write it on every Run / Test, and\n * the small muted \"last used values · Clear\" note every collecting surface shows.\n */\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useW6WApi } from \"./provider.tsx\";\nimport {\n findTestInput,\n rememberableInput,\n testInputSavesSettled,\n trackTestInputSave,\n} from \"./test-inputs.ts\";\nimport type { ActionParam } from \"./types.ts\";\n\nexport interface RememberedTestInput {\n /** `true` once the read settled (or there was nothing to read). */\n loaded: boolean;\n /** `false` when the host has no `loadTestInputs` — fall back to the older source. */\n supported: boolean;\n /** `undefined` = no row; `{}` = cleared; else the values last used. */\n input: Record<string, unknown> | undefined;\n /** Remember `values` (secret literals dropped). Best-effort: never throws. */\n save: (values: Record<string, unknown>, params?: readonly ActionParam[]) => void;\n /** Forget the values (stored as `{}`, so no older source refills the form). */\n clear: () => void;\n}\n\nexport function useRememberedTestInput(\n workflowId: string | undefined,\n nodeId: string | undefined,\n): RememberedTestInput {\n const api = useW6WApi();\n const supported = typeof api.loadTestInputs === \"function\" && !!workflowId && !!nodeId;\n const [loaded, setLoaded] = useState(!supported);\n const [input, setInput] = useState<Record<string, unknown> | undefined>(undefined);\n useEffect(() => {\n if (!supported || !workflowId || !nodeId || !api.loadTestInputs) {\n setLoaded(true);\n return;\n }\n let canceled = false;\n setLoaded(false);\n // A save still on the wire (an edit made a moment ago, on another surface) lands first.\n testInputSavesSettled()\n .then(() => api.loadTestInputs?.(workflowId) ?? [])\n .then((rows) => {\n if (canceled) return;\n setInput(findTestInput(rows, nodeId));\n setLoaded(true);\n })\n // A failed read never blocks the form: no remembered values, older source applies.\n .catch(() => {\n if (!canceled) setLoaded(true);\n });\n return () => {\n canceled = true;\n };\n }, [api, supported, workflowId, nodeId]);\n\n const write = useCallback(\n (next: Record<string, unknown>) => {\n setInput(next);\n if (!workflowId || !nodeId || typeof api.saveTestInput !== \"function\") return;\n trackTestInputSave(api.saveTestInput(workflowId, nodeId, next)).catch((err) => {\n console.error(\"test input save failed\", err);\n });\n },\n [api, workflowId, nodeId],\n );\n const save = useCallback(\n (values: Record<string, unknown>, params?: readonly ActionParam[]) =>\n write(rememberableInput(values, params)),\n [write],\n );\n const clear = useCallback(() => write({}), [write]);\n return { loaded, supported, input, save, clear };\n}\n\n/** The small muted note under a prefilled form: \"last used values · Clear\". */\nexport function LastUsedNote({ onClear }: { onClear: () => void }) {\n return (\n <p className=\"w6w-muted w6w-small\" data-testid=\"last-used-note\">\n last used values ·{\" \"}\n <button type=\"button\" className=\"w6w-linkbtn\" onClick={onClear}>\n Clear\n </button>\n </p>\n );\n}\n","import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { PropertyEntryForm } from \"./PropertyEntryForm.tsx\";\nimport { type StepTestPersist, requiredParamsFilled } from \"./StepBuilderModal.tsx\";\nimport { type CapturedWebhookRequest, WebhookListenPanel } from \"./WebhookListenPanel.tsx\";\nimport { ResultViewer } from \"./components/ResultViewer.tsx\";\nimport { useW6WApi, useWorkflowProject } from \"./provider.tsx\";\nimport { asFieldDefs, fieldsToParams, seedValues } from \"./trigger-fields.ts\";\nimport { LastUsedNote, useRememberedTestInput } from \"./use-test-input.tsx\";\n\n/** How long an edited sample payload sits before it is remembered (it is flushed on close too). */\nexport const EDIT_SAVE_DEBOUNCE_MS = 600;\n\ntype TestState =\n | { status: \"running\" }\n | { status: \"done\"; value: unknown; logs?: string[] }\n | { status: \"error\"; error: string; errorCode?: string; logs?: string[] };\n\n/**\n * The Test-tab widget for a manual/webhook trigger. A trigger's configured\n * `fields` ARE the run's starting state, so testing it means **filling those\n * fields**, not running the raw config (which is why the trigger's output used to\n * come back `{}` — the invoke never carried an `input`).\n *\n * It projects the trigger's `fields` into params (see `./trigger-fields.ts`) and\n * hands them to {@link PropertyEntryForm} — the one property-entry surface, which\n * gives it the per-field widgets, per-field `ƒx`, and the fields ⇄ raw-JSON\n * toggle. This component keeps only the *run*: it enforces each field's\n * `required` via {@link requiredParamsFilled} before enabling Test, and invokes\n * with `{ input: {…filled} }` so the handler (which passes `params.input`\n * through) returns the populated values as the trigger's output state.\n *\n * A trigger with no declared fields (e.g. a webhook, whose payload is arbitrary)\n * gets the raw JSON payload editor — that is the entry form's own empty-params\n * path, not a second code path here — so the operator can still supply a\n * starting state, and the same `{ input }` projection applies.\n *\n * **Remembered values (T4.1.3).** With `persist` supplied, the values are not\n * just used for the invoke: they are saved as the step's latest `step_tests`\n * fixture (`with`) and the run is recorded **against that fixture's id**, and the\n * form seeds itself from the latest fixture next time it opens. The store is\n * project-owned and shared per workflow — any editor of the workflow sees the\n * same saved values, which is the answer to HITL-2. The canvas ▶ Run collect\n * form reads and writes the same fixture, so values entered on either surface\n * come back on the other.\n *\n * That persistence is **local to testing** — `TriggerFillForm` itself never\n * calls `POST /workflows/:id/run`. It does not by itself reach a production\n * workflow run: that route does accept an `input` body field, and the server\n * lands it as the entry trigger's output (`run-workflow.ts`,\n * `EnqueueRunInput.input`), but a CALLER has to fetch the saved fixture and\n * pass it in. Studio's header ▶ Run is that caller (`WorkflowsPage.tsx`'s\n * `onRunClick` → `resolveHeaderRunInput`,\n * `packages/studio/src/lib/workflow-live-run.ts`): it fetches the manual\n * trigger's latest `step_tests` row and sends its `with` verbatim as `input`.\n * This form is not in that path; it only writes the fixture that call reads.\n *\n * **Listen for test event.** With `listen` supplied (a `@w6w/webhook` trigger inside a workflow),\n * the primary action is {@link WebhookListenPanel}: the real request a caller sends becomes the\n * payload. **Use as test data** runs exactly this form's Test path with the captured request as\n * the values, so it lands as the trigger's output and saved test like a typed payload would. The\n * manual payload box stays, folded below as the secondary option.\n */\nexport function TriggerFillForm({\n app,\n action,\n fields,\n persist,\n listen,\n}: {\n app: string;\n action: string;\n /** The trigger's `fields` param value (an array of field definitions). */\n fields: unknown;\n /**\n * Where to remember the entered values. Absent in the add-step builder — that\n * step is not in a workflow yet, so there is no `(workflowId, stepId)` to key\n * a fixture by and this form neither reads nor writes one.\n */\n persist?: StepTestPersist;\n /** Offer \"Listen for test event\" (webhook triggers in a saved workflow). */\n listen?: { stepWith: Record<string, unknown> | undefined; readOnly?: boolean };\n}) {\n const api = useW6WApi();\n // The workflow's selected project scopes document-expression resolution in the\n // trigger test (undefined outside the editor → server default project).\n const project = useWorkflowProject();\n const defs = useMemo(() => asFieldDefs(fields), [fields]);\n const params = useMemo(() => fieldsToParams(defs), [defs]);\n const hasFields = params.length > 0;\n\n // One value bag for both paths: declared fields fill it by key, a webhook's\n // raw payload replaces it wholesale.\n const [values, setValues] = useState<Record<string, unknown>>(() => seedValues(defs));\n\n const [state, setState] = useState<TestState | null>(null);\n\n // Pre-fill from the step's last saved fixture. Depends on the ids rather than\n // on `persist` itself — the host builds that object inline, so its identity\n // changes every render.\n const persistWorkflowId = persist?.workflowId;\n const persistStepId = persist?.stepId;\n // The remembered test input (`node_test_inputs`, written by every Run / Test\n // of this trigger on any surface — this tab, the canvas Run node modal) wins\n // over the fixture; a `{}` row was cleared, so the declared defaults stay.\n const remembered = useRememberedTestInput(persistWorkflowId, persistStepId);\n const [prefilled, setPrefilled] = useState(false);\n // The \"Or test with a sample payload\" section opens by itself when a saved payload was loaded\n // into it, so the operator SEES what ▶ Run / the header Run will run with. Collapsed, a loaded\n // payload looked like none at all. The operator's own toggle wins afterwards.\n const [manualOpen, setManualOpen] = useState(false);\n // Nothing to wait for when there is no fixture key (the add-step builder).\n const [seeded, setSeeded] = useState(!persistWorkflowId || !persistStepId);\n // biome-ignore lint/correctness/useExhaustiveDependencies: seeds ONCE, when the remembered read settles — a later save must not re-seed\n useEffect(() => {\n if (!persistWorkflowId || !persistStepId) {\n setSeeded(true);\n return;\n }\n if (!remembered.loaded) return;\n if (remembered.input !== undefined) {\n const input = remembered.input;\n if (Object.keys(input).length > 0) {\n setValues((v) => ({ ...v, ...input }));\n setPrefilled(true);\n setManualOpen(true);\n }\n setSeeded(true);\n return;\n }\n let canceled = false;\n api\n .listStepTests(persistWorkflowId, persistStepId)\n .then((tests) => {\n if (canceled) return;\n // `listStepTests` is oldest-first, so the LAST entry is the most recent\n // fixture — the same convention the editor's upstream-seed effect uses.\n // Layered over the declared defaults so a field added since the last run\n // still arrives with its default rather than blank. An `ExprValue`\n // (`{type:\"expr\",…}`) is stored and restored as-is: `FxField` derives\n // expression mode from the value, so it comes back as a chip.\n const latest = tests.length ? tests[tests.length - 1] : null;\n if (latest?.with) {\n setValues((v) => ({ ...v, ...latest.with }));\n if (Object.keys(latest.with).length > 0) setManualOpen(true);\n }\n setSeeded(true);\n })\n // A missing/failed list must never block the form — fall back to the\n // declared defaults, silently, exactly as the seed effect does.\n .catch(() => {\n if (!canceled) setSeeded(true);\n });\n return () => {\n canceled = true;\n };\n }, [api, persistWorkflowId, persistStepId, remembered.loaded]);\n const [formKey, setFormKey] = useState(0);\n const clearRemembered = () => {\n clearTimeout(saveTimer.current);\n pendingSave.current = null;\n remembered.clear();\n setPrefilled(false);\n setValues(seedValues(defs));\n setFormKey((k) => k + 1);\n };\n\n // An EDITED payload is remembered as it is typed (debounced) and once more as this form goes away\n // (the modal's Done / close) — not only on Test run — so the header Run, ▶ on the node and the\n // Run node modal all run what was last on screen, with no Test run needed first.\n const pendingSave = useRef<Record<string, unknown> | null>(null);\n const saveTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const flushSave = useRef(() => {});\n flushSave.current = () => {\n clearTimeout(saveTimer.current);\n const next = pendingSave.current;\n pendingSave.current = null;\n if (next) remembered.save(next, params);\n };\n useEffect(() => () => flushSave.current(), []);\n const editValues = (next: Record<string, unknown>) => {\n setValues(next);\n if (!persistWorkflowId || !persistStepId || !seeded) return;\n pendingSave.current = next;\n clearTimeout(saveTimer.current);\n saveTimer.current = setTimeout(() => flushSave.current(), EDIT_SAVE_DEBOUNCE_MS);\n };\n\n // A raw-JSON draft that is not a values map never reaches `values`. Testing\n // now WRITES the saved fixture the Run form pre-fills from, so running the\n // previous payload while the operator looks at a different one would persist\n // the wrong values too — the same interlock Run uses (T4.1.2's validity-out).\n const [draftValid, setDraftValid] = useState(true);\n // With no declared params the required-check is vacuously true — a webhook\n // payload has nothing to require.\n const canRun = draftValid && requiredParamsFilled(params, values);\n\n const run = async (override?: Record<string, unknown>) => {\n const input = override ?? values;\n // This run's own save below supersedes any edit still waiting on the debounce.\n clearTimeout(saveTimer.current);\n pendingSave.current = null;\n // Remembered server-side before the invoke, whatever its outcome (secret literals dropped).\n if (persist) remembered.save(input, params);\n setState({ status: \"running\" });\n let outcome: Exclude<TestState, { status: \"running\" }>;\n try {\n // The filled values become the trigger's output/run-input — the handler\n // reads `params.input` and returns it verbatim.\n const result = await api.invokeAction(app, action, { input }, { project });\n outcome = {\n status: \"done\",\n value: result.value,\n logs: (result as { logs?: string[] }).logs,\n };\n } catch (e) {\n const err = e as { message?: string; code?: string; logs?: string[] };\n outcome = {\n status: \"error\",\n error: err.message ?? String(e),\n errorCode: err.code,\n logs: err.logs,\n };\n }\n setState(outcome);\n // Remember what was entered, and record the run AGAINST that fixture — the\n // same two-call sequence `StepTestRun` uses on the non-trigger Test path.\n // Without the `stepTestId` the fixture's `last_run_*` columns are never\n // written. Best-effort: a persist failure never masks the run's own result.\n if (persist) {\n try {\n const saved = await api.saveStepTest(persist.workflowId, persist.stepId, {\n input: persist.input,\n with: input,\n });\n await api.recordStepTestRun(persist.workflowId, persist.stepId, {\n stepTestId: saved.id,\n status: outcome.status === \"done\" ? \"succeeded\" : \"failed\",\n input: persist.input,\n output: outcome.status === \"done\" ? outcome.value : undefined,\n error: outcome.status === \"error\" ? outcome.error : undefined,\n });\n } catch (err) {\n console.error(\"step test persist failed\", err);\n }\n }\n };\n\n const logs = state && state.status !== \"running\" ? state.logs : undefined;\n\n // A captured request becomes the payload (shown in the manual box too) and is tested + saved.\n const useCaptured = (request: CapturedWebhookRequest) => {\n const payload = { ...request } as Record<string, unknown>;\n setValues(payload);\n void run(payload);\n };\n const listenPanel = listen && persist && (\n <WebhookListenPanel\n workflowId={persist.workflowId}\n stepId={persist.stepId}\n stepWith={listen.stepWith}\n readOnly={listen.readOnly}\n onUse={useCaptured}\n using={state?.status === \"running\"}\n />\n );\n\n return (\n <div className=\"w6w-stack\">\n {listenPanel}\n {listenPanel ? (\n <details\n className=\"w6w-listen-manual\"\n data-testid=\"trigger-sample-payload\"\n open={manualOpen}\n onToggle={(e) => setManualOpen(e.currentTarget.open)}\n >\n <summary className=\"w6w-small\">Or test with a sample payload</summary>\n {manualEntry()}\n </details>\n ) : (\n manualEntry()\n )}\n {resultBlock()}\n </div>\n );\n\n function manualEntry() {\n return (\n <div className=\"w6w-stack\">\n {/* Held until the saved values land, so the form is never shown with the\n defaults and then re-written under the operator's cursor. */}\n {!seeded ? (\n <p className=\"w6w-muted w6w-small\">Loading saved values…</p>\n ) : (\n <>\n {prefilled && <LastUsedNote onClear={clearRemembered} />}\n <PropertyEntryForm\n // Remounted on Clear, so a raw-JSON draft is re-derived from the defaults too.\n key={formKey}\n params={params}\n values={values}\n onChange={editValues}\n onValidityChange={setDraftValid}\n />\n {!hasFields && (\n <span className=\"w6w-hint\">\n This trigger declares no fields — provide a sample payload to test with. It becomes\n the trigger's output state (<code>input</code>).\n </span>\n )}\n </>\n )}\n\n <div className=\"w6w-steptest\">\n <div className=\"w6w-steptest-bar\">\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n disabled={!seeded || !canRun || state?.status === \"running\"}\n onClick={() => void run()}\n >\n {state?.status === \"running\" ? \"Running…\" : \"▶ Test run\"}\n </button>\n {seeded && !canRun && (\n <span className=\"w6w-muted w6w-small\">\n {draftValid\n ? \"Fill the required fields to test.\"\n : \"The payload must be a JSON object to test.\"}\n </span>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n function resultBlock() {\n return (\n <div className=\"w6w-steptest\">\n {state?.status === \"error\" && (\n <div className=\"w6w-result w6w-error\">\n {state.errorCode && (\n <div className=\"w6w-small\" style={{ opacity: 0.75, marginBottom: 4 }}>\n <code>{state.errorCode}</code>\n </div>\n )}\n {state.error}\n </div>\n )}\n {state?.status === \"done\" && (\n <div className=\"w6w-testout\">\n <div className=\"w6w-testout-label\">Output state (filled values)</div>\n <ResultViewer value={state.value} maxHeight={220} />\n </div>\n )}\n {logs && logs.length > 0 && (\n <div className=\"w6w-testout\">\n <div className=\"w6w-testout-label\">Console output</div>\n <pre\n className=\"w6w-result w6w-testout-console\"\n style={{ whiteSpace: \"pre-wrap\", maxHeight: 160, overflow: \"auto\", margin: 0 }}\n >\n {logs.join(\"\\n\")}\n </pre>\n </div>\n )}\n </div>\n );\n }\n}\n","import { useState } from \"react\";\nimport { ParamsForm } from \"./ParamsForm.tsx\";\n\nconst units = [\n [\"s\", \"Seconds\"],\n [\"m\", \"Minutes\"],\n [\"h\", \"Hours\"],\n [\"d\", \"Days\"],\n [\"w\", \"Weeks\"],\n];\nconst durationPattern =\n /^(?=\\d)(?:\\d+w)?(?:\\d+d)?(?:\\d+h)?(?:\\d+m)?(?:\\d+(?:\\.\\d+)?s)?$|^P(?:\\d+W)?(?:\\d+D)?(?:T(?=\\d)(?:\\d+H)?(?:\\d+M)?(?:\\d+(?:\\.\\d+)?S)?)?$/i;\n\n/** Both input modes write the same duration field; switching never discards a compound value. */\nexport function WaitEditor({\n values,\n onChange,\n readOnly,\n}: {\n values: Record<string, unknown>;\n onChange: (values: Record<string, unknown>) => void;\n readOnly?: boolean;\n}) {\n const duration = values.duration ?? \"1s\";\n const single =\n typeof duration === \"string\" ? duration.match(/^(\\d+(?:\\.\\d+)?)([smhdw])$/i) : null;\n const [lastUnit, setLastUnit] = useState(\"s\");\n const [mode, setMode] = useState<\"text\" | \"value\">(\"text\");\n const [target, setTarget] = useState<\"duration\" | \"until\">(values.until ? \"until\" : \"duration\");\n const invalid =\n typeof duration === \"string\" &&\n (!durationPattern.test(duration.trim()) || /^P$/i.test(duration.trim()));\n return (\n <div className=\"w6w-params-form\">\n <label>\n Wait for\n <select\n aria-label=\"Wait for\"\n disabled={readOnly}\n value={target}\n onChange={(e) => {\n const next = e.target.value as \"duration\" | \"until\";\n setTarget(next);\n onChange({\n ...values,\n duration: next === \"duration\" ? \"1s\" : \"\",\n until: \"\",\n });\n }}\n >\n <option value=\"duration\">A duration</option>\n <option value=\"until\">Until a timestamp</option>\n </select>\n </label>\n {target === \"until\" ? (\n <ParamsForm\n params={[\n {\n key: \"until\",\n label: \"Until\",\n type: \"string\",\n hint: \"ISO-8601 timestamp, e.g. 2026-10-08T09:00:00Z.\",\n },\n ]}\n values={values}\n onChange={onChange}\n readOnly={readOnly}\n />\n ) : (\n <>\n <label>\n Duration input\n <select\n aria-label=\"Duration input\"\n disabled={readOnly}\n value={mode}\n onChange={(e) => {\n if (single) {\n setLastUnit(single?.[2].toLowerCase() ?? lastUnit);\n }\n setMode(e.target.value as \"text\" | \"value\");\n }}\n >\n <option value=\"text\">Shorthand</option>\n <option value=\"value\" disabled={!single}>\n Value and unit\n </option>\n </select>\n </label>\n {mode === \"value\" ? (\n <div className=\"w6w-field-row\">\n <label>\n Value\n <input\n aria-label=\"Duration value\"\n type=\"number\"\n min=\"0\"\n step={(single?.[2].toLowerCase() ?? lastUnit) === \"s\" ? \"any\" : \"1\"}\n disabled={readOnly}\n value={single?.[1] ?? \"\"}\n onChange={(e) =>\n onChange({\n ...values,\n duration: `${e.target.value}${single?.[2].toLowerCase() ?? lastUnit}`,\n })\n }\n />\n </label>\n <label>\n Unit\n <select\n aria-label=\"Duration unit\"\n disabled={readOnly}\n value={single?.[2].toLowerCase() ?? lastUnit}\n onChange={(e) => {\n setLastUnit(e.target.value);\n onChange({\n ...values,\n duration: `${single?.[1] ?? \"\"}${e.target.value}`,\n });\n }}\n >\n {units.map(([value, label]) => (\n <option key={value} value={value}>\n {label}\n </option>\n ))}\n </select>\n </label>\n </div>\n ) : (\n <ParamsForm\n params={[\n {\n key: \"duration\",\n label: \"Duration\",\n type: \"string\",\n default: \"1s\",\n hint: \"Use 30s, 1h30m30s, or 3d30s. Units: w, d, h, m, s, in that order. Uppercase and ISO-8601 also work. Value and unit is available for single-unit durations.\",\n },\n ]}\n values={values}\n onChange={onChange}\n readOnly={readOnly}\n />\n )}\n {invalid && (\n <p role=\"alert\">\n Enter a duration such as 30s or 1h30m30s, using units w, d, h, m, s in order.\n </p>\n )}\n </>\n )}\n </div>\n );\n}\n","import { type ReactNode, type RefObject, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\n/** Full-row flyout anchored inside the nearest dialog’s top layer. */\nexport function AnchoredFlyout({\n anchorRef,\n onClose,\n children,\n}: {\n // Anchored to the ROW (both App and Connection buttons together), not the\n // individual trigger button — two reasons, both from the same feedback\n // pass (2026-08-30): a flyout anchored to whichever button sits at the\n // row's right edge (Connection) could overflow past the modal's own right\n // border (\"fix anchor\"), and the app picker specifically was asked to\n // \"take up the entire horizontal width of the content... extend to the\n // end of the prod button\". Anchoring both to the row's own bounding box\n // solves both at once: the flyout's width always matches content already\n // known to fit inside the modal, and it never hangs off either edge.\n anchorRef: RefObject<HTMLElement | null>;\n onClose: () => void;\n children: ReactNode;\n}) {\n const popRef = useRef<HTMLDivElement>(null);\n const [pos, setPos] = useState<{ top: number; left: number; width: number } | null>(null);\n const [container, setContainer] = useState<HTMLElement | null>(null);\n\n useEffect(() => {\n const el = anchorRef.current;\n if (!el) return;\n const r = el.getBoundingClientRect();\n setPos({ top: r.bottom + 6, left: r.left, width: r.width });\n setContainer(el.closest(\"dialog\") ?? document.body);\n }, [anchorRef]);\n\n useEffect(() => {\n function onDocPointerDown(e: MouseEvent) {\n const target = e.target as Node;\n if (popRef.current?.contains(target)) return;\n // A click ON the anchor is the trigger's own toggle — never close here\n // AND reopen there in the same gesture.\n if (anchorRef.current?.contains(target)) return;\n onClose();\n }\n function onKeyDown(e: KeyboardEvent) {\n if (e.key === \"Escape\") onClose();\n }\n document.addEventListener(\"mousedown\", onDocPointerDown);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"mousedown\", onDocPointerDown);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [onClose, anchorRef]);\n\n if (!pos || !container) return null;\n return createPortal(\n <div\n ref={popRef}\n className=\"w6w-flyout\"\n style={{ top: pos.top, left: pos.left, width: pos.width }}\n >\n {children}\n </div>,\n container,\n );\n}\n","/**\n * Host-supplied per-step problems painted on the canvas. Pure — no React or\n * @xyflow imports. The host owns detection (connection problems from the host's\n * own lookup, loop problems from `findLoopProblems` and parallel state writes from\n * `findStateWriteProblems` in `@w6w/ui/flow`); the\n * canvas only paints what it is given and offers each problem's one-click fix.\n */\nimport type { LoopInvalid } from \"./flow-loop.ts\";\n\n/** A one-click fix: pure data, applied by `applyStepProblemFix` on the author's click. */\nexport type StepProblemFix =\n | { kind: \"unwrap_items\"; label: \"Unwrap Items\" }\n | { kind: \"use_current_item\"; foreachId: string; label: \"Use Current item\" };\n\nexport type StepProblem =\n | { code: \"unknown_connection\"; connection: string }\n | { code: \"foreach_wrapped_items\"; fix: StepProblemFix }\n | { code: \"foreach_body_refs_output\"; foreachId: string; refs: string[]; fix: StepProblemFix }\n | { code: \"loop_body_invalid\"; reason: LoopInvalid }\n /** Writes a state path that a step running at the same time (`with`) also writes (`findStateWriteProblems`). */\n | { code: \"state_parallel_write\"; path: string[]; with: string[] }\n /** The saved workflow still lacks setup (unbound alias, empty store, missing var/secret/constant); `items` name what. */\n | { code: \"setup_incomplete\"; items: string[] };\n\n/** Keyed by step id; a step carries every problem it has (D-B1). */\nexport type StepProblems = Record<string, StepProblem[]>;\n\ninterface ProblemNode {\n id: string;\n data: { stepProblems?: StepProblem[] };\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== \"object\" || typeof b !== \"object\" || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const ka = Object.keys(a);\n const kb = Object.keys(b);\n if (ka.length !== kb.length) return false;\n return ka.every(\n (k) =>\n Object.prototype.hasOwnProperty.call(b, k) &&\n deepEqual((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]),\n );\n}\n\n/**\n * Stamp `data.stepProblems` from `problems`, clearing it for steps no longer in\n * the map (or mapped to `[]`). Returns the SAME node object when the incoming\n * list deep-equals the stamped one.\n */\nexport function applyStepProblems<N extends ProblemNode>(\n nodes: N[],\n problems: StepProblems | undefined,\n): N[] {\n return nodes.map((n) => {\n const next = problems && Object.hasOwn(problems, n.id) ? problems[n.id] : undefined;\n const cur = n.data.stepProblems;\n if (next === undefined || next.length === 0) {\n if (cur === undefined && !(\"stepProblems\" in n.data)) return n;\n const { stepProblems: _drop, ...rest } = n.data;\n return { ...n, data: rest } as N;\n }\n if (cur && deepEqual(cur, next)) return n;\n return { ...n, data: { ...n.data, stepProblems: structuredClone(next) } };\n });\n}\n\nconst INVALID_LOOP_TEXT: Record<LoopInvalid[\"reason\"], string> = {\n body_not_literal: \"This loop's body is not a list of step ids\",\n body_unknown_step: \"This loop's body names a step that doesn't exist\",\n body_self: \"This loop's body contains the For each itself\",\n body_duplicate: \"This loop's body lists a step twice\",\n body_claimed_twice: \"A step in this loop's body is also owned by another control step\",\n body_contains_control: \"This loop's body contains a control step (If, For each, Parallel…)\",\n body_step_has_edges: \"A step in this loop's body also has its own connections\",\n legacy_not_linear:\n \"The steps after this For each aren't one straight line, so they can't be read as its loop body\",\n};\n\nexport function stepProblemTooltip(p: StepProblem): string {\n switch (p.code) {\n case \"unknown_connection\":\n return `Connection ${p.connection} no longer exists — open the step and choose another on the Setup tab`;\n case \"foreach_wrapped_items\":\n return \"Items wraps a list in another list — this loops once\";\n case \"foreach_body_refs_output\":\n return `Refers to the For each's output (${p.refs.join(\", \")}) from inside its loop — use Current item instead`;\n case \"loop_body_invalid\": {\n const text = INVALID_LOOP_TEXT[p.reason.reason] ?? \"This loop's body is not valid\";\n return p.reason.stepId ? `${text} (${p.reason.stepId})` : text;\n }\n case \"state_parallel_write\": {\n const label = `state${p.path.length ? `.${p.path.join(\".\")}` : \"\"}`;\n return `Writes ${label} at the same time as ${p.with.join(\", \")} — parallel branches don't see each other's writes; the final value follows the workflow's step order`;\n }\n case \"setup_incomplete\":\n return `Setup incomplete — ${p.items.join(\", \")}`;\n }\n}\n\n/** True while the step still points at a connection the host reports missing (any entry). */\nexport function isConnectionBlocked(\n step: { uses: { connection?: string | null } },\n problems: StepProblem[] | undefined,\n): boolean {\n return (\n problems?.some(\n (p) => p.code === \"unknown_connection\" && step.uses.connection === p.connection,\n ) ?? false\n );\n}\n\n/** The Setup tab's Connection button label — exactly five outcomes. */\nexport function connectionButtonLabel(\n connection: string | undefined | null,\n conns: { id: string; displayName?: string; builtIn?: boolean }[] | null,\n failed: boolean,\n): string {\n if (!connection) return \"No connection\";\n if (failed) return \"Couldn't load connections\";\n if (conns === null) return connection;\n const found = conns.find((c) => c.id === connection);\n if (found) return found.builtIn ? \"Built-in\" : (found.displayName ?? connection);\n return \"Missing connection — choose another\";\n}\n","import type { FlowStep, FlowWorkflow } from \"./flow-types.ts\";\nimport type { AppSummary, AuthDef, ConnectionSummary } from \"./types.ts\";\n\nexport type FlowConnections = Record<string, { app: string; connection: string | null }>;\n\nexport type ConnectionResourceEdit =\n | { type: \"add\"; name: string; app: string; connection: string }\n | { type: \"update\"; ref: string; name: string; connection: string; nodeIds?: string[] }\n | { type: \"replace\"; ref: string; connection: string }\n | { type: \"rename\"; ref: string; name: string }\n | { type: \"remove\"; ref: string }\n | { type: \"assign\"; ref: string; nodeIds: string[] };\n\nexport interface WorkflowConnectionResources {\n workflowId: string;\n nodes: Pick<FlowStep, \"id\" | \"uses\">[];\n connections: FlowConnections;\n /** App identity already resolved for the canvas; reuse it in the connections rail. */\n apps?: ReadonlyMap<string, AppSummary>;\n readOnly?: boolean;\n /** Select and reveal a consuming node on the canvas. Available in read-only views too. */\n focusNode?: (nodeId: string) => void;\n /** Temporary canvas emphasis, without changing selection or the saved workflow. */\n highlightNode?: (nodeId: string | null) => void;\n /** Stable callback against the current canvas, including edits made since the panel opened. */\n edit: (edit: ConnectionResourceEdit) => void;\n}\n\n/** Edit references and their consumers together, so one undo restores the whole change. */\nexport function editConnectionResources(\n nodes: FlowStep[],\n connections: FlowConnections,\n edit: ConnectionResourceEdit,\n): { nodes: FlowStep[]; connections: FlowConnections } {\n if (edit.type === \"update\") {\n // Validate and apply the whole dialog as one canvas edit/undo entry.\n const renamed = editConnectionResources(nodes, connections, {\n type: \"rename\",\n ref: edit.ref,\n name: edit.name,\n });\n const ref = edit.name.trim();\n const replaced = editConnectionResources(renamed.nodes, renamed.connections, {\n type: \"replace\",\n ref,\n connection: edit.connection,\n });\n return edit.nodeIds\n ? editConnectionResources(replaced.nodes, replaced.connections, {\n type: \"assign\",\n ref,\n nodeIds: edit.nodeIds,\n })\n : replaced;\n }\n if (edit.type === \"add\" || edit.type === \"rename\") {\n const name = edit.name.trim();\n if (!name) throw new Error(\"Give the workflow connection a name.\");\n if (Object.hasOwn(connections, name) && (edit.type === \"add\" || name !== edit.ref)) {\n throw new Error(\"A workflow connection already uses that name.\");\n }\n if (edit.type === \"add\") {\n return {\n nodes,\n connections: { ...connections, [name]: { app: edit.app, connection: edit.connection } },\n };\n }\n }\n if (!Object.hasOwn(connections, edit.ref))\n throw new Error(\"This workflow connection no longer exists.\");\n const resource = connections[edit.ref];\n switch (edit.type) {\n case \"replace\":\n return {\n nodes,\n connections: { ...connections, [edit.ref]: { ...resource, connection: edit.connection } },\n };\n case \"rename\": {\n const name = edit.name.trim();\n return {\n connections: Object.fromEntries(\n Object.entries(connections).map(([ref, value]) => [ref === edit.ref ? name : ref, value]),\n ),\n nodes: nodes.map((n) =>\n n.uses.connectionRef === edit.ref ? withConnectionRef(n, name) : n,\n ),\n };\n }\n case \"remove\": {\n if (nodes.some((n) => n.uses.connectionRef === edit.ref))\n throw new Error(\"Choose another connection for its nodes before removing this resource.\");\n const { [edit.ref]: _removed, ...rest } = connections;\n return { nodes, connections: rest };\n }\n case \"assign\": {\n const selected = new Set(edit.nodeIds);\n if (nodes.some((n) => selected.has(n.id) && n.uses.app !== resource.app))\n throw new Error(\"A connection can only be assigned to nodes for the same app.\");\n return {\n connections,\n nodes: nodes.map((n) => (selected.has(n.id) ? withConnectionRef(n, edit.ref) : n)),\n };\n }\n }\n}\n\n/** Missing/foreign bindings stay unresolved in the editor; the server rejects invalid references. */\nexport function connectionIdFor(step: FlowStep, connections?: FlowConnections): string | undefined {\n const { connectionRef, connection, app } = step.uses;\n if (connectionRef === undefined) return connection ?? undefined;\n const entry =\n connections && Object.hasOwn(connections, connectionRef)\n ? connections[connectionRef]\n : undefined;\n return entry?.app === app ? (entry.connection ?? undefined) : undefined;\n}\n\n/** A workflow-owned name, independent of the first node or the account's display name. */\nexport function nextWorkflowConnectionName(appId: string, connections: FlowConnections): string {\n const appName = appId.split(/[./]/).filter(Boolean).at(-1) ?? \"connection\";\n const base =\n appName\n .toLowerCase()\n .replace(/[^a-z0-9_]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\") || \"connection\";\n let index = 1;\n while (Object.hasOwn(connections, `${base}_${index}`)) index++;\n return `${base}_${index}`;\n}\n\n/** Lift old inline IDs on the next editor save. Independent bindings remain independent. */\nexport function centralizeConnections<T extends Pick<FlowWorkflow, \"connections\" | \"nodes\">>(\n workflow: T,\n): T {\n let connections = workflow.connections ?? {};\n let changed = false;\n const nodes = (workflow.nodes ?? []).map((step) => {\n if (!step.uses.connection || step.uses.connectionRef !== undefined) return step;\n // Reuse an existing legacy binding, but never name a new binding after a node.\n const existing = Object.hasOwn(connections, step.id) ? connections[step.id] : undefined;\n const key =\n existing?.app === step.uses.app && existing.connection === step.uses.connection\n ? step.id\n : nextWorkflowConnectionName(step.uses.app, connections);\n connections = {\n ...connections,\n [key]: { app: step.uses.app, connection: step.uses.connection },\n };\n changed = true;\n return withConnectionRef(step, key);\n });\n return changed ? { ...workflow, nodes, connections } : workflow;\n}\n\n/** Drop only unreferenced aliases when serializing the complete workflow. */\nexport function pruneUnusedConnections<T extends Pick<FlowWorkflow, \"connections\" | \"nodes\">>(\n workflow: T,\n): T {\n if (!workflow.connections) return workflow;\n const used = new Set(workflow.nodes.map((node) => node.uses.connectionRef));\n const entries = Object.entries(workflow.connections);\n const kept = entries.filter(([ref]) => used.has(ref));\n if (kept.length === entries.length) return workflow;\n return { ...workflow, connections: Object.fromEntries(kept) };\n}\n\nexport function withConnectionRef(step: FlowStep, connectionRef: string): FlowStep {\n const { connection: _connection, ...uses } = step.uses;\n return { ...step, uses: { ...uses, connectionRef } };\n}\n\n/** An ordinary account selection affects this node only, detaching it from a shared entry. */\nexport function selectNodeConnection(\n step: FlowStep,\n connection: string | undefined,\n nodes: FlowStep[],\n connections: FlowConnections,\n): { step: FlowStep; connections: FlowConnections } {\n if (!connection) {\n const { connection: _id, connectionRef: _ref, ...uses } = step.uses;\n return { step: { ...step, uses }, connections };\n }\n const ref = step.uses.connectionRef;\n const shared = ref && nodes.some((n) => n.id !== step.id && n.uses.connectionRef === ref);\n const key = ref && !shared ? ref : nextWorkflowConnectionName(step.uses.app, connections);\n return {\n step: withConnectionRef(step, key),\n connections: { ...connections, [key]: { app: step.uses.app, connection } },\n };\n}\n\nexport function connectionSourceNodes(\n step: FlowStep,\n nodes: FlowStep[],\n connections: FlowConnections,\n): FlowStep[] {\n return nodes.filter(\n (n) =>\n n.id !== step.id &&\n n.uses.app === step.uses.app &&\n n.uses.connectionRef !== undefined &&\n !!connectionIdFor(n, connections),\n );\n}\n\n/** Accounts used anywhere in the workflow, including independently stored bindings. */\nexport function connectionUsers(\n app: string,\n connection: string | undefined,\n nodes: FlowStep[],\n connections: FlowConnections,\n): FlowStep[] {\n if (!connection) return [];\n return nodes.filter((n) => n.uses.app === app && connectionIdFor(n, connections) === connection);\n}\n\n/** An explicit initial selection wins; otherwise inherit the last added configured node. */\nexport function defaultConnectionFor(\n step: FlowStep,\n choices: ConnectionSummary[],\n nodes: FlowStep[],\n connections: FlowConnections,\n initialConnection?: string,\n): { connection?: string; connectionRef?: string } {\n if (initialConnection) return { connection: initialConnection };\n for (const node of [...nodes].reverse()) {\n if (node.id === step.id || node.uses.app !== step.uses.app) continue;\n const id = connectionIdFor(node, connections);\n if (!id || !choices.some((c) => c.id === id && c.appId === step.uses.app)) continue;\n return node.uses.connectionRef\n ? { connectionRef: node.uses.connectionRef }\n : { connection: id };\n }\n for (const [ref, resource] of Object.entries(connections)) {\n if (\n resource.app === step.uses.app &&\n choices.some((c) => c.appId === resource.app && c.id === resource.connection)\n ) {\n return { connectionRef: ref };\n }\n }\n const sameApp = choices.filter((c) => c.appId === step.uses.app);\n const selected = sameApp.find((c) => c.builtIn) ?? sameApp[0];\n return selected ? { connection: selected.id } : {};\n}\n\n/** The server's zero-credential sentinel is a real picker choice, without creating a row. */\nexport function withDefaultConnection(\n appId: string,\n auths: AuthDef[],\n choices: ConnectionSummary[],\n): ConnectionSummary[] {\n if (choices.some((c) => c.builtIn)) return choices;\n const allowed = auths.some(\n (a) =>\n a.available !== false &&\n (a.key === \"zero-credential\" ||\n (a.autoSatisfied === true && (a.type === \"tenantAuth\" || a.type === \"jit\"))),\n );\n if (!allowed) return choices;\n return [\n ...choices,\n {\n id: `zerocred:${appId}`,\n appId,\n authKey: \"zero-credential\",\n displayName: \"Built-in\",\n builtIn: true,\n state: \"connected\",\n },\n ];\n}\n\n/** Change every binding used by the displayed account's consumers, retaining reference keys. */\nexport function replaceWorkflowConnection(\n app: string,\n before: string,\n after: string,\n nodes: FlowStep[],\n connections: FlowConnections,\n): FlowConnections {\n const refs = new Set(\n connectionUsers(app, before, nodes, connections).map((n) => n.uses.connectionRef),\n );\n return Object.fromEntries(\n Object.entries(connections).map(([ref, value]) => [\n ref,\n refs.has(ref) ? { ...value, connection: after } : value,\n ]),\n );\n}\n","import { type RefObject, createContext, useContext, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { AddConnectionModal } from \"./AddConnectionModal.tsx\";\nimport { AnchoredFlyout } from \"./components/AnchoredFlyout.tsx\";\nimport { Modal } from \"./components/Modal.tsx\";\nimport type { FlowStep } from \"./flow-types.ts\";\nimport { connectionButtonLabel } from \"./step-problems.ts\";\nimport type { ConnectionSummary } from \"./types.ts\";\nimport {\n type FlowConnections,\n connectionIdFor,\n connectionUsers,\n replaceWorkflowConnection,\n} from \"./workflow-connections.ts\";\n\nexport const WorkflowConnectionsContext = createContext<{\n nodes: FlowStep[];\n readOnly?: boolean;\n connections: FlowConnections;\n setConnections: (connections: FlowConnections) => void;\n} | null>(null);\n\nexport function useWorkflowConnections() {\n return useContext(WorkflowConnectionsContext);\n}\n\n/** One account menu for both adding and editing workflow nodes. */\nexport function WorkflowConnectionPicker({\n step,\n conns,\n failed = false,\n readOnly,\n open,\n onOpenChange,\n anchorRef,\n onChangeConnection,\n onChangeConnectionRef,\n onConnectionCreated,\n}: {\n step: FlowStep;\n conns: ConnectionSummary[] | null;\n failed?: boolean;\n readOnly?: boolean;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n anchorRef: RefObject<HTMLElement | null>;\n onChangeConnection: (id: string) => void;\n onChangeConnectionRef: (ref: string) => void;\n onConnectionCreated: () => void;\n}) {\n const scope = useWorkflowConnections();\n const disabled = readOnly || scope?.readOnly;\n const connections = scope?.connections ?? {};\n const nodes = scope?.nodes ?? [];\n const choices = (conns ?? [])\n .map((conn) => ({ conn, users: connectionUsers(step.uses.app, conn.id, nodes, connections) }))\n .sort((a, b) => Number(b.users.length > 0) - Number(a.users.length > 0));\n const currentId =\n connectionIdFor(step, connections) ??\n (step.uses.connectionRef === undefined\n ? conns?.find((c) => c.builtIn && c.appId === step.uses.app)?.id\n : undefined);\n const peers = connectionUsers(step.uses.app, currentId, nodes, connections).filter(\n (n) => n.id !== step.id,\n );\n const [pending, setPending] = useState<string | null>(null);\n const [creating, setCreating] = useState(false);\n // Dialogs are siblings of the enclosing dialog, never nested in its body.\n const portalHost =\n pending || creating\n ? (anchorRef.current?.closest(\"dialog\")?.parentElement ?? document.body)\n : null;\n\n const apply = (id: string, all: boolean) => {\n if (disabled) return;\n if (all && scope && currentId) {\n scope.setConnections(\n replaceWorkflowConnection(step.uses.app, currentId, id, nodes, connections),\n );\n const bound = nodes.find((n) => n.id === step.id) ?? step;\n if (bound.uses.connectionRef) onChangeConnectionRef(bound.uses.connectionRef);\n else onChangeConnection(id);\n } else {\n const source = connectionUsers(step.uses.app, id, nodes, connections)\n .filter((n) => n.id !== step.id && n.uses.connectionRef)\n .at(-1);\n const resource = Object.entries(connections).find(\n ([, c]) => c.app === step.uses.app && c.connection === id,\n );\n if (source?.uses.connectionRef) onChangeConnectionRef(source.uses.connectionRef);\n else if (resource) onChangeConnectionRef(resource[0]);\n else onChangeConnection(id);\n }\n setPending(null);\n onOpenChange(false);\n };\n const choose = (id: string) => {\n if (disabled) return;\n onOpenChange(false);\n if (id === currentId) return;\n if (peers.length > 0 && nodes.some((n) => n.id === step.id)) setPending(id);\n else apply(id, false);\n };\n\n return (\n <>\n <button\n type=\"button\"\n className=\"w6w-app-conn-btn\"\n aria-label=\"Connection\"\n aria-expanded={open}\n disabled={disabled || (conns === null && !failed)}\n onClick={() => onOpenChange(!open)}\n >\n <span className=\"w6w-conn-label-name\">\n {conns === null && !failed && !currentId\n ? \"Loading connections…\"\n : connectionButtonLabel(currentId, conns, failed)}\n </span>\n </button>\n {open && (\n <AnchoredFlyout anchorRef={anchorRef} onClose={() => onOpenChange(false)}>\n <div className=\"w6w-stack\">\n {failed && (\n <p role=\"alert\" className=\"w6w-field-error\">\n Couldn’t load connections.\n </p>\n )}\n {Object.entries(connections).some(([, c]) => c.app === step.uses.app) && (\n <div className=\"w6w-stack\">\n <strong className=\"w6w-small\">Workflow connections</strong>\n <div className=\"w6w-stepbuilder-list\">\n {Object.entries(connections)\n .filter(([, c]) => c.app === step.uses.app)\n .map(([ref, c]) => (\n <button\n key={ref}\n type=\"button\"\n className=\"w6w-stepbuilder-item\"\n disabled={\n disabled ||\n !c.connection ||\n !conns?.some((conn) => conn.id === c.connection)\n }\n aria-pressed={step.uses.connectionRef === ref}\n data-connection-ref={ref}\n onClick={() => {\n onChangeConnectionRef(ref);\n onOpenChange(false);\n }}\n >\n <span className=\"w6w-stepbuilder-item-main\">\n <strong>{ref}</strong>\n <span className=\"w6w-muted w6w-small\">\n {connectionButtonLabel(c.connection ?? undefined, conns, failed)}\n </span>\n </span>\n </button>\n ))}\n </div>\n </div>\n )}\n <div className=\"w6w-stepbuilder-list\">\n {choices.map(({ conn, users }) => {\n return (\n <button\n key={conn.id}\n type=\"button\"\n className=\"w6w-stepbuilder-item\"\n disabled={disabled}\n aria-pressed={conn.id === currentId}\n data-connection-id={conn.id}\n onClick={() => choose(conn.id)}\n >\n <span className=\"w6w-stepbuilder-item-main\">\n <strong>{conn.builtIn ? \"Built-in\" : conn.displayName || conn.id}</strong>\n <span className=\"w6w-muted w6w-small\">\n {users.length > 0\n ? `In use in this workflow · ${users.map((n) => n.id).join(\", \")}`\n : conn.builtIn\n ? \"Built-in connection\"\n : conn.state}\n </span>\n </span>\n </button>\n );\n })}\n </div>\n <button\n type=\"button\"\n className=\"w6w-btn\"\n disabled={disabled}\n onClick={() => {\n onOpenChange(false);\n setCreating(true);\n }}\n >\n + New connection\n </button>\n </div>\n </AnchoredFlyout>\n )}\n {creating &&\n portalHost &&\n createPortal(\n <AddConnectionModal\n initialAppId={step.uses.app}\n onClose={() => setCreating(false)}\n onCreated={({ connectionId }) => {\n setCreating(false);\n onConnectionCreated();\n choose(connectionId);\n }}\n />,\n portalHost,\n )}\n {pending &&\n portalHost &&\n createPortal(\n <Modal title=\"Change connection\" onClose={() => setPending(null)}>\n <div className=\"w6w-modal-body\">\n <p>Change the connection for all these nodes, or only this node?</p>\n <ul>\n <li>{step.id || \"New node\"}</li>\n {peers.map((n) => (\n <li key={n.id}>{n.id}</li>\n ))}\n </ul>\n </div>\n <div className=\"w6w-modal-actions\">\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n onClick={() => setPending(null)}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n disabled={disabled}\n onClick={() => apply(pending, true)}\n >\n All {peers.length + 1} nodes\n </button>\n <button\n type=\"button\"\n className=\"w6w-btn\"\n disabled={disabled}\n onClick={() => apply(pending, false)}\n >\n Only this node\n </button>\n </div>\n </Modal>,\n portalHost,\n )}\n </>\n );\n}\n","import type { ReactNode } from \"react\";\nimport type { ApiCallRecord } from \"../types.ts\";\nimport { ResultViewer } from \"./ResultViewer.tsx\";\n\nexport interface ApiCallsPanelProps {\n /** The captured outbound calls to render, in the order they were made. */\n calls: ApiCallRecord[];\n /**\n * Open every call's `<details>` on first render. Default `false` — the wire\n * log is ground truth you reach for, not something to read on every run. A\n * host that already landed the user on ONE specific call (e.g. a drill-down\n * that scoped the list to it) passes `true` so the user isn't made to click\n * twice through their own target.\n */\n defaultOpen?: boolean;\n /**\n * React `key` for each call. Defaults to method + url + array index, which is\n * stable within a single run because captured calls carry no id of their own.\n * A host rendering PERSISTED rows (which do have an id) across a paginated\n * list must pass its own — index keys collide between pages and React then\n * reuses the wrong `<details>` open-state.\n */\n keyOf?: (call: ApiCallRecord, index: number) => string;\n /**\n * Section header. Defaults to `API call(s) (N)`. Pass `false` to suppress it\n * entirely when the host already owns the heading — same idiom as\n * `ActionTestForm`'s `embedded` prop, which suppresses its own pop-out chrome\n * because the host provides it. Any other node replaces the default text.\n */\n title?: ReactNode | false;\n}\n\n/** Captured calls have no id of their own; index is stable within a run. */\nfunction defaultKeyOf(call: ApiCallRecord, index: number): string {\n return `${call.method}-${call.url ?? call.host}-${index}`;\n}\n\n/**\n * The wire log for a run: each outbound HTTP call the action made, with the\n * request we sent and the response we got back. Collapsed by default — it is the\n * ground truth you open when the result looks wrong (e.g. a template variable\n * that came through unrendered), not something to read on every run.\n *\n * Purely presentational: it renders exactly what it is given, with no fetching,\n * no context, and no derivation of state from the calls. Credential redaction\n * happens server-side at capture time (request AND response headers); nothing\n * here re-inspects or re-redacts them.\n */\nexport function ApiCallsPanel({ calls, defaultOpen, keyOf, title }: ApiCallsPanelProps) {\n if (calls.length === 0) return null;\n const key = keyOf ?? defaultKeyOf;\n return (\n <div className=\"w6w-stack\" style={{ gap: 4 }}>\n {title !== false && (\n <strong className=\"w6w-small\">\n {title ?? (\n <>\n API {calls.length === 1 ? \"call\" : \"calls\"} ({calls.length})\n </>\n )}\n </strong>\n )}\n {calls.map((call, i) => (\n <details\n key={key(call, i)}\n open={defaultOpen}\n className=\"w6w-result\"\n style={{ padding: 8 }}\n >\n <summary style={{ cursor: \"pointer\" }}>\n <span className=\"w6w-small\">\n {call.method} {call.url ?? call.host} →{\" \"}\n <strong>{call.error ? \"failed\" : call.status}</strong>\n {call.durationMs !== undefined && (\n <span className=\"w6w-muted\"> · {call.durationMs}ms</span>\n )}\n </span>\n </summary>\n <div className=\"w6w-stack\" style={{ gap: 6, marginTop: 8 }}>\n {call.error && <div className=\"w6w-error w6w-small\">{call.error}</div>}\n <div className=\"w6w-muted w6w-small\">Request headers</div>\n <pre className=\"w6w-result\">{JSON.stringify(call.requestHeaders ?? {}, null, 2)}</pre>\n {call.requestBody && (\n <>\n <div className=\"w6w-muted w6w-small\">Request body</div>\n <ResultViewer value={call.requestBody} maxHeight={240} />\n </>\n )}\n <div className=\"w6w-muted w6w-small\">Response headers</div>\n <pre className=\"w6w-result\">{JSON.stringify(call.responseHeaders ?? {}, null, 2)}</pre>\n {call.responseBody && (\n <>\n <div className=\"w6w-muted w6w-small\">Response body</div>\n <ResultViewer value={call.responseBody} maxHeight={240} />\n </>\n )}\n {call.truncated && (\n <div className=\"w6w-muted w6w-small\">\n A captured body exceeded the size cap and was truncated.\n </div>\n )}\n </div>\n </details>\n ))}\n </div>\n );\n}\n","import type { EventbriteTriggerChoices } from \"../eventbrite-trigger-selection.ts\";\n\n/** The same event list the app's webhook registration uses, saved as activity/actions. */\nexport function EventbriteTriggerPicker({\n choices,\n onChange,\n readOnly,\n}: {\n choices: EventbriteTriggerChoices;\n onChange: (actions: string[]) => void;\n readOnly?: boolean;\n}) {\n const selected = new Set(choices.selected);\n const all = choices.options.every((o) => selected.has(o.value));\n const options = [\n ...choices.options,\n ...choices.selected\n .filter((value) => !choices.options.some((o) => o.value === value))\n .map((value) => ({ value, label: value })),\n ];\n return (\n <div className=\"w6w-field\">\n <span>Triggers *</span>\n <div className=\"w6w-multiselect-checks\">\n <div className=\"w6w-multiselect-checks-toolbar\">\n <label className=\"w6w-multiselect-check\">\n <input\n type=\"checkbox\"\n checked={all}\n ref={(el) => {\n if (el) el.indeterminate = !all && selected.size > 0;\n }}\n disabled={readOnly}\n onChange={(e) =>\n onChange(e.target.checked ? choices.options.map((o) => o.value) : [])\n }\n />\n <span>All events</span>\n </label>\n <span className=\"w6w-muted w6w-small\">{selected.size} selected</span>\n </div>\n <fieldset className=\"w6w-multiselect-checks-options\" aria-label=\"Eventbrite events\">\n {options.map((option) => (\n <label key={option.value} className=\"w6w-multiselect-check\">\n <input\n type=\"checkbox\"\n checked={selected.has(option.value)}\n disabled={readOnly}\n onChange={(e) =>\n onChange(\n e.target.checked\n ? [...choices.selected, option.value]\n : choices.selected.filter((v) => v !== option.value),\n )\n }\n />\n <span>{option.label}</span>\n </label>\n ))}\n </fieldset>\n </div>\n <span className=\"w6w-hint\">Start this workflow when any selected event occurs.</span>\n </div>\n );\n}\n","/**\n * InternalIcon — an internal pseudo-app's glyph on a rounded tile, sized and\n * shaped to match `AppIcon`'s image tile so internal (`@w6w/*`) nodes and app\n * nodes read as the same family everywhere they appear (canvas, add-step\n * picker, edit modal). The glyph markup comes from the node def\n * (`InternalNodeDef.icon` / `internalNodeIcon`) — static, in-repo SVG (no user\n * input). It strokes with the accent color and tracks the active theme.\n *\n * Deliberately NOT the shared `Icon` (`./Icon.tsx`), despite owning an `<svg>`:\n * this is a DATA-DRIVEN per-app identity mark — its content is a markup string\n * off the node def, one glyph per internal app, not a fixed UI glyph with a name\n * in the set (`./icons.tsx`). Unifying them would mean changing\n * `InternalNodeDef` to carry a name instead of its markup, which is a data-model\n * change, not an icon migration.\n */\nexport function InternalIcon({ icon, size = 28 }: { icon: string; size?: number }) {\n return (\n <span\n aria-hidden=\"true\"\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: size,\n height: size,\n borderRadius: 6,\n flexShrink: 0,\n background: \"var(--w6w-icon-swatch, var(--w6w-panel-2))\",\n color: \"var(--w6w-accent)\",\n }}\n >\n <svg\n width={Math.round(size * 0.6)}\n height={Math.round(size * 0.6)}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n // biome-ignore lint/security/noDangerouslySetInnerHtml: static, in-repo SVG glyph markup (no user input)\n dangerouslySetInnerHTML={{ __html: icon }}\n />\n </span>\n );\n}\n","import type { ActionDef } from \"./types.ts\";\n\nexport interface EventbriteTriggerChoices {\n triggerKey: string;\n options: { value: string; label: string; triggerKey: string }[];\n selected: string[];\n}\n\n/** Eventbrite's activity trigger registers several events on one webhook. Keep its\n * event catalog in the app manifest; the editor only adapts the existing trigger keys. */\nexport function eventbriteTriggerChoices(\n appId: string,\n triggers: ActionDef[] | null,\n triggerKey: string,\n values: Record<string, unknown>,\n): EventbriteTriggerChoices | null {\n if (appId !== \"io.w6w.eventbrite\") return null;\n const activity = triggers?.find((t) => t.key === \"activity\");\n const actions = activity?.params?.find((p) => p.key === \"actions\" && p.type === \"multiselect\");\n if (!activity || !Array.isArray(actions?.options) || !actions.options.length) return null;\n const options = actions.options.map((option) => {\n const value = String(option.value);\n const key = value.replace(/[._]/g, \"-\");\n return {\n value,\n label: triggers?.find((t) => t.key === key)?.title ?? option.label,\n triggerKey: key,\n };\n });\n const fixed = options.find((o) => o.triggerKey === triggerKey);\n if (triggerKey && triggerKey !== activity.key && !fixed) return null;\n // Advanced JSON can bind actions dynamically. Keep its normal param editor rather than\n // presenting an empty checklist that would silently discard that binding.\n if (triggerKey === activity.key && values.actions != null && !Array.isArray(values.actions)) {\n return null;\n }\n return {\n triggerKey: activity.key,\n options: options.sort((a, b) => a.label.localeCompare(b.label)),\n selected: fixed\n ? [fixed.value]\n : Array.isArray(values.actions)\n ? values.actions.filter((v): v is string => typeof v === \"string\")\n : [],\n };\n}\n","/**\n * The pure loop core: the canvas-only `each` lane, body derivation, and the\n * lifecycle helpers that keep a For each's `with.body` consistent.\n *\n * ## The model\n *\n * On the canvas a loop body is a chain of **each-lane** edges (`data.when:\n * \"each\"`) leaving the For each, `F → b0 → b1 → …`. The lane is **never\n * serialized**: {@link loopBodies} derives `with.body` from those edges on every\n * save and a stored `body` is never trusted. On load the body is drawn back as\n * each-lane edges ({@link definitionLoops} decides what a definition's loops are).\n *\n * Mirrors the engine's `plan.ts`: `controlOwnedIds` (foreach `body`, parallel\n * `branches`, if `then`/`else`), the \"claimed by more than one control\" check, and\n * the implicit chain restricted to main-graph steps. Any edge touching an owned\n * step is a PlanError there — so nothing here ever lets one be emitted.\n *\n * Internal to `@w6w/ui`: NOT re-exported from `flow.ts`/`index.ts` (T2.3.2 adds\n * what it needs). Keep this file JSX-free.\n */\nimport type { Edge } from \"@xyflow/react\";\nimport { edgeLane } from \"./flow-connect.ts\";\nimport {\n CONTROL_APP,\n EACH_SOURCE_HANDLE,\n FOREACH_EACH_ROUTE,\n type FlowEdge,\n type FlowStep,\n type FlowWorkflow,\n ROUTER_APP,\n edgeVisuals,\n routeHandle,\n} from \"./flow-types.ts\";\nimport { type StepNode, flowEdgeId } from \"./flow-utils.ts\";\n\ntype UsesLike = { uses?: { app?: string; action?: string } };\n\n/** A step is a foreach iff it is `@w6w/control` · `foreach` (P1). */\nexport function isForeachStep(step: UsesLike | undefined): boolean {\n return step?.uses?.app === CONTROL_APP && step.uses.action === \"foreach\";\n}\n\nfunction isControlStep(step: UsesLike | undefined): boolean {\n return step?.uses?.app === CONTROL_APP;\n}\n\n/** A loop body may contain an If gate or a Router; nested control blocks need their own canvas model. */\nfunction isLoopBodyStep(step: FlowStep | undefined): boolean {\n if (step?.uses.app === ROUTER_APP) return true;\n return (\n !isControlStep(step) ||\n (step?.uses.action === \"if\" && step.with?.then === undefined && step.with?.else === undefined)\n );\n}\n\n/**\n * The step ids a control step owns — engine `controlOwnedIds`, arm for arm\n * (foreach `body`, parallel `branches`, if `then`/`else`; strings at any array depth).\n */\nexport function controlOwnedIds(step: FlowStep): string[] {\n if (!isControlStep(step)) return [];\n const w = step.with ?? {};\n const out: string[] = [];\n const collect = (v: unknown) => {\n if (typeof v === \"string\") out.push(v);\n else if (Array.isArray(v)) for (const el of v) collect(el);\n };\n collect(w.body);\n collect(w.branches);\n collect(w.then);\n collect(w.else);\n return out;\n}\n\n/** Every step id owned by some control step (engine `ownedByControl`). */\nexport function ownedStepIds(steps: readonly FlowStep[]): Set<string> {\n const owned = new Set<string>();\n for (const s of steps) for (const id of controlOwnedIds(s)) owned.add(id);\n return owned;\n}\n\n/** A canvas each-lane edge in the ONE shape load, bridge and `applyConnect` share (P3). */\nexport function eachLaneEdge(\n from: string,\n to: string,\n fromIsForeach: boolean,\n route?: string,\n): Edge {\n return {\n id: flowEdgeId(from, to, \"each\", route),\n source: from,\n target: to,\n sourceHandle:\n route !== undefined ? routeHandle(route) : fromIsForeach ? EACH_SOURCE_HANDLE : undefined,\n animated: false,\n data: { when: \"each\", ...(route === undefined ? {} : { route }) },\n ...edgeVisuals(\"each\", undefined),\n };\n}\n\n// ── Canvas side ────────────────────────────────────────────────────────────\n\nconst routeOf = (e: Edge): string | undefined =>\n typeof e.data?.route === \"string\" ? e.data.route : undefined;\n\n/**\n * The body drawn from `foreachId`: every step reachable from its Each-item port\n * over each-lane edges, as a topological order (Kahn over the body's own each-lane\n * edges, ties broken by discovery order) so the Each-item target is first and every\n * edge goes from an earlier id to a later one. A plain chain comes out exactly as\n * the chain. Never includes `foreachId` or a repeat — so it terminates on a cycle\n * (steps stuck in one are appended in discovery order). `claimed` (internal) stops\n * the walk BEFORE a step an earlier foreach already owns.\n */\nexport function loopBody(\n foreachId: string,\n nodes: readonly StepNode[],\n edges: readonly Edge[],\n claimed?: ReadonlySet<string>,\n): string[] {\n const exists = new Set(nodes.map((n) => n.id));\n const each = edges.filter((e) => edgeLane(e) === \"each\");\n const seen = new Set<string>([foreachId]);\n const found: string[] = [];\n const queue = [foreachId];\n for (let q = 0; q < queue.length; q++) {\n for (const e of each) {\n if (e.source !== queue[q]) continue;\n if (!exists.has(e.target) || seen.has(e.target) || claimed?.has(e.target)) continue;\n seen.add(e.target);\n found.push(e.target);\n queue.push(e.target);\n }\n }\n const order = new Map(found.map((id, i) => [id, i]));\n const internal = each.filter(\n (e) => e.source !== foreachId && order.has(e.source) && order.has(e.target),\n );\n const indeg = new Map(found.map((id) => [id, 0]));\n for (const e of internal) indeg.set(e.target, (indeg.get(e.target) ?? 0) + 1);\n const out: string[] = [];\n const done = new Set<string>();\n for (;;) {\n const next = found.find((id) => !done.has(id) && indeg.get(id) === 0);\n if (next === undefined) break;\n done.add(next);\n out.push(next);\n for (const e of internal)\n if (e.source === next) indeg.set(e.target, (indeg.get(e.target) ?? 0) - 1);\n }\n for (const id of found) if (!done.has(id)) out.push(id);\n return out;\n}\n\n/** The each-lane edges with both ends inside `body` (the For each → body[0] link is not one). */\nexport function bodyInternalEdges(body: readonly string[], edges: readonly Edge[]): Edge[] {\n const ids = new Set(body);\n return edges.filter((e) => edgeLane(e) === \"each\" && ids.has(e.source) && ids.has(e.target));\n}\n\n/**\n * A body is plain iff it is a chain the ordered `with.body` list already says: every\n * body node has at most one outgoing each-lane edge and none carries a route. Plain\n * bodies serialize as the list alone; anything else also emits its body edges.\n */\nexport function isPlainBody(body: readonly string[], edges: readonly Edge[]): boolean {\n const internal = bodyInternalEdges(body, edges);\n const outs = new Set<string>();\n for (const e of internal) {\n if (routeOf(e) !== undefined || outs.has(e.source)) return false;\n outs.add(e.source);\n }\n return true;\n}\n\n/** The definition edges a canvas's non-plain loop bodies need (empty for plain chains). */\nexport function loopBodyDefinitionEdges(\n nodes: readonly StepNode[],\n edges: readonly Edge[],\n): FlowEdge[] {\n const out: FlowEdge[] = [];\n for (const body of loopBodies(nodes, edges).values()) {\n if (isPlainBody(body, edges)) continue;\n for (const e of bodyInternalEdges(body, edges)) {\n const route = routeOf(e);\n out.push({ from: e.source, to: e.target, ...(route === undefined ? {} : { route }) });\n }\n }\n return out;\n}\n\n/** Every foreach's body, handled in `nodes` order so emitted bodies are disjoint (P6). */\nexport function loopBodies(\n nodes: readonly StepNode[],\n edges: readonly Edge[],\n): Map<string, string[]> {\n const out = new Map<string, string[]>();\n const claimed = new Set<string>();\n for (const n of nodes) {\n if (!isForeachStep(n.data?.step)) continue;\n const chain = loopBody(n.id, nodes, edges, claimed);\n for (const id of chain) claimed.add(id);\n out.set(n.id, chain);\n }\n return out;\n}\n\n/** `bodyStepId → foreachId` over the whole canvas. */\nexport function loopMembership(\n nodes: readonly StepNode[],\n edges: readonly Edge[],\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [fid, chain] of loopBodies(nodes, edges)) for (const id of chain) out[id] = fid;\n return out;\n}\n\n/**\n * The edge set after deleting step `id` (D-A4). A body step with exactly one inbound\n * and one outbound each-lane edge is bridged (`prev → next`, each lane, keeping the\n * inbound edge's route when `prev` is an If/Router, `out-each` iff `prev` is the\n * foreach); any other body step just loses its incident edges; deleting the foreach\n * also removes the each-lane edges of its whole body (the body steps stay, as\n * ordinary unconnected nodes). A non-body step is the plain incident-edge filter.\n */\nexport function bridgeDeletedBodyStep(\n id: string,\n nodes: readonly StepNode[],\n edges: readonly Edge[],\n): Edge[] {\n const incident = (e: Edge) => e.source === id || e.target === id;\n const plain = edges.filter((e) => !incident(e));\n const stepOf = (nid: string) => nodes.find((n) => n.id === nid)?.data?.step;\n if (isForeachStep(stepOf(id))) {\n const body = loopBody(id, nodes, edges);\n const inBody = new Set(body);\n return plain.filter(\n (e) =>\n !(\n edgeLane(e) === \"each\" &&\n (e.source === id || inBody.has(e.source)) &&\n inBody.has(e.target)\n ),\n );\n }\n const fid = loopMembership(nodes, edges)[id];\n if (fid === undefined) return plain;\n const ins = edges.filter((e) => e.target === id && edgeLane(e) === \"each\");\n const outs = edges.filter((e) => e.source === id && edgeLane(e) === \"each\");\n if (ins.length !== 1 || outs.length !== 1) return plain;\n const prev = ins[0].source;\n const next = outs[0].target;\n if (plain.some((e) => e.source === prev && e.target === next && edgeLane(e) === \"each\")) {\n return plain;\n }\n return [...plain, eachLaneEdge(prev, next, prev === fid, routeOf(ins[0]))];\n}\n\n/** `with.body` is the derived view of the each lane — drop it from a foreach (P1); other steps untouched. */\nexport function stripBody<T extends UsesLike & { with?: Record<string, unknown> }>(step: T): T {\n if (!isForeachStep(step) || !step.with || !(\"body\" in step.with)) return step;\n const { body: _body, ...rest } = step.with;\n return { ...step, with: rest };\n}\n\n// ── Connect-time refusal (T2.3.1) ──────────────────────────────────────────\n\n/** Why a connection would break the v1 linear-body rule (exhaustive; see {@link loopRefusal}). */\nexport type LoopRefusalReason =\n | \"error_lane_in_body\"\n | \"outside_inbound\"\n | \"loop_cycle\"\n | \"already_in_loop\"\n | \"control_in_body\"\n | \"body_branch\"\n | \"body_exit\";\n\n/**\n * The loop rule for drawing `source → target` in `lane` (already promoted: a success\n * connect from a body node arrives as `\"each\"`). First match wins. Pure; run on the\n * INPUT edges, never a post-eviction set.\n */\nexport function loopRefusal(\n source: string,\n target: string,\n lane: \"success\" | \"error\" | \"each\",\n nodes: StepNode[],\n edges: Edge[],\n): LoopRefusalReason | null {\n const M = loopMembership(nodes, edges);\n if (lane === \"error\") {\n return M[source] !== undefined || M[target] !== undefined ? \"error_lane_in_body\" : null;\n }\n if (lane === \"success\") return M[target] !== undefined ? \"outside_inbound\" : null;\n const stepOf = (id: string) => nodes.find((n) => n.id === id)?.data?.step;\n const owner = isForeachStep(stepOf(source)) ? source : M[source];\n if (owner === undefined) return null;\n if (target === owner) return \"loop_cycle\";\n // The only shape rule: the For each's Each-item port takes ONE edge. Downstream of\n // its first step the body is an ordinary graph (fan-out and joins; port capacity is\n // the caller's out-cap census).\n const branches = (): boolean =>\n source !== owner || !edges.some((e) => e.source === source && edgeLane(e) === \"each\");\n if (M[target] === owner) {\n // A join inside the same body: fine unless it closes a cycle (or re-enters via the For each).\n if (source === owner) return \"loop_cycle\";\n if (reaches(target, source, edges)) return \"loop_cycle\";\n return branches() ? null : \"body_branch\";\n }\n if (M[target] !== undefined) return \"already_in_loop\";\n if (!isLoopBodyStep(stepOf(target))) return \"control_in_body\";\n if (!branches()) return \"body_branch\";\n if (edges.some((e) => e.source === target || e.target === target)) return \"body_exit\";\n return null;\n}\n\n/** True when `to` is reachable from `from` over each-lane edges (or they are the same step). */\nfunction reaches(from: string, to: string, edges: readonly Edge[]): boolean {\n const seen = new Set<string>([from]);\n const stack = [from];\n while (stack.length > 0) {\n const cur = stack.pop() as string;\n if (cur === to) return true;\n for (const e of edges) {\n if (e.source !== cur || edgeLane(e) !== \"each\" || seen.has(e.target)) continue;\n seen.add(e.target);\n stack.push(e.target);\n }\n }\n return false;\n}\n\n/** The author-facing sentence for each refusal (shown in the node-anchored notice). */\nconst LOOP_REFUSAL_MESSAGES: Record<LoopRefusalReason, string> = {\n error_lane_in_body:\n \"A step inside a loop can't have an error connection. Handle the failure outside the loop.\",\n outside_inbound:\n \"This step is inside a loop, so nothing outside it can connect into it. Connect from the loop's Each item side instead.\",\n loop_cycle: \"A loop body can't connect back to its own For each.\",\n already_in_loop: \"That step is already inside another loop.\",\n control_in_body:\n \"A loop body supports plain steps, If conditions and Routers. Nested control blocks aren't supported here yet.\",\n body_branch:\n \"A For each's Each item port connects to one first step. Branch inside the loop from that step onward.\",\n body_exit:\n \"That step is already connected elsewhere in the workflow. Use a step with no connections, or disconnect it first.\",\n};\n\nexport function loopRefusalMessage(reason: LoopRefusalReason): string {\n return LOOP_REFUSAL_MESSAGES[reason];\n}\n\n/**\n * Set or clear `data.loopOf` from {@link loopMembership}. Same array reference when\n * nothing changed, and the same node object for every unchanged node.\n */\nexport function stampLoopOf(nodes: StepNode[], edges: Edge[]): StepNode[] {\n const M = loopMembership(nodes, edges);\n let changed = false;\n const out = nodes.map((n) => {\n const want = M[n.id];\n if (n.data.loopOf === want) return n;\n changed = true;\n if (want === undefined) {\n const { loopOf: _drop, ...data } = n.data;\n return { ...n, data };\n }\n return { ...n, data: { ...n.data, loopOf: want } };\n });\n return changed ? out : nodes;\n}\n\n/** The delete-confirm text. Byte-identical to the plain message unless a For each owns a body. */\nexport function deleteStepMessage(id: string, nodes: StepNode[], edges: Edge[]): string {\n const base = `Delete node \"${id}\"? Its connections are removed too.`;\n const step = nodes.find((n) => n.id === id)?.data?.step;\n if (!isForeachStep(step)) return base;\n const body = loopBody(id, nodes, edges);\n if (body.length === 0) return base;\n return `${base} Its loop body steps ${body.map((b) => `\"${b}\"`).join(\", \")} stay as standalone steps.`;\n}\n\n// ── Definition side ────────────────────────────────────────────────────────\n\nexport type LoopInvalidReason =\n | \"body_not_literal\"\n | \"body_unknown_step\"\n | \"body_self\"\n | \"body_duplicate\"\n | \"body_claimed_twice\"\n | \"body_contains_control\"\n | \"body_step_has_edges\"\n | \"legacy_not_linear\";\n\nexport type LoopInvalid = { reason: LoopInvalidReason; stepId?: string };\nexport type LoopResult =\n | { body: string[]; source: \"body\" | \"legacy\"; edges?: FlowEdge[] }\n | { invalid: LoopInvalid };\n\n/** The edges the engine would run: declared, else the implicit chain over main-graph (non-owned) steps. */\nexport function effectiveEdges(wf: FlowWorkflow): FlowEdge[] {\n if (wf.edges) return wf.edges;\n const owned = ownedStepIds(wf.nodes);\n const main = wf.nodes.filter((s) => !owned.has(s.id));\n const out: FlowEdge[] = [];\n for (let i = 0; i < main.length - 1; i++) out.push({ from: main[i].id, to: main[i + 1].id });\n return out;\n}\n\nconst isSuccess = (e: FlowEdge) => (e.when ?? \"success\") === \"success\";\n\n/** A saved For each → `body[0]` link ({@link FOREACH_EACH_ROUTE}); the canvas draws it from `with.body`. */\nexport const isEachLink = (e: FlowEdge): boolean => e.route === FOREACH_EACH_ROUTE && isSuccess(e);\n\n/**\n * What each foreach's loop is, in a stored definition — the ONE place that knows\n * the legacy-chain rule (D-A3). A foreach carrying a `body` key is judged on it;\n * one without is a legacy loop iff its success-lane successors form a valid linear\n * chain (every node a non-control step owned by no control, whose only inbound edge\n * is from its predecessor and whose only outbound edge is a success edge onward).\n */\nexport function definitionLoops(wf: FlowWorkflow): Record<string, LoopResult> {\n const byId = new Map(wf.nodes.map((s) => [s.id, s]));\n const owners = new Map<string, Set<string>>();\n for (const s of wf.nodes) {\n for (const sub of controlOwnedIds(s)) {\n const set = owners.get(sub) ?? new Set<string>();\n set.add(s.id);\n owners.set(sub, set);\n }\n }\n const edges = effectiveEdges(wf);\n const declared = wf.edges ?? [];\n const out: Record<string, LoopResult> = {};\n\n for (const f of wf.nodes) {\n if (!isForeachStep(f)) continue;\n const w = f.with ?? {};\n if (\"body\" in w) {\n out[f.id] = literalBody(f.id, w.body);\n continue;\n }\n out[f.id] = legacyBody(f.id);\n }\n return out;\n\n function literalBody(fid: string, body: unknown): LoopResult {\n const bad = (reason: LoopInvalidReason, stepId?: string): LoopResult => ({\n invalid: stepId === undefined ? { reason } : { reason, stepId },\n });\n if (!Array.isArray(body) || body.some((b) => typeof b !== \"string\")) {\n return bad(\"body_not_literal\");\n }\n const ids = body as string[];\n const inBody = new Set(ids);\n const seen = new Set<string>();\n for (const id of ids) {\n if (!byId.has(id)) return bad(\"body_unknown_step\", id);\n if (id === fid) return bad(\"body_self\", id);\n if (seen.has(id)) return bad(\"body_duplicate\", id);\n seen.add(id);\n if (!isLoopBodyStep(byId.get(id))) return bad(\"body_contains_control\", id);\n const own = owners.get(id);\n if (own && [...own].some((o) => o !== fid)) return bad(\"body_claimed_twice\", id);\n }\n // Body edges: success-lane edges with BOTH ends in this body, never into body[0].\n // The For each's own Each item link to body[0] restates the list. Any other edge\n // touching a body step is still refused.\n const bodyEdges: FlowEdge[] = [];\n for (const e of declared) {\n if (isEachLink(e) && e.from === fid && e.to === ids[0]) continue;\n const touches = inBody.has(e.from) || inBody.has(e.to);\n if (!touches) continue;\n const internal = inBody.has(e.from) && inBody.has(e.to) && isSuccess(e) && e.to !== ids[0];\n if (!internal) return bad(\"body_step_has_edges\", inBody.has(e.from) ? e.from : e.to);\n bodyEdges.push(e);\n }\n return bodyEdges.length > 0\n ? { body: ids, source: \"body\", edges: bodyEdges }\n : { body: ids, source: \"body\" };\n }\n\n function legacyBody(fid: string): LoopResult {\n // A routed edge names its port (Done), so only the unrouted shape can be a legacy chain.\n const succ = edges.filter((e) => e.from === fid && isSuccess(e) && e.route === undefined);\n if (succ.length === 0) return { body: [], source: \"body\" };\n const bad = (stepId: string): LoopResult => ({\n invalid: { reason: \"legacy_not_linear\", stepId },\n });\n if (succ.length > 1) return bad(fid);\n const chain: string[] = [];\n const seen = new Set<string>([fid]);\n let prev = fid;\n let next: string | undefined = succ[0].to;\n while (next !== undefined) {\n const n: string = next;\n const step = byId.get(n);\n if (!step || seen.has(n) || !isLoopBodyStep(step) || owners.has(n)) return bad(n);\n const inbound = edges.filter((e) => e.to === n);\n if (inbound.length !== 1 || inbound[0].from !== prev) return bad(n);\n const outbound = edges.filter((e) => e.from === n);\n if (outbound.length > 1 || (outbound.length === 1 && !isSuccess(outbound[0]))) return bad(n);\n seen.add(n);\n chain.push(n);\n prev = n;\n next = outbound[0]?.to;\n }\n return { body: chain, source: \"legacy\" };\n }\n}\n","/**\n * Connection rules for the flow canvas: which edges may be drawn, what the edge\n * set becomes once one is, and how edge ids are rewritten when a step is renamed.\n *\n * These are total, pure functions of `(source, target, nodes, edges)` and they\n * live in a **`.ts`** module on purpose. They used to sit inside\n * `WorkflowFlowEditor.tsx`, where Node's type-stripping test runner cannot reach\n * them (it cannot parse JSX), so the exit-port capacity rule — the highest-risk\n * decision in the editor's wiring — was covered only by inspection. Here it is\n * covered by `flow-connect.test.ts` (`node --test`, no new dependency). Keep this\n * file JSX-free.\n *\n * Internal to `@w6w/ui`: imported by relative path, deliberately NOT re-exported\n * from `index.ts` / `flow.ts`.\n */\nimport { type Edge, addEdge } from \"@xyflow/react\";\nimport { type LoopRefusalReason, isForeachStep, loopMembership, loopRefusal } from \"./flow-loop.ts\";\nimport {\n type CanvasLane,\n FOREACH_DONE_ROUTE,\n IF_FALSE_ROUTE,\n type PortsLookup,\n RACE_APP,\n ROUTER_APP,\n edgeVisuals,\n isIfStep,\n nodePortsForStep,\n routeHandle,\n routesForStep,\n sourceHandleForLane,\n} from \"./flow-types.ts\";\nimport { type StepNode, flowEdgeId } from \"./flow-utils.ts\";\n\n/**\n * Which lane a React Flow edge belongs to (core `rfcs/workflow.md` · `Edge.when`\n * amendment). **Omitted ⇒ `\"success\"`**, and read defensively: an edge that\n * predates the `data.when` stamp — or one React Flow synthesised — may carry no\n * `data` at all. The single accessor: every consumer calls this rather than\n * re-deriving the fallback, so \"absent means success\" is decided once.\n */\nexport function edgeLane(e: Edge): CanvasLane {\n const when = (e.data as { when?: string } | undefined)?.when;\n return when === \"error\" ? \"error\" : when === \"each\" ? \"each\" : \"success\";\n}\n\n/**\n * A refused connection: the source's exit port is full **in this lane** and the cap\n * is finite. Drawing past a finite `out` cap is refused, never satisfied by evicting\n * an existing edge (an unbounded `\"many\"` out never refuses).\n */\nexport type OutCapRefusal = { refused: \"out_cap\"; cap: number };\n\n/**\n * A refused connection that would break the v1 linear-body rule of a For each\n * (see {@link loopRefusal}). Raised before the out-cap census and before any\n * inbound eviction, always against the INPUT edges.\n */\nexport type LoopRefusal = { refused: \"loop\"; reason: LoopRefusalReason };\n\n/**\n * The id of the edge in `survivors` that `id` would duplicate, or `null` when it is\n * free — **the one id-uniqueness test in this module**, shared by the creation path\n * ({@link planConnect}) and the re-lane path ({@link planRelane}).\n *\n * Both paths must answer the same question because `flowEdgeId` is not injective\n * over free-text step ids: a step literally named `b:error` makes `a → b` in the\n * error lane and `a → \"b:error\"` in the success lane mint ONE id. React Flow's store\n * is id-keyed, so a duplicate id is not an error — it is one of the two wires\n * silently vanishing from the canvas, which reads as the editor losing the author's\n * work. Two independent copies of this test is how one order (mark, then draw) got\n * through while the other (draw, then mark) was refused.\n *\n * Always called with the edges that **survive** eviction, never the whole set: a\n * collider the same call evicts is not a collision (see `flow-connect.test.ts`\n * case 11).\n */\nfunction collidingEdgeId(survivors: Edge[], id: string): string | null {\n return survivors.find((e) => e.id === id)?.id ?? null;\n}\n\n/**\n * The hard rules for an edge `source → target` — the ones no amount of\n * replacement can satisfy: a real, *distinct* pair (no self-loops), no duplicate\n * edge, the target accepts an entry port (blocks connecting *into* a trigger,\n * which declares `in: 0`), and the source has an exit port. Port **capacity** is\n * deliberately NOT checked here: an input accepts any number of edges, and the exit\n * cap is refused in `applyConnect`. Used as the live `isValidConnection`.\n *\n * The duplicate-pair check is **lane-blind by design**, and that is a v1 *editor*\n * limit, not a model limit: the model permits a success edge and an error edge\n * between the same two steps (D-T1-8 widened the engine's `skippedEdges` key so\n * they cannot collide), but v1 declines to author that pair because there are no\n * id'd source handles to pick the lane from (D-T1-7).\n *\n * A colliding minted **id** is deliberately NOT rejected here, even though\n * {@link applyConnect} refuses it: this predicate is the live `isValidConnection`,\n * and a `false` here means React Flow never fires `onConnect`, so the editor never\n * gets to *say why*. That refusal is invisible (and, worse, lands in\n * `onConnectEnd`'s \"dropped on empty canvas\" branch, which opens the step builder).\n * Letting the drop through and refusing in `applyConnect` is what lets the reason\n * paint — see {@link connectConflict}.\n */\nexport function canConnect(\n source: string | null | undefined,\n target: string | null | undefined,\n nodes: StepNode[],\n edges: Edge[],\n lookup?: PortsLookup,\n route?: string,\n): boolean {\n if (!source || !target || source === target) return false;\n if (edges.some((e) => e.source === source && e.target === target && e.data?.route === route))\n return false;\n const srcStep = nodes.find((n) => n.id === source)?.data.step;\n const tgtStep = nodes.find((n) => n.id === target)?.data.step;\n if (!srcStep || !tgtStep) return false;\n // Only presence matters: `in: 0` (a trigger) takes no edge; any `in >= 1` takes many.\n const srcPorts = nodePortsForStep(srcStep, lookup);\n const tgtPorts = nodePortsForStep(tgtStep, lookup);\n return srcPorts.out >= 1 && tgtPorts.in >= 1;\n}\n\n/**\n * The plan for a new `source → target` connection: the resulting edge set, plus the\n * id of an existing edge the minted id would **collide** with (`null` when it is\n * safe). The creation-path twin of {@link planRelane}, deliberately the same shape —\n * both public entry points read off this one plan, so the eviction arithmetic and\n * the id-uniqueness test are computed once, in the right order (the collision is\n * tested against the edges that SURVIVE eviction).\n */\nfunction planConnect(\n source: string | null | undefined,\n target: string | null | undefined,\n nodes: StepNode[],\n edges: Edge[],\n when: CanvasLane,\n lookup?: PortsLookup,\n drawnRoute?: string,\n): { next: Edge[]; conflict: string | null; refusal: OutCapRefusal | LoopRefusal | null } | null {\n // A For each's success connect is its Done port, routed so it never reads as Each item.\n const fromForeach =\n when === \"success\" && isForeachStep(nodes.find((n) => n.id === source)?.data.step);\n const route = fromForeach && drawnRoute === undefined ? FOREACH_DONE_ROUTE : drawnRoute;\n if (!canConnect(source, target, nodes, edges, lookup, route) || !source || !target) return null;\n const srcStep = nodes.find((n) => n.id === source)?.data.step;\n const tgtStep = nodes.find((n) => n.id === target)?.data.step;\n if (!srcStep || !tgtStep) return null;\n const srcIsIf = isIfStep(srcStep);\n if (fromForeach) {\n if (route !== FOREACH_DONE_ROUTE) return null;\n } else if (srcStep.uses.app === ROUTER_APP && when === \"success\") {\n if (!routesForStep(srcStep).some((r) => r.id === route)) return null;\n } else if (srcIsIf && when === \"success\") {\n // An If's True port is unrouted; its False port is the one route it has.\n if (route !== undefined && route !== IF_FALSE_ROUTE) return null;\n } else if (route !== undefined) return null;\n // A success connect drawn from a body node extends the body (its ordinary right\n // handle is the only one it has), so it is an each-lane edge. Computed once.\n const inBody = loopMembership(nodes, edges)[source] !== undefined;\n const effLane: CanvasLane = when === \"success\" && inBody ? \"each\" : when;\n // An each lane from something that is neither a For each nor a body step has no\n // handle to be drawn from: it must not mint an edge.\n if (effLane === \"each\" && !inBody && !isForeachStep(srcStep)) return null;\n // The loop rule runs on the INPUT edges, before the out-cap census and before\n // the inbound eviction (D-A6) — so a refused drop never evicts anything.\n const loopReason = loopRefusal(source, target, effLane, nodes, edges);\n if (loopReason) {\n return { next: edges, conflict: null, refusal: { refused: \"loop\", reason: loopReason } };\n }\n const srcPorts = nodePortsForStep(srcStep, lookup);\n const next = edges;\n // The source's exit port IN THIS LANE is full at a finite cap: REFUSE. Nothing is\n // evicted — `next` stays the input edge set. The other lane is untouched.\n const fromSrc = next.filter(\n (e) => e.source === source && edgeLane(e) === effLane && e.data?.route === route,\n );\n // A Router route holds one edge; an If's False port fans out like its True port.\n const cap = route === undefined || srcIsIf || fromForeach ? srcPorts.out : 1;\n if (fromSrc.length >= cap) {\n return { next: edges, conflict: null, refusal: { refused: \"out_cap\", cap } };\n }\n // The target's entry port is never full: an input takes any number of inbound edges, so a\n // connect only ever ADDS (`in: 0`, a trigger, is refused by canConnect).\n // Stamp the lane at creation: a freshly drawn wire is a success edge unless the\n // caller says otherwise, and flowToWorkflow reads `data.when` back off the edge\n // (it would see `undefined` otherwise). \"success\" is emitted as ABSENT on the\n // way out. The id comes from `flowEdgeId`, so an error edge is qualified and\n // cannot collide with its success sibling. `sourceHandle` is stamped by\n // EXPLICIT assignment (T1.1.1) so the anchor follows the lane the same way\n // `id`/`data` do. `edgeVisuals(when)` (className/label) is spread here too —\n // 2026-08-30 fix: a freshly DRAWN error edge previously carried the right\n // `data.when`/`sourceHandle` (so it persisted and reloaded correctly) but\n // rendered with no red dash / \"on error\" label until the next page load,\n // because only `planRelane` (re-laning an EXISTING edge) applied it — the\n // create path never did. Same trap `planRelane`'s own comment warns about:\n // this must be an explicit spread here, not left for a later re-render.\n const id = flowEdgeId(source, target, effLane, route);\n // A body node has no Each-item handle: stamping `out-each` there would leave the\n // edge unrendered, so only the For each itself anchors to it.\n const sourceHandle = effLane === \"each\" && inBody ? undefined : sourceHandleForLane(effLane);\n return {\n next: addEdge(\n {\n source,\n target,\n id,\n sourceHandle: route === undefined ? sourceHandle : routeHandle(route),\n data: { when: effLane, ...(route === undefined ? {} : { route }) },\n // No run state: this mints a freshly DRAWN edge, never a run-taken\n // one — the live run-aware repaint is a separate effect\n // (WorkflowFlowEditor.tsx, T1.1.1), not this creation path.\n ...edgeVisuals(effLane, undefined),\n },\n next,\n ),\n conflict: collidingEdgeId(next, id),\n refusal: null,\n };\n}\n\n/**\n * Build the next edge set for a new `source → target` connection. **Additive at the\n * source**: a source under its `out` cap (or unbounded) keeps every existing edge and\n * gains one; at a finite cap the connection is **refused** (see {@link connectRefusal}),\n * never satisfied by evicting. The target's entry port accepts any number of\n * inbound edges, so nothing is ever evicted there. Returns `null` when the\n * connection is disallowed by {@link canConnect}, refused at the out cap — **or when the minted id would\n * duplicate a surviving edge's id**, the same refusal {@link setEdgeWhen} performs\n * through the same {@link collidingEdgeId} test.\n *\n * That last one closes the reverse order of the `:error` collision: marking `a → b`\n * as the error lane is refused when `a → \"b:error\"` already exists, but *first*\n * marking `a → b` Error and *then* drawing `a → \"b:error\"` used to be allowed and\n * minted a duplicate id — React Flow's id-keyed store then held one wire for two\n * edges (measured `storeSize 1 / 2`). Refusing here is narrow on purpose; rejecting\n * the step id itself is the durable fix and would also have to reject ids inside\n * workflows that already exist (FOLLOWUPS.md). The caller must surface the refusal —\n * see {@link connectConflict}.\n *\n * The source's exit capacity is **per lane** (T3.2.2): success edges compete only\n * with success edges, error edges only with error edges. So a finite `out: 1`\n * step refuses a second success edge *within* a lane,\n * while additionally being able to hold one error edge — which is what makes a\n * `send → (error) → fallback` shape authorable at all. No `ports.out` bump is\n * needed, so every persisted definition and palette entry stays valid.\n *\n * The target's entry has no capacity: any number of edges, from any number of\n * sources (several triggers may feed one node), converge on it.\n */\nexport function applyConnect(\n source: string | null | undefined,\n target: string | null | undefined,\n nodes: StepNode[],\n edges: Edge[],\n when: CanvasLane = \"success\",\n lookup?: PortsLookup,\n route?: string,\n): Edge[] | null {\n const plan = planConnect(source, target, nodes, edges, when, lookup, route);\n if (!plan || plan.conflict || plan.refusal) return null;\n return plan.next;\n}\n\n/**\n * The id of the existing edge that drawing `source → target` would collide with, or\n * `null` when the connection is safe (or refused for an ordinary reason — a\n * duplicate pair, a self-loop, a portless step — which the drag already showed the\n * user by marking the drop invalid). The creation-path twin of\n * {@link edgeWhenConflict}, and the same channel: it lets the caller *name* the\n * offending edge in an inline refusal instead of losing a wire silently. The editor\n * selects that edge and renders the message in the edge-lane panel (never a browser\n * dialog; see `.ai/conventions.md`).\n */\nexport function connectConflict(\n source: string | null | undefined,\n target: string | null | undefined,\n nodes: StepNode[],\n edges: Edge[],\n when: CanvasLane = \"success\",\n lookup?: PortsLookup,\n route?: string,\n): string | null {\n return planConnect(source, target, nodes, edges, when, lookup, route)?.conflict ?? null;\n}\n\n/**\n * The out-cap refusal for drawing `source → target`, or `null` when the source has\n * room (or is unbounded). The editor renders `cap` in an inline message on the same\n * channel as {@link connectConflict}; {@link applyConnect} returns `null` for it.\n */\nexport function connectRefusal(\n source: string | null | undefined,\n target: string | null | undefined,\n nodes: StepNode[],\n edges: Edge[],\n when: CanvasLane = \"success\",\n lookup?: PortsLookup,\n route?: string,\n): OutCapRefusal | LoopRefusal | null {\n return planConnect(source, target, nodes, edges, when, lookup, route)?.refusal ?? null;\n}\n\n/**\n * The plan for re-laning one edge: the resulting edge set, plus the id of an\n * existing edge it would **collide** with (`null` when it is safe).\n *\n * Both public entry points below read off this, so the eviction arithmetic and the\n * collision test are computed once, in the right order — the collision is checked\n * against the edges that SURVIVE eviction. Checking it against all edges instead\n * would refuse a legitimate switch: re-laning the error half of a same-target\n * pair back to success mints the success sibling's id, but that sibling is\n * evicted by the very same call (see `flow-connect.test.ts` case 11).\n */\nfunction planRelane(\n edges: Edge[],\n edgeId: string,\n when: \"success\" | \"error\",\n nodes: StepNode[],\n lookup?: PortsLookup,\n): { next: Edge[]; conflict: string | null; refusal: OutCapRefusal | null } | null {\n // EXACTLY ONE edge must own `edgeId`. None ⇒ nothing to re-lane. Two or more ⇒ the\n // edge set is already corrupt (a step id containing `->` mints a duplicate id —\n // FOLLOWUPS.md), and both the lookup here and the replacement below match BY ID,\n // so proceeding would rewrite EVERY match: the second edge's endpoints silently\n // overwritten with the first's and then persisted through the host's onChange.\n // Refuse instead — `null` is the refusal channel, and the caller already has a\n // generic message for \"this edge can't be switched right now\".\n const matches = edges.filter((e) => e.id === edgeId);\n if (matches.length !== 1) return null;\n const me = matches[0];\n // An each-lane edge is a loop body link, never re-laned (the lane is not a\n // persisted outcome) — refused like any other un-switchable edge.\n if (edgeLane(me) === \"each\") return null;\n const srcStep = nodes.find((n) => n.id === me.source)?.data.step;\n if (!srcStep) return null;\n if (srcStep.uses.app === ROUTER_APP || srcStep.uses.app === RACE_APP) return null;\n const out = nodePortsForStep(srcStep, lookup).out;\n // The DESTINATION lane at the source is full at a finite cap: REFUSE, evicting\n // nothing (exactly the rule `applyConnect` applies on creation). `me` is excluded —\n // it is the edge moving in.\n //\n // ...but ONLY when the edge is actually MOVING. An edge already in `when`\n // occupies that lane already, so a no-op re-lane is never refused: a definition\n // loaded with more edges out of one step than its cap is over capacity but valid.\n //\n // `e.source === me.source` is a CORRECTNESS barrier: capacity belongs to one\n // step's exit port, so other steps' edges must not be counted (pinned by\n // `flow-connect.test.ts` \"the lane census is per-SOURCE\").\n const others = edges.filter((e) => e.id !== edgeId);\n const sameLane =\n edgeLane(me) === when\n ? []\n : others.filter((e) => e.source === me.source && edgeLane(e) === when);\n if (sameLane.length >= out) {\n return { next: edges, conflict: null, refusal: { refused: \"out_cap\", cap: out } };\n }\n // The lane rides on `data.when`, the visuals come from the shared\n // `edgeVisuals`, and the id is re-minted because it ENCODES the lane\n // (`flowEdgeId`). `className`/`label`/`sourceHandle` are assigned rather than\n // spread: for \"success\" `edgeVisuals` returns `{}` and `sourceHandleForLane`\n // returns `undefined`, and spreading `...me` over either would leave a stale\n // error class / a stale error-port anchor on an edge being moved back to the\n // success lane (T1.1.1 — `sourceHandle` has exactly the same hazard as\n // `className`).\n // No run state: an edge is only re-laned during live authoring — there is\n // no run in progress while an author re-lanes an edge (T1.1.1).\n const visuals = edgeVisuals(when, undefined);\n // A For each's success edge leaves its Done port (routed); its error edge is unrouted.\n const foreach = isForeachStep(srcStep);\n const done = foreach && when === \"success\" ? FOREACH_DONE_ROUTE : undefined;\n const { route: _route, ...unrouted } = (me.data ?? {}) as Record<string, unknown>;\n const relaned: Edge = {\n ...me,\n id: flowEdgeId(me.source, me.target, when, done),\n data: foreach ? { ...unrouted, when, ...(done ? { route: done } : {}) } : { ...me.data, when },\n className: visuals.className,\n label: visuals.label,\n sourceHandle: done ? routeHandle(done) : sourceHandleForLane(when),\n };\n // The same id-uniqueness test the creation path runs, against the survivors only.\n const conflict = collidingEdgeId(others, relaned.id);\n return {\n // `edgeId` is single-owner (guarded above), so this replaces exactly one edge.\n next: edges.map((e) => (e.id === edgeId ? relaned : e)),\n conflict,\n refusal: null,\n };\n}\n\n/**\n * Re-lane one edge. Updates its `data.when`, its visuals and its id, and frees\n * nothing: when the destination lane is at a finite out cap the switch is refused\n * (see {@link relaneRefusal}) — the same rule `applyConnect` applies on creation.\n *\n * Returns a **new** array and mutates nothing (React Flow's state handle compares\n * by identity), or **`null` when the switch must be refused** — the `applyConnect`\n * idiom. It is refused when the re-minted id would duplicate a surviving edge's\n * id, which happens for a step id ending in `:error`: `flowEdgeId` qualifies the\n * error lane with that same suffix, so `a → b` in the error lane and `a → \"b:error\"`\n * in the success lane mint one id, and React Flow's id-keyed store would collapse\n * them — one wire silently vanishing from the canvas, which reads as the editor\n * losing the author's work. The caller must surface the refusal (see\n * {@link edgeWhenConflict}); rejecting the step id itself is the durable fix and\n * is deliberately NOT done here, because it would also have to reject ids inside\n * workflows that already exist (FOLLOWUPS.md).\n *\n * It is refused for one more reason: an `edgeId` owned by more than one edge. That\n * edge set is already corrupt, and re-laning by id would rewrite **every** match,\n * overwriting the other edge's endpoints (`edgeWhenConflict` returns `null` there —\n * there is no *other* edge to name, so the caller's generic refusal applies).\n */\nexport function setEdgeWhen(\n edges: Edge[],\n edgeId: string,\n when: \"success\" | \"error\",\n nodes: StepNode[],\n lookup?: PortsLookup,\n): Edge[] | null {\n const plan = planRelane(edges, edgeId, when, nodes, lookup);\n if (!plan || plan.conflict || plan.refusal) return null;\n return plan.next;\n}\n\n/**\n * The id of the existing edge that {@link setEdgeWhen} would collide with, or\n * `null` when the switch is safe. Lets the caller *name* the offending edge in an\n * inline refusal instead of failing silently — the editor renders it in the\n * edge-lane panel (never a browser dialog; see `.ai/conventions.md`).\n */\nexport function edgeWhenConflict(\n edges: Edge[],\n edgeId: string,\n when: \"success\" | \"error\",\n nodes: StepNode[],\n lookup?: PortsLookup,\n): string | null {\n return planRelane(edges, edgeId, when, nodes, lookup)?.conflict ?? null;\n}\n\n/** The out-cap refusal for re-laning `edgeId`, or `null` — the re-lane twin of {@link connectRefusal}. */\nexport function relaneRefusal(\n edges: Edge[],\n edgeId: string,\n when: \"success\" | \"error\",\n nodes: StepNode[],\n lookup?: PortsLookup,\n): OutCapRefusal | null {\n return planRelane(edges, edgeId, when, nodes, lookup)?.refusal ?? null;\n}\n\n/**\n * Rewrite the edge set after a step's id changed from `prevId` to `nextId`:\n * re-point every endpoint and **re-mint the id in the edge's own lane**.\n *\n * Extracted from `updateStep` so it is testable, and fixing a real defect: the\n * rewrite used to rebuild every id as `` `${source}->${target}` `` unconditionally,\n * dropping an error edge's `:error` qualifier — so renaming a step collapsed a\n * same-target success+error pair into one edge in React Flow's id-keyed store.\n * That was unreachable while a second outgoing edge deleted the first; per-lane\n * exit capacity is what makes it reachable, hence the fix ships alongside it.\n */\nexport function renameStepInEdges(edges: Edge[], prevId: string, nextId: string): Edge[] {\n return edges.map((e) => {\n const source = e.source === prevId ? nextId : e.source;\n const target = e.target === prevId ? nextId : e.target;\n return {\n ...e,\n source,\n target,\n id: flowEdgeId(\n source,\n target,\n edgeLane(e),\n typeof e.data?.route === \"string\" ? e.data.route : undefined,\n ),\n };\n });\n}\n","/**\n * Convert between the Workflow logical model and the React Flow node/edge\n * representation. Also computes an auto-layout — topological columns with\n * separate rows for independent paths — that is deterministic and portable\n * so the same workflow always opens with the same layout.\n */\nimport type { Edge, Node } from \"@xyflow/react\";\nimport { edgeLane } from \"./flow-connect.ts\";\nimport {\n definitionLoops,\n eachLaneEdge,\n effectiveEdges,\n isEachLink,\n isForeachStep,\n loopBodies,\n loopBodyDefinitionEdges,\n stripBody,\n} from \"./flow-loop.ts\";\nimport {\n type CanvasLane,\n FOREACH_DONE_ROUTE,\n FOREACH_EACH_ROUTE,\n type FlowEdge,\n type FlowStep,\n type FlowWorkflow,\n type FlowWorkflowInput,\n IF_FALSE_ROUTE,\n edgeVisuals,\n isIfStep,\n isInternalApp,\n sourceHandleForLane,\n} from \"./flow-types.ts\";\n// T1.1.1 — the run-aware visual state a live-run repaint effect stamps onto a\n// node's `data` (see `WorkflowFlowEditor.tsx`'s patch effect). Never written\n// here: `workflowToFlow` is memoized on workflow identity alone (Trap 1), so\n// threading run state through it would repaint nothing on a poll tick.\nimport type { RunStatus, StepVisualState } from \"./run-visuals.ts\";\nimport type { StepProblem } from \"./step-problems.ts\";\nimport { centralizeConnections } from \"./workflow-connections.ts\";\n\nexport interface StepNodeData extends Record<string, unknown> {\n step: FlowStep;\n /** True for internal pseudo-app nodes (`@w6w/*`) — rendered as pill cards. */\n isInternal: boolean;\n /**\n * This step's status within the run the host is currently showing\n * (T1.1.1). `undefined`/`\"no-run\"` ⇒ no run, or this canvas isn't showing\n * one. Patched in by `WorkflowFlowEditor.tsx`'s live-run repaint effect —\n * never set here, and never read by {@link flowToWorkflow}, which only\n * ever reads `.step` off a node's `data` (A6 — nothing run-related is\n * persisted).\n */\n stepStatus?: StepVisualState;\n /**\n * The owning run's OWN status, alongside {@link stepStatus} — a node\n * card's visual is a function of BOTH (RunStatus × StepStatus, not\n * StepStatus alone; see `run-visuals.ts`'s `stepNodeVisual`). Same\n * provenance/persistence rules as `stepStatus`.\n */\n runStatus?: RunStatus;\n /**\n * Host-supplied problems with this step (a dangling connection, loop problems).\n * Patched in by `WorkflowFlowEditor.tsx`'s `stepProblems` effect — never set\n * here, absent (never `[]`) when there are none, and never read by {@link flowToWorkflow} (not persisted).\n */\n stepProblems?: StepProblem[];\n /**\n * The For each this step is a loop-body member of (canvas-only; derived on load\n * and by the editor, never read by {@link flowToWorkflow}).\n */\n loopOf?: string;\n /** This For each was converted from a legacy (no-`body`) loop on load. Canvas-only. */\n legacyLoop?: boolean;\n}\n\nexport type StepNode = Node<StepNodeData>;\n\n/**\n * The React Flow id for the edge `from → to` in a given lane — **the one place**\n * the id convention lives.\n *\n * A success edge keeps the historic unqualified `from->to` spelling (so no\n * persisted definition changes id when it is reloaded); an error edge is\n * **qualified** with `:error`, because the model permits a success edge AND an\n * error edge between the same pair (core `rfcs/workflow.md` · `Edge.when`\n * amendment; D-T1-8) and two edges sharing one id would be collapsed by React\n * Flow's id-keyed store — silently losing a lane.\n *\n * Every site that mints or rewrites an edge id calls this: {@link workflowToFlow},\n * `applyConnect` (edge creation) and `renameStepInEdges` (the step-rename\n * rewrite) in `flow-connect.ts`. A second hand-rolled copy of the template is\n * exactly how the rename path came to drop the qualifier.\n */\nexport function flowEdgeId(from: string, to: string, when?: CanvasLane, route?: string): string {\n const base = when === \"error\" ? `${from}->${to}:error` : `${from}->${to}`;\n return route === undefined ? base : `${base}:route:${encodeURIComponent(route)}`;\n}\n\n/**\n * Why a step id may not be saved from the editor, or `null` when it may. The one\n * rule here is \"no `.`\" (a dotted id cannot be addressed by `steps.<id>.output`);\n * duplicates and the edge-time `->` / `:error` checks are NOT this function's job.\n */\nexport function stepIdError(id: string): string | null {\n return id.includes(\".\") ? \"A step id can't contain a dot (.).\" : null;\n}\n\n/**\n * {@link stepIdError} plus uniqueness: why `id` may not name a node of a graph whose other\n * nodes are `taken`, or `null`. The rename in the step editor and the name in the add flow\n * both validate through this.\n */\nexport function stepNameError(id: string, taken: Iterable<string>): string | null {\n const err = stepIdError(id);\n if (err) return err;\n for (const other of taken) if (other === id) return `A step named \"${id}\" already exists.`;\n return null;\n}\n\n/**\n * The one wording for a refused edge id, shared by both routes into the collision —\n * drawing a wire whose minted id is taken (`applyConnect` / `connectConflict`) and\n * re-laning one onto a taken id (`setEdgeWhen` / `edgeWhenConflict`). `lead` names\n * what was refused, `id` is the taken id, and `involved` carries the step ids of the\n * **two edges that mint it**: the new/moving edge's endpoints and the sitting\n * edge's. Rendered inline with `role=\"alert\"`, never in a browser dialog\n * (`.ai/conventions.md`).\n *\n * It lives here, beside {@link flowEdgeId}, for two reasons: the clash *is* a\n * property of that function's non-injectivity over free-text step ids, and this\n * module is JSX-free so `node --test` can pin the wording (it used to sit in\n * `WorkflowFlowEditor.tsx`, where the runner cannot reach it — which is how the\n * wrong advice below shipped uncovered).\n *\n * ⚠️ **The cause is DETERMINED, never asserted.** This message used to hard-code\n * *\"because a step id ending in `:error` collides with the error-lane marker.\n * Rename that step\"* — and the guard has a second, equally real trigger: a step id\n * containing `->`, the separator itself. With steps `a`, `b->c`, `a->b`, `c` and an\n * edge `a → \"b->c\"`, drawing `\"a->b\" → c` is correctly refused (both mint\n * `a->b->c`) while **no step id ends in `:error`** — so the author was told to\n * rename a step that does not exist, and given advice that could not resolve their\n * problem. Inferring the cause from the taken `id` alone does not fix that: an id\n * ending in `:error` may equally be an error-lane edge whose collision came from an\n * embedded `->`. So the culprit is looked up among the ids actually involved, and\n * when none of them is ambiguous the message names **no** cause at all.\n *\n * ## Which of the two triggers it is, is decided by the LANE PAIR\n *\n * Scanning the involved ids for *either* spelling and taking the first match is\n * **not** enough — it names a step whose renaming cannot resolve the clash. Steps\n * `p->q`, `b`, `b:error` with `p->q → b` sitting on the **error** lane and\n * `p->q → \"b:error\"` drawn on the **success** lane both mint `p->q->b:error`; the\n * first-match scan blames `p->q`, which is the **shared source of both edges**, so\n * renaming it re-mints both and the edge is still refused. The mirror is just as\n * wrong: two **success**-lane edges over steps `x:error`, `y->z`, `x:error->y`, `z`\n * collide with no error lane anywhere, yet get blamed on the error-lane marker.\n *\n * The lane pair decides it, and decides it exactly:\n * - **Same lane on both edges** ⇒ `f1->t1` == `f2->t2` (with the same suffix) forces\n * the two splits to differ, i.e. an **embedded `->`**; it also forces both\n * endpoints to differ (equal sources would force equal targets and vice versa), so\n * renaming *any* involved id re-mints exactly one of the two edges.\n * - **Different lanes** ⇒ `fs->ts` == `fe->te:error`, and since `:error` contains\n * neither `-` nor `>` its 6 characters cannot overlap the separator — so **the\n * success edge's target** ends in `:error`, and that is the step to rename.\n *\n * The lanes are not passed in: they are recovered from `id` itself, which\n * {@link flowEdgeId} is the only minter of, so an endpoint pair spells `id` on at\n * most one lane (`f->t` and `f->t:error` are never equal). A pair that spells it on\n * neither means an already-corrupt edge set — the lane pair then determines nothing\n * and the message names no cause, exactly as when nothing involved is ambiguous. A\n * vague-but-true message beats a confident false one.\n */\nexport function idClashMessage(\n lead: string,\n id: string,\n involved: readonly (string | null | undefined)[],\n): string {\n const laneOf = (from: string | null | undefined, to: string | null | undefined) =>\n !from || !to\n ? undefined\n : flowEdgeId(from, to) === id\n ? \"success\"\n : flowEdgeId(from, to, \"error\") === id\n ? \"error\"\n : undefined;\n const drawn = laneOf(involved[0], involved[1]);\n const sitting = laneOf(involved[2], involved[3]);\n const sameLane = drawn !== undefined && drawn === sitting;\n const mixedLane = drawn !== undefined && sitting !== undefined && drawn !== sitting;\n // On mixed lanes the culprit is the SUCCESS edge's target (`involved` is\n // `[drawn.source, drawn.target, sitting.source, sitting.target]`).\n const successTarget = drawn === \"success\" ? involved[1] : involved[3];\n const culprit = sameLane\n ? involved.find((s): s is string => !!s && s.includes(\"->\"))\n : mixedLane && successTarget?.endsWith(\":error\")\n ? successTarget\n : undefined;\n // One long template per arm on purpose: `lint/style/useTemplate` forbids\n // concatenating a template with a literal, and the formatter does not break\n // string contents.\n const cause =\n culprit === undefined\n ? \"Rename one of the steps it connects, then try again.\"\n : sameLane\n ? `A step id containing “->” collides with the edge-id separator, so two different edges mint one id — rename the step “${culprit}”, then try again.`\n : `A step id ending in “:error” collides with the error-lane marker, so two different edges mint one id — rename the step “${culprit}”, then try again.`;\n return `${lead}: the id “${id}” is already taken by another edge. ${cause}`;\n}\n\n/** Nice constants — tunable but stable defaults so layouts don't jitter. */\nconst COLUMN_WIDTH = 240;\nconst ROW_HEIGHT = 100;\nconst MARGIN_X = 40;\nconst MARGIN_Y = 40;\n\n/**\n * The canvas slot a step in column `col`, row `row` occupies — **the one place**\n * the placement arithmetic lives, exactly as {@link flowEdgeId} is the one place\n * the id convention lives.\n *\n * Two callers, and the reason they must share this is user-visible: {@link\n * workflowToFlow} uses the slot as the *fallback* for a step with no stored\n * `position` (first open), while {@link relayoutNodes} uses it for *every* node\n * (the auto-layout control). A second copy of the arithmetic would make\n * \"auto-layout\" disagree with \"first open\" — the one difference an author would\n * notice immediately — so the only thing that differs between the two is whether\n * a stored coordinate wins, which belongs at the call site.\n *\n * A **fresh object** every call: React Flow owns `node.position` and mutates it\n * in place during a drag (see {@link storedPosition}).\n */\nfunction slotPosition(col: number, row: number): { x: number; y: number } {\n return { x: MARGIN_X + col * COLUMN_WIDTH, y: MARGIN_Y + row * ROW_HEIGHT };\n}\n\n/**\n * Layer index per step id under a topological layout of the graph: a step sits\n * one column right of its furthest-right predecessor (longest-path layering,\n * computed by relaxation).\n *\n * ## Termination — this loop used to hang the tab\n *\n * The relaxation is **bounded to `steps.length + 1` passes**. The unbounded\n * `while (changed)` it replaces assumed a DAG (\"for a DAG this converges\") and\n * never exited on a cycle: with `a → b → a` the `<` test stays satisfiable\n * forever and the layers climb without bound. The engine rejects cycles at plan\n * time, but **this editor lets you draw one**, and `workflowToFlow` calls this\n * on open — so a cyclic workflow froze the tab on load, and would have frozen it\n * mid-edit once an auto-layout button called the same code from a click.\n *\n * A **pass bound** was chosen over a separate cycle detector (a DFS colouring)\n * for two reasons: it keeps one traversal and one notion of \"the graph\" instead\n * of two that can drift, and the bound is provably exact rather than heuristic —\n * by the Bellman-Ford argument, after `k` full passes every step whose longest\n * path from a source is `k` edges long already holds its final layer, and an\n * acyclic graph's longest path visits each step at most once. So a DAG reaches\n * its fixpoint within `steps.length` passes and the extra pass here only ever\n * observes `changed === false`. **Acyclic output is therefore byte-identical to\n * the unbounded version** — the bound is not a heuristic cut-off, and\n * `artifacts/T3.3.1-computelayers-equivalence.sh` proves it against the previous\n * commit's blob over 200+ fixtures.\n *\n * ⚠️ What is **not** guaranteed is that a layer stays ≤ `steps.length - 1` (an\n * earlier revision of this comment claimed it, and used the claim to call the\n * clamp below a provable no-op on any DAG — that was **false**). `layer.get(pred)\n * ?? 0` treats an edge whose `from` is **not a declared step** as a phantom\n * predecessor sitting at layer 0, so such an edge contributes a real `+1`:\n * `steps: [a, b]` with `edges: [ghost→a, a→b]` puts `b` in column **2** while\n * `lastColumn` is 1. That graph is still fine — it converges, so `changed` is\n * `false` and the clamp never runs; the extra column simply renders (pinned by\n * `flow-utils.test.ts` · \"an edge from an UNDECLARED step adds a column\"). The\n * honest invariant is the narrower one: **the clamp runs only when the pass bound\n * is exhausted with the layout still moving, which requires a cycle.**\n *\n * Exceeding the bound *is* the cycle signal (`changed` is still true). The\n * layout then stays **usable** rather than throwing or refusing: the runaway\n * values are clamped to the last real column, so the steps on the cycle stack up\n * in one column (the path layout gives them distinct rows) and\n * the author can see the loop they drew and delete an edge. Refusing to lay out\n * a cyclic graph would trade a hang for a workflow nobody can open to fix. The\n * clamp cannot fire on a DAG, because a DAG converges before the bound is spent —\n * **not** because its layers are bounded by `steps.length - 1`; see the ⚠️ above.\n */\nfunction computeLayers(steps: FlowStep[], edges: FlowEdge[]): Map<string, number> {\n const layer = new Map<string, number>();\n const incoming = new Map<string, string[]>();\n for (const s of steps) {\n layer.set(s.id, 0);\n incoming.set(s.id, []);\n }\n for (const e of edges) {\n incoming.get(e.to)?.push(e.from);\n }\n // Iterate to fixpoint. For a DAG this converges in O(V+E) passes — and the\n // pass bound is what makes that assumption safe instead of load-bearing.\n const maxPasses = steps.length + 1;\n let passes = 0;\n let changed = true;\n while (changed && passes < maxPasses) {\n passes++;\n changed = false;\n for (const s of steps) {\n const preds = incoming.get(s.id) ?? [];\n if (preds.length === 0) continue;\n const next = preds.reduce((max, p) => Math.max(max, (layer.get(p) ?? 0) + 1), 0);\n if ((layer.get(s.id) ?? 0) < next) {\n layer.set(s.id, next);\n changed = true;\n }\n }\n }\n if (changed) {\n // The bound ran out with the layout still moving ⇒ there is a cycle. Pull\n // the runaway columns back to the last real one so the graph still renders.\n const lastColumn = Math.max(0, steps.length - 1);\n for (const [id, col] of layer) {\n if (col > lastColumn) layer.set(id, lastColumn);\n }\n }\n return layer;\n}\n\n/**\n * Keep each path on its own row until it joins another path. A per-column row\n * counter loses that ancestry and can draw one trigger's edge through a node\n * belonging to another trigger.\n *\n * Choose one forward parent per node to form a layout forest. At a join, align\n * with the furthest-away parent so its long edge can bypass the shorter path.\n * Likewise place a parent's longest outgoing branch first. Other branches get\n * their own rows, including the space their descendants need. Only forward\n * edges participate, so even a malformed cycle has a finite, usable layout.\n */\nfunction computePositions(\n steps: FlowStep[],\n edges: FlowEdge[],\n): Map<string, { x: number; y: number }> {\n const layer = computeLayers(steps, edges);\n const order = new Map(steps.map((s, i) => [s.id, i]));\n const parent = new Map<string, string>();\n for (const { from, to } of edges) {\n const fromCol = layer.get(from);\n const toCol = layer.get(to);\n if (fromCol === undefined || toCol === undefined || fromCol >= toCol) continue;\n const prev = parent.get(to);\n if (\n prev === undefined ||\n fromCol < (layer.get(prev) ?? 0) ||\n (fromCol === layer.get(prev) && (order.get(from) ?? 0) < (order.get(prev) ?? 0))\n ) {\n parent.set(to, from);\n }\n }\n const children = new Map(steps.map((s) => [s.id, [] as string[]]));\n for (const [child, from] of parent) children.get(from)?.push(child);\n for (const siblings of children.values()) {\n siblings.sort(\n (a, b) =>\n (layer.get(b) ?? 0) - (layer.get(a) ?? 0) || (order.get(a) ?? 0) - (order.get(b) ?? 0),\n );\n }\n const positions = new Map<string, { x: number; y: number }>();\n let row = 0;\n for (const root of steps.filter((s) => !parent.has(s.id))) {\n const stack = [root.id];\n while (stack.length) {\n const id = stack.pop();\n if (id === undefined) continue;\n positions.set(id, slotPosition(layer.get(id) ?? 0, row));\n const branch = children.get(id) ?? [];\n if (branch.length === 0) row++;\n else for (let i = branch.length - 1; i >= 0; i--) stack.push(branch[i]);\n }\n }\n return positions;\n}\n\n/**\n * A step's **stored** canvas coordinate, when it has a usable one.\n *\n * `position` arrives from a persisted JSON document (core `rfcs/workflow.md` ·\n * authoring-presentation amendment, mirrored on {@link FlowStep}), so both axes\n * are checked with `Number.isFinite`: a `null`, a string, a `NaN` from a\n * `JSON.parse`d `null`, or a half-written `{ x }` falls back to the computed slot\n * rather than putting the node at an unreachable coordinate.\n *\n * A **fresh object** is returned, never the one hanging off the step: React Flow\n * owns `node.position` while a drag is in flight, and the same step object is\n * also handed to the node's `data.step`.\n */\nfunction storedPosition(step: FlowStep): { x: number; y: number } | undefined {\n const p = step.position;\n if (!p || !Number.isFinite(p.x) || !Number.isFinite(p.y)) return undefined;\n return { x: p.x, y: p.y };\n}\n\n/** Read a definition in either shape into the canonical `nodes[]` form. */\nexport function normalizeInput(input: FlowWorkflowInput): FlowWorkflow {\n const o = input as { nodes?: FlowStep[]; steps?: FlowStep[] };\n if (o.nodes !== undefined && o.steps !== undefined) {\n throw new Error(\"workflow carries both nodes and steps\");\n }\n const { steps: _s, ...rest } = input as FlowWorkflow & { steps?: unknown };\n return { ...rest, nodes: o.nodes ?? o.steps ?? [] } as FlowWorkflow;\n}\n\n/**\n * Turn a Workflow into (nodes, edges) with an auto-layout when no positions are\n * known.\n *\n * A step's **stored `position` wins** over the computed slot (the amendment's\n * \"omitted ⇒ the editor computes a layout\" arm, and its converse). A partially\n * positioned graph mixes the two: positioned steps sit where they were left,\n * unpositioned ones take their computed slot.\n *\n * Layout runs over the whole graph, including positioned steps, so a fallback\n * coordinate does not depend on which neighbours already have saved positions.\n */\nexport function workflowToFlow(input: FlowWorkflowInput): { nodes: StepNode[]; edges: Edge[] } {\n const wf = normalizeInput(input);\n const defs = wf.nodes;\n let edges: FlowEdge[] = effectiveEdges(wf);\n // Loops (D-A3): draw every foreach body as each-lane edges. A legacy loop's\n // success edges are replaced by exactly those each-lane edges; a `body` loop's\n // members are touched by no declared edge (validated), so nothing is removed.\n // An invalid body keeps the step verbatim with no each-lane edges.\n const eachEdges: Edge[] = [];\n const loopOf = new Map<string, string>();\n const legacyFoes = new Set<string>();\n const drop = new Set<FlowEdge>();\n for (const [fid, loop] of Object.entries(definitionLoops(wf))) {\n if (\"invalid\" in loop) continue;\n let prev = fid;\n if (loop.edges && loop.body.length > 0) {\n // A branched body: the Each-item link, then each declared body edge as an each-lane edge.\n eachEdges.push(eachLaneEdge(fid, loop.body[0], true));\n for (const e of loop.edges) {\n drop.add(e);\n eachEdges.push(eachLaneEdge(e.from, e.to, false, e.route));\n }\n for (const id of loop.body) loopOf.set(id, fid);\n continue;\n }\n for (const id of loop.body) {\n if (loop.source === \"legacy\") {\n const e = edges.find(\n (x) => x.from === prev && x.to === id && (x.when ?? \"success\") === \"success\",\n );\n if (e) drop.add(e);\n }\n eachEdges.push(eachLaneEdge(prev, id, prev === fid));\n loopOf.set(id, fid);\n prev = id;\n }\n if (loop.source === \"legacy\") legacyFoes.add(fid);\n }\n // A For each's saved Each item link is redrawn from its body above, never as a plain edge.\n const foreachIds = new Set(defs.filter(isForeachStep).map((s) => s.id));\n for (const e of edges) if (foreachIds.has(e.from) && isEachLink(e)) drop.add(e);\n if (drop.size > 0) edges = edges.filter((e) => !drop.has(e));\n const positions = computePositions(defs, [\n ...edges,\n ...eachEdges.map((e) => ({ from: e.source, to: e.target })),\n ]);\n const nodes: StepNode[] = defs.map((step) => {\n const isInternal = isInternalApp(step.uses.app);\n return {\n id: step.id,\n type: isInternal ? \"control\" : \"step\",\n position: storedPosition(step) ?? positions.get(step.id) ?? slotPosition(0, 0),\n data: {\n step,\n isInternal,\n ...(loopOf.has(step.id) ? { loopOf: loopOf.get(step.id) } : {}),\n ...(legacyFoes.has(step.id) ? { legacyLoop: true } : {}),\n },\n };\n });\n\n // An If has no error port: its bottom handle is the False branch (ifPortLayout).\n // An error edge saved from that handle before it was False is read as False.\n const ifIds = new Set(defs.filter(isIfStep).map((s) => s.id));\n // A For each's unrouted success edge (saved before its Done port had an id) is Done.\n const flowEdges: Edge[] = edges.map((saved) => {\n const e: FlowEdge =\n saved.when === \"error\" && saved.route === undefined && ifIds.has(saved.from)\n ? { from: saved.from, to: saved.to, route: IF_FALSE_ROUTE }\n : foreachIds.has(saved.from) && saved.route === undefined && saved.when !== \"error\"\n ? { ...saved, route: FOREACH_DONE_ROUTE }\n : saved;\n // Omitted ⇒ \"success\" (core rfcs/workflow.md · Edge.when amendment). The\n // lane rides on `data` so flowToWorkflow can read it straight back off the\n // React Flow edge; the className + label that tell an error edge apart on\n // the canvas come from {@link edgeVisuals} — the single source of truth,\n // shared with `setEdgeWhen`, which re-lanes an edge live. Inlining them here\n // is how the loaded look and the just-marked look drift apart.\n //\n // The id is qualified per lane, because the model permits a success edge AND\n // an error edge between the same pair: two edges sharing one id would be\n // collapsed by React Flow's id-keyed store and one lane silently lost. The\n // qualifier comes from {@link flowEdgeId}, which every other id site calls.\n //\n // `sourceHandle` is stamped from {@link sourceHandleForLane} (T1.1.1) so a\n // workflow saved before the error port existed renders its error edges from\n // the new port on next open, not only edges drawn live after the feature\n // shipped. `sourceHandle` is presentation only — `flowToWorkflow` never\n // reads it back, so this does not touch the persisted `Edge.when` round-trip.\n const when = e.when ?? \"success\";\n return {\n id: flowEdgeId(e.from, e.to, when, e.route),\n source: e.from,\n target: e.to,\n sourceHandle: e.route === undefined ? sourceHandleForLane(when) : `route:${e.route}`,\n animated: false,\n data: { when, ...(e.route === undefined ? {} : { route: e.route }) },\n // No run state here either (T1.1.1): `workflowToFlow` only ever runs\n // on workflow identity change (Trap 1), never on a live run's poll\n // tick, so it has no run state to pass — the live-run repaint effect\n // in `WorkflowFlowEditor.tsx` is the one call site that does.\n ...edgeVisuals(when, undefined),\n };\n });\n\n return { nodes, edges: [...flowEdges, ...eachEdges] };\n}\n\n/**\n * Re-flow every node with the same deterministic layering the editor uses on\n * first open — the auto-layout control's whole implementation.\n *\n * Takes React Flow's `(nodes, edges)` rather than a `FlowWorkflow` because the\n * button acts on **what is currently on the canvas**, including steps added and\n * wires drawn since the last save.\n *\n * Same {@link computePositions} as {@link\n * workflowToFlow}, so a graph with no stored positions lays out byte-identically\n * either way (pinned by `flow-utils.test.ts` — \"auto-layout agrees with first\n * open\"). The **only** difference is that a stored coordinate does not win here:\n * overriding hand placement is precisely what the author asked for by clicking.\n * The editor records this as one undoable layout change.\n *\n * Layering is keyed by **`node.id`**, not `node.data.step.id`: React Flow's\n * `edge.source`/`edge.target` name node ids, so keying by anything else would\n * silently drop every edge from the layering (a `?? 0` fallback puts the whole\n * graph in column 0) if the two ever disagreed.\n *\n * Returns a **new array of new node objects** — React Flow's state handle\n * compares by reference, so a mutated-in-place array does not re-render — with\n * every node's `id`, `type` and `data` carried across untouched (`data` by the\n * same reference, so no node card re-derives its metadata).\n */\nexport function relayoutNodes(nodes: StepNode[], edges: Edge[]): StepNode[] {\n // `computeLayers` reads only `.id` off a step; keying on the NODE id keeps it\n // consistent with the edge endpoints below. The bounded relaxation inside is\n // what makes this safe to call from a click: before it, a cyclic graph froze\n // the tab, and this button would have frozen it mid-edit.\n const steps: FlowStep[] = nodes.map((n) => ({ ...n.data.step, id: n.id }));\n const positions = computePositions(\n steps,\n edges.map((e) => ({ from: e.source, to: e.target })),\n );\n return nodes.map((n) => ({ ...n, position: positions.get(n.id) ?? slotPosition(0, 0) }));\n}\n\n/**\n * Reverse direction: pull the graph state back into a Workflow shape for\n * onChange.\n *\n * Each emitted step carries the **current canvas coordinate** of its node, unless\n * `original.settings.savePosition` is explicitly `false`. The flag is read off\n * the workflow this function already receives — deliberately **not** a new\n * parameter or an options bag, because both exported conversion functions are\n * public `@w6w/ui/flow` API for a partner-facing library and a signature\n * change here would break it for a value the function can already see.\n *\n * ⚠️ **`savePosition` defaults to `true`** (core `rfcs/workflow.md` ·\n * authoring-presentation amendment), so it is read as `!== false`: an absent\n * `settings` object means positions *are* persisted. The practical consequence is\n * intended — **a workflow that has never been saved by this editor starts\n * carrying `position` on every step the first time it is saved.**\n */\nexport function flowToWorkflow(\n originalInput: FlowWorkflowInput,\n nodes: StepNode[],\n edges: Edge[],\n): FlowWorkflow {\n // `!== false`, never `?? false` and never `=== true`: omitted ⇒ ON.\n const original = normalizeInput(originalInput);\n const savePosition = original.settings?.savePosition !== false;\n const nodeById = new Map<string, StepNode>(nodes.map((n) => [n.id, n]));\n\n /**\n * Stamp a step with its node's coordinate.\n *\n * `Math.round` is required, not cosmetic: React Flow reports fractional\n * coordinates, and auto-save dedupes by comparing the serialized payload — an\n * unrounded float would make a no-op render look like a change and produce a\n * write storm.\n *\n * When `savePosition` is `false` the step is returned **untouched**, which is\n * not the same as clearing it: \"not written\" is not \"erased\", so a coordinate a\n * colleague already stored survives someone else turning their own toggle off\n * (amendment: \"any values already stored are left as they are, not erased\").\n */\n const withPosition = (step: FlowStep): FlowStep => {\n if (!savePosition) return step;\n const p = nodeById.get(step.id)?.position;\n if (!p || !Number.isFinite(p.x) || !Number.isFinite(p.y)) return step;\n return { ...step, position: { x: Math.round(p.x), y: Math.round(p.y) } };\n };\n\n // Preserve original step order where possible; append new nodes at the end.\n const stepById = new Map<string, FlowStep>();\n for (const s of original.nodes) stepById.set(s.id, s);\n for (const n of nodes) if (n.data?.step) stepById.set(n.id, n.data.step);\n\n // Each foreach's body is DERIVED from the canvas's each-lane edges — a stored\n // `with.body` is never trusted (P6/P8).\n const derived = loopBodies(nodes, edges);\n const originalLoops = definitionLoops(original);\n const originalById = new Map<string, FlowStep>(original.nodes.map((s) => [s.id, s]));\n const successFrom = new Set<string>();\n for (const e of edges) if (edgeLane(e) === \"success\") successFrom.add(e.source);\n const withBody = (step: FlowStep): FlowStep => {\n if (!isForeachStep(step)) return step;\n const chain = derived.get(step.id) ?? [];\n const orig = originalById.get(step.id);\n const loop = originalLoops[step.id];\n let emit: { value: unknown } | null;\n if (chain.length > 0) emit = { value: chain };\n else if (loop && \"invalid\" in loop && loop.invalid.reason !== \"legacy_not_linear\") {\n emit = orig?.with && \"body\" in orig.with ? { value: orig.with.body } : null;\n } else if (loop && \"invalid\" in loop) emit = null;\n else if (successFrom.has(step.id) || (orig?.with && \"body\" in orig.with)) emit = { value: [] };\n else emit = null;\n const w = step.with ?? {};\n if (emit === null) {\n if (!(\"body\" in w)) return step;\n return stripBody(step);\n }\n // An existing `body` keeps its key slot in `with`; a new one is appended.\n return { ...step, with: { ...w, body: emit.value } };\n };\n const emitted = (s: FlowStep): FlowStep => withPosition(withBody(s));\n\n const nextSteps: FlowStep[] = [];\n const seen = new Set<string>();\n for (const s of original.nodes) {\n const current = stepById.get(s.id);\n if (current && nodes.some((n) => n.id === s.id)) {\n nextSteps.push(emitted(current));\n seen.add(s.id);\n }\n }\n for (const n of nodes) {\n if (seen.has(n.id)) continue;\n const s = stepById.get(n.id);\n if (s) nextSteps.push(emitted(s));\n }\n\n // Read the lane back off the React Flow edge (put there by workflowToFlow /\n // by applyConnect at creation). `\"success\"` is written as ABSENT — the house\n // omit-the-default idiom — so a definition with no error edge round-trips\n // byte-identically to what was loaded.\n //\n // The each lane is canvas-only and never serialized, and no emitted edge may\n // touch a body step the engine will own (any such edge is a PlanError there).\n const bodyIds = new Set<string>();\n for (const chain of derived.values()) for (const id of chain) bodyIds.add(id);\n const foreachIds = new Set(nodes.filter((n) => isForeachStep(n.data?.step)).map((n) => n.id));\n const plainEdges: FlowEdge[] = edges\n .filter((e) => edgeLane(e) !== \"each\" && !bodyIds.has(e.source) && !bodyIds.has(e.target))\n .map((e): FlowEdge => {\n const route =\n typeof e.data?.route === \"string\"\n ? e.data.route\n : foreachIds.has(e.source) && edgeLane(e) === \"success\"\n ? FOREACH_DONE_ROUTE\n : undefined;\n return {\n from: e.source,\n to: e.target,\n ...(edgeLane(e) === \"error\" ? { when: \"error\" as const } : {}),\n ...(route === undefined ? {} : { route }),\n };\n });\n\n // Each For each's Each item link names its port, so no reader takes it for Done.\n const eachLinks: FlowEdge[] = [];\n for (const [fid, chain] of derived) {\n if (chain.length > 0) eachLinks.push({ from: fid, to: chain[0], route: FOREACH_EACH_ROUTE });\n }\n\n // A branched body (anything but a plain chain) also emits its body-internal edges.\n const nextEdges = [...plainEdges, ...eachLinks, ...loopBodyDefinitionEdges(nodes, edges)];\n // Connections are workflow resources: keep them even before their first node uses them.\n return centralizeConnections({ ...original, nodes: nextSteps, edges: nextEdges });\n}\n\n/** The workflow's stored camera, as `settings.viewport` declares it. */\ntype StoredViewport = NonNullable<NonNullable<FlowWorkflow[\"settings\"]>[\"viewport\"]>;\n\n/**\n * The workflow's **stored** camera position, when it has a usable one — the\n * viewport counterpart to {@link storedPosition}, and the single definition of\n * \"a viewport this editor will act on\". Both the restore-on-open read and\n * {@link withViewport}'s no-op comparison go through it, so they cannot disagree\n * about what counts as stored.\n *\n * All three components are checked with `Number.isFinite` for the same reason\n * `storedPosition` checks two: `settings.viewport` arrives from a persisted JSON\n * document that an author can hand-edit (studio's `</>` raw-JSON modal), and a\n * `null`, a string or a half-written `{ x, y }` would otherwise be handed to\n * React Flow's `defaultViewport` as the initial transform — a `NaN` there blanks\n * the canvas, with no way back except editing the JSON again. Unusable ⇒\n * `undefined`, i.e. \"no stored viewport\", which falls back to `fitView`.\n *\n * A **fresh object** is returned, never the one hanging off `settings`: React\n * Flow owns the viewport it is given.\n */\nexport function storedViewport(wf: FlowWorkflow): StoredViewport | undefined {\n const v = wf.settings?.viewport;\n if (!v || !Number.isFinite(v.x) || !Number.isFinite(v.y) || !Number.isFinite(v.zoom)) {\n return undefined;\n }\n return { x: v.x, y: v.y, zoom: v.zoom };\n}\n\n/**\n * Record the author's viewport on the workflow (core `rfcs/workflow.md` ·\n * authoring-presentation amendment). Pure, so the two decisions that matter —\n * rounding and no-op detection — are unit-testable without mounting React Flow.\n *\n * Returns `wf` **UNCHANGED (the same reference)** when:\n * - `settings.savePosition` is `false` — read as `!== false`, never `?? false`\n * and never `=== true`: **omitted ⇒ ON**, same as `flowToWorkflow`;\n * - the rounded viewport already equals the stored one;\n * - the incoming viewport is not finite (nothing usable to store).\n *\n * The same-reference return **is** the coalescing guard: the caller emits only\n * when the reference changes, so a pan that lands back where it started emits\n * nothing at all. That matters because the host's auto-save is a trailing\n * debounce over emitted changes — every emission is a candidate network write.\n *\n * Rounding is pinned for that same reason (and mirrors `flowToWorkflow`'s\n * coordinate rounding): `x`/`y` to integers, `zoom` to **3 decimal places**.\n * A trackpad reports the zoom as a long float, so without it two visually\n * identical viewports serialize differently and every idle gesture looks like a\n * change to a payload-comparing auto-save.\n *\n * `settings` is spread, not replaced, so `autoSave` / `savePosition` survive a\n * viewport write — the mirror image of `writeSetting` (studio) deleting a key at\n * its default without disturbing `viewport`. That mirror runs to the **guard on\n * the spread** as well: `settings` is typed as an object here, but it arrives from\n * a `JSON.parse`d document an author can hand-edit (studio's `</>` raw-JSON\n * modal), so `\"settings\": \"hello\"` would spread into indexed keys —\n * `{\"0\":\"h\",\"1\":\"e\",…, viewport}` — **on a pan**, and the host's auto-save would\n * re-persist that on a debounce with nobody clicking anything. Anything that is\n * not a plain object therefore reads as \"no settings\", i.e. the write produces a\n * fresh `{ viewport }`, discarding the unusable value; the predicate is\n * `writeSetting`'s, character for character, so the two really are one rule.\n */\nexport function withViewport(wf: FlowWorkflow, vp: StoredViewport): FlowWorkflow {\n // `!== false`, never `?? false` and never `=== true`: omitted ⇒ ON.\n const savePosition = wf.settings?.savePosition !== false;\n if (!savePosition) return wf;\n if (!Number.isFinite(vp.x) || !Number.isFinite(vp.y) || !Number.isFinite(vp.zoom)) return wf;\n const next: StoredViewport = {\n x: Math.round(vp.x),\n y: Math.round(vp.y),\n zoom: Math.round(vp.zoom * 1000) / 1000,\n };\n const current = storedViewport(wf);\n if (current && current.x === next.x && current.y === next.y && current.zoom === next.zoom) {\n return wf;\n }\n // Studio's `writeSetting` predicate, verbatim — a non-object `settings` must not\n // spread into indexed keys (see the docstring).\n const prev =\n typeof wf.settings === \"object\" && wf.settings !== null && !Array.isArray(wf.settings)\n ? wf.settings\n : undefined;\n return { ...wf, settings: { ...prev, viewport: next } };\n}\n\n/**\n * Turn a human-readable label (an action's `label`/`displayName`) into an\n * id-safe slug for {@link suggestStepId}'s `prefix` — human override,\n * 2026-08-30: a step id derived from its OWN action (\"data_1\",\n * \"render_template_1\", \"manual_trigger_1\") orients a reader who never\n * renamed it, unlike the generic \"gate_1\"/\"step_1\" every internal/external\n * step used to get regardless of what it actually does. Lowercase,\n * underscore-separated, ASCII word characters only; falls back to `\"step\"`\n * for a label that slugifies to nothing (empty, or entirely punctuation).\n */\nexport function slugifyLabel(label: string): string {\n const slug = label\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n return slug || \"step\";\n}\n\n/**\n * The current chain's ROOT: the earliest-added node (array/declaration order)\n * with no incoming edge. `undefined` for an empty graph. Used to give a\n * newly-added TRIGGER a sensible default wire — human override, 2026-08-30 —\n * rather than always landing as a floating node. Array order (not position)\n * is the tie-break because it is deterministic and matches \"the node that\n * was here first,\" not wherever the canvas happens to have placed it.\n */\nexport function findChainRoot(nodes: StepNode[], edges: Edge[]): StepNode | undefined {\n const hasIncoming = new Set(edges.map((e) => e.target));\n return nodes.find((n) => !hasIncoming.has(n.id));\n}\n\n/**\n * The current chain's TAIL: the most-recently-added node (array/declaration\n * order) with no outgoing edge. `undefined` for an empty graph. Used to give\n * a newly-added non-trigger STEP a sensible default wire — the most recently\n * placed branch is the one a user adding steps one at a time is most likely\n * extending.\n */\nexport function findChainTail(nodes: StepNode[], edges: Edge[]): StepNode | undefined {\n const hasOutgoing = new Set(edges.map((e) => e.source));\n for (let i = nodes.length - 1; i >= 0; i--) {\n if (!hasOutgoing.has(nodes[i].id)) return nodes[i];\n }\n return undefined;\n}\n\n/** Suggest a unique step id given the current graph. */\nexport function suggestStepId(existing: string[], prefix = \"step\"): string {\n const set = new Set(existing);\n for (let i = 1; i < 1000; i++) {\n const id = `${prefix}_${i}`;\n if (!set.has(id)) return id;\n }\n return `${prefix}_${crypto.randomUUID().slice(0, 8)}`;\n}\n\n// ── Code-view serializers ──────────────────────────────────────────────────\n//\n// The ONE place a step or its params turn into code-view text — three hosts\n// (`StepBuilderModal.tsx`'s `ControlStepConfig`/`AppStepConfig` and\n// `WorkflowFlowEditor.tsx`'s `StepEditModal`) used to call `JSON.stringify`\n// locally, which is how a manual trigger's `<>` came to show only\n// `{\"fields\":[…]}`: `with.fields` is that trigger's one declared param, and a\n// bare `JSON.stringify(step.with)` never surfaced `uses`/`id` at all.\n\n/**\n * A step, or the add-step hosts' in-progress `BuiltStep` (`StepBuilderModal.tsx`)\n * — structurally `FlowStep` minus `id`, which those hosts legitimately have not\n * minted yet (the editor assigns it once the step first joins the graph). Kept\n * structural rather than importing `BuiltStep` so this module stays the\n * dependency-free base every host already imports from, not the other way\n * round.\n */\nexport type StepLike = Omit<FlowStep, \"id\"> & { id?: string };\n\n/**\n * The full-step `<>` view text — every persisted field, `id` included when the\n * caller has one, no more and no less. Core `rfcs/workflow.md`: \"A step **is**\n * an Invocation\", so this is the whole step, not a derived projection — no\n * `kind` field is added, and nothing here special-cases a trigger's\n * `with.fields`; it is an ordinary declared param living in the same `with`\n * slot every step uses.\n *\n * **Read-only in v1 (D-3)** — a hand-edited `uses`/`id` has no validation path\n * today, so callers must not wire a write-back path from this text. Write\n * access stays on {@link paramsToJson}'s view and the Form view.\n */\nexport function stepToJson(step: StepLike): string {\n // A foreach's `with.body` is derived from the canvas — never shown or edited.\n return JSON.stringify(stripBody(step), null, 2);\n}\n\n/**\n * The params-only view text — `step.with`, exactly what the `<>` view showed\n * before this task split \"the whole step\" out from \"just its params\". Still\n * writable: the params-only `JsonEditor`'s `onValidChange` feeds straight back\n * into `with`/`withValues`, same as it always has.\n */\nexport function paramsToJson(step: Pick<StepLike, \"with\"> & { uses?: StepLike[\"uses\"] }): string {\n return JSON.stringify(stripBody(step).with ?? {}, null, 2);\n}\n","/**\n * An upstream step's output SHAPE — the field paths a later step can pick —\n * from the places one can come from. A real shape (a fresh test output, else\n * the persisted one) is the BASE and keeps every key; the app's declared\n * `output` (`core/rfcs/action.md` `OutputField[]`) annotates it and adds its\n * declared-only keys (muted). With no real shape the declared `output` drives\n * the keys alone, then keys inferred from the action's `sample`. With none of\n * these, the author has to run a test.\n *\n * Every field is a dot-separated PATH (`start.utc`), the spec's own notation\n * for nesting (`OutputField.key`: \"Dot notation for nested paths\"). That is\n * also exactly how the engine resolves a ref — JSONLogic `var` splits on `.`\n * (`core/packages/expr/src/jsonlogic.ts` `getVar`) — so `steps.<id>.output.<path>`\n * reaches the nested value. A segment that can't survive that split is dropped\n * by the picker (`isRefSafePath`).\n *\n * Pure and JSX-free so `node --test` exercises it directly.\n */\n\n/** One pickable output field of a step. `key` is a dot path; `label` is display-only. */\nexport interface OutputFieldRef {\n key: string;\n label?: string;\n /** `true` — `key` is a dot path whose segments are checked one by one. */\n path: true;\n /**\n * `true` when a real (fresh/persisted) shape exists and this key came ONLY from the app's\n * declaration — the picker adds it muted, \"declared by the app\".\n */\n declaredOnly?: true;\n}\n\n/**\n * Where a step's offered fields came from: a fresh test output, the persisted test shape,\n * the app's declared `output`, or keys inferred from the app's `sample`.\n */\nexport type OutputShapeSource = \"fresh\" | \"persisted\" | \"declared\" | \"sample\";\n\n/** How deep inference walks a sample/test value. Deeper paths stay reachable via the parent. */\nconst MAX_DEPTH = 3;\n/** Cap on inferred fields per step, so a huge test payload can't flood the rail. */\nconst MAX_FIELDS = 100;\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/**\n * The fields an action's `output` declares, or `undefined` when it declares\n * none. A `DynamicOutput` (`{ source }`) is resolved by a hook the editor does\n * not run, so it counts as \"nothing declared\" and the test-run fallback applies.\n */\nexport function declaredOutputFields(output: unknown): OutputFieldRef[] | undefined {\n if (!Array.isArray(output)) return undefined;\n const fields: OutputFieldRef[] = [];\n const seen = new Set<string>();\n const add = (f: OutputFieldRef) => {\n if (seen.has(f.key)) return;\n seen.add(f.key);\n fields.push(f);\n };\n for (const f of output) {\n if (!isPlainObject(f) || typeof f.key !== \"string\" || f.key === \"\") continue;\n const label = typeof f.label === \"string\" && f.label !== \"\" ? f.label : undefined;\n add({ key: f.key, ...(label ? { label } : {}), path: true });\n // `items` (core/rfcs/action.md): one level of list-element fields, offered as the\n // element-index path `<key>.0.<itemKey>` the engine resolves (and the editor already\n // builds for an after-loop For each).\n if (f.type === \"array\" && Array.isArray(f.items)) {\n for (const it of f.items) {\n if (!isPlainObject(it) || typeof it.key !== \"string\" || it.key === \"\") continue;\n const il = typeof it.label === \"string\" && it.label !== \"\" ? it.label : undefined;\n add({ key: `${f.key}.0.${it.key}`, ...(il ? { label: il } : {}), path: true });\n }\n }\n }\n return fields.length > 0 ? fields : undefined;\n}\n\n/**\n * The item keys a declared array field's `items` lists (`undefined` when the key is not a\n * declared array field with items) — what a never-run For each over that array iterates.\n */\nexport function declaredItemFields(output: unknown, key: string): OutputFieldRef[] | undefined {\n if (!Array.isArray(output)) return undefined;\n const f = output.find((o) => isPlainObject(o) && o.key === key);\n if (!isPlainObject(f) || !Array.isArray(f.items)) return undefined;\n return declaredOutputFields([{ key, type: \"array\", items: f.items }])\n ?.filter((x) => x.key !== key)\n .map((x) => ({ ...x, key: x.key.slice(key.length + 3) }));\n}\n\n/**\n * Field paths inferred from a concrete value (an action's `sample` or a test\n * run's output): every key of a plain object, recursing into nested plain\n * objects up to {@link MAX_DEPTH}. Arrays and scalars are leaves. `undefined`\n * when the value isn't a plain object with at least one key.\n */\nexport function inferOutputFields(value: unknown): OutputFieldRef[] | undefined {\n if (!isPlainObject(value)) return undefined;\n const fields: OutputFieldRef[] = [];\n const walk = (obj: Record<string, unknown>, prefix: string, depth: number) => {\n for (const [k, v] of Object.entries(obj)) {\n if (fields.length >= MAX_FIELDS) return;\n const key = prefix ? `${prefix}.${k}` : k;\n fields.push({ key, path: true });\n if (isPlainObject(v) && depth < MAX_DEPTH) walk(v, key, depth + 1);\n }\n };\n walk(value, \"\", 1);\n return fields.length > 0 ? fields : undefined;\n}\n\n/** The value at a dot path inside `value`, or `undefined` when any segment is missing. */\nexport function valueAtPath(value: unknown, path: string): unknown {\n let cur: unknown = value;\n for (const seg of path.split(\".\")) {\n if (!isPlainObject(cur) || !(seg in cur)) return undefined;\n cur = cur[seg];\n }\n return cur;\n}\n\n/** The subset of an action definition this module reads. */\nexport interface ActionShapeDef {\n output?: unknown;\n sample?: unknown;\n}\n\n/**\n * Resolve a step's offered fields. KEYS MERGE and never hide:\n * - with a real shape (the fresh test output, else the persisted one) every real key is\n * offered; the app's declared `output` annotates matching keys (label) and its\n * declared-only keys are appended with `declaredOnly: true`;\n * - with no real shape, the declared `output` drives the keys alone (`declared`), else\n * the keys inferred from `sample` (`sample`).\n * `action` is the app action/trigger definition (`undefined` while its app is loading);\n * `fresh` / `persisted` are SEPARATE inputs so the tier stays visible.\n */\nexport function resolveOutputShape(\n action: ActionShapeDef | undefined,\n fresh: unknown,\n persisted?: unknown,\n): { fields: OutputFieldRef[]; from: OutputShapeSource } | undefined {\n const declared = declaredOutputFields(action?.output);\n const freshFields = inferOutputFields(fresh);\n const realFields = freshFields ?? inferOutputFields(persisted);\n if (realFields) {\n const byKey = new Map((declared ?? []).map((d) => [d.key, d]));\n const have = new Set(realFields.map((f) => f.key));\n const merged: OutputFieldRef[] = realFields.map((f) => {\n const d = byKey.get(f.key);\n return d?.label ? { ...f, label: d.label } : f;\n });\n for (const d of declared ?? []) if (!have.has(d.key)) merged.push({ ...d, declaredOnly: true });\n return { fields: merged, from: freshFields ? \"fresh\" : \"persisted\" };\n }\n if (declared) return { fields: declared, from: \"declared\" };\n const fromSample = inferOutputFields(action?.sample);\n if (fromSample) return { fields: fromSample, from: \"sample\" };\n return undefined;\n}\n","/**\n * The incoming state a single-step Test / ▶ Run is sent with, and the pure\n * graph logic that derives it. Extracted out of `WorkflowFlowEditor.tsx` so\n * `node --test` can exercise it directly — the same precedent `flow-connect.ts`\n * sets (see that file's own header comment); this module stays JSX-free.\n *\n * Three surfaces mount this state today, all from the SAME functions so they\n * cannot drift: the step editor's Test tab and the canvas ▶ Run collect form\n * (both already wired, unchanged by this move) and `StepBuilderModal`'s\n * add-step Test tab (T1.1.1 — the new caller, via {@link stepBuilderUpstreamSteps}).\n */\nimport type { Edge } from \"@xyflow/react\";\nimport type {\n ExpressionFieldSource,\n ExpressionLoopSource,\n ExpressionStepSource,\n} from \"./components/ExpressionOptions.tsx\";\nimport { wholeValueRef } from \"./components/json-compose.ts\";\nimport { isForeachStep, loopBodies, loopMembership } from \"./flow-loop.ts\";\nimport {\n STOP_APP,\n TRIGGER_APP,\n WEBHOOK_APP,\n internalNodeDef,\n isInternalApp,\n} from \"./flow-types.ts\";\nimport type { StepNode } from \"./flow-utils.ts\";\nimport {\n type ActionShapeDef,\n type OutputShapeSource,\n declaredItemFields,\n inferOutputFields,\n resolveOutputShape,\n valueAtPath,\n} from \"./output-shape.ts\";\nimport type { StepMeta, StepStartState, StepTest } from \"./provider.tsx\";\nimport { buildResolveScope, resolveParamValue } from \"./resolve-params.ts\";\nimport { asFieldDefs, fieldsToParams } from \"./trigger-fields.ts\";\nimport { type SubscriptionSummary, isExprValue, isSecretValue } from \"./types.ts\";\nimport { type FlowConnections, connectionIdFor } from \"./workflow-connections.ts\";\n\n/**\n * What the editor knows about upstream steps' output SHAPES beyond the static\n * `internalNodeDef(...).output` — both optional, so a caller without them gets\n * exactly the old projection.\n */\nexport interface StepShapeContext {\n /**\n * An app step's action definition (its declared `output` / `sample`).\n * `undefined` while that app's actions haven't loaded — the step then makes\n * no \"run a test\" claim it might have to retract a moment later.\n */\n actionDef?: (app: string, action: string) => ActionShapeDef | undefined;\n /**\n * An app TRIGGER's definition (its declared `output` / `sample`), same \"undefined = not\n * loaded, no claim\" semantics as `actionDef`. Feeds `trigger.event.<key>`.\n */\n triggerDef?: (app: string, trigger: string) => ActionShapeDef | undefined;\n /** Each step's FRESH test-run output (this session), by step id. */\n testOutputs?: Record<string, unknown>;\n /**\n * Each step's PERSISTED test output (server-side `node_samples`), by step id. A SEPARATE\n * input from `testOutputs` so the tiers stay visible; fresh beats persisted.\n */\n persistedOutputs?: Record<string, unknown>;\n /** Each For each's saved Test sample (`foreachTestSample`), by step id — the item-shape fallback. */\n loopSamples?: Record<string, unknown[]>;\n}\n\n/** A graph ancestor carrying a saved step-test, offered as a one-click seed. */\nexport interface SeedSource {\n stepId: string;\n label: string;\n test: StepTest;\n}\n\n/**\n * `pendingConnect`'s shape (`WorkflowFlowEditor.tsx`'s state): the handle a\n * connection drag was released from, when it ended on empty canvas and opened\n * the step builder to create + auto-wire a new node. `position` is part of\n * that state too (where to place the new node) but unused by the direction\n * rule below, so it is deliberately omitted here — `pendingConnect`'s real\n * type carries it, and a wider object satisfies this narrower one structurally.\n */\ninterface PendingConnect {\n nodeId: string;\n handleType: \"source\" | \"target\";\n /** The lane the drag came off (WFE's `pendingConnect` carries it). */\n lane?: \"success\" | \"error\" | \"each\";\n}\n\n/**\n * Every node id that is a graph ancestor of `rootId` — walks `edges` backward. Exported for\n * `state-shape.ts` (which imports this module, never the reverse).\n */\nexport function ancestorIds(rootId: string, edges: Edge[]): Set<string> {\n const parents = new Map<string, string[]>();\n for (const e of edges) {\n const arr = parents.get(e.target) ?? [];\n arr.push(e.source);\n parents.set(e.target, arr);\n }\n const ancestors = new Set<string>();\n const stack = [rootId];\n while (stack.length) {\n const id = stack.pop() as string;\n for (const p of parents.get(id) ?? []) {\n if (!ancestors.has(p)) {\n ancestors.add(p);\n stack.push(p);\n }\n }\n }\n return ancestors;\n}\n\n/**\n * Project the nodes in `ids` into `ExpressionStepSource`s, the one place that\n * decides trigger detection and declared-output projection — shared by\n * {@link upstreamStateSources} and {@link stepBuilderUpstreamSteps} so both\n * callers agree on what a trigger ancestor looks like.\n */\nfunction projectStepSources(\n ids: Set<string>,\n nodes: StepNode[],\n shapes: StepShapeContext = {},\n): {\n steps: ExpressionStepSource[];\n hasTrigger: boolean;\n eventOutputs?: ExpressionFieldSource[];\n eventOutputsFrom?: OutputShapeSource;\n} {\n const steps: ExpressionStepSource[] = [];\n let hasTrigger = false;\n let eventShape: ReturnType<typeof resolveOutputShape>;\n for (const n of nodes) {\n if (!ids.has(n.id)) continue;\n const step = n.data.step;\n // A Stop workflow ends the run, so no step after it reads its output. Its static meta\n // still reaches the Metadata section, which reads `nodeMeta`, not these sources.\n if (step.uses.app === STOP_APP) continue;\n const isTrigger = internalNodeDef(step.uses.app, step.uses.action)?.group === \"trigger\";\n // What this node last produced — a Test this session (fresh), else the server's remembered\n // sample (`node_samples`, written by every run and test of it, a trigger's included).\n const testOutput = shapes.testOutputs?.[step.id];\n const persistedOutput = shapes.persistedOutputs?.[step.id];\n if (step.uses.trigger === true) {\n // An APP trigger's output IS the event that fired it, so once it has run, `trigger.event`\n // and `nodes.<id>.output` offer the same fields: the last payload it ran with (fresh, else\n // persisted), labelled with — and topped up by — the trigger's declared event fields.\n hasTrigger = true;\n const shape = resolveOutputShape(\n shapes.triggerDef?.(step.uses.app, step.uses.action),\n testOutput,\n persistedOutput,\n );\n eventShape ??= shape;\n // Only an OBSERVED payload aliases `nodes.<id>.output`: declared fields stay on `trigger.event`.\n if (shape && (shape.from === \"fresh\" || shape.from === \"persisted\")) {\n steps.push({ id: step.id, label: step.id, outputs: shape.fields, outputsFrom: shape.from });\n continue;\n }\n }\n if (isTrigger) {\n // `trigger.event` stays on offer — but the trigger is ALSO a `steps.<id>`\n // source (see `upstreamStateSources`'s doc below), so it falls through to\n // the push.\n hasTrigger = true;\n }\n // Declared output fields, from one of two DISJOINT sources today — a\n // manual trigger's own `with.fields`, or a node's static `output`\n // declaration (`internalNodeDef(...).output`, e.g. `@w6w/template ·\n // render` / `@w6w/http · request`). A manual trigger never carries a\n // static `output` (INTERNAL_NODES declares one or the other, never both),\n // so this is written as explicit precedence rather than a merge that could\n // silently clobber one with the other: the manual-trigger path wins when\n // it applies, the static declaration is the fallback otherwise.\n //\n // MANUAL-TRIGGER-ONLY for the `with.fields` path: a webhook/scheduler\n // entry node's `with.fields` payload is `trigger.event` (see the\n // file-header-level doc below), not `steps.<id>.output`, so it must not be\n // projected here; on any other node `with.fields` is that action's INPUT,\n // and projecting it would fabricate declared outputs the step never\n // produces. The trigger-field parser already skips a blank/missing `key`.\n const isManualTrigger = isTrigger && step.uses.app === TRIGGER_APP;\n const declared: { key: string; label?: string }[] = isManualTrigger\n ? fieldsToParams(asFieldDefs(step.with?.fields)).map((p) => ({\n key: p.key,\n label: p.label,\n }))\n : (internalNodeDef(step.uses.app, step.uses.action)?.output ?? []);\n const source: ExpressionStepSource = { id: step.id, label: step.id };\n // OMITTED (not `[]`) when nothing is declared, so a consumer can tell\n // \"nothing declared\" from \"declared none\". Keys are verbatim: each becomes\n // `steps.<id>.output.<key>`, and only that form resolves at run time.\n if (declared.length > 0) {\n steps.push({ ...source, outputs: declared });\n continue;\n }\n // An entry node with no declared fields (a webhook, a schedule, a field-less Manual trigger)\n // outputs the payload it ran with — the sample payload on an editor run, the received event\n // on a delivery — so its last observed output (fresh, else persisted) is its shape. A webhook\n // or schedule's output is also the run's event, so `trigger.event` offers the same fields; a\n // Manual trigger's run has no event, so it never feeds `trigger.event`.\n if (isTrigger) {\n const real = resolveOutputShape(undefined, testOutput, persistedOutput);\n if (real && !isManualTrigger) eventShape ??= real;\n steps.push(real ? { ...source, outputs: real.fields, outputsFrom: real.from } : source);\n continue;\n }\n if (isInternalApp(step.uses.app)) {\n // A built-in node with no static output (`@w6w/script`, a Function\n // call, …): its last test run (fresh, else persisted) is the only shape there is.\n const real = resolveOutputShape(undefined, testOutput, persistedOutput);\n steps.push(real ? { ...source, outputs: real.fields, outputsFrom: real.from } : source);\n continue;\n }\n // An app action: its declared `output`, else its `sample`, else the last\n // test run (`output-shape.ts`). With none, the author has to run a test —\n // but only say so once the action definition has actually loaded.\n const action = shapes.actionDef?.(step.uses.app, step.uses.action);\n const shape = resolveOutputShape(action, testOutput, persistedOutput);\n // Only this branch is an external app action, so only it carries `hasMeta` (R-7),\n // and only with a real app id (a blank `uses.app` is a half-built step).\n const meta = step.uses.app.trim() !== \"\" ? { hasMeta: true as const } : {};\n if (shape) {\n steps.push({ ...source, outputs: shape.fields, outputsFrom: shape.from, ...meta });\n } else {\n steps.push(action ? { ...source, needsTest: true, ...meta } : { ...source, ...meta });\n }\n }\n return {\n steps,\n hasTrigger,\n ...(eventShape ? { eventOutputs: eventShape.fields, eventOutputsFrom: eventShape.from } : {}),\n };\n}\n\n/**\n * The array a For each's `items` resolves to at design time, or `undefined`.\n * A whole-value ref (`{{ nodes.x.output.tickets }}` / `{ \"$\": … }`) resolves through\n * `resolve-params.ts` against the saved test outputs; a literal array is returned as-is;\n * anything else (a non-array result, a multipart template, a missing ref) is `undefined`.\n */\nexport function resolveLoopItems(\n items: unknown,\n testOutputs: Record<string, unknown>,\n): unknown[] | undefined {\n const steps: Record<string, { output?: unknown }> = {};\n for (const [id, output] of Object.entries(testOutputs)) steps[id] = { output };\n return resolveLoopItemsInState(items, { steps });\n}\n\n/**\n * {@link resolveLoopItems} against a whole Test start state (`startStateFromSeeds`), so a\n * For each's own Test resolves `items` exactly as the other steps' Test previews do — a\n * `trigger.event` ref included.\n */\nexport function resolveLoopItemsInState(\n items: unknown,\n state: StepStartState | undefined,\n): unknown[] | undefined {\n if (wholeValueRef(items) !== null) {\n const segs = resolveParamValue(items, buildResolveScope(undefined, state));\n const seg = segs.length === 1 ? segs[0] : undefined;\n return seg?.status === \"resolved\" && Array.isArray(seg.value) ? seg.value : undefined;\n }\n return Array.isArray(items) ? items : undefined;\n}\n\n/** How many items a For each's saved Test keeps: enough for the shape, never the whole list. */\nexport const FOREACH_TEST_SAMPLE_MAX = 10;\n\n/**\n * The step-test fixture a For each's Test saves. Nothing runs, so no run is recorded and\n * `lastRunOutput` stays empty — the For each's real output is its BODY's results, and an\n * after-loop step must not preview (or be seeded with) the input list as that. The sample\n * rides in the fixture's `with` instead: the resolved `items` (capped) and the full count.\n */\nexport function foreachTestFixture(\n items: unknown[],\n input: Record<string, unknown>,\n): { input: Record<string, unknown>; with: Record<string, unknown> } {\n return {\n input,\n with: { items: items.slice(0, FOREACH_TEST_SAMPLE_MAX), itemCount: items.length },\n };\n}\n\n/** The sample a For each's saved Test carries (`foreachTestFixture`), or `undefined`. */\nexport function foreachTestSample(test: StepTest | null | undefined): unknown[] | undefined {\n const items = test?.with?.items;\n return Array.isArray(items) && items.length > 0 ? items : undefined;\n}\n\n/**\n * The picker's loop-aware projection, in ONE place (never a filter in a caller).\n * `ownLoop` is the For each the anchor sits in the body of (or is about to join).\n * - Inside that body the For each itself is dropped (its own output does not exist yet),\n * along with every OTHER loop's body steps; earlier body steps and the For each's own\n * ancestors stay.\n * - Any other For each in scope (after the loop) keeps its place and offers `items` plus the\n * LAST body step's fields as `items.0.<field>` (D-A11). Body steps are never offered.\n */\nfunction loopAwareSources(\n ids: Set<string>,\n ownLoop: string | undefined,\n nodes: StepNode[],\n edges: Edge[],\n shapes: StepShapeContext = {},\n): {\n steps: ExpressionStepSource[];\n hasTrigger: boolean;\n extraSampleIds: string[];\n eventOutputs?: ExpressionFieldSource[];\n eventOutputsFrom?: OutputShapeSource;\n} {\n const membership = loopMembership(nodes, edges);\n const visible = new Set<string>();\n for (const id of ids) {\n if (id === ownLoop) continue;\n const owner = membership[id];\n if (owner !== undefined && owner !== ownLoop) continue;\n visible.add(id);\n }\n const projected = projectStepSources(visible, nodes, shapes);\n const bodies = loopBodies(nodes, edges);\n const extra: string[] = [];\n const steps = projected.steps.map((st): ExpressionStepSource => {\n const body = bodies.get(st.id);\n if (!body || body.length === 0) return st;\n const last = body[body.length - 1];\n const lastStep = nodes.find((n) => n.id === last)?.data.step;\n const testOutputs = shapes.testOutputs ?? {};\n const shape = lastStep\n ? resolveOutputShape(\n shapes.actionDef?.(lastStep.uses.app, lastStep.uses.action),\n testOutputs[last],\n shapes.persistedOutputs?.[last],\n )\n : undefined;\n if (!extra.includes(last)) extra.push(last);\n const fields = (shape?.fields ?? []).map((f) => ({\n key: `items.0.${f.key}`,\n path: true as const,\n ...(f.declaredOnly ? { declaredOnly: true as const } : {}),\n }));\n return {\n id: st.id,\n label: st.label,\n outputs: [{ key: \"items\", path: true }, ...fields],\n ...(shape ? { outputsFrom: shape.from } : {}),\n };\n });\n return {\n steps,\n hasTrigger: projected.hasTrigger,\n extraSampleIds: extra,\n ...(projected.eventOutputs\n ? { eventOutputs: projected.eventOutputs, eventOutputsFrom: projected.eventOutputsFrom }\n : {}),\n };\n}\n\n/** `nodes.<id>.output.<path>` / `steps.<id>.output.<path>` → its parts, else `undefined`. */\nfunction outputRefParts(ref: string): { id: string; path: string } | undefined {\n const segs = ref.trim().split(\".\");\n if ((segs[0] !== \"nodes\" && segs[0] !== \"steps\") || segs.length < 4 || segs[2] !== \"output\") {\n return undefined;\n }\n return { id: segs[1], path: segs.slice(3).join(\".\") };\n}\n\n/** The declared item keys / sample item behind a For each's whole-value `items` ref, if any. */\nfunction declaredLoopItems(\n items: unknown,\n nodes: StepNode[],\n shapes: StepShapeContext,\n): { itemSample?: unknown; itemOutputs?: ExpressionFieldSource[] } | undefined {\n const ref = wholeValueRef(items);\n const parts = ref ? outputRefParts(ref) : undefined;\n const step = parts ? nodes.find((n) => n.id === parts.id)?.data.step : undefined;\n if (!parts || !step) return undefined;\n const def = shapes.actionDef?.(step.uses.app, step.uses.action);\n const sampled = valueAtPath(def?.sample, parts.path);\n const first = Array.isArray(sampled) && sampled.length > 0 ? sampled[0] : undefined;\n const declaredItems = declaredItemFields(def?.output, parts.path);\n const itemOutputs = declaredItems ?? inferOutputFields(first);\n if (first === undefined && !itemOutputs) return undefined;\n return {\n ...(first !== undefined ? { itemSample: first } : {}),\n ...(itemOutputs ? { itemOutputs } : {}),\n };\n}\n\n/** The `loop` source for a step in `foreachId`'s body — keys absent when unresolvable. */\nfunction loopSourceFor(\n foreachId: string,\n nodes: StepNode[],\n shapes: StepShapeContext = {},\n): ExpressionLoopSource {\n const loop: ExpressionLoopSource = { foreachId };\n const items = nodes.find((n) => n.id === foreachId)?.data.step.with?.items;\n // Live resolution first (it follows the current binding); the For each's own saved Test\n // covers the case the upstream steps have no saved output to resolve against.\n // Real outputs are read fresh-else-persisted (a persisted test supplies what no fresh one did).\n const real = { ...(shapes.persistedOutputs ?? {}), ...(shapes.testOutputs ?? {}) };\n const live = resolveLoopItems(items, real);\n const arr = live && live.length > 0 ? live : shapes.loopSamples?.[foreachId];\n if (arr && arr.length > 0) {\n loop.itemSample = arr[0];\n const outputs = inferOutputFields(arr[0]);\n if (outputs) loop.itemOutputs = outputs;\n return loop;\n }\n // Never run: a whole-value ref to an upstream step's DECLARED array field gives the item\n // keys (`items`), and a declared `sample`'s first element the sample item. Never fabricated.\n const declared = declaredLoopItems(items, nodes, shapes);\n if (declared?.itemSample !== undefined) loop.itemSample = declared.itemSample;\n if (declared?.itemOutputs) loop.itemOutputs = declared.itemOutputs;\n return loop;\n}\n\n/**\n * The workflow state a given step can reference: the outputs of every step\n * that runs before it (its graph ancestors) plus whether a trigger precedes\n * it.\n *\n * A trigger ancestor is **both**. It is pushed into `steps` like any other\n * ancestor — `core/rfcs/node-types.md` (\"Triggers as nodes\"): *\"Executing a\n * trigger node yields the run's start payload … which downstream nodes read as\n * `steps.<triggerId>.output`\"* — **and** it sets `hasTrigger`, which offers the\n * separate `trigger.event` root. The two are different values, not two spellings\n * of one: `trigger.event` is the dispatcher-delivered event payload (seeded from\n * `seed.event`), while a manual trigger's filled fields land under\n * `steps.<id>.output`. Offering only the former is why a trigger's declared\n * fields were unreachable from the picker.\n *\n * A **manual trigger** that declares output fields (`with.fields`) carries\n * them as `outputs`, so a consumer can offer `steps.<id>.output.<key>` per\n * field. Only a manual trigger: `fields` is an ordinary param name, and on any\n * other node — including a webhook/scheduler entry node, whose payload is\n * `trigger.event` instead (see the ⚠️ note below) — it holds that action's\n * INPUT; an `@w6w/http:request` with `with.fields = [{key:\"x\"}]` would\n * otherwise be advertised as declaring an output `x` it never produces. The\n * manual trigger's `fields` is the one case where the param IS the output\n * contract (`core/rfcs/node-types.md:194-196`; `trigger.md:119` covers only\n * what drives editor autocomplete).\n *\n * ⚠️ These declared fields resolve differently on each run path. On the\n * **single-step Test / ▶ Run** path (below), this editor sends a start state\n * seeded from the upstream saved fixtures (see {@link startStateFromSeeds})\n * which `POST /apps/:id/actions/:key/invoke` projects onto\n * `steps.<id>.output`. On a **full run**, a manual trigger's declared fields\n * resolve too: `POST /workflows/:id/run` accepts an `input` body field, and\n * `run-workflow.ts` seeds the `@w6w/trigger` node's own output with it\n * (verified by `server/e2e/trigger_run_payload_e2e_test.ts`). A\n * webhook/scheduler entry node's declared fields do **not** resolve on a full\n * run — its payload there is `trigger.event`, not `steps.<id>.output`, by\n * design (`core/rfcs/trigger.md:378`) — which is exactly why the projection\n * above is narrowed to a manual trigger only.\n *\n * With no specific step (shouldn't happen for a field edit) every node is offered.\n */\nexport function upstreamStateSources(\n editingId: string | null,\n nodes: StepNode[],\n edges: Edge[],\n shapes?: StepShapeContext,\n draftId?: string | null,\n): {\n steps: ExpressionStepSource[];\n hasTrigger: boolean;\n /** Present iff the anchor step is a loop-body member. */\n loop?: ExpressionLoopSource;\n /**\n * Saved tests the projection reads beyond `steps`: an after-loop For each's last body step,\n * and the enclosing For each itself (its Test's item sample).\n */\n extraSampleIds?: string[];\n /** An app trigger ancestor's declared `trigger.event.<key>` fields. */\n eventOutputs?: ExpressionFieldSource[];\n eventOutputsFrom?: OutputShapeSource;\n} {\n // `draftId` anchors the add-step builder's rail once the draft has a place in the graph — an\n // incoming edge, or a loop body. Ancestry already honors exclusive branches: a step on an If's\n // other branch or another Router route is no ancestor, so it is not offered. Only a floating\n // draft (no incoming edge yet) keeps offering every node.\n let anchor = editingId;\n if (\n !anchor &&\n draftId &&\n (edges.some((e) => e.target === draftId) || loopMembership(nodes, edges)[draftId] !== undefined)\n ) {\n anchor = draftId;\n }\n if (!anchor) return projectStepSources(new Set(nodes.map((n) => n.id)), nodes, shapes);\n const ownLoop = loopMembership(nodes, edges)[anchor];\n const out = loopAwareSources(ancestorIds(anchor, edges), ownLoop, nodes, edges, shapes);\n if (ownLoop && !out.extraSampleIds.includes(ownLoop)) out.extraSampleIds.push(ownLoop);\n return {\n steps: out.steps,\n hasTrigger: out.hasTrigger,\n ...(out.eventOutputs\n ? { eventOutputs: out.eventOutputs, eventOutputsFrom: out.eventOutputsFrom }\n : {}),\n ...(ownLoop ? { loop: loopSourceFor(ownLoop, nodes, shapes) } : {}),\n ...(out.extraSampleIds.length > 0 ? { extraSampleIds: out.extraSampleIds } : {}),\n };\n}\n\n/**\n * The new add-step wizard's graph ancestors, derived from `pendingConnect` —\n * the handle a connection drag was released from before the builder opened\n * (`null` for a floating add with no drag at all).\n *\n * **Direction matters.** `addBuiltStep`'s edge-wiring ternary\n * (`WorkflowFlowEditor.tsx`) only makes the new step DOWNSTREAM of\n * `pendingConnect.nodeId` when the drag came off a **source** handle\n * (`[pendingConnect.nodeId, id]`); off a **target** handle the new step becomes\n * the edge's SOURCE instead (`[id, pendingConnect.nodeId]`), so\n * `pendingConnect.nodeId` ends up downstream of the new step, not upstream —\n * offering it as a seed would be backwards. A `handleType: \"source\"` drag\n * carries the dragged node itself (it IS upstream of the step about to be\n * created) plus that node's own ancestors, via the same projection\n * {@link upstreamStateSources} uses.\n */\nexport function stepBuilderUpstreamSteps(\n pendingConnect: PendingConnect | null,\n nodes: StepNode[],\n edges: Edge[],\n shapes?: StepShapeContext,\n): ExpressionStepSource[] {\n if (!pendingConnect || pendingConnect.handleType === \"target\") return [];\n const ids = ancestorIds(pendingConnect.nodeId, edges);\n ids.add(pendingConnect.nodeId);\n const ownLoop = builderOwnLoop(pendingConnect, nodes, edges);\n return loopAwareSources(ids, ownLoop, nodes, edges, shapes).steps;\n}\n\n/**\n * The For each the add-step builder's new step lands in the body of: a drag off a For each's\n * Each-item handle puts it IN that body; a drag off a body step keeps it in that step's body.\n * Off the Done side the For each stays on offer.\n */\nfunction builderOwnLoop(\n pendingConnect: PendingConnect,\n nodes: StepNode[],\n edges: Edge[],\n): string | undefined {\n const dragged = nodes.find((n) => n.id === pendingConnect.nodeId);\n return pendingConnect.lane === \"each\" && isForeachStep(dragged?.data.step)\n ? pendingConnect.nodeId\n : loopMembership(nodes, edges)[pendingConnect.nodeId];\n}\n\n/** The `loop` source for the add-step builder's new step — the same decision as its rail. */\nexport function stepBuilderLoop(\n pendingConnect: PendingConnect | null,\n nodes: StepNode[],\n edges: Edge[],\n shapes?: StepShapeContext,\n): ExpressionLoopSource | undefined {\n if (!pendingConnect || pendingConnect.handleType === \"target\") return undefined;\n const ownLoop = builderOwnLoop(pendingConnect, nodes, edges);\n return ownLoop ? loopSourceFor(ownLoop, nodes, shapes) : undefined;\n}\n\n/**\n * Gather each graph ancestor's latest saved step-test so the incoming-state\n * control can offer it as a seed. **One implementation**, called by every\n * surface that mounts {@link SeedSource}s — the step editor's Test tab, the\n * canvas ▶ Run collect form, and `StepBuilderModal`'s add-step Test tab — so\n * the `gate_1 · succeeded` chip behaves identically everywhere.\n *\n * `listStepTests` is injected (rather than reached for via `useW6WApi()`\n * directly) so this stays a plain async function `node --test` can call with a\n * stub — the React-facing wrapper is `use-seed-sources.ts`'s `useSeedSources`.\n * It returns oldest-first per step, so the last entry is the most recent\n * fixture. A step with no saved fixture (an empty list, or a lookup that\n * throws) contributes nothing — best-effort, per step, never breaking the rest.\n */\nexport async function fetchSeedSources(\n listStepTests: (stepId: string) => Promise<StepTest[]>,\n upstreamSteps: ExpressionStepSource[],\n): Promise<SeedSource[]> {\n const results = await Promise.all(\n upstreamSteps.map(async (s): Promise<SeedSource | null> => {\n try {\n const tests = await listStepTests(s.id);\n const latest = tests.length ? tests[tests.length - 1] : null;\n return latest ? { stepId: s.id, label: s.label ?? s.id, test: latest } : null;\n } catch {\n return null;\n }\n }),\n );\n return results.filter((r): r is SeedSource => r !== null);\n}\n\n/**\n * The start state a single-step Test / ▶ Run is sent with: **the last-known\n * saved output of each upstream step**, keyed by step id, in the shape the\n * invoke route accepts (`{ steps: { <id>: { output } } }` — the server's\n * `StartStateInput`, `packages/api/ambient-scope.ts`). It is what makes a\n * `with` block written as `{{ steps.<id>.output.<field> }}` resolve to the\n * value that step last produced instead of concatenating as `\"\"`.\n *\n * Read from the same `step_tests` fixtures the seed chips offer — no upstream\n * step is re-run to produce it, and nothing here is computed live.\n *\n * A step whose fixture never captured an output contributes **no entry** rather\n * than an empty one, and a set with no outputs at all returns `undefined` so\n * the invoke body carries no `state` key at all (byte-identical to a request\n * from before this existed). Each id gets its OWN `{ output }` object: sharing\n * one would make every reference resolve the last step's data.\n *\n * ⚠️ Single-step scope only. A full run (`POST /workflows/:id/run`) builds its\n * own scope and is not affected by this.\n */\nexport function startStateFromSeeds(\n seeds: SeedSource[],\n loop?: { item?: unknown; index?: number },\n): StepStartState | undefined {\n const steps: Record<string, { output?: unknown; meta?: StepMeta }> = {};\n for (const s of seeds) {\n const output = s.test.lastRunOutput;\n const hasOutput = output !== undefined && output !== null;\n // `lastRunOutput` is NULL for both \"never ran\" and \"ran and returned null\"\n // (`rowToStepTest`), so only a succeeded status tells them apart. A failed\n // run is never seeded, even when it carries meta (meta reaches scope for\n // succeeded steps only).\n if (!hasOutput && s.test.lastRunStatus !== \"succeeded\") continue;\n const meta = s.test.lastRunMeta;\n steps[s.stepId] = { output: hasOutput ? output : null, ...(meta ? { meta } : {}) };\n }\n const hasSteps = Object.keys(steps).length > 0;\n // Off a loop body the result is exactly what it was before `loop` existed.\n if (!loop) return hasSteps ? { steps } : undefined;\n // A loop-body step also carries the iteration scope (`state.foreach`, the same wire shape the\n // engine's inner scope has); the `item` key is present only when there is one.\n return {\n ...(hasSteps ? { steps } : {}),\n foreach: { ...(loop.item !== undefined ? { item: loop.item } : {}), index: loop.index ?? 0 },\n };\n}\n\n/** The default `{ item, index }` a loop-body Test is seeded with: the sample item, index 0. */\nexport function loopSeedFromSource(\n loop: ExpressionLoopSource | undefined,\n): { item?: unknown; index?: number } | undefined {\n if (!loop) return undefined;\n return { ...(\"itemSample\" in loop ? { item: loop.itemSample } : {}), index: 0 };\n}\n\n/** The editable \"Current item\" text a loop's sample item starts as (`\"\"` when there is none). */\nexport function loopItemText(loop: ExpressionLoopSource | undefined): string {\n if (!loop || !(\"itemSample\" in loop)) return \"\";\n return JSON.stringify(loop.itemSample, null, 2) ?? \"\";\n}\n\n/**\n * Parse the loop seed control's two fields. A blank item means \"no item\"; a blank index means 0.\n * Invalid item JSON, or an index that is not a non-negative integer, is an ERROR — the caller\n * refuses the run rather than falling back to the sample.\n */\nexport function parseLoopSeed(\n itemText: string,\n indexText: string,\n): { ok: true; value: { item?: unknown; index: number } } | { ok: false; error: string } {\n let item: unknown;\n if (itemText.trim() !== \"\") {\n try {\n item = JSON.parse(itemText);\n } catch {\n return { ok: false, error: \"The current item must be valid JSON.\" };\n }\n }\n const idx = indexText.trim() === \"\" ? 0 : Number(indexText.trim());\n if (!Number.isInteger(idx) || idx < 0) {\n return { ok: false, error: \"The index must be a whole number, 0 or more.\" };\n }\n return { ok: true, value: { ...(item !== undefined ? { item } : {}), index: idx } };\n}\n\n/**\n * Sample values for a step's `nodes.<id>.meta.*` refs (and the `steps.` alias), from a saved fixture's\n * `lastRunMeta`. Reads the four named fields only; absent meta yields nothing\n * (a version or connection is never derived from anywhere else).\n */\nexport function stepMetaSampleValues(\n stepId: string,\n meta: StepMeta | null | undefined,\n): Record<string, unknown> {\n if (!meta) return {};\n const out: Record<string, unknown> = {};\n // `nodes.` is what the picker inserts; `steps.` stays as its compat alias.\n for (const root of [\"nodes\", \"steps\"]) {\n const p = `${root}.${stepId}.meta`;\n out[`${p}.app`] = meta.app;\n out[`${p}.version`] = meta.version;\n out[`${p}.action`] = meta.action;\n out[`${p}.connectionId`] = meta.connectionId;\n }\n return out;\n}\n\n/**\n * The flat `sampleValues` the expression editor's Result preview reads: each upstream step's\n * last test output on the very refs the picker inserts (`nodes.<id>.output`, `.output.<key>`,\n * each offered nested path), mirrored under `steps.` (the compat alias), plus metadata and,\n * for a loop-body step, `foreach.item` / `foreach.item.<key>` / `foreach.index` (= 0, the\n * sample element's position). Lives here (not in WFE) so a render test can drive it.\n */\nexport function upstreamSampleValues(\n steps: ExpressionStepSource[],\n testOutputs: Record<string, unknown>,\n testMetas: Record<string, StepMeta>,\n loop?: ExpressionLoopSource,\n tiers?: SampleTiers,\n): Record<string, unknown> {\n return collectSampleValues(steps, testOutputs, testMetas, loop, tiers).values;\n}\n\n/**\n * The lower tiers of preview values, beside the fresh `testOutputs`: the PERSISTED test\n * outputs and the app's declared `sample`s (by step id; `event` is an app trigger's sample,\n * read as `trigger.event`). Precedence per ref: fresh > persisted > sample.\n */\nexport interface SampleTiers {\n persisted?: Record<string, unknown>;\n samples?: Record<string, unknown>;\n event?: unknown;\n}\n\n/** Which tier each value in {@link upstreamSampleValues} came from, keyed by the same ref. */\nexport function upstreamSampleValueSources(\n steps: ExpressionStepSource[],\n testOutputs: Record<string, unknown>,\n testMetas: Record<string, StepMeta>,\n loop?: ExpressionLoopSource,\n tiers?: SampleTiers,\n): Record<string, \"fresh\" | \"persisted\" | \"sample\"> {\n return collectSampleValues(steps, testOutputs, testMetas, loop, tiers).sources;\n}\n\n/**\n * The declared `sample` of each app step (by id) and of an app trigger (as the event\n * sample), read through `shapes.actionDef` / `triggerDef`. An `output`-only definition\n * contributes nothing: no placeholders are fabricated.\n */\nexport function declaredSamples(\n nodes: StepNode[],\n shapes: StepShapeContext,\n): { samples: Record<string, unknown>; event?: unknown } {\n const samples: Record<string, unknown> = {};\n let event: unknown;\n for (const n of nodes) {\n const u = n.data.step.uses;\n if (u.trigger === true) {\n const v = shapes.triggerDef?.(u.app, u.action)?.sample;\n if (event === undefined && v !== undefined) event = v;\n continue;\n }\n if (isInternalApp(u.app)) continue;\n const v = shapes.actionDef?.(u.app, u.action)?.sample;\n if (v !== undefined) samples[n.id] = v;\n }\n return { samples, ...(event !== undefined ? { event } : {}) };\n}\n\nfunction collectSampleValues(\n steps: ExpressionStepSource[],\n testOutputs: Record<string, unknown>,\n testMetas: Record<string, StepMeta>,\n loop: ExpressionLoopSource | undefined,\n tiers: SampleTiers = {},\n): { values: Record<string, unknown>; sources: Record<string, \"fresh\" | \"persisted\" | \"sample\"> } {\n const next: Record<string, unknown> = {};\n const sources: Record<string, \"fresh\" | \"persisted\" | \"sample\"> = {};\n for (const st of steps) {\n Object.assign(next, stepMetaSampleValues(st.id, testMetas[st.id]));\n // Lowest tier first; a higher tier overwrites the refs it supplies.\n const layers = [\n [\"sample\", tiers.samples?.[st.id]],\n [\"persisted\", tiers.persisted?.[st.id]],\n [\"fresh\", testOutputs[st.id]],\n ] as const;\n for (const [tier, output] of layers) {\n if (output === undefined) continue;\n const put = (path: string, value: unknown) => {\n for (const root of [\"nodes\", \"steps\"]) {\n next[`${root}.${path}`] = value;\n sources[`${root}.${path}`] = tier;\n }\n };\n put(`${st.id}.output`, output);\n if (typeof output === \"object\" && output !== null && !Array.isArray(output)) {\n for (const [k, v] of Object.entries(output as Record<string, unknown>)) {\n put(`${st.id}.output.${k}`, v);\n }\n }\n for (const o of st.outputs ?? []) {\n if (!o.path || !o.key.includes(\".\")) continue;\n const v = valueAtPath(output, o.key);\n if (v !== undefined) put(`${st.id}.output.${o.key}`, v);\n }\n }\n }\n if (tiers.event !== undefined) {\n const put = (ref: string, value: unknown) => {\n next[ref] = value;\n sources[ref] = \"sample\";\n };\n put(\"trigger.event\", tiers.event);\n if (typeof tiers.event === \"object\" && tiers.event !== null && !Array.isArray(tiers.event)) {\n for (const [k, v] of Object.entries(tiers.event as Record<string, unknown>)) {\n put(`trigger.event.${k}`, v);\n }\n }\n for (const f of inferOutputFields(tiers.event) ?? []) {\n const v = valueAtPath(tiers.event, f.key);\n if (v !== undefined) put(`trigger.event.${f.key}`, v);\n }\n }\n if (loop && \"itemSample\" in loop) {\n next[\"foreach.item\"] = loop.itemSample;\n for (const o of loop.itemOutputs ?? []) {\n const v = valueAtPath(loop.itemSample, o.key);\n if (v !== undefined) next[`foreach.item.${o.key}`] = v;\n }\n next[\"foreach.index\"] = 0;\n }\n return { values: next, sources };\n}\n\n/** A sealed secret, an expression envelope or a `{ \"$\": path }` binding: not configuration. */\nfunction isDynamicValue(v: unknown): boolean {\n if (typeof v !== \"object\" || v === null || Array.isArray(v)) return false;\n const o = v as Record<string, unknown>;\n if (o.type === \"secret\" || o.type === \"expr\") return true;\n const keys = Object.keys(o);\n return keys.length === 1 && keys[0] === \"$\";\n}\n\n/**\n * Each node's configuration keys for the picker's \"Node settings\" group — what the engine lays\n * at `nodes.<id>.config` (`nodeConfigOf`): the step's literal `with` keys (never a secret, never a\n * binding), plus `url` for a webhook trigger node (the host adds it from the node's subscription).\n * A node with none is left out.\n */\nexport function nodeConfigSources(nodes: StepNode[]): { id: string; keys: string[] }[] {\n const out: { id: string; keys: string[] }[] = [];\n for (const n of nodes) {\n const step = n.data.step;\n const keys = Object.entries(step.with ?? {})\n .filter(([, v]) => v !== undefined && !isDynamicValue(v))\n .map(([k]) => k);\n const isWebhook = step.uses.app === WEBHOOK_APP || step.uses.trigger === true;\n if (isWebhook && !keys.includes(\"url\")) keys.unshift(\"url\");\n if (keys.length > 0) out.push({ id: step.id, keys });\n }\n return out;\n}\n\n/** `undefined` for a value that is not static configuration — `@w6w/workflow`'s `staticValue`. */\nfunction staticValue(v: unknown): unknown {\n if (isExprValue(v) || isSecretValue(v)) return undefined;\n if (Array.isArray(v)) return v.map(staticValue).filter((x) => x !== undefined);\n if (typeof v === \"object\" && v !== null) {\n const o = v as Record<string, unknown>;\n const keys = Object.keys(o);\n if (keys.length === 1 && keys[0] === \"$\" && typeof o.$ === \"string\") return undefined;\n const out: Record<string, unknown> = {};\n for (const [k, x] of Object.entries(o)) {\n const sv = staticValue(x);\n if (sv !== undefined) out[k] = sv;\n }\n return out;\n }\n return v;\n}\n\n/**\n * Each node's configuration VALUES — the client's `nodeConfigOf`: the step's static `with`\n * (sealed secrets and bindings dropped, so nothing sealed ever reaches a preview) with a webhook\n * trigger node's `url` laid over it from the workflow's subscriptions, picked as the server's\n * `hostNodeConfig` picks it (the one bound to the node, else for a `@w6w/webhook` node the newest\n * webhook subscription). A node with nothing to configure is absent.\n */\nexport function nodeConfigValues(\n nodes: StepNode[],\n subs: readonly SubscriptionSummary[],\n): Record<string, Record<string, unknown>> {\n const out: Record<string, Record<string, unknown>> = {};\n for (const n of nodes) {\n const step = n.data.step;\n const config = { ...((staticValue(step.with ?? {}) ?? {}) as Record<string, unknown>) };\n const sub = subscriptionFor(step, subs);\n if (sub?.webhookUrl) config.url = sub.webhookUrl;\n if (Object.keys(config).length > 0) out[step.id] = config;\n }\n return out;\n}\n\n/**\n * A webhook trigger node's subscription, picked as the server's `hostNodeStatic` picks it: the\n * one bound to the node, else for a `@w6w/webhook` node the workflow's newest webhook one.\n */\nfunction subscriptionFor(\n step: StepNode[\"data\"][\"step\"],\n subs: readonly SubscriptionSummary[],\n): SubscriptionSummary | undefined {\n if (step.uses.app !== WEBHOOK_APP && step.uses.trigger !== true) return undefined;\n return (\n subs.find((s) => s.nodeId === step.id) ??\n (step.uses.app === WEBHOOK_APP ? subs.find((s) => s.appId === WEBHOOK_APP) : undefined)\n );\n}\n\n/**\n * Each node's static metadata VALUES — the client's `nodeMetaOf`: `app`, `action` and\n * `connectionId` (the node's own connection, else `null`) from the definition, plus a webhook\n * trigger node's `subscriptionId` and `url` from its subscription ({@link subscriptionFor}), and\n * `version` from `apps` — the same summary the canvas labels the node with (`<id> - v<version>`),\n * i.e. the version it will dispatch. Readable at `nodes.<id>.meta.<key>` whether or not the node\n * ran; a run's reported meta overrides it. An app with no known version has no `version` (the\n * previews then say \"resolved at run\"). A node with no app is absent.\n */\nexport function nodeMetaValues(\n nodes: StepNode[],\n subs: readonly SubscriptionSummary[],\n apps?: ReadonlyMap<string, { version?: string }>,\n connections?: FlowConnections,\n): Record<string, Record<string, unknown>> {\n const out: Record<string, Record<string, unknown>> = {};\n for (const n of nodes) {\n const step = n.data.step;\n if (!step.uses.app) continue;\n const meta: Record<string, unknown> = {\n app: step.uses.app,\n action: step.uses.action,\n connectionId: connectionIdFor(step, connections) ?? null,\n };\n const version = apps?.get(step.uses.app)?.version;\n if (version) meta.version = version;\n const sub = subscriptionFor(step, subs);\n if (sub) meta.subscriptionId = sub.id;\n if (sub?.webhookUrl) meta.url = sub.webhookUrl;\n out[step.id] = meta;\n }\n return out;\n}\n\n/**\n * {@link nodeMetaValues} as the flat `sampleValues` the Result preview reads, on the refs the\n * picker inserts (`nodes.<id>.meta.<key>`, mirrored under `steps.`).\n */\nexport function nodeMetaSampleValues(\n meta: Record<string, Record<string, unknown>>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [id, m] of Object.entries(meta)) {\n for (const [k, v] of Object.entries(m)) {\n out[`nodes.${id}.meta.${k}`] = v;\n out[`steps.${id}.meta.${k}`] = v;\n }\n }\n return out;\n}\n","/**\n * The React-facing wrapper around `step-preview-state.ts`'s pure\n * {@link fetchSeedSources} — the one piece of the seed pipeline that must stay\n * a hook (it reaches for `useW6WApi()` + `useState`/`useEffect`), so it lives\n * apart from that JSX-free module. Every surface that offers upstream seed\n * chips mounts this SAME hook: the step editor's Test tab, the canvas ▶ Run\n * collect form, and `StepBuilderModal`'s add-step Test tab.\n */\nimport { useEffect, useState } from \"react\";\nimport type { ExpressionStepSource } from \"./components/ExpressionOptions.tsx\";\nimport { useW6WApi } from \"./provider.tsx\";\nimport { type SeedSource, fetchSeedSources } from \"./step-preview-state.ts\";\n\n/**\n * Gather each graph ancestor's latest saved step-test so the incoming-state\n * control can offer it as a seed. **One implementation**, mounted by every\n * surface — the step editor's Test tab, the canvas ▶ Run collect form, and the\n * add-step builder's Test tab — so the `gate_1 · succeeded` chip behaves\n * identically on each.\n *\n * Driven by `upstreamSteps` (from `upstreamStateSources` /\n * `stepBuilderUpstreamSteps`), not a re-walked graph. Keyed on the *set* of\n * upstream ids rather than the array's identity: that array is rebuilt on\n * every node drag and every field edit, so keying on it would refetch on each\n * keystroke.\n */\nexport function useSeedSources(\n workflowId: string,\n upstreamSteps: ExpressionStepSource[],\n enabled: boolean,\n): SeedSource[] {\n const api = useW6WApi();\n const [seedSources, setSeedSources] = useState<SeedSource[]>([]);\n const idsKey = JSON.stringify(upstreamSteps.map((s) => [s.id, s.label]));\n useEffect(() => {\n const ids = JSON.parse(idsKey) as [string, string][];\n if (!enabled || ids.length === 0) {\n setSeedSources([]);\n return;\n }\n let canceled = false;\n fetchSeedSources(\n (stepId) => api.listStepTests(workflowId, stepId),\n ids.map(([id, label]) => ({ id, label })),\n ).then((seeds) => {\n if (!canceled) setSeedSources(seeds);\n });\n return () => {\n canceled = true;\n };\n }, [api, workflowId, idsKey, enabled]);\n return seedSources;\n}\n","import { effectiveParam } from \"@w6w/expr\";\nimport {\n type ReactNode,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport { AddConnectionModal } from \"./AddConnectionModal.tsx\";\nimport { AppPicker } from \"./AppPicker.tsx\";\nimport { ConditionEditor } from \"./ConditionEditor.tsx\";\nimport { JsonEditor } from \"./JsonEditor.tsx\";\nimport { type NodeConfig, NodeConfigForm } from \"./NodeConfigForm.tsx\";\nimport { ParamCustomization } from \"./ParamCustomization.tsx\";\nimport { ParamsForm, flattenParams, isParamVisible } from \"./ParamsForm.tsx\";\nimport { RouterEditor } from \"./RouterEditor.tsx\";\nimport { StepNameEditor } from \"./StepNameEditor.tsx\";\nimport { StopEditor } from \"./StopEditor.tsx\";\nimport { TriggerFillForm } from \"./TriggerFillForm.tsx\";\nimport { WaitEditor } from \"./WaitEditor.tsx\";\nimport { WorkflowConnectionPicker, useWorkflowConnections } from \"./WorkflowConnections.tsx\";\nimport { mergeResolvedApps, nextIdBatch } from \"./app-pages.ts\";\nimport { ApiCallsPanel } from \"./components/ApiCallsPanel.tsx\";\nimport { AppIcon } from \"./components/AppIcon.tsx\";\nimport { Combobox } from \"./components/Combobox.tsx\";\nimport { EventbriteTriggerPicker } from \"./components/EventbriteTriggerPicker.tsx\";\nimport {\n type ExpressionLoopSource,\n type ExpressionStepSource,\n useExpressionOptions,\n} from \"./components/ExpressionOptions.tsx\";\nimport { Icon } from \"./components/Icon.tsx\";\nimport { InternalIcon } from \"./components/InternalIcon.tsx\";\nimport { Modal } from \"./components/Modal.tsx\";\nimport { ResultViewer } from \"./components/ResultViewer.tsx\";\nimport { holdsExpression } from \"./components/expression-template.ts\";\nimport type { IconName } from \"./components/icons.tsx\";\nimport { eventbriteTriggerChoices } from \"./eventbrite-trigger-selection.ts\";\nimport {\n CALL_APP,\n DATA_APP,\n DOCUMENT_APP,\n INTERNAL_NODES,\n type InternalNodeDef,\n RACE_APP,\n RACE_DESCRIPTION,\n ROUTER_APP,\n STOP_APP,\n STORE_APP,\n WEBHOOK_APP,\n internalNodeDefaults,\n isControlApp,\n isInternalApp,\n isTriggerApp,\n} from \"./flow-types.ts\";\nimport { stepNameError, stepToJson } from \"./flow-utils.ts\";\nimport { customizedParamValues, hasParamCustomization } from \"./param-customization.ts\";\nimport {\n type StepMeta,\n type StepStartState,\n type W6WApi,\n useW6WApi,\n useWorkflowId,\n useWorkflowProject,\n} from \"./provider.tsx\";\nimport { loopSeedFromSource, startStateFromSeeds } from \"./step-preview-state.ts\";\nimport { rememberableInput } from \"./test-inputs.ts\";\nimport type {\n ActionDef,\n ActionParam,\n ApiCallRecord,\n AppSummary,\n AuthDef,\n ConnectionSummary,\n FunctionSummary,\n ThemeMode,\n WorkflowDetail,\n WorkflowSummary,\n} from \"./types.ts\";\nimport { useSeedSources } from \"./use-seed-sources.ts\";\nimport {\n connectionIdFor,\n defaultConnectionFor,\n withDefaultConnection,\n} from \"./workflow-connections.ts\";\n\n/** The step the builder emits — the editor assigns the final `id` unless `id` carries a\n * name the user chose in the add flow. `NodeConfig` carries the base settings (retry /\n * onError / notes) set on the Config view. */\nexport interface BuiltStep extends NodeConfig {\n /** The node name chosen in the add flow; on `onDraftChange` it renames the minted node. */\n id?: string;\n uses: {\n app: string;\n action: string;\n connection?: string | null;\n connectionRef?: string;\n /** Marks an app TRIGGER node (`action` is the trigger key); the engine/server read it. */\n trigger?: true;\n };\n with?: Record<string, unknown>;\n}\n\nexport interface StepBuilderModalProps {\n onClose: () => void;\n /**\n * Fired once per session, the moment the step first has identity — for an\n * app step, when Setup completes (action + connection, if needed); for a\n * control node, on mount. Returns the minted step id so subsequent edits can\n * target it via {@link StepBuilderModalProps.onDraftChange}.\n */\n // biome-ignore lint/suspicious/noConfusingVoidType: widened so studio's void-returning callers stay assignable.\n onAdd: (step: BuiltStep) => string | undefined | void;\n /**\n * Fired for every field change **after** the step has been committed via\n * `onAdd` — keeps the already-added node current without minting a second\n * one. `id` is the id `onAdd` returned. Progressive commit (mint-then-update)\n * only engages when this is supplied; omitted callers (the Functions/\n * Endpoints pickers) keep the original one-shot \"Add node\" behavior.\n */\n onDraftChange?: (id: string, step: BuiltStep) => void;\n /**\n * The graph's current node ids. With `onDraftChange`, the add flow shows the minted node's\n * name with the same rename control the step editor has, validated against these (unique,\n * no dot), and applies it on Done — so the node is created with that name.\n */\n stepIds?: string[];\n theme?: ThemeMode;\n /**\n * Hide the GRAPH-ONLY tabs — Triggers / Controls / Utilities / Data, the\n * flow-control and internal `@w6w/*` node kinds that only mean something\n * inside a workflow canvas. Used by every picker that binds a *target*\n * rather than adding a node to a graph.\n *\n * ⚠️ It does NOT hide Functions and Workflows, and did not always behave\n * that way: it used to, which is why the Implementation card's picker\n * showed only `Connected apps / Apps / AI` and F-2.0's tabs were\n * unreachable outside the canvas. A Function and a Workflow are *callable\n * targets*, not graph-only node kinds — they belong in every picker.\n * {@link StepBuilderModalProps.callables} is the knob for those two.\n */\n appsOnly?: boolean;\n /**\n * Which callable families the Functions/Workflows tabs offer. Defaults to\n * BOTH, so a caller that says nothing keeps the full F-2.0 homepage\n * (`Connected apps | Functions | Workflows`). Pass a narrower array — or\n * `[]` — where the surrounding contract cannot accept one of them.\n */\n callables?: readonly (\"function\" | \"workflow\")[];\n /**\n * Which homepage tab opens first. Defaults to `\"connected\"` — F-2.0's\n * homepage. A caller re-opening the picker for an already-bound target\n * passes that target's own family, so \"Change\" lands where the current\n * value lives instead of making the author re-find the tab. The canvas's\n * right-click \"Add trigger\" opens on `\"triggers\"`.\n */\n initialTab?: \"connected\" | \"functions\" | \"workflows\" | \"triggers\";\n\n /** Modal heading. Defaults to \"Add a node\". */\n title?: string;\n /**\n * Workflow-step context, when the builder is opened for a step that already\n * lives in a workflow. When present the `testRequired` save-gate can discover a\n * previously-saved **passing** test for the step via {@link W6WApi.listStepTests}.\n * Absent in the plain add-step flow (the step has no id yet) — there the gate is\n * satisfied by running a passing test in-session.\n */\n workflowId?: string;\n /** Step id paired with {@link StepBuilderModalProps.workflowId}. */\n stepId?: string;\n /**\n * The new step's known graph ancestors, when the builder is opened from the\n * workflow canvas (`stepBuilderUpstreamSteps`, derived from the connection\n * drag that opened it). Threaded into the Test tab's `<StepTestRun>` the same\n * way `StepEditModal` seeds an existing step's Test tab, so a `with` block\n * written as `{{ steps.<id>.output.<field> }}` resolves instead of coming\n * back empty. Absent (defaults to `[]`) for the Functions/Endpoints pickers,\n * which have no graph to draw ancestors from.\n */\n upstreamSteps?: ExpressionStepSource[];\n /**\n * The For each whose body the new step lands in (`stepBuilderLoop`, same decision as its\n * rail). Seeds the Test tab's `state.foreach` with the sample item and index 0; not editable here.\n */\n loop?: ExpressionLoopSource;\n /**\n * Pre-select an app when the modal opens. When provided along with\n * initialAction/initialConnection/initialWith, the modal opens directly\n * to the action configuration view instead of the app picker.\n * Used when editing an existing action (e.g., clicking \"Change\" on an\n * Endpoint's already-configured target).\n */\n initialApp?: AppSummary;\n /**\n * Pre-select an action key. Requires initialApp to be set.\n */\n initialAction?: string;\n /**\n * Pre-select a connection. Requires initialApp and initialAction.\n */\n initialConnection?: string;\n /**\n * Pre-fill the action's parameter values. Requires initialApp and initialAction.\n */\n initialWith?: Record<string, unknown>;\n /**\n * Narrow which apps a scoped caller may pick, everywhere an app list is\n * computed — the \"Apps\" tab's grid, the \"AI\" tab's composed filter, and\n * {@link StepBuilderModalProps.callables}'s \"Ready to use\" tab. An\n * `undefined` filter is a no-op; every existing caller (none of which sets\n * this) is unaffected.\n *\n * On \"Ready to use\", an app built from a connection's inline `app` meta\n * carries only `id` plus those meta keys (`displayName`, icons, brand\n * colours) — no `version` or `categories` — so the filter sees just those,\n * and the selected-app header omits the ` · v<version>` suffix for it.\n */\n appsFilter?: (app: AppSummary) => boolean;\n /**\n * Server-side id allow-list for the Apps-tab picker (forwarded as `ids` to the\n * paged fetch), so the footer total equals the cards shown.\n */\n appsIds?: string[];\n /**\n * Stop at \"a connection is chosen\" — no Action, no Configure/Test. Renders\n * {@link AppConnectionOnlyConfig} in place of the usual `AppStepConfig`\n * once an app is picked. Used by a caller that only needs a connection\n * (e.g. binding a repository), not a runnable step.\n */\n connectionOnly?: boolean;\n /**\n * Fired once, on {@link AppConnectionOnlyConfig}'s footer button — never on\n * selection alone. Only meaningful with {@link StepBuilderModalProps.connectionOnly}.\n */\n onConnected?: (connectionId: string, app: AppSummary) => void;\n /**\n * Callable ids (`fn_…` / `wf_…`) the Functions and Workflows tabs, and the\n * \"Ready to use\" tab, never offer — matched by id equality only. A Function\n * editor passes its own id: a Function bound to itself has no state change,\n * so the only outcome is an infinite loop. Absent ⇒ nothing is excluded.\n */\n excludeCallableIds?: readonly string[];\n /**\n * Fired once an app trigger or webhook picked on the Triggers tab is committed (needs\n * `onDraftChange`), with the new node's id: the host closes this modal and\n * opens that node in its own step editor, as it does for any node.\n */\n onOpenStep?: (id: string) => void;\n}\n\n/** {@link StepBuilderModalProps.callables}'s default — both families. Module\n * scope so the default is one shared frozen array, never a fresh literal per\n * render (it lands in a `useEffect`-free read path, but a stable identity\n * keeps it honest for any future memo). */\nconst CALLABLE_FAMILIES = [\"function\", \"workflow\"] as const;\n\n/** Row glyphs for the home tab's non-app entries, in `InternalIcon`'s\n * stroked-24-viewBox idiom so a Function/Workflow row sits on the same tile\n * an app row's icon does. Feather `git-branch` for a Workflow (it is a graph)\n * and `zap` for a Function (one operation, immediate). */\nconst CALLABLE_GLYPH: Record<\"function\" | \"workflow\", string> = {\n workflow:\n '<line x1=\"6\" y1=\"3\" x2=\"6\" y2=\"15\"/><circle cx=\"18\" cy=\"6\" r=\"3\"/><circle cx=\"6\" cy=\"18\" r=\"3\"/><path d=\"M18 9a9 9 0 0 1-9 9\"/>',\n function: '<polygon points=\"13 2 3 14 12 14 11 22 21 10 12 10 13 2\"/>',\n};\n\ntype Tab =\n | \"connected\"\n | \"functions\"\n | \"workflows\"\n | \"apps\"\n | \"ai\"\n | \"triggers\"\n | \"controls\"\n | \"utilities\"\n | \"data\";\n\n/** Config sub-tabs shared by the add-step config and the node editor. */\ntype StepConfigTab = \"setup\" | \"configure\" | \"test\";\n\n/** The four representations of the Configure tab: form, full-step JSON,\n * params-only JSON, node settings. */\nexport type ConfigView = \"props\" | \"code\" | \"params-code\" | \"config\";\n\n/** The glyph + accessible label each view is drawn with. Every glyph is a named\n * entry of the shared set (`components/icons.tsx`), drawn at 15px like the\n * editor's toolbar glyphs. `props`/`code` read as \"the step, as a form\" vs \"the\n * step, as code\"; `braces` (square braces, NOT `code`'s chevrons) reads as \"the\n * params, as a value\" — distinct at a glance from the pair above it. */\nconst CONFIG_VIEW_GLYPHS: Record<ConfigView, { label: string; icon: IconName }> = {\n props: { label: \"Form\", icon: \"form\" },\n code: { label: \"JSON\", icon: \"code\" },\n \"params-code\": { label: \"Params JSON\", icon: \"braces\" },\n config: { label: \"Node settings\", icon: \"settings-2\" },\n};\n\n/** Every view, in the order the editor's tabs bar has always shown them. */\nconst ALL_CONFIG_VIEWS: ConfigView[] = [\"props\", \"code\", \"params-code\", \"config\"];\n\n/**\n * The props / code / params-code / config view toggle, right-aligned in the\n * tabs bar. Disabled off the Configure tab (all four views represent the\n * action's config).\n *\n * `views` narrows it to a subset, in the order given — a fields ⇄ raw-JSON\n * property form (see `PropertyEntryForm`) passes `[\"props\", \"code\"]`. There is\n * deliberately no second toggle component: one glyph set, one styling, one\n * pressed-state behaviour, however many views a host offers.\n */\nexport function ConfigViewToggle({\n view,\n onChange,\n disabled,\n views = ALL_CONFIG_VIEWS,\n customized = false,\n}: {\n view: ConfigView;\n onChange: (v: ConfigView) => void;\n disabled?: boolean;\n /** Which views to offer, in order. Defaults to all four. */\n views?: ConfigView[];\n customized?: boolean;\n}) {\n const btn = (v: ConfigView) => (\n <button\n key={v}\n type=\"button\"\n title={CONFIG_VIEW_GLYPHS[v].label}\n aria-label={CONFIG_VIEW_GLYPHS[v].label}\n aria-pressed={view === v}\n disabled={disabled}\n className={`w6w-icon-btn${view === v && !disabled ? \" active\" : \"\"}`}\n onClick={() => onChange(v)}\n >\n <Icon name={CONFIG_VIEW_GLYPHS[v].icon} size={15} />\n </button>\n );\n return (\n <div className=\"w6w-view-toggle\">\n {customized && (\n <button\n type=\"button\"\n className=\"w6w-json-customized\"\n disabled={disabled}\n onClick={() => onChange(\"params-code\")}\n title=\"JSON customization adds or overrides form values\"\n >\n JSON customized\n </button>\n )}\n {views.map(btn)}\n </div>\n );\n}\n\n/**\n * Guided \"add a step\" flow. A sidebar toggles between **Apps** (pick app →\n * ensure a connection → pick action → fill params) and **Controls** — the\n * internal nodes: triggers, flow control (if/foreach/parallel/wait), and compute\n * (script/data). Emits a `BuiltStep` via `onAdd`.\n *\n * Data + IO come from `useW6WApi()`, so mount it under `<W6WUIProvider>`.\n */\nexport function StepBuilderModal({\n onClose,\n onAdd,\n onDraftChange,\n theme,\n appsOnly,\n callables = CALLABLE_FAMILIES,\n initialTab,\n title,\n workflowId,\n stepId,\n upstreamSteps = [],\n loop,\n initialApp,\n initialAction,\n initialConnection,\n initialWith,\n appsFilter,\n appsIds,\n connectionOnly,\n onConnected,\n excludeCallableIds,\n onOpenStep,\n stepIds = [],\n}: StepBuilderModalProps) {\n // Naming on add: the id `onAdd` minted for this node, the name the user gave it (applied\n // on Done), and the last step the config emitted (what the rename re-sends).\n const [mintedId, setMintedId] = useState<string | null>(null);\n const [stepName, setStepName] = useState<string | null>(null);\n const lastBuilt = useRef<BuiltStep | null>(null);\n const trackAdd = (step: BuiltStep) => {\n const id = onAdd(step);\n if (typeof id === \"string\") {\n lastBuilt.current = step;\n setMintedId(id);\n setStepName(null);\n }\n return id;\n };\n const trackDraft = onDraftChange\n ? (id: string, step: BuiltStep) => {\n lastBuilt.current = step;\n onDraftChange(id, step);\n }\n : undefined;\n const finish = () => {\n if (mintedId && stepName && stepName !== mintedId && trackDraft && lastBuilt.current) {\n trackDraft(mintedId, { ...lastBuilt.current, id: stepName });\n }\n onClose();\n };\n const titled = (label: ReactNode) =>\n mintedId && onDraftChange ? (\n <span className=\"w6w-stepbuilder-title\">\n {label}\n <StepNameEditor\n value={stepName ?? mintedId}\n onCommit={(id) => {\n const err = stepNameError(\n id,\n stepIds.filter((other) => other !== mintedId),\n );\n if (!err) setStepName(id);\n return err;\n }}\n />\n </span>\n ) : (\n label\n );\n // Default to the apps the user already connected — no searching for the one\n // integration they use every day.\n const [tab, setTab] = useState<Tab>(initialTab ?? \"connected\");\n const [query, setQuery] = useState(\"\");\n // When an app is selected the modal collapses to a single-app detail view:\n // the sidebar is hidden and the header switches to the app's name + icon.\n // Initialize with initialApp if provided to skip the app picker.\n const [selectedApp, setSelectedApp] = useState<AppSummary | null>(initialApp ?? null);\n // Same collapse for a chosen internal node (trigger / control / compute) — its\n // config form (dynamic ParamsForm over the node's schema) shows before adding.\n const [selectedNode, setSelectedNode] = useState<InternalNodeDef | null>(null);\n // An app picked on the Triggers tab runs the SAME `AppStepConfig` as an app\n // picked for an action (app → account → pick), in its `kind=\"trigger\"` mode:\n // picking a trigger adds ONE trigger node the way picking an action adds one.\n const [selectedTriggerApp, setSelectedTriggerApp] = useState<AppSummary | null>(null);\n // Same collapse for a picked Function/Workflow target (D-12/D-15): both tabs\n // mint the SAME `@w6w/call` step shape, so one piece of state (family + id +\n // label) is enough — `CallableStepConfig` decides what to call from `family`.\n const [selectedCallable, setSelectedCallable] = useState<{\n family: \"function\" | \"workflow\";\n id: string;\n label: string;\n } | null>(null);\n\n // The home tab's contents, fetched here rather than inside the tab, because\n // whether the TAB EXISTS depends on them: nothing connected and nothing\n // built ⇒ no \"Ready to use\" tab at all. Still `\"loading\"` counts as present,\n // so the sidebar does not shuffle a beat after it renders.\n const hasAppsIds = !!appsIds && appsIds.length > 0;\n const readyToUse = useReadyToUse(callables, appsFilter, excludeCallableIds, appsIds);\n const homeAvailable = readyToUse.state !== \"empty\";\n // If the home tab vanishes while it is the open one, fall to the catalogue\n // rather than rendering a tab body with no tab.\n useEffect(() => {\n if (!homeAvailable && tab === \"connected\") setTab(\"apps\");\n }, [homeAvailable, tab]);\n\n if (selectedCallable) {\n return (\n <Modal\n title={titled(selectedCallable.label)}\n ariaLabel={selectedCallable.label}\n subtitle={<code>{selectedCallable.id}</code>}\n onClose={onClose}\n size=\"xl\"\n headerRight={\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n onClick={() => setSelectedCallable(null)}\n >\n ← Back\n </button>\n }\n >\n <div className=\"w6w-stepbuilder-config\">\n <CallableStepConfig\n family={selectedCallable.family}\n targetId={selectedCallable.id}\n targetLabel={selectedCallable.label}\n onAdd={trackAdd}\n onClose={onClose}\n onDone={finish}\n onDraftChange={trackDraft}\n />\n </div>\n </Modal>\n );\n }\n\n if (selectedNode) {\n return (\n <Modal\n title={titled(selectedNode.groupActions ? selectedNode.displayName : selectedNode.label)}\n ariaLabel={selectedNode.groupActions ? selectedNode.displayName : selectedNode.label}\n titleIcon={<InternalIcon icon={selectedNode.icon} size={22} />}\n subtitle={\n <code>\n {selectedNode.app}\n {!selectedNode.groupActions && ` · ${selectedNode.action}`}\n </code>\n }\n onClose={onClose}\n size=\"xl\"\n headerRight={\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n onClick={() => setSelectedNode(null)}\n >\n ← Back\n </button>\n }\n >\n <div className=\"w6w-stepbuilder-config\">\n <ControlStepConfig\n node={selectedNode}\n onAdd={trackAdd}\n onClose={onClose}\n onDone={finish}\n onDraftChange={trackDraft}\n onOpenStep={onOpenStep}\n workflowId={workflowId}\n upstreamSteps={upstreamSteps}\n loop={loop}\n />\n </div>\n </Modal>\n );\n }\n\n const pickedApp = selectedTriggerApp ?? selectedApp;\n if (pickedApp) {\n const kind = selectedTriggerApp ? \"trigger\" : \"action\";\n const changeApp = () => {\n setSelectedApp(null);\n setSelectedTriggerApp(null);\n };\n return (\n <Modal\n title={titled(pickedApp.displayName)}\n ariaLabel={pickedApp.displayName}\n subtitle={\n <>\n <code>{pickedApp.id}</code>\n {pickedApp.version && ` · v${pickedApp.version}`}\n </>\n }\n onClose={onClose}\n size=\"xl\"\n titleIcon={\n <AppIcon\n src={pickedApp.iconSvg}\n srcDark={pickedApp.iconSvgDark}\n brandColor={pickedApp.brandColor}\n name={pickedApp.displayName}\n theme={theme}\n size={22}\n />\n }\n >\n <div className=\"w6w-stepbuilder-config\">\n {/* App-switching lives in the Setup tab's \"Change\" (à la Zapier), not a\n top-right back button. */}\n {connectionOnly && kind === \"action\" ? (\n <AppConnectionOnlyConfig\n appId={pickedApp.id}\n app={pickedApp}\n onClose={onClose}\n onChangeApp={changeApp}\n theme={theme}\n initialConnection={initialConnection}\n onConnected={(connectionId, app) => onConnected?.(connectionId, app)}\n />\n ) : (\n <AppStepConfig\n kind={kind}\n onOpenStep={onOpenStep}\n appId={pickedApp.id}\n app={pickedApp}\n onAdd={trackAdd}\n onClose={onClose}\n onDone={finish}\n onDraftChange={trackDraft}\n onChangeApp={changeApp}\n theme={theme}\n workflowId={workflowId}\n stepId={stepId}\n upstreamSteps={upstreamSteps}\n loop={loop}\n // The initial* props pre-fill an ACTION step being edited; a\n // trigger is always picked fresh.\n {...(kind === \"action\" ? { initialAction, initialConnection, initialWith } : {})}\n />\n )}\n </div>\n </Modal>\n );\n }\n\n return (\n <Modal title={title ?? \"Add a node\"} onClose={onClose} size=\"xl\">\n <div className=\"w6w-stepbuilder-picker\">\n <input\n type=\"search\"\n className=\"w6w-stepbuilder-search\"\n aria-label=\"Search nodes and apps\"\n placeholder=\"Search this tab…\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n />\n <div className=\"w6w-stepbuilder\">\n <nav className=\"w6w-stepbuilder-sidebar\">\n {/* F-2.0's homepage, and the order it asks for:\n Ready to use · Apps · AI · Workflows · Functions\n The home tab is ONE list holding connected apps + Workflows +\n Functions (see `ReadyToUseFlow`); the four after it are the\n browse-everything tabs. `callables` still narrows the two\n callable tabs — and the home list with them — for a call site\n whose contract cannot accept one of the families. */}\n {homeAvailable && (\n <button\n type=\"button\"\n className={`w6w-stepbuilder-tab${tab === \"connected\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"connected\")}\n >\n Ready to use\n </button>\n )}\n <button\n type=\"button\"\n className={`w6w-stepbuilder-tab${tab === \"apps\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"apps\")}\n >\n Apps\n </button>\n <button\n type=\"button\"\n className={`w6w-stepbuilder-tab${tab === \"ai\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"ai\")}\n >\n AI\n </button>\n {callables.includes(\"workflow\") && (\n <button\n type=\"button\"\n className={`w6w-stepbuilder-tab${tab === \"workflows\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"workflows\")}\n >\n Workflows\n </button>\n )}\n {callables.includes(\"function\") && (\n <button\n type=\"button\"\n className={`w6w-stepbuilder-tab${tab === \"functions\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"functions\")}\n >\n Functions\n </button>\n )}\n {!appsOnly && (\n <>\n <button\n type=\"button\"\n className={`w6w-stepbuilder-tab${tab === \"triggers\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"triggers\")}\n >\n Triggers\n </button>\n <button\n type=\"button\"\n className={`w6w-stepbuilder-tab${tab === \"controls\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"controls\")}\n >\n Controls\n </button>\n <button\n type=\"button\"\n className={`w6w-stepbuilder-tab${tab === \"utilities\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"utilities\")}\n >\n Utilities\n </button>\n <button\n type=\"button\"\n className={`w6w-stepbuilder-tab${tab === \"data\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"data\")}\n >\n Data\n </button>\n </>\n )}\n </nav>\n <div className=\"w6w-stepbuilder-content\">\n {tab === \"connected\" ? (\n <ReadyToUseFlow\n data={readyToUse}\n query={query}\n appsFilter={appsFilter}\n onSelectApp={setSelectedApp}\n onSelectCallable={setSelectedCallable}\n theme={theme}\n />\n ) : tab === \"functions\" ? (\n <CallableList\n family=\"function\"\n query={query}\n excludeIds={excludeCallableIds}\n onSelect={(t) => setSelectedCallable({ family: \"function\", ...t })}\n />\n ) : tab === \"workflows\" ? (\n <CallableList\n family=\"workflow\"\n query={query}\n excludeIds={excludeCallableIds}\n onSelect={(t) => setSelectedCallable({ family: \"workflow\", ...t })}\n />\n ) : tab === \"apps\" ? (\n <AppPicker\n search={false}\n searchValue={query}\n onSelectApp={setSelectedApp}\n theme={theme}\n filter={appsFilter}\n ids={appsIds}\n />\n ) : tab === \"ai\" ? (\n <AppPicker\n search={false}\n searchValue={query}\n onSelectApp={setSelectedApp}\n theme={theme}\n // `category=\"ai\"` reaches the server on the bounded paged path\n // (A2); `filter` is the client-side backstop every mode still\n // applies — the only path that needs it end-to-end is a legacy\n // `listApps()`-only host, which never sees `category` at all.\n category={hasAppsIds ? undefined : \"ai\"}\n ids={appsIds}\n // With `appsIds` the server-side id set IS the provider set, so\n // the client AI-category backstop is dropped (it would hide a\n // provider and break \"N of N\"); `appsFilter` still applies.\n filter={(a) =>\n (appsFilter?.(a) ?? true) &&\n (hasAppsIds || (a.categories?.includes(\"ai\") ?? false))\n }\n emptyMessage=\"No AI apps registered yet.\"\n />\n ) : tab === \"triggers\" ? (\n <TriggersFlow\n query={query}\n onSelect={setSelectedNode}\n onSelectApp={setSelectedTriggerApp}\n theme={theme}\n appsFilter={appsFilter}\n appsIds={appsIds}\n />\n ) : tab === \"controls\" ? (\n <ControlsFlow query={query} onSelect={setSelectedNode} />\n ) : tab === \"data\" ? (\n <DataFlow query={query} onSelect={setSelectedNode} />\n ) : (\n <UtilitiesFlow query={query} onSelect={setSelectedNode} />\n )}\n </div>\n </div>\n </div>\n </Modal>\n );\n}\n\nfunction matchesPickerQuery(query: string, ...values: Array<string | undefined>): boolean {\n const text = values.filter(Boolean).join(\" \").toLowerCase();\n return query\n .trim()\n .toLowerCase()\n .split(/\\s+/)\n .every((word) => text.includes(word));\n}\n\nfunction matchesNodeQuery(node: InternalNodeDef, query: string): boolean {\n return matchesPickerQuery(query, node.label, node.displayName, node.app, node.action);\n}\n\n// ── Internal nodes tab (triggers, flow control, compute) ───────────────────\n\n/** A flat, clickable list of internal nodes. Shared by Controls + Utilities. */\nfunction NodeList({\n nodes,\n onSelect,\n query,\n}: {\n nodes: InternalNodeDef[];\n onSelect: (node: InternalNodeDef) => void;\n query: string;\n}) {\n const seen = new Set<string>();\n const visible = nodes.filter((n) => {\n if (!matchesNodeQuery(n, query)) return false;\n if (!n.groupActions) return true;\n if (seen.has(n.app)) return false;\n seen.add(n.app);\n return true;\n });\n if (!visible.length) return <p className=\"w6w-muted w6w-small\">No nodes match “{query}”.</p>;\n return (\n <div className=\"w6w-stepbuilder-list\">\n {visible.map((n) => (\n <NodeRow key={`${n.app}:${n.action}`} node={n} onSelect={onSelect} />\n ))}\n </div>\n );\n}\n\n/** One internal-node row — shared by {@link NodeList} and the Triggers tab's built-in column. */\nfunction NodeRow({\n node: n,\n onSelect,\n}: {\n node: InternalNodeDef;\n onSelect: (node: InternalNodeDef) => void;\n}) {\n return (\n <button type=\"button\" className=\"w6w-stepbuilder-item\" onClick={() => onSelect(n)}>\n <InternalIcon icon={n.icon} size={24} />\n <span className=\"w6w-stepbuilder-item-main\">\n <strong>{n.groupActions ? n.displayName : n.label}</strong>\n <code className=\"w6w-muted w6w-small\">\n {n.app}\n {!n.groupActions && ` · ${n.action}`}\n </code>\n </span>\n </button>\n );\n}\n\n/**\n * Triggers tab — the \"Ready to use\" layout (F-2): **Your apps** on the left,\n * the connected apps that declare at least one trigger; **Built-in** on the\n * right (Manual / Webhook / Schedule); and a \"Search all apps\" button that opens\n * an Apps-tab-style `AppPicker` narrowed SERVER-side to apps with triggers\n * (`hasTriggers`).\n *\n * Unlike the home tab, BOTH columns always render: an empty left column says\n * so and points at the search, rather than vanishing and leaving the built-ins\n * to read as the only triggers there are.\n *\n * Picking an app, from either place, runs the app-action flow itself —\n * {@link AppStepConfig} with `kind=\"trigger\"`: account and trigger on the one\n * Setup screen, and picking the trigger adds ONE trigger node; no\n * Subscription is created here (the server derives it when the workflow is\n * published). The built-ins keep their existing `onSelect` → `onAdd` path.\n */\nfunction TriggersFlow({\n query,\n onSelect,\n onSelectApp,\n theme,\n appsFilter,\n appsIds,\n}: {\n query: string;\n onSelect: (node: InternalNodeDef) => void;\n onSelectApp: (app: AppSummary) => void;\n theme?: ThemeMode;\n appsFilter?: (app: AppSummary) => boolean;\n appsIds?: readonly string[];\n}) {\n const api = useW6WApi();\n const nodes = INTERNAL_NODES.filter((n) => n.group === \"trigger\" && matchesNodeQuery(n, query));\n const [searching, setSearching] = useState(false);\n // Connected apps resolved through `listAppsByIds` (inline connection meta has\n // no `triggerCount`), then filtered to the ones that declare a trigger.\n const data = useReadyToUse([], appsFilter, undefined, appsIds, { resolveInline: true });\n\n if (searching) {\n return (\n <div className=\"w6w-stack\">\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n onClick={() => setSearching(false)}\n >\n ← Back\n </button>\n <AppPicker\n onSelectApp={onSelectApp}\n theme={theme}\n filter={appsFilter}\n ids={appsIds ? [...appsIds] : undefined}\n hasTriggers\n search={false}\n searchValue={query}\n emptyMessage=\"No apps declare triggers yet.\"\n />\n </div>\n );\n }\n\n const apps = data.apps\n .filter((a) => (a.triggerCount ?? 0) > 0 && matchesPickerQuery(query, a.displayName, a.id))\n .sort(byLabel((a: AppSummary) => a.displayName));\n const leftRows: ReactNode[] = apps.map((a) => (\n <AppRow key={a.id} app={a} theme={theme} onSelect={onSelectApp} />\n ));\n if (data.moreApps) {\n leftRows.push(\n <button\n key=\"__load_more_apps\"\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n onClick={data.loadMoreApps}\n >\n Load more\n </button>,\n );\n }\n let leftBody: ReactNode;\n if (data.state === \"error\") {\n leftBody = <div className=\"w6w-result w6w-error\">{data.error}</div>;\n } else if (data.state === \"loading\") {\n leftBody = <p className=\"w6w-muted w6w-small\">Loading…</p>;\n } else if (query.trim() && data.appIds?.length && typeof api.listAppsPage === \"function\") {\n leftBody = (\n <AppPicker\n search={false}\n searchValue={query}\n ids={data.appIds}\n hasTriggers\n filter={appsFilter}\n onSelectApp={onSelectApp}\n theme={theme}\n />\n );\n } else if (leftRows.length === 0) {\n leftBody = (\n <p className=\"w6w-muted w6w-small w6w-readytouse-empty\">\n {query.trim()\n ? `No connected apps match “${query}”.`\n : \"No connected apps with triggers yet\"}{\" \"}\n ·{\" \"}\n <button type=\"button\" className=\"w6w-linkbtn\" onClick={() => setSearching(true)}>\n Search all apps\n </button>\n </p>\n );\n } else {\n leftBody = <div className=\"w6w-stepbuilder-list w6w-stepbuilder-scroll\">{leftRows}</div>;\n }\n return (\n <div className=\"w6w-apppicker-host\">\n <div className=\"w6w-readytouse\" data-cols={2}>\n <section className=\"w6w-readytouse-col\" data-col=\"your-apps\">\n <h4 className=\"w6w-readytouse-heading\">Your apps</h4>\n {leftBody}\n </section>\n <div className=\"w6w-readytouse-stack\">\n <section className=\"w6w-readytouse-col\" data-col=\"built-in\">\n <h4 className=\"w6w-readytouse-heading\">Built-in</h4>\n <div className=\"w6w-stepbuilder-list w6w-stepbuilder-scroll\">\n {nodes.length === 0 && (\n <p className=\"w6w-muted w6w-small\">No built-in triggers match “{query}”.</p>\n )}\n {nodes.map((n) => (\n <NodeRow key={`${n.app}:${n.action}`} node={n} onSelect={onSelect} />\n ))}\n </div>\n </section>\n </div>\n </div>\n <div className=\"w6w-readytouse-footer\">\n <button type=\"button\" className=\"w6w-btn\" onClick={() => setSearching(true)}>\n Search all apps\n </button>\n </div>\n </div>\n );\n}\n\n/** Controls tab — engine-native flow control only (branch, loop, parallelize, wait). */\nfunction ControlsFlow({\n onSelect,\n query,\n}: { onSelect: (node: InternalNodeDef) => void; query: string }) {\n const nodes = INTERNAL_NODES.filter((n) => n.group === \"control\" && !n.hidden);\n return (\n <div className=\"w6w-stack\">\n <p className=\"w6w-muted w6w-small\">\n Flow-control nodes branch, route, join paths, loop, parallelize, pause, or stop the run.\n </p>\n <NodeList nodes={nodes} onSelect={onSelect} query={query} />\n </div>\n );\n}\n\n/** Utilities tab — compute + request nodes. Variables and store actions live in Data. */\nfunction UtilitiesFlow({\n onSelect,\n query,\n}: { onSelect: (node: InternalNodeDef) => void; query: string }) {\n const nodes = INTERNAL_NODES.filter(\n (n) =>\n n.group !== \"control\" &&\n n.group !== \"trigger\" &&\n n.app !== DATA_APP &&\n n.app !== DOCUMENT_APP &&\n n.app !== STORE_APP &&\n !n.hidden,\n );\n return (\n <div className=\"w6w-stack\">\n <p className=\"w6w-muted w6w-small\">\n Run scripts, work with regular expressions, render templates, call models, or make HTTP\n requests.\n </p>\n <NodeList nodes={nodes} onSelect={onSelect} query={query} />\n </div>\n );\n}\n\n/** Data tab — typed variables and persistent data-store actions. */\nfunction DataFlow({\n onSelect,\n query,\n}: { onSelect: (node: InternalNodeDef) => void; query: string }) {\n const nodes = INTERNAL_NODES.filter(\n (n) => (n.app === DATA_APP || n.app === STORE_APP || n.app === DOCUMENT_APP) && !n.hidden,\n );\n return (\n <div className=\"w6w-stack\">\n <p className=\"w6w-muted w6w-small\">\n Set data, read documents, read and write store entries, or query stored rows.\n </p>\n <NodeList nodes={nodes} onSelect={onSelect} query={query} />\n </div>\n );\n}\n\n/**\n * Config form for a chosen internal node — its schema rendered through the same\n * `ParamsForm` as app actions, seeded with the node's defaults. Emits the built\n * step on Add.\n */\nexport function ControlStepConfig({\n node: initialNode,\n onAdd,\n onClose,\n onDone,\n onDraftChange,\n onOpenStep,\n workflowId,\n upstreamSteps = [],\n loop,\n}: {\n node: InternalNodeDef;\n // biome-ignore lint/suspicious/noConfusingVoidType: see StepBuilderModalProps.onAdd, forwarded as-is.\n onAdd: (s: BuiltStep) => string | undefined | void;\n onClose: () => void;\n /** Done, once the node is added — applies the add flow's name, then closes. Else `onClose`. */\n onDone?: () => void;\n /** See {@link StepBuilderModalProps.onDraftChange}. */\n onDraftChange?: (id: string, step: BuiltStep) => void;\n /** Open the full webhook editor, including its URL and listener, as soon as it is added. */\n onOpenStep?: (id: string) => void;\n workflowId?: string;\n /** The new step's known graph ancestors — see {@link StepBuilderModalProps.upstreamSteps}. */\n upstreamSteps?: ExpressionStepSource[];\n /** See {@link StepBuilderModalProps.loop}. */\n loop?: ExpressionLoopSource;\n}) {\n const [node, setNode] = useState(initialNode);\n const actions = initialNode.groupActions\n ? INTERNAL_NODES.filter((candidate) => candidate.app === initialNode.app && !candidate.hidden)\n : [];\n const [withValues, setWithValues] = useState<Record<string, unknown>>(() =>\n internalNodeDefaults(node.app, node.action),\n );\n // Internal nodes have no connection/action to pick, so there's no Setup tab —\n // just Configure + Test (flow-control nodes aren't testable standalone).\n const testable = !isControlApp(node.app);\n // The step-being-added's graph ancestors that carry a saved step-test, offered\n // as one-click seeds for the incoming state — the SAME pipeline `StepEditModal`\n // uses, so the Test tab here resolves `{{ steps.<id>.output.<field> }}` the\n // same way an existing step's Test tab does (T1.1.1). Only meaningful when the\n // builder was opened from a workflow canvas (`workflowId` present); the\n // Functions/Endpoints pickers pass no `workflowId` and no `upstreamSteps`.\n const seedSources = useSeedSources(workflowId ?? \"\", upstreamSteps, testable && !!workflowId);\n const testStartState = startStateFromSeeds(seedSources, loopSeedFromSource(loop));\n const [tab, setTab] = useState<\"configure\" | \"test\">(\"configure\");\n const [configView, setConfigView] = useState<ConfigView>(\"props\");\n // Draft text backing the \"code\" (full-step, read-only) view.\n const [codeText, setCodeText] = useState(\"{}\");\n const [draftConfig, setDraftConfig] = useState<NodeConfig>({});\n const configComplete = requiredParamsFilled(node.params, withValues);\n\n // The id `onAdd` minted at commit time, once a control node's identity has\n // been committed to the graph this session. `null` until then (and forever,\n // for a caller that doesn't supply `onDraftChange` — the original one-shot\n // \"Add node\" behavior).\n const [committedId, setCommittedId] = useState<string | null>(null);\n const buildStep = (): BuiltStep => ({\n uses: { app: node.app, action: node.action },\n with: withValues,\n ...draftConfig,\n });\n\n // Mint — a control node has identity the instant it's picked (no Setup tab),\n // so commit it to the graph on mount, exactly once.\n // biome-ignore lint/correctness/useExhaustiveDependencies: mint fires once on mount only; buildStep/onAdd intentionally read fresh closure state without retriggering this effect.\n useEffect(() => {\n if (!onDraftChange) return;\n const id = onAdd(buildStep());\n if (id) setCommittedId(id);\n if (id && node.app === WEBHOOK_APP) onOpenStep?.(id);\n }, []);\n\n // Update — keep the already-committed node current on every subsequent field\n // change, instead of minting a duplicate via a second `onAdd` call.\n // biome-ignore lint/correctness/useExhaustiveDependencies: buildStep reads fresh closure state; only these fields should retrigger the update.\n useEffect(() => {\n if (!onDraftChange || committedId === null) return;\n onDraftChange(committedId, buildStep());\n }, [committedId, withValues, draftConfig, node]);\n\n const changeConfigView = (v: ConfigView) => {\n if (v === \"code\") setCodeText(stepToJson(buildStep()));\n setConfigView(v);\n };\n const add = () => onAdd(buildStep());\n\n return (\n <div className=\"w6w-stepconfig\">\n <div className=\"w6w-tabsbar\">\n <div className=\"w6w-subtabs\">\n <button\n type=\"button\"\n className={`w6w-subtab${tab === \"configure\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"configure\")}\n >\n Configure\n </button>\n {testable && (\n <button\n type=\"button\"\n disabled={!configComplete}\n title={configComplete ? undefined : \"Fill the required fields first\"}\n className={`w6w-subtab${tab === \"test\" ? \" active\" : \"\"}`}\n onClick={() => configComplete && setTab(\"test\")}\n >\n Test\n </button>\n )}\n </div>\n <ConfigViewToggle\n view={configView}\n customized={hasParamCustomization(withValues)}\n onChange={changeConfigView}\n disabled={tab !== \"configure\"}\n />\n </div>\n\n <div className=\"w6w-stepconfig-body\">\n {tab === \"configure\" && configView === \"props\" && actions.length > 1 && (\n <label className=\"w6w-field\">\n <span>Action</span>\n <select\n className=\"w6w-input\"\n aria-label=\"Action\"\n value={node.action}\n onChange={(event) => {\n const next = actions.find((candidate) => candidate.action === event.target.value);\n if (!next) return;\n const defaults = internalNodeDefaults(next.app, next.action);\n setWithValues(\n Object.fromEntries(\n next.params.flatMap((param) =>\n param.key in withValues\n ? [[param.key, withValues[param.key]]]\n : param.key in defaults\n ? [[param.key, defaults[param.key]]]\n : [],\n ),\n ),\n );\n setNode(next);\n }}\n >\n {actions.map((action) => (\n <option key={action.action} value={action.action}>\n {action.label}\n </option>\n ))}\n </select>\n </label>\n )}\n {tab === \"configure\" &&\n (configView === \"props\" ? (\n node.app === RACE_APP ? (\n <p className=\"w6w-muted w6w-small\">{RACE_DESCRIPTION}</p>\n ) : node.action === \"wait\" && isControlApp(node.app) ? (\n <WaitEditor values={withValues} onChange={setWithValues} />\n ) : node.action === \"if\" && isControlApp(node.app) ? (\n <ConditionEditor values={withValues} onChange={setWithValues} />\n ) : node.app === STOP_APP ? (\n <StopEditor values={withValues} onChange={setWithValues} />\n ) : node.app === ROUTER_APP ? (\n <RouterEditor values={withValues} onChange={setWithValues} />\n ) : (\n <ParamsForm params={node.params} values={withValues} onChange={setWithValues} />\n )\n ) : configView === \"code\" ? (\n // Full step, read-only (D-3) — `stepToJson` is the ONE serializer,\n // shared with the two other code-view hosts.\n <JsonEditor\n value={codeText}\n onChange={() => {}}\n readOnly\n minHeight=\"240px\"\n height=\"100%\"\n aria-label=\"Node JSON\"\n copyable\n />\n ) : configView === \"params-code\" ? (\n <ParamCustomization values={withValues} onChange={setWithValues} />\n ) : (\n <NodeConfigForm\n config={draftConfig}\n onChange={setDraftConfig}\n // A trigger has no failure of its own to retry or police — same\n // reason its canvas card renders no error exit port.\n failureHandling={!isTriggerApp(node.app)}\n // A `@w6w/call`/`@w6w/control` step runs no retry loop of its\n // own (core rfcs/workflow.md \"Retries come first\"; D-3).\n retryControls={!isControlApp(node.app) && node.app !== CALL_APP}\n />\n ))}\n {tab === \"test\" &&\n testable &&\n (isTriggerApp(node.app) ? (\n <TriggerFillForm app={node.app} action={node.action} fields={withValues.fields} />\n ) : (\n <StepTestRun\n app={node.app}\n action={node.action}\n values={withValues}\n canRun={configComplete}\n state={testStartState}\n />\n ))}\n </div>\n\n {/* Footer — pinned to the modal bottom, outside the scroll area. */}\n <div className=\"w6w-modal-actions w6w-stepconfig-footer\">\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost\" onClick={onClose}>\n Cancel\n </button>\n {tab === \"configure\" && testable ? (\n <button\n type=\"button\"\n className=\"w6w-btn\"\n disabled={!configComplete}\n onClick={() => setTab(\"test\")}\n >\n Next →\n </button>\n ) : (\n <button\n type=\"button\"\n className=\"w6w-btn\"\n onClick={committedId !== null ? (onDone ?? onClose) : add}\n >\n {committedId !== null ? \"Done\" : \"Add node\"}\n </button>\n )}\n </div>\n </div>\n );\n}\n\n// ── Functions / Workflows tabs (F-2.0, D-12/D-15) ───────────────────────────\n//\n// Both tabs mint ONE step shape — an `@w6w/call` step — so there is no\n// per-family component pair: `CallableList` (the browse-and-pick stage,\n// styled after `AppPicker.tsx`) and `CallableStepConfig` (Configure/Test/Add,\n// mirroring `ControlStepConfig`'s progressive-commit shape) both take a single\n// `family: \"function\" | \"workflow\"` prop that only decides which endpoints to\n// call and what `with.targetKind` gets stamped.\n\n/**\n * Searchable list of a family's summaries — the picker's browse-and-pick\n * stage. Mirrors `AppPicker.tsx`'s shape (search box, sorted/filtered list,\n * loading/error/empty states); a Function/Workflow summary has no\n * icon/brandColor, so each row is text-only. `onSelect` hands the picked\n * target's id + display label up to `StepBuilderModal`, which collapses into\n * `CallableStepConfig` exactly as picking an app or an internal node does.\n */\nfunction CallableList({\n family,\n query,\n excludeIds,\n onSelect,\n}: {\n family: \"function\" | \"workflow\";\n query: string;\n /** See {@link StepBuilderModalProps.excludeCallableIds}. */\n excludeIds?: readonly string[];\n onSelect: (target: { id: string; label: string }) => void;\n}) {\n const api = useW6WApi();\n const [items, setItems] = useState<Array<FunctionSummary | WorkflowSummary> | null>(null);\n const [error, setError] = useState<string | null>(null);\n const noun = family === \"function\" ? \"Functions\" : \"Workflows\";\n\n useEffect(() => {\n let canceled = false;\n const p = family === \"function\" ? api.listFunctions() : api.listWorkflows();\n p.then((r) => !canceled && setItems(r)).catch(\n (e) => !canceled && setError((e as Error).message),\n );\n return () => {\n canceled = true;\n };\n }, [api, family]);\n\n // Single layout owner, mirroring `.w6w-apppicker-host`'s role for AppPicker\n // (I4: every render path — error/loading/empty/loaded — reports the same\n // host height, so the modal never resizes switching between them).\n const host = (body: ReactNode) => <div className=\"w6w-apppicker-host\">{body}</div>;\n\n if (error) return host(<div className=\"w6w-result w6w-error\">{error}</div>);\n if (items === null) {\n return host(<p className=\"w6w-muted w6w-small\">Loading {noun.toLowerCase()}…</p>);\n }\n if (items.length === 0) {\n return host(<p className=\"w6w-muted w6w-small\">No {noun.toLowerCase()} registered yet.</p>);\n }\n\n // The same label rule the home tab uses — one definition, so a Function is\n // named identically wherever it is listed.\n const label = callableLabel;\n const q = query.trim().toLowerCase();\n const sorted = withoutIds(items, excludeIds).sort(byLabel(label));\n const visible = q\n ? sorted.filter((it) => label(it).toLowerCase().includes(q) || it.id.toLowerCase().includes(q))\n : sorted;\n\n return host(\n <div className=\"w6w-stepbuilder-apps\">\n {visible.length === 0 ? (\n <p className=\"w6w-muted w6w-small\">\n No {noun.toLowerCase()} match “{query}”.\n </p>\n ) : (\n <div className=\"w6w-stepbuilder-list w6w-stepbuilder-scroll\">\n {/* The SAME row component the home tab renders — same glyph, same\n tinted background. This list used to draw its own bare row, so a\n Function looked like one thing here and another there. */}\n {visible.map((it) => (\n <CallableRow key={it.id} family={family} item={it} onSelect={onSelect} />\n ))}\n </div>\n )}\n </div>,\n );\n}\n\n/**\n * A Workflow target's declared inputs, for the picker's Configure stage — the\n * entry/trigger step's own `with.fields` (core rfcs/node-types.md, the manual\n * trigger's `fields` param — see `INTERNAL_NODES`). A webhook/schedule trigger\n * declares no such fields, so this returns `[]` and the Configure stage's\n * `ParamsForm` renders empty, which is a legitimate call (no inputs to send).\n */\nconst TRIGGER_FIELD_TYPES: readonly string[] = [\"string\", \"number\", \"boolean\", \"json\"];\n\nexport function triggerFieldsOf(wf: WorkflowDetail): ActionParam[] {\n const step = (wf.nodes ?? wf.steps ?? []).find((s) => isTriggerApp(s.uses.app));\n const raw = step?.with?.fields;\n if (!Array.isArray(raw)) return [];\n const out: ActionParam[] = [];\n for (const item of raw) {\n if (typeof item !== \"object\" || item === null) continue;\n const rec = item as Record<string, unknown>;\n const key = typeof rec.key === \"string\" ? rec.key : \"\";\n if (!key) continue;\n const type = typeof rec.type === \"string\" ? rec.type : \"string\";\n out.push({\n key,\n label: key,\n type: (TRIGGER_FIELD_TYPES.includes(type) ? type : \"string\") as ActionParam[\"type\"],\n default: rec.default,\n required: Boolean(rec.required),\n });\n }\n return out;\n}\n\n/**\n * Config → test → add flow for a picked Function/Workflow target (D-12,\n * D-15). Mints a single `@w6w/call` step — `family` only decides which\n * summary/detail/invoke endpoints are called and what `with.targetKind` is\n * stamped; it is never two near-copies. Mirrors `ControlStepConfig`'s\n * progressive-commit shape (mint via `onAdd` the instant the target is\n * picked, then `onDraftChange` on every later change) — unlike `AppStepConfig`\n * there is no Setup tab (the target picked in `CallableList` IS the identity)\n * and no `NodeConfigForm` here: a second onError/retry form is out of scope —\n * `NodeConfigForm` is reached once the `@w6w/call` step already lives on a\n * canvas, not at add-time.\n */\nexport function CallableStepConfig({\n family,\n targetId,\n targetLabel,\n onAdd,\n onClose,\n onDone,\n onDraftChange,\n}: {\n family: \"function\" | \"workflow\";\n targetId: string;\n targetLabel: string;\n // biome-ignore lint/suspicious/noConfusingVoidType: see StepBuilderModalProps.onAdd, forwarded as-is.\n onAdd: (s: BuiltStep) => string | undefined | void;\n onClose: () => void;\n /** Done, once the node is added — applies the add flow's name, then closes. Else `onClose`. */\n onDone?: () => void;\n /** See {@link StepBuilderModalProps.onDraftChange}. */\n onDraftChange?: (id: string, step: BuiltStep) => void;\n}) {\n const api = useW6WApi();\n const [fields, setFields] = useState<ActionParam[] | null>(null);\n const [fieldsError, setFieldsError] = useState<string | null>(null);\n const [inputs, setInputs] = useState<Record<string, unknown>>({});\n const [wait, setWait] = useState(true);\n const [tab, setTab] = useState<\"configure\" | \"test\">(\"configure\");\n // The id `onAdd` minted at commit time — see `ControlStepConfig`'s identical\n // field for the progressive-commit rationale.\n const [committedId, setCommittedId] = useState<string | null>(null);\n\n // Load the target's own declared inputs (acceptance 2b's seam pin: they\n // populate the `inputs` object below, never `input` singular).\n useEffect(() => {\n let canceled = false;\n setFields(null);\n setFieldsError(null);\n const p =\n family === \"function\"\n ? api.getFunction(targetId).then((d) => d.inputs)\n : api.getWorkflow(targetId).then(triggerFieldsOf);\n p.then((f) => !canceled && setFields(f)).catch(\n (e) => !canceled && setFieldsError((e as Error).message),\n );\n return () => {\n canceled = true;\n };\n }, [api, family, targetId]);\n\n const configComplete = fields !== null && requiredParamsFilled(fields, inputs);\n\n const buildStep = (): BuiltStep => ({\n uses: { app: CALL_APP, action: \"call\" },\n with: { targetKind: family, targetId, inputs, wait },\n });\n\n // Mint — a Function/Workflow target has identity the instant it's picked,\n // exactly like ControlStepConfig's mount-time mint. `CallableStepConfig` is\n // only ever mounted for one target: `StepBuilderModal` collapses into it via\n // `selectedCallable`, and \"← Back\" unmounts this subtree entirely rather\n // than re-parenting it onto a new `targetId`.\n // biome-ignore lint/correctness/useExhaustiveDependencies: mint fires once on mount only; buildStep/onAdd intentionally read fresh closure state without retriggering this effect.\n useEffect(() => {\n if (!onDraftChange) return;\n const id = onAdd(buildStep());\n if (id) setCommittedId(id);\n }, []);\n\n // Update — keep the already-committed node current on every later change.\n // biome-ignore lint/correctness/useExhaustiveDependencies: buildStep reads fresh closure state; only these fields should retrigger the update.\n useEffect(() => {\n if (!onDraftChange || committedId === null) return;\n onDraftChange(committedId, buildStep());\n }, [committedId, inputs, wait]);\n\n const add = () => onAdd(buildStep());\n\n return (\n <div className=\"w6w-stepconfig\">\n <div className=\"w6w-tabsbar\">\n <div className=\"w6w-subtabs\">\n <button\n type=\"button\"\n className={`w6w-subtab${tab === \"configure\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"configure\")}\n >\n Configure\n </button>\n <button\n type=\"button\"\n disabled={!configComplete}\n title={configComplete ? undefined : \"Fill the required fields first\"}\n className={`w6w-subtab${tab === \"test\" ? \" active\" : \"\"}`}\n onClick={() => configComplete && setTab(\"test\")}\n >\n Test\n </button>\n </div>\n </div>\n\n <div className=\"w6w-stepconfig-body\">\n {tab === \"configure\" ? (\n <div className=\"w6w-stack\">\n {fieldsError ? (\n <div className=\"w6w-result w6w-error\">{fieldsError}</div>\n ) : fields === null ? (\n <p className=\"w6w-muted w6w-small\">Loading {targetLabel}’s inputs…</p>\n ) : fields.length === 0 ? (\n <p className=\"w6w-muted w6w-small\">\n {targetLabel} declares no inputs — it can be called as-is.\n </p>\n ) : (\n <ParamsForm params={fields} values={inputs} onChange={setInputs} />\n )}\n <label className=\"w6w-field\">\n <span>\n <input type=\"checkbox\" checked={wait} onChange={(e) => setWait(e.target.checked)} />{\" \"}\n Wait for completion\n </span>\n <span className=\"w6w-hint\">\n On: block until the sub-run finishes and expose its output. Off: return a run handle\n and continue.\n </span>\n </label>\n </div>\n ) : (\n <CallableTestRun\n family={family}\n targetId={targetId}\n inputs={inputs}\n canRun={configComplete}\n />\n )}\n </div>\n\n {/* Footer — pinned to the modal bottom, outside the scroll area. */}\n <div className=\"w6w-modal-actions w6w-stepconfig-footer\">\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost\" onClick={onClose}>\n Cancel\n </button>\n {tab === \"configure\" ? (\n <button\n type=\"button\"\n className=\"w6w-btn\"\n disabled={!configComplete}\n onClick={() => setTab(\"test\")}\n >\n Next →\n </button>\n ) : (\n <button\n type=\"button\"\n className=\"w6w-btn\"\n onClick={committedId !== null ? (onDone ?? onClose) : add}\n >\n {committedId !== null ? \"Done\" : \"Add node\"}\n </button>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * Inline test run for a picked Function/Workflow — the picker's own Test stage\n * (D-11/D-15(c)): invokes the SAME `wait: true` path the saved step will take\n * at run time (`api.invokeFunction` / `api.runWorkflow`), never a client-side\n * poll. A Workflow's non-`terminal` result (the server's own `?wait=true`\n * timeout, a `202`) renders as \"still running\" with its `runId` — never a\n * silent no-op.\n */\nfunction CallableTestRun({\n family,\n targetId,\n inputs,\n canRun,\n}: {\n family: \"function\" | \"workflow\";\n targetId: string;\n inputs: Record<string, unknown>;\n canRun: boolean;\n}) {\n const api = useW6WApi();\n const [state, setState] = useState<\n | { status: \"running\" }\n | { status: \"done\"; output: unknown; runId?: string; terminal: boolean; error?: unknown }\n | { status: \"error\"; error: string }\n | null\n >(null);\n\n const run = async () => {\n if (!canRun || state?.status === \"running\") return;\n setState({ status: \"running\" });\n try {\n if (family === \"function\") {\n const output = await api.invokeFunction(targetId, inputs);\n setState({ status: \"done\", output, terminal: true });\n } else {\n const r = await api.runWorkflow(targetId, { input: inputs });\n setState({\n status: \"done\",\n output: r.output,\n runId: r.runId,\n terminal: r.terminal,\n error: r.error,\n });\n }\n } catch (e) {\n setState({ status: \"error\", error: (e as { message?: string }).message ?? String(e) });\n }\n };\n\n return (\n <div className=\"w6w-steptest\">\n <div className=\"w6w-steptest-bar\">\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n disabled={!canRun || state?.status === \"running\"}\n onClick={run}\n >\n {state?.status === \"running\" ? \"Running…\" : \"▶ Test run\"}\n </button>\n {!canRun && <span className=\"w6w-muted w6w-small\">Fill the required fields to test.</span>}\n </div>\n {state?.status === \"error\" && <div className=\"w6w-result w6w-error\">{state.error}</div>}\n {state?.status === \"done\" && !state.terminal && (\n <div className=\"w6w-testout\">\n <div className=\"w6w-testout-label\">Still running</div>\n <div className=\"w6w-result\">\n Run <code>{state.runId}</code> has not finished yet — check its status from the\n workflow's run history.\n </div>\n </div>\n )}\n {state?.status === \"done\" && state.terminal && state.error !== undefined && (\n <div className=\"w6w-testout\">\n <div className=\"w6w-testout-label\">Run failed</div>\n <pre\n className=\"w6w-result w6w-error\"\n style={{ whiteSpace: \"pre-wrap\", maxHeight: 220, overflow: \"auto\", margin: 0 }}\n >\n {JSON.stringify(state.error, null, 2)}\n </pre>\n </div>\n )}\n {state?.status === \"done\" && state.terminal && state.error === undefined && (\n <div className=\"w6w-testout\">\n <div className=\"w6w-testout-label\">Result</div>\n <ResultViewer value={state.output} maxHeight={220} />\n </div>\n )}\n </div>\n );\n}\n\n/**\n * The starting `with` for a freshly picked action: every param whose `default` is\n * an expression (e.g. `\"{{ const.account_id }}\"`). A plain default is only shown\n * as a placeholder value and never stored, so an expression default would render\n * as literal text and never reach the engine — seeding it makes it a live,\n * saved binding the user can still clear or replace.\n */\nexport function expressionDefaults(params: ActionParam[]): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const p of params) {\n if (holdsExpression(p.default)) out[p.key] = p.default;\n }\n return out;\n}\n\n/**\n * Whether every required param has a usable value — gates the inline \"Test run\".\n * A required array (e.g. a `vars` table) may be empty (see the Data node); other\n * required fields must be non-empty.\n *\n * A param hidden by its own `showIf` is skipped, matching `ParamsForm`'s render\n * visibility — this is what lets `required` and `showIf` combine at all (e.g.\n * SendGrid's `contentValue`, required only when NOT using a dynamic template):\n * without it, a conditionally-required field would either block the gate in the\n * branch where it's moot, or (if left non-required to dodge that) never be\n * caught here and only surface as a raw runtime error from the app's own\n * `execute()` — the app was previously written the second way for exactly this\n * reason; that workaround was fixed alongside this once the gate learned `showIf`.\n */\nexport function requiredParamsFilled(\n params: ActionParam[],\n values: Record<string, unknown>,\n): boolean {\n const effectiveValues = customizedParamValues(values);\n if (effectiveValues === null) return false;\n if (effectiveValues === undefined) return true; // Validate bound object fields on Test/run.\n // Built once from the FULL top-level tree (not per-section) so a section\n // child's `showIf` can reference a sibling outside its own section — same\n // reasoning as `ParamsForm`'s `effective`.\n const flat = flattenParams(params);\n const effective = (key: string) =>\n effectiveValues[key] !== undefined\n ? effectiveValues[key]\n : flat.find((p) => p.key === key)?.default;\n\n const check = (\n list: ActionParam[],\n vals: Record<string, unknown>,\n eff: (key: string) => unknown,\n ): boolean =>\n list.every((base) => {\n // `when` overlay: effective `required` (same helper as the core runtime).\n const p = effectiveParam(base, eff);\n // A `section` is a layout-only container whose children write flat at this\n // level — recurse so a required child (e.g. a grouped Sender Email) still\n // gates. The section param itself carries no value.\n if (p.type === \"section\") return check(p.children ?? [], vals, eff);\n // A `group` nests its children's values under its own key (or, for\n // `repeat: true`, one nested slice per row) — mirrors `GroupField`'s\n // rendering (`ParamsForm.tsx`) including its group-local-first `showIf`\n // resolution (D-3): a child's `showIf` checks the group's OWN children\n // first, falling back to `eff` (the enclosing scope) for any key the\n // group doesn't declare.\n if (p.type === \"group\") {\n const children = p.children ?? [];\n const flatChildren = flattenParams(children);\n const scoped =\n (groupVals: Record<string, unknown>) =>\n (key: string): unknown => {\n const local = flatChildren.find((c) => c.key === key);\n if (!local) return eff(key);\n return groupVals[key] !== undefined ? groupVals[key] : local.default;\n };\n if (p.repeat) {\n const rows = Array.isArray(vals[p.key]) ? (vals[p.key] as unknown[]) : [];\n // An empty list passes unless the group itself is required.\n if (rows.length === 0) return !p.required;\n return rows.every((row) => {\n const rowVals = (row ?? {}) as Record<string, unknown>;\n return check(children, rowVals, scoped(rowVals));\n });\n }\n const groupVals = (vals[p.key] ?? {}) as Record<string, unknown>;\n return check(children, groupVals, scoped(groupVals));\n }\n if (!p.required) return true;\n if (!isParamVisible(base, eff)) return true;\n const v = vals[p.key] ?? p.default;\n if (v === undefined || v === null) return false;\n if (typeof v === \"string\") return v.trim() !== \"\";\n return true;\n });\n return check(params, effectiveValues, effective);\n}\n\n/**\n * Whether adding this step is gated on a **passing** saved test — the per-app\n * `testRequired` save-gate. Defaults to **required**; an app/node surface may\n * opt out by carrying `testRequired: false`.\n *\n * The flag is read defensively off the app/node surface because the core app\n * manifest does not carry a `testRequired` field yet (a recorded follow-up); an\n * absent flag therefore means **required**, so today every app step must pass a\n * test before it can be added.\n */\nexport function isTestRequired(surface: unknown): boolean {\n const flag = (surface as { testRequired?: unknown } | null | undefined)?.testRequired;\n return typeof flag === \"boolean\" ? flag : true;\n}\n\ntype TestState =\n | { status: \"running\" }\n | { status: \"done\"; value: unknown; logs?: string[]; meta?: StepMeta }\n | { status: \"error\"; error: string; errorCode?: string; logs?: string[] };\n\n/**\n * The full account of one test run, for the Log view: the request the builder\n * sent to the w6w invoke route, the server's complete answer (success body or\n * error body), and the outbound vendor calls the server captured on the way.\n * `apiCalls` is empty when the action threw before making any HTTP call.\n */\ninterface TestRunLog {\n startedAt: string;\n durationMs: number;\n request: { method: \"POST\"; path: string; body: Record<string, unknown> };\n response: { ok: boolean; status?: number; body: unknown };\n apiCalls: ApiCallRecord[];\n}\n\n/** The parsed error body an invoke failure carries — ui's `ApiError` on `body`, `@w6w/sdk`'s on `raw`. */\nfunction errorBodyOf(e: unknown): unknown {\n const err = e as { body?: unknown; raw?: unknown; message?: string; code?: string } | null;\n return err?.body ?? err?.raw ?? { error: err?.code, message: err?.message ?? String(e) };\n}\n\nfunction apiCallsIn(body: unknown): ApiCallRecord[] {\n const calls = (body as { apiCalls?: unknown } | null)?.apiCalls;\n return Array.isArray(calls) ? (calls as ApiCallRecord[]) : [];\n}\n\n/** Modal body for {@link TestRunLog} — the request, the response, then each vendor call. */\nfunction TestRunLogModal({ log, onClose }: { log: TestRunLog; onClose: () => void }) {\n return (\n <Modal title=\"Test run log\" subtitle={log.startedAt} size=\"wide\" onClose={onClose}>\n <div className=\"w6w-modal-body w6w-stack\" style={{ gap: 12 }}>\n <div className=\"w6w-testout\">\n <div className=\"w6w-testout-label\">\n Request to w6w · {log.request.method} {log.request.path}\n </div>\n <ResultViewer value={log.request.body} maxHeight={320} />\n </div>\n <div className=\"w6w-testout\">\n <div className=\"w6w-testout-label\">\n Response from w6w ·{\" \"}\n {log.response.ok\n ? \"ok\"\n : `failed${log.response.status ? ` (HTTP ${log.response.status})` : \"\"}`}{\" \"}\n · {log.durationMs}ms\n </div>\n <ResultViewer value={log.response.body} maxHeight={320} />\n </div>\n <div className=\"w6w-testout\">\n <div className=\"w6w-testout-label\">Outbound API calls ({log.apiCalls.length})</div>\n {log.apiCalls.length > 0 ? (\n <ApiCallsPanel calls={log.apiCalls} title={false} defaultOpen />\n ) : (\n <div className=\"w6w-muted w6w-small\">\n No HTTP request reached the vendor API — the action\n {log.response.ok ? \" made no outbound call\" : \" failed before sending one\"}.\n </div>\n )}\n </div>\n </div>\n </Modal>\n );\n}\n\n/**\n * Where a test run should be persisted. When present, `StepTestRun` saves the\n * fixture (`saveStepTest`) and records the run's outcome (`recordStepTestRun`)\n * against the given workflow step after each invoke. `input` is the resolved\n * incoming state captured alongside the params (`values` → `with`). Absent in\n * the add-step builder (the step isn't in a workflow yet).\n */\nexport interface StepTestPersist {\n workflowId: string;\n stepId: string;\n input: Record<string, unknown>;\n}\n\n/** Imperative handle so a host (e.g. the step modal footer) can trigger the run. */\nexport interface StepTestRunHandle {\n run: () => void;\n}\n\n/**\n * Inline \"Test run\" — invokes the action/node with the current params (and, for\n * app actions, the chosen connection) so the user can try a step from inside the\n * builder before adding it. Pressable only once required fields are filled.\n *\n * When `persist` is supplied (the node editor's Test tab), each run also saves\n * the fixture and records the outcome server-side, so a step test becomes saved\n * and re-runnable. `hideRunButton` suppresses the inline button when the host\n * drives the run from elsewhere (the modal footer) via the imperative handle.\n */\nexport const StepTestRun = forwardRef<\n StepTestRunHandle,\n {\n app: string;\n action: string;\n connectionId?: string;\n values: Record<string, unknown>;\n canRun: boolean;\n hideRunButton?: boolean;\n persist?: StepTestPersist;\n /**\n * The run's start state — what the upstream steps last produced — so a\n * `values` entry written as `{{ steps.<id>.output.<field> }}` resolves\n * server-side instead of coming back empty. The host builds it (both the\n * node editor's Test tab and, since T1.1.1, the add-step builder's Test\n * tab seed it from the upstream fixtures, via `useSeedSources` +\n * `startStateFromSeeds`); absent only when the host itself has no upstream\n * steps to offer — the Functions/Endpoints pickers, which have no graph.\n */\n state?: StepStartState;\n /** Notified when the run starts/finishes so a host button can reflect it. */\n onBusyChange?: (busy: boolean) => void;\n /**\n * Notified with the outcome of each finished run (`true` = passed). Lets a\n * host satisfy the `testRequired` save-gate from an in-session test run.\n */\n onResult?: (passed: boolean) => void;\n }\n>(function StepTestRun(\n {\n app,\n action,\n connectionId,\n values,\n canRun,\n hideRunButton,\n persist,\n state: startState,\n onBusyChange,\n onResult,\n },\n ref,\n) {\n const api = useW6WApi();\n // Resolve document expressions against the workflow's selected project (the\n // editor provides it; undefined outside the editor → server default project).\n const project = useWorkflowProject();\n // Named on the invoke so `{{ nodes.<id>.config.* }}` resolves as on a run.\n const workflowId = useWorkflowId();\n const [state, setState] = useState<TestState | null>(null);\n const [log, setLog] = useState<TestRunLog | null>(null);\n const [logOpen, setLogOpen] = useState(false);\n // Set once a session run starts, so a late read-back never overwrites it.\n const ranRef = useRef(false);\n // The stored run's time while its result is on show; cleared by a new run.\n const [restoredAt, setRestoredAt] = useState<string | null>(null);\n\n // Show the step's newest stored run (success or failure) on (re)open. Read-only:\n // never saves, records, invokes or notifies the host.\n const persistWorkflowId = persist?.workflowId;\n const persistStepId = persist?.stepId;\n // The node's static metadata (`nodes.<id>.meta.*`): shown before any run, and under a run's own.\n const nodeMeta = useExpressionOptions().nodeMeta;\n const staticMeta = persistStepId ? nodeMeta?.[persistStepId] : undefined;\n useEffect(() => {\n if (!persistWorkflowId || !persistStepId) return;\n let canceled = false;\n api\n .listStepTests(persistWorkflowId, persistStepId)\n .then((rows) => {\n let row: (typeof rows)[number] | undefined;\n for (const r of rows) {\n if (!r.lastRunAt || !r.lastRunStatus) continue;\n if (!row || Date.parse(r.lastRunAt) > Date.parse(row.lastRunAt as string)) row = r;\n }\n if (!row || !row.lastRunAt || canceled || ranRef.current) return;\n if (row.lastRunStatus === \"succeeded\") {\n setState({\n status: \"done\",\n value: row.lastRunOutput,\n ...(row.lastRunMeta ? { meta: row.lastRunMeta } : {}),\n });\n } else {\n setState({\n status: \"error\",\n error:\n typeof row.lastRunError === \"string\"\n ? row.lastRunError\n : row.lastRunError == null\n ? \"Test failed\"\n : JSON.stringify(row.lastRunError),\n });\n }\n setRestoredAt(row.lastRunAt);\n })\n .catch(() => {});\n return () => {\n canceled = true;\n };\n }, [api, persistWorkflowId, persistStepId]);\n\n const run = async () => {\n if (!canRun || state?.status === \"running\") return;\n ranRef.current = true;\n setRestoredAt(null);\n setState({ status: \"running\" });\n onBusyChange?.(true);\n let outcome: Exclude<TestState, { status: \"running\" }>;\n const startedAt = new Date();\n const request: TestRunLog[\"request\"] = {\n method: \"POST\",\n path: `/apps/${encodeURIComponent(app)}/actions/${encodeURIComponent(action)}/invoke`,\n // Mirrors the body `invokeAction` puts on the wire.\n body: {\n params: values,\n ...(connectionId ? { connectionId } : {}),\n ...(project ? { project } : {}),\n ...(startState ? { state: startState } : {}),\n ...(workflowId ? { workflowId } : {}),\n },\n };\n const finishLog = (response: TestRunLog[\"response\"]) =>\n setLog({\n startedAt: startedAt.toLocaleString(),\n durationMs: Date.now() - startedAt.getTime(),\n request,\n response,\n apiCalls: apiCallsIn(response.body),\n });\n try {\n const result = await api.invokeAction(app, action, values, {\n ...(connectionId ? { connectionId } : {}),\n project,\n // Omitted when the host has no upstream state to offer, so the request\n // is unchanged for every caller that never had one.\n ...(startState ? { state: startState } : {}),\n ...(workflowId ? { workflowId } : {}),\n });\n finishLog({ ok: true, body: result });\n outcome = {\n status: \"done\",\n value: result.value,\n logs: (result as { logs?: string[] }).logs,\n ...(result.meta ? { meta: result.meta } : {}),\n };\n } catch (e) {\n const err = e as { message?: string; code?: string; logs?: string[]; status?: number };\n finishLog({\n ok: false,\n ...(typeof err.status === \"number\" ? { status: err.status } : {}),\n body: errorBodyOf(e),\n });\n outcome = {\n status: \"error\",\n error: err.message ?? String(e),\n errorCode: err.code,\n logs: err.logs,\n };\n }\n setState(outcome);\n onResult?.(outcome.status === \"done\");\n // Persist the fixture + record the outcome when the host targets a workflow\n // step. Best-effort: a failed save must never mask the run's own result.\n if (persist) {\n // The incoming state is remembered too (`node_test_inputs`), so the Test\n // tab and the Run node modal reopen prefilled with it.\n api\n .saveTestInput?.(persist.workflowId, persist.stepId, rememberableInput(persist.input))\n .catch((err) => console.error(\"test input save failed\", err));\n try {\n const saved = await api.saveStepTest(persist.workflowId, persist.stepId, {\n input: persist.input,\n with: values,\n });\n await api.recordStepTestRun(persist.workflowId, persist.stepId, {\n stepTestId: saved.id,\n status: outcome.status === \"done\" ? \"succeeded\" : \"failed\",\n input: persist.input,\n output: outcome.status === \"done\" ? outcome.value : undefined,\n error: outcome.status === \"error\" ? outcome.error : undefined,\n ...(outcome.status === \"done\" && outcome.meta ? { meta: outcome.meta } : {}),\n });\n } catch (err) {\n console.error(\"step test persist failed\", err);\n }\n }\n onBusyChange?.(false);\n };\n\n useImperativeHandle(ref, () => ({ run }));\n\n const logs = state && state.status !== \"running\" ? state.logs : undefined;\n\n return (\n <div className=\"w6w-steptest\">\n {(!hideRunButton || log) && (\n <div className=\"w6w-steptest-bar\">\n {!hideRunButton && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n disabled={!canRun || state?.status === \"running\"}\n onClick={run}\n >\n {state?.status === \"running\" ? \"Running…\" : \"▶ Test run\"}\n </button>\n )}\n {log && state?.status !== \"running\" && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n onClick={() => setLogOpen(true)}\n title=\"The full request and response of the last test run\"\n >\n Log{log.apiCalls.length > 0 ? ` (${log.apiCalls.length})` : \"\"}\n </button>\n )}\n {!hideRunButton && !canRun && (\n <span className=\"w6w-muted w6w-small\">Fill the required fields to test.</span>\n )}\n </div>\n )}\n {logOpen && log && <TestRunLogModal log={log} onClose={() => setLogOpen(false)} />}\n {restoredAt && (state?.status === \"done\" || state?.status === \"error\") && (\n <div className=\"w6w-muted w6w-small w6w-testout-restored\">\n Last run · {new Date(restoredAt).toLocaleString()}\n </div>\n )}\n {state?.status === \"error\" && (\n <div className=\"w6w-result w6w-error\">\n {state.errorCode && (\n <div className=\"w6w-small\" style={{ opacity: 0.75, marginBottom: 4 }}>\n <code>{state.errorCode}</code>\n </div>\n )}\n {state.error}\n </div>\n )}\n {state?.status === \"done\" && (\n <div className=\"w6w-testout\">\n <div className=\"w6w-testout-label\">Result (return value)</div>\n <ResultViewer value={state.value} maxHeight={220} />\n {(state.meta || staticMeta) && (\n <>\n <div className=\"w6w-testout-label\">Metadata</div>\n <ResultViewer value={{ ...staticMeta, ...state.meta }} maxHeight={220} />\n </>\n )}\n </div>\n )}\n {state?.status !== \"done\" && state?.status !== \"running\" && staticMeta && (\n <div className=\"w6w-testout\" data-testid=\"steptest-static-meta\">\n <div className=\"w6w-testout-label\">Metadata</div>\n <ResultViewer value={staticMeta} maxHeight={220} />\n </div>\n )}\n {logs && logs.length > 0 && (\n <div className=\"w6w-testout\">\n <div className=\"w6w-testout-label\">Console output</div>\n <pre\n className=\"w6w-result w6w-testout-console\"\n style={{ whiteSpace: \"pre-wrap\", maxHeight: 160, overflow: \"auto\", margin: 0 }}\n >\n {logs.join(\"\\n\")}\n </pre>\n </div>\n )}\n </div>\n );\n});\n\n// ── Connected apps tab (default) ─────────────────────────────────────────────\n\n/**\n * What the home tab has to show. Lifted out of the tab's own component because\n * the MODAL needs the answer too: a home tab with nothing in it is not\n * rendered at all (no connected apps, no Functions, no Workflows ⇒ no tab),\n * and that decision belongs to whoever draws the sidebar.\n *\n * `state` is deliberately four-valued. \"Empty\" and \"not loaded yet\" must not\n * collapse into one: hiding the tab while its fetches are in flight would make\n * it appear a beat later, moving the sidebar under the cursor.\n */\ninterface ReadyToUse {\n state: \"loading\" | \"error\" | \"empty\" | \"ready\";\n error?: string;\n apps: AppSummary[];\n /** Full connected-id scope for server search, including apps not loaded yet. */\n appIds?: string[];\n fns: FunctionSummary[];\n wfs: WorkflowSummary[];\n /** More connected-app ids remain unresolved — draw an explicit \"load more\" affordance. */\n moreApps: boolean;\n /** Resolve the next bounded batch of connected-app ids. No-op off the bounded path or with nothing left. */\n loadMoreApps: () => void;\n}\n\n/** Bounded batch size for {@link W6WApi.listAppsByIds} resolution — a handful\n * per request, never the whole connected-id list at once (A3). */\nconst READY_TO_USE_ID_BATCH = 12;\n\n/** A stable, always-empty `Set` — the first batch's \"nothing requested yet\". */\nconst EMPTY_ID_SET: ReadonlySet<string> = new Set();\n\n/**\n * Clamp the poll-interval text to an integer number of minutes ≥ `min`. Blank,\n * non-numeric or below-minimum input yields `min`; fractions round to nearest.\n */\nexport function clampMinutes(raw: string, min: number): number {\n const n = Number(raw.trim());\n if (raw.trim() === \"\" || !Number.isFinite(n) || n < min) return min;\n return Math.max(min, Math.round(n));\n}\n\n/**\n * \"Ready to use\"'s data: distinct connected app ids (A3) resolved in bounded\n * batches via the optional `listAppsByIds`, plus Functions/Workflows.\n *\n * `/connections` already includes a synthetic zero-credential row per\n * zero-credential-flagged app the caller's tenant can use with no connection\n * step (`admin/connections.ts`) — so the DISTINCT connection app ids alone are\n * the full \"ready\" membership; unlike the old full-catalog scan, no separate\n * `AppSummary.zeroCredential` check is needed on this path.\n *\n * `listAppsByIds` is optional (older/imported providers implement only\n * `listApps`): capability is `typeof api.listAppsByIds === \"function\"`\n * ALONE — never inferred from a runtime result. A first batch that resolves\n * to an empty array is a LEGITIMATE answer from a fully-working\n * `listAppsByIds` (every connected app was since deleted from the catalog,\n * an ordinary case) and must be shown as such, not treated as evidence the\n * optional method \"isn't really implemented\" (T2.1.1 ROUND 2 — that\n * conflation previously made a correct, well-typed empty result permanently\n * fall back to the unbounded `listApps()` for the rest of the component's\n * lifetime, the exact \"one request per entire catalog at open\" A3 forbids).\n * When the method is genuinely absent, this hook falls back to the ORIGINAL\n * full-catalog scan (`listApps()` + the zero-credential check), unchanged —\n * and with `listApps` itself also absent (now optional, like this member),\n * settles on the empty catalog instead of calling an undefined function.\n *\n * On the bounded path each connection's inline `app` meta is read FIRST: an\n * app id with a non-null `app` on any of its rows is built as\n * `{ ...c.app, id: c.appId }` and seeded as resolved + requested, so\n * `listAppsByIds` is called only for ids whose rows all lack it (`app` absent\n * or `null`) — and not at all when none do. Such inline apps have no\n * `version`/`categories`: the selected-app header drops its ` · v<version>`\n * suffix and `appsFilter` sees only `id` and the meta keys.\n *\n * Exported for tests only (not re-exported from the package index).\n */\nexport function useReadyToUse(\n callables: readonly (\"function\" | \"workflow\")[],\n appsFilter?: (app: AppSummary) => boolean,\n excludeIds?: readonly string[],\n appsIds?: readonly string[],\n /** `resolveInline`: ignore a connection row's inline `app` meta and resolve every id through\n * `listAppsByIds` — for a caller that needs fields the inline meta lacks (`triggerCount`). */\n opts?: { resolveInline?: boolean },\n): ReadyToUse {\n // When a provider-id allow-list is set, apps outside it are never offered.\n const idSet = appsIds && appsIds.length > 0 ? new Set(appsIds) : null;\n const allowed = (a: AppSummary) => (idSet ? idSet.has(a.id) : true) && (appsFilter?.(a) ?? true);\n const api = useW6WApi();\n const [connectedIds, setConnectedIds] = useState<string[] | null>(null);\n const [allApps, setAllApps] = useState<AppSummary[] | null>(null);\n const [fnsRaw, setFns] = useState<FunctionSummary[] | null>(null);\n const [wfsRaw, setWfs] = useState<WorkflowSummary[] | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [resolved, setResolved] = useState<Map<string, AppSummary>>(() => new Map());\n const [requestedIds, setRequestedIds] = useState<Set<string>>(() => new Set());\n // Ids sent to `listAppsByIds` and not yet resolved. Separate from\n // `requestedIds` (whose emptiness is the first-batch loading gate). The ref\n // mirrors it so a same-tick second call is guarded too.\n const [inFlightIds, setInFlightIds] = useState<ReadonlySet<string>>(EMPTY_ID_SET);\n const inFlightRef = useRef<ReadonlySet<string>>(EMPTY_ID_SET);\n const setInFlight = useCallback((next: ReadonlySet<string>) => {\n inFlightRef.current = next;\n setInFlightIds(next);\n }, []);\n // App ids whose connection rows carried inline `app` meta — never looked up.\n const inlineIdsRef = useRef<ReadonlySet<string>>(EMPTY_ID_SET);\n\n const wantFns = callables.includes(\"function\");\n const wantWfs = callables.includes(\"workflow\");\n const bounded = typeof api.listAppsByIds === \"function\";\n\n useEffect(() => {\n let canceled = false;\n const fail = (e: unknown) => !canceled && setError((e as Error).message);\n api\n .listConnections()\n .then((conns) => {\n if (canceled) return;\n const ids: string[] = [];\n const seen = new Set<string>();\n const inline = new Map<string, AppSummary>();\n for (const c of conns) {\n if (isInternalApp(c.appId)) continue;\n if (bounded && !opts?.resolveInline && c.app && !inline.has(c.appId)) {\n inline.set(c.appId, { ...c.app, id: c.appId });\n }\n if (seen.has(c.appId)) continue;\n seen.add(c.appId);\n ids.push(c.appId);\n }\n if (inline.size > 0) {\n inlineIdsRef.current = new Set(inline.keys());\n setResolved((prev) => new Map([...prev, ...inline]));\n setRequestedIds((prev) => new Set([...prev, ...inline.keys()]));\n }\n setConnectedIds(ids);\n })\n .catch(fail);\n // A family this picker does not offer is never fetched, and resolves to an\n // empty list so the readiness check below still completes.\n if (wantFns) {\n api\n .listFunctions()\n .then((r) => !canceled && setFns(r))\n .catch(fail);\n } else setFns([]);\n if (wantWfs) {\n api\n .listWorkflows()\n .then((r) => !canceled && setWfs(r))\n .catch(fail);\n } else setWfs([]);\n return () => {\n canceled = true;\n };\n }, [api, bounded, wantFns, wantWfs, opts?.resolveInline]);\n\n // Legacy full-catalog fallback — fetched only when there is no bounded id\n // lookup to use instead, never alongside it.\n useEffect(() => {\n if (bounded) return;\n const listApps = api.listApps;\n // Neither `listAppsByIds` (checked above, via `bounded`) nor `listApps`:\n // settle on the empty catalog below rather than calling an undefined\n // function — the \"ready to use\" tab then shows just Functions/Workflows\n // (or its own empty state), never a throw or a stuck loading state.\n if (typeof listApps !== \"function\") {\n setAllApps([]);\n return;\n }\n let canceled = false;\n listApps()\n .then((r) => !canceled && setAllApps(r))\n .catch((e) => !canceled && setError((e as Error).message));\n return () => {\n canceled = true;\n };\n }, [api, bounded]);\n\n // Re-armed on every mount: StrictMode mounts, unmounts and remounts once, and\n // a ref left `false` by that simulated unmount drops every batch's answer.\n const mountedRef = useRef(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const resolveBatch = useCallback(\n (batch: string[]) => {\n const listAppsByIds = api.listAppsByIds;\n if (!listAppsByIds || batch.length === 0 || inFlightRef.current.size > 0) return;\n setInFlight(new Set(batch));\n listAppsByIds(batch)\n .then((apps) => {\n if (!mountedRef.current) return;\n setInFlight(EMPTY_ID_SET);\n // An empty result (every requested id was a 404) is a legitimate\n // answer, not evidence the optional method \"isn't really\n // implemented\" — see this hook's own doc-comment above. It is\n // recorded as resolved (nothing to show for this batch) exactly\n // like a batch with some, but not all, ids found.\n setResolved((prev) => {\n const next = new Map(prev);\n for (const a of apps) next.set(a.id, a);\n return next;\n });\n setRequestedIds((prev) => new Set([...prev, ...batch]));\n })\n .catch((e) => mountedRef.current && setError((e as Error).message));\n },\n [api, setInFlight],\n );\n\n // Exactly ONE automatic batch, the moment connected ids first arrive —\n // every subsequent batch is explicit, via `loadMoreApps` (A3: \"never one\n // request per entire catalog at open\"). Guarded by a ref (not `requestedIds`\n // itself) so a re-render before the first batch resolves can never start a\n // second, duplicate first-batch request.\n const firstBatchStartedRef = useRef(false);\n useEffect(() => {\n if (!bounded || connectedIds === null || firstBatchStartedRef.current) return;\n const batch = nextIdBatch(connectedIds, inlineIdsRef.current, READY_TO_USE_ID_BATCH);\n if (batch.length === 0) return;\n firstBatchStartedRef.current = true;\n resolveBatch(batch);\n }, [bounded, connectedIds, resolveBatch]);\n\n const loadMoreApps = () => {\n if (!bounded || connectedIds === null) return;\n if (inFlightRef.current.size > 0) return;\n const exclude = new Set([...requestedIds, ...inFlightRef.current]);\n resolveBatch(nextIdBatch(connectedIds, exclude, READY_TO_USE_ID_BATCH));\n };\n\n if (error)\n return { state: \"error\", error, apps: [], fns: [], wfs: [], moreApps: false, loadMoreApps };\n if (fnsRaw === null || wfsRaw === null) {\n return { state: \"loading\", apps: [], fns: [], wfs: [], moreApps: false, loadMoreApps };\n }\n // Excluded at the read, not in the fetch effect: the exclusion list's identity\n // is the caller's, and must never re-trigger the network calls.\n const fns = withoutIds(fnsRaw, excludeIds);\n const wfs = withoutIds(wfsRaw, excludeIds);\n\n if (bounded) {\n if (connectedIds === null) {\n return { state: \"loading\", apps: [], fns, wfs, moreApps: false, loadMoreApps };\n }\n if (connectedIds.length > 0 && requestedIds.size === 0) {\n return { state: \"loading\", apps: [], fns, wfs, moreApps: false, loadMoreApps };\n }\n const apps = mergeResolvedApps(connectedIds, resolved).filter(allowed);\n const moreApps =\n inFlightIds.size === 0 &&\n nextIdBatch(connectedIds, new Set([...requestedIds, ...inFlightIds]), 1).length > 0;\n const empty = apps.length === 0 && fns.length === 0 && wfs.length === 0 && !moreApps;\n return {\n state: empty ? \"empty\" : \"ready\",\n apps,\n appIds: connectedIds.filter((id) => !idSet || idSet.has(id)),\n fns,\n wfs,\n moreApps,\n loadMoreApps,\n };\n }\n\n if (allApps === null) {\n return { state: \"loading\", apps: [], fns, wfs, moreApps: false, loadMoreApps };\n }\n // Reserved `@w6w/*` pseudo-apps are never connectable — they are added from\n // the Controls/Utilities tabs, exactly as `AppPicker` excludes them.\n //\n // \"Ready to use\" means EITHER an actual Connection exists OR the app needs\n // none at all — a zero-credential-flagged app's whole point is that its\n // tenant's users get the declared tenantAuth/jit path with no connection\n // step, so requiring membership in `connectedIds` alone hid it from the one\n // tab it is MOST meant to appear in. This full-catalog fallback path is the\n // ONLY place that check still needs `AppSummary.zeroCredential` directly —\n // the bounded path above gets zero-credential membership from `/connections`'\n // own synthetic rows instead (see this function's doc comment).\n const connectedSet = new Set(connectedIds ?? []);\n const apps = allApps.filter(\n (a) =>\n !isInternalApp(a.id) && allowed(a) && (connectedSet.has(a.id) || a.zeroCredential === true),\n );\n const empty = apps.length === 0 && fns.length === 0 && wfs.length === 0;\n return { state: empty ? \"empty\" : \"ready\", apps, fns, wfs, moreApps: false, loadMoreApps };\n}\n\n/** A copy of `items` without any entry whose `id` equals one of `ids` (id\n * equality only — never name or position). No `ids` ⇒ an unchanged copy. */\nexport function withoutIds<T extends { id: string }>(\n items: readonly T[],\n ids?: readonly string[],\n): T[] {\n return ids && ids.length > 0 ? items.filter((it) => !ids.includes(it.id)) : [...items];\n}\n\n/** Sort helper — by display label, case-insensitively. */\nfunction byLabel<T>(label: (t: T) => string) {\n return (a: T, b: T) => label(a).localeCompare(label(b), undefined, { sensitivity: \"base\" });\n}\n\n/** A Function/Workflow summary's display name, falling back to name then id. */\nfunction callableLabel(it: FunctionSummary | WorkflowSummary): string {\n const dn = it.displayName;\n if (dn?.trim()) return dn;\n return \"name\" in it ? it.name : it.id;\n}\n\n/**\n * One Function/Workflow row. Shared by the home tab and by the Workflows and\n * Functions tabs, so a Function looks like a Function wherever it is offered —\n * same glyph, same tinted background. Two surfaces drawing the same thing\n * differently is how a list stops being learnable.\n */\nfunction CallableRow({\n family,\n item,\n onSelect,\n}: {\n family: \"function\" | \"workflow\";\n item: FunctionSummary | WorkflowSummary;\n onSelect: (t: { id: string; label: string }) => void;\n}) {\n const label = callableLabel(item);\n return (\n <button\n type=\"button\"\n className=\"w6w-stepbuilder-item w6w-stepbuilder-item--callable\"\n data-kind={family}\n onClick={() => onSelect({ id: item.id, label })}\n >\n <InternalIcon icon={CALLABLE_GLYPH[family]} size={24} />\n <span className=\"w6w-stepbuilder-item-main\">\n <strong>{label}</strong>\n <code className=\"w6w-muted w6w-small\">{item.id}</code>\n </span>\n </button>\n );\n}\n\n/**\n * The picker's home tab — **everything already usable**, in the two-column\n * layout the intake draws:\n *\n * Connnected apps | functions\n * | workflows\n *\n * Connected apps down the left; Functions above Workflows down the right, with\n * a rule between the halves. That sketch is a LAYOUT, not a tab list — it was\n * built as three sidebar tabs first, and that was wrong twice over: the three\n * kinds belong on one screen, side by side, so the author sees everything they\n * can reach without navigating. The browse-everything tabs (Apps, AI,\n * Workflows, Functions) still sit below this one for the full catalogues.\n *\n * \"Ready to use\" rather than \"Connected apps\": what unites the columns is that\n * none of them needs setting up before it can be picked. The Apps tab, by\n * contrast, is the catalogue, where picking may mean connecting first.\n *\n * **Every empty column disappears** — heading and all. A \"Workflows\" heading\n * over nothing claims you have workflows ready to use, which is exactly what\n * an empty list is telling you is false. No connected apps ⇒ no left column,\n * and the grid collapses to one. Nothing at all ⇒ the modal does not render\n * the tab (see {@link useReadyToUse}), so this component never sees that case.\n *\n * The modal owns one search field shared by every tab. Filtering this list\n * never changes whether the Ready to use tab itself is available.\n */\n/** One home-tab column: a heading and its rows. Rendered only when it HAS rows. The\n * Triggers tab draws the same `.w6w-readytouse` markup but keeps an empty column. */\nfunction readyToUseColumn(title: string, rows: ReactNode[]) {\n return rows.length === 0 ? null : (\n <section key={title} className=\"w6w-readytouse-col\">\n <h4 className=\"w6w-readytouse-heading\">{title}</h4>\n <div className=\"w6w-stepbuilder-list w6w-stepbuilder-scroll\">{rows}</div>\n </section>\n );\n}\n\n/** One app row (icon + name + id) — shared by the home tab and the Triggers tab. */\nfunction AppRow({\n app: a,\n theme,\n onSelect,\n}: {\n app: AppSummary;\n theme?: ThemeMode;\n onSelect: (app: AppSummary) => void;\n}) {\n return (\n <button\n type=\"button\"\n className=\"w6w-stepbuilder-item\"\n data-kind=\"app\"\n onClick={() => onSelect(a)}\n >\n <AppIcon\n src={a.iconSvg}\n srcDark={a.iconSvgDark}\n brandColor={a.brandColor}\n name={a.displayName}\n theme={theme}\n size={24}\n />\n <span className=\"w6w-stepbuilder-item-main\">\n <strong>{a.displayName}</strong>\n <code className=\"w6w-muted w6w-small\">{a.id}</code>\n </span>\n </button>\n );\n}\n\nfunction ReadyToUseFlow({\n data,\n query,\n appsFilter,\n onSelectApp,\n onSelectCallable,\n theme,\n}: {\n data: ReadyToUse;\n query: string;\n appsFilter?: (app: AppSummary) => boolean;\n onSelectApp: (app: AppSummary) => void;\n onSelectCallable: (t: { family: \"function\" | \"workflow\"; id: string; label: string }) => void;\n theme?: ThemeMode;\n}) {\n const api = useW6WApi();\n // Single layout owner for every exit, so the panel never resizes between\n // error/loading and the loaded columns — mirrors `.w6w-apppicker-host`'s role\n // in `AppPicker` and `CallableList`.\n const host = (body: ReactNode) => <div className=\"w6w-apppicker-host\">{body}</div>;\n\n if (data.state === \"error\") {\n return host(<div className=\"w6w-result w6w-error\">{data.error}</div>);\n }\n if (data.state === \"loading\") return host(<p className=\"w6w-muted w6w-small\">Loading…</p>);\n\n const apps = data.apps\n .filter((a) => matchesPickerQuery(query, a.displayName, a.id))\n .sort(byLabel((a: AppSummary) => a.displayName));\n const fns = data.fns\n .filter((f) => matchesPickerQuery(query, callableLabel(f), f.id))\n .sort(byLabel(callableLabel));\n const wfs = data.wfs\n .filter((w) => matchesPickerQuery(query, callableLabel(w), w.id))\n .sort(byLabel(callableLabel));\n\n const column = readyToUseColumn;\n\n const leftRows: ReactNode[] = apps.map((a) => (\n <AppRow key={a.id} app={a} theme={theme} onSelect={onSelectApp} />\n ));\n // A3: further connected-app ids remain unresolved — an explicit affordance,\n // never an automatic drain of the rest of the connected-id list.\n if (data.moreApps) {\n leftRows.push(\n <button\n key=\"__load_more_apps\"\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n onClick={data.loadMoreApps}\n >\n Load more\n </button>,\n );\n }\n const left =\n query.trim() && data.appIds?.length && typeof api.listAppsPage === \"function\" ? (\n <section className=\"w6w-readytouse-col\">\n <h4 className=\"w6w-readytouse-heading\">Connected apps</h4>\n <AppPicker\n search={false}\n searchValue={query}\n ids={data.appIds}\n filter={appsFilter}\n onSelectApp={onSelectApp}\n theme={theme}\n />\n </section>\n ) : (\n column(\"Connected apps\", leftRows)\n );\n\n // Functions above Workflows — the order the intake draws them in.\n const right = [\n column(\n \"Functions\",\n fns.map((f) => (\n <CallableRow\n key={f.id}\n family=\"function\"\n item={f}\n onSelect={(t) => onSelectCallable({ family: \"function\", ...t })}\n />\n )),\n ),\n column(\n \"Workflows\",\n wfs.map((w) => (\n <CallableRow\n key={w.id}\n family=\"workflow\"\n item={w}\n onSelect={(t) => onSelectCallable({ family: \"workflow\", ...t })}\n />\n )),\n ),\n ].filter(Boolean);\n\n // `data-cols` drives the grid template, so a missing half collapses rather\n // than leaving an empty tract — and the divider only exists when there are\n // in fact two halves to divide.\n const cols = (left ? 1 : 0) + (right.length > 0 ? 1 : 0);\n if (!cols)\n return host(<p className=\"w6w-muted w6w-small\">Nothing ready to use matches “{query}”.</p>);\n return host(\n <div className=\"w6w-readytouse\" data-cols={cols}>\n {left}\n {right.length > 0 && <div className=\"w6w-readytouse-stack\">{right}</div>}\n </div>,\n );\n}\n\n/** An app's triggers as action-shaped defs ({ key, title, description, params }), so\n * the action pickers and param forms take them as they are. No API member => none. */\nexport function getTriggerDefs(api: W6WApi, appId: string): Promise<ActionDef[]> {\n return (api.getAppTriggers?.(appId) ?? Promise.resolve([])).then((ts) =>\n ts.map((t) => ({\n key: t.key,\n title: t.title,\n description: t.description,\n params: (t.params ?? []) as ActionParam[],\n })),\n );\n}\n\n/** An app trigger's Test tab: it runs when the app reports the event, not by hand. */\nexport function AppTriggerTestNote({ title, app }: { title: string; app: string }) {\n return (\n <p className=\"w6w-muted w6w-small\">\n <strong>{title}</strong> runs when {app} reports it, so there is nothing to run by hand.\n Publish the workflow to start listening.\n </p>\n );\n}\n\nexport function AppStepConfig({\n kind = \"action\",\n onOpenStep,\n appId,\n app,\n onAdd,\n onClose,\n onDone,\n onDraftChange,\n onChangeApp,\n theme,\n workflowId,\n stepId,\n upstreamSteps = [],\n loop,\n initialAction,\n initialConnection,\n initialWith,\n}: {\n /**\n * What the Setup tab picks: one of the app's actions, or (`\"trigger\"`, the\n * Triggers tab) one of its triggers. Same account step, same picker, same\n * add-on-pick; a trigger node carries `uses.trigger: true` and lists\n * `api.getAppTriggers`. Its Test tab only says when it runs: there is no\n * action to invoke by hand.\n */\n kind?: \"action\" | \"trigger\";\n /** See {@link StepBuilderModalProps.onOpenStep}. */\n onOpenStep?: (id: string) => void;\n appId: string;\n app?: AppSummary;\n // biome-ignore lint/suspicious/noConfusingVoidType: see StepBuilderModalProps.onAdd, forwarded as-is.\n onAdd: (s: BuiltStep) => string | undefined | void;\n onClose: () => void;\n /** Done, once the node is added — applies the add flow's name, then closes. Else `onClose`. */\n onDone?: () => void;\n /** See {@link StepBuilderModalProps.onDraftChange}. */\n onDraftChange?: (id: string, step: BuiltStep) => void;\n onChangeApp?: () => void;\n theme?: ThemeMode;\n workflowId?: string;\n stepId?: string;\n /** The new step's known graph ancestors — see {@link StepBuilderModalProps.upstreamSteps}. */\n upstreamSteps?: ExpressionStepSource[];\n /** See {@link StepBuilderModalProps.loop}. */\n loop?: ExpressionLoopSource;\n /** Pre-selected action key, opens directly to Configure tab when provided with initialWith */\n initialAction?: string;\n /** Pre-selected connection id */\n initialConnection?: string;\n /** Pre-filled parameter values */\n initialWith?: Record<string, unknown>;\n}) {\n const api = useW6WApi();\n const isTrigger = kind === \"trigger\";\n const aNoun = isTrigger ? \"a trigger\" : \"an action\";\n const [auths, setAuths] = useState<AuthDef[] | null>(null);\n const [conns, setConns] = useState<ConnectionSummary[] | null>(null);\n const [actions, setActions] = useState<ActionDef[] | null>(null);\n const [metaError, setMetaError] = useState<string | null>(null);\n\n const [accountId, setAccountId] = useState<string>(initialConnection ?? \"\");\n const [connectionRef, setConnectionRef] = useState<string | undefined>();\n const connectionScope = useWorkflowConnections();\n const connectionScopeRef = useRef(connectionScope);\n connectionScopeRef.current = connectionScope;\n const connectionId = connectionRef\n ? (connectionIdFor(\n { id: stepId ?? \"\", uses: { app: appId, action: \"\", connectionRef } },\n connectionScope?.connections,\n ) ?? \"\")\n : accountId;\n const setConnectionId = useCallback((id: string | ((prev: string) => string)) => {\n setConnectionRef(undefined);\n setAccountId(id);\n }, []);\n const [actionKey, setActionKey] = useState<string>(initialAction ?? \"\");\n const [withValues, setWithValues] = useState<Record<string, unknown>>(initialWith ?? {});\n const rowRef = useRef<HTMLDivElement>(null);\n const [connectionPickerOpen, setConnectionPickerOpen] = useState(false);\n // Setup (app + connection + action) / Configure (params) / Test — same tabs as\n // the node editor, so add + edit are consistent.\n // When initial values are provided, skip Setup and open directly to Configure.\n const [tab, setTab] = useState<StepConfigTab>(\n initialAction && initialWith ? \"configure\" : \"setup\",\n );\n // The Configure tab's four representations (form / full-step JSON /\n // params-only JSON / node settings).\n const [configView, setConfigView] = useState<ConfigView>(\"props\");\n // Draft text backing the \"code\" (full-step, read-only) view.\n const [codeText, setCodeText] = useState(\"{}\");\n // Base node settings (retry / onError / notes) set on the Config view.\n const [draftConfig, setDraftConfig] = useState<NodeConfig>({});\n\n // Load auth methods, existing connections, and actions for the app in parallel.\n useEffect(() => {\n let canceled = false;\n setMetaError(null);\n const pickables = isTrigger ? getTriggerDefs(api, appId) : api.getAppActions(appId);\n Promise.all([api.getAppAuth(appId), api.listConnectionsForApp(appId), pickables])\n .then(([au, co, ac]) => {\n if (canceled) return;\n const choices = withDefaultConnection(appId, au, co);\n setAuths(au);\n setConns(choices);\n setActions(ac);\n const scope = connectionScopeRef.current;\n const selected = defaultConnectionFor(\n { id: stepId ?? \"\", uses: { app: appId, action: \"\" } },\n choices,\n scope?.nodes ?? [],\n scope?.connections ?? {},\n initialConnection,\n );\n if (selected.connectionRef) setConnectionRef(selected.connectionRef);\n else setConnectionId(selected.connection ?? \"\");\n })\n .catch((e) => !canceled && setMetaError((e as Error).message));\n return () => {\n canceled = true;\n };\n }, [api, appId, isTrigger, setConnectionId, initialConnection, stepId]);\n\n const refetchConns = async () => {\n const co = await api.listConnectionsForApp(appId);\n setConns(withDefaultConnection(appId, auths ?? [], co));\n };\n\n const availableAuths = (auths ?? []).filter((a) => a.available !== false);\n // Tenant-scoped auth can use the built-in account; stored accounts remain available.\n const autoSatisfied = availableAuths.some(\n (a) => a.autoSatisfied === true && (a.type === \"tenantAuth\" || a.type === \"jit\"),\n );\n // The server prefers `tenantAuth` over `jit` and mints it for the run's owner, so a scheduled or\n // queued run reaches it too. Only a `jit` sign-in forwards the signed-in user's own token, which\n // a queued run does not have.\n const autoNeedsSignedInUser =\n autoSatisfied &&\n !availableAuths.some((a) => a.autoSatisfied === true && a.type === \"tenantAuth\");\n const needsConnection = availableAuths.length > 0 && !autoSatisfied;\n const hasConnection = (conns ?? []).length > 0;\n const selectedAction = (actions ?? []).find((a) => a.key === actionKey);\n const eventChoices = isTrigger\n ? eventbriteTriggerChoices(appId, actions, actionKey, withValues)\n : null;\n // Alphabetical by display title (falling back to key) so the dropdown is\n // scannable regardless of the manifest's declaration order.\n const sortedActions = [...(actions ?? [])].sort((a, b) =>\n (a.title ?? a.key).localeCompare(b.title ?? b.key, undefined, { sensitivity: \"base\" }),\n );\n\n // Per-app `testRequired` save-gate — defaults to required, read off the app\n // surface. `testPassed` is satisfied either by an in-session passing test run\n // (below) or by a previously-saved passing test discovered via `listStepTests`\n // when the builder carries a workflow-step context.\n const testRequired = isTestRequired(app);\n const [testPassed, setTestPassed] = useState(false);\n useEffect(() => {\n if (!testRequired || !workflowId || !stepId) return;\n let canceled = false;\n api\n .listStepTests(workflowId, stepId)\n .then((tests) => {\n if (!canceled && tests.some((t) => t.lastRunStatus === \"succeeded\")) setTestPassed(true);\n })\n .catch(() => {});\n return () => {\n canceled = true;\n };\n }, [api, testRequired, workflowId, stepId]);\n\n // The step-being-added's graph ancestors that carry a saved step-test,\n // offered as one-click seeds for the incoming state — the SAME pipeline\n // `StepEditModal` uses, so the Test tab here resolves\n // `{{ steps.<id>.output.<field> }}` the same way an existing step's Test\n // tab does (T1.1.1). Only meaningful when the builder was opened from a\n // workflow canvas (`workflowId` present); the Functions/Endpoints pickers\n // pass no `workflowId` and no `upstreamSteps`.\n const seedSources = useSeedSources(workflowId ?? \"\", upstreamSteps, !!workflowId);\n const testStartState = startStateFromSeeds(seedSources, loopSeedFromSource(loop));\n\n const connectionSatisfied = !needsConnection || (hasConnection && !!connectionId);\n // Setup is done when an action is picked and its connection (if any) is set;\n // Configure is done when the action's required params are filled.\n const setupComplete =\n !!actionKey && connectionSatisfied && (!eventChoices || eventChoices.selected.length > 0);\n const configComplete =\n setupComplete &&\n !!selectedAction &&\n requiredParamsFilled(selectedAction.params ?? [], withValues);\n // HITL-1 amendment: a passing test is required to *publish* (T4.2.1), not to\n // add the step to the graph — `testRequired`/`testPassed` still drive the\n // Test tab's own \"test passed\" messaging below.\n const canAdd = setupComplete;\n\n const selectedConn = (conns ?? []).find((c) => c.id === connectionId);\n\n function buildStep(): BuiltStep {\n return {\n uses: {\n app: appId,\n action: selectedAction?.key ?? actionKey,\n // Workflow defaults are explicit references, including the server's built-in account.\n ...(connectionRef ? { connectionRef } : connectionId ? { connection: connectionId } : {}),\n ...(isTrigger ? { trigger: true as const } : {}),\n },\n with: withValues,\n ...draftConfig,\n };\n }\n function add() {\n if (!selectedAction) return;\n onAdd(buildStep());\n }\n\n // The id `onAdd` minted at commit time, once Setup has completed this\n // session. `null` until then (and forever, for a caller that doesn't supply\n // `onDraftChange` — the original one-shot \"Add node\" behavior).\n const [committedId, setCommittedId] = useState<string | null>(null);\n\n // Mint — the moment Setup first completes (action + connection, if needed),\n // commit the WIP step to the graph, exactly once.\n // biome-ignore lint/correctness/useExhaustiveDependencies: buildStep/onAdd intentionally read fresh closure state; only the mint gate should retrigger this effect.\n useEffect(() => {\n if (!onDraftChange || committedId !== null || !setupComplete) return;\n // A checklist needs several clicks. Commit it when the author leaves Setup, not on\n // the first check (which would close the picker before the selection is finished).\n if (eventChoices && tab === \"setup\") return;\n const id = onAdd(buildStep());\n if (id) setCommittedId(id);\n if (id && isTrigger) onOpenStep?.(id);\n }, [onDraftChange, committedId, setupComplete, tab]);\n\n // Update — keep the already-committed node current on every subsequent field\n // change, instead of minting a duplicate via a second `onAdd` call.\n // biome-ignore lint/correctness/useExhaustiveDependencies: buildStep reads fresh closure state; only these fields should retrigger the update.\n useEffect(() => {\n if (!onDraftChange || committedId === null) return;\n onDraftChange(committedId, buildStep());\n }, [committedId, withValues, draftConfig, connectionId, connectionRef]);\n\n const changeConfigView = (v: ConfigView) => {\n if (v === \"code\") setCodeText(stepToJson(buildStep()));\n setConfigView(v);\n };\n\n return (\n <div className=\"w6w-stepconfig\">\n {/* Tabs bar — full width: Setup/Configure/Test on the left, the props/code/\n config view icons on the right (enabled only on the Configure tab). */}\n <div className=\"w6w-tabsbar\">\n <div className=\"w6w-subtabs\">\n <button\n type=\"button\"\n className={`w6w-subtab${tab === \"setup\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"setup\")}\n >\n Setup\n </button>\n <button\n type=\"button\"\n disabled={!setupComplete}\n title={setupComplete ? undefined : \"Complete Setup first\"}\n className={`w6w-subtab${tab === \"configure\" ? \" active\" : \"\"}`}\n onClick={() => setupComplete && setTab(\"configure\")}\n >\n Configure\n </button>\n <button\n type=\"button\"\n disabled={!configComplete}\n title={configComplete ? undefined : \"Fill the required fields first\"}\n className={`w6w-subtab${tab === \"test\" ? \" active\" : \"\"}`}\n onClick={() => configComplete && setTab(\"test\")}\n >\n Test\n </button>\n </div>\n <ConfigViewToggle\n view={configView}\n customized={hasParamCustomization(withValues)}\n onChange={changeConfigView}\n disabled={tab !== \"configure\"}\n />\n </div>\n\n <div className=\"w6w-stepconfig-body\">\n {/* Setup — app, connection, action (or trigger). */}\n {tab === \"setup\" && (\n <div className=\"w6w-stack\">\n {metaError && <div className=\"w6w-result w6w-error\">{metaError}</div>}\n {auths === null && !metaError && <p className=\"w6w-muted w6w-small\">Loading…</p>}\n\n <div className=\"w6w-field\">\n <span>App</span>\n <div className=\"w6w-app-conn-row\" ref={rowRef}>\n <button\n type=\"button\"\n className=\"w6w-app-conn-btn\"\n aria-label=\"App\"\n onClick={onChangeApp}\n disabled={!onChangeApp}\n >\n {app && (\n <AppIcon\n src={app.iconSvg}\n srcDark={app.iconSvgDark}\n brandColor={app.brandColor}\n name={app.displayName}\n theme={theme}\n size={20}\n />\n )}\n <span className=\"w6w-conn-label-name\">{app?.displayName ?? appId}</span>\n </button>\n <WorkflowConnectionPicker\n step={{\n id: committedId ?? stepId ?? \"\",\n uses: {\n app: appId,\n action: actionKey,\n ...(connectionRef\n ? { connectionRef }\n : { connection: connectionId || undefined }),\n },\n }}\n conns={conns}\n failed={!!metaError}\n open={connectionPickerOpen}\n onOpenChange={setConnectionPickerOpen}\n anchorRef={rowRef}\n onChangeConnection={setConnectionId}\n onChangeConnectionRef={setConnectionRef}\n onConnectionCreated={() => {\n void refetchConns();\n }}\n />\n </div>\n {autoNeedsSignedInUser && selectedConn?.builtIn && (\n <span className=\"w6w-hint\">\n Scheduled or queued runs need a stored connection. Choose one from the connection\n menu.\n </span>\n )}\n {auths !== null && needsConnection && !hasConnection && (\n <span className=\"w6w-hint\">\n This app needs a connection before its actions can run.\n </span>\n )}\n </div>\n\n {/* Action */}\n {actions !== null &&\n (actions.length === 0 ? (\n <p className=\"w6w-muted w6w-small\">\n {isTrigger ? \"This app declares no triggers.\" : \"This app exposes no actions.\"}\n </p>\n ) : eventChoices ? (\n <EventbriteTriggerPicker\n choices={eventChoices}\n onChange={(selected) => {\n setActionKey(eventChoices.triggerKey);\n setWithValues((prev) => ({ ...prev, actions: selected }));\n }}\n />\n ) : (\n // biome-ignore lint/a11y/noLabelWithoutControl: Combobox renders its own <input> INSIDE this label, so the field text labels the control at runtime; the rule cannot see through the component boundary.\n <label className=\"w6w-field\">\n <span>\n {isTrigger ? \"Trigger\" : \"Action\"}\n {actionKey ? \"\" : \" *\"}\n </span>\n <Combobox\n value={actionKey}\n placeholder={`— pick ${aNoun} —`}\n // Always the searchable combobox (T-1): a short action list used\n // to collapse to a native <select>, which hides the filter and\n // opens an unbounded OS popup over the modal.\n mode=\"combobox\"\n // …and its popup is capped below the shared 240px so it fits the\n // modal body instead of adding a second scroller to it (T-1).\n listMaxHeight={200}\n onChange={(key) => {\n setActionKey(key);\n setWithValues(\n expressionDefaults(\n (actions ?? []).find((a) => a.key === key)?.params ?? [],\n ),\n );\n // A new action hasn't been tested — re-arm the save-gate.\n setTestPassed(false);\n }}\n options={sortedActions.map((a) => ({\n value: a.key,\n label: `${a.title ?? a.key} (${a.key})`,\n }))}\n />\n {selectedAction?.description && (\n <span className=\"w6w-hint\">{selectedAction.description}</span>\n )}\n </label>\n ))}\n </div>\n )}\n\n {/* Configure — the action's config, as a form (props), the full step\n (code), the params alone (params-code), or the base node settings\n (config). */}\n {tab === \"configure\" &&\n (!selectedAction ? (\n <p className=\"w6w-muted w6w-small\">Pick {aNoun} in Setup first.</p>\n ) : configView === \"props\" ? (\n <ParamsForm\n params={selectedAction.params ?? []}\n values={withValues}\n onChange={setWithValues}\n dynamic={{\n appId,\n actionKey: selectedAction.key,\n connectionId: connectionId || undefined,\n appName: app?.displayName,\n }}\n />\n ) : configView === \"code\" ? (\n // Full step, read-only (D-3) — `stepToJson` is the ONE serializer,\n // shared with the two other code-view hosts.\n <JsonEditor\n value={codeText}\n onChange={() => {}}\n readOnly\n minHeight=\"240px\"\n height=\"100%\"\n aria-label=\"Node JSON\"\n copyable\n />\n ) : configView === \"params-code\" ? (\n <ParamCustomization values={withValues} onChange={setWithValues} />\n ) : (\n // A trigger has no failure of its own to retry or police.\n <NodeConfigForm\n config={draftConfig}\n onChange={setDraftConfig}\n failureHandling={!isTrigger}\n />\n ))}\n\n {/* Test — try the action with the current params. */}\n {tab === \"test\" &&\n (selectedAction && isTrigger ? (\n <AppTriggerTestNote\n title={selectedAction.title ?? selectedAction.key}\n app={app?.displayName ?? appId}\n />\n ) : selectedAction ? (\n <StepTestRun\n app={appId}\n action={selectedAction.key}\n connectionId={connectionId || undefined}\n values={withValues}\n canRun={\n setupComplete && requiredParamsFilled(selectedAction.params ?? [], withValues)\n }\n state={testStartState}\n onResult={setTestPassed}\n />\n ) : (\n <p className=\"w6w-muted w6w-small\">Pick an action in Setup first.</p>\n ))}\n </div>\n\n {/* Test-required note — always rendered while on the Test tab, as a\n sibling ABOVE the footer, so the footer's two buttons never move\n whether the note has text or not (the row's reserved min-height\n keeps both states geometrically identical). */}\n {tab === \"test\" && (\n <div className=\"w6w-stepconfig-testnote\">\n {testRequired && !testPassed && (\n <span className=\"w6w-muted w6w-small\">\n Not yet tested. You can publish without running a test.\n </span>\n )}\n </div>\n )}\n\n {/* Footer — pinned to the modal bottom. Each tab has a Next button; the\n last (Test) commits the step. */}\n <div className=\"w6w-modal-actions w6w-stepconfig-footer\">\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost\" onClick={onClose}>\n Cancel\n </button>\n {tab === \"test\" ? (\n <button\n type=\"button\"\n className=\"w6w-btn\"\n disabled={committedId === null && !canAdd}\n onClick={committedId !== null ? (onDone ?? onClose) : add}\n >\n {committedId !== null ? \"Done\" : \"Add node\"}\n </button>\n ) : (\n <button\n type=\"button\"\n className=\"w6w-btn\"\n disabled={tab === \"setup\" ? !setupComplete : !configComplete}\n onClick={() => setTab(tab === \"setup\" ? \"configure\" : \"test\")}\n >\n Next →\n </button>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * {@link AppStepConfig}'s Setup tab, minus the Action and Configure/Test\n * gate — for a caller that only needs \"a connection is chosen\" (e.g. binding\n * a repository), not a runnable step. Copies its App section and all three\n * Connection-section branches verbatim, same CSS classes; fetches only\n * {@link W6WApi.getAppAuth} + {@link W6WApi.listConnectionsForApp} (never\n * `getAppActions`). Ends in one footer button, gated on `connectionSatisfied`\n * alone, that fires {@link onConnected} once — never on selection (D-sbm-2).\n */\nexport function AppConnectionOnlyConfig({\n appId,\n app,\n onClose,\n onChangeApp,\n theme,\n initialConnection,\n onConnected,\n}: {\n appId: string;\n app?: AppSummary;\n onClose: () => void;\n onChangeApp?: () => void;\n theme?: ThemeMode;\n /** Pre-selected connection id */\n initialConnection?: string;\n /** Fired once, on the footer button — never on a state change (D-sbm-2). */\n onConnected: (connectionId: string, app: AppSummary) => void;\n}) {\n const api = useW6WApi();\n const [auths, setAuths] = useState<AuthDef[] | null>(null);\n const [conns, setConns] = useState<ConnectionSummary[] | null>(null);\n const [metaError, setMetaError] = useState<string | null>(null);\n\n const [connectionId, setConnectionId] = useState<string>(initialConnection ?? \"\");\n const [showConnModal, setShowConnModal] = useState(false);\n // Once a connection is chosen it renders as a static label; \"Change\" flips\n // back to the dropdown. No connection selected yet also forces the dropdown.\n const [changingConn, setChangingConn] = useState(false);\n\n // Load auth methods and existing connections for the app in parallel — no\n // actions fetch here: this component stops at \"a connection is chosen\", it\n // never lists or picks an Action.\n useEffect(() => {\n let canceled = false;\n setMetaError(null);\n Promise.all([api.getAppAuth(appId), api.listConnectionsForApp(appId)])\n .then(([au, co]) => {\n if (canceled) return;\n setAuths(au);\n setConns(co);\n // P2: in the auto-satisfied state, never auto-select an existing\n // connection — see AppStepConfig's own fetch effect for why.\n const autoSat = (au ?? []).some((a) => a.autoSatisfied === true);\n if (!autoSat && co.length > 0) setConnectionId(co[0].id);\n })\n .catch((e) => !canceled && setMetaError((e as Error).message));\n return () => {\n canceled = true;\n };\n }, [api, appId]);\n\n const refetchConns = async () => {\n const co = await api.listConnectionsForApp(appId);\n setConns(co);\n if (co.length > 0) setConnectionId((prev) => prev || co[0].id);\n };\n\n const availableAuths = (auths ?? []).filter((a) => a.available !== false);\n const autoSatisfied = availableAuths.some(\n (a) => a.autoSatisfied === true && (a.type === \"tenantAuth\" || a.type === \"jit\"),\n );\n // The server prefers `tenantAuth` over `jit` and mints it for the run's owner, so a scheduled or\n // queued run reaches it too. Only a `jit` sign-in forwards the signed-in user's own token, which\n // a queued run does not have.\n const autoNeedsSignedInUser =\n autoSatisfied &&\n !availableAuths.some((a) => a.autoSatisfied === true && a.type === \"tenantAuth\");\n const needsConnection = availableAuths.length > 0 && !autoSatisfied;\n const hasConnection = (conns ?? []).length > 0;\n const connectionSatisfied = !needsConnection || (hasConnection && !!connectionId);\n\n const selectedConn = (conns ?? []).find((c) => c.id === connectionId);\n // Show the dropdown only before a connection is picked or while changing it;\n // otherwise the selected connection reads as a compact label.\n const showConnPicker = changingConn || !connectionId;\n\n return (\n <div className=\"w6w-stepconfig\">\n <div className=\"w6w-stepconfig-body\">\n <div className=\"w6w-stack\">\n {metaError && <div className=\"w6w-result w6w-error\">{metaError}</div>}\n {auths === null && !metaError && <p className=\"w6w-muted w6w-small\">Loading…</p>}\n\n {/* App — click Change to go back to the app picker. */}\n <div className=\"w6w-field\">\n <span>App</span>\n <div className=\"w6w-conn-label\">\n {app && (\n <AppIcon\n src={app.iconSvg}\n srcDark={app.iconSvgDark}\n brandColor={app.brandColor}\n name={app.displayName}\n theme={theme}\n size={20}\n />\n )}\n <span className=\"w6w-conn-label-name\">{app?.displayName ?? appId}</span>\n {onChangeApp && (\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n onClick={onChangeApp}\n >\n Change\n </button>\n )}\n </div>\n </div>\n\n {/* Connection — the third, auto-satisfied state (P3): the section\n still renders (it never disappears — a user may still want to\n add their own third-party account), but the picker is replaced\n by a passive line plus the escape hatch. */}\n {auths !== null && autoSatisfied && (\n <div className=\"w6w-field\">\n <span>Connection</span>\n <div className=\"w6w-conn-label\">\n <span className=\"w6w-conn-label-name\">\n Connected automatically — this app needs no connection for your organization.\n </span>\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n onClick={() => setShowConnModal(true)}\n >\n Create connection\n </button>\n </div>\n {/* P3a: a `jit` sign-in needs the signed-in user's own token, which a\n scheduled or queued run of this saved workflow does not have. */}\n {autoNeedsSignedInUser && (\n <span className=\"w6w-hint\">\n A scheduled or queued run of this workflow still needs a connection configured on\n this step — use \"Create connection\" if this step will run on a schedule.\n </span>\n )}\n </div>\n )}\n\n {/* Connection — the two pre-existing states (needs one / has one). */}\n {auths !== null &&\n needsConnection &&\n (!hasConnection ? (\n <div className=\"w6w-result w6w-stepconfig-conn-empty\">\n <div style={{ marginBottom: 8 }}>\n This app needs a connection before its actions can run.\n </div>\n <button type=\"button\" className=\"w6w-btn\" onClick={() => setShowConnModal(true)}>\n Create connection\n </button>\n </div>\n ) : showConnPicker ? (\n <label className=\"w6w-field\">\n <span>Connection</span>\n <div style={{ display: \"flex\", gap: 6 }}>\n <select\n value={connectionId}\n onChange={(e) => {\n setConnectionId(e.target.value);\n setChangingConn(false);\n }}\n style={{ flex: 1 }}\n >\n {(conns ?? []).map((c) => (\n <option key={c.id} value={c.id}>\n {c.displayName || c.id} {c.state ? `(${c.state})` : \"\"}\n </option>\n ))}\n </select>\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n onClick={() => setShowConnModal(true)}\n >\n + New\n </button>\n </div>\n </label>\n ) : (\n <div className=\"w6w-field\">\n <span>Connection</span>\n <div className=\"w6w-conn-label\">\n <span className=\"w6w-conn-label-name\">\n {selectedConn?.displayName || selectedConn?.id || connectionId}\n {selectedConn?.state ? ` (${selectedConn.state})` : \"\"}\n </span>\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n onClick={() => setChangingConn(true)}\n >\n Change\n </button>\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost w6w-btn-sm\"\n onClick={() => setShowConnModal(true)}\n >\n + New\n </button>\n </div>\n </div>\n ))}\n </div>\n </div>\n\n {/* Footer — pinned to the modal bottom. One button: it commits the\n chosen connection and hands control back to the caller. Gated on\n connectionSatisfied alone — there is no Action here, so the\n `!!actionKey` clause of AppStepConfig's setupComplete does not\n exist. Fires onConnected on click only, never on a state change\n (D-sbm-2). */}\n <div className=\"w6w-modal-actions w6w-stepconfig-footer\">\n <button type=\"button\" className=\"w6w-btn w6w-btn-ghost\" onClick={onClose}>\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"w6w-btn\"\n disabled={!connectionSatisfied || !app}\n onClick={() => app && onConnected(connectionId, app)}\n >\n Next →\n </button>\n </div>\n\n {showConnModal && (\n <AddConnectionModal\n theme={theme}\n initialAppId={appId}\n onClose={() => setShowConnModal(false)}\n onCreated={async ({ connectionId: id }) => {\n setShowConnModal(false);\n setConnectionId(id);\n setChangingConn(false);\n await refetchConns();\n }}\n />\n )}\n </div>\n );\n}\n","import { useRef, useState } from \"react\";\nimport { JsonEditor } from \"./JsonEditor.tsx\";\nimport { ParamsForm } from \"./ParamsForm.tsx\";\nimport { ConfigViewToggle } from \"./StepBuilderModal.tsx\";\nimport type { ActionParam } from \"./types.ts\";\n\n/** The two views this form offers — a subset of the editor's `ConfigView`. */\nconst VIEWS = [\"props\", \"code\"] as const;\ntype EntryView = (typeof VIEWS)[number];\n\nexport interface PropertyEntryFormProps {\n /** Declared params to collect values for. Empty ⇒ raw-JSON only. */\n params: ActionParam[];\n /** Current values, keyed by param `key`. */\n values: Record<string, unknown>;\n /** Fired with the next values object on every (valid) edit. */\n onChange: (next: Record<string, unknown>) => void;\n /**\n * **The validity-out.** Fired (on change only) with whether the raw-JSON draft\n * currently *is* a values map. A draft that does not parse — **or that parses\n * to an array / scalar / `null`** — never reaches `onChange`, so without this\n * channel a host cannot tell \"the user is mid-edit on something that isn't a\n * values map\" from \"the user is happy with what's collected\", and would run\n * the *previous* payload silently. Hosts that execute something (the canvas ▶\n * Run) MUST gate their run affordance on it. Always `true` while the field\n * form is showing — a form cannot be syntactically wrong.\n */\n onValidityChange?: (valid: boolean) => void;\n readOnly?: boolean;\n /** Which view opens first. Defaults to the field form. */\n initialView?: EntryView;\n}\n\n/**\n * Whether a parsed JSON draft IS a values map. An array, a scalar and `null` all\n * parse but are not a set of values — and `typeof null === \"object\"`, so the\n * null arm is load-bearing, not defensive noise (dropping it lets `null` through\n * as the whole values object and blows up the required-check downstream).\n */\nfunction isValuesMap(parsed: unknown): parsed is Record<string, unknown> {\n return parsed !== null && typeof parsed === \"object\" && !Array.isArray(parsed);\n}\n\n/**\n * The one property-entry surface: a param form ⇄ raw-JSON editor over a single\n * `values` object. **Chrome-less and value-emitting** — its root is a plain\n * `div.w6w-stack`, it owns no modal, no header, no run button and no result\n * pane. It collects values and emits them through `onChange`; the *host* decides\n * what to do with them (Test invokes, Run executes the step) and supplies any\n * surrounding chrome.\n *\n * That is deliberate: it is mounted both inline inside an already-open\n * `<dialog>` (the step editor's Test tab) and inside a modal of its own (Run).\n * Rendering a modal in here would give the first host a modal-in-a-modal —\n * which *works* mechanically, since this library's modal is a native\n * `<dialog>` that top-layer-stacks, and just looks wrong.\n *\n * The fields view is {@link ParamsForm} reused as-is, so per-field `ƒx`\n * (expression binding) comes for free. The raw view is {@link JsonEditor} bound\n * to the **values** object — never the field *definitions* — and only pushes\n * back when the text parses to a plain object, so an invalid draft cannot\n * corrupt what has been collected. Because such a draft is *silently* held back,\n * the form also reports it through `onValidityChange` (the validity-out): a host\n * that runs something real must gate its run affordance on that, or it would\n * execute the previous payload while the operator looks at a different one. The\n * toggle is the shared {@link ConfigViewToggle}, narrowed to its two views.\n *\n * With **no declared params** (a webhook trigger, an action with no schema)\n * there is nothing to render a form from, so it shows the raw-JSON view alone\n * and hides the toggle.\n */\nexport function PropertyEntryForm({\n params,\n values,\n onChange,\n onValidityChange,\n readOnly,\n initialView = \"props\",\n}: PropertyEntryFormProps) {\n const hasFields = params.length > 0;\n const [view, setView] = useState<EntryView>(initialView);\n // No params ⇒ there is no form to show, so the raw view is the only view.\n const showJson = !hasFields || view === \"code\";\n // The JSON draft is local text: it is re-seeded from the VALUES (never from\n // the param *definitions* — that blob-where-a-form-should-be is the bug this\n // form exists to kill) whenever the raw view is (re-)entered, and only flows\n // back when it parses to a values map.\n const [text, setText] = useState(() => toJsonText(values));\n // Whether the current raw draft is a values map. Mirrored in a ref so the\n // validity-out fires on *change* only — no effect, no render loop.\n const [draftValid, setDraftValid] = useState(true);\n const validRef = useRef(true);\n const emitValid = (next: boolean) => {\n if (next === validRef.current) return;\n validRef.current = next;\n setDraftValid(next);\n onValidityChange?.(next);\n };\n\n const openView = (next: EntryView) => {\n // Either way the old draft is discarded: entering the raw view re-seeds it\n // from the values, leaving it drops it. So validity resets with it.\n if (next === \"code\") setText(toJsonText(values));\n emitValid(true);\n setView(next);\n };\n\n // A webhook-style payload gets the plainer label; alongside a field form the\n // raw view is explicitly \"the same values, as JSON\".\n const label = hasFields ? \"Values (JSON)\" : \"Payload\";\n\n return (\n <div className=\"w6w-stack\">\n {/* Right-aligned, like the toggle's other two call sites in their tabs\n bar. Inline style because the form owns no chrome of its own — no new\n rule in `styles.css` for a one-line layout. */}\n {hasFields && (\n <div style={{ display: \"flex\", justifyContent: \"flex-end\" }}>\n <ConfigViewToggle\n view={view}\n views={[...VIEWS]}\n onChange={(v) => openView(v as EntryView)}\n />\n </div>\n )}\n\n {showJson ? (\n <div className=\"w6w-field\">\n <span>{label}</span>\n <JsonEditor\n value={text}\n onChange={setText}\n readOnly={readOnly}\n minHeight=\"140px\"\n aria-label={`${label} JSON`}\n onValidChange={(parsed) => {\n // Only a plain object IS a values map — an array, a scalar or\n // `null` is a half-typed edit, not a new set of values. It never\n // reaches `onChange`, so the host is told through the validity-out\n // instead of silently keeping (and running) the previous payload.\n const ok = isValuesMap(parsed);\n emitValid(ok);\n if (ok) onChange(parsed);\n }}\n // Fires for unparseable text too, where `onValidChange` never does.\n onValidityChange={(r) => {\n if (!r.valid) emitValid(false);\n }}\n />\n {!draftValid && (\n <span className=\"w6w-hint\">\n This draft isn’t a JSON object yet — the collected values are unchanged until it is.\n </span>\n )}\n </div>\n ) : (\n <ParamsForm params={params} values={values} onChange={onChange} readOnly={readOnly} />\n )}\n </div>\n );\n}\n\n/** Render a values object as the editor's starting text. */\nfunction toJsonText(values: Record<string, unknown>): string {\n return JSON.stringify(values ?? {}, null, 2);\n}\n","import type { ReactNode } from \"react\";\nimport { Modal } from \"./Modal.tsx\";\n\nexport interface ConfirmModalProps {\n title: string;\n message: string;\n /** Fired when the user confirms. The caller clears its pending state via onClose. */\n onConfirm: () => void;\n /** Fired on Cancel, Esc, or outside-click — dismisses without confirming. */\n onClose: () => void;\n confirmLabel?: string;\n cancelLabel?: string;\n /** Prevent dismissal and repeated submission while the action is running. */\n pending?: boolean;\n /** Style the confirm button as destructive (default true — this dialog gates dangerous actions). */\n destructive?: boolean;\n /** Extra consequence copy under the message (e.g. a warning line) that a string cannot carry. */\n children?: ReactNode;\n}\n\n/**\n * A reusable confirmation dialog built on `@w6w/ui`'s <Modal>, so it inherits the\n * same backdrop, Esc-dismiss and outside-click close as every other dialog here.\n * Replaces the browser's native confirmation prompt: Confirm fires `onConfirm`;\n * Cancel/Esc/outside-click fires `onClose` only (no confirmation).\n *\n * Prop API mirrors `packages/studio/src/components/ConfirmModal.tsx` and\n * `packages/admin/src/components/ConfirmModal.tsx` so all three consoles share one\n * vocabulary. Only the class names differ — this one is `w6w-*` namespaced.\n *\n * It owns its own <Modal>, so never render it *inside* another modal's body: ui's\n * Modal is a native <dialog>, so nesting one works mechanically and fails no gate —\n * it just looks wrong. Render it as a **sibling** of the other modal instead.\n *\n * Confirmations are `{pending}` state + a rendered sibling modal, never a blocking\n * call: a caller reachable from a keydown handler cannot swap in a boolean.\n */\nexport function ConfirmModal({\n title,\n message,\n onConfirm,\n onClose,\n confirmLabel = \"Confirm\",\n cancelLabel = \"Cancel\",\n destructive = true,\n pending = false,\n children,\n}: ConfirmModalProps) {\n return (\n <Modal\n title={title}\n onClose={() => {\n if (!pending) onClose();\n }}\n >\n {/* One body wrapper + a pinned footer (D-3): long consequence copy scrolls\n inside `.w6w-modal-body`, the buttons never leave the dialog's bottom. */}\n <div className=\"w6w-modal-body\">\n <p className=\"w6w-muted w6w-small\">{message}</p>\n {children}\n </div>\n <div className=\"w6w-modal-actions\">\n <button\n type=\"button\"\n className=\"w6w-btn w6w-btn-ghost\"\n onClick={onClose}\n disabled={pending}\n >\n {cancelLabel}\n </button>\n <button\n type=\"button\"\n className={destructive ? \"w6w-btn w6w-btn-danger\" : \"w6w-btn\"}\n onClick={onConfirm}\n disabled={pending}\n >\n {confirmLabel}\n </button>\n </div>\n </Modal>\n );\n}\n","/**\n * Persisted node samples — the server's record of the last output SHAPE (and, when small enough,\n * the value) each node produced, from a step Test, a node run or a full run\n * (`GET /workflows/:id/node-samples`). The editor loads them once per workflow so the picker,\n * the ƒx previews and the Test tab still offer an upstream node's keys after a reload, a reopen or\n * another browser, without re-running anything.\n *\n * They are a FALLBACK under what the editor already holds: a fresh in-memory output (a saved\n * step-test's `lastRunOutput`) wins, unless the persisted sample is strictly newer. Field\n * inference (`inferOutputFields`) is the same either way — a skeleton carries the same keys as\n * the real value it was taken from.\n *\n * Pure and JSX-free so `node --test` exercises it directly.\n */\n\n/** A node output's structural shape, as the server records it. */\nexport type NodeShape =\n | { type: \"string\" | \"number\" | \"boolean\" | \"null\" | \"unknown\" }\n | { type: \"object\"; fields: Record<string, NodeShape> }\n | { type: \"array\"; items?: NodeShape };\n\n/** One persisted node sample (`GET /workflows/:id/node-samples` → `nodeSamples[]`). */\nexport interface NodeSample {\n nodeId: string;\n shape: NodeShape;\n /** The output itself, when the server kept it (omitted when too large — `sampleOmitted`). */\n sample?: unknown;\n sampleOmitted?: true;\n source: \"step_test\" | \"node_run\" | \"run\";\n runId?: string;\n /** ISO timestamp of the write. */\n updatedAt: string;\n}\n\n/**\n * A representative value of `shape`: `\"\"`, `0`, `false`, `null`, an object of its fields, an\n * array of one item skeleton (`[]` when the item shape is unknown). `unknown` is `null`.\n */\nexport function shapeToSkeleton(shape: NodeShape | undefined): unknown {\n if (!shape || typeof shape !== \"object\") return null;\n switch (shape.type) {\n case \"string\":\n return \"\";\n case \"number\":\n return 0;\n case \"boolean\":\n return false;\n case \"object\": {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(shape.fields ?? {})) out[k] = shapeToSkeleton(v);\n return out;\n }\n case \"array\":\n return shape.items ? [shapeToSkeleton(shape.items)] : [];\n default:\n return null;\n }\n}\n\n/** Index `samples` by node id (the last entry for a repeated id wins). */\nexport function indexNodeSamples(\n samples: readonly NodeSample[] | undefined,\n): Record<string, NodeSample> {\n const out: Record<string, NodeSample> = {};\n for (const s of samples ?? []) {\n if (s && typeof s.nodeId === \"string\" && s.nodeId !== \"\") out[s.nodeId] = s;\n }\n return out;\n}\n\n/** `true` when the persisted sample carries the real value (not just a shape). */\nfunction hasSampleValue(s: NodeSample): boolean {\n return s.sampleOmitted !== true && \"sample\" in s && s.sample !== undefined;\n}\n\n/** `true` when `p` was written strictly after the fresh output's run time `freshAt`. */\nfunction persistedIsNewer(p: NodeSample, freshAt: string | null | undefined): boolean {\n if (!freshAt) return false;\n const a = Date.parse(p.updatedAt);\n const b = Date.parse(freshAt);\n return Number.isFinite(a) && Number.isFinite(b) && a > b;\n}\n\n/**\n * One node's effective output for SHAPE inference: the fresh in-memory output wins (unless the\n * persisted sample is strictly newer than `freshAt`), else the persisted `sample`, else\n * {@link shapeToSkeleton} of its shape. `undefined` when neither exists.\n */\nexport function effectiveNodeOutput(\n nodeId: string,\n fresh: Record<string, unknown>,\n persisted: Record<string, NodeSample>,\n freshAt?: Record<string, string | null | undefined>,\n): unknown {\n const f = fresh[nodeId];\n const p = persisted[nodeId];\n if (f !== undefined && (!p || !persistedIsNewer(p, freshAt?.[nodeId]))) return f;\n if (!p) return f;\n return hasSampleValue(p) ? p.sample : shapeToSkeleton(p.shape);\n}\n\n/**\n * {@link effectiveNodeOutput} for every node with a fresh or persisted output — the map the\n * editor hands `StepShapeContext.testOutputs`, so a downstream node's picker offers the\n * persisted keys after a reload.\n */\nexport function effectiveNodeOutputs(\n fresh: Record<string, unknown>,\n persisted: Record<string, NodeSample>,\n freshAt?: Record<string, string | null | undefined>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const id of new Set([...Object.keys(fresh), ...Object.keys(persisted)])) {\n const v = effectiveNodeOutput(id, fresh, persisted, freshAt);\n if (v !== undefined) out[id] = v;\n }\n return out;\n}\n\n/**\n * The outputs the Result PREVIEWS read: real values only — never a skeleton, which would preview\n * a made-up `\"\"`/`0`. Same precedence as {@link effectiveNodeOutput}; a newer persisted sample\n * with no value falls back to the fresh one.\n */\nexport function previewNodeOutputs(\n fresh: Record<string, unknown>,\n persisted: Record<string, NodeSample>,\n freshAt?: Record<string, string | null | undefined>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = { ...fresh };\n for (const [id, p] of Object.entries(persisted)) {\n if (!hasSampleValue(p)) continue;\n if (fresh[id] === undefined || persistedIsNewer(p, freshAt?.[id])) out[id] = p.sample;\n }\n return out;\n}\n\n/**\n * {@link effectiveNodeOutputs} split into its two tiers, so the editor can hand the picker\n * `testOutputs` (fresh) and `persistedOutputs` (persisted) SEPARATELY and show the right hint.\n * A persisted sample wins only when there is no fresh output or it is strictly newer than\n * `freshAt`; then the fresh entry is dropped from `fresh` and the persisted shape (its kept\n * value, else its skeleton) goes in `persisted`. Elsewhere `fresh` is the fresh map unchanged.\n */\nexport function splitNodeOutputs(\n fresh: Record<string, unknown>,\n persisted: Record<string, NodeSample>,\n freshAt?: Record<string, string | null | undefined>,\n): { fresh: Record<string, unknown>; persisted: Record<string, unknown> } {\n const outFresh: Record<string, unknown> = { ...fresh };\n const outPersisted: Record<string, unknown> = {};\n for (const [id, p] of Object.entries(persisted)) {\n if (fresh[id] !== undefined && !persistedIsNewer(p, freshAt?.[id])) continue;\n delete outFresh[id];\n outPersisted[id] = hasSampleValue(p) ? p.sample : shapeToSkeleton(p.shape);\n }\n return { fresh: outFresh, persisted: outPersisted };\n}\n\n/**\n * {@link previewNodeOutputs} split into tiers: `persisted` holds only REAL kept values of the\n * persisted samples that win (never a skeleton); `fresh` is the fresh map minus those ids.\n */\nexport function splitPreviewOutputs(\n fresh: Record<string, unknown>,\n persisted: Record<string, NodeSample>,\n freshAt?: Record<string, string | null | undefined>,\n): { fresh: Record<string, unknown>; persisted: Record<string, unknown> } {\n const outFresh: Record<string, unknown> = { ...fresh };\n const outPersisted: Record<string, unknown> = {};\n for (const [id, p] of Object.entries(persisted)) {\n if (!hasSampleValue(p)) continue;\n if (fresh[id] === undefined || persistedIsNewer(p, freshAt?.[id])) {\n delete outFresh[id];\n outPersisted[id] = p.sample;\n }\n }\n return { fresh: outFresh, persisted: outPersisted };\n}\n","/**\n * Which app meta (name/icon/brand) a connection renders with. PURE and free of\n * runtime imports so `node --test` can load it.\n *\n * The server inlines `app` on each connection summary. Three states:\n * - an object -> render from it; no lookup.\n * - `null` -> the server found no app row; render the `appId` fallback and\n * never look it up (a lookup would only miss again).\n * - `undefined`-> an older server that does not inline it; use the by-id record\n * the apps provider resolved.\n */\n\n/** The display fields every renderer of a connection's app reads. */\nexport interface InlineAppMeta {\n displayName?: string;\n iconSvg?: string;\n iconSvgDark?: string;\n brandColor?: string;\n brandColorDark?: string;\n}\n\ninterface ConnectionLike {\n appId: string;\n app?: InlineAppMeta | null;\n}\n\n/** The meta to render a connection with, or `undefined` for the `appId` fallback. */\nexport function resolveConnectionAppMeta<A extends InlineAppMeta>(\n connection: ConnectionLike,\n byId: ReadonlyMap<string, A>,\n): InlineAppMeta | undefined {\n if (connection.app) return connection.app;\n if (connection.app === null) return undefined;\n return byId.get(connection.appId);\n}\n\n/**\n * The app ids to look up by id: the unique `appId`s, first-seen order, of the\n * connections whose `app` is `undefined`. Rows with an object or `null` are\n * excluded.\n */\nexport function connectionAppIdsToLookUp(connections: readonly ConnectionLike[]): string[] {\n const seen = new Set<string>();\n for (const c of connections) {\n if (c.app === undefined) seen.add(c.appId);\n }\n return [...seen];\n}\n"],"names":["LABEL_OVERRIDES","categoryLabel","slug","known","word","deriveCategories","apps","counts","app","count","a","b","matchesCategories","selected","cats","edgeVisuals","when","runState","lane","runClass","ERROR_SOURCE_HANDLE","EACH_SOURCE_HANDLE","FOREACH_DONE_ROUTE","FOREACH_EACH_ROUTE","sourceHandleForLane","laneForSourceHandle","handleId","INTERNAL_APP_PREFIX","CONTROL_APP","SCRIPT_APP","DATA_APP","TRIGGER_APP","HTTP_APP","WEBHOOK_APP","SCHEDULER_APP","RESPOND_APP","CALL_APP","DOCUMENT_APP","MODEL_APP","TEMPLATE_APP","REGEX_APP","STORE_APP","STOP_APP","ROUTER_APP","RACE_APP","RACE_DESCRIPTION","routesForStep","step","_a","r","routeHandle","id","routeFromHandle","handle","ROUTER_PORTS_AT_BASE_HEIGHT","ROUTER_PORT_STEP","routerPortLayout","routes","fallback","port","side","IF_FALSE_ROUTE","isIfStep","ifPortLayout","isInternalApp","isControlApp","isTriggerApp","isTriggerStep","uses","DEFAULT_NODE_PORTS","portCount","v","resolvePorts","layers","inn","out","l","nodePortsForStep","lookup","action","appTriggerPorts","internalNodeDef","ICON_TRIGGER","ICON_IF","ICON_FOREACH","ICON_PARALLEL","ICON_WAIT","ICON_SCHEDULER","ICON_SCRIPT","ICON_DATA","ICON_HTTP","ICON_WEBHOOK","ICON_RESPOND","ICON_AGGREGATE","ICON_CALL","ICON_DOCUMENT","ICON_MODEL","ICON_TEMPLATE","ICON_STORE","REGEX_NODES","INTERNAL_NODES","internalNodeLabel","internalNodeIcon","internalNodeParams","internalNodeDefaults","p","sameAppsPageQuery","initialAppsPageState","query","generation","dedupeAppend","existing","incoming","seen","added","appsPageReducer","state","nonAdvancing","hasMore","excludeInternalApps","nextIdBatch","ids","requested","batchSize","batch","mergeResolvedApps","resolved","ProvidedThemeCtx","createContext","detectTheme","explicit","provided","attr","useEffectiveTheme","useContext","mode","setMode","useState","useEffect","update","mql","observer","AppIcon","src","srcDark","brandColor","name","size","theme","displaySrc","brokenSrc","setBrokenSrc","jsx","initials","s","Ctx","W6WUIProvider","api","children","content","useW6WApi","useOptionalW6WApi","WorkflowProjectCtx","WorkflowIdCtx","WorkflowProjectProvider","project","workflowId","useWorkflowProject","useWorkflowId","CHIP_VISIBLE_BUDGET","DEFAULT_PAGE_LIMIT","SEARCH_DEBOUNCE_MS","modelProviderOf","provider","bridgeSupportChip","entry","reason","AppPicker","onSelectApp","filter","searchPlaceholder","emptyMessage","search","searchValue","onSearchChange","emptyAction","providedApps","categoryFilter","providerFilter","bridgeSupport","category","hasTriggers","pageLimit","loadPage","supplied","idsKey","paged","loadPageRef","useRef","fetchedApps","setFetchedApps","legacyError","setLegacyError","listApps","canceled","e","pageState","dispatch","useReducer","localQuery","setLocalQuery","inputValue","setInputValue","value","debouncedQuery","setDebouncedQuery","generationRef","abortRef","fetchPage","useCallback","cursor","custom","listAppsPage","controller","request","page","code","next","t","loadMore","retry","selectedCats","setSelectedCats","catsExpanded","setCatsExpanded","onlyProviders","setOnlyProviders","host","body","rawApps","fatalError","loadingMore","pageError","pagedInitialLoading","connectable","base","jsxs","chips","withinBudget","pinnedOverflow","c","collapsedChips","hiddenChipCount","displayedChips","toggleCat","prev","clearCats","designatedCount","providerToggleVisible","providerActive","providerFiltered","catFiltered","sorted","q","searchActive","visible","clientFilterDroppedCards","filtersEmpty","onlyProviderFilterActive","clearAllFilters","Fragment","bridgeEntry","bridge","ALLOWED_PROTOCOLS","safeUrl","url","DISALLOWED_ELEMENTS","SafeLink","_node","href","rest","splitFrontmatter","text","m","Frontmatter","yaml","Markdown","className","frontmatter","ReactMarkdown","HEADING","BOLD","renderEditable","root","doc","raw","block","at","strong","weight","el","w","runText","runs","merged","last","bold","core","lead","trail","editableToMarkdown","lines","cur","open","level","walk","node","tag","heading","lvl","child","noteDisplayMarkdown","SECTIONS_Z_INDEX","NOTES_Z_INDEX","NOTE_TOOLBAR_Z_INDEX","NOTE_COLORS","TEXT_SIZES","MIN_W","MIN_H","TOOLBAR_GAP","LABEL_GAP","stop","selectAll","sel","range","caretToEnd","Layers","canvas","viewport","readOnly","zoom","onChange","onSectionDrop","onRequestDelete","live","setLive","selectedNote","setSelectedNote","selectedSection","setSelectedSection","editingNote","setEditingNote","menu","setMenu","drag","editor","pendingFormat","inside","onDown","active","_b","editable","sections","notes","geoOf","boxStyle","g","patchNote","patch","n","patchSection","commitNote","note","md","selectNote","selectSection","startEdit","then","editorRef","format","command","arg","run","frame","d","begin","kind","move","ev","up","_gone","geo","cls","noInteract","toolbarNote","toolbarSection","z","toolbarStyle","aboveFrame","gap","colorMenu","current","label","testid","pick","keepFocus","createPortal","editing","Icon","FlowResolved","props","useStore","CanvasLayer","EDITOR_THEME_SPEC","scriptCompletions","worker","nextId","destroyed","pending","finish","resolve","source","context","event","options","javascriptLanguage","ViewPlugin","languageExtension","language","javascript","python","CodeEditor","extensions","useMemo","EditorView","CodeMirror","lintJsonUnlessEmpty","parse","jsonParseLinter","view","JsonEditor","copied","copy","useCopyToClipboard","json","linter","lintGutter","handleChange","parsed","_c","_d","CheckGlyph","CopyGlyph","shouldUseCombobox","optionHeight","viewportHeight","filterOptions","o","DEFAULT_LIST_MAX_HEIGHT","DETAIL_STYLE","LIST_STYLE","Combobox","placeholder","disabled","ariaLabel","forceSelection","listMaxHeight","onInputChange","emptyText","footer","useBox","useId","selectedLabel","setText","setOpen","filtering","setFiltering","setActive","rootRef","shown","listStyle","optId","i","close","onKeyDown","onBlur","isFormResolvedOptions","isExprValue","isSecretValue","toWirePart","partsToValue","parts","cleaned","trailingBackslashCount","serializeTemplate","RUN_SCOPE_ROOTS","isRunScopeRoot","segment","STATE_ROOTS","stateAliasSpellings","ref","firstSegment","parseRootAnchoredTemplate","parseTemplate","EDIT_ESCAPE","isOurPart","hasRefusedChainToken","refs","coalesceOperandRefs","RESOLVE_ESCAPE","holdsExpression","parseResolvableText","unescapeText","valueToParts","renderResult","samples","hit","VAR_PREFIX","LEGACY_VARS_PREFIX","DOCUMENTS_PREFIX","CONST_PREFIX","STATE_PREFIX","canonicalRef","stateSpellingRank","rawRef","stateSampleValue","tree","key","buildResolveScope","sampleValues","testStartState","config","meta","stateSamples","documents","constants","rank","branch","vars","steps","sv","hasItem","hasIndex","seeded","foreach","walkPath","path","part","CONFIG_REF","META_REF","withConfig","nodes","resolveRef","scope","k","walked","metaOf","resolvePart","isDollarPath","isDollarExpr","resolveParamValue","deepEqual","aArr","bArr","arrA","arrB","objA","objB","keysA","keysB","foldOne","seg","foldOneAsText","foldResolvedSegments","segments","resolveParamJson","resolveVarsJson","rows","row","IconButton","forwardRef","icon","iconSize","title","onClick","danger","glyph","SIZE_CLASS","Modal","onClose","titleIcon","subtitle","headerRight","onCancel","ROOTS","OPERATOR","hasOperator","hasComparisonRefs","expr","expressionReferences","resolveAuthorRef","first","candidates","compileAuthoredParts","original","unchanged","marker","readable","formatReadableExpression","wrapped","start","knownStart","operand","_e","after","parseReadableExpression","error","authoredReferences","canonical","sampleRoot","keys","target","previous","previewAuthoredParts","seeds","overrides","textSamples","evaluate","STEP_OUTPUT_REF","STEP_META_REF","varLabel","chainOperandVarRef","chainLabel","chain","token","UNREACHABLE_KEY_CHARS","isRefSafeKey","isRefSafePath","outputFieldTree","fields","paths","f","field","segs","depth","cut","makeChip","renderToggle","span","sigil","parseCoalesceChain","toggle","toggleLabel","x","BLOCK_TAGS","chipToPart","readParts","pushText","lastInBlock","isBlock","walkChildren","parent","isBlockParent","isFillerBreak","fillBlock","caretBlock","ensureFillerBreak","isMultilineHost","paintParts","opts","placeCaretAtEnd","insertNodeAtCaret","promoteCompletedMarkerAtCaret","offset","openIdx","slashes","markerRange","chip","chipToText","insideJsonString","pos","inString","ch","keyForRef","openerBefore","stack","top","freeKey","obj","addRefToDraft","literal","literalJson","quoted","insert","ok","prop","before","opener","sep","head","empty","item","indent","BARE_REF","bareRefBinding","wholeValueRef","sampleStepsState","resolveComposed","resolveLeaf","ExpressionEditorModal","masked","multiline","fieldLabel","onSave","jsonValue","onSaveJson","wholeField","startingStateProp","jsonProblem","jsonBinding","seedMode","insertAs","setInsertAs","jsonText","setJsonText","jsonView","jsonTouched","jsonParsed","seedProblem","canSaveJson","sampleScope","insertJsonRef","whole","emptyContainer","setParts","authored","paintGen","setPaintGen","focusChipsAfterPaint","setSamples","adding","setAdding","expanded","setExpanded","toggleExpanded","openPick","setOpenPick","useLayoutEffect","sync","insertPart","hasRenderPart","adoptText","restoreFocus","save","closeAdding","secrets","inputs","nodeConfigs","loop","configKeys","nodeMeta","metaLeavesOf","META_LEAVES","APP_META_KEYS","isExternalAppNode","upstreamAppIds","st","metaSources","metaIds","hasWorkflowState","hasState","stateFields","openSection","sectionProps","loopFields","eventFields","template","effectiveSamples","usedRefs","result","resultNotes","tier","_composite","loopOpen","currentItemBtn","configEntry","fieldSources","stepId","shapeHint","from","metaNode","hint","RailSection","FieldsToggle","stepKey","isOpen","wholeBtn","docKey","leaf","nextKind","Copyable","AddValueModal","onToggle","testId","bodyId","bodyRef","onCreate","setName","setValue","description","setDescription","setError","setPending","noun","submit","excludeSelfStep","selfId","ExpressionOptionsCtx","ExpressionOptionsProvider","inherited","useExpressionOptions","ExpressionInput","setState","sealed","sealing","setSealing","modalOpen","setModalOpen","wantFocus","wrapperRef","ctxOptions","sealSecret","syncFromDom","sealPlain","env","onLeave","adopt","MARKER","findCodeBindings","literals","comments","two","three","nl","end","j","lit","REF","STEP","codeReadFor","namespace","convertCodeBindingsToReads","converted","left","read","ctx","atStart","atEnd","piece","ScriptCodeField","param","req","pickerOpen","setPickerOpen","exprOptions","insertPicked","picked","examples","width","comment","what","flat","list","isUnresolvedValue","allowCustomOf","dynamicParams","params","refreshOnOf","splitForm","values","form","unresolved","planRequests","changed","bad","on","cacheKey","isCacheable","fieldsOverlap","noFetchReason","reconcileValue","useDynamicFields","dynamic","remote","setRemote","latest","cache","inflight","only","ps","call","vs","plan","byKey","cleared","cached","appLabel","apply","flush","done","res","msg","ctxKey","snaps","commit","focus","blur","now","why","rec","isParamVisible","getValue","matchesParamCondition","flattenParams","renderFieldRows","renderOne","rowId","group","makeRenderOne","set","effective","SectionField","RepeatField","GroupField","ParamField","DynamicFieldsCtx","ParamsForm","dyn","effectiveParam","main","additional","PYTHON_CODE_DEFAULT","LEGACY_CODE_DEFAULTS","visibleChildren","ARRAY_ITEM_SCALAR_TYPES","fitsArrayItemFields","groupValue","groupSet","flatChildren","groupEffective","local","groupRenderOne","JsonParamField","synthesized","ArrayField","ParamFieldBody","rawOnChange","listModelRoutes","listDataStores","listDataStoreEntries","workflowProject","dynState","controlId","FxField","siblingLanguage","fallbackDefault","ModelRouteField","StoreField","storeName","StoreKeyField","VarsField","MultiSelectField","ChoiceField","unsetLabel","isNumber","inputType","display","setRoutes","stores","setStores","STORE_KEY_PAGE","STORE_KEY_DEBOUNCE_MS","PREVIEW_CHARS","storeEntryDetail","store","setQuery","setPage","loading","setLoading","ctrl","prefix","timer","typed","bare","variant","fx","inline","headerActions","onValidityChange","boundRef","bound","seed","invalid","setInvalid","upstream","onEdit","onValid","onValidity","valid","commitBareRef","binding","clear","restored","csv","selectedKeys","available","labelFor","add","opt","remove","option","ArrayItemInput","ph","isObject","items","blank","patchAt","idx","it","fv","_","DATA_VAR_TYPES","EMPTY_DATA_VARS","dataVarRows","old","type","dataVarsJson","coerceVarValue","varValueToText","previousRows","invalidJson","setInvalidJson","jsonError","setJsonError","jsonMode","_key","object","CONDITION_OPERATORS","CONDITION_OPERATOR_HINTS","operators","op","operatorLabels","conditionOperatorLabel","CONDITION_COMBINATORS","combinatorLabels","conditionCombinatorLabel","combinator","comparisonOf","logic","allowNegation","entries","operator","args","inner","readComparison","readConditionGroup","single","writeConditionGroup","comparison","conditionOperandValue","operands","conditionOperandText","EMPTY_ROW","EMPTY_GROUP","same","ConditionEditor","purpose","condition","advanced","setAdvanced","draft","setDraft","nextKey","setKeys","simple","rowKeys","emit","nextKeys","changeRow","index","addRow","removeRow","multiple","booleanCheck","HELPER_TEXT","RetryPolicyFields","retryOn","attempts","delayMs","backoff","setRetry","NodeConfigForm","hasGraph","failureHandling","retryControls","reroute","onError","hasParamCustomization","customizedParamValues","previewCustomization","literalKeys","ParamCustomization","_customization","parseJsonFields","AuthFieldsForm","enterSubmitProps","edit","isSecret","CredentialPicker","credentials","onModeChange","selectedId","onSelect","canUseExisting","contract","bindingFieldsFor","sa","others","buildBinding","settings","POPUP_FEATURES","startOAuthPopup","authorizationUrl","reject","popup","cleanup","onMessage","pollHandle","data","NON_TEXT_INPUT_TYPES","isWithinContentEditable","useEnterSubmit","onSubmit","AddConnectionModal","selectedApp","setSelectedApp","resolvingInitial","setResolvingInitial","listAppsByIds","ConnectionConfig","onCreated","auths","setAuths","authKey","setAuthKey","displayName","setDisplayName","credential","setCredential","stored","setStored","pickedMode","setPickedMode","setSelectedId","credName","setCredName","bindingVals","setBindingVals","createdId","auth","isOAuth","listCredentials","createCredential","credentialStep","usable","chosenId","bindingFields","isZeroCred","requiredMissing","submitDisabled","connectionId","credentialId","made","conn","enterSubmit","DeleteButton","RouterEditor","conditions","dragged","setDragged","dropTarget","setDropTarget","renaming","setRenaming","draftName","setDraftName","to","route","rename","StepNameEditor","onCommit","err","StopEditor","conditional","HTML_PREVIEW_CSP","htmlPreviewSrcDoc","html","HtmlPreview","kindOf","scalarText","isContainer","countLabel","isArray","JsonTree","expandDepth","JsonNode","container","RESULT_RENDER_MAX_CHARS","MD_HEADING","MD_FENCE","MD_LIST_ITEM","MD_LINK","detectResultFormat","resultCopyText","RESULT_HIGHLIGHT_MAX_CHARS","renderSource","CodeBlock","ResultViewer","maxHeight","setExpandDepth","treeEpoch","setTreeEpoch","renderable","overLimit","copyText","bar","pickWebhookSubscription","subs","hooks","SECRET_HEADER_RE","MASK","displayHeaders","headers","POLL_WAIT_S","WebhookListenPanel","stepWith","onUse","using","sub","setSub","creating","setCreating","setNow","halt","createUrl","create","created","listen","poll","opened","abort","mine","formatLeft","CapturedRequest","receivedAt","hasQuery","asFieldDefs","fieldWidget","coerceDefault","fieldsToParams","defs","seedValues","findTestInput","nodeId","input","isBinding","rememberableInput","secretKeys","inFlightSaves","trackTestInputSave","settled","testInputSavesSettled","useRememberedTestInput","supported","loaded","setLoaded","setInput","write","LastUsedNote","onClear","EDIT_SAVE_DEBOUNCE_MS","TriggerFillForm","persist","hasFields","setValues","persistWorkflowId","persistStepId","remembered","prefilled","setPrefilled","manualOpen","setManualOpen","setSeeded","tests","formKey","setFormKey","clearRemembered","saveTimer","pendingSave","flushSave","editValues","draftValid","setDraftValid","canRun","requiredParamsFilled","override","outcome","saved","logs","useCaptured","payload","listenPanel","manualEntry","resultBlock","PropertyEntryForm","units","durationPattern","WaitEditor","duration","lastUnit","setLastUnit","setTarget","AnchoredFlyout","anchorRef","popRef","setPos","setContainer","onDocPointerDown","ka","kb","applyStepProblems","problems","_drop","INVALID_LOOP_TEXT","stepProblemTooltip","isConnectionBlocked","connectionButtonLabel","connection","conns","failed","found","editConnectionResources","connections","renamed","replaced","resource","withConnectionRef","_removed","connectionIdFor","connectionRef","nextWorkflowConnectionName","appId","centralizeConnections","workflow","_connection","selectNodeConnection","_id","_ref","shared","connectionUsers","defaultConnectionFor","choices","initialConnection","sameApp","withDefaultConnection","replaceWorkflowConnection","WorkflowConnectionsContext","useWorkflowConnections","WorkflowConnectionPicker","onOpenChange","onChangeConnection","onChangeConnectionRef","onConnectionCreated","currentId","peers","portalHost","all","choose","users","defaultKeyOf","ApiCallsPanel","calls","defaultOpen","keyOf","EventbriteTriggerPicker","InternalIcon","eventbriteTriggerChoices","triggers","triggerKey","activity","actions","fixed","isForeachStep","isControlStep","isLoopBodyStep","controlOwnedIds","collect","ownedStepIds","owned","eachLaneEdge","fromIsForeach","flowEdgeId","routeOf","loopBody","foreachId","edges","claimed","exists","each","edgeLane","queue","order","internal","indeg","bodyInternalEdges","isPlainBody","outs","loopBodyDefinitionEdges","loopBodies","loopMembership","fid","bridgeDeletedBodyStep","incident","plain","nid","inBody","ins","stripBody","_body","loopRefusal","M","stepOf","owner","branches","reaches","LOOP_REFUSAL_MESSAGES","loopRefusalMessage","stampLoopOf","want","deleteStepMessage","effectiveEdges","wf","isSuccess","isEachLink","definitionLoops","byId","owners","declared","literalBody","legacyBody","own","bodyEdges","succ","inbound","outbound","collidingEdgeId","survivors","canConnect","srcStep","tgtStep","srcPorts","tgtPorts","planConnect","drawnRoute","fromForeach","srcIsIf","effLane","loopReason","fromSrc","cap","sourceHandle","addEdge","applyConnect","connectConflict","connectRefusal","planRelane","edgeId","matches","me","visuals","_route","unrouted","relaned","conflict","setEdgeWhen","edgeWhenConflict","relaneRefusal","renameStepInEdges","prevId","stepIdError","stepNameError","taken","other","idClashMessage","involved","laneOf","drawn","sitting","sameLane","mixedLane","successTarget","culprit","cause","COLUMN_WIDTH","ROW_HEIGHT","MARGIN_X","MARGIN_Y","slotPosition","col","computeLayers","layer","maxPasses","passes","preds","max","lastColumn","computePositions","fromCol","toCol","siblings","positions","storedPosition","normalizeInput","_s","workflowToFlow","eachEdges","loopOf","legacyFoes","drop","foreachIds","isInternal","ifIds","flowEdges","relayoutNodes","flowToWorkflow","originalInput","savePosition","nodeById","withPosition","stepById","derived","originalLoops","originalById","successFrom","withBody","orig","emitted","nextSteps","bodyIds","plainEdges","eachLinks","nextEdges","storedViewport","withViewport","vp","slugifyLabel","findChainRoot","hasIncoming","findChainTail","hasOutgoing","suggestStepId","stepToJson","MAX_DEPTH","MAX_FIELDS","isPlainObject","declaredOutputFields","output","il","declaredItemFields","inferOutputFields","valueAtPath","resolveOutputShape","fresh","persisted","freshFields","realFields","have","fromSample","ancestorIds","rootId","parents","arr","ancestors","projectStepSources","shapes","hasTrigger","eventShape","isTrigger","testOutput","persistedOutput","shape","isManualTrigger","_f","real","_g","resolveLoopItems","testOutputs","resolveLoopItemsInState","FOREACH_TEST_SAMPLE_MAX","foreachTestFixture","foreachTestSample","test","loopAwareSources","ownLoop","membership","projected","bodies","extra","lastStep","outputRefParts","declaredLoopItems","def","sampled","itemOutputs","loopSourceFor","outputs","upstreamStateSources","editingId","draftId","anchor","stepBuilderUpstreamSteps","pendingConnect","builderOwnLoop","stepBuilderLoop","fetchSeedSources","listStepTests","upstreamSteps","startStateFromSeeds","hasOutput","hasSteps","loopSeedFromSource","loopItemText","parseLoopSeed","itemText","indexText","stepMetaSampleValues","upstreamSampleValues","testMetas","tiers","collectSampleValues","upstreamSampleValueSources","declaredSamples","u","sources","put","isDynamicValue","nodeConfigSources","staticValue","nodeConfigValues","subscriptionFor","nodeMetaValues","version","nodeMetaSampleValues","useSeedSources","enabled","seedSources","setSeedSources","CALLABLE_FAMILIES","CALLABLE_GLYPH","CONFIG_VIEW_GLYPHS","ALL_CONFIG_VIEWS","ConfigViewToggle","views","customized","btn","StepBuilderModal","onAdd","onDraftChange","appsOnly","callables","initialTab","initialApp","initialAction","initialWith","appsFilter","appsIds","connectionOnly","onConnected","excludeCallableIds","onOpenStep","stepIds","mintedId","setMintedId","stepName","setStepName","lastBuilt","trackAdd","trackDraft","titled","tab","setTab","selectedNode","setSelectedNode","selectedTriggerApp","setSelectedTriggerApp","selectedCallable","setSelectedCallable","hasAppsIds","readyToUse","useReadyToUse","homeAvailable","CallableStepConfig","ControlStepConfig","pickedApp","changeApp","AppConnectionOnlyConfig","AppStepConfig","ReadyToUseFlow","CallableList","TriggersFlow","ControlsFlow","DataFlow","UtilitiesFlow","matchesPickerQuery","matchesNodeQuery","NodeList","NodeRow","searching","setSearching","leftRows","byLabel","AppRow","leftBody","initialNode","onDone","setNode","candidate","withValues","setWithValues","testable","configView","setConfigView","codeText","setCodeText","draftConfig","setDraftConfig","configComplete","committedId","setCommittedId","buildStep","changeConfigView","defaults","StepTestRun","family","excludeIds","setItems","callableLabel","withoutIds","CallableRow","TRIGGER_FIELD_TYPES","triggerFieldsOf","targetId","targetLabel","setFields","fieldsError","setFieldsError","setInputs","wait","setWait","CallableTestRun","expressionDefaults","effectiveValues","check","vals","eff","scoped","groupVals","rowVals","isTestRequired","surface","flag","errorBodyOf","apiCallsIn","TestRunLogModal","log","hideRunButton","startState","onBusyChange","onResult","setLog","logOpen","setLogOpen","ranRef","restoredAt","setRestoredAt","staticMeta","startedAt","finishLog","response","useImperativeHandle","READY_TO_USE_ID_BATCH","EMPTY_ID_SET","idSet","allowed","connectedIds","setConnectedIds","allApps","setAllApps","fnsRaw","setFns","wfsRaw","setWfs","setResolved","requestedIds","setRequestedIds","inFlightIds","setInFlightIds","inFlightRef","setInFlight","inlineIdsRef","wantFns","wantWfs","bounded","fail","mountedRef","resolveBatch","firstBatchStartedRef","loadMoreApps","exclude","fns","wfs","moreApps","connectedSet","dn","readyToUseColumn","onSelectCallable","column","right","cols","getTriggerDefs","ts","AppTriggerTestNote","onChangeApp","aNoun","setConns","setActions","metaError","setMetaError","accountId","setAccountId","setConnectionRef","connectionScope","connectionScopeRef","setConnectionId","actionKey","setActionKey","rowRef","connectionPickerOpen","setConnectionPickerOpen","pickables","au","co","ac","refetchConns","availableAuths","autoSatisfied","autoNeedsSignedInUser","needsConnection","hasConnection","selectedAction","eventChoices","sortedActions","testRequired","testPassed","setTestPassed","setupComplete","canAdd","selectedConn","showConnModal","setShowConnModal","changingConn","setChangingConn","connectionSatisfied","showConnPicker","VIEWS","isValuesMap","initialView","setView","showJson","toJsonText","validRef","emitValid","openView","ConfirmModal","message","onConfirm","confirmLabel","cancelLabel","destructive","shapeToSkeleton","indexNodeSamples","hasSampleValue","persistedIsNewer","freshAt","effectiveNodeOutput","effectiveNodeOutputs","previewNodeOutputs","splitNodeOutputs","outFresh","outPersisted","splitPreviewOutputs","resolveConnectionAppMeta","connectionAppIdsToLookUp"],"mappings":";;;;;;;;;;;;;AA4BA,MAAMA,KAAoD;AAAA,EACxD,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,QAAQ;AACV;AAaO,SAASC,GAAcC,GAAsB;AAClD,MAAI,OAAOA,KAAS,YAAYA,EAAK,KAAA,MAAW,GAAI,QAAO;AAC3D,QAAMC,IAAQH,GAAgBE,CAAI;AAClC,SAAIC,KACGD,EACJ,MAAM,SAAS,EACf,OAAO,OAAO,EACd,IAAI,CAACE,MAASA,EAAK,OAAO,CAAC,EAAE,gBAAgBA,EAAK,MAAM,CAAC,CAAC,EAC1D,KAAK,GAAG;AACb;AAoBO,SAASC,GAAiBC,GAA6C;AAC5E,QAAMC,wBAAa,IAAA;AACnB,aAAWC,KAAOF;AAChB,eAAWJ,KAAQM,EAAI,cAAc,CAAA;AACnC,MAAAD,EAAO,IAAIL,IAAOK,EAAO,IAAIL,CAAI,KAAK,KAAK,CAAC;AAGhD,SAAO,CAAC,GAAGK,EAAO,QAAA,CAAS,EACxB,IAAI,CAAC,CAACL,GAAMO,CAAK,OAAO,EAAE,MAAAP,GAAM,OAAOD,GAAcC,CAAI,GAAG,OAAAO,EAAA,EAAQ,EACpE;AAAA,IACC,CAACC,GAAGC,MACFA,EAAE,QAAQD,EAAE,SAASA,EAAE,MAAM,cAAcC,EAAE,OAAO,QAAW,EAAE,aAAa,QAAQ;AAAA,EAAA;AAE9F;AAQO,SAASC,GAAkBJ,GAAiBK,GAAsC;AACvF,MAAIA,EAAS,WAAW,EAAG,QAAO;AAClC,QAAMC,IAAON,EAAI,cAAc,CAAA;AAC/B,SAAOK,EAAS,KAAK,CAACX,MAASY,EAAK,SAASZ,CAAI,CAAC;AACpD;ACuCO,SAASa,GACdC,GACAC,GAIA;AACA,QAAMC,IACJF,MAAS,UACL,EAAE,WAAW,kBAAkB,OAAO,WAAA,IACtCA,MAAS,SACP,EAAE,WAAW,gBAAA,IACb,CAAA;AACR,MAAI,CAACC,EAAU,QAAOC;AACtB,QAAMC,IAAWF,MAAa,UAAU,mBAAmB;AAC3D,SAAO;AAAA,IACL,WAAWC,EAAK,YAAY,GAAGA,EAAK,SAAS,IAAIC,CAAQ,KAAKA;AAAA,IAC9D,GAAID,EAAK,QAAQ,EAAE,OAAOA,EAAK,MAAA,IAAU,CAAA;AAAA,EAAC;AAE9C;AAOO,MAAME,KAAsB,aAOtBC,KAAqB,YAOrBC,KAAqB,QAGrBC,KAAqB;AAgB3B,SAASC,GAAoBR,GAAkD;AACpF,SAAOA,MAAS,UAAUI,KAAsBJ,MAAS,SAASK,KAAqB;AACzF;AAWO,SAASI,GAAoBC,GAAiD;AACnF,SAAOA,MAAaN,KAChB,UACAM,MAAaL,KACX,SACA;AACR;AAuFO,MAAMM,KAAsB,SAEtBC,KAAc,gBAEdC,KAAa,eAEbC,KAAW,aAEXC,KAAc,gBAEdC,KAAW,aAEXC,KAAc,gBAEdC,KAAgB,kBAEhBC,KAAc,gBAOdC,KAAW,aAOXC,KAAe,iBAMfC,KAAY,cASZC,KAAe,iBAEfC,KAAY,cAQZC,KAAY,cAEZC,KAAW,aACXC,KAAa,eACbC,KAAW,aACXC,KACX;AASK,SAASC,GAAcC,GAA+B;;AAC3D,SAAIA,EAAK,KAAK,QAAQJ,MAAc,CAAC,MAAM,SAAQK,IAAAD,EAAK,SAAL,gBAAAC,EAAW,MAAM,IAAU,CAAA,IACvED,EAAK,KAAK,OAAO;AAAA,IACtB,CAACE,MAAwB,CAAC,CAACA,KAAK,OAAOA,KAAM,YAAY,OAAOA,EAAE,MAAO;AAAA,EAAA;AAE7E;AAEO,MAAMC,KAAc,CAACC,MAAuB,SAASA,CAAE,IACjDC,KAAkB,CAACC,MAC9BA,KAAA,QAAAA,EAAQ,WAAW,YAAYA,EAAO,MAAM,CAAC,IAAI,QAGtCC,KAA8B,GAE9BC,KAAmB;AA0BzB,SAASC,GAAiBC,GAAmC;AAClE,QAAMC,IAAWD,EAAO,KAAK,CAACR,MAAMA,EAAE,OAAO,GACvCU,IAAO,CAACV,OAAgC;AAAA,IAC5C,IAAIA,EAAE;AAAA,IACN,UAAUC,GAAYD,EAAE,EAAE;AAAA,IAC1B,OAAOA,EAAE,UAAU,aAAaA,EAAE,SAASA,EAAE;AAAA,EAAA,IAEzCW,IAAOH,EAAO,OAAO,CAACR,MAAMA,MAAMS,CAAQ;AAChD,SAAO;AAAA,IACL,OAAOE,EAAK,IAAI,CAACX,GAAG,OAAO,EAAE,GAAGU,EAAKV,CAAC,GAAG,KAAK,IAAK,IAAI,OAAOW,EAAK,SAAU,GAAG,MAAM;AAAA,IACtF,GAAIF,IAAW,EAAE,QAAQC,EAAKD,CAAQ,EAAA,IAAM,CAAA;AAAA,IAC5C,GAAIE,EAAK,SAASN,KACd,EAAE,WAAWM,EAAK,SAASL,OAC3B,CAAA;AAAA,EAAC;AAET;AAOO,MAAMM,KAAiB;AAEvB,SAASC,GAASf,GAAyB;AAChD,SAAOA,EAAK,KAAK,QAAQnB,MAAemB,EAAK,KAAK,WAAW;AAC/D;AASO,SAASgB,KAAoD;AAClE,SAAO;AAAA,IACL,OAAO,CAAC,EAAE,IAAI,QAAQ,OAAO,QAAQ,KAAK,OAAO;AAAA,IACjD,QAAQ,EAAE,IAAIF,IAAgB,UAAUX,GAAYW,EAAc,GAAG,OAAO,QAAA;AAAA,EAAQ;AAExF;AAGO,SAASG,GAAcxD,GAAsB;AAClD,SAAOA,EAAI,WAAWmB,EAAmB;AAC3C;AAGO,SAASsC,GAAazD,GAAsB;AACjD,SAAOA,MAAQoB,MAAepB,MAAQoC;AACxC;AAQO,SAASsB,GAAa1D,GAAsB;AACjD,SAAOA,MAAQuB,MAAevB,MAAQyB,MAAezB,MAAQ0B;AAC/D;AAQO,SAASiC,GAAcC,GAAgD;AAC5E,SAAOF,GAAaE,EAAK,GAAG,KAAKA,EAAK,YAAY;AACpD;AAmEO,MAAMC,KAAgC,EAAE,IAAI,GAAG,KAAK,OAAO,kBAAA;AAElE,SAASC,GAAUC,GAA8C;AAC/D,SAAIA,MAAM,SAAe,OAAO,oBACzB,OAAOA,KAAM,WAAWA,IAAI;AACrC;AAGO,SAASC,MAAgBC,GAA8C;AAC5E,MAAIC,GACAC;AACJ,aAAWC,KAAKH;AACd,IAAAC,UAAQJ,GAAUM,KAAA,gBAAAA,EAAG,EAAE,IACvBD,UAAQL,GAAUM,KAAA,gBAAAA,EAAG,GAAG;AAE1B,SAAO,EAAE,IAAIF,KAAOL,GAAmB,IAAI,KAAKM,KAAON,GAAmB,IAAA;AAC5E;AAkBO,SAASQ,GAAiB9B,GAAgB+B,GAAiC;;AAChF,MAAI/B,EAAK,KAAK,QAAQJ,GAAY,QAAO,EAAE,IAAI,GAAG,KAAKG,GAAcC,CAAI,EAAE,OAAA;AAC3E,QAAM,EAAE,KAAAvC,GAAK,QAAAuE,EAAA,IAAWhC,EAAK,MAEvBiC,IAAyCjC,EAAK,KAAK,UAAU,EAAE,IAAI,GAAG,KAAK,EAAA,IAAM;AACvF,SAAOyB;AAAA,IACLzB,EAAK;AAAA,IACL+B,KAAA,gBAAAA,EAAStE,GAAKuE;AAAA,MACd/B,IAAAiC,GAAgBzE,GAAKuE,CAAM,MAA3B,gBAAA/B,EAA8B,UAASgC;AAAA,EAAA;AAE3C;AAKA,MAAME,KAAe,+DAEfC,KACJ,uIAEIC,KACJ,sJAEIC,KACJ,uHAEIC,KAAY,0EAEZC,KACJ,8MAGIC,KAAc,6EAEdC,KACJ,0IAEIC,KACJ,mLAEIC,KACJ,uMAEIC,KAAe,6EAEfC,KAAiB,oEAEjBC,KACJ,oJAEIC,KACJ,+NAEIC,KACJ,+YAEIC,KACJ,wKAGIC,KACJ,8IAGIC,KAAiC;AAAA,EACrC;AAAA,IACE,KAAK3D;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,QAAQ,EAAE,WAAW,GAAA;AAAA,QACrB,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,QAAQ;AAAA,MACN,EAAE,KAAK,SAAS,OAAO,kBAAA;AAAA,MACvB;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,MAAA;AAAA,MAET;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,MAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKA;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,QAAQ,EAAE,WAAW,GAAA;AAAA,QACrB,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,MAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKA;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,QAAQ,EAAE,WAAW,GAAA;AAAA,QACrB,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,QAAQ,EAAE,WAAW,GAAA;AAAA,QACrB,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,MAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKA;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,cAAc;AAAA,IACd,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,QAAQ,EAAE,WAAW,GAAA;AAAA,QACrB,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,MAAA;AAAA,IACT;AAAA,EACF;AAEJ,GAGa4D,KAAoC;AAAA,EAC/C,GAAGD;AAAA,EACH;AAAA,IACE,KAAKvD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,QAAQ,KAAK,EAAA;AAAA,IAC1B,QAAQ,CAAA;AAAA,EAAC;AAAA,EAEX;AAAA,IACE,KAAKD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMwC;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS;AAAA,UACP,EAAE,IAAI,WAAW,OAAO,WAAW,WAAW,GAAA;AAAA,UAC9C,EAAE,IAAI,WAAW,OAAO,WAAW,SAAS,GAAA;AAAA,QAAK;AAAA,MACnD;AAAA,IACF;AAAA,IAEF,QAAQ,CAAC,EAAE,KAAK,SAAS,OAAO,kBAAkB;AAAA,EAAA;AAAA,EAEpD;AAAA,IACE,KAAKzC;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,QAAQ,CAAC,EAAE,KAAK,WAAW,OAAO,WAAW;AAAA,EAAA;AAAA,EAE/C;AAAA,IACE,KAAKX;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMmD;AAAA,IACN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,CAAA;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,EAAE,KAAK,OAAO,OAAO,OAAO,MAAM,UAAU,aAAa,aAAA;AAAA,YACzD;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,cACN,SAAS;AAAA,cACT,SAAS;AAAA,gBACP,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,gBAC1B,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,gBAC1B,EAAE,OAAO,WAAW,OAAO,UAAA;AAAA,gBAC3B,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,cAAO;AAAA,YACjC;AAAA,YAEF,EAAE,KAAK,WAAW,OAAO,WAAW,MAAM,UAAU,aAAa,WAAA;AAAA,YACjE,EAAE,KAAK,YAAY,OAAO,YAAY,MAAM,WAAW,SAAS,GAAA;AAAA,UAAM;AAAA,QACxE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKjD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM0D;AAAA,IACN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,CAAC,MAAM;AAAA,QAChB,MAAM;AAAA,QACN,SAAS;AAAA,UACP,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,UACvB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,UACxB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,UACvB,EAAE,OAAO,SAAS,OAAO,QAAA;AAAA,UACzB,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,UAC1B,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,QAAO;AAAA,MACjC;AAAA,MAEF;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,QACN,SAAS;AAAA,UACP,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,UACxB,EAAE,OAAO,SAAS,OAAO,aAAA;AAAA,UACzB,EAAE,OAAO,UAAU,OAAO,cAAA;AAAA,UAC1B,EAAE,OAAO,OAAO,OAAO,aAAA;AAAA,QAAa;AAAA,MACtC;AAAA,MAEF;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,QACL,QAAQ,EAAE,OAAO,QAAQ,QAAQ,QAAA;AAAA,MAAQ;AAAA,MAE3C;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,QACL,QAAQ,EAAE,OAAO,QAAQ,QAAQ,QAAA;AAAA,MAAQ;AAAA,MAE3C;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,QACL,aAAa;AAAA,QACb,QAAQ,EAAE,OAAO,QAAQ,QAAQ,SAAA;AAAA,MAAS;AAAA,MAE5C;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,QACL,QAAQ,EAAE,OAAO,QAAQ,QAAQ,SAAA;AAAA,MAAS;AAAA,MAE5C;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,QAAQ,EAAE,OAAO,QAAQ,QAAQ,MAAA;AAAA,MAAM;AAAA,MAEzC;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,QACN,SAAS;AAAA,UACP,EAAE,OAAO,cAAc,OAAO,qBAAA;AAAA,UAC9B,EAAE,OAAO,YAAY,OAAO,wBAAA;AAAA,UAC5B,EAAE,OAAO,gBAAgB,OAAO,wBAAA;AAAA,UAChC,EAAE,OAAO,aAAa,OAAO,YAAA;AAAA,QAAY;AAAA,MAC3C;AAAA,MAEF;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,QAAQ,EAAE,OAAO,gBAAgB,OAAO,CAAC,cAAc,EAAA;AAAA,MAAE;AAAA,MAE3D;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ,EAAE,OAAO,gBAAgB,QAAQ,aAAA;AAAA,MAAa;AAAA,MAExD,EAAE,KAAK,WAAW,OAAO,YAAY,MAAM,WAAW,SAAS,IAAO,UAAU,GAAA;AAAA,MAChF,EAAE,KAAK,cAAc,OAAO,eAAe,MAAM,WAAW,SAAS,IAAO,UAAU,GAAA;AAAA,MACtF;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM,EAAE,MAAM,UAAU,aAAa,mBAAA;AAAA,QACrC,MAAM;AAAA,MAAA;AAAA,MAER,EAAE,KAAK,sBAAsB,OAAO,qBAAqB,MAAM,UAAU,UAAU,GAAA;AAAA,MACnF,EAAE,KAAK,QAAQ,OAAO,uBAAuB,MAAM,UAAU,UAAU,GAAA;AAAA,MACvE;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,CAAA;AAAA,QACT,UAAU;AAAA,QACV,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,EAAE,KAAK,QAAQ,OAAO,QAAQ,MAAM,SAAA;AAAA,YACpC,EAAE,KAAK,SAAS,OAAO,SAAS,MAAM,SAAA;AAAA,UAAS;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMqD;AAAA;AAAA,IAEN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,QACN,SAAS;AAAA,UACP,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,UACxB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,UACxB,EAAE,OAAO,YAAY,OAAO,WAAA;AAAA,QAAW;AAAA,MACzC;AAAA,MAEF;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,aAAa;AAAA,QACb,QAAQ,EAAE,OAAO,QAAQ,QAAQ,OAAA;AAAA,MAAO;AAAA,MAE1C;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,aAAa;AAAA,QACb,QAAQ,EAAE,OAAO,QAAQ,QAAQ,OAAA;AAAA,MAAO;AAAA,MAE1C;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,QAAQ,EAAE,OAAO,QAAQ,QAAQ,WAAA;AAAA,MAAW;AAAA,MAE9C;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,UAAU;AAAA,MAAA;AAAA,IACZ;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAK3D;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMuD;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKvD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMwD;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,OAAO;AAAA,QACP,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKxD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMyD;AAAA,IACN,QAAQ,CAAA;AAAA,EAAC;AAAA,EAEX;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM0D;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM2D;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,UACP,EAAE,OAAO,cAAc,OAAO,aAAA;AAAA,UAC9B,EAAE,OAAO,cAAc,OAAO,aAAA;AAAA,UAC9B,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,QAAS;AAAA,QAErC,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,aAAa;AAAA,QACb,SAAS;AAAA;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA;AAAA,QAEE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,OAAO;AAAA,QACP,aAAa;AAAA,QACb,UAAU;AAAA,UACR;AAAA,YACE,KAAK;AAAA,YACL,MAAM;AAAA,YACN,OAAO;AAAA,YACP,OAAO;AAAA,YACP,MAAM;AAAA,UAAA;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKjD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM0D;AAAA;AAAA;AAAA;AAAA,IAIN,QAAQ,CAAC,EAAE,KAAK,UAAU;AAAA,IAC1B,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,OAAO;AAAA,QACP,MACE;AAAA,MAAA;AAAA,MAIJ;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS,CAAA;AAAA,QACT,MACE;AAAA,MAAA;AAAA,IAEJ;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKnE;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM2D;AAAA,IACN,QAAQ;AAAA,MACN;AAAA;AAAA;AAAA;AAAA,QAIE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,SAAS,CAAA;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAK3D;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM2D;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,OAAO;AAAA,QACP,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,SAAS,CAAA;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM0D;AAAA;AAAA;AAAA,IAGN,QAAQ;AAAA,MACN,EAAE,KAAK,SAAA;AAAA,MACP,EAAE,KAAK,aAAA;AAAA,MACP,EAAE,KAAK,KAAA;AAAA,MACP,EAAE,KAAK,UAAA;AAAA,MACP,EAAE,KAAK,OAAA;AAAA,IAAO;AAAA,IAEhB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,SAAS;AAAA,QACT,SAAS;AAAA,UACP,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,UACvB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,UACxB,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,UACvB,EAAE,OAAO,SAAS,OAAO,QAAA;AAAA,UACzB,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,QAAS;AAAA,QAErC,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS,CAAA;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS,CAAA;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKvD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMyD;AAAA,IACN,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,QACN,SAAS;AAAA,UACP,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,UACxB,EAAE,OAAO,QAAQ,OAAO,OAAA;AAAA,UACxB,EAAE,OAAO,UAAU,OAAO,UAAA;AAAA,QAAU;AAAA,MACtC;AAAA,MAEF,EAAE,KAAK,gBAAgB,OAAO,wBAAwB,MAAM,UAAU,SAAS,IAAA;AAAA,MAC/E;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,CAAA;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,CAAA;AAAA,QACT,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,EAAE,KAAK,QAAQ,OAAO,QAAQ,MAAM,SAAA;AAAA,YACpC,EAAE,KAAK,SAAS,OAAO,SAAS,MAAM,SAAA;AAAA,UAAS;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKhE;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMiE;AAAA,IACN,QAAQ;AAAA;AAAA;AAAA;AAAA,IAIR,OAAO,EAAE,IAAI,IAAI,KAAK,EAAA;AAAA,IACtB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,QACN,SAAS;AAAA,UACP,EAAE,OAAO,SAAS,OAAO,QAAA;AAAA,UACzB,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,QAAS;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKjE;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMiE;AAAA;AAAA;AAAA,IAGN,OAAO,EAAE,IAAI,QAAQ,KAAK,EAAA;AAAA,IAC1B,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,QACN,SAAS;AAAA,UACP,EAAE,OAAO,SAAS,OAAO,QAAA;AAAA,UACzB,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,QAAS;AAAA,MACrC;AAAA,MAEF;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,CAAA;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,EAAE,KAAK,OAAO,OAAO,OAAO,MAAM,SAAA;AAAA,YAClC,EAAE,KAAK,SAAS,OAAO,SAAS,MAAM,SAAA;AAAA,UAAS;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM0D;AAAA;AAAA;AAAA;AAAA,IAIN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA;AAAA;AAAA;AAAA,QAIE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,QACN,SAAS;AAAA,UACP,EAAE,OAAO,YAAY,OAAO,WAAA;AAAA,UAC5B,EAAE,OAAO,YAAY,OAAO,WAAA;AAAA,QAAW;AAAA,MACzC;AAAA,MAEF;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS;AAAA,QACT,aAAa;AAAA,QACb,MAAM;AAAA,MAAA;AAAA,MAER;AAAA;AAAA;AAAA;AAAA,QAIE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS,CAAA;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER;AAAA;AAAA;AAAA;AAAA,QAIE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM0D;AAAA;AAAA;AAAA;AAAA;AAAA,IAKN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM0D;AAAA;AAAA;AAAA;AAAA;AAAA,IAKN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MACE;AAAA,MAAA;AAAA,MAGJ;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MACE;AAAA,MAAA;AAAA,MAGJ;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MACE;AAAA,MAAA;AAAA,MAGJ;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,CAAA;AAAA,QACT,MACE;AAAA,MAAA;AAAA,MAGJ;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,QACN,aAAa;AAAA,QACb,SAAS;AAAA,UACP,EAAE,OAAO,UAAU,OAAO,uBAAA;AAAA,UAC1B,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,UAC1B,EAAE,OAAO,aAAa,OAAO,YAAA;AAAA,UAC7B,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,QAAS;AAAA,MACrC;AAAA,MAEF;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MACE;AAAA,QAEF,aAAa;AAAA,QACb,SAAS;AAAA,UACP,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,UAC1B,EAAE,OAAO,OAAO,OAAO,MAAA;AAAA,QAAM;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAK1D;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM0D;AAAA,IACN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAK1D;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM0D;AAAA,IACN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEF;AAAA,IACE,KAAKvD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMyD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,QAAQ;AAAA,MACN,EAAE,KAAK,QAAA;AAAA,MACP,EAAE,KAAK,MAAA;AAAA,MACP,EAAE,KAAK,QAAA;AAAA,MACP,EAAE,KAAK,UAAA;AAAA,MACP,EAAE,KAAK,YAAA;AAAA,IAAY;AAAA,EACrB;AAAA,EAEF;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMyD;AAAA,IACN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,QAAQ,CAAC,EAAE,KAAK,MAAA,GAAS,EAAE,KAAK,QAAA,GAAW,EAAE,KAAK,UAAA,GAAa,EAAE,KAAK,aAAa;AAAA,EAAA;AAAA,EAErF;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMyD;AAAA,IACN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,KAAK,UAAA,CAAW;AAAA,EAAA;AAAA,EAE7C;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMyD;AAAA,IACN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,QAAQ,CAAC,EAAE,KAAK,MAAA,GAAS,EAAE,KAAK,QAAA,GAAW,EAAE,KAAK,WAAW;AAAA,EAAA;AAAA,EAE/D;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMyD;AAAA,IACN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,QAAQ,CAAC,EAAE,KAAK,WAAW,EAAE,KAAK,aAAA,CAAc;AAAA,EAAA;AAAA,EAElD;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMyD;AAAA,IACN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,QAAQ,CAAC,EAAE,KAAK,SAAS;AAAA,EAAA;AAAA,EAE3B;AAAA,IACE,KAAKzD;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAMyD;AAAA,IACN,OAAO,EAAE,IAAI,GAAG,KAAK,EAAA;AAAA,IACrB,QAAQ;AAAA,MACN;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,QAAQ,CAAC,EAAE,KAAK,MAAA,GAAS,EAAE,KAAK,QAAA,GAAW,EAAE,KAAK,WAAW;AAAA,EAAA;AAEjE;AAGO,SAASjB,GAAgBzE,GAAauE,GAA6C;AACxF,SAAOqB,GAAe,KAAK,CAAC,MAAM,EAAE,QAAQ5F,KAAO,EAAE,WAAWuE,CAAM;AACxE;AAGO,SAASsB,GAAkB7F,GAAauE,GAAwB;;AACrE,WAAO/B,IAAAiC,GAAgBzE,GAAKuE,CAAM,MAA3B,gBAAA/B,EAA8B,UAAS+B;AAChD;AAOO,SAASuB,GAAiB9F,GAAauE,GAAwB;;AACpE,WAAO/B,IAAAiC,GAAgBzE,GAAKuE,CAAM,MAA3B,gBAAA/B,EAA8B,SAAQ;AAC/C;AAGO,SAASuD,GAAmB/F,GAAauE,GAA+B;;AAC7E,WAAO/B,IAAAiC,GAAgBzE,GAAKuE,CAAM,MAA3B,gBAAA/B,EAA8B,WAAU,CAAA;AACjD;AAGO,SAASwD,GAAqBhG,GAAauE,GAAyC;AACzF,QAAMJ,IAA+B,CAAA;AACrC,aAAW8B,KAAKF,GAAmB/F,GAAKuE,CAAM;AAC5C,IAAI0B,EAAE,YAAY,aAAeA,EAAE,GAAG,IAAIA,EAAE;AAE9C,SAAO9B;AACT;AC73DO,SAAS+B,GAAkBhG,GAAkBC,GAA2B;AAC7E,SACED,EAAE,MAAMC,EAAE,MACTD,EAAE,YAAY,SAASC,EAAE,YAAY,QACrCD,EAAE,OAAO,IAAI,KAAK,GAAG,OAAOC,EAAE,OAAO,IAAI,KAAK,GAAG;AAEtD;AAyBO,SAASgG,GAAqBC,GAAsBC,IAAa,GAAkB;AACxF,SAAO,EAAE,OAAAD,GAAO,YAAAC,GAAY,QAAQ,WAAW,MAAM,CAAA,GAAI,SAAS,GAAA;AACpE;AAsCO,SAASC,GAAaC,GAAwBC,GAAsC;AACzF,QAAMC,IAAO,IAAI,IAAIF,EAAS,IAAI,CAACrG,MAAMA,EAAE,EAAE,CAAC,GACxCwG,IAAsB,CAAA;AAC5B,aAAW1G,KAAOwG;AAChB,IAAIC,EAAK,IAAIzG,EAAI,EAAE,MACnByG,EAAK,IAAIzG,EAAI,EAAE,GACf0G,EAAM,KAAK1G,CAAG;AAEhB,SAAO0G,EAAM,WAAW,IAAIH,IAAW,CAAC,GAAGA,GAAU,GAAGG,CAAK;AAC/D;AAOO,SAASC,GAAgBC,GAAsBrC,GAAuC;AAC3F,UAAQA,EAAO,MAAA;AAAA,IACb,KAAK;AACH,aAAIA,EAAO,eAAeqC,EAAM,cAAcV,GAAkB3B,EAAO,OAAOqC,EAAM,KAAK,IAChFA,IAEFT,GAAqB5B,EAAO,OAAOA,EAAO,UAAU;AAAA,IAE7D,KAAK;AACH,aAAIqC,EAAM,WAAW,WAAW,CAACA,EAAM,UAAgBA,IAChD,EAAE,GAAGA,GAAO,QAAQ,eAAA;AAAA,IAE7B,KAAK;AACH,aAAIA,EAAM,WAAW,UAAgBA,IAC9B,EAAE,GAAGA,GAAO,QAAQA,EAAM,KAAK,WAAW,IAAI,YAAY,eAAA;AAAA,IAEnE,KAAK,eAAe;AAIlB,UAAIrC,EAAO,eAAeqC,EAAM,WAAY,QAAOA;AACnD,YAAM9G,IAAOwG,GAAaM,EAAM,MAAMrC,EAAO,IAAI,GAI3CsC,IACJtC,EAAO,eAAe,UAAaA,EAAO,eAAeA,EAAO,iBAC5DuC,IAAU,EAAQvC,EAAO,cAAe,CAACsC;AAC/C,aAAO;AAAA,QACL,GAAGD;AAAA,QACH,QAAQ;AAAA,QACR,MAAA9G;AAAA,QACA,QAAQgH,IAAUvC,EAAO,aAAa;AAAA,QACtC,SAAAuC;AAAA,QACA,OAAO,OAAOvC,EAAO,SAAU,WAAWA,EAAO,QAAQqC,EAAM;AAAA,QAC/D,OAAO;AAAA,MAAA;AAAA,IAEX;AAAA,IACA,KAAK;AACH,aAAIrC,EAAO,eAAeqC,EAAM,aAAmBA,IAI5C,EAAE,GAAGA,GAAO,QAAQ,SAAS,OAAOrC,EAAO,MAAA;AAAA,IAEpD;AACE,aAAOqC;AAAA,EAAA;AAEb;AAYO,SAASG,GAAoBjH,GAA2C;AAC7E,SAAOA,EAAK,OAAO,CAACI,MAAM,CAACsD,GAActD,EAAE,EAAE,CAAC;AAChD;AAYO,SAAS8G,GACdC,GACAC,GACAC,GACU;AACV,MAAIA,KAAa,EAAG,QAAO,CAAA;AAC3B,QAAMC,IAAkB,CAAA;AACxB,aAAWzE,KAAMsE;AACf,QAAI,CAAAC,EAAU,IAAIvE,CAAE,MACpByE,EAAM,KAAKzE,CAAE,GACTyE,EAAM,UAAUD;AAAW;AAEjC,SAAOC;AACT;AASO,SAASC,GACdJ,GACAK,GACc;AACd,QAAMnD,IAAoB,CAAA;AAC1B,aAAWxB,KAAMsE,GAAK;AACpB,UAAMjH,IAAMsH,EAAS,IAAI3E,CAAE;AAC3B,IAAI3C,KAAKmE,EAAI,KAAKnE,CAAG;AAAA,EACvB;AACA,SAAOmE;AACT;ACzNO,MAAMoD,KAAmBC,GAAqC,MAAS;AAUvE,SAASC,GAAYC,GAAiCC,GAAiC;;AAC5F,MAAID,EAAU,QAAOA;AACrB,MAAIC,EAAU,QAAOA;AACrB,MAAI,OAAO,WAAa,IAAa,QAAO;AAC5C,QAAMC,IAAO,SAAS,gBAAgB,aAAa,YAAY;AAC/D,SAAIA,MAAS,UAAUA,MAAS,UAAgBA,KACzCpF,IAAA,OAAO,eAAP,QAAAA,EAAA,aAAoB,gCAAgC,UAAU,SAAS;AAChF;AAWO,SAASqF,GAAkBH,GAAiC;AACjE,QAAMC,IAAWG,GAAWP,EAAgB,GACtC,CAACQ,GAAMC,CAAO,IAAIC,EAAoB,MAAMR,GAAYC,GAAUC,CAAQ,CAAC;AAEjF,SAAAO,GAAU,MAAM;AACd,QAAIR,GAAU;AACZ,MAAAM,EAAQN,CAAQ;AAChB;AAAA,IACF;AACA,QAAIC,GAAU;AACZ,MAAAK,EAAQL,CAAQ;AAChB;AAAA,IACF;AACA,QAAI,OAAO,SAAW,IAAa;AAEnC,UAAMQ,IAAS,MAAMH,EAAQP,GAAY,QAAWE,CAAQ,CAAC,GAEvDS,IAAM,OAAO,WAAW,8BAA8B;AAC5D,IAAAA,EAAI,iBAAiB,UAAUD,CAAM;AAErC,UAAME,IAAW,IAAI,iBAAiBF,CAAM;AAC5C,WAAAE,EAAS,QAAQ,SAAS,iBAAiB;AAAA,MACzC,YAAY;AAAA,MACZ,iBAAiB,CAAC,YAAY;AAAA,IAAA,CAC/B,GAIDF,EAAA,GAEO,MAAM;AACX,MAAAC,EAAI,oBAAoB,UAAUD,CAAM,GACxCE,EAAS,WAAA;AAAA,IACX;AAAA,EACF,GAAG,CAACX,GAAUC,CAAQ,CAAC,GAEhBI;AACT;ACpDO,SAASO,GAAQ,EAAE,KAAAC,GAAK,SAAAC,GAAS,YAAAC,GAAY,MAAAC,GAAM,MAAAC,IAAO,IAAI,OAAAC,KAAgB;AAEnF,QAAMC,IADYhB,GAAkBe,CAAK,MACR,SAAUJ,KAAWD,IAAOA,GAMvD,CAACO,GAAWC,CAAY,IAAId,EAA6B,MAAS;AAExE,MAAIY,KAAcA,MAAeC;AAC/B,WACE,gBAAAE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKH;AAAA,QACL,OAAOF;AAAA,QACP,QAAQA;AAAA,QACR,KAAI;AAAA,QACJ,SAAS,MAAMI,EAAaF,CAAU;AAAA,QACtC,OAAO;AAAA,UACL,OAAOF;AAAA,UACP,QAAQA;AAAA,UACR,cAAc;AAAA,UACd,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,UAKZ,WAAW;AAAA,UACX,SAAS,KAAK,IAAI,GAAG,KAAK,MAAMA,IAAO,IAAI,CAAC;AAAA,UAC5C,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOX,YAAY;AAAA,QAAA;AAAA,MACd;AAAA,IAAA;AAKN,QAAMM,KAAYP,KAAQ,KACvB,MAAM,KAAK,EACX,MAAM,GAAG,CAAC,EACV,IAAI,CAACQ;;AAAM,aAAA1G,IAAA0G,EAAE,CAAC,MAAH,gBAAA1G,EAAM,kBAAiB;AAAA,GAAE,EACpC,KAAK,EAAE;AAEV,SACE,gBAAAwG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,OAAOL;AAAA,QACP,QAAQA;AAAA,QACR,cAAc;AAAA,QACd,YAAYF,KAAc;AAAA,QAC1B,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,UAAU,KAAK,MAAME,IAAO,IAAI;AAAA,QAChC,YAAY;AAAA,MAAA;AAAA,MAGb,UAAAM;AAAA,IAAA;AAAA,EAAA;AAGP;AC0hBA,MAAME,KAAM3B,GAA6B,IAAI;AAsCtC,SAAS4B,GAAc,EAAE,KAAAC,GAAK,OAAAT,GAAO,UAAAU,KAAgC;AAC1E,QAAMC,IACJ,gBAAAP,EAACG,GAAI,UAAJ,EAAa,OAAOE,GACnB,UAAA,gBAAAL,EAACzB,GAAiB,UAAjB,EAA0B,OAAOqB,GAAQ,UAAAU,GAAS,GACrD;AAEF,SAAKV,IAEH,gBAAAI,EAAC,SAAI,cAAYJ,GAAO,OAAO,EAAE,SAAS,WAAA,GACvC,UAAAW,EAAA,CACH,IAJiBA;AAMrB;AAMO,SAASC,KAAoB;AAClC,QAAMH,IAAMvB,GAAWqB,EAAG;AAC1B,MAAI,CAACE;AACH,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAIJ,SAAOA;AACT;AAMO,SAASI,KAAwC;AACtD,SAAO3B,GAAWqB,EAAG,KAAK;AAC5B;AASA,MAAMO,KAAqBlC,GAAkC,MAAS,GAEhEmC,KAAgBnC,GAAkC,MAAS;AAM1D,SAASoC,GAAwB;AAAA,EACtC,SAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAR;AACF,GAIG;AACD,SACE,gBAAAN,EAACU,GAAmB,UAAnB,EAA4B,OAAOG,GAClC,UAAA,gBAAAb,EAACW,GAAc,UAAd,EAAuB,OAAOG,GAAa,UAAAR,GAAS,GACvD;AAEJ;AAGO,SAASS,KAAyC;AACvD,SAAOjC,GAAW4B,EAAkB;AACtC;AAGO,SAASM,KAAoC;AAClD,SAAOlC,GAAW6B,EAAa;AACjC;AC1tBA,MAAMM,KAAsB,GAOtBC,KAAqB,IAGrBC,KAAqB;AAQpB,SAASC,GAAgBpK,GAAkE;AAChG,QAAMqK,IAAWrK,EAAI;AACrB,SAAI,CAACqK,KAAY,OAAOA,KAAa,WAAiB,OAC/CA;AACT;AAQA,SAASC,GACPC,GACwC;AACxC,MAAI,CAACA,EAAO,QAAO;AACnB,MAAIA,EAAM,UAAW,QAAO,EAAE,MAAM,oBAAoB,OAAO,mBAAA;AAC/D,QAAMC,IAAS,OAAOD,EAAM,UAAW,WAAWA,EAAM,OAAO,SAAS;AACxE,SAAO;AAAA,IACL,MAAMC,MAAW,KAAK,gBAAgB,iBAAiBA,CAAM;AAAA,IAC7D,OAAOA,MAAW,KAAK,yBAAyBA;AAAA,EAAA;AAEpD;AA8HO,SAASC,GAAU;AAAA,EACxB,aAAAC;AAAA,EACA,OAAA9B;AAAA,EACA,QAAA+B;AAAA,EACA,mBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,QAAAC,IAAS;AAAA,EACT,aAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,aAAAC;AAAA,EACA,MAAMC;AAAA,EACN,gBAAAC,IAAiB;AAAA,EACjB,gBAAAC,IAAiB;AAAA,EACjB,eAAAC;AAAA,EACA,UAAAC;AAAA,EACA,aAAAC;AAAA,EACA,KAAAtE;AAAA,EACA,WAAAuE,IAAYtB;AAAA,EACZ,UAAAuB;AACF,GAAmB;AACjB,QAAMpC,IAAMG,GAAA,GAGNkC,IAAWR,MAAiB,QAc5BS,IAAS1E,KAAOA,EAAI,SAAS,IAAIA,EAAI,KAAK,GAAG,IAAI,IACjD2E,IAAQ,CAACF,MAAaD,MAAa,UAAa,OAAOpC,EAAI,gBAAiB,aAC5EwC,IAAcC,GAAOL,CAAQ;AACnC,EAAAI,EAAY,UAAUJ;AAGtB,QAAM,CAACM,GAAaC,CAAc,IAAI/D,EAA8B,IAAI,GAClE,CAACgE,GAAaC,CAAc,IAAIjE,EAAwB,IAAI;AAElE,EAAAC,GAAU,MAAM;AACd,QAAIwD,KAAYE,EAAO;AACvB,UAAMO,IAAW9C,EAAI;AAKrB,QAAI,OAAO8C,KAAa,YAAY;AAClC,MAAAH,EAAe,CAAA,CAAE;AACjB;AAAA,IACF;AACA,QAAII,KAAW;AACf,WAAAD,EAAA,EACG,KAAK,CAAC1J,OAAM,CAAC2J,MAAYJ,EAAevJ,EAAC,CAAC,EAC1C,MAAM,CAAC4J,OAAM,CAACD,MAAYF,EAAgBG,GAAY,OAAO,CAAC,GAC1D,MAAM;AACX,MAAAD,KAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAKqC,GAAUE,CAAK,CAAC;AAGzB,QAAM,CAACU,GAAWC,CAAQ,IAAIC;AAAA,IAC5B7F;AAAA,IACAR,GAAqB,EAAE,GAAG,IAAI,UAAAmF,GAAU,KAAArE,EAAA,GAAO,CAAC;AAAA,EAAA,GAE5C,CAACwF,GAAYC,CAAa,IAAIzE,EAAS,EAAE,GACzC0E,IAAa5B,KAAe0B,GAC5BG,IAAgB,CAACC,MAAkB;AACvC,IAAI9B,MAAgB,UAAW2B,EAAcG,CAAK,GAClD7B,KAAA,QAAAA,EAAiB6B;AAAA,EACnB,GACM,CAACC,GAAgBC,CAAiB,IAAI9E,EAAS0E,EAAW,MAAM,GAKhEK,IAAgBlB,GAAO,CAAC,GACxBmB,KAAWnB,GAA+B,IAAI,GAE9CoB,KAAYC;AAAA,IAChB,CAAC/G,GAAsBC,IAAoB+G,OAA+B;;AACxE,YAAMC,KAASxB,EAAY,SACrByB,KAAejE,EAAI;AACzB,UAAI,CAACgE,MAAU,CAACC,GAAc;AAC9B,OAAA9K,KAAAyK,GAAS,YAAT,QAAAzK,GAAkB;AAClB,YAAM+K,KAAa,IAAI,gBAAA;AACvB,MAAAN,GAAS,UAAUM;AAInB,UAAIC;AACJ,UAAI;AACF,QAAAA,KAAUH,KACNA,GAAO;AAAA,UACL,GAAGjH,EAAM,KAAK;AAAA,UACd,QAAAgH;AAAA,UACA,OAAO5B;AAAA,UACP,GAAIpF,EAAM,MAAM,EAAE,KAAKA,EAAM,IAAA,IAAQ,CAAA;AAAA,UACrC,QAAQmH,GAAW;AAAA,QAAA,CACpB,IACAD,GAAkD;AAAA,UACjD,GAAGlH,EAAM,KAAK;AAAA,UACd,UAAUA,EAAM;AAAA,UAChB,GAAImF,IAAc,EAAE,aAAa,GAAA,IAAS,CAAA;AAAA,UAC1C,GAAInF,EAAM,MAAM,EAAE,KAAKA,EAAM,IAAA,IAAQ,CAAA;AAAA,UACrC,QAAAgH;AAAA,UACA,OAAO5B;AAAA,UACP,SAAS;AAAA,UACT,QAAQ+B,GAAW;AAAA,QAAA,CACpB;AAAA,MACP,SAASlB,IAAG;AACV,QAAAmB,KAAU,QAAQ,OAAOnB,EAAC;AAAA,MAC5B;AACA,MAAAmB,GACG,KAAK,CAACC,OAAS;AACd,YAAIT,EAAc,YAAY3G,IAC9B;AAAA,cAAI,CAACoH,MAAQ,CAAC,MAAM,QAASA,GAA4B,IAAI,GAAG;AAO9D,YAAAlB,EAAS;AAAA,cACP,MAAM;AAAA,cACN,YAAAlG;AAAA,cACA,OAAO;AAAA,YAAA,CACR;AACD;AAAA,UACF;AACA,UAAAkG,EAAS;AAAA,YACP,MAAM;AAAA,YACN,YAAAlG;AAAA,YACA,MAAMoH,GAAK;AAAA,YACX,YAAYA,GAAK;AAAA,YACjB,iBAAiBL;AAAA,YACjB,OAAO,OAAOK,GAAK,SAAU,WAAWA,GAAK,QAAQ;AAAA,UAAA,CACtD;AAAA;AAAA,MACH,CAAC,EACA,MAAM,CAACpB,OAAe;AAIrB,YAHIW,EAAc,YAAY3G,MAG1BgG,cAAa,SAASA,GAAE,SAAS,aAAc;AAKnD,cAAMqB,IAAQrB,MAAA,gBAAAA,GAAiC;AAC/C,YACEe,OAAW,WACVM,MAAS,sBAAsBA,MAAS,qBACzC;AACA,gBAAMC,IAAO,EAAEX,EAAc;AAC7B,UAAAT,EAAS,EAAE,MAAM,iBAAiB,OAAAnG,GAAO,YAAYuH,GAAM,GAC3DT,GAAU9G,GAAOuH,GAAM,MAAS;AAChC;AAAA,QACF;AACA,QAAApB,EAAS,EAAE,MAAM,eAAe,YAAAlG,IAAY,OAAQgG,GAAY,SAAS;AAAA,MAC3E,CAAC;AAAA,IACL;AAAA,IACA,CAAChD,GAAKmC,GAAWD,CAAW;AAAA,EAAA;AAI9B,EAAArD,GAAU,MAAM;AACd,QAAI,CAAC0D,EAAO;AACZ,UAAMgC,IAAI,WAAW,MAAMb,EAAkBJ,EAAW,KAAA,CAAM,GAAGxC,EAAkB;AACnF,WAAO,MAAM,aAAayD,CAAC;AAAA,EAC7B,GAAG,CAACjB,GAAYf,CAAK,CAAC,GAKtB1D,GAAU,MAAM;AACd,QAAI,CAAC0D,EAAO;AACZ,UAAMvF,IAAa,EAAE2G,EAAc,SAC7B5G,KAAuB;AAAA,MAC3B,GAAG0G;AAAA,MACH,UAAAxB;AAAA,MACA,GAAIK,IAAS,EAAE,KAAKA,EAAO,MAAM,GAAG,MAAM,CAAA;AAAA,IAAC;AAE7C,WAAAY,EAAS,EAAE,MAAM,iBAAiB,OAAAnG,IAAO,YAAAC,GAAY,GACrD6G,GAAU9G,IAAOC,GAAY,MAAS,GAC/B,MAAM;;AACX,OAAA7D,KAAAyK,GAAS,YAAT,QAAAzK,GAAkB;AAAA,IACpB;AAAA,EACF,GAAG,CAACoJ,GAAOkB,GAAgBxB,GAAUK,GAAQuB,EAAS,CAAC,GAIvDhF,GAAU,MAAM;AACd,QAAK0D;AACL,aAAO,MAAA;;AAAM,gBAAApJ,IAAAyK,GAAS,YAAT,gBAAAzK,EAAkB;AAAA;AAAA,EACjC,GAAG,CAACoJ,CAAK,CAAC;AAEV,QAAMiC,IAAW,MAAM;AACrB,QAAI,CAACjC,KAASU,EAAU,WAAW,WAAW,CAACA,EAAU,QAAS;AAClE,UAAMjG,IAAa2G,EAAc;AACjC,IAAAT,EAAS,EAAE,MAAM,aAAa,GAC9BW,GAAUZ,EAAU,OAAOjG,GAAYiG,EAAU,MAAM;AAAA,EACzD,GAEMwB,IAAQ,MAAM;AAClB,IAAI,CAAClC,KAASU,EAAU,WAAW,YACnCC,EAAS,EAAE,MAAM,SAAS,GAC1BW,GAAUZ,EAAU,OAAOU,EAAc,SAASV,EAAU,MAAM;AAAA,EACpE,GAEM,CAACyB,GAAcC,CAAe,IAAI/F,EAAmB,CAAA,CAAE,GACvD,CAACgG,GAAcC,CAAe,IAAIjG,EAAS,EAAK,GAGhD,CAACkG,IAAeC,CAAgB,IAAInG,EAAS,EAAK,GAIlDoG,IAAO,CAACC,wBAAqB,OAAA,EAAI,WAAU,sBAAsB,UAAAA,GAAK;AAG5E,MAAIC,GACAC,IAA4B,MAC5BC,IAAc,IACd3H,KAAU,IACV4H,KAA2B,MAO3BC,KAAsB;AAkB1B,MAhBIjD,IACF6C,IAAUrD,KAAgB,OACjBU,KACT2C,IAAUjC,EAAU,MACpBqC,KAAsBrC,EAAU,WAAW,WAC3CmC,IAAcnC,EAAU,WAAW,gBACnCxF,KAAUwF,EAAU,SAChBA,EAAU,WAAW,YACnBA,EAAU,KAAK,WAAW,IAAGkC,IAAalC,EAAU,SAAS,yBAC5DoC,KAAYpC,EAAU,SAAS,4BAGtCiC,IAAUxC,GACVyC,IAAavC,IAGX,CAACL,KAAS4C,EAAY,QAAOH,oBAAM,OAAA,EAAI,WAAU,wBAAwB,UAAAG,EAAA,CAAW,CAAM;AAC9F,MAAI,CAAC5C,KAAS2C,MAAY;AACxB,WAAOF,EAAK,gBAAArF,EAAC,KAAA,EAAE,WAAU,uBAAsB,2BAAa,CAAI;AAElE,EAAAuF,UAAY,CAAA;AAIZ,QAAMK,KAAc7H,GAAoBwH,CAAO,GACzCM,KAAOlE,IAASiE,GAAY,OAAOjE,CAAM,IAAIiE;AASnD,MAAI,CAAChD,KAASiD,GAAK,WAAW;AAC5B,WAAOR;AAAA,MACL,gBAAAS,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,KAAA,EAAE,WAAU,uBACV,UAAA6B,KAAgB,kEACnB;AAAA,QACCI;AAAA,MAAA,EAAA,CACH;AAAA,IAAA;AAWJ,QAAM8D,KAAQ5D,IAAiBtL,GAAiBgP,EAAI,IAAI,CAAA,GAClDG,KAAeD,GAAM,MAAM,GAAG9E,EAAmB,GACjDgF,KAAiBF,GACpB,MAAM9E,EAAmB,EACzB,OAAO,CAACiF,MAAMnB,EAAa,SAASmB,EAAE,IAAI,CAAC,GACxCC,KAAiB,CAAC,GAAGH,IAAc,GAAGC,EAAc,GACpDG,KAAkBL,GAAM,SAASI,GAAe,QAChDE,KAAiBpB,IAAec,KAAQI,IACxCG,KAAY,CAAC5P,MACjBsO;AAAA,IAAgB,CAACuB,OACfA,GAAK,SAAS7P,CAAI,IAAI6P,GAAK,OAAO,CAACrG,OAAMA,OAAMxJ,CAAI,IAAI,CAAC,GAAG6P,IAAM7P,CAAI;AAAA,EAAA,GAEnE8P,KAAY,MAAMxB,EAAgB,EAAE,GAQpCyB,KAAkBZ,GAAK,OAAO,CAAC3O,MAAMkK,GAAgBlK,CAAC,MAAM,IAAI,EAAE,QAClEwP,KAAwBtE,KAAkBqE,KAAkB,GAG5DE,KAAiBD,MAAyBvB,IAC1CyB,KAAmBD,KAAiBd,GAAK,OAAO,CAAC3O,MAAMkK,GAAgBlK,CAAC,MAAM,IAAI,IAAI2O,IAQtFgB,KACJ1E,KAAkB4C,EAAa,SAAS,IACpC6B,GAAiB,OAAO,CAAC1P,MAAME,GAAkBF,GAAG6N,CAAY,CAAC,IACjE6B,IAEAE,KAASlE,IACXiE,KACA,CAAC,GAAGA,EAAW,EAAE;AAAA,IAAK,CAAC3P,GAAGC,OACxBD,EAAE,YAAY,cAAcC,GAAE,aAAa,QAAW,EAAE,aAAa,OAAA,CAAQ;AAAA,EAAA,GAK7E4P,KAAInE,IAAQ,KAAKe,EAAW,KAAA,EAAO,YAAA,GACnCqD,KAAerD,EAAW,KAAA,EAAO,SAAS,GAC1CsD,KAAUF,KACZD,GAAO;AAAA,IACL,CAAC5P,MAAMA,EAAE,YAAY,cAAc,SAAS6P,EAAC,KAAK7P,EAAE,GAAG,YAAA,EAAc,SAAS6P,EAAC;AAAA,EAAA,IAEjFD,IAcEI,KACHvF,MAAW,UAAakE,GAAK,WAAWD,GAAY,UACpDe,MAAkBC,GAAiB,WAAWf,GAAK,UACnD1D,KAAkB4C,EAAa,SAAS,KAAK8B,GAAY,WAAWD,GAAiB,QAIlFO,MACFhF,KAAkB4C,EAAa,SAAS,KAAM4B,OAAmBM,GAAQ,WAAW,GAClFG,KAA2BT,MAAkB5B,EAAa,WAAW,GACrEsC,KAAkB,MAAM;AAC5B,IAAArC,EAAgB,CAAA,CAAE,GAClBI,EAAiB,EAAK,GACtBxB,EAAc,EAAE;AAAA,EAClB;AAEA,SAAOyB;AAAA,IACL,gBAAAS,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAA;AAAA,MAAAhE,KACC,gBAAA9B;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,aAAa4B,KAAqB;AAAA,UAClC,OAAO+B;AAAA,UACP,UAAU,CAACN,MAAMO,EAAcP,EAAE,OAAO,KAAK;AAAA,UAC7C,cAAW;AAAA,QAAA;AAAA,MAAA;AAAA,OAGbqD,MAA0BvE,KAAkB4D,GAAM,SAAS,MAC3D,gBAAAD,EAAC,OAAA,EAAI,WAAU,sBACZ,UAAA;AAAA,QAAAY,MACC,gBAAAZ;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,gBAAcX;AAAA,YACd,cAAW;AAAA,YACX,SAAS,MAAMC,EAAiB,CAACmB,MAAS,CAACA,CAAI;AAAA,YAChD,UAAA;AAAA,cAAA;AAAA,cACiB,gBAAAT,EAAC,QAAA,EAAK,WAAU,aAAY,UAAA;AAAA,gBAAA;AAAA,gBAAEW;AAAA,gBAAgB;AAAA,cAAA,EAAA,CAAC;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGlEtE,KAAkB4D,GAAM,SAAS,KAChC,gBAAAD,EAAAwB,IAAA,EACG,UAAA;AAAA,UAAAjB,GAAe,IAAI,CAACH,MACnB,gBAAAJ;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,gBAAcf,EAAa,SAASmB,EAAE,IAAI;AAAA,cAC1C,cAAY,aAAaA,EAAE,KAAK;AAAA,cAChC,SAAS,MAAMI,GAAUJ,EAAE,IAAI;AAAA,cAE9B,UAAA;AAAA,gBAAAA,EAAE;AAAA,gBAAM;AAAA,gBAAC,gBAAAJ,EAAC,QAAA,EAAK,WAAU,aAAY,UAAA;AAAA,kBAAA;AAAA,kBAAEI,EAAE;AAAA,kBAAM;AAAA,gBAAA,EAAA,CAAC;AAAA,cAAA;AAAA,YAAA;AAAA,YAP5CA,EAAE;AAAA,UAAA,CASV;AAAA,UACA,CAACjB,KAAgBmB,KAAkB,KAClC,gBAAAN;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAMZ,EAAgB,EAAI;AAAA,cACpC,UAAA;AAAA,gBAAA;AAAA,gBACGkB;AAAA,gBAAgB;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGrBnB,KAAgBc,GAAM,SAAS9E,MAC9B,gBAAAjB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAMkF,EAAgB,EAAK;AAAA,cACrC,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAIFH,EAAa,SAAS,KACrB,gBAAA/E;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAASwG;AAAA,cACV,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAED,EAAA,CAEJ;AAAA,MAAA,GAEJ;AAAA,MAED5D,KAAS+C,KACR,gBAAA3F,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,gBAAA,CAAa,IAC9C4C,KAAS4C,IACX,gBAAAM,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAA;AAAA,QAAAN;AAAA,QAAY;AAAA,QACb,gBAAAxF,EAAC,YAAO,MAAK,UAAS,WAAU,oCAAmC,SAAS8E,GAAO,UAAA,QAAA,CAEnF;AAAA,MAAA,EAAA,CACF,IACEmC,GAAQ,WAAW,KAAK,CAACnJ,KAC3BqJ,KACE,gBAAArB,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,KAAA,EAAE,WAAU,uBACV,UAAAoH,KACGJ,KACE,6BAA6BrD,CAAU,OACvC,sCACFqD,KACE,kBAAkBrD,CAAU,kCAC5B,0CACR;AAAA,QACA,gBAAA3D;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,SAASqH;AAAA,YACV,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,EAAA,CACF,IACGzE,IAMH,gBAAAkD,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,KAAA,EAAE,WAAU,uBACV,UAAAgH,KACG,kBAAkBrD,CAAU,OAC3B9B,KACD,iEAAA,CACN;AAAA,QACC,CAACmF,MAAgB/E;AAAA,MAAA,EAAA,CACpB;AAAA;AAAA;AAAA;AAAA,QAVA,gBAAA6D,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA;AAAA,UAAA;AAAA,UAAgBnC;AAAA,UAAW;AAAA,QAAA,EAAA,CAAE;AAAA,UAalE,gBAAAmC,EAAAwB,IAAA,EACG,UAAA;AAAA,QAAAL,GAAQ,WAAW,KAAKnJ;AAAA;AAAA;AAAA;AAAA;AAAA,UAKvB,gBAAAkC,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,uDAAA,CAEnC;AAAA,8BAEC,OAAA,EAAI,WAAU,kEACZ,UAAAiH,GAAQ,IAAI,CAAC/P,MAAM;AAClB,gBAAMqQ,KAAclF,KAAA,gBAAAA,EAAe,IAAInL,EAAE,KACnCsQ,KAASlG,GAAkBiG,EAAW;AAC5C,iBACE,gBAAAzB;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAMpE,EAAYxK,CAAC;AAAA,cAE5B,UAAA;AAAA,gBAAA,gBAAA8I;AAAA,kBAACV;AAAA,kBAAA;AAAA,oBACC,KAAKpI,EAAE;AAAA,oBACP,SAASA,EAAE;AAAA,oBACX,YAAYA,EAAE;AAAA,oBACd,MAAMA,EAAE;AAAA,oBACR,OAAA0I;AAAA,oBACA,MAAM;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAER,gBAAAkG,EAAC,QAAA,EAAK,WAAU,6BACd,UAAA;AAAA,kBAAA,gBAAA9F,EAAC,UAAA,EAAQ,YAAE,YAAA,CAAY;AAAA,kBAMvB,gBAAAA,EAAC,QAAA,EAAK,WAAU,yBAAyB,YAAE,IAAG;AAAA,kBAC7C9I,EAAE,WACD,gBAAA4O,EAAC,QAAA,EAAK,WAAU,8BAA6B,UAAA;AAAA,oBAAA;AAAA,oBAAE5O,EAAE;AAAA,kBAAA,GAAQ;AAAA,kBAM1DsQ,MACC,gBAAAxH;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,WACEuH,MAAA,QAAAA,GAAa,YACT,uCACA;AAAA,sBAEN,OAAOC,GAAO;AAAA,sBAEb,UAAAA,GAAO;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBACV,EAAA,CAEJ;AAAA,cAAA;AAAA,YAAA;AAAA,YAxCKtQ,EAAE;AAAA,UAAA;AAAA,QA2Cb,CAAC,EAAA,CACH;AAAA,QAED0L,KAAS,OAAOU,EAAU,SAAU,YACnC,gBAAAtD,EAAC,OAAA,EAAI,WAAU,iCACZ,UAAAkH,KACG,GAAGD,GAAQ,MAAM,IAAIA,GAAQ,WAAW,IAAI,QAAQ,MAAM,KAC1D,GAAG3D,EAAU,KAAK,MAAM,OAAOA,EAAU,KAAK,GAAA,CACpD;AAAA,QAEDV,KAAS8C,MACR,gBAAAI,EAAC,OAAA,EAAI,WAAU,kCACZ,UAAA;AAAA,UAAAJ;AAAA,UAAW;AAAA,UACZ,gBAAA1F,EAAC,YAAO,MAAK,UAAS,WAAU,oCAAmC,SAAS8E,GAAO,UAAA,QAAA,CAEnF;AAAA,QAAA,GACF;AAAA,QAEDlC,KAAS9E,MAAW,CAAC4H,MACpB,gBAAA1F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,SAAS6E;AAAA,YACT,UAAUY;AAAA,YAET,cAAc,kBAAkB;AAAA,UAAA;AAAA,QAAA;AAAA,MACnC,EAAA,CAEJ;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA;AAEJ;AClvBA,MAAMgC,KAAoB,oBAAI,IAAI,CAAC,SAAS,UAAU,SAAS,CAAC;AAOzD,SAASC,GAAQC,GAAqB;AAC3C,MAAI;AACF,WAAOF,GAAkB,IAAI,IAAI,IAAIE,CAAG,EAAE,QAAQ,IAAIA,IAAM;AAAA,EAC9D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,MAAMC,KAAsB,CAAC,KAAK;AAElC,SAASC,GAAS;AAAA,EAChB,MAAMC;AAAA,EACN,MAAAC;AAAA,EACA,UAAAzH;AAAA,EACA,GAAG0H;AACL,GAA6C;AAC3C,SACE,gBAAAhI,EAAC,KAAA,EAAG,GAAGgI,GAAM,MAAMD,KAAQ,QAAW,QAAO,UAAS,KAAI,gCACvD,UAAAzH,EAAA,CACH;AAEJ;AAOO,SAAS2H,GAAiBC,GAA4D;AAC3F,QAAMC,IAAI,sDAAsD,KAAKD,CAAI;AACzE,SAAKC,IACE,EAAE,aAAaA,EAAE,CAAC,GAAG,MAAMD,EAAK,MAAMC,EAAE,CAAC,EAAE,MAAM,EAAA,IADzC,EAAE,aAAa,MAAM,MAAMD,EAAA;AAE5C;AAGA,SAASE,GAAY,EAAE,MAAAC,KAA0B;AAC/C,SACE,gBAAAvC,EAAC,WAAA,EAAQ,WAAU,sBAAqB,eAAY,kBAClD,UAAA;AAAA,IAAA,gBAAA9F,EAAC,aAAQ,UAAA,cAAA,CAAW;AAAA,IACpB,gBAAAA,EAAC,OAAA,EACC,UAAA,gBAAAA,EAAC,QAAA,EAAM,aAAK,EAAA,CACd;AAAA,EAAA,GACF;AAEJ;AAOO,SAASsI,GAAS,EAAE,SAAA/H,GAAS,WAAAgI,KAA4B;AAC9D,QAAM,EAAE,aAAAC,GAAa,MAAAlD,MAAS2C,GAAiB1H,CAAO;AACtD,SACE,gBAAAuF,EAAC,SAAI,WAAAyC,GACF,UAAA;AAAA,KAAAC,KAAA,gBAAAA,EAAa,WAAU,gBAAAxI,EAACoI,IAAA,EAAY,MAAMI,GAAa;AAAA,IACxD,gBAAAxI;AAAA,MAACyI;AAAA,MAAA;AAAA,QACC,UAAQ;AAAA,QACR,cAAcf;AAAA,QACd,oBAAoBE;AAAA,QACpB,kBAAgB;AAAA,QAChB,YAAY,EAAE,GAAGC,GAAA;AAAA,QAEhB,UAAAvC;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GACF;AAEJ;AC7DA,MAAMoD,KAAU,qBACVC,KAAO,WAAA,oCAAA,GAAA;AAGN,SAASC,GAAeC,GAAmBtI,GAAuB;AACvE,QAAMuI,IAAMD,EAAK;AACjB,EAAAA,EAAK,gBAAA;AACL,aAAWE,KAAOxI,EAAQ,MAAM;AAAA,CAAI,GAAG;AACrC,UAAM4H,IAAIO,GAAQ,KAAKK,CAAG,GACpBC,IAAQF,EAAI,cAAcX,IAAI,IAAIA,EAAE,CAAC,EAAE,MAAM,KAAK,KAAK,GACvDD,IAAOC,IAAIA,EAAE,CAAC,IAAIY;AACxB,QAAIE,IAAK;AACT,eAAW9R,KAAK+Q,EAAK,SAASS,EAAI,GAAG;AACnC,MAAIxR,EAAE,QAAQ8R,KAAID,EAAM,OAAOF,EAAI,eAAeZ,EAAK,MAAMe,GAAI9R,EAAE,KAAK,CAAC,CAAC;AAC1E,YAAM+R,IAASJ,EAAI,cAAc,QAAQ;AACzC,MAAAI,EAAO,cAAc/R,EAAE,CAAC,GACxB6R,EAAM,OAAOE,CAAM,GACnBD,IAAK9R,EAAE,QAAQA,EAAE,CAAC,EAAE;AAAA,IACtB;AACA,IAAI8R,IAAKf,EAAK,UAAQc,EAAM,OAAOF,EAAI,eAAeZ,EAAK,MAAMe,CAAE,CAAC,CAAC,GAChED,EAAM,cAAYA,EAAM,OAAOF,EAAI,cAAc,IAAI,CAAC,GAC3DD,EAAK,OAAOG,CAAK;AAAA,EACnB;AACF;AAEA,SAASG,GAAOC,GAAsC;;AACpD,QAAMC,KAAI7P,IAAA4P,EAAG,UAAH,gBAAA5P,EAAU;AACpB,MAAI,CAAC6P,EAAG;AACR,MAAIA,MAAM,UAAUA,MAAM,SAAU,QAAO;AAC3C,QAAM,IAAI,OAAOA,CAAC;AAClB,SAAO,OAAO,SAAS,CAAC,IAAI,KAAK,MAAM;AACzC;AAEA,SAASC,GAAQC,GAAqB;AACpC,QAAMC,IAAgB,CAAA;AACtB,aAAW/P,KAAK8P,GAAM;AACpB,UAAME,IAAOD,EAAOA,EAAO,SAAS,CAAC;AACrC,IAAIC,KAAQA,EAAK,SAAShQ,EAAE,OAAMgQ,EAAK,QAAQhQ,EAAE,OAC5C+P,EAAO,KAAK,EAAE,GAAG/P,GAAG;AAAA,EAC3B;AACA,SAAO+P,EACJ,IAAI,CAAC,EAAE,MAAAtB,GAAM,MAAAwB,QAAW;AACvB,UAAMC,IAAOzB,EAAK,KAAA;AAClB,QAAI,CAACwB,KAAQ,CAACC,EAAM,QAAOzB;AAC3B,UAAM0B,IAAO1B,EAAK,MAAM,GAAGA,EAAK,QAAQyB,CAAI,CAAC,GACvCE,IAAQ3B,EAAK,MAAM0B,EAAK,SAASD,EAAK,MAAM;AAClD,WAAO,GAAGC,CAAI,KAAKD,CAAI,KAAKE,CAAK;AAAA,EACnC,CAAC,EACA,KAAK,EAAE;AACZ;AAGO,SAASC,GAAmBjB,GAA2B;AAC5D,QAAMkB,IAAgB,CAAA;AACtB,MAAIC,IAAmB;AACvB,QAAMC,IAAO,CAACC,OACZF,IAAM,EAAE,OAAAE,GAAO,MAAM,GAAC,GACtBH,EAAM,KAAKC,CAAG,GACPA,IAEHG,IAAO,CAACC,GAAYF,GAAeR,MAAkB;AACzD,QAAIU,EAAK,aAAa,GAAG;AACvB,YAAMxF,KAAKwF,EAAK,eAAe,IAAI,QAAQ,MAAM,GAAG,EAAE,QAAQ,OAAO,EAAE;AACvE,MAAIxF,MAAIoF,KAAOC,EAAKC,CAAK,GAAG,KAAK,KAAK,EAAE,MAAMtF,GAAG,MAAA8E,EAAA,CAAM;AACvD;AAAA,IACF;AACA,QAAIU,EAAK,aAAa,EAAG;AACzB,UAAMhB,IAAKgB,GACLC,IAAMjB,EAAG,QAAQ,YAAA;AACvB,QAAIiB,MAAQ,MAAM;AAChB,MAAKL,KAAKC,EAAKC,CAAK,GACpBF,IAAM;AACN;AAAA,IACF;AACA,UAAMM,IAAU,aAAa,KAAKD,CAAG,GAC/BrB,IAAQsB,KAAW,CAAC,OAAO,KAAK,MAAM,MAAM,MAAM,cAAc,KAAK,EAAE,SAASD,CAAG;AACzF,IAAIrB,MAAOgB,IAAM;AACjB,UAAMO,IAAMD,IAAU,OAAOA,EAAQ,CAAC,CAAC,IAAIJ,GACrC,IAAIG,MAAQ,OAAOA,MAAQ,WAAW,KAAQlB,GAAOC,CAAE,KAAKM;AAClE,eAAWc,KAASpB,EAAG,WAAY,CAAAe,EAAKK,GAAOD,GAAK,CAAC;AACrD,IAAIvB,MAAOgB,IAAM;AAAA,EACnB;AACA,aAAWQ,KAAS3B,EAAK,WAAY,CAAAsB,EAAKK,GAAO,GAAG,EAAK;AACzD,QAAMrP,IAAM4O,EAAM,IAAI,CAAC3O,MAAM;AAC3B,UAAM8M,IAAOoB,GAAQlO,EAAE,IAAI;AAC3B,WAAOA,EAAE,QAAQ,IAAI,GAAG,IAAI,OAAOA,EAAE,KAAK,CAAC,IAAI8M,EAAK,UAAA,CAAW,KAAKA;AAAA,EACtE,CAAC;AACD,SAAO/M,EAAI,UAAUA,EAAIA,EAAI,SAAS,CAAC,EAAE,KAAA,MAAW,KAAI,CAAAA,EAAI,IAAA;AAC5D,SAAOA,EAAI,KAAK;AAAA,CAAI;AACtB;AAOO,SAASsP,GAAoBlK,GAAyB;AAC3D,SAAOA,EAAQ,QAAQ,uBAAuB;AAAA,CAAQ;AACxD;AClFO,MAAMmK,KAAmB,IACnBC,KAAgB,IAEhBC,KAAuB,KAGvBC,KAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAGMC,KAAa;AAAA,EACjB,EAAE,OAAO,GAAG,OAAO,QAAA;AAAA,EACnB,EAAE,OAAO,GAAG,OAAO,UAAA;AAAA,EACnB,EAAE,OAAO,GAAG,OAAO,aAAA;AAAA,EACnB,EAAE,OAAO,GAAG,OAAO,OAAA;AACrB,GAEMC,KAAQ,IACRC,KAAQ,IACRC,KAAc,IACdC,KAAY,GACZC,KAAO,CAAC,MAAuC,EAAE,gBAAA;AAevD,SAASC,GAAUhC,GAAiB;AAClC,QAAMiC,IAAMjC,EAAG,cAAc,aAAA;AAC7B,MAAI,CAACiC,EAAK;AACV,QAAMC,IAAQlC,EAAG,cAAc,YAAA;AAC/B,EAAAkC,EAAM,mBAAmBlC,CAAE,GAC3BiC,EAAI,gBAAA,GACJA,EAAI,SAASC,CAAK;AACpB;AAEA,SAASC,GAAWnC,GAAiB;AACnC,QAAMiC,IAAMjC,EAAG,cAAc,aAAA;AAC7B,MAAI,CAACiC,EAAK;AACV,QAAMC,IAAQlC,EAAG,cAAc,YAAA;AAC/B,EAAAkC,EAAM,mBAAmBlC,CAAE,GAC3BkC,EAAM,SAAS,EAAK,GACpBD,EAAI,gBAAA,GACJA,EAAI,SAASC,CAAK;AACpB;AAEA,SAASE,GAAO;AAAA,EACd,QAAAC;AAAA,EACA,WAAAlD;AAAA,EACA,UAAAmD;AAAA,EACA,UAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,UAAAC;AAAA,EACA,eAAAC;AAAA,EACA,iBAAAC;AACF,GAAoD;AAClD,QAAM,CAACC,GAAMC,CAAO,IAAIhN,EAA8B,CAAA,CAAE,GAClD,CAACiN,GAAcC,CAAe,IAAIlN,EAAwB,IAAI,GAC9D,CAACmN,GAAiBC,CAAkB,IAAIpN,EAAwB,IAAI,GACpE,CAACqN,GAAaC,CAAc,IAAItN,EAAwB,IAAI,GAC5D,CAACuN,GAAMC,CAAO,IAAIxN,EAAkC,IAAI,GACxDyN,IAAO5J,GAAoB,IAAI,GAC/B6J,IAAS7J,GAA2B,IAAI,GAExC8J,IAAgB9J,GAA4B,IAAI;AAsBtD,MAnBA5D,GAAU,MAAM;AACd,QAAI,CAACgN,KAAgB,CAACE,EAAiB;AACvC,UAAMS,IAASX,IACX,kBAAkBA,CAAY,2BAA2BA,CAAY,OACrE,wBAAwBE,CAAe,8BAA8BA,CAAe,MAClFU,IAAS,CAACzJ,MAAoB;;AAClC,YAAMuB,IAAIvB,EAAE;AACZ,WAAI7J,KAAAoL,KAAA,gBAAAA,EAAG,YAAH,QAAApL,GAAA,KAAAoL,GAAaiI,GAAS;AAE1B,YAAME,IAAS,SAAS;AACxB,OAAIC,KAAAD,KAAA,gBAAAA,EAAQ,YAAR,QAAAC,GAAA,KAAAD,GAAkB,+BAAkC,KAAA,GACxDZ,EAAgB,IAAI,GACpBE,EAAmB,IAAI,GACvBI,EAAQ,IAAI;AAAA,IACd;AACA,kBAAO,iBAAiB,eAAeK,GAAQ,EAAI,GAC5C,MAAM,OAAO,oBAAoB,eAAeA,GAAQ,EAAI;AAAA,EACrE,GAAG,CAACZ,GAAcE,CAAe,CAAC,GAE9B,CAACV,EAAU,QAAO;AACtB,QAAMuB,IAAW,CAACtB,KAAY,CAAC,CAACE,GAC1BqB,IAA4BzB,EAAO,YAAY,CAAA,GAC/C0B,IAAsB1B,EAAO,SAAS,CAAA,GACtC2B,IAAQ,CAACjW,MACb6U,EAAK7U,EAAE,EAAE,KAAK,EAAE,GAAGA,EAAE,SAAS,GAAG,GAAGA,EAAE,SAAS,GAAG,GAAGA,EAAE,KAAK,OAAO,GAAGA,EAAE,KAAK,OAAA,GACzEkW,IAAW,CAAClW,MAAiD;AACjE,UAAMmW,IAAIF,EAAMjW,CAAC;AACjB,WAAO;AAAA,MACL,MAAMmW,EAAE;AAAA,MACR,KAAKA,EAAE;AAAA,MACP,OAAOA,EAAE;AAAA,MACT,QAAQA,EAAE;AAAA,MACT,sBAAiCnW,EAAE;AAAA,IAAA;AAAA,EAExC,GACMoW,IAAY,CAAC5T,GAAY6T,MAC7B3B,KAAA,gBAAAA,EAAW,EAAE,GAAGJ,GAAQ,OAAO0B,EAAM,IAAI,CAACM,MAAOA,EAAE,OAAO9T,IAAK,EAAE,GAAG8T,GAAG,GAAGD,EAAA,IAAUC,CAAE,MAClFC,IAAe,CAAC/T,GAAY6T,MAChC3B,KAAA,gBAAAA,EAAW;AAAA,IACT,GAAGJ;AAAA,IACH,UAAUyB,EAAS,IAAI,CAAChN,MAAOA,EAAE,OAAOvG,IAAK,EAAE,GAAGuG,GAAG,GAAGsN,EAAA,IAAUtN,CAAE;AAAA,EAAA,IAIlEyN,IAAa,CAAChU,MAAe;AACjC,UAAMyP,IAAKuD,EAAO,SACZiB,IAAOT,EAAM,KAAK,CAACM,MAAMA,EAAE,OAAO9T,CAAE;AAC1C,QAAI,EAACyP,KAAA,QAAAA,EAAI,gBAAe,CAACwE,EAAM;AAC/B,UAAMC,IAAK/D,GAAmBV,CAAE;AAChC,IAAIyE,MAAOD,EAAK,WAASL,EAAU5T,GAAI,EAAE,SAASkU,GAAI;AAAA,EACxD,GACMC,IAAa,CAACnU,MAAe;AACjC,IAAA0S,EAAmB,IAAI,GACvBF,EAAgBxS,CAAE;AAAA,EACpB,GACMoU,IAAgB,CAACpU,MAAe;AACpC,IAAAwS,EAAgB,IAAI,GACpBE,EAAmB1S,CAAE;AAAA,EACvB,GACMqU,IAAY,CAACrU,GAAYsU,MAAsB;AACnD,IAAArB,EAAc,UAAUqB,KAAQ,MAChCH,EAAWnU,CAAE,GACb4S,EAAe5S,CAAE,GACjB8S,EAAQ,IAAI;AAAA,EACd,GAGMyB,IAAY,CAACT,MAAkB,CAACrE,MAA8B;AAClE,QAAI,CAACA,KAAMA,EAAG,QAAQ,UAAU,IAAK;AACrC,IAAAA,EAAG,QAAQ,QAAQ,KACnBuD,EAAO,UAAUvD,GACjBR,GAAeQ,GAAIqE,EAAE,OAAO,GAC5BrE,EAAG,MAAA;AACH,UAAM6E,IAAOrB,EAAc;AAC3B,IAAAA,EAAc,UAAU,MACpBqB,KACF7C,GAAUhC,CAAE,GACZ6E,EAAA,GACAN,EAAWF,EAAE,EAAE,QACCrE,CAAE;AAAA,EACtB,GAEM+E,IAAS,CAACxU,GAAYyU,GAAiBC,MAAiB;;AAC5D,IAAA5B,EAAQ,IAAI;AACZ,UAAM6B,IAAM,MAAM,SAAS,YAAYF,GAAS,IAAOC,CAAG;AAC1D,IAAI/B,MAAgB3S,OAAMH,IAAAmT,EAAO,YAAP,QAAAnT,EAAgB,gBACxC8U,EAAA,GACAX,EAAWhU,CAAE,KACRqU,EAAUrU,GAAI2U,CAAG;AAAA,EAC1B,GAEMC,IAAQ,CAACC,MACbA,EAAE,SAAS,SACP,EAAE,GAAGA,EAAE,MAAM,GAAGA,EAAE,KAAK,IAAIA,EAAE,IAAI,GAAGA,EAAE,KAAK,IAAIA,EAAE,GAAA,IACjD,EAAE,GAAGA,EAAE,MAAM,GAAG,KAAK,IAAIzD,IAAOyD,EAAE,KAAK,IAAIA,EAAE,EAAE,GAAG,GAAG,KAAK,IAAIxD,IAAOwD,EAAE,KAAK,IAAIA,EAAE,EAAE,EAAA,GAEpFC,IAAQ,CACZpL,GACAlM,GACAuX,GACA3P,MACG;AACH,QAAI,CAACkO,KAAY5J,EAAE,WAAW,EAAG;AACjC,IAAAA,EAAE,gBAAA,GACFA,EAAE,eAAA;AACF,UAAMmL,IAAU;AAAA,MACd,MAAAE;AAAA,MACA,IAAIvX,EAAE;AAAA,MACN,MAAA4H;AAAA,MACA,IAAIsE,EAAE;AAAA,MACN,IAAIA,EAAE;AAAA,MACN,MAAM+J,EAAMjW,CAAC;AAAA,MACb,IAAI;AAAA,MACJ,IAAI;AAAA,IAAA;AAEN,IAAAuV,EAAK,UAAU8B;AACf,UAAMG,KAAO,CAACC,OAAqB;AACjC,MAAAJ,EAAE,MAAMI,GAAG,UAAUJ,EAAE,OAAO5C,KAAQ,IACtC4C,EAAE,MAAMI,GAAG,UAAUJ,EAAE,OAAO5C,KAAQ,IACtCK,EAAQ,CAAC7Q,QAAO,EAAE,GAAGA,IAAG,CAACoT,EAAE,EAAE,GAAGD,EAAMC,CAAC,EAAA,EAAI;AAAA,IAC7C,GACMK,KAAK,MAAM;AAQf,UAPA,OAAO,oBAAoB,eAAeF,EAAI,GAC9C,OAAO,oBAAoB,aAAaE,EAAE,GAC1CnC,EAAK,UAAU,MACfT,EAAQ,CAAC7Q,OAAM;AACb,cAAM,EAAE,CAACoT,EAAE,EAAE,GAAGM,IAAO,GAAG9G,OAAS5M;AACnC,eAAO4M;AAAA,MACT,CAAC,GACGwG,EAAE,OAAO,KAAKA,EAAE,OAAO,EAAG;AAC9B,YAAMlB,KAAIiB,EAAMC,CAAC,GACXO,KAAM;AAAA,QACV,UAAU,EAAE,GAAGzB,GAAE,GAAG,GAAGA,GAAE,EAAA;AAAA,QACzB,MAAM,EAAE,OAAOA,GAAE,GAAG,QAAQA,GAAE,EAAA;AAAA,MAAE;AAElC,MAAIkB,EAAE,SAAS,aAAaA,EAAE,SAAS,UAAU1C,IAC/CA,EAAc0C,EAAE,IAAI,EAAE,IAAIA,EAAE,IAAI,IAAIA,EAAE,IAAI,IACjCA,EAAE,SAAS,SAAQjB,EAAUiB,EAAE,IAAIO,EAAG,IAC5CrB,EAAac,EAAE,IAAIO,EAAG;AAAA,IAC7B;AACA,WAAO,iBAAiB,eAAeJ,EAAI,GAC3C,OAAO,iBAAiB,aAAaE,EAAE;AAAA,EACzC,GAEMG,KAAMzG,IAAY,IAAIA,CAAS,KAAK,IACpC0G,KAAa,wBACbC,IAAcjC,IAAWE,EAAM,KAAK,CAACM,MAAMA,EAAE,OAAOvB,CAAY,IAAI,QACpEiD,IAAiBlC,IAAWC,EAAS,KAAK,CAAChN,MAAMA,EAAE,OAAOkM,CAAe,IAAI,QAC7EgD,IAAIxD,KAAQ,GACZyD,IAAe,CAAC5B,MAAiC;AACrD,UAAMH,IAAIF,EAAMK,CAAC;AAGjB,WAAO;AAAA,MACL,MAAMH,EAAE,IAAIA,EAAE,IAAI;AAAA,MAClB,KAAKA,EAAE;AAAA,MACP,WAAW,gCAAgCrC,KAAcmE,CAAC,cAAc,IAAIA,CAAC;AAAA,MAC7E,iBAAiB;AAAA,MAChB,sBAAiC3B,EAAE;AAAA,IAAA;AAAA,EAExC,GAGM6B,IAAa,CAACpP,GAAkBqP,MAA+B;AACnE,UAAMjC,IAAIF,EAAMlN,CAAC;AACjB,WAAO;AAAA,MACL,MAAMoN,EAAE;AAAA,MACR,KAAKA,EAAE;AAAA,MACP,WAAW,6BAA6BiC,IAAMH,CAAC,cAAc,IAAIA,CAAC;AAAA,MAClE,iBAAiB;AAAA,MAChB,sBAAiClP,EAAE;AAAA,IAAA;AAAA,EAExC,GACMsP,IAAY,CAChBC,GACAC,GACAC,GACAC,MAEA,gBAAA9J,EAAC,OAAA,EAAI,WAAU,sCAAqC,MAAK,QACtD,UAAA;AAAA,IAAA+E,GAAY,IAAI,CAAC3E,MAChB,gBAAAlG;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,MAAK;AAAA,QACL,MAAK;AAAA,QACL,gBAAckG,MAAMuJ;AAAA,QACpB,cAAY,UAAUvJ,CAAC;AAAA,QACvB,OAAOA;AAAA,QACP,WAAW,sBAAsBA,MAAMuJ,IAAU,YAAY,EAAE;AAAA,QAC/D,OAAO,EAAG,sBAAiCvJ,EAAA;AAAA,QAC3C,eAAa,GAAGyJ,CAAM;AAAA,QACtB,cAAYzJ;AAAA,QACZ,SAAS,MAAM;AACb,UAAAuG,EAAQ,IAAI,GACRvG,MAAMuJ,KAASG,EAAK1J,CAAC;AAAA,QAC3B;AAAA,MAAA;AAAA,MAbKA;AAAA,IAAA,CAeR;AAAA,IACD,gBAAAlG,EAAC,SAAA,EAAM,WAAU,8CAA6C,OAAM,UAClE,UAAA,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAY,UAAU0P,CAAK;AAAA,QAC3B,eAAa,GAAGC,CAAM;AAAA,QACtB,OAAOF;AAAA,QACP,UAAU,CAACpM,MAAMuM,EAAKvM,EAAE,cAAc,KAAK;AAAA,MAAA;AAAA,IAAA,EAC7C,CACF;AAAA,EAAA,GACF,GAIIwM,KAAY,CAACxM,MAA2D;AAC5E,IAAMA,EAAE,OAAmB,QAAQ,OAAO,OAAK,eAAA;AAAA,EACjD;AACA,SAAOyM;AAAA,IACL,gBAAAhK,EAAAwB,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAxB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,uCAAuCkJ,EAAG;AAAA,UACrD,OAAO,EAAE,QAAQtE,GAAA;AAAA,UACjB,eAAY;AAAA,UAEX,UAAA;AAAA,YAAAwC,EAAS,IAAI,CAAChN,MACb,gBAAAF;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAW,qBAAqBoM,MAAoBlM,EAAE,KAAK,cAAc,EAAE;AAAA,gBAC3E,OAAOmN,EAASnN,CAAC;AAAA,gBACjB,mBAAiBA,EAAE;AAAA,gBACnB,eAAY;AAAA,gBAEX,UAAA+M,KACC,gBAAAjN;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,WAAW,mBAAmBiP,EAAU;AAAA,oBACxC,eAAY;AAAA,oBACZ,eAAe,CAAC5L,MAAMoL,EAAMpL,GAAGnD,GAAG,WAAW,QAAQ;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACvD;AAAA,cAXGA,EAAE;AAAA,YAAA,CAcV;AAAA,YAGAgN,EAAS;AAAA,cAAI,CAAChN,OACbiP,KAAA,gBAAAA,EAAgB,QAAOjP,EAAE,KAAK,OAC5B,gBAAAF;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAW,2BAA2BiN,IAAW,aAAagC,EAAU,KAAK,EAAE;AAAA,kBAC/E,OAAOK,EAAWpP,GAAGgL,EAAS;AAAA,kBAC9B,sBAAoBhL,EAAE;AAAA,kBACtB,eAAY;AAAA,kBACZ,OAAO+M,IAAW,iCAAiC;AAAA,kBACnD,eACEA,IACI,CAAC5J,MAAM;AACL,oBAAA0K,EAAc7N,EAAE,EAAE,GAClBuO,EAAMpL,GAAGnD,GAAG,WAAW,MAAM;AAAA,kBAC/B,IACA;AAAA,kBAGL,UAAAA,EAAE,UAAU+M,IAAW,qBAAqB;AAAA,gBAAA;AAAA,gBAfxC/M,EAAE;AAAA,cAAA;AAAA,YAgBT;AAAA,UAEJ;AAAA,QAAA;AAAA,MAAA;AAAA,MAEF,gBAAAF;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,oCAAoCgP,EAAG;AAAA,UAClD,OAAO,EAAE,QAAQrE,GAAA;AAAA,UACjB,eAAY;AAAA,UAEX,UAAAwC,EAAM,IAAI,CAACM,MAAM;AAChB,kBAAMsC,IAAU9C,KAAYX,MAAgBmB,EAAE;AAC9C,mBACE,gBAAA3H;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAW,kBAAkBoG,MAAiBuB,EAAE,KAAK,cAAc,EAAE;AAAA,gBACrE,OAAOJ,EAASI,CAAC;AAAA,gBACjB,gBAAcA,EAAE;AAAA,gBAChB,eAAY;AAAA,gBAIX,UAAA;AAAA,kBAAAsC,IACC,gBAAA/P;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBAEC,KAAKkO,EAAUT,CAAC;AAAA,sBAChB,WAAW,+CAA+CwB,EAAU;AAAA,sBACpE,iBAAe;AAAA,sBACf,gCAA8B;AAAA,sBAC9B,MAAK;AAAA,sBACL,UAAU;AAAA,sBACV,kBAAe;AAAA,sBACf,cAAW;AAAA,sBACX,eAAY;AAAA,sBACZ,eAAe9D;AAAA,sBACf,QAAQ,MAAM;AACZ,wBAAAwC,EAAWF,EAAE,EAAE,GACfd,EAAO,UAAU,MACjBJ,EAAe,IAAI;AAAA,sBACrB;AAAA,sBACA,WAAW,CAAClJ,MAAM;AAChB,wBAAIA,EAAE,QAAQ,YAAUA,EAAE,cAAc,KAAA;AAAA,sBAC1C;AAAA,sBACA,SAAS,CAACA,MAAM;AAEd,wBAAAA,EAAE,eAAA,GACF,SAAS;AAAA,0BACP;AAAA,0BACA;AAAA,0BACAA,EAAE,cAAc,QAAQ,YAAY;AAAA,wBAAA;AAAA,sBAExC;AAAA,oBAAA;AAAA,oBA3BI;AAAA,kBAAA,IA8BN,gBAAArD;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBAEC,WAAW,wBAAwBiP,EAAU;AAAA,sBAC7C,eAAY;AAAA,sBACZ,OAAOhC,IAAW,EAAE,QAAQ,QAAQ,aAAa,WAAW;AAAA,sBAC5D,eACEA,IACI,CAAC5J,MAAM;AACL,wBAAAyK,EAAWL,EAAE,EAAE,GACfgB,EAAMpL,GAAGoK,GAAG,QAAQ,MAAM;AAAA,sBAC5B,IACA;AAAA,sBAEN,eAAeR,IAAW,MAAMe,EAAUP,EAAE,EAAE,IAAI;AAAA,sBAEjD,YAAE,QAAQ,KAAA,IACT,gBAAAzN,EAACsI,MAAS,SAASmC,GAAoBgD,EAAE,OAAO,GAAG,IAEnDR,uBAAa,QAAA,EAAK,WAAU,yBAAwB,UAAA,wBAAA,CAAqB;AAAA,oBAAA;AAAA,oBAjBvE;AAAA,kBAAA;AAAA,kBAqBPA,KACC,gBAAAjN;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,WAAW,mBAAmBiP,EAAU;AAAA,sBACxC,eAAY;AAAA,sBACZ,eAAe,CAAC5L,MAAMoL,EAAMpL,GAAGoK,GAAG,QAAQ,QAAQ;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBACpD;AAAA,cAAA;AAAA,cAnEGA,EAAE;AAAA,YAAA;AAAA,UAuEb,CAAC;AAAA,QAAA;AAAA,MAAA;AAAA,MAEF0B,KACC,gBAAAnP;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,mBAAmBgP,EAAG;AAAA,UACjC,OAAO,EAAE,QAAQpE,GAAA;AAAA,UACjB,eAAY;AAAA,UAEZ,UAAA,gBAAA9E;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW,wCAAwCmJ,EAAU;AAAA,cAC7D,MAAK;AAAA,cACL,cAAW;AAAA,cACX,eAAY;AAAA,cACZ,wBAAsBE,EAAe;AAAA,cACrC,OAAOG,EAAWH,GAAgBlE,EAAW;AAAA,cAC7C,eAAeE;AAAA,cACf,aAAa0E;AAAA,cAEb,UAAA;AAAA,gBAAA,gBAAA7P;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,WAAU;AAAA,oBACV,cAAW;AAAA,oBACX,OAAM;AAAA,oBACN,eAAY;AAAA,oBACZ,eAAe,CAACqD,MAAMoL,EAAMpL,GAAG8L,GAAgB,WAAW,MAAM;AAAA,oBAEhE,UAAA,gBAAAnP,EAACgQ,IAAA,EAAK,MAAK,OAAA,CAAO;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEpB,gBAAAhQ;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,WAAU;AAAA,oBACV,cAAW;AAAA,oBACX,aAAY;AAAA,oBACZ,eAAY;AAAA,oBACZ,cAAcmP,EAAe;AAAA,oBAE7B,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,IAAIA,EAAe,MAAM,SAAS,CAAC,CAAC;AAAA,oBAC/D,QAAQ,CAAC9L,MAAM;AACb,4BAAMtI,IAAIsI,EAAE,cAAc;AAC1B,sBAAItI,MAAMoU,EAAe,SAAOzB,EAAayB,EAAe,IAAI,EAAE,OAAOpU,GAAG;AAAA,oBAC9E;AAAA,oBACA,WAAW,CAACsI,MAAM;AAChB,uBAAIA,EAAE,QAAQ,WAAWA,EAAE,QAAQ,aAAUA,EAAE,cAAc,KAAA;AAAA,oBAC/D;AAAA,kBAAA;AAAA,kBARK,GAAG8L,EAAe,EAAE,IAAIA,EAAe,KAAK;AAAA,gBAAA;AAAA,gBAUnD,gBAAAnP,EAAC,QAAA,EAAK,WAAU,uBAAA,CAAuB;AAAA,gBACvC,gBAAA8F,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,kBAAA,gBAAAA;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,MAAK;AAAA,sBACL,WAAW,eAAe0G,MAAS,UAAU,YAAY,EAAE;AAAA,sBAC3D,cAAW;AAAA,sBACX,iBAAeA,MAAS;AAAA,sBACxB,OAAM;AAAA,sBACN,eAAY;AAAA,sBACZ,SAAS,MAAMC,EAAQD,MAAS,UAAU,OAAO,OAAO;AAAA,sBAExD,UAAA;AAAA,wBAAA,gBAAAxM,EAAC,QAAA,EAAK,WAAU,kBAAA,CAAkB;AAAA,wBAClC,gBAAAA,EAACgQ,IAAA,EAAK,MAAK,gBAAe,MAAM,GAAA,CAAI;AAAA,sBAAA;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBAErCxD,MAAS,WACRgD;AAAA,oBAAUL,EAAe;AAAA,oBAAO;AAAA,oBAAW;AAAA,oBAAiB,CAACjJ,MAC3DwH,EAAayB,EAAe,IAAI,EAAE,OAAOjJ,GAAG;AAAA,kBAAA;AAAA,gBAC9C,GACJ;AAAA,gBACA,gBAAAlG,EAAC,QAAA,EAAK,WAAU,uBAAA,CAAuB;AAAA,gBACvC,gBAAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,WAAU;AAAA,oBACV,cAAW;AAAA,oBACX,OAAM;AAAA,oBACN,eAAY;AAAA,oBACZ,SAAS,MAAM;AACb,sBAAAyM,EAAQ,IAAI,GACZV,KAAA,QAAAA,EAAkB,WAAWoD,EAAe;AAAA,oBAC9C;AAAA,oBAEA,UAAA,gBAAAnP,EAACgQ,IAAA,EAAK,MAAK,QAAA,CAAQ;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACrB;AAAA,YAAA;AAAA,UAAA;AAAA,QACF;AAAA,MAAA;AAAA,MAGHd,KACC,gBAAAlP;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,mBAAmBgP,EAAG;AAAA,UACjC,OAAO,EAAE,QAAQpE,GAAA;AAAA,UACjB,eAAY;AAAA,UAEZ,UAAA,gBAAA9E;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW,oBAAoBmJ,EAAU;AAAA,cACzC,MAAK;AAAA,cACL,cAAW;AAAA,cACX,eAAY;AAAA,cACZ,qBAAmBC,EAAY;AAAA,cAC/B,OAAOG,EAAaH,CAAW;AAAA,cAC/B,eAAe/D;AAAA,cACf,aAAa0E;AAAA,cAEb,UAAA;AAAA,gBAAA,gBAAA7P;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,WAAU;AAAA,oBACV,cAAW;AAAA,oBACX,OAAM;AAAA,oBACN,eAAY;AAAA,oBACZ,eAAe,CAACqD,MAAMoL,EAAMpL,GAAG6L,GAAa,QAAQ,MAAM;AAAA,oBAE1D,UAAA,gBAAAlP,EAACgQ,IAAA,EAAK,MAAK,OAAA,CAAO;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEpB,gBAAAhQ,EAAC,QAAA,EAAK,WAAU,uBAAA,CAAuB;AAAA,gBACvC,gBAAA8F,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,kBAAA,gBAAAA;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,MAAK;AAAA,sBACL,WAAW,eAAe0G,MAAS,UAAU,YAAY,EAAE;AAAA,sBAC3D,cAAW;AAAA,sBACX,iBAAeA,MAAS;AAAA,sBACxB,OAAM;AAAA,sBACN,eAAY;AAAA,sBACZ,SAAS,MAAMC,EAAQD,MAAS,UAAU,OAAO,OAAO;AAAA,sBAExD,UAAA;AAAA,wBAAA,gBAAAxM,EAAC,QAAA,EAAK,WAAU,kBAAA,CAAkB;AAAA,wBAClC,gBAAAA,EAACgQ,IAAA,EAAK,MAAK,gBAAe,MAAM,GAAA,CAAI;AAAA,sBAAA;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBAErCxD,MAAS,WACRgD;AAAA,oBAAUN,EAAY;AAAA,oBAAO;AAAA,oBAAQ;AAAA,oBAAc,CAAChJ,MAClDqH,EAAU2B,EAAY,IAAI,EAAE,OAAOhJ,GAAG;AAAA,kBAAA;AAAA,gBACxC,GACJ;AAAA,gBACA,gBAAAlG,EAAC,QAAA,EAAK,WAAU,uBAAA,CAAuB;AAAA,gBACvC,gBAAA8F,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,kBAAA,gBAAAA;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,MAAK;AAAA,sBACL,WAAW,iCAAiC0G,MAAS,SAAS,YAAY,EAAE;AAAA,sBAC5E,cAAW;AAAA,sBACX,iBAAeA,MAAS;AAAA,sBACxB,OAAM;AAAA,sBACN,eAAY;AAAA,sBACZ,SAAS,MAAMC,EAAQD,MAAS,SAAS,OAAO,MAAM;AAAA,sBACvD,UAAA;AAAA,wBAAA;AAAA,wBAEC,gBAAAxM,EAACgQ,IAAA,EAAK,MAAK,gBAAe,MAAM,GAAA,CAAI;AAAA,sBAAA;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBAErCxD,MAAS,UACR,gBAAAxM,EAAC,OAAA,EAAI,WAAU,qCAAoC,MAAK,QACrD,UAAA8K,GAAW,IAAI,CAAC5K,MACf,gBAAAF;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBAEC,MAAK;AAAA,sBACL,MAAK;AAAA,sBACL,WAAW,oCAAoCE,EAAE,KAAK;AAAA,sBACtD,eAAa,aAAaA,EAAE,KAAK;AAAA,sBACjC,SAAS,MACPiO,EAAOe,EAAY,IAAI,eAAehP,EAAE,QAAQ,KAAKA,EAAE,KAAK,MAAM,OAAO;AAAA,sBAG1E,UAAAA,EAAE;AAAA,oBAAA;AAAA,oBATEA,EAAE;AAAA,kBAAA,CAWV,EAAA,CACH;AAAA,gBAAA,GAEJ;AAAA,gBACA,gBAAAF;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,WAAU;AAAA,oBACV,cAAW;AAAA,oBACX,OAAM;AAAA,oBACN,eAAY;AAAA,oBACZ,SAAS,MAAMmO,EAAOe,EAAY,IAAI,MAAM;AAAA,oBAE5C,UAAA,gBAAAlP,EAACgQ,IAAA,EAAK,MAAK,OAAA,CAAO;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEpB,gBAAAhQ,EAAC,QAAA,EAAK,WAAU,uBAAA,CAAuB;AAAA,gBACvC,gBAAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,WAAU;AAAA,oBACV,cAAW;AAAA,oBACX,OAAM;AAAA,oBACN,eAAY;AAAA,oBACZ,SAAS,MAAM;AACb,sBAAAyM,EAAQ,IAAI,GACZV,KAAA,QAAAA,EAAkB,QAAQmD,EAAY;AAAA,oBACxC;AAAA,oBAEA,UAAA,gBAAAlP,EAACgQ,IAAA,EAAK,MAAK,QAAA,CAAQ;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACrB;AAAA,YAAA;AAAA,UAAA;AAAA,QACF;AAAA,MAAA;AAAA,IACF,GAEJ;AAAA,IACAtE;AAAA,EAAA;AAEJ;AAEA,SAASuE,GAAaC,GAAyB;AAC7C,QAAMxE,IAAWyE,GAAS,CAAC,MAAA;;AAAM,aAAA3W,IAAA,EAAE,YAAF,gBAAAA,EAAW,cAAc,6BAA4B;AAAA,GAAI,GACpFoS,IAAOuE,GAAS,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAC3C,SAAO,gBAAAnQ,EAACwL,MAAQ,GAAG0E,GAAO,MAAMA,EAAM,QAAQtE,GAAM,UAAAF,GAAoB;AAC1E;AAMO,SAAS0E,GAAYF,GAAyB;AACnD,SAAIA,EAAM,aAAa,2BACb1E,IAAA,EAAQ,GAAG0E,GAAO,UAAUA,EAAM,UAAU,IAE/C,gBAAAlQ,EAACiQ,IAAA,EAAc,GAAGC,EAAA,CAAO;AAClC;ACzoBO,MAAMG,KAA4D;AAAA,EACvE,KAAK;AAAA,IACH,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,cAAc;AAAA,EAAA;AAAA,EAEhB,gBAAgB,EAAE,SAAS,QAAQ,aAAa,oBAAA;AAAA,EAChD,eAAe;AAAA,IACb,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,aAAa;AAAA,EAAA;AAAA,EAEf,gBAAgB,EAAE,UAAU,QAAQ,cAAc,MAAA;AAAA,EAClD,eAAe;AAAA,IACb,YAAY;AAAA,IACZ,eAAe;AAAA,EAAA;AAAA,EAEjB,YAAY,EAAE,aAAa,kBAAA;AAC7B;ACvCO,SAASC,KAAoB;AAClC,MAAIC,GACAC,IAAS,GACTC,IAAY;AAChB,QAAMC,wBAAc,IAAA,GACdC,IAAS,MAAM;AACnB,IAAAJ,KAAA,QAAAA,EAAQ,aACRA,IAAS;AACT,eAAWK,KAAWF,EAAQ,OAAA,EAAU,CAAAE,EAAQ,CAAA,CAAE;AAClD,IAAAF,EAAQ,MAAA;AAAA,EACV,GACMG,IAAS,OAAOC,MAAiE;AACrF,UAAMla,IAAOka,EAAQ,YAAY,QAAQ;AACzC,QACEL,KACA,CAAC7Z,KACA,CAACka,EAAQ,YACRla,EAAK,SAASA,EAAK,MACnBka,EAAQ,MAAM,SAASA,EAAQ,MAAM,GAAGA,EAAQ,GAAG,MAAM;AAE3D,aAAO;AACT,IAAKP,MACHA,IAAS,IAAI,OAAO,IAAA;AAAA;AAAA,MAAA,KAAA,IAAA,IAAA,+CAAA,YAAA,GAAA,EAAA;AAAA,MAAA,YAAA;AAAA,IAAA,GAA2D;AAAA,MAC7E,MAAM;AAAA,IAAA,CACP,GACDA,EAAO,YAAY,CAACQ,MAAqE;;AACvF,OAAAvX,IAAAkX,EAAQ,IAAIK,EAAM,KAAK,EAAE,MAAzB,QAAAvX,EAA6BuX,EAAM,KAAK,UACxCL,EAAQ,OAAOK,EAAM,KAAK,EAAE;AAAA,IAC9B,GACAR,EAAO,UAAUI;AAEnB,UAAMK,IAAU,MAAM,IAAI,QAA4B,CAACJ,MAAY;AACjE,YAAMjX,IAAK,EAAE6W;AACb,MAAAE,EAAQ,IAAI/W,GAAIiX,CAAO,GACvBE,EAAQ;AAAA,QACN;AAAA,QACA,MAAM;AACJ,UAAAJ,EAAQ,OAAO/W,CAAE,GACjBiX,EAAQ,CAAA,CAAE;AAAA,QACZ;AAAA,QACA,EAAE,aAAa,GAAA;AAAA,MAAK,GAEtBL,KAAA,QAAAA,EAAQ,YAAY,EAAE,IAAA5W,GAAI,MAAMmX,EAAQ,MAAM,IAAI,SAAA,GAAY,UAAUA,EAAQ,IAAA;AAAA,IAClF,CAAC;AACD,WAAOA,EAAQ,WAAW,CAACE,EAAQ,SAAS,OAAO,EAAE,MAAMpa,EAAK,MAAM,SAAAoa,EAAA;AAAA,EACxE;AACA,SAAO;AAAA,IACLC,GAAmB,KAAK,GAAG,EAAE,cAAcJ,GAAQ;AAAA,IACnDK,GAAW,OAAO,OAChBT,IAAY,IACL;AAAA,MACL,UAAU;AACR,QAAAA,IAAY,IACZE,EAAA;AAAA,MACF;AAAA,IAAA,EAEH;AAAA,EAAA;AAEL;AC1CA,SAASQ,GAAkBC,GAAqC;AAC9D,UAAQA,GAAA;AAAA,IACN,KAAK;AACH,aAAOC,GAAA;AAAA,IACT,KAAK;AACH,aAAOA,GAAW,EAAE,YAAY,IAAM;AAAA,IACxC,KAAK;AACH,aAAOC,GAAA;AAAA,EAAO;AAEpB;AAuCO,SAASC,GAAWrB,GAAwB;AACjD,QAAMtQ,IAAQf,GAAkBqR,EAAM,KAAK,GACrCsB,IAAaC;AAAA,IACjB,MAAM;AAAA,MACJ,GAAIvB,EAAM,WAAW,CAACiB,GAAkBjB,EAAM,QAAQ,CAAC,IAAI,CAAA;AAAA,MAC3D,GAAIA,EAAM,aAAa,gBAAgBA,EAAM,aAAa,eACtD,CAACI,GAAA,CAAmB,IACpB,CAAA;AAAA,MACJoB,GAAW,MAAMrB,EAAiB;AAAA,IAAA;AAAA,IAEpC,CAACH,EAAM,QAAQ;AAAA,EAAA;AAGjB,SACE,gBAAAlQ,EAAC,SAAI,WAAU,mBAAkB,cAAYkQ,EAAM,YAAY,KAAK,eAClE,UAAA,gBAAAlQ;AAAA,IAAC2R;AAAA,IAAA;AAAA,MACC,OAAOzB,EAAM;AAAA,MACb,UAAUA,EAAM;AAAA,MAChB,YAAAsB;AAAA,MACA,aAAatB,EAAM;AAAA,MACnB,UAAUA,EAAM;AAAA,MAChB,OAAAtQ;AAAA,MACA,QAAQsQ,EAAM;AAAA,MACd,WAAWA,EAAM,aAAa;AAAA,MAC9B,WAAWA,EAAM;AAAA,MACjB,gBAAgBA,EAAM;AAAA,MACtB,YAAY;AAAA,QACV,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,qBAAqB,CAACA,EAAM;AAAA,QAC5B,iBAAiB;AAAA,QACjB,eAAe;AAAA,MAAA;AAAA,IACjB;AAAA,EAAA,GAEJ;AAEJ;ACpBA,SAAS0B,KAAsB;AAC7B,QAAMC,IAAQC,GAAA;AACd,SAAO,CAACC,MAAsBA,EAAK,MAAM,IAAI,WAAW,KAAA,MAAW,KAAK,KAAKF,EAAME,CAAI;AACzF;AAaO,SAASC,GAAW9B,GAAwB;AACjD,QAAMtQ,IAAQf,GAAkBqR,EAAM,KAAK,GAIrC,EAAE,QAAA+B,GAAQ,MAAAC,EAAA,IAASC,GAAmBjC,EAAM,KAAK,GACjDsB,IAAaC;AAAA,IACjB,MAAM;AAAA,MACJW,GAAA;AAAA,MACA,GAAIlC,EAAM,oBAAoB,KAAQ,CAAA,IAAK,CAACmC,GAAOT,GAAA,CAAqB,GAAGU,IAAY;AAAA,MACvFZ,GAAW,MAAMrB,EAAiB;AAAA,IAAA;AAAA,IAEpC,CAACH,EAAM,eAAe;AAAA,EAAA;AAGxB,WAASqC,EAAa5N,GAAc;;AAElC,QADAuL,EAAM,SAASvL,CAAI,GACf,GAACuL,EAAM,iBAAiB,CAACA,EAAM,mBACnC;AAAA,UAAIvL,EAAK,OAAO,WAAW,GAAG;AAC5B,SAAAnL,IAAA0W,EAAM,qBAAN,QAAA1W,EAAA,KAAA0W,GAAyB,EAAE,OAAO,IAAO,OAAO;AAChD;AAAA,MACF;AACA,UAAI;AACF,cAAMsC,IAAS,KAAK,MAAM7N,CAAI;AAC9B,SAAAqI,IAAAkD,EAAM,kBAAN,QAAAlD,EAAA,KAAAkD,GAAsBsC,KACtBC,IAAAvC,EAAM,qBAAN,QAAAuC,EAAA,KAAAvC,GAAyB,EAAE,OAAO,GAAA;AAAA,MACpC,SAAS7M,GAAG;AACV,SAAAqP,IAAAxC,EAAM,qBAAN,QAAAwC,EAAA,KAAAxC,GAAyB,EAAE,OAAO,IAAO,OAAQ7M,EAAY;MAC/D;AAAA;AAAA,EACF;AAEA,SACE,gBAAAyC,EAAC,SAAI,WAAU,mBAAkB,cAAYoK,EAAM,YAAY,KAAK,eAClE,UAAA;AAAA,IAAA,gBAAAlQ;AAAA,MAAC2R;AAAA,MAAA;AAAA,QACC,OAAOzB,EAAM;AAAA,QACb,UAAUqC;AAAA,QACV,YAAAf;AAAA,QACA,aAAatB,EAAM;AAAA,QACnB,UAAUA,EAAM;AAAA,QAOhB,UAAU,CAACA,EAAM;AAAA,QACjB,OAAAtQ;AAAA,QACA,QAAQsQ,EAAM;AAAA,QACd,WAAWA,EAAM,aAAa;AAAA,QAC9B,WAAWA,EAAM;AAAA,QACjB,gBAAgBA,EAAM;AAAA,QACtB,QAAQA,EAAM;AAAA,QACd,SAASA,EAAM;AAAA,QACf,YAAY;AAAA,UACV,aAAa;AAAA,UACb,YAAY;AAAA,UACZ,qBAAqB,CAACA,EAAM;AAAA,UAC5B,gBAAgB;AAAA,UAChB,iBAAiB;AAAA,UACjB,eAAe;AAAA,QAAA;AAAA,MACjB;AAAA,IAAA;AAAA,IAEDA,EAAM;AAAA,IACNA,EAAM,YACL,gBAAApK,EAAAwB,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAtH;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAW,gCAAgCiS,IAAS,eAAe,EAAE;AAAA,UACrE,cAAW;AAAA,UACX,SAAS,MAAM,KAAKC,EAAA;AAAA,UAEnB,UAAAD,IAAS,gBAAAjS,EAAC2S,IAAA,CAAA,CAAW,sBAAMC,IAAA,CAAA,CAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAKxC,gBAAA5S,EAAC,UAAK,WAAU,uBAAsB,aAAU,UAC7C,UAAAiS,IAAS,WAAW,GAAA,CACvB;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;AChJO,SAASY,GACd5b,GACA6b,GACAC,GACS;AACT,SAAO9b,IAAQ6b,IAAe,MAAMC;AACtC;AAGO,SAASC,GAAchC,GAA2B5T,GAAiC;AACxF,QAAM2J,IAAI3J,EAAM,KAAA,EAAO,YAAA;AACvB,SAAK2J,IACEiK,EAAQ;AAAA,IACb,CAACiC,MAAMA,EAAE,MAAM,cAAc,SAASlM,CAAC,KAAKkM,EAAE,MAAM,YAAA,EAAc,SAASlM,CAAC;AAAA,EAAA,IAF/DiK;AAIjB;AAEO,MAAMkC,KAA0B,KAEjCC,KAA8B;AAAA,EAClC,SAAS;AAAA,EACT,UAAU;AAAA,EACV,SAAS;AAAA,EACT,UAAU;AAAA,EACV,cAAc;AAAA,EACd,YAAY;AACd,GAGMC,KAA4B;AAAA,EAChC,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AAAA,EACP,KAAK;AAAA,EACL,WAAW;AAAA;AAAA;AAAA,EAGX,oBAAoB;AAAA,EACpB,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,WAAW;AACb;AAEO,SAASC,GAAS;AAAA,EACvB,SAAArC;AAAA,EACA,OAAAnN;AAAA,EACA,UAAAgI;AAAA,EACA,aAAAyH;AAAA,EACA,UAAAC;AAAA,EACA,cAAcC;AAAA,EACd,MAAAzU,IAAO;AAAA,EACP,gBAAA0U,IAAiB;AAAA,EACjB,cAAAX,IAAe;AAAA,EACf,eAAAY,IAAgBR;AAAA,EAChB,WAAA3K;AAAA,EACA,eAAAoL;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,QAAAC;AACF,GAAkB;;AAChB,QAAMC,IACJ/U,MAAS,cACRA,MAAS,UACR8T;AAAA,IACE7B,EAAQ;AAAA,IACR8B;AAAA,IACA,OAAO,SAAW,MAAc,IAAI,OAAO;AAAA,EAAA,GAG3CnZ,IAAKoa,GAAA,GACLC,MACJxa,IAAAwX,EAAQ,KAAK,CAACiC,MAAMA,EAAE,UAAUpP,CAAK,MAArC,gBAAArK,EAAwC,WAAUia,IAAiB,KAAK5P,IACpE,CAACqE,GAAM+L,CAAO,IAAIhV,EAAS+U,CAAa,GACxC,CAAC/J,GAAMiK,CAAO,IAAIjV,EAAS,EAAK,GAChC,CAACkV,GAAWC,CAAY,IAAInV,EAAS,EAAK,GAC1C,CAAC8N,GAAQsH,CAAS,IAAIpV,EAAS,CAAC,GAChCqV,IAAUxR,GAAuB,IAAI;AAE3C,EAAA5D,GAAU,MAAM;AACd,IAAA+U,EAAQD,CAAa;AAAA,EACvB,GAAG,CAACA,CAAa,CAAC;AAElB,QAAMO,IAAQ9C;AAAA,IACZ,MAAO0C,IAAYnB,GAAchC,GAAS9I,CAAI,IAAI8I;AAAA,IAClD,CAACA,GAAS9I,GAAMiM,CAAS;AAAA,EAAA,GAErBK,IAAY/C;AAAA,IAChB,OAAO,EAAE,GAAG2B,IAAY,WAAWM,EAAA;AAAA,IACnC,CAACA,CAAa;AAAA,EAAA;AAGhB,MAAI,CAACI;AACH,WACE,gBAAAhO;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAAyC;AAAA,QACA,OAAA1E;AAAA,QACA,UAAA0P;AAAA,QACA,cAAYC;AAAA,QACZ,UAAU,CAACnQ,MAAMwI,EAASxI,EAAE,OAAO,KAAK;AAAA,QAEvC,UAAA;AAAA,UAAAiQ,MAAgB,UAAazP,MAAU,MACtC,gBAAA7D,EAAC,YAAO,OAAM,IAAG,UAAQ,IACtB,UAAAsT,EAAA,CACH;AAAA,UAEDtC,EAAQ,IAAI,CAACiC,MACZ,gBAAAjT,EAAC,UAAA,EAAqB,OAAOiT,EAAE,OAC5B,UAAAA,EAAE,MAAA,GADQA,EAAE,KAEf,CACD;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAKP,QAAMwB,IAAQ,CAACC,MAAc,GAAG/a,CAAE,QAAQ+a,CAAC,IAErCC,IAAQ,MAAM;AAClB,IAAAT,EAAQ,EAAK,GACbE,EAAa,EAAK;AAAA,EACpB,GAEMxE,IAAO,CAACqD,MAAsB;AAClC,IAAAgB,EAAQhB,EAAE,KAAK,GACfpH,EAASoH,EAAE,KAAK,GAChB0B,EAAA;AAAA,EACF,GAEMC,IAAY,CAACvR,MAA6C;AAC9D,IAAIA,EAAE,QAAQ,eACZA,EAAE,eAAA,GACG4G,IACAoK,EAAU,CAACnd,MAAM,KAAK,IAAIA,IAAI,GAAGqd,EAAM,SAAS,CAAC,CAAC,IAD5CL,EAAQ,EAAI,KAEd7Q,EAAE,QAAQ,aACnBA,EAAE,eAAA,GACG4G,IACAoK,EAAU,CAACnd,MAAM,KAAK,IAAIA,IAAI,GAAG,CAAC,CAAC,IAD7Bgd,EAAQ,EAAI,KAEd7Q,EAAE,QAAQ,UACf4G,KAAQsK,EAAMxH,CAAM,KACtB1J,EAAE,eAAA,GACFuM,EAAK2E,EAAMxH,CAAM,CAAC,KACR0G,MACNvL,MAAS8L,KAAenI,EAAS3D,CAAI,GACzCyM,EAAA,KAEOtR,EAAE,QAAQ,aACf4G,OAAQ,gBAAA,GACZgK,EAAQD,CAAa,GACrBW,EAAA;AAAA,EAEJ,GAEME,IAAS,MAAM;AACnB,IAAIpB,MAAwBO,CAAa,IAChC9L,MAAS8L,KAAenI,EAAS3D,CAAI,GAC9CyM,EAAA;AAAA,EACF;AAEA,SACE,gBAAA7O,EAAC,OAAA,EAAI,KAAKwO,GAAS,WAAU,gBAAe,OAAO,EAAE,UAAU,WAAA,GAC7D,UAAA;AAAA,IAAA,gBAAAtU;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,MAAK;AAAA,QACL,WAAAuI;AAAA,QACA,OAAOL;AAAA,QACP,UAAAqL;AAAA,QACA,aAAAD;AAAA,QACA,cAAYE;AAAA,QACZ,iBAAevJ;AAAA,QACf,iBAAe,GAAGtQ,CAAE;AAAA,QACpB,qBAAkB;AAAA,QAClB,yBAAuBsQ,KAAQsK,EAAMxH,CAAM,IAAI0H,EAAM1H,CAAM,IAAI;AAAA,QAC/D,cAAa;AAAA,QACb,SAAS,MAAMmH,EAAQ,EAAI;AAAA,QAC3B,UAAU,CAAC7Q,MAAM;AACf,UAAA4Q,EAAQ5Q,EAAE,OAAO,KAAK,GACtBsQ,KAAA,QAAAA,EAAgBtQ,EAAE,OAAO,QACzB+Q,EAAa,EAAI,GACjBC,EAAU,CAAC,GACXH,EAAQ,EAAI;AAAA,QACd;AAAA,QACA,WAAAU;AAAA,QACA,QAAAC;AAAA,MAAA;AAAA,IAAA;AAAA,IAED5K,KACC,gBAAAnE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAI,GAAGnM,CAAE;AAAA,QAET,MAAK;AAAA,QACL,UAAU;AAAA,QACV,cAAY6Z;AAAA,QACZ,OAAOgB;AAAA,QAEN,UAAA;AAAA,UAAAD,EAAM,IAAI,CAACtB,GAAGyB,MACb,gBAAA5O;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,IAAI2O,EAAMC,CAAC;AAAA,cAEX,MAAK;AAAA,cACL,UAAU;AAAA,cACV,iBAAezB,EAAE,UAAUpP;AAAA,cAC3B,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,YAAY6Q,MAAM3H,IAAS,uBAAuB;AAAA,cAAA;AAAA,cAEpD,aAAa,CAAC1J,OAAM;AAClB,gBAAAA,GAAE,eAAA,GACFuM,EAAKqD,CAAC;AAAA,cACR;AAAA,cACA,cAAc,MAAMoB,EAAUK,CAAC;AAAA,cAE9B,UAAA;AAAA,gBAAAzB,EAAE;AAAA,gBACFA,EAAE,WAAW,UACZ,gBAAAjT,EAAC,QAAA,EAAK,WAAU,uBAAsB,OAAOmT,IAC1C,UAAAF,EAAE,OAAA,CACL;AAAA,cAAA;AAAA,YAAA;AAAA,YAtBGA,EAAE;AAAA,UAAA,CAyBV;AAAA,UACAsB,EAAM,WAAW,KAChB,gBAAAvU,EAAC,SAAI,MAAK,gBAAe,OAAO,EAAE,SAAS,WAAW,SAAS,IAAA,GAC5D,UAAA4T,GACH;AAAA,UAEDC,MAAW,UACV,gBAAA7T;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,OAAO,EAAE,SAAS,WAAW,SAAS,KAAK,UAAU,SAAA;AAAA,cAEpD,UAAA6T;AAAA,YAAA;AAAA,UAAA;AAAA,QACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAEJ,GAEJ;AAEJ;ACnCO,SAASiB,GAAsB7B,GAAiC;AACrE,SACE,OAAOA,KAAM,YACbA,MAAM,QACN,CAAC,MAAM,QAAQA,CAAC,KACfA,EAA2B,WAAW;AAE3C;AAiZO,SAAS8B,GAAYha,GAA4B;AACtD,SACE,OAAOA,KAAM,YACbA,MAAM,QACN,CAAC,MAAM,QAAQA,CAAC,KACfA,EAAyB,SAAS,UACnC,MAAM,QAASA,EAA0B,KAAK;AAElD;AAGO,SAASia,GAAcja,GAA8B;AAC1D,SACE,OAAOA,KAAM,YACbA,MAAM,QACN,CAAC,MAAM,QAAQA,CAAC,KACfA,EAAyB,SAAS,YACnC,OAAQA,EAA+B,cAAe,YACtD,OAAQA,EAAuB,MAAO;AAE1C;ACloBA,SAASka,GAAWhY,GAAuB;AACzC,SAAIA,EAAE,SAAS,SAAe,EAAE,MAAM,QAAQ,OAAOA,EAAE,SAAS,GAAA,IAC5DA,EAAE,SAAS,SAAe,EAAE,MAAM,QAAQ,MAAMA,EAAE,KAAA,IAC/C,EAAE,MAAMA,EAAE,MAAM,KAAKA,EAAE,OAAO,GAAA;AACvC;AAUO,SAASiY,GAAaC,GAAuC;AAClE,QAAMC,IAAUD,EAAM,OAAO,CAAClY,MAAMA,EAAE,SAAS,WAAWA,EAAE,SAAS,QAAQ,EAAE;AAC/E,MAAImY,EAAQ,WAAW,EAAG,QAAO;AACjC,MAAIA,EAAQ,KAAK,CAACnY,MAAMA,EAAE,SAAS,QAAQ;AACzC,WAAO,EAAE,MAAM,QAAQ,OAAOmY,EAAQ,IAAIH,EAAU,EAAA;AAEtD,MAAI9Z,IAAM;AACV,aAAW8B,KAAKmY,GAAS;AACvB,QAAInY,EAAE,SAAS,QAAQ;AACrB,MAAA9B,KAAO8B,EAAE,SAAS;AAClB;AAAA,IACF;AAGA,IAAIoY,GAAuBla,CAAG,IAAI,MAAM,MAAGA,KAAO,OAClDA,KAAOma,GAAkB,CAACL,GAAWhY,CAAC,CAAC,CAAC;AAAA,EAC1C;AACA,SAAO9B;AACT;AAEA,SAASka,GAAuBnV,GAAmB;AACjD,MAAIuN,IAAI;AACR,SAAOA,IAAIvN,EAAE,UAAUA,EAAEA,EAAE,SAAS,IAAIuN,CAAC,MAAM,OAAM,CAAAA,KAAK;AAC1D,SAAOA;AACT;AA0CA,MAAM8H,KAAqD;AAAA,EACzD,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,WAAW;AAAA,EACX,OAAO;AACT;AAGuD,OAAO,OAAO,OAAO,KAAKA,EAAe,CAAC;AAEjG,MAAMC,KAAiB,CAACC,MACtB,OAAO,UAAU,eAAe,KAAKF,IAAiBE,CAAO,GAGzDC,KAAc,CAAC,SAAS,OAAO,MAAM;AAQpC,SAASC,GAAoBC,GAAuB;AACzD,aAAW/M,KAAQ6M;AACjB,QAAIE,MAAQ/M,KAAQ+M,EAAI,WAAW,GAAG/M,CAAI,GAAG,GAAG;AAC9C,YAAMb,IAAO4N,EAAI,MAAM/M,EAAK,MAAM;AAClC,aAAO,CAAC,GAAG,oBAAI,IAAI,CAAC+M,GAAK,GAAGF,GAAY,IAAI,CAACjc,MAAMA,IAAIuO,CAAI,CAAC,CAAC,CAAC;AAAA,IAChE;AAEF,SAAO,CAAC4N,CAAG;AACb;AAGA,SAASC,GAAaD,GAAqB;AACzC,QAAMlB,IAAIkB,EAAI,QAAQ,GAAG;AACzB,SAAOlB,MAAM,KAAKkB,IAAMA,EAAI,MAAM,GAAGlB,CAAC;AACxC;AAwBO,SAASoB,GAA0B5V,GAAuB;AAC/D,QAAMiV,IAAQY,GAAc7V,GAAG,UAAU8V,EAAW;AACpD,SAAOb,EAAM,MAAMc,EAAS,IAAId,IAAQ,CAAC,EAAE,MAAM,QAAQ,OAAOjV,GAAG;AACrE;AAGA,SAAS+V,GAAUhZ,GAAsB;AACvC,MAAIA,EAAE,SAAS,OAAO;AACpB,UAAM2Y,IAAM3Y,EAAE,OAAO;AACrB,WAAO,CAACiZ,GAAqBN,CAAG,KAAKJ,GAAeK,GAAaD,CAAG,CAAC;AAAA,EACvE;AACA,MAAI3Y,EAAE,SAAS,QAAQ;AACrB,UAAMkZ,IAAOC,GAAoBnZ,EAAE,IAAI;AACvC,WAAIkZ,MAAS,OAAa,KACnBA,EAAK,MAAM,CAACP,MAAQJ,GAAeK,GAAaD,CAAG,CAAC,CAAC;AAAA,EAC9D;AACA,SAAO;AACT;AAMA,MAAMI,KAA8B,EAAE,QAAQC,IAAW,WAAW,OAAA,GAE9DI,KAAiC,EAAE,QAAQJ,IAAW,WAAW,QAAA;AAOhE,SAASK,GAAgBvb,GAAqB;AACnD,SAAIga,GAAYha,CAAC,IAAU,KAEzB,OAAOA,KAAM,YACbA,EAAE,SAAS,IAAI,KACf+a,GAA0B/a,CAAC,EAAE,KAAK,CAACkC,MAAMA,EAAE,SAAS,MAAM;AAE9D;AAOO,SAASsZ,GAAoBrW,GAA8B;AAChE,MAAI,CAACA,EAAE,SAAS,IAAI,EAAG,QAAO;AAC9B,QAAMiV,IAAQY,GAAc7V,GAAG,UAAUmW,EAAc;AACvD,SAAKlB,EAAM,MAAMc,EAAS,MACtBd,EAAM,KAAK,CAAClY,MAAMA,EAAE,SAAS,MAAM,KAChCkY,EAAM,IAAI,CAAClY,MAAMA,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAMiD,KADHiV,IADb;AAGtC;AAGA,SAASqB,GAAatO,GAAsB;AAC1C,SAAKA,EAAK,SAAS,IAAI,IAChB6N,GAAc7N,GAAM,UAAUmO,EAAc,EAChD,IAAI,CAACpZ,MAAOA,EAAE,SAAS,SAAUA,EAAE,SAAS,KAAMqY,GAAkB,CAACrY,CAAC,CAAC,CAAE,EACzE,KAAK,EAAE,IAHuBiL;AAInC;AAYO,SAASuO,GAAa5S,GAG3B;AACA,MAAImR,GAAcnR,CAAK,EAAG,QAAO,EAAE,OAAO,CAAA,GAAI,QAAQA,EAAA;AACtD,MAAIkR,GAAYlR,CAAK,EAAG,QAAO,EAAE,OAAOA,EAAM,MAAM,IAAI,CAAC5G,OAAO,EAAE,GAAGA,IAAI,GAAG,QAAQ,KAAA;AACpF,QAAMiD,IAAI,OAAO2D,KAAU,WAAWA,IAAQ;AAC9C,SAAO,EAAE,OAAO3D,IAAI4V,GAA0B5V,CAAC,IAAI,CAAA,GAAI,QAAQ,KAAA;AACjE;AAsBO,SAASwW,GAAavB,GAAmBwB,GAAyC;AACvF,MAAIxb,IAAM;AACV,aAAW8B,KAAKkY;AACd,YAAQlY,EAAE,MAAA;AAAA,MACR,KAAK;AACH,QAAA9B,KAAOqb,GAAavZ,EAAE,SAAS,EAAE;AACjC;AAAA,MACF,KAAK;AAAA,MACL,KAAK,UAAU;AACb,cAAM2Z,IAAMjB,GAAoB1Y,EAAE,OAAO,EAAE,EAAE,KAAK,CAACiD,MAAMA,KAAKyW,CAAO;AACrE,QAAAxb,KAAOyb,MAAQ,SAAY,KAAKD,EAAQC,CAAG;AAC3C;AAAA,MACF;AAAA,MACA,KAAK;AACH,QAAAzb,KAAO;AACP;AAAA,MACF,KAAK;AAEH,QAAAA,KAAOma,GAAkB,CAACrY,CAAC,CAAC;AAC5B;AAAA,IAAA;AAGN,SAAO9B;AACT;ACvMA,MAAM0b,KAAa,QAEbC,KAAqB,SACrBC,KAAmB,cACnBC,KAAe,UAEfC,KAAe;AAGrB,SAASC,GAAatB,GAAqB;AACzC,SAAIA,MAAQ,WAAWA,MAAQ,SAAe,QAC1CA,EAAI,WAAWkB,EAAkB,IAAUD,KAAajB,EAAI,MAAMkB,GAAmB,MAAM,IAC3FlB,EAAI,WAAWqB,EAAY,IAAUJ,KAAajB,EAAI,MAAMqB,GAAa,MAAM,IAC5ErB;AACT;AAGA,SAASuB,GAAkBC,GAAwB;AACjD,SAAIA,EAAO,WAAWH,EAAY,IAAU,IACxCG,EAAO,WAAWP,EAAU,IAAU,IACnC;AACT;AASA,SAASQ,GAAiBC,GAAgC;AACxD,SAAIA,EAAK,OAAO,IAAUA,EAAK,QACxB,OAAO;AAAA,IACZ,MAAM,KAAKA,EAAK,UAAU,CAAC,CAACC,GAAK/M,CAAK,MAAM,CAAC+M,GAAKF,GAAiB7M,CAAK,CAAC,CAAC;AAAA,EAAA;AAE9E;AAeO,SAASgN,GACdC,GACAC,GACAC,GACAC,GACc;AACd,QAAMC,IAAgC,EAAE,8BAAc,IAAA,GAAO,MAAM,EAAA,GAC7DC,IAAqC,CAAA,GACrCC,IAAqC,CAAA;AAC3C,aAAW,CAACX,GAAQvT,CAAK,KAAK,OAAO,QAAQ4T,KAAgB,CAAA,CAAE,GAAG;AAChE,UAAM7B,IAAMsB,GAAaE,CAAM;AAC/B,QAAIxB,EAAI,WAAWiB,EAAU,GAAG;AAC9B,YAAMU,IAAM3B,EAAI,MAAMiB,GAAW,MAAM,GACjCmB,IAAOb,GAAkBC,CAAM;AACrC,UAAIa,IAASJ;AACb,iBAAWpC,KAAW8B,EAAI,MAAM,GAAG,GAAG;AACpC,YAAI/M,IAAQyN,EAAO,SAAS,IAAIxC,CAAO;AACvC,QAAKjL,MACHA,IAAQ,EAAE,UAAU,oBAAI,IAAA,GAAO,MAAM,EAAA,GACrCyN,EAAO,SAAS,IAAIxC,GAASjL,CAAK,IAEpCyN,IAASzN;AAAA,MACX;AACA,MAAIwN,KAAQC,EAAO,SACjBA,EAAO,QAAQpU,GACfoU,EAAO,OAAOD;AAAA,IAElB,MAAA,CAAWpC,EAAI,WAAWmB,EAAgB,IACxCe,EAAUlC,EAAI,MAAMmB,GAAiB,MAAM,CAAC,IAAIlT,IACzC+R,EAAI,WAAWoB,EAAY,MAAGe,EAAUnC,EAAI,MAAMoB,GAAa,MAAM,CAAC,IAAInT;AAAA,EACrF;AACA,QAAMqU,IAAOb,GAAiBQ,CAAY,GACpCM,KACHT,KAAA,gBAAAA,EAAgB,UAAmE,CAAA,GAGhFU,IAAKX,KAAgB,CAAA,GACrBY,IAAU,OAAO,OAAOD,GAAI,cAAc,GAC1CE,IAAW,OAAOF,EAAG,eAAe,KAAM,UAG1CG,IAASb,KAAA,gBAAAA,EAAgB,SACzBc,IAAUD,IACZ,EAAE,GAAGA,EAAA,IACLF,KAAWC,IACT;AAAA,IACE,GAAID,IAAU,EAAE,MAAMD,EAAG,cAAc,EAAA,IAAM,CAAA;AAAA,IAC7C,GAAIE,IAAW,EAAE,OAAOF,EAAG,eAAe,EAAA,IAAgB,CAAA;AAAA,EAAC,IAE7D;AACN,SAAO;AAAA,IACL,GAAII,IAAU,EAAE,SAAAA,EAAA,IAAY,CAAA;AAAA,IAC5B,MAAAN;AAAA,IACA,OAAOA;AAAA,IACP,WAAAJ;AAAA,IACA,WAAAC;AAAA,IACA,OAAAI;AAAA,IACA,OAAOA;AAAA,IACP,UAAST,KAAA,gBAAAA,EAAgB,YAAW,CAAA;AAAA,IACpC,MAAMD,KAAgB,CAAA;AAAA,IACtB,GAAIE,IAAS,EAAE,QAAAA,EAAA,IAAW,CAAA;AAAA,IAC1B,GAAIC,IAAO,EAAE,MAAAA,MAAS,CAAA;AAAA,EAAC;AAE3B;AAWA,SAASa,GACP5P,GACA6P,GACsC;AACtC,QAAMvD,IAAQuD,EAAK,MAAM,GAAG;AAC5B,MAAI1O,IAAenB;AACnB,aAAW8P,KAAQxD,GAAO;AACxB,QAAInL,MAAQ,QAAQ,OAAOA,KAAQ,iBAAiB,EAAE,SAAS,IAAO,OAAO,OAAA;AAC7E,QAAI,EAAE2O,KAAS3O,GAAkC,QAAO,EAAE,SAAS,IAAO,OAAO,OAAA;AACjF,IAAAA,IAAOA,EAAgC2O,CAAI;AAAA,EAC7C;AACA,SAAO,EAAE,SAAS,IAAM,OAAO3O,EAAA;AACjC;AAGA,MAAM4O,KAAa,sDAEbC,KAAW;AAOjB,SAASC,GACPC,GACApB,GACAC,GACuB;;AACvB,MAAI,CAACD,KAAU,CAACC,EAAM,QAAOmB;AAC7B,QAAM5d,IAA+B,EAAE,GAAG4d,EAAA;AAC1C,aAAWpf,KAAM,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAKie,KAAQ,CAAA,CAAE,GAAG,GAAG,OAAO,KAAKD,KAAU,CAAA,CAAE,CAAC,CAAC,GAAG;AACpF,UAAMzR,IAAIyR,KAAA,gBAAAA,EAAShe;AACnB,IAAAwB,EAAIxB,CAAE,IAAI;AAAA,MACR,GAAGof,EAAMpf,CAAE;AAAA,MACX,MAAM,EAAE,GAAGie,KAAA,gBAAAA,EAAOje,IAAK,IAAGH,IAAAuf,EAAMpf,CAAE,MAAR,gBAAAH,EAAW,MAAM,GAAI0M,IAAI,EAAE,QAAQA,EAAA,IAAM,CAAA,EAAC;AAAA,MACpE,GAAIA,IAAI,EAAE,QAAQA,MAAM,CAAA;AAAA,IAAC;AAAA,EAE7B;AACA,SAAO/K;AACT;AAGA,SAAS6d,GAAWpD,GAAaqD,GAAsC;;AACrE,QAAMP,IAAOxB,GAAatB,CAAG;AAI7B,MACEqD,EAAM,SACLP,EAAK,WAAW7B,EAAU,KACzB6B,EAAK,WAAW3B,EAAgB,KAChC2B,EAAK,WAAW1B,EAAY,IAC9B;AACA,UAAMO,IAAM5B,GAAoBC,CAAG,EAAE,KAAK,CAACsD,MAAM,OAAO,OAAOD,EAAM,MAAgBC,CAAC,CAAC;AACvF,QAAI3B,MAAQ,OAAW,QAAO,EAAE,QAAQ,YAAY,KAAA3B,GAAK,OAAOqD,EAAM,KAAK1B,CAAG,EAAA;AAAA,EAChF;AAGA,QAAM,EAAE,MAAAW,GAAM,WAAAH,GAAW,QAAAJ,GAAQ,MAAAC,GAAM,GAAG5P,MAASiR,GAC7CF,IAAQD,GAAWG,EAAM,SAASA,EAAM,OAAOtB,GAAQC,CAAI,GAC3D/O,IAAgC;AAAA,IACpC,GAAGb;AAAA,IACH,KAAKkQ;AAAA,IACL,GAAIH,IAAY,EAAE,OAAOA,EAAA,IAAc,CAAA;AAAA,IACvC,OAAAgB;AAAA,IACA,OAAOA;AAAA,EAAA,GAEHI,IAASV,GAAS5P,GAAM6P,CAAI;AAClC,MAAIS,EAAO,QAAS,QAAO,EAAE,QAAQ,YAAY,KAAAvD,GAAK,OAAOuD,EAAO,MAAA;AAGpE,MAAIP,GAAW,KAAKF,CAAI,UAAU,EAAE,QAAQ,UAAU,KAAA9C,EAAA;AAEtD,QAAMwD,KAAS5f,IAAAqf,GAAS,KAAKH,CAAI,MAAlB,gBAAAlf,EAAsB;AACrC,SAAI4f,MAAW,WAAaxB,KAAA,QAAAA,EAAOwB,MAAgB,EAAE,QAAQ,UAAU,KAAAxD,EAAA,IAChE,EAAE,QAAQ,cAAc,KAAAA,EAAA;AACjC;AAGA,SAASyD,GAAYV,GAAgBM,GAAsC;AACzE,UAAQN,EAAK,MAAA;AAAA,IACX,KAAK;AACH,aAAO,EAAE,QAAQ,YAAY,OAAOA,EAAK,SAAS,GAAA;AAAA,IACpD,KAAK;AACH,aAAOK,GAAWL,EAAK,OAAO,IAAIM,CAAK;AAAA,IACzC,KAAK;AAKH,aAAO,EAAE,QAAQ,UAAU,KAAKN,EAAK,IAAA;AAAA,IACvC,KAAK;AAIH,aAAO,EAAE,QAAQ,gBAAA;AAAA,IACnB,KAAK;AAMH,aAAO,EAAE,QAAQ,gBAAA;AAAA,IACnB;AACE,aAAO,EAAE,QAAQ,YAAY,OAAO,OAAA;AAAA,EAAU;AAEpD;AAGO,SAASW,GAAave,GAAiC;AAC5D,SACE,OAAOA,KAAM,YACbA,MAAM,QACN,CAAC,MAAM,QAAQA,CAAC,KAChB,OAAO,KAAKA,CAAW,EAAE,WAAW,KACpC,OAAQA;AAEZ;AAGO,SAASwe,GAAaxe,GAAqC;AAChE,SACE,OAAOA,KAAM,YACbA,MAAM,QACN,CAAC,MAAM,QAAQA,CAAC,KAChB,OAAO,KAAKA,CAAW,EAAE,WAAW,KACpC,WAAYA;AAEhB;AAWO,SAASye,GAAkB3V,GAAgBoV,GAAwC;AACxF,MAAIjE,GAAcnR,CAAK,EAAG,QAAO,CAAC,EAAE,QAAQ,UAAU;AACtD,MAAIkR,GAAYlR,CAAK,EAAG,QAAQA,EAAoB,MAAM,IAAI,CAAC5G,MAAMoc,GAAYpc,GAAGgc,CAAK,CAAC;AAG1F,MAAI,OAAOpV,KAAU,UAAU;AAC7B,UAAMsR,IAAQoB,GAAoB1S,CAAK;AACvC,QAAIsR,UAAcA,EAAM,IAAI,CAAClY,MAAMoc,GAAYpc,GAAGgc,CAAK,CAAC;AAAA,EAC1D;AACA,SAAIK,GAAazV,CAAK,IAAU,CAACmV,GAAW,OAAQnV,EAAyB,CAAC,GAAGoV,CAAK,CAAC,IACnFM,GAAa1V,CAAK,IAAU,CAAC,EAAE,QAAQ,iBAAiB,IACrD,CAAC,EAAE,QAAQ,YAAY,OAAAA,GAAO;AACvC;AAYO,SAAS4V,GAAUviB,GAAYC,GAAqB;AACzD,MAAID,MAAMC,EAAG,QAAO;AAEpB,MADI,OAAOD,KAAM,OAAOC,KACpBD,MAAM,QAAQC,MAAM,QAAQ,OAAOD,KAAM,SAAU,QAAO;AAC9D,QAAMwiB,IAAO,MAAM,QAAQxiB,CAAC,GACtByiB,IAAO,MAAM,QAAQxiB,CAAW;AACtC,MAAIuiB,MAASC,EAAM,QAAO;AAC1B,MAAID,GAAM;AACR,UAAME,IAAO1iB,GACP2iB,IAAO1iB;AACb,WAAOyiB,EAAK,WAAWC,EAAK,UAAUD,EAAK,MAAM,CAAC7e,GAAG2Z,MAAM+E,GAAU1e,GAAG8e,EAAKnF,CAAC,CAAC,CAAC;AAAA,EAClF;AACA,QAAMoF,IAAO5iB,GACP6iB,IAAO5iB,GACP6iB,IAAQ,OAAO,KAAKF,CAAI,GACxBG,IAAQ,OAAO,KAAKF,CAAI;AAC9B,SACEC,EAAM,WAAWC,EAAM,UAAUD,EAAM,MAAM,CAACd,MAAMA,KAAKa,KAAQN,GAAUK,EAAKZ,CAAC,GAAGa,EAAKb,CAAC,CAAC,CAAC;AAEhG;AC7YA,SAASgB,GAAQC,GAA+B;AAC9C,UAAQA,EAAI,QAAA;AAAA,IACV,KAAK;AACH,aAAOA,EAAI,UAAU,SAAY,cAAcA,EAAI;AAAA,IACrD,KAAK;AACH,aAAO,gBAAgBA,EAAI,GAAG;AAAA,IAChC,KAAK;AACH,aAAO,qBAAqBA,EAAI,GAAG;AAAA,IACrC,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAOA,EAAI,MAAM,YAAYA,EAAI,GAAG,MAAM;AAAA,EAAA;AAEhD;AAGA,SAASC,GAAcD,GAA8B;AACnD,SAAIA,EAAI,WAAW,cAAcA,EAAI,UAAU,SACtC,OAAOA,EAAI,SAAU,WAAWA,EAAI,QAAQ,KAAK,UAAUA,EAAI,KAAK,IAEtE,OAAOD,GAAQC,CAAG,CAAC;AAC5B;AAUO,SAASE,GAAqBC,GAAsC;AACzE,SAAIA,EAAS,WAAW,IAAUJ,GAAQI,EAAS,CAAC,CAAC,IAC9CA,EAAS,IAAIF,EAAa,EAAE,KAAK,EAAE;AAC5C;AAGO,SAASG,GAAiB1W,GAAgBoV,GAA8B;AAC7E,SAAOoB,GAAqBb,GAAkB3V,GAAOoV,CAAK,CAAC;AAC7D;AAOO,SAASuB,GACdC,GACAxB,GACyB;AACzB,QAAM9d,IAA+B,CAAA;AACrC,aAAWuf,KAAOD;AAChB,IAAAtf,EAAIuf,EAAI,OAAO,UAAU,IAAIH,GAAiBG,EAAI,OAAOzB,CAAK;AAEhE,SAAO9d;AACT;ACZO,MAAMwf,KAAaC;AAAA,EACxB,SAAoB1K,GAAO0F,GAAK;AAC9B,UAAM;AAAA,MACJ,OAAAlG;AAAA,MACA,UAAApP;AAAA,MACA,MAAAua;AAAA,MACA,UAAAC;AAAA,MACA,OAAAC;AAAA,MACA,SAAAC;AAAA,MACA,UAAAzH;AAAA,MACA,WAAAhL;AAAA,MACA,QAAA0S;AAAA,MACA,GAAGjT;AAAA,IAAA,IACDkI,GACEgL,IAAQ5a,MAAaua,IAAO,gBAAA7a,EAACgQ,IAAA,EAAK,MAAM6K,GAAM,MAAMC,KAAY,GAAA,CAAI,IAAK;AAC/E,WACE,gBAAA9a;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAA4V;AAAA,QACA,MAAK;AAAA,QACL,WAAW,CAAC,mBAAmBqF,IAAS,2BAA2B,IAAI1S,KAAa,EAAE,EACnF,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,QACX,OAAOwS,KAASrL;AAAA,QAChB,cAAYA;AAAA,QACZ,gBAAc1H,EAAK,cAAc;AAAA,QACjC,iBAAeA,EAAK,eAAe;AAAA,QACnC,iBAAeA,EAAK,eAAe;AAAA,QACnC,UAAAuL;AAAA,QACA,SAAAyH;AAAA,QACA,eAAahT,EAAK,aAAa;AAAA,QAE9B,UAAAkT;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEAP,GAAW,cAAc;ACjEzB,MAAMQ,KAA8D;AAAA,EAClE,SAAS;AAAA,EACT,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,YAAY;AACd;AAEO,SAASC,GAAM;AAAA,EACpB,OAAAL;AAAA,EACA,WAAAvH;AAAA,EACA,SAAA6H;AAAA,EACA,UAAA/a;AAAA,EACA,MAAAX,IAAO;AAAA,EACP,WAAA2b;AAAA,EACA,UAAAC;AAAA,EACA,aAAAC;AACF,GAAe;AACb,QAAM5F,IAAM9S,GAA0B,IAAI;AAE1C,SAAA5D,GAAU,MAAM;AACd,UAAMkK,IAAKwM,EAAI;AACf,QAAI,CAACxM,EAAI;AACT,IAAKA,EAAG,QAAMA,EAAG,UAAA;AACjB,UAAMqS,IAAW,CAACpY,MAAa;AAC7B,MAAAA,EAAE,eAAA,GACFgY,EAAA;AAAA,IACF,GAKML,IAAU,CAAC3X,MAAkB;AACjC,UAAIA,EAAE,WAAW+F,EAAI;AACrB,YAAM3P,IAAI2P,EAAG,sBAAA;AAGb,OADE/F,EAAE,UAAU5J,EAAE,QAAQ4J,EAAE,UAAU5J,EAAE,SAAS4J,EAAE,UAAU5J,EAAE,OAAO4J,EAAE,UAAU5J,EAAE,WACrE4hB,EAAA;AAAA,IACf;AACA,WAAAjS,EAAG,iBAAiB,UAAUqS,CAAQ,GACtCrS,EAAG,iBAAiB,SAAS4R,CAAO,GAC7B,MAAM;AACX,MAAA5R,EAAG,oBAAoB,UAAUqS,CAAQ,GACzCrS,EAAG,oBAAoB,SAAS4R,CAAO;AAAA,IACzC;AAAA,EACF,GAAG,CAACK,CAAO,CAAC,GAGV,gBAAArb,EAAC,OAAA,EAAI,WAAU,sBACb,UAAA,gBAAA8F;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAA8P;AAAA,MACA,WAAW,YAAYuF,GAAWxb,CAAI,CAAC;AAAA,MACvC,cAAY6T,MAAc,OAAOuH,KAAU,WAAWA,IAAQ;AAAA,MAE9D,UAAA;AAAA,QAAA,gBAAAjV,EAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,mBACX,UAAA;AAAA,YAAAwV;AAAA,YACD,gBAAAtb,EAAC,UAAM,UAAA+a,EAAA,CAAM;AAAA,YACZQ,KAAY,gBAAAvb,EAAC,QAAA,EAAK,WAAU,sBAAsB,UAAAub,EAAA,CAAS;AAAA,UAAA,GAC9D;AAAA,UACCC;AAAA,QAAA,GACH;AAAA,QACClb;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAEL;AAEJ;ACtFA,MAAMob,yBAAY,IAAI;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC,GACKC,KAAW,yBACXC,KAAc,CAAC/K,MAAmB8K,GAAS,KAAK9K,CAAM,KAAK,cAAc,KAAKA,CAAM,GACpFgL,KAAoB,CAACC,MAAkBC,GAAqBD,CAAI,EAAE,KAAKF,EAAW;AAExF,SAASI,GAAiBpG,GAAa5E,GAAoC;;AACzE,QAAM,CAACiL,GAAO,GAAGjU,CAAI,IAAI4N,EAAI,MAAM,GAAG;AACtC,MAAIqG,MAAU;AACZ,UAAM,IAAI,MAAM,uEAAuE;AACzF,MAAIP,GAAM,IAAIO,CAAK,EAAG,QAAOrG;AAC7B,QAAMsG,IAAa;AAAA,IACjB,IAAI1iB,IAAAwX,EAAQ,UAAR,QAAAxX,EAAe,KAAK,CAACD,MAASA,EAAK,OAAO0iB,KAAS,CAAC,SAASA,CAAK,SAAS,IAAI,CAAA;AAAA,IACnF,IAAIjP,IAAAgE,EAAQ,SAAR,QAAAhE,EAAc,SAASiP,KAAS,CAAC,OAAOA,CAAK,EAAE,IAAI,CAAA;AAAA,IACvD,IAAIxJ,IAAAzB,EAAQ,cAAR,QAAAyB,EAAmB,SAASwJ,KAAS,CAAC,SAASA,CAAK,EAAE,IAAI,CAAA;AAAA,EAAC;AAEjE,MAAIC,EAAW,SAAS;AACtB,UAAM,IAAI,MAAM,IAAID,CAAK,oDAAoD;AAC/E,MAAIC,EAAW,WAAW;AACxB,UAAM,IAAI,MAAM,kBAAkBD,CAAK,mDAAmD;AAC5F,SAAO,CAACC,EAAW,CAAC,GAAG,GAAGlU,CAAI,EAAE,KAAK,GAAG;AAC1C;AAIO,SAASmU,GACdC,GACApL,GAC6C;;AAC7C,QAAMqL,IAAY,EAAE,OAAOD,GAAU,OAAO,KAAA,GACtCjH,IAAQiH,EAAS;AAAA,IAAQ,CAACzD,MAC9BA,EAAK,SAAS,SAAS7C,GAA0B6C,EAAK,SAAS,EAAE,IAAI,CAACA,CAAI;AAAA,EAAA;AAE5E,MAAIxD,EAAM,KAAK,CAACwD,MAASA,EAAK,SAAS,QAAQ,EAAG,QAAO0D;AAEzD,MAAIlH,EAAM,WAAW,KAAKA,EAAM,CAAC,EAAE,SAAS,UAAU,CAAC0G,GAAkB1G,EAAM,CAAC,EAAE,IAAI;AACpF,WAAO,EAAE,OAAAA,GAAO,OAAO,KAAA;AACzB,MAAItE,IAASsE,EACV,IAAI,CAACwD,MAAS;AACb,QAAIA,EAAK,SAAS,OAAQ,QAAOA,EAAK,SAAS;AAC/C,QAAIA,EAAK,SAAS,iBAAiB,cAAcA,EAAK,OAAO,EAAE;AAC/D,QAAIA,EAAK,SAAS,QAAQ;AAGxB,UAAIkD,GAAkBlD,EAAK,IAAI,GAAG;AAChC,cAAM2D,IAAShH,GAAkB,CAACqD,CAAI,CAAC;AACvC,YAAI,CAAC2D,EAAO,WAAW,MAAM,EAAG,QAAO,IAAIA,EAAO,MAAM,GAAG,EAAE,EAAE,MAAM;AAAA,MACvE;AACA,YAAMC,IAAWC,GAAyB7D,EAAK,IAAI;AACnD,aAAO4D,MAAa,OAAOjH,GAAkB,CAACqD,CAAI,CAAC,IAAI,IAAI4D,CAAQ;AAAA,IACrE;AAEA,WAAOX,GAAYjD,EAAK,OAAO,EAAE,IAAKA,EAAK,OAAO,KAAM,MAAMA,EAAK,OAAO,EAAE;AAAA,EAC9E,CAAC,EACA,KAAK,EAAE,EACP,KAAA;AACH,MAAI,CAACiD,GAAY/K,CAAM,EAAG,QAAOwL;AACjC,QAAMI,IAAU,qBAAqB,KAAK5L,CAAM;AAChD,EAAI4L,KAAWb,GAAYa,EAAQ,CAAC,CAAC,MAAG5L,IAAS4L,EAAQ,CAAC,EAAE,KAAA;AAC5D,QAAMC,IAAQ7L,EAAO,QAAQ,YAAY,EAAE,GACrCoL,KAAQziB,IAAA,mCAAmC,KAAKkjB,CAAK,MAA7C,gBAAAljB,EAAiD,IACzDmjB,IACJD,EAAM,WAAW,IAAI,KACpBT,MAAU,WACRP,GAAM,IAAIO,CAAK,KACdA,MAAU,eACVjP,IAAAgE,EAAQ,UAAR,gBAAAhE,EAAe,KAAK,CAACzT,MAASA,EAAK,OAAO0iB,SAC1CxJ,IAAAzB,EAAQ,SAAR,gBAAAyB,EAAc,SAASwJ,SACvBvJ,IAAA1B,EAAQ,cAAR,gBAAA0B,EAAmB,SAASuJ;AAElC,MAAI,CAACU,KAAc,CAAC,uCAAuC,KAAKD,CAAK,EAAG,QAAOL;AAC/E,MAAIM,KAAc,CAAC,cAAc,KAAK9L,CAAM,GAAG;AAC7C,UAAM+L,KAAUC,IAAA,sDAAsD,KAAKH,CAAK,MAAhE,gBAAAG,EAAoE;AACpF,QAAID,GAAS;AACX,YAAME,IAAQJ,EAAM,MAAME,EAAQ,MAAM,EAAE,QAAQ,WAAW,EAAE;AAG/D,UAAI,CAAC,8BAA8B,KAAKE,CAAK,KAAK,sBAAsB,KAAKA,CAAK;AAChF,eAAOT;AAAA,IACX;AAAA,EACF;AACA,MAAI;AAEF,WAAO,EAAE,OAAO,CAAC,EAAE,MAAM,QAAQ,MADpBU,GAAwBlM,GAAQ,CAAC+E,MAAQoG,GAAiBpG,GAAK5E,CAAO,CAAC,EACnD,CAAM,GAAG,OAAO,KAAA;AAAA,EACnD,SAASgM,GAAO;AACd,WAAO,EAAE,OAAA7H,GAAO,OAAO6H,aAAiB,QAAQA,EAAM,UAAU,wBAAA;AAAA,EAClE;AACF;AAGO,SAASC,GAAmB9H,GAA6B;AAC9D,SAAO;AAAA,IACL,GAAG,IAAI;AAAA,MACLA,EAAM;AAAA,QAAQ,CAACwD,MACbA,EAAK,SAAS,SACVoD,GAAqBpD,EAAK,IAAI,KAC7BA,EAAK,SAAS,SAASA,EAAK,SAAS,aAAaA,EAAK,MACtD,CAACA,EAAK,GAAG,IACT,CAAA;AAAA,MAAC;AAAA,IACT;AAAA,EACF;AAEJ;AAEA,SAASuE,GAAUtH,GAAqB;AACtC,SAAOA,EAAI,QAAQ,2BAA2B,KAAK,EAAE,QAAQ,kBAAkB,OAAO;AACxF;AAEA,SAASuH,GAAWxG,GAA2D;AAC7E,QAAM9N,IAAgC,uBAAO,OAAO,IAAI;AAGxD,aAAW,CAAC+M,GAAK/R,CAAK,KAAK,OAAO,QAAQ8S,CAAO,EAAE;AAAA,IACjD,CAAC,CAACzf,CAAC,GAAG,CAACC,CAAC,MAAMD,EAAE,MAAM,GAAG,EAAE,SAASC,EAAE,MAAM,GAAG,EAAE;AAAA,EAAA,GAChD;AACD,UAAMimB,IAAOF,GAAUtH,CAAG,EAAE,MAAM,GAAG;AACrC,QACE,CAAC8F,GAAM,IAAI0B,EAAK,CAAC,CAAC,KAClBA,EAAK,KAAK,CAAC7F,MAAQ,CAAC,aAAa,eAAe,WAAW,EAAE,SAASA,CAAG,CAAC;AAE1E;AACF,QAAI8F,IAASxU;AACb,eAAW0O,KAAO6F,EAAK,MAAM,GAAG,EAAE,GAAG;AACnC,YAAME,IAAWD,EAAO9F,CAAG,GACrB5S,IAAO2Y,KAAY,OAAOA,KAAa,WAAW,EAAE,GAAGA,EAAA,IAAa,CAAA;AAC1E,MAAAD,EAAO9F,CAAG,IAAI5S,GACd0Y,IAAS1Y;AAAA,IACX;AACA,IAAA0Y,EAAOD,EAAKA,EAAK,SAAS,CAAC,CAAC,IAAIvZ;AAAA,EAClC;AACA,SAAAgF,EAAK,QAAQA,EAAK,OAClBA,EAAK,OAAOA,EAAK,KACjBA,EAAK,QAAQA,EAAK,KACXA;AACT;AAIO,SAAS0U,GACdpI,GACAqI,IAAiC,CAAA,GACjCC,IAAoC,CAAA,GAC5B;AACR,QAAM9G,IAAU,EAAE,GAAG6G,EAAA;AACrB,aAAW,CAAC5H,GAAK1N,CAAI,KAAK,OAAO,QAAQuV,CAAS;AAChD,QAAI;AACF,MAAA9G,EAAQf,CAAG,IAAI,KAAK,MAAM1N,CAAI;AAAA,IAChC,QAAQ;AACN,MAAAyO,EAAQf,CAAG,IAAI1N;AAAA,IACjB;AAEF,QAAMW,IAAOsU,GAAWxG,CAAO,GACzB+G,IAAc,OAAO;AAAA,IACzB,OAAO,QAAQ/G,CAAO,EAAE,IAAI,CAAC,CAACf,GAAK/R,CAAK,MAAM;AAAA,MAC5C+R;AAAA,MACA,OAAO/R,KAAU,WAAWA,IAAQ,KAAK,UAAUA,CAAK;AAAA,IAAA,CACzD;AAAA,EAAA;AAEH,SAAOsR,EACJ,IAAI,CAACwD,MAAS;AACb,QAAIA,EAAK,SAAS,UAAU6D,GAAyB7D,EAAK,IAAI,MAAM;AAClE,aAAOjC,GAAa,CAACiC,CAAI,GAAG+E,CAAW;AAEzC,QADa3B,GAAqBpD,EAAK,IAAI,EAClC,KAAK,CAAC/C,MAAQ,CAACA,KAAOA,EAAI,MAAM,GAAG,EAAE,CAAC,MAAM,SAAS,EAAG,QAAO;AACxE,UAAM/R,IAAQ8Z,GAAShF,EAAK,MAAM9P,CAAI;AACtC,WAAO,OAAOhF,KAAU,WAAWA,IAAS,KAAK,UAAUA,CAAK,KAAK;AAAA,EACvE,CAAC,EACA,KAAK,EAAE;AACZ;AC/KA,MAAM+Z,KAAkB,iDAGlBC,KAAgB,uEAyBTC,KAAW,CAAClI,MAAwB;AAC/C,MAAIA,EAAI,WAAW,MAAM,UAAUA,EAAI,MAAM,CAAa;AAC1D,MAAIA,EAAI,WAAW,OAAO,UAAUA,EAAI,MAAM,CAAc;AAC5D,MAAIA,EAAI,WAAW,QAAQ,UAAUA,EAAI,MAAM,CAAe;AAC9D,QAAMzN,IAAIyV,GAAgB,KAAKhI,CAAG;AAClC,MAAIzN,EAAG,QAAOA,EAAE,CAAC,IAAI,GAAGA,EAAE,CAAC,CAAC,IAAIA,EAAE,CAAC,CAAC,KAAKA,EAAE,CAAC;AAC5C,QAAMyP,IAAOiG,GAAc,KAAKjI,CAAG;AACnC,SAAIgC,IAAa,GAAGA,EAAK,CAAC,CAAC,WAAWA,EAAK,CAAC,CAAC,KACtChC;AACT;AAMA,SAASmI,GAAmBhjB,GAAgC;AAC1D,MAAIA,MAAM,QAAQ,OAAOA,KAAM,YAAY,MAAM,QAAQA,CAAC,EAAG;AAC7D,QAAMqiB,IAAO,OAAO,KAAKriB,CAA4B;AACrD,MAAIqiB,EAAK,WAAW,KAAKA,EAAK,CAAC,MAAM,MAAO;AAC5C,QAAMxH,IAAO7a,EAA8B;AAC3C,SAAO,OAAO6a,KAAQ,WAAWA,IAAM;AACzC;AAUA,SAASoI,GAAWC,GAA8B;AAChD,QAAMC,IAAQD,EAAM,OAAO,OAAO,OAAO,MACnC/V,IAAO+V,EAAM,SAChB,IAAI,CAACrB,MAAY;AAChB,UAAMhH,IAAMmI,GAAmBnB,CAAO;AACtC,WAAOhH,MAAQ,SAAYkI,GAASlI,CAAG,IAAI,KAAK,UAAUgH,CAAO;AAAA,EACnE,CAAC,EACA,KAAK,IAAIsB,CAAK,GAAG;AACpB,SAAOhW,EAAK,SAAS,KAAK,GAAGA,EAAK,MAAM,GAAG,EAAE,CAAC,MAAMA;AACtD;AAiBA,MAAMiW,KAAwB;AAWvB,SAASC,GAAa7G,GAAsB;AACjD,SAAIA,MAAQ,MAAMA,MAAQA,EAAI,KAAA,IAAe,KACtC,CAAC4G,GAAsB,KAAK5G,CAAG;AACxC;AASO,SAAS8G,GAAc3F,GAAuB;AACnD,SAAOA,EAAK,MAAM,GAAG,EAAE,MAAM0F,EAAY;AAC3C;AASO,SAASE,GACdC,GAC6C;AAC7C,QAAMC,IAAQ,IAAI,IAAID,EAAO,OAAO,CAACE,MAAMA,EAAE,IAAI,EAAE,IAAI,CAACA,MAAMA,EAAE,GAAG,CAAC;AACpE,SAAOF,EAAO,IAAI,CAACG,MAAU;AAC3B,QAAI,CAACA,EAAM,KAAM,QAAO,EAAE,OAAAA,GAAO,OAAO,GAAG,MAAMA,EAAM,IAAA;AACvD,UAAMC,IAAOD,EAAM,IAAI,MAAM,GAAG;AAChC,QAAIE,IAAQ,GACRC,IAAM;AACV,aAASnK,IAAI,GAAGA,IAAIiK,EAAK,QAAQjK;AAC/B,MAAI8J,EAAM,IAAIG,EAAK,MAAM,GAAGjK,CAAC,EAAE,KAAK,GAAG,CAAC,MACtCkK,KACAC,IAAMnK;AAGV,WAAO,EAAE,OAAAgK,GAAO,OAAAE,GAAO,MAAMD,EAAK,MAAME,CAAG,EAAE,KAAK,GAAG,EAAA;AAAA,EACvD,CAAC;AACH;AAeO,SAASC,GACdhW,GACA6P,GACA,EAAE,cAAAoG,EAAA,IAA6C,CAAA,GAClC;AACb,QAAMC,IAAOlW,EAAI,cAAc,MAAM;AACrC,EAAAkW,EAAK,kBAAkB,SACvBA,EAAK,YAAY,+BAA+BrG,EAAK,IAAI,IACzDqG,EAAK,aAAa,aAAarG,EAAK,IAAI;AAExC,QAAMsG,IAAQnW,EAAI,cAAc,MAAM;AACtC,EAAAmW,EAAM,YAAY;AAClB,QAAMvP,IAAQ5G,EAAI,cAAc,MAAM;AAGtC,MAFA4G,EAAM,YAAY,uBAEdiJ,EAAK,SAAS;AAChB,IAAAqG,EAAK,aAAa,YAAYrG,EAAK,OAAO,EAAE,GAG5CsG,EAAM,cAAc,KACpBvP,EAAM,cAAcoO,GAASnF,EAAK,OAAO,EAAE,GAC3CqG,EAAK,QAAQ,aAAarG,EAAK,OAAO,EAAE;AAAA,WAC/BA,EAAK,SAAS;AACvB,IAAAqG,EAAK,aAAa,YAAYrG,EAAK,OAAO,EAAE,GAK5CsG,EAAM,cAAc,KACpBvP,EAAM,cAAcoO,GAASnF,EAAK,OAAO,EAAE,GAC3CqG,EAAK,QAAQ,uBAAuBrG,EAAK,OAAO,EAAE;AAAA,WACzCA,EAAK,SAAS;AACvB,IAAAqG,EAAK,aAAa,YAAYrG,EAAK,OAAO,EAAE,GAC5CsG,EAAM,cAAc,MACpBvP,EAAM,cAAciJ,EAAK,OAAO,IAChCqG,EAAK,QAAQ,WAAWrG,EAAK,OAAO,EAAE;AAAA,OACjC;AACL,UAAM5P,IAAM,OAAO4P,EAAK,QAAS,WAAWA,EAAK,OAAO,KAAK,UAAUA,EAAK,QAAQ,EAAE;AACtF,IAAAqG,EAAK,aAAa,aAAajW,CAAG,GAClCkW,EAAM,cAAc;AACpB,UAAMhB,IAAQiB,GAAmBvG,EAAK,IAAI;AAC1C,QAAIsF;AACF,MAAAvO,EAAM,cAAcsO,GAAWC,CAAK,GACpCe,EAAK,QAAQ,eAAe1J,GAAkB,CAACqD,CAAI,CAAC,CAAC;AAAA,SAChD;AACL,YAAM4D,IAAWC,GAAyB7D,EAAK,MAAMmF,EAAQ;AAC7D,MAAApO,EAAM,cAAc6M,MAAaxT,EAAI,SAAS,KAAK,GAAGA,EAAI,MAAM,GAAG,EAAE,CAAC,MAAMA,KAAO,SACnFiW,EAAK,QAAQ,eAAezC,KAAYxT,CAAG;AAAA,IAC7C;AAAA,EACF;AAIA,MAFAiW,EAAK,OAAOC,GAAOvP,CAAK,IAEnBiJ,EAAK,SAAS,SAASA,EAAK,SAAS,aAAaoG,GAAc;AAMnE,UAAMI,IAASrW,EAAI,cAAc,MAAM;AACvC,IAAAqW,EAAO,YAAY,wBACnBA,EAAO,aAAa,sBAAsB,GAAG,GAC7CA,EAAO,aAAa,QAAQ,QAAQ;AACpC,UAAMC,IACJzG,EAAK,SAAS,WAAW,iCAAiC;AAC5D,IAAAwG,EAAO,aAAa,cAAcC,CAAW,GAC7CD,EAAO,QAAQC,GACfD,EAAO,cAAc,KACrBH,EAAK,OAAOG,CAAM;AAAA,EACpB;AAEA,QAAME,IAAIvW,EAAI,cAAc,MAAM;AAClC,SAAAuW,EAAE,YAAY,mBACdA,EAAE,aAAa,UAAU,GAAG,GAC5BA,EAAE,aAAa,QAAQ,QAAQ,GAC/BA,EAAE,aAAa,cAAc,QAAQ,GACrCA,EAAE,cAAc,KAChBL,EAAK,OAAOK,CAAC,GACNL;AACT;AAMA,MAAMM,KAAa,oBAAI,IAAI,CAAC,OAAO,GAAG,CAAC;AAWhC,SAASC,GAAWnW,GAAkC;AAC3D,QAAMsF,IAAOtF,EAAG,aAAa,WAAW;AACxC,MAAIsF,MAAS,SAASA,MAAS,YAAYA,MAAS;AAClD,WAAO,EAAE,MAAAA,GAAM,KAAKtF,EAAG,aAAa,UAAU,KAAK,GAAA;AAErD,MAAIsF,MAAS,QAAQ;AACnB,UAAM3F,IAAMK,EAAG,aAAa,WAAW,KAAK;AAC5C,QAAI0S,IAAgB/S;AACpB,QAAI;AACF,MAAA+S,IAAO,KAAK,MAAM/S,CAAG;AAAA,IACvB,QAAQ;AACN,MAAA+S,IAAO/S;AAAA,IACT;AACA,WAAO,EAAE,MAAM,QAAQ,MAAA+S,EAAA;AAAA,EACzB;AACA,SAAO;AACT;AAeO,SAAS0D,GAAU3W,GAA+B;AACvD,QAAMsM,IAAoB,CAAA,GACpBsK,IAAW,CAAC7a,MAAc;AAC9B,QAAI,CAACA,EAAG;AACR,UAAM6E,IAAO0L,EAAMA,EAAM,SAAS,CAAC;AACnC,IAAI1L,KAAQA,EAAK,SAAS,WAAa,SAASA,EAAK,SAAS,MAAM7E,MACzD,KAAK,EAAE,MAAM,QAAQ,OAAOA,GAAG;AAAA,EAC5C,GAGMuF,IAAO,CAACC,GAAYsV,MAAyB;AACjD,QAAItV,EAAK,aAAa,KAAK,WAAW;AACpC,MAAAqV,EAASrV,EAAK,eAAe,EAAE;AAC/B;AAAA,IACF;AACA,QAAIA,EAAK,aAAa,KAAK,aAAc;AACzC,UAAMhB,IAAKgB,GAELuO,IAAO4G,GAAWnW,CAAE;AAC1B,QAAIuP,GAAM;AACR,MAAAxD,EAAM,KAAKwD,CAAI;AACf;AAAA,IACF;AAGA,UAAMtO,KAAOjB,EAAG,WAAW,IAAI,YAAA;AAC/B,QAAIiB,MAAQ,MAAM;AAYhB,MAAKqV,KAAaD,EAAS;AAAA,CAAI;AAC/B;AAAA,IACF;AAEA,UAAME,IAAUL,GAAW,IAAIjV,CAAG;AAClC,IAAIsV,KAAWxK,EAAM,SAAS,OAAY;AAAA,CAAI,GAC9CyK,EAAaxW,GAAIuW,CAAO;AAAA,EAC1B,GAEMC,IAAe,CAACC,GAAcC,MAA2B;AAC7D,UAAMxf,IAAW,MAAM,KAAKuf,EAAO,UAAU;AAC7C,IAAAvf,EAAS,QAAQ,CAACkK,GAAOkK,MAAMvK,EAAKK,GAAOsV,KAAiBpL,MAAMpU,EAAS,SAAS,CAAC,CAAC;AAAA,EACxF;AAEA,SAAAsf,EAAa/W,GAAM,EAAI,GAChBsM;AACT;AAYA,MAAM4K,KAAgB,CAAC3V,MACrB,CAAC,CAACA,MAAUA,EAAqB,WAAW,IAAI,YAAA,MAAkB;AAUpE,SAAS4V,GAAUhX,GAA0B;AAC3C,EAAI+W,GAAc/W,EAAM,SAAS,KACjCA,EAAM,YAAYA,EAAM,cAAc,cAAc,IAAI,CAAC;AAC3D;AAWA,SAASiX,GAAWtT,GAAkC;AACpD,QAAMtB,IAAMsB,EAAO,cAAc,aAAA,GAC3BrB,IAAQD,KAAA,QAAAA,EAAK,aAAaA,EAAI,WAAW,CAAC,IAAI;AAOpD,MAAI,CAACC,KAAS,CAACqB,EAAO,SAASrB,EAAM,YAAY,EAAG,QAAOqB;AAC3D,MAAIvC,IAAoBkB,EAAM;AAC9B,SAAOlB,KAAQA,MAASuC,KAAQ;AAC9B,QAAIvC,EAAK,aAAa,KAAK,cAAc;AACvC,YAAMhB,IAAKgB;AACX,UAAIkV,GAAW,KAAKlW,EAAG,WAAW,IAAI,aAAa,EAAG,QAAOA;AAAA,IAC/D;AACA,IAAAgB,IAAOA,EAAK;AAAA,EACd;AACA,SAAOuC;AACT;AAaO,SAASuT,GAAkBvT,GAA2B;AAC3D,EAAAqT,GAAUC,GAAWtT,CAAM,CAAC;AAC9B;AAgBA,MAAMwT,KAAkB,CAAC/W,MAA6BA,EAAG,aAAa,gBAAgB,MAAM;AASrF,SAASgX,GACdhX,GACA+L,GACAkL,GACM;;AACN,QAAMvX,IAAMM,EAAG;AACf,EAAAA,EAAG,cAAc;AACjB,aAAWnM,KAAKkY;AACd,IAAIlY,EAAE,SAAS,SACTA,EAAE,SAAOmM,EAAG,YAAYN,EAAI,eAAe7L,EAAE,KAAK,CAAC,IAEvDmM,EAAG,YAAY0V,GAAShW,GAAK7L,GAAGojB,CAAI,CAAC;AAczC,QAAM5W,IAAO0L,EAAMA,EAAM,SAAS,CAAC;AACnC,GAAI1L,KAAA,gBAAAA,EAAM,UAAS,YAAUjQ,IAAAiQ,EAAK,UAAL,QAAAjQ,EAAY,SAAS;AAAA,OAAS2mB,GAAgB/W,CAAE,KAAG4W,GAAU5W,CAAE;AAC9F;AAaO,SAASkX,GAAgBlX,GAAuB;AACrD,QAAMiC,IAAMjC,EAAG,cAAc,aAAA;AAC7B,MAAI,CAACiC,EAAK;AACV,QAAMC,IAAQlC,EAAG,cAAc,YAAA;AAC/B,EAAAkC,EAAM,mBAAmBlC,CAAE,GAC3BkC,EAAM,SAAS,EAAK,GACpBD,EAAI,gBAAA,GACJA,EAAI,SAASC,CAAK;AACpB;AAGO,SAASiV,GAAkB5T,GAAqBvC,GAAkB;AACvE,QAAMtB,IAAM6D,EAAO,eACbtB,IAAMvC,EAAI,aAAA,GACVwC,IAAQD,KAAA,QAAAA,EAAK,aAAaA,EAAI,WAAW,CAAC,IAAI;AACpD,MAAIC,KAASqB,EAAO,SAASrB,EAAM,uBAAuB,GAAG;AAC3D,IAAAA,EAAM,eAAA,GACNA,EAAM,WAAWlB,CAAI;AACrB,UAAM0S,IAAQhU,EAAI,YAAA;AAClB,IAAAgU,EAAM,cAAc1S,CAAI,GACxB0S,EAAM,SAAS,EAAI,GACnBzR,KAAA,QAAAA,EAAK,mBACLA,KAAA,QAAAA,EAAK,SAASyR;AAAA,EAChB;AAME,IAAIiD,GAAcpT,EAAO,SAAS,MAAU,aAAavC,GAAMuC,EAAO,SAAS,IAC1EA,EAAO,YAAYvC,CAAI,GAC5BkW,GAAgB3T,CAAM;AAExB,EAAAA,EAAO,MAAA;AACT;AAuBO,SAAS6T,GACd7T,GACA0T,IAAmC,IAC1B;AACT,QAAMvX,IAAM6D,EAAO,eACbtB,IAAMvC,EAAI,aAAA;AAChB,MAAI,CAACuC,KAAOA,EAAI,eAAe,KAAK,CAACA,EAAI,YAAa,QAAO;AAC7D,QAAMC,IAAQD,EAAI,WAAW,CAAC,GACxBjB,IAAOkB,EAAM;AACnB,MAAIlB,EAAK,aAAa,KAAK,aAAa,CAACuC,EAAO,SAASvC,CAAI,EAAG,QAAO;AAEvE,QAAMqW,IAASnV,EAAM,aACfpD,IAAOkC,EAAK,eAAe;AACjC,MAAIqW,IAAS,KAAKvY,EAAK,MAAMuY,IAAS,GAAGA,CAAM,MAAM,KAAM,QAAO;AAClE,QAAMC,IAAUxY,EAAK,YAAY,MAAMuY,IAAS,CAAC;AACjD,MAAIC,MAAY,GAAI,QAAO;AAE3B,QAAMpE,IAASpU,EAAK,MAAMwY,GAASD,CAAM,GACnCjO,IAASsD,GAA0BwG,CAAM;AAC/C,MAAI9J,EAAO,WAAW,KAAKA,EAAO,CAAC,EAAE,SAAS,OAAQ,QAAO;AAE7D,MAAImO,IAAU;AACd,SAAOD,IAAU,IAAIC,KAAW,KAAKzY,EAAKwY,IAAU,IAAIC,CAAO,MAAM,OAAM,CAAAA,KAAW;AACtF,MAAIA,IAAU,MAAM,EAAG,QAAO;AAE9B,QAAMC,IAAc9X,EAAI,YAAA;AACxB,EAAA8X,EAAY,SAASxW,GAAMsW,CAAO,GAClCE,EAAY,OAAOxW,GAAMqW,CAAM,GAC/BG,EAAY,eAAA;AACZ,QAAMC,IAAO/B,GAAShW,GAAK0J,EAAO,CAAC,GAAG6N,CAAI;AAC1C,EAAAO,EAAY,WAAWC,CAAI;AAE3B,QAAM/D,IAAQhU,EAAI,YAAA;AAClB,SAAAgU,EAAM,cAAc+D,CAAI,GACxB/D,EAAM,SAAS,EAAI,GACnBzR,EAAI,gBAAA,GACJA,EAAI,SAASyR,CAAK,GACX;AACT;AAYO,SAASgE,GAAWD,GAAgC;AACzD,QAAMlI,IAAO4G,GAAWsB,CAAI;AAC5B,MAAI,CAAClI,EAAM,QAAO;AAClB,QAAM4D,IACJ5D,EAAK,SAAS,UAAU,CAACuG,GAAmBvG,EAAK,IAAI,IACjD6D,GAAyB7D,EAAK,IAAI,IAClC,MACAzQ,IAAO2Y,EAAK,cAAc,eAAetE,KAAYjH,GAAkB,CAACqD,CAAI,CAAC,CAAC;AACpF,SAAAkI,EAAK,YAAY3Y,CAAI,GACdA;AACT;ACvkBO,SAAS6Y,GAAiB7Y,GAAc8Y,GAAsB;AACnE,MAAIC,IAAW;AACf,WAASvM,IAAI,GAAGA,IAAIsM,KAAOtM,IAAIxM,EAAK,QAAQwM,KAAK;AAC/C,UAAMwM,IAAKhZ,EAAKwM,CAAC;AACjB,QAAIuM,KAAYC,MAAO,MAAM;AAC3B,MAAAxM;AACA;AAAA,IACF;AACA,IAAIwM,MAAO,QAAKD,IAAW,CAACA;AAAA,EAC9B;AACA,SAAOA;AACT;AAaO,SAASE,GAAUvL,GAAqB;AAC7C,QAAM+I,IAAO/I,EAAI,MAAM,GAAG,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE,GAC5CnM,IAAOkV,EAAKA,EAAK,SAAS,CAAC,KAAK;AACtC,UAAKlV,MAAS,YAAYA,MAAS,WAAWkV,EAAK,UAAU,IACpDlV,MAAS,SAAS,GAAGkV,EAAKA,EAAK,SAAS,CAAC,CAAC,UAAUA,EAAKA,EAAK,SAAS,CAAC,IAE1ElV;AACT;AAGA,SAAS2X,GAAalZ,GAAc8Y,GAA+B;AACjE,QAAMK,IAAkB,CAAA;AACxB,MAAIJ,IAAW;AACf,WAAS,IAAI,GAAG,IAAID,KAAO,IAAI9Y,EAAK,QAAQ,KAAK;AAC/C,UAAMgZ,IAAKhZ,EAAK,CAAC;AACjB,QAAI+Y,GAAU;AACZ,MAAIC,MAAO,OAAM,MACRA,MAAO,QAAKD,IAAW;AAChC;AAAA,IACF;AACA,IAAIC,MAAO,MAAKD,IAAW,KAClBC,MAAO,OAAOA,MAAO,MAAKG,EAAM,KAAKH,CAAE,KACvCA,MAAO,OAAOA,MAAO,UAAW,IAAA;AAAA,EAC3C;AACA,QAAMI,IAAMD,EAAMA,EAAM,SAAS,CAAC;AAClC,SAAOC,MAAQ,OAAOA,MAAQ,MAAMA,IAAM;AAC5C;AAGA,SAASC,GAAQC,GAAqCjK,GAAqB;AACzE,MAAI,CAACiK,KAAO,CAAC,OAAO,OAAOA,GAAKjK,CAAG,EAAG,QAAOA;AAC7C,MAAI,IAAI;AACR,SAAO,OAAO,OAAOiK,GAAK,GAAGjK,CAAG,IAAI,CAAC,EAAE,IAAG;AAC1C,SAAO,GAAGA,CAAG,IAAI,CAAC;AACpB;AAkBO,SAASkK,GACdvZ,GACA8Y,GACApL,GACA8L,GACiC;;AACjC,QAAMC,IAAcD,IAAW,KAAK,UAAUA,EAAQ,KAAK,KAAK,SAAU,IACpEpF,IAASoF,IACX,KAAK,UAAU,OAAOA,EAAQ,SAAU,WAAWA,EAAQ,QAAQC,CAAW,EAAE,MAAM,GAAG,EAAE,IAC3F,MAAM/L,CAAG,OACPgM,IAASF,IAAUC,IAAc,KAAK,UAAUrF,CAAM,GACtDrT,IAAK,CAACyL,GAAWmN,OAAoB;AAAA,IACzC,MAAM3Z,EAAK,MAAM,GAAGwM,CAAC,IAAImN,IAAS3Z,EAAK,MAAMwM,CAAC;AAAA,IAC9C,OAAOA,IAAImN,EAAO;AAAA,EAAA;AAEpB,MAAId,GAAiB7Y,GAAM8Y,CAAG,EAAG,QAAO/X,EAAG+X,GAAK1E,CAAM;AAEtD,MAAI9J,GACAsP,IAAK;AACT,MAAI;AACF,IAAAtP,IAAS,KAAK,MAAMtK,CAAI;AAAA,EAC1B,QAAQ;AACN,IAAA4Z,IAAK;AAAA,EACP;AACA,QAAMN,IACJM,KAAMtP,MAAW,QAAQ,OAAOA,KAAW,YAAY,CAAC,MAAM,QAAQA,CAAM,IACvEA,IACD,MACAuP,IAAO,MAAM,GAAG,KAAK,UAAUR,GAAQC,GAAKL,GAAUvL,CAAG,CAAC,CAAC,CAAC,KAAKgM,CAAM,IAEvEI,IAAS9Z,EAAK,MAAM,GAAG8Y,CAAG,EAAE,QAAA,GAC5Bza,IAAOyb,EAAOA,EAAO,SAAS,CAAC,GAC/Brd,IAAOuD,EAAK,MAAM8Y,CAAG,EAAE,UAAA,EAAY,CAAC,GACpCiB,IAASb,GAAalZ,GAAM8Y,CAAG;AACrC,MAAIza,MAAS,OAAOA,MAAS,OAAQA,MAAS,OAAO0b,MAAW;AAC9D,WAAOhZ,EAAG+X,GAAKY,KAAUrb,MAAS,OAAO5B,MAAS,UAAaA,MAAS,MAAM,OAAO,GAAG;AAE1F,MAAI4B,MAAS,OAAQA,MAAS,OAAO0b,MAAW,KAAM;AACpD,UAAMC,IAAMvd,MAAS,UAAaA,MAAS,MAAM,OAAO;AACxD,WAAOsE,EAAG+X,IAAMza,MAAS,MAAM,MAAM,MAAMwb,EAAA,IAASG,CAAG;AAAA,EACzD;AAEA,MAAIJ,MAAON,KAAO,MAAM,QAAQhP,CAAM,IAAI;AACxC,UAAMmC,IAAQzM,EAAK,YAAYsZ,IAAM,MAAM,GAAG,GACxCW,IAAOja,EAAK,MAAM,GAAGyM,CAAK,EAAE,QAAA,GAC5ByN,IAAQD,EAAK,SAASX,IAAM,MAAM,GAAG,GACrCa,IAAOb,IAAMO,EAAA,IAASH,GACtBrS,IAAMrH,EAAK,MAAMia,EAAK,QAAQxN,CAAK;AACzC,QAAIpF,EAAI,SAAS;AAAA,CAAI,GAAG;AAEtB,YAAM+S,IAASF,IACX,GAAG7S,EAAI,MAAMA,EAAI,YAAY;AAAA,CAAI,IAAI,CAAC,CAAC,SACtC/V,IAAA,OAAO,KAAK2oB,EAAK,MAAMA,EAAK,YAAY;AAAA,CAAI,IAAI,CAAC,CAAC,MAAlD,gBAAA3oB,EAAsD,OAAM,IAC3DqoB,IAAS,GAAGO,IAAQ,KAAK,GAAG;AAAA,EAAKE,CAAM,GAAGD,CAAI;AACpD,aAAO,EAAE,MAAMF,IAAON,IAAS3Z,EAAK,MAAMia,EAAK,MAAM,GAAG,OAAOA,EAAK,SAASN,EAAO,OAAA;AAAA,IACtF;AACA,UAAMA,IAAS,GAAGO,IAAQ,KAAK,GAAG,IAAIC,CAAI,KACpC3N,IAAIyN,EAAK;AACf,WAAO,EAAE,MAAMja,EAAK,MAAM,GAAGwM,CAAC,IAAImN,IAAS3Z,EAAK,MAAMyM,CAAK,GAAG,OAAOD,IAAImN,EAAO,SAAS,EAAA;AAAA,EAC3F;AACA,SAAO5Y,EAAG+X,GAAKY,CAAM;AACvB;AAOA,MAAMW,KACJ;AACK,SAASC,GAAeta,GAA6B;AAC1D,QAAMC,IAAIoa,GAAS,KAAKra,EAAK,MAAM;AACnC,SAAOC,IAAI,MAAMA,EAAE,CAAC,CAAC,QAAQ;AAC/B;AAMO,SAASsa,GAAc5e,GAA+B;AAC3D,MAAI,OAAOA,KAAU,UAAU;AAC7B,QAAI,CAACA,EAAM,SAAS,IAAI,EAAG,QAAO;AAClC,UAAMsR,IAAQW,GAA0BjS,CAAK;AAC7C,WAAOsR,EAAM,WAAW,KAAKA,EAAM,CAAC,EAAE,SAAS,QAASA,EAAM,CAAC,EAAE,OAAO,OAAQ;AAAA,EAClF;AACA,SACEtR,MAAU,QACV,OAAOA,KAAU,YACjB,CAAC,MAAM,QAAQA,CAAK,KACpB,OAAO,KAAKA,CAAK,EAAE,WAAW,KAC9B,OAAQA,EAA0B,KAAM,WAEhCA,EAAwB,IAE3B;AACT;AAOO,SAAS6e,GACdjL,GACgB;;AAChB,QAAMU,IAA+D,CAAA;AACrE,aAAW,CAACvC,GAAK/R,CAAK,KAAK,OAAO,QAAQ4T,KAAgB,CAAA,CAAE,GAAG;AAC7D,UAAMtc,IAAM,qCAAqC,KAAKya,CAAG;AACzD,QAAIza,GAAK;AACP,MAAAgd,EAAMhd,EAAI,CAAC,CAAC,IAAI,EAAE,GAAGgd,EAAMhd,EAAI,CAAC,CAAC,GAAG,QAAQ0I,EAAA;AAC5C;AAAA,IACF;AACA,UAAM+T,IAAO,4CAA4C,KAAKhC,CAAG;AACjE,QAAIgC,GAAM;AACR,MAAAO,EAAA3e,IAAMoe,EAAK,CAAC,OAAZO,EAAA3e,KAAmB,CAAA;AACnB,YAAM0G,IAAIiY,EAAMP,EAAK,CAAC,CAAC;AAEvB,MAAA1X,EAAE,OAAO,EAAE,GAAGA,EAAE,MAAM,CAAC0X,EAAK,CAAC,CAAC,GAAG/T,EAAA;AAAA,IACnC;AAAA,EACF;AACA,SAAO,EAAE,OAAAsU,EAAA;AACX;AASO,SAASwK,GAAgB9e,GAAgB+e,GAAkD;AAChG,MAAI,OAAO/e,KAAU,UAAU;AAC7B,UAAMsR,IAAQoB,GAAoB1S,CAAK;AACvC,WAAKsR,IAEDA,EAAM,WAAW,KAAKA,EAAM,CAAC,EAAE,SAAS,QAAcyN,EAAY,EAAE,GAAGzN,EAAM,CAAC,EAAE,KAAK,IAClFyN,EAAY,EAAE,MAAM,QAAQ,OAAAzN,GAA2B,IAH3CtR;AAAA,EAIrB;AACA,MAAI,MAAM,QAAQA,CAAK,EAAG,QAAOA,EAAM,IAAI,CAAC9I,MAAM4nB,GAAgB5nB,GAAG6nB,CAAW,CAAC;AACjF,MAAI/e,MAAU,QAAQ,OAAOA,KAAU,UAAU;AAC/C,UAAMuZ,IAAO,OAAO,KAAKvZ,CAAK;AAC9B,WAAIuZ,EAAK,WAAW,KAAKA,EAAK,CAAC,MAAM,OAAO,OAAQvZ,EAAyB,KAAM,WAC1E+e,EAAY/e,CAAK,IAEnB,OAAO;AAAA,MACZ,OAAO,QAAQA,CAAK,EAAE,IAAI,CAAC,CAACqV,GAAGne,CAAC,MAAM,CAACme,GAAGyJ,GAAgB5nB,GAAG6nB,CAAW,CAAC,CAAC;AAAA,IAAA;AAAA,EAE9E;AACA,SAAO/e;AACT;AChJO,SAASgf,GAAsB;AAAA,EACpC,OAAAhf;AAAA,EACA,QAAAif;AAAA,EACA,WAAAC;AAAA,EACA,SAAA/R;AAAA,EACA,YAAAgS;AAAA,EACA,QAAAC;AAAA,EACA,SAAA5H;AAAA,EACA,MAAAtc;AAAA,EACA,WAAAmkB;AAAA,EACA,YAAAC;AAAA,EACA,OAAOC;AAAA,EACP,eAAeC;AAAA,EACf,aAAAC;AAAA,EACA,OAAAvI;AACF,GAA+B;;AAC7B,QAAMwI,IAAcxkB,MAAS,gBACvBykB,IAAWD,KAAeF,MAAsB,IAEhD,CAACI,GAAUC,CAAW,IAAIzkB,EAA0B,KAAK,GAGzD,CAAC0kB,GAAUC,CAAW,IAAI3kB;AAAA,IAAS,MACvCikB,MAAc,SAAY,KAAK,KAAK,UAAUA,GAAW,MAAM,CAAC;AAAA,EAAA,GAE5DW,IAAW/gB,GAA0B,IAAI,GAIzCghB,IAAchhB,GAAO,EAAK,GAC1BihB,IAAatS,GAAQ,MAAoD;AAC7E,QAAIkS,EAAS,KAAA,MAAW,GAAI,QAAO,EAAE,IAAI,GAAA;AACzC,QAAI;AACF,aAAO,EAAE,IAAI,IAAM,OAAO,KAAK,MAAMA,CAAQ,EAAA;AAAA,IAC/C,QAAQ;AACN,aAAO,EAAE,IAAI,GAAA;AAAA,IACf;AAAA,EACF,GAAG,CAACA,CAAQ,CAAC,GACPK,IAAcR,KAAYF,KAAA,gBAAAA,EAAcK,OAAa,OAAQ,MAC7DM,IAAcT,KACfG,EAAS,KAAA,MAAW,MAAMI,EAAW,OAAOC,MAAgB,OAC7DD,EAAW,IACTG,IAAc,MAClB1M;AAAA,IACExG,EAAQ;AAAA,IACR0R,GAAiB1R,EAAQ,YAAY;AAAA,IACrCA,EAAQ;AAAA,IACRA,EAAQ;AAAA,EAAA,GAENmT,IAAgB,CAACvO,MAAgB;AACrC,UAAM7D,IAAO8R,EAAS,SAChB/a,IAAMiJ,IAAOA,EAAK,MAAM,IAAI,aAAa4R;AAC/C,QAAIH,GAAU;AAGZ,YAAM9B,KACJ+B,MAAa,UACT,EAAE,OAAOlJ,GAAiB,MAAM3E,CAAG,OAAOsO,EAAA,CAAa,KAAK,SAC5D,QACAre,KAAOiD,EAAI,KAAA,MAAW,KAAK,OAAOA,GAClCkY,KAAM8C,EAAY,WAAW/R,IAAOA,EAAK,MAAM,UAAU,KAAK,OAAOlM,GAAK,QAC1ElB,KAAO8c,GAAc5b,IAAMmb,IAAKpL,GAAK8L,EAAO;AAClD,UAAI,CAAC3P,GAAM;AACT,QAAA6R,EAAYjf,GAAK,IAAI;AACrB;AAAA,MACF;AACA,MAAAoN,EAAK,SAAS;AAAA,QACZ,SAAS,EAAE,MAAM,GAAG,IAAIjJ,EAAI,QAAQ,QAAQnE,GAAK,KAAA;AAAA,QACjD,WAAW,EAAE,QAAQA,GAAK,MAAA;AAAA,MAAM,CACjC,GACDoN,EAAK,MAAA;AACL;AAAA,IACF;AAGA,QAAIqS,KAAuB;AAC3B,QAAI;AACF,MAAAA,KAAQtb,EAAI,WAAW,KAAK,OAAO2Z,GAAc,KAAK,MAAM3Z,CAAG,CAAC;AAAA,IAClE,QAAQ;AACN,MAAAsb,KAAQ;AAAA,IACV;AACA,QAAIC,KAAiB;AACrB,QAAIjB;AACF,UAAI;AACF,cAAM5Q,KAAkB,KAAK,MAAM1J,CAAG;AACtC,QAAAub,KAAiB,MAAM,QAAQ7R,EAAM,IACjCA,GAAO,WAAW,IAClB,OAAOA,MAAW,YAAYA,OAAW,QAAQ,OAAO,KAAKA,EAAM,EAAE,WAAW;AAAA,MACtF,QAAQ;AACN,QAAA6R,KAAiB;AAAA,MACnB;AAEF,QAAIvb,EAAI,KAAA,MAAW,MAAMsb,OAAU,QAAQC,IAAgB;AACzD,MAAAlB,KAAA,QAAAA,EAAa,MAAMvN,CAAG,QACtByF,EAAA;AACA;AAAA,IACF;AACA,QAAI,CAACtJ,EAAM;AAEX,UAAMiP,KAAM8C,EAAY,UAAU/R,EAAK,MAAM,UAAU,KAAK,OAAOjJ,EAAI,QACjEnE,KAAO8c,GAAc3Y,GAAKkY,IAAKpL,CAAG;AACxC,IAAA7D,EAAK,SAAS;AAAA,MACZ,SAAS,EAAE,MAAM,GAAG,IAAIjJ,EAAI,QAAQ,QAAQnE,GAAK,KAAA;AAAA,MACjD,WAAW,EAAE,QAAQA,GAAK,MAAA;AAAA,IAAM,CACjC,GACDoN,EAAK,MAAA;AAAA,EACP,GACM,CAACoD,GAAOmP,CAAQ,IAAIrlB;AAAA,IACxB,MAAMkd,GAAqB1F,GAAa5S,CAAK,EAAE,OAAOmN,CAAO,EAAE;AAAA,EAAA,GAE3DuT,IAAW9S,GAAQ,MAAM0K,GAAqBhH,GAAOnE,CAAO,GAAG,CAACmE,GAAOnE,CAAO,CAAC,GAK/E,CAACwT,GAAUC,CAAW,IAAIxlB,EAAS,CAAC,GACpCiP,IAAYpL,GAAuB,IAAI,GAGvC4hB,IAAuB5hB,GAAO,EAAK,GAGnC,CAAC6T,GAASgO,CAAU,IAAI1lB,EAAiC,CAAA,CAAE,GAI3D,CAAC2lB,IAAQC,EAAS,IAAI5lB,EAAkC,IAAI,GAI5D,CAAC6lB,GAAUC,CAAW,IAAI9lB,EAAsB,MAAM,oBAAI,KAAK,GAC/D+lB,IAAiB,CAACzN,MAAgB;AACtC,IAAAwN,EAAY,CAACxe,MAAS;AACpB,YAAM5B,IAAO,IAAI,IAAI4B,CAAI;AACzB,aAAI5B,EAAK,IAAI4S,CAAG,IAAG5S,EAAK,OAAO4S,CAAG,IAC7B5S,EAAK,IAAI4S,CAAG,GACV5S;AAAA,IACT,CAAC;AAAA,EACH,GAGM,CAACsgB,GAAUC,CAAW,IAAIjmB,EAAyC,MAAM;AAG/E,EAAAkmB,GAAgB,MAAM;AACpB,UAAM/b,IAAK8E,EAAU;AACrB,IAAK9E,MAGLgX,GAAWhX,GAAI+L,GAAO,EAAE,cAAc,IAAM,GACxCuP,EAAqB,YACvBA,EAAqB,UAAU,IAC/BpE,GAAgBlX,CAAE,GAClBA,EAAG,MAAA;AAAA,EAEP,GAAG,CAACob,CAAQ,CAAC;AAEb,QAAMY,IAAO,MAAM;AACjB,UAAMhc,IAAK8E,EAAU;AACrB,IAAI9E,KAAIkb,EAAS9E,GAAUpW,CAAE,CAAC;AAAA,EAChC,GAEMic,KAAa,CAAC1M,MAAmB;AACrC,UAAMvP,IAAK8E,EAAU;AACrB,IAAK9E,MACLmX,GAAkBnX,GAAI0V,GAAS1V,EAAG,eAAeuP,GAAM,EAAE,cAAc,GAAA,CAAM,CAAC,GAC9E2L,EAAS9E,GAAUpW,CAAE,CAAC;AAAA,EACxB,GAQMkc,IAAgBnQ,EAAM,KAAK,CAAClY,MAAMA,EAAE,SAAS,QAAQ,GAWrDsoB,IAAY,CAACrd,GAAc,EAAE,cAAAsd,QAA8C;AAC/E,IAAAlB,EAASnI,GAAqBrG,GAA0B5N,CAAI,GAAG8I,CAAO,EAAE,KAAK,GAE7EyT,EAAY,CAACnX,MAAMA,IAAI,CAAC;AAAA,EAC1B,GAEMmY,IAAO,MAAM;AACjB,UAAMrc,IAAK8E,EAAU,SACfvJ,IAAOwX,GAAqB/S,IAAKoW,GAAUpW,CAAE,IAAI+L,GAAOnE,CAAO;AACrE,IAAIrM,EAAK,UACTse,KAAA,QAAAA,EAAS/N,GAAavQ,EAAK,KAAK,IAChC0W,EAAA;AAAA,EACF,GAQMqK,IAAc,MAAM;AACxB,IAAAb,GAAU,IAAI,GACdH,EAAqB,UAAU,IAC/BD,EAAY,CAACnX,MAAMA,IAAI,CAAC;AAAA,EAC1B,GAEM4K,IAAOlH,EAAQ,QAAQ,CAAA,GACvB+G,KAAY/G,EAAQ,aAAa,CAAA,GACjC2U,KAAU3U,EAAQ,WAAW,CAAA,GAC7B4U,KAAS5U,EAAQ,UAAU,CAAA,GAC3B8G,KAAY9G,EAAQ,aAAa,CAAA,GACjCmH,KAAQnH,EAAQ,SAAS,CAAA,GACzB6U,KAAc7U,EAAQ,eAAe,CAAA,GACrC8U,KAAO9U,EAAQ,MAIf+U,KAAa,IAAI;AAAA,IACrBF,GACG,IAAI,CAACpY,MAAM,CAACA,EAAE,IAAIA,EAAE,KAAK,OAAO2Q,EAAY,CAAC,CAAU,EACvD,OAAO,CAAC,CAAA,EAAGhB,CAAI,MAAMA,EAAK,SAAS,CAAC;AAAA,EAAA,GAKnC4I,KAAWhV,EAAQ,YAAY,CAAA,GAC/BiV,KAAe,CAACtsB,MACpBusB,GAAY;AAAA,IAAO,CAAC,CAAC3O,CAAG,MACtB4O,GAAc,IAAI5O,CAAG,IAAI6O,GAAkBzsB,CAAE,IAAI,OAAO,OAAOqsB,GAASrsB,CAAE,KAAK,CAAA,GAAI4d,CAAG;AAAA,EAAA,GAIpF8O,KAAiBlO,GAAM,OAAO,CAACmO,MAAOA,EAAG,YAAY,EAAI,EAAE,IAAI,CAACA,MAAOA,EAAG,EAAE,GAC5EF,KAAoB,CAACzsB,MAAe;;AACxC,QAAI0sB,GAAe,SAAS1sB,CAAE,EAAG,QAAO;AACxC,UAAM3C,KAAMwC,IAAAwsB,GAASrsB,CAAE,MAAX,gBAAAH,EAAc;AAC1B,WAAO,OAAOxC,KAAQ,YAAY,CAACwD,GAAcxD,CAAG;AAAA,EACtD,GACMuvB,KAAc,CAAC5sB,MACnBssB,GAAatsB,CAAE,EAAE;AAAA,IAAI,CAAC,CAAC4d,GAAK7H,CAAK,MAC/BmB,GAAOnB,GAAO,EAAE,MAAM,OAAO,KAAK,SAAS/V,CAAE,SAAS4d,CAAG,GAAA,GAAM,uBAAuB,IAAI;AAAA,EAAA,GAMxFiP,KAAU,CAAC,uBAAO,IAAI,CAAC,GAAG,OAAO,KAAKR,EAAQ,GAAG,GAAGK,IAAgB,GAAGN,GAAW,KAAA,CAAM,CAAC,CAAC,GAC1FU,KAAmBtO,GAAM,SAAS,KAAK,CAAC,CAACnH,EAAQ,YACjD0V,KAAW,CAAClD,MAAaiD,MAAoB,CAAC,CAACX,KAG/Ca,KAAcnD,IAChB,CAAA,OACChqB,KAAAwX,EAAQ,eAAR,gBAAAxX,GAAoB,WAAU,CAAA,GAAI,OAAO,CAACilB,MAAMJ,GAAcI,EAAE,GAAG,CAAC,GACnEvR,KAA6B;AAAA,IACjC,GAAIwZ,KAAY,CAAC,OAAO,IAAc,CAAA;AAAA,IACtC,GAAIC,GAAY,SAAS,IAAK,CAAC,UAAU,IAAc,CAAA;AAAA,IACvD,GAAIH,GAAQ,SAAS,IAAK,CAAC,MAAM,IAAc,CAAA;AAAA,IAC/C,GAAIxV,EAAQ,WAAW,SAAa,CAAC,QAAQ,IAAc,CAAA;AAAA,IAC3D;AAAA,IACA,GAAI+G,GAAU,SAAS,IAAK,CAAC,QAAQ,IAAc,CAAA;AAAA,IACnD,GAAI,CAACwL,KAAeC,IAAY,CAAC,MAAM,IAAc,CAAA;AAAA,IACrD,GAAKD,IAAuC,CAAA,IAAxB,CAAC,SAAS;AAAA,EAAe,GAEzCqD,KACJ3B,MAAa,UAAWA,MAAa,QAAQ,CAAC/X,GAAS,SAAS+X,CAAQ,IACnE/X,GAAS,KAAK,CAAC,MAAM,MAAM,MAAM,KAAK,OACvC+X,GAEA4B,KAAe,CAACtP,OAAyB;AAAA,IAC7C,MAAMqP,OAAgBrP;AAAA,IACtB,UAAU,MAAM2N,EAAY0B,OAAgBrP,IAAM,OAAOA,CAAG;AAAA,EAAA,IAExDuP,OAAchB,MAAA,gBAAAA,GAAM,gBAAe,CAAA,GAAI;AAAA,IAAO,CAAC7S,MACnDA,EAAE,OAAOoL,GAAcpL,EAAE,GAAG,IAAImL,GAAanL,EAAE,GAAG;AAAA,EAAA,GAE9C8T,MAAe/V,EAAQ,gBAAgB,CAAA,GAAI;AAAA,IAAO,CAACiC,MACvDA,EAAE,OAAOoL,GAAcpL,EAAE,GAAG,IAAImL,GAAanL,EAAE,GAAG;AAAA,EAAA,GAE9C+T,KAAW1R,GAAkBiP,EAAS,KAAK,GAM3C0C,KAAmBxV,GAAQ,MAAM;AACrC,UAAM8G,IAAiC,CAAA;AACvC,eAAW,CAAC3C,GAAK7a,CAAC,KAAK,OAAO,QAAQiW,EAAQ,gBAAgB,CAAA,CAAE;AAC9D,MAAAuH,EAAO3C,CAAG,IAAI,OAAO7a,KAAM,WAAWA,IAAI,KAAK,UAAUA,CAAC;AAE5D,WAAO,EAAE,GAAGwd,GAAQ,GAAG5B,EAAA;AAAA,EACzB,GAAG,CAAC3F,EAAQ,cAAc2F,CAAO,CAAC,GAQ5BuQ,KAAWzV,GAAQ,MAAMwL,GAAmBsH,EAAS,KAAK,GAAG,CAACA,EAAS,KAAK,CAAC,GAG7E4C,KAAS1V,GAAQ,MAAM;AAC3B,QAAI8S,EAAS,MAAO,QAAO;AAC3B,QAAI;AACF,aAAOhH,GAAqBgH,EAAS,OAAOvT,EAAQ,cAAc2F,CAAO;AAAA,IAC3E,QAAQ;AAEN,aAAOqQ;AAAA,IACT;AAAA,EACF,GAAG,CAACzC,GAAUvT,EAAQ,cAAc2F,GAASqQ,EAAQ,CAAC,GAIhDI,IAAc3V,GAAQ,MAAM;;AAChC,UAAMtE,wBAAY,IAAA;AAClB,eAAWyI,KAAOsR,IAAU;AAC1B,UAAIvQ,EAAQf,CAAG,MAAM,OAAW;AAChC,YAAMyR,MAAO7tB,IAAAwX,EAAQ,iBAAR,gBAAAxX,EAAuBoc;AACpC,MAAIyR,OAAS,WAAUla,EAAM,IAAI,sBAAsB,IAC9Cka,OAAS,eAAala,EAAM,IAAI,gBAAgB;AAAA,IAC3D;AACA,WAAO,CAAC,GAAGA,CAAK;AAAA,EAClB,GAAG,CAAC+Z,IAAUvQ,GAAS3F,EAAQ,YAAY,CAAC,GAMtCH,KAAS,CACbnB,GACAiJ,GACA3J,GACAiQ,IACAqI,KAAa,IACb9T,IAGA8D,OAEA,gBAAAxR;AAAA,IAAC;AAAA,IAAA;AAAA,MAEC,WAAU;AAAA,MACV,OAAO;AAAA,QACL,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,UAAU;AAAA,QACV,GAAIwR,MAAQA,GAAK,QAAQ,IAAI,EAAE,aAAaA,GAAK,QAAQ,OAAO,CAAA;AAAA,MAAC;AAAA,MAGnE,UAAA;AAAA,QAAA,gBAAAxR;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAW,wBAAwBkJ,CAAG,GAAGsI,MAAA,QAAAA,GAAM,eAAe,sBAAsB,EAAE;AAAA,YACtF,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,GAAIA,MAAA,QAAAA,GAAM,eAAe,EAAE,SAAS,IAAA,IAAQ,CAAA,EAAC;AAAA,YAC5E,OAAO,WAAUA,MAAA,gBAAAA,GAAM,SAAQ5H,CAAK;AAAA,YACpC,cAAY8D;AAAA,YACZ,SAAS,MACP+P,IAAc5K,EAAK,SAAS,SAASwL,EAAcxL,EAAK,OAAO,EAAE,IAAI0M,GAAW1M,CAAI;AAAA,YAGrF,UAAA;AAAA,cAAAsG,OAAU,QAAQ,gBAAAjf,EAAC,QAAA,EAAK,WAAU,uBAAuB,UAAAif,IAAM;AAAA,cAChE,gBAAAjf,EAAC,QAAA,EAAK,WAAU,8BAA8B,UAAA0P,GAAM;AAAA,eACnD4H,MAAA,gBAAAA,GAAM,iBACL,gBAAAtX;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,eAAY;AAAA,kBACZ,OAAO,EAAE,YAAY,EAAA;AAAA,kBACtB,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,eAIFsX,MAAA,gBAAAA,GAAM,cACL,gBAAAtX;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,eAAY;AAAA,kBACZ,OAAM;AAAA,kBACN,OAAO,EAAE,YAAY,EAAA;AAAA,kBACtB,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YAED;AAAA,UAAA;AAAA,QAAA;AAAA,QAGH,CAACujB,KACA,gBAAAvjB;AAAA,UAAC2a;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,UAAU;AAAA,YACV,OAAM;AAAA,YACN,eAAY;AAAA,YACZ,SAAS,MAAM0K,GAAW1M,CAAI;AAAA,UAAA;AAAA,QAAA;AAAA,MAChC;AAAA,IAAA;AAAA,IAjDG,GAAGA,EAAK,IAAI,IAAIA,EAAK,OAAOjJ,CAAK;AAAA,EAAA,GAsDpC6X,KAAWzC,EAAS,IAAI,WAAW,GACnC0C,KAAiB3W;AAAA,IACrB;AAAA,IACA,EAAE,MAAM,OAAO,KAAK,eAAA;AAAA,IACpB;AAAA,IACA;AAAA,EAAA,GAKI4W,KAAc,CAAC9tB,GAAYyjB,MAAmB;AAClD,QAAIA,EAAK,WAAW,EAAG,QAAO;AAC9B,UAAMnT,IAAO6a,EAAS,IAAI,QAAQnrB,CAAE,EAAE;AACtC,WACE,gBAAAmM,EAAAwB,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAtH,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA,gBAAA8F;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,eAAY;AAAA,UACZ,iBAAemE;AAAA,UACf,OAAOA,IAAO,gBAAgB;AAAA,UAC9B,SAAS,MAAM+a,EAAe,QAAQrrB,CAAE,EAAE;AAAA,UAE1C,UAAA;AAAA,YAAA,gBAAAqG,EAAC,UAAK,WAAU,4BAA2B,eAAY,QACpD,UAAAiK,IAAO,MAAM,IAAA,CAChB;AAAA,YAAO;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA,GAGX;AAAA,MACCA,KACC,gBAAAjK,EAAC,OAAA,EAAI,WAAU,4BAA2B,eAAY,sBACnD,UAAAod,EAAK;AAAA,QAAI,CAAClE,OACTrI;AAAA,UACEqI;AAAA,UACA,EAAE,MAAM,OAAO,KAAK,SAASvf,CAAE,gBAAgBuf,EAAC,GAAA;AAAA,UAChD;AAAA,UACA;AAAA,QAAA;AAAA,MACF,EACF,CACF;AAAA,IAAA,GAEJ;AAAA,EAEJ,GAMMwO,KAAe,CACnBC,GACApJ,GACAjK,IAAU,SAASqT,CAAM,cAEzBrJ,GAAgBC,CAAM,EAAE,IAAI,CAAC,EAAE,OAAAG,IAAO,OAAAE,IAAO,MAAAlf,SAAW;AACtD,UAAMkW,KAAM,GAAGtB,CAAO,IAAIoK,GAAM,GAAG;AACnC,WAAO7N,GAAOnR,IAAM,EAAE,MAAM,OAAO,KAAAkW,MAAO,uBAAuB,MAAM,IAAO,QAAW;AAAA,MACvF,MAAMkI,GAASlI,EAAG;AAAA,MAClB,OAAAgJ;AAAA,MACA,cAAcF,GAAM,iBAAiB;AAAA,IAAA,CACtC;AAAA,EACH,CAAC,GAKGkJ,KAAY,CAACC,MACbA,MAAS,WAAWA,MAAS,cAE7B,gBAAA7nB,EAAC,UAAK,WAAU,4BAA2B,eAAY,yBACpD,UAAA6nB,MAAS,UAAU,kCAAkC,wBAAA,CACxD,IAGAA,MAAS,cAAcA,MAAS,WAEhC,gBAAA7nB,EAAC,QAAA,EAAK,WAAU,4BAA2B,eAAa,oBAAoB6nB,CAAI,IAC7E,UAAAA,MAAS,aAAa,wBAAwB,wBACjD,IAGG,MAKHC,KAAW,CAACnuB,MAAe;AAC/B,UAAM4d,IAAM,SAAS5d,CAAE,IACjBsQ,IAAO6a,EAAS,IAAIvN,CAAG;AAC7B,WACE,gBAAAzR,EAACwB,IAAA,EACC,UAAA;AAAA,MAAA,gBAAAxB,EAAC,OAAA,EAAI,WAAU,4BAA2B,eAAY,sBACpD,UAAA;AAAA,QAAA,gBAAA9F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,eAAY;AAAA,YACZ,iBAAeiK;AAAA,YACf,cAAYA,IAAO,QAAQtQ,CAAE,cAAc,QAAQA,CAAE;AAAA,YACrD,OAAOsQ,IAAO,kBAAkB;AAAA,YAChC,SAAS,MAAM+a,EAAezN,CAAG;AAAA,YAEhC,cAAO,MAAM;AAAA,UAAA;AAAA,QAAA;AAAA,QAEf1G;AAAA,UACClX;AAAA,UACA,EAAE,MAAM,OAAO,KAAK,SAASA,CAAE,QAAA;AAAA,UAC/B;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MACF,GACF;AAAA,MACCsQ,KACC,gBAAAnE,EAAC,OAAA,EAAI,WAAU,4BAA2B,eAAY,wBACnD,UAAA;AAAA,QAAAygB,GAAY5sB,CAAE;AAAA,QACd8tB,GAAY9tB,GAAIosB,GAAW,IAAIpsB,CAAE,KAAK,CAAA,CAAE;AAAA,MAAA,EAAA,CAC3C;AAAA,IAAA,EAAA,GAzBW4d,CA2Bf;AAAA,EAEJ;AAEA,SACE,gBAAAzR;AAAA,IAACsV;AAAA,IAAA;AAAA,MACC,OAAOL,MAAUwI,IAAc,oBAAoB;AAAA,MACnD,UAAUP,IAAa,gBAAAhjB,EAAC,QAAA,EAAM,aAAW,IAAU;AAAA,MACnD,SAAAqb;AAAA,MACA,MAAK;AAAA,MACL,aACEkI,IACE,gBAAAzd,EAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,YAAO,MAAK,UAAS,WAAU,yBAAwB,SAASqb,GAAS,UAAA,SAAA,CAE1E;AAAA,QACA,gBAAArb;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,eAAY;AAAA,YACZ,UAAU,CAACikB;AAAA,YACX,OACEA,IACI,2BACCD,KAAe;AAAA,YAEtB,SAAS,MAAM;AACb,cAAKC,MACLd,KAAA,QAAAA,EAAaY,EAAW,KAAKA,EAAW,QAAQ,SAChD1I,EAAA;AAAA,YACF;AAAA,YACD,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,EAAA,CACF,IAEA,gBAAAvV,EAAC,OAAA,EAAI,WAAU,yBAMZ,UAAA;AAAA,QAAA,CAACgd,KACA,gBAAA9iB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,UAAUslB;AAAA,YACV,OACEA,IACI,0FACA;AAAA,YAEN,SAAS,MAAM;AACb,cAAArC,KAAA,QAAAA,EAAS3N,GAAkBH,CAAK,IAChCkG,EAAA;AAAA,YACF;AAAA,YACD,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAIH,gBAAArb,EAAC,YAAO,MAAK,UAAS,WAAU,yBAAwB,SAASqb,GAAS,UAAA,SAAA,CAE1E;AAAA,QACA,gBAAArb;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,SAASylB;AAAA,YACT,eAAY;AAAA,YACZ,UAAUlB,EAAS,UAAU;AAAA,YAC9B,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,GACF;AAAA,MAIJ,UAAA;AAAA,QAAA,gBAAAze,EAAC,OAAA,EAAI,WAAU,iBAEb,UAAA;AAAA,UAAA,gBAAAA,EAAC,SAAA,EAAM,WAAU,yBAKd,UAAA;AAAA,YAAA0d,KACC,gBAAA1d;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,cAAW;AAAA,gBACX,OAAO,EAAE,SAAS,QAAQ,KAAK,GAAG,YAAY,UAAU,cAAc,EAAA;AAAA,gBAEtE,UAAA;AAAA,kBAAA,gBAAA9F,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,aAAS;AAAA,kBAE7C;AAAA,oBACE,CAAC,OAAO,aAAa,iDAAiD;AAAA,oBACtE,CAAC,SAAS,SAAS,kDAAkD;AAAA,kBAAA,EAEvE,IAAI,CAAC,CAACuX,GAAK7H,GAAOqY,CAAI,MACtB,gBAAA/nB;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBAEC,MAAK;AAAA,sBACL,gBAAcyjB,MAAalM;AAAA,sBAC3B,eAAa,kBAAkBA,CAAG;AAAA,sBAClC,OAAOwQ;AAAA,sBACP,WAAW,qBAAqBtE,MAAalM,IAAM,KAAK,gBAAgB;AAAA,sBACxE,SAAS,MAAMmM,EAAYnM,CAAG;AAAA,sBAE7B,UAAA7H;AAAA,oBAAA;AAAA,oBARI6H;AAAA,kBAAA,CAUR;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAGJgM,KAAe,CAACC,KAAY,CAACkD,MAC5B,gBAAA1mB,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,oBAAA,CAAiB;AAAA,YAExD0mB,wBACEsB,IAAA,EAAY,OAAM,kBAAkB,GAAGnB,GAAa,OAAO,GACzD,UAAA;AAAA,cAAAf,MACC,gBAAAhgB,EAAC,OAAA,EAAI,WAAU,0BAAyB,eAAY,mBAClD,UAAA;AAAA,gBAAA,gBAAA9F,EAAC,QAAA,EAAK,WAAU,4BAA2B,UAAA,QAAI;AAAA,gBAG9C8mB,GAAW,SAAS,IACnB,gBAAAhhB,EAAC,OAAA,EAAI,WAAU,4BACZ,UAAA;AAAA,kBAAA0hB;AAAA,kBACD,gBAAAxnB;AAAA,oBAACioB;AAAA,oBAAA;AAAA,sBACC,OAAOnB,GAAW;AAAA,sBAClB,MAAMS;AAAA,sBACN,UAAU,MAAMvC,EAAe,WAAW;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAC5C,EAAA,CACF,IAEAwC;AAAA,gBAEDV,GAAW,SAAS,KAAKS,MACxB,gBAAAvnB,EAAC,OAAA,EAAI,WAAU,4BAA2B,eAAY,oBACnD,UAAA8mB,GAAW,IAAI,CAAC7T,MAAM;AACrB,wBAAM2C,IAAM,gBAAgB3C,EAAE,GAAG;AACjC,yBAAOpC,GAAOoC,EAAE,KAAK,EAAE,MAAM,OAAO,KAAA2C,EAAA,GAAO,uBAAuB,IAAI;AAAA,gBACxE,CAAC,EAAA,CACH;AAAA,gBAED/E,GAAO,SAAS,EAAE,MAAM,OAAO,KAAK,gBAAA,GAAmB,qBAAqB,GAAG;AAAA,cAAA,GAClF;AAAA,cAEDG,EAAQ,eACN+V,GAAY,SAAS,IACpB,gBAAAjhB,EAAAwB,IAAA,EACE,UAAA;AAAA,gBAAA,gBAAAxB,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,kBAAA,gBAAA9F;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,MAAK;AAAA,sBACL,WAAU;AAAA,sBACV,eAAY;AAAA,sBACZ,iBAAe8kB,EAAS,IAAI,OAAO;AAAA,sBACnC,cAAYA,EAAS,IAAI,OAAO,IAAI,gBAAgB;AAAA,sBACpD,OAAOA,EAAS,IAAI,OAAO,IAAI,gBAAgB;AAAA,sBAC/C,SAAS,MAAME,EAAe,OAAO;AAAA,sBAEpC,UAAAF,EAAS,IAAI,OAAO,IAAI,MAAM;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBAEhCjU;AAAA,oBACC;AAAA,oBACA,EAAE,MAAM,OAAO,KAAK,gBAAA;AAAA,oBACpB;AAAA,oBACA;AAAA,oBACA;AAAA,kBAAA;AAAA,gBACF,GACF;AAAA,gBACCiU,EAAS,IAAI,OAAO,uBAClB,OAAA,EAAI,WAAU,4BAA2B,eAAY,qBACnD,UAAA;AAAA,kBAAA8C,GAAU5W,EAAQ,gBAAgB;AAAA,kBAClC0W,GAAa,IAAIX,IAAa,eAAe;AAAA,gBAAA,EAAA,CAChD;AAAA,cAAA,EAAA,CAEJ,IAEA,gBAAAjhB,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,gBAAA,gBAAA9F,EAAC,QAAA,EAAK,WAAU,8BAA6B,eAAY,QAAO;AAAA,gBAC/D6Q;AAAA,kBACC;AAAA,kBACA,EAAE,MAAM,OAAO,KAAK,gBAAA;AAAA,kBACpB;AAAA,kBACA;AAAA,gBAAA;AAAA,cACF,EAAA,CACF;AAAA,cAEHsH,GAAM,IAAI,CAACmO,MAAO;AAOjB,sBAAM/H,KAAU+H,EAAG,WAAW,CAAA,GAAI;AAAA,kBAAO,CAACrT,OACxCA,GAAE,OAAOoL,GAAcpL,GAAE,GAAG,IAAImL,GAAanL,GAAE,GAAG;AAAA,gBAAA,GAE9CiV,IAAU,QAAQ5B,EAAG,EAAE,IACvB6B,KAASrD,EAAS,IAAIoD,CAAO,GAQ7BE,KAAWvX;AAAA,kBACfyV,EAAG,SAASA,EAAG;AAAA,kBACf,EAAE,MAAM,OAAO,KAAK,SAASA,EAAG,EAAE,UAAA;AAAA,kBAClC;AAAA,kBACA;AAAA,kBACA/H,EAAO,SAAS;AAAA,gBAAA;AAElB,uBAAIgF,IAEA,gBAAAzd,EAACwB,IAAA,EACC,UAAA;AAAA,kBAAA,gBAAAtH,EAAC,UAAK,WAAU,4BAA4B,UAAAsmB,EAAG,SAASA,EAAG,IAAG;AAAA,kBAC7DzV;AAAA,oBACC;AAAA,oBACA,EAAE,MAAM,OAAO,KAAK,SAASyV,EAAG,EAAE,UAAA;AAAA,oBAClC;AAAA,oBACA;AAAA,oBACA;AAAA,oBACA,oBAAoBA,EAAG,SAASA,EAAG,EAAE;AAAA,kBAAA;AAAA,kBAEtCA,EAAG,aACF,gBAAAtmB,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,4BAA2B,eAAY,mBAAkB,uDAEzE,GACF;AAAA,kBAEDue,EAAO,SAAS,KACf,gBAAAzY,EAAAwB,IAAA,EACE,UAAA;AAAA,oBAAA,gBAAAxB,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,sBAAA,gBAAA9F;AAAA,wBAAC;AAAA,wBAAA;AAAA,0BACC,MAAK;AAAA,0BACL,WAAU;AAAA,0BACV,eAAY;AAAA,0BACZ,iBAAemoB;AAAA,0BACf,cAAYA,KAAS,gBAAgB;AAAA,0BACrC,OAAOA,KAAS,gBAAgB;AAAA,0BAChC,SAAS,MAAMnD,EAAekD,CAAO;AAAA,0BAEpC,eAAS,MAAM;AAAA,wBAAA;AAAA,sBAAA;AAAA,sBAElB,gBAAAloB;AAAA,wBAACioB;AAAA,wBAAA;AAAA,0BACC,OAAO1J,EAAO;AAAA,0BACd,MAAM4J;AAAA,0BACN,UAAU,MAAMnD,EAAekD,CAAO;AAAA,wBAAA;AAAA,sBAAA;AAAA,oBACxC,GACF;AAAA,oBACCC,MACC,gBAAAriB,EAAC,OAAA,EAAI,WAAU,4BACZ,UAAA;AAAA,sBAAA8hB,GAAUtB,EAAG,WAAW;AAAA,sBACxBoB,GAAapB,EAAG,IAAI/H,CAAM;AAAA,oBAAA,EAAA,CAC7B;AAAA,kBAAA,EAAA,CAEJ;AAAA,gBAAA,EAAA,GA3CW+H,EAAG,EA6ClB,IAIF,gBAAAxgB,EAACwB,IAAA,EACE,UAAA;AAAA,kBAAAiX,EAAO,SAAS,IACf,gBAAAzY,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,oBAAA,gBAAA9F;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,MAAK;AAAA,wBACL,WAAU;AAAA,wBACV,eAAY;AAAA,wBACZ,iBAAemoB;AAAA,wBACf,cAAYA,KAAS,gBAAgB;AAAA,wBACrC,OAAOA,KAAS,gBAAgB;AAAA,wBAChC,SAAS,MAAMnD,EAAekD,CAAO;AAAA,wBAEpC,eAAS,MAAM;AAAA,sBAAA;AAAA,oBAAA;AAAA,oBAEjBE;AAAA,oBACD,gBAAApoB;AAAA,sBAACioB;AAAA,sBAAA;AAAA,wBACC,OAAO1J,EAAO;AAAA,wBACd,MAAM4J;AAAA,wBACN,UAAU,MAAMnD,EAAekD,CAAO;AAAA,sBAAA;AAAA,oBAAA;AAAA,kBACxC,EAAA,CACF,IAEA,gBAAApiB,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,oBAAA,gBAAA9F,EAAC,QAAA,EAAK,WAAU,8BAA6B,eAAY,QAAO;AAAA,oBAC/DooB;AAAA,kBAAA,GACH;AAAA,kBAKD9B,EAAG,aACF,gBAAAtmB,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,4BAA2B,eAAY,mBAAkB,uDAEzE,GACF;AAAA,kBAKDue,EAAO,SAAS,KAAK4J,MACpB,gBAAAriB,EAAC,OAAA,EAAI,WAAU,4BACZ,UAAA;AAAA,oBAAA8hB,GAAUtB,EAAG,WAAW;AAAA,oBACxBoB,GAAapB,EAAG,IAAI/H,CAAM;AAAA,kBAAA,EAAA,CAC7B;AAAA,gBAAA,EAAA,GA5CW+H,EAAG,EA8ClB;AAAA,cAEJ,CAAC;AAAA,YAAA,GACH;AAAA,YAEDK,GAAY,SAAS,KACpB,gBAAA7gB,EAACkiB,IAAA,EAAY,OAAM,SAAQ,QAAO,oBAAoB,GAAGnB,GAAa,UAAU,GAG7E,UAAA;AAAA,cAAAhW,GAAO,SAAS,EAAE,MAAM,OAAO,KAAK,WAAW,qBAAqB,KAAK,EAAI;AAAA,cAC9E,gBAAA7Q,EAAC,OAAA,EAAI,WAAU,4BAA2B,eAAY,qBACnD,UAAAse,GAAgBqI,EAAW,EAAE,IAAI,CAAC,EAAE,OAAAjI,GAAO,OAAAE,GAAO,MAAAlf,QAAW;AAC5D,sBAAMkW,KAAM,SAAS8I,EAAM,GAAG;AAC9B,uBAAO7N;AAAA,kBACLnR;AAAA,kBACA,EAAE,MAAM,OAAO,KAAAkW,GAAA;AAAA,kBACf;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,EAAE,MAAMkI,GAASlI,EAAG,GAAG,OAAAgJ,GAAO,WAAWF,EAAM,UAAU,OAAA;AAAA,gBAAO;AAAA,cAEpE,CAAC,EAAA,CACH;AAAA,YAAA,GACF;AAAA,YAED8H,GAAQ,SAAS,KAChB,gBAAAxmB,EAACgoB,MAAY,OAAM,YAAW,QAAO,uBAAuB,GAAGnB,GAAa,MAAM,GAG/E,aAAQ,IAAI,CAACltB,MAAOmuB,GAASnuB,CAAE,CAAC,GACnC;AAAA,YAIF,gBAAAmM,EAAAwB,IAAA,EACG,UAAA;AAAA,cAAA0J,EAAQ,WAAW,UAClB,gBAAAlL,EAACkiB,IAAA,EAAY,OAAM,UAAU,GAAGnB,GAAa,QAAQ,GAClD,UAAA;AAAA,gBAAAjB,GAAO,WAAW,KAAK,gBAAA5lB,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,aAAS;AAAA,gBACtE4lB,GAAO;AAAA,kBAAI,CAAClR,MACX7D,GAAO6D,GAAG,EAAE,MAAM,OAAO,KAAK,UAAUA,CAAC,GAAA,GAAM,qBAAqB,GAAG;AAAA,gBAAA;AAAA,cACzE,GACF;AAAA,cAGF,gBAAA5O;AAAA,gBAACkiB;AAAA,gBAAA;AAAA,kBACC,OAAM;AAAA,kBACL,GAAGnB,GAAa,MAAM;AAAA,kBACvB,QACE7V,EAAQ,aACN,gBAAAhR;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,MAAK;AAAA,sBACL,WAAU;AAAA,sBACV,eAAY;AAAA,sBACZ,SAAS,MAAM6kB,GAAU,KAAK;AAAA,sBAC/B,UAAA;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBAMJ,UAAA;AAAA,oBAAA3M,EAAK,WAAW,KAAK,gBAAAlY,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,gBAAY;AAAA,oBACvEkY,EAAK;AAAA,sBAAI,CAACnd,MACT8V,GAAO9V,GAAG,EAAE,MAAM,OAAO,KAAK,OAAOA,CAAC,GAAA,GAAM,qBAAqB,GAAG;AAAA,oBAAA;AAAA,kBACtE;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGDgd,GAAU,SAAS,KAClB,gBAAA/X;AAAA,gBAACgoB;AAAA,gBAAA;AAAA,kBACC,OAAM;AAAA,kBACN,QAAO;AAAA,kBACN,GAAGnB,GAAa,QAAQ;AAAA,kBAExB,UAAA9O,GAAU;AAAA,oBAAI,CAAC7R,MACd2K,GAAO3K,GAAG,EAAE,MAAM,OAAO,KAAK,SAASA,CAAC,GAAA,GAAM,qBAAqB,GAAG;AAAA,kBAAA;AAAA,gBACxE;AAAA,cAAA;AAAA,YACF,GAEJ;AAAA,aACE,CAACqd,KAAeC,MAChB,gBAAA1d,EAACkiB,IAAA,EAAY,OAAM,aAAa,GAAGnB,GAAa,MAAM,GACnD,UAAA;AAAA,cAAA/O,GAAU,WAAW,KAAK,gBAAA9X,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,gBAAY;AAAA,cAC5E8X,GAAU,IAAI,CAACtJ,MAAM;AAIpB,sBAAM+P,KAAU/P,EAAE,UAAU,CAAA,GAAI,OAAO,CAACiQ,OAAML,GAAaK,GAAE,GAAG,CAAC,GAC3D4J,IAAS,OAAO7Z,EAAE,GAAG,IACrB2Z,KAASrD,EAAS,IAAIuD,CAAM,GAI5BD,KAAWvX;AAAA,kBACfrC,EAAE;AAAA,kBACF,EAAE,MAAM,OAAO,KAAK,aAAaA,EAAE,GAAG,GAAA;AAAA,kBACtC;AAAA,kBACA;AAAA,kBACA+P,EAAO,SAAS;AAAA,gBAAA;AAElB,uBACE,gBAAAzY,EAACwB,IAAA,EACE,UAAA;AAAA,kBAAAiX,EAAO,SAAS,IACf,gBAAAzY,EAAC,OAAA,EAAI,WAAU,4BACZ,UAAA;AAAA,oBAAAsiB;AAAA,oBACD,gBAAApoB;AAAA,sBAACioB;AAAA,sBAAA;AAAA,wBACC,OAAO1J,EAAO;AAAA,wBACd,MAAM4J;AAAA,wBACN,UAAU,MAAMnD,EAAeqD,CAAM;AAAA,sBAAA;AAAA,oBAAA;AAAA,kBACvC,EAAA,CACF,IAEAD;AAAA,kBAYD7J,EAAO,SAAS,KAAK4J,MACpB,gBAAAnoB,EAAC,OAAA,EAAI,WAAU,4BACZ,UAAAue,EAAO,IAAI,CAACE,OAAM;AACjB,0BAAM7I,KAAM,aAAapH,EAAE,GAAG,IAAIiQ,GAAE,GAAG;AACvC,2BACE,gBAAA3Y,EAAC,OAAA,EAAc,WAAU,+BACtB,UAAA;AAAA,sBAAA+K,GAAO4N,GAAE,KAAK,EAAE,MAAM,OAAO,KAAA7I,GAAA,GAAO,qBAAqB,GAAG;AAAA,sBAC5D,CAAC2N,KACA,gBAAAvjB;AAAA,wBAAC;AAAA,wBAAA;AAAA,0BACC,MAAK;AAAA,0BACL,WAAU;AAAA,0BACV,eAAY;AAAA,0BACZ,OAAO,UAAU4V,EAAG;AAAA,0BACpB,cAAY,UAAUA,EAAG;AAAA,0BACzB,SAAS,MAAMyP,GAAW,EAAE,MAAM,UAAU,KAAAzP,IAAK;AAAA,0BAClD,UAAA;AAAA,wBAAA;AAAA,sBAAA;AAAA,oBAED,EAAA,GAZMA,EAcV;AAAA,kBAEJ,CAAC,EAAA,CACH;AAAA,gBAAA,EAAA,GA7CWpH,EAAE,GA+CjB;AAAA,cAEJ,CAAC;AAAA,YAAA,GACH;AAAA,YAED,CAAC+U,KACA,gBAAAzd;AAAA,cAACkiB;AAAA,cAAA;AAAA,gBACC,OAAM;AAAA,gBACL,GAAGnB,GAAa,SAAS;AAAA,gBAC1B,QACE7V,EAAQ,gBACN,gBAAAhR;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,WAAU;AAAA,oBACV,eAAY;AAAA,oBACZ,SAAS,MAAM6kB,GAAU,QAAQ;AAAA,oBAClC,UAAA;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAMJ,UAAA;AAAA,kBAAAc,GAAQ,WAAW,KAAK,gBAAA3lB,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,cAAU;AAAA,kBACxE2lB,GAAQ;AAAA,oBAAI,CAACzlB,MACZ2Q,GAAO3Q,GAAG,EAAE,MAAM,UAAU,KAAKA,KAAK,wBAAwB,IAAI;AAAA,kBAAA;AAAA,gBACpE;AAAA,cAAA;AAAA,YAAA;AAAA,UACF,GAEJ;AAAA,UAGCqjB,KACC,gBAAAzd,EAAC,OAAA,EAAI,WAAU,sBACb,UAAA;AAAA,YAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,cAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,4BAA2B,UAAA;AAAA,gBAAA;AAAA,gBAEzC,gBAAAA,EAAC,QAAA,EAAK,WAAU,uBACb,UAAA;AAAA,kBAAA;AAAA,kBAAI;AAAA,gBAAA,EAAA,CAEP;AAAA,cAAA,GACF;AAAA,cACA,gBAAA9F;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,SAAS,MAAM;AACb,oBAAA8jB,EAAY,UAAU;AAAA,kBACxB;AAAA,kBAEA,UAAA,gBAAA9jB;AAAA,oBAACgS;AAAA,oBAAA;AAAA,sBACC,OAAO2R;AAAA,sBACP,UAAUC;AAAA,sBACV,QAAO;AAAA,sBACP,WAAU;AAAA,sBACV,cAAW;AAAA,sBACX,aACEJ,IACI,8DACA;AAAA,sBAEN,gBAAgB,CAACzR,MAAS;AACxB,wBAAA8R,EAAS,UAAU9R;AAAA,sBACrB;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBACF;AAAA,cAAA;AAAA,YACF,GACF;AAAA,YACA,gBAAAjM,EAAC,OAAA,EAAI,WAAU,mDACb,UAAA;AAAA,cAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,4BAA2B,UAAA;AAAA,gBAAA;AAAA,gBAEzC,gBAAAA,EAAC,QAAA,EAAK,WAAU,uBACb,UAAA;AAAA,kBAAA;AAAA,kBACA0d,IACG,iEACA;AAAA,gBAAA,EAAA,CACN;AAAA,cAAA,GACF;AAAA,cACCQ,uBACE,QAAA,EAAK,WAAU,uBAAsB,MAAK,SAAQ,eAAY,qBAC5D,UAAAA,EAAA,CACH;AAAA,cAEF,gBAAAhkB,EAAC,SAAI,WAAU,wBAAuB,eAAY,oBAC/C,UAAA+jB,EAAW,KACR,KAAK;AAAA,gBACHpB;AAAA,kBAAgBoB,EAAW;AAAA,kBAAO,CAACuE,MACjC/N,GAAiB+N,GAAMpE,GAAa;AAAA,gBAAA;AAAA,gBAEtC;AAAA,gBACA;AAAA,cAAA,IAEFP,EAAS,KAAA,MAAW,KAClB,KACA,eAAA,CACR;AAAA,YAAA,EAAA,CACF;AAAA,UAAA,GACF;AAAA,UAID,CAACJ,KACA,gBAAAzd,EAAC,OAAA,EAAI,WAAU,sBACb,UAAA;AAAA,YAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,cAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,4BAA2B,UAAA;AAAA,gBAAA;AAAA,gBAEzC,gBAAA9F,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,yCAAA,CAAsC;AAAA,cAAA,GAC9E;AAAA,cACA,gBAAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,KAAKkO;AAAA,kBACL,WAAW,sBAAsB4U,IAAS,eAAe,EAAE,GACzD3N,EAAM,WAAW,IAAI,cAAc,EACrC;AAAA,kBACA,iBAAe;AAAA,kBACf,gCAA8B;AAAA,kBAC9B,MAAK;AAAA,kBACL,UAAU;AAAA,kBACV,kBAAgB4N,IAAY,SAAS;AAAA,kBACrC,cAAW;AAAA,kBACX,oBAAiB;AAAA,kBACjB,gBAAcwB,EAAS,UAAU;AAAA,kBACjC,oBAAkBA,EAAS,QAAQ,uBAAuB;AAAA,kBAC1D,YAAY;AAAA,kBACZ,SAAS,MAAM;AAQb,0BAAMnb,IAAK8E,EAAU;AACrB,oBAAI9E,KAAIoX,GAA8BpX,GAAI,EAAE,cAAc,IAAM,GAChEgc,EAAA;AAAA,kBACF;AAAA,kBACA,eAAe,CAAC/hB,MAAM;AAUpB,0BAAMga,IAASha,EAAE;AAEjB,wBADIga,EAAO,QAAQ,UAAU,KACzBA,EAAO,QAAQ,sBAAsB,EAAG;AAC5C,0BAAMwD,IAAOxD,EAAO,QAAQ,gBAAgB;AAC5C,wBAAI,CAACwD,EAAM;AACX,oBAAAxd,EAAE,eAAA;AACF,0BAAM+G,KAAO0W,GAAWD,CAAI;AAC5B,wBAAIzW,IAAM;AACR,4BAAMtB,KAAMsB,GAAK,eACX0S,KAAQhU,GAAI,YAAA;AAClB,sBAAAgU,GAAM,cAAc1S,EAAI,GACxB0S,GAAM,SAAS,EAAI;AACnB,4BAAMzR,KAAMvC,GAAI,aAAA;AAChB,sBAAAuC,MAAA,QAAAA,GAAK,mBACLA,MAAA,QAAAA,GAAK,SAASyR;AAAA,oBAChB;AACA,oBAAAsI,EAAA;AAAA,kBACF;AAAA,kBACA,QAAQ,MAAM;AAMZ,0BAAMhc,IAAK8E,EAAU;AACrB,oBAAK9E,KACLmc,EAAUjQ,GAAkBkK,GAAUpW,CAAE,CAAC,GAAG,EAAE,cAAc,IAAO;AAAA,kBACrE;AAAA,kBACA,SAAS,CAAC/F,MAAM;;AAOd,oBAAAA,EAAE,eAAA;AACF,0BAAM+F,IAAK8E,EAAU;AACrB,wBAAI,CAAC9E,EAAI;AACT,0BAAMlB,MAAO1O,KAAA6J,EAAE,kBAAF,gBAAA7J,GAAiB,QAAQ,kBAAiB;AACvD,+BAAWmf,MAAQ7C,GAA0B5N,CAAI;AAC/C,sBAAIyQ,GAAK,SAAS,SAChB4H,GAAkBnX,GAAIA,EAAG,cAAc,eAAeuP,GAAK,SAAS,EAAE,CAAC,IAEvE4H;AAAA,wBACEnX;AAAA,wBACA0V,GAAS1V,EAAG,eAAeuP,IAAM,EAAE,cAAc,IAAM;AAAA,sBAAA;AAI7D,oBAAAyM,EAAA;AAAA,kBACF;AAAA,kBACA,SAAS,CAAC/hB,MAAM;;AACd,0BAAMga,IAASha,EAAE,QACXgc,IAAIhC,EAAO,QAAQ,UAAU;AACnC,wBAAIgC,GAAG;AACL,sBAAAhc,EAAE,eAAA,IACF7J,KAAA6lB,EAAE,QAAQ,gBAAgB,MAA1B,QAAA7lB,GAA6B,UAC7B4rB,EAAA;AACA;AAAA,oBACF;AAMA,0BAAMjG,KAAS9B,EAAO,QAAQ,sBAAsB;AACpD,wBAAI8B,IAAQ;AACV,sBAAA9b,EAAE,eAAA;AACF,4BAAMwd,KAAO1B,GAAO,QAAQ,gBAAgB;AAC5C,0BAAI0B,IAAM;AACR,8BAAMjL,KAAMiL,GAAK,aAAa,UAAU,KAAK,IACvC0H,KACJ1H,GAAK,aAAa,WAAW,MAAM,WAAW,QAAQ;AACxD,wBAAAA,GAAK;AAAA,0BACH/B;AAAA,4BACE+B,GAAK;AAAA,4BACL,EAAE,MAAM0H,IAAU,KAAA3S,GAAA;AAAA,4BAClB,EAAE,cAAc,GAAA;AAAA,0BAAK;AAAA,wBACvB;AAAA,sBAEJ;AACA,sBAAAwP,EAAA;AAAA,oBACF;AAAA,kBACF;AAAA,kBACA,WAAW,CAAC/hB,MAAM;AAMhB,wBALIA,EAAE,QAAQ,YAIdA,EAAE,eAAA,GACE,CAAC0f,GAAW;AAChB,0BAAM3Z,IAAK8E,EAAU;AACrB,oBAAK9E,MAMLmX,GAAkBnX,GAAIA,EAAG,cAAc,eAAe;AAAA,CAAI,CAAC,GAC3D8W,GAAkB9W,CAAE,GACpBgc,EAAA;AAAA,kBACF;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEF,gBAAAtf,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA;AAAA,gBAAA;AAAA,gBACZ,gBAAA9F,EAAC,UAAK,UAAA,aAAA,CAAU;AAAA,gBAAO;AAAA,gBAA0B;AAAA,gBACzE,gBAAAA,EAAC,UAAK,UAAA,KAAA,CAAU;AAAA,gBAAO;AAAA,gBAAI,gBAAAA,EAAC,UAAK,UAAA,KAAA,CAAE;AAAA,gBAAO;AAAA,cAAA,GAC5C;AAAA,cACCukB,EAAS,SACR,gBAAAvkB,EAAC,QAAA,EAAK,IAAG,sBAAqB,MAAK,SAAQ,WAAU,aAClD,UAAAukB,EAAS,MAAA,CACZ;AAAA,YAAA,GAEJ;AAAA,YACC2C,GAAS,SAAS,KACjB,gBAAAphB,EAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,cAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,4BAA2B,UAAA;AAAA,gBAAA;AAAA,gBAEzC,gBAAAA,EAAC,QAAA,EAAK,WAAU,uBACb,UAAA;AAAA,kBAAA;AAAA,kBAAI;AAAA,gBAAA,EAAA,CAEP;AAAA,cAAA,GACF;AAAA,cACCohB,GAAS,IAAI,CAACtR,MACb,gBAAA9P,EAAC,SAAA,EAAgB,WAAU,aACzB,UAAA;AAAA,gBAAA,gBAAA9F,EAAC,UAAM,UAAA4V,EAAA,CAAI;AAAA,gBACX,gBAAA5V;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,OAAO2W,EAAQf,CAAG,KAAKqR,GAAiBrR,CAAG,KAAK;AAAA,oBAChD,aAAY;AAAA,oBACZ,UAAU,CAACvS,MAAMshB,EAAW,CAACzkB,OAAO,EAAE,GAAGA,GAAG,CAAC0V,CAAG,GAAGvS,EAAE,OAAO,QAAQ;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACtE,EAAA,GAPUuS,CAQZ,CACD;AAAA,YAAA,GACH;AAAA,YAEF,gBAAA9P,EAAC,OAAA,EAAI,WAAU,mDACb,UAAA;AAAA,cAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,4BAA2B,UAAA;AAAA,gBAAA;AAAA,gBAEzC,gBAAAA,EAAC,QAAA,EAAK,WAAU,uBACb,UAAA;AAAA,kBAAA;AAAA,kBAAI;AAAA,gBAAA,EAAA,CAEP;AAAA,cAAA,GACF;AAAA,cACA,gBAAA9F,EAACwoB,IAAA,EAAS,OAAOrB,IAAQ,UAAQ,IAC/B,UAAA,gBAAAnnB,EAAC,OAAA,EAAI,WAAU,wBAAwB,UAAAmnB,MAAU,IAAA,CAAI,GACvD;AAAA,cACCC,EAAY,SAAS,KACpB,gBAAApnB,EAAC,QAAA,EAAK,WAAU,uBAAsB,eAAY,sBAC/C,UAAAonB,EAAY,KAAK,KAAK,EAAA,CACzB;AAAA,YAAA,EAAA,CAEJ;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,GAEJ;AAAA,QAOCxC,OAAW,SAAS5T,EAAQ,aAC3B,gBAAAhR,EAACyoB,IAAA,EAAc,MAAK,OAAM,UAAUzX,EAAQ,WAAW,SAAS0U,EAAA,CAAa;AAAA,QAE9Ed,OAAW,YAAY5T,EAAQ,gBAC9B,gBAAAhR,EAACyoB,IAAA,EAAc,MAAK,UAAS,UAAUzX,EAAQ,cAAc,SAAS0U,EAAA,CAAa;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAI3F;AAyBA,SAASsC,GAAY;AAAA,EACnB,OAAAtY;AAAA,EACA,MAAAzF;AAAA,EACA,UAAAye;AAAA,EACA,QAAAntB;AAAA,EACA,QAAAotB;AAAA,EACA,UAAAroB;AACF,GAOG;AACD,QAAMsoB,IAAS7U,GAAA,GACT8U,IAAU/lB,GAAuB,IAAI;AAE3C,SAAAqiB,GAAgB,MAAM;AACpB,IAAI0D,EAAQ,YAASA,EAAQ,QAAQ,QAAQ,CAAC5e;AAAA,EAChD,GAAG,CAACA,CAAI,CAAC,GAEP,gBAAAnE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,sBAAsBmE,IAAO,aAAa,EAAE;AAAA,MACvD,eAAa0e;AAAA,MACb,qBAAmB1e,IAAO,SAAS;AAAA,MAEnC,UAAA;AAAA,QAAA,gBAAAnE,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,UAAA,gBAAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,eAAY;AAAA,cACZ,iBAAemE;AAAA,cACf,iBAAe2e;AAAA,cACf,SAASF;AAAA,cAET,UAAA;AAAA,gBAAA,gBAAA1oB,EAAC,QAAA,EAAK,WAAU,6BAA6B,UAAA0P,GAAM;AAAA,kCAClD,QAAA,EAAK,WAAU,6BAA4B,eAAY,QAAO,UAAA,IAAA,CAE/D;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAEDnU;AAAA,QAAA,GACH;AAAA,0BACC,OAAA,EAAI,IAAIqtB,GAAQ,KAAKC,GAAS,WAAU,4BAA2B,eAAa,CAAC5e,GAChF,UAAA,gBAAAjK,EAAC,OAAA,EAAI,WAAU,6BAA6B,UAAAM,GAAS,EAAA,CACvD;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,SAAS2nB,GAAa;AAAA,EACpB,OAAAhxB;AAAA,EACA,MAAAgT;AAAA,EACA,UAAAye;AACF,GAA2D;AACzD,SACE,gBAAA5iB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,eAAY;AAAA,MACZ,iBAAemE;AAAA,MACf,OAAOA,IAAO,gBAAgB;AAAA,MAC9B,SAASye;AAAA,MAER,UAAA;AAAA,QAAAzxB;AAAA,QAAM;AAAA,QAAEA,MAAU,IAAI,UAAU;AAAA,QAAS;AAAA,QAAEgT,IAAO,MAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAG/D;AAGA,MAAMic,KAAkC;AAAA,EACtC,CAAC,OAAO,KAAK;AAAA,EACb,CAAC,WAAW,aAAa;AAAA,EACzB,CAAC,UAAU,QAAQ;AAAA,EACnB,CAAC,gBAAgB,eAAe;AAAA,EAChC,CAAC,kBAAkB,iBAAiB;AAAA,EACpC,CAAC,OAAO,aAAa;AACvB,GAEMC,yBAAoB,IAAI,CAAC,OAAO,WAAW,UAAU,cAAc,CAAC;AAkB1E,SAASsC,GAAc,EAAE,MAAA/Z,GAAM,UAAAoa,GAAU,SAAAzN,KAA+B;AACtE,QAAM,CAAC3b,GAAMqpB,CAAO,IAAI9pB,EAAS,EAAE,GAC7B,CAAC4E,GAAOmlB,CAAQ,IAAI/pB,EAAS,EAAE,GAC/B,CAACgqB,GAAaC,CAAc,IAAIjqB,EAAS,EAAE,GAC3C,CAAC+d,GAAOmM,CAAQ,IAAIlqB,EAAwB,IAAI,GAChD,CAACyR,GAAS0Y,CAAU,IAAInqB,EAAS,EAAK,GAEtCoqB,IAAO3a,MAAS,QAAQ,aAAa;AAE3C,iBAAe4a,IAAS;AACtB,IAAAH,EAAS,IAAI,GACbC,EAAW,EAAI;AACf,QAAI;AACF,YAAMN,EAAS,EAAE,MAAAppB,GAAM,OAAAmE,GAAO,aAAaolB,KAAe,QAAW,GACrE5N,EAAA;AAAA,IACF,SAAShY,GAAG;AACV,MAAA8lB,EAAU9lB,EAAY,OAAO;AAAA,IAC/B,UAAA;AACE,MAAA+lB,EAAW,EAAK;AAAA,IAClB;AAAA,EACF;AAEA,2BACGhO,IAAA,EAAM,OAAO,OAAOiO,CAAI,IAAI,SAAAhO,GAG3B,UAAA;AAAA,IAAA,gBAAArb,EAAC,SAAI,WAAU,kBACb,UAAA,gBAAA8F,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,OAAA,CAAI;AAAA,QACV,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAON;AAAA,YACP,UAAU,CAAC2D,MAAM0lB,EAAQ1lB,EAAE,OAAO,KAAK;AAAA,YACvC,aAAaqL,MAAS,QAAQ,sBAAsB;AAAA,YACpD,cAAa;AAAA,YACb,eAAY;AAAA,YAEZ,WAAS;AAAA,UAAA;AAAA,QAAA;AAAA,QAEX,gBAAA1O,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,4FAAA,CAGtC;AAAA,MAAA,GACF;AAAA,MAEA,gBAAA8F,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,QAAA,CAAK;AAAA,QACX,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAM0O,MAAS,WAAW,aAAa;AAAA,YACvC,OAAA7K;AAAA,YACA,UAAU,CAACR,MAAM2lB,EAAS3lB,EAAE,OAAO,KAAK;AAAA,YACxC,cAAa;AAAA,YACb,eAAY;AAAA,UAAA;AAAA,QAAA;AAAA,QAEbqL,MAAS,YACR,gBAAA1O,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,2EAAA,CAEtC;AAAA,MAAA,GAEJ;AAAA,MAEA,gBAAA8F,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,cAAA,CAAW;AAAA,QACjB,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAOipB;AAAA,YACP,UAAU,CAAC5lB,MAAM6lB,EAAe7lB,EAAE,OAAO,KAAK;AAAA,YAC9C,aAAY;AAAA,YACZ,cAAa;AAAA,UAAA;AAAA,QAAA;AAAA,MACf,GACF;AAAA,MAEC2Z,KAAS,gBAAAhd,EAAC,OAAA,EAAI,WAAU,wBAAwB,UAAAgd,EAAA,CAAM;AAAA,IAAA,EAAA,CACzD,EAAA,CACF;AAAA,IACA,gBAAAlX,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,MAAA,gBAAA9F;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,eAAY;AAAA,UACZ,SAASqb;AAAA,UACV,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAGD,gBAAArb;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,eAAY;AAAA,UACZ,UAAU,CAACN,KAAQ,CAACmE,KAAS6M;AAAA,UAC7B,SAAS4Y;AAAA,UAER,cAAU,YAAY;AAAA,QAAA;AAAA,MAAA;AAAA,IACzB,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AC7gDO,SAASC,GACdpR,GACAqR,GACwB;AACxB,SAAOA,IAASrR,EAAM,OAAO,CAACjY,MAAMA,EAAE,OAAOspB,CAAM,IAAIrR;AACzD;AAmOA,MAAMsR,KAAuBjrB,GAAiC,EAAE;AAqBzD,SAASkrB,GAA0B,EAAE,OAAA7lB,GAAO,UAAAvD,KAA4C;AAC7F,QAAMqpB,IAAY7qB,GAAW2qB,EAAoB,GAI3CjgB,IAASiI,GAAQ,OAAO,EAAE,GAAGkY,GAAW,GAAG9lB,EAAA,IAAU,CAAC8lB,GAAW9lB,CAAK,CAAC;AAC7E,2BAAQ4lB,GAAqB,UAArB,EAA8B,OAAOjgB,GAAS,UAAAlJ,GAAS;AACjE;AAQO,SAASspB,KAA0C;AACxD,SAAO9qB,GAAW2qB,EAAoB;AACxC;ACpRO,SAASI,GAAgB;AAAA,EAC9B,OAAAhmB;AAAA,EACA,UAAAgI;AAAA,EACA,aAAAyH;AAAA,EACA,QAAAwP;AAAA,EACA,WAAAC;AAAA,EACA,UAAApX;AAAA,EACA,SAAAqF;AAAA,EACA,cAAcwC;AAChB,GAAyB;AAGvB,QAAM,CAAC5V,GAAOksB,CAAQ,IAAI7qB,EAAS,MAAMwX,GAAa5S,CAAK,CAAC,GACtD,EAAE,OAAAsR,GAAO,QAAA4U,EAAA,IAAWnsB,GACpB,CAAC4mB,GAAUC,CAAW,IAAIxlB,EAAS,CAAC,GACpC,CAAC+qB,GAASC,CAAU,IAAIhrB,EAAS,EAAK,GACtC,CAACirB,GAAWC,CAAY,IAAIlrB,EAAS,EAAK,GAC1CmrB,IAAYtnB,GAAO,EAAK,GACxBoL,IAAYpL,GAAuB,IAAI,GACvCunB,IAAavnB,GAAuB,IAAI,GAExCwnB,IAAaV,GAAA,GAGbtrB,IAAW,EAAE,GAAGgsB,GAAY,GAAItZ,KAAW,CAAA,EAAC,GAC5CuZ,IAAaD,EAAW;AAK9B,EAAAnF,GAAgB,MAAM;AACpB,UAAM/b,IAAK8E,EAAU;AACrB,IAAI,CAAC9E,KAAM2gB,MACX3J,GAAWhX,GAAI+L,CAAK,IAChBiV,EAAU,WAAWhhB,EAAG,cAAc,kBAAkBA,OAC1DA,EAAG,MAAA,GACHkX,GAAgBlX,CAAE,GAClBghB,EAAU,UAAU;AAAA,EAExB,GAAG,CAAC5F,GAAUuF,CAAM,CAAC;AAErB,QAAMS,IAAc,MAAM;AACxB,UAAMphB,IAAK8E,EAAU;AACrB,QAAI,CAAC9E,EAAI;AACT,UAAMzE,IAAO6a,GAAUpW,CAAE;AACzB,IAAA0gB,EAAS,CAAC5pB,OAAO,EAAE,GAAGA,GAAG,OAAOyE,IAAO;AACvC,UAAM4f,IAAWpI,GAAqBxX,GAAMrG,CAAQ;AACpD,IAAAuN,EAASqJ,GAAaqP,EAAS,KAAK,CAAC;AAAA,EACvC,GAIMkG,IAAY,OAAO1vB,MAAc;AACrC,QAAI,CAACwvB,EAAY,QAAO;AACxB,IAAAN,EAAW,EAAI;AACf,QAAI;AACF,YAAMS,IAAM,MAAMH,EAAWxvB,CAAC;AAC9B,aAAAqvB,EAAU,UAAU,IACpBN,EAAS,EAAE,OAAO,CAAA,GAAI,QAAQY,GAAK,GACnCjG,EAAY,CAACnX,MAAMA,IAAI,CAAC,GACxBzB,EAAS6e,CAAG,GACL;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT,UAAA;AACE,MAAAT,EAAW,EAAK;AAAA,IAClB;AAAA,EACF,GAWMU,IAAU,CAACtnB,MAAwB;;AACvC,QAAI6mB,KAAa,CAACpH,KAAUnX,KAAYqe,EAAS;AACjD,UAAMrlB,IAAOtB,EAAE;AACf,QAAIsB,OAAQnL,IAAA6wB,EAAW,YAAX,QAAA7wB,EAAoB,SAASmL,IAAO;AAChD,UAAM5J,IAAIma,GAAaC,CAAK;AAE5B,IAAI,OAAOpa,KAAM,YAAYA,MAAM,MAAM,CAACub,GAAgBvb,CAAC,KAAQ0vB,EAAU1vB,CAAC;AAAA,EAChF,GAIM6vB,IAAQ,CAACjmB,MAA6B;AAC1C,QAAIme,KAAU,OAAOne,KAAS,YAAYA,EAAK,KAAA,MAAW,MAAM,CAAC2R,GAAgB3R,CAAI,GAAG;AACtF,MAAK8lB,EAAU9lB,CAAI;AACnB;AAAA,IACF;AACA,IAAAylB,EAAU,UAAU,IACpBN,EAASrT,GAAa9R,CAAI,CAAC,GAC3B8f,EAAY,CAACnX,MAAMA,IAAI,CAAC,GACxBzB,EAASlH,CAAI;AAAA,EACf;AAGA,SAAIolB,IAEA,gBAAAjkB,EAAC,SAAI,WAAW,kBAAkB6F,IAAW,iBAAiB,EAAE,IAAI,cAAY6H,GAC9E,UAAA;AAAA,IAAA,gBAAA1N,EAAC,QAAA,EAAK,WAAU,sCAAqC,OAAM,oBACzD,UAAA;AAAA,MAAA,gBAAA9F,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,MAAE;AAAA,MACxC,gBAAAA,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,SAAA,CAAM;AAAA,IAAA,GAC9C;AAAA,IACC,CAAC2L,KACA,gBAAA3L;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM;AACb,UAAAoqB,EAAU,UAAU,IACpBN,EAAS,EAAE,OAAO,CAAA,GAAI,QAAQ,MAAM,GACpCrF,EAAY,CAACnX,MAAMA,IAAI,CAAC,GACxBzB,EAAS,EAAE;AAAA,QACb;AAAA,QACD,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAED,GAEJ,sBAKD,OAAA,EAAI,WAAU,YAAW,KAAKwe,GAAY,QAAQM,GACjD,UAAA;AAAA,IAAA,gBAAA7kB,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,MAAA,gBAAA9F;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAKkO;AAAA,UACL,WAAW,kBAAkB4U,IAAS,eAAe,EAAE,GACrD3N,EAAM,WAAW,IAAI,cAAc,EACrC,GAAGxJ,IAAW,iBAAiB,EAAE;AAAA,UACjC,iBAAiB,CAACA;AAAA,UAClB,gCAA8B;AAAA,UAC9B,MAAK;AAAA,UACL,UAAUA,IAAW,KAAK;AAAA,UAC1B,kBAAgBoX,IAAY,SAAS;AAAA,UACrC,cAAYvP;AAAA,UACZ,oBAAkBF,KAAe;AAAA,UACjC,YAAY;AAAA,UACZ,SAAS,MAAM;AAQb,kBAAMlK,IAAK8E,EAAU;AACrB,YAAI9E,QAAkCA,CAAE,GACxCohB,EAAA;AAAA,UACF;AAAA,UACA,SAAS,CAACnnB,MAAM;;AACd,kBAAMgc,IAAKhc,EAAE,OAAuB,QAAQ,UAAU;AACtD,YAAKgc,MACLhc,EAAE,eAAA,IACF7J,IAAA6lB,EAAE,QAAQ,gBAAgB,MAA1B,QAAA7lB,EAA6B,UAC7BgxB,EAAA;AAAA,UACF;AAAA,UACA,eAAe,CAACnnB,MAAM;AAKpB,kBAAMga,IAASha,EAAE;AACjB,gBAAIga,EAAO,QAAQ,UAAU,EAAG;AAChC,kBAAMwD,IAAOxD,EAAO,QAAQ,gBAAgB;AAC5C,gBAAI,CAACwD,EAAM;AACX,YAAAxd,EAAE,eAAA;AACF,kBAAM+G,IAAO0W,GAAWD,CAAI;AAC5B,gBAAIzW,GAAM;AACR,oBAAMtB,IAAMsB,EAAK,eACX0S,IAAQhU,EAAI,YAAA;AAClB,cAAAgU,EAAM,cAAc1S,CAAI,GACxB0S,EAAM,SAAS,EAAI;AACnB,oBAAMzR,IAAMvC,EAAI,aAAA;AAChB,cAAAuC,KAAA,QAAAA,EAAK,mBACLA,KAAA,QAAAA,EAAK,SAASyR;AAAA,YAChB;AACA,YAAA0N,EAAA;AAAA,UACF;AAAA,UACA,WAAW,CAACnnB,MAAM;AAMhB,gBALIA,EAAE,QAAQ,YAIdA,EAAE,eAAA,GACE,CAAC0f,GAAW;AAChB,kBAAM3Z,IAAK8E,EAAU;AACrB,YAAK9E,MAMLmX,GAAkBnX,GAAIA,EAAG,cAAc,eAAe;AAAA,CAAI,CAAC,GAC3D8W,GAAkB9W,CAAE,GACpBohB,EAAA;AAAA,UACF;AAAA,QAAA;AAAA,MAAA;AAAA,MAED,CAAC7e,KACA,gBAAA3L;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAM;AAAA,UACN,cAAW;AAAA,UACX,SAAS,MAAMmqB,EAAa,EAAI;AAAA,UACjC,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,GAEJ;AAAA,IAECD,KACC,gBAAAlqB;AAAA,MAAC6iB;AAAA,MAAA;AAAA,QACC,OAAO3N,GAAaC,CAAK;AAAA,QACzB,QAAA2N;AAAA,QACA,WAAAC;AAAA,QACA,SAASzkB;AAAA,QACT,YAAYkV;AAAA,QACZ,QAAQoX;AAAA,QACR,SAAS,MAAMT,EAAa,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EACnC,GAEJ;AAEJ;ACxPA,MAAMU,KAAS;AAQR,SAASC,GACdpmB,GACA0M,IAA2B,cACZ;AACf,QAAME,IAASF,MAAa,UAEtB2Z,IAA4D,CAAA,GAC5DC,IAA6C,CAAA;AACnD,MAAI,IAAI;AACR,SAAO,IAAItmB,EAAK,UAAQ;AACtB,UAAMwB,IAAIxB,EAAK,CAAC,GACVumB,IAAMvmB,EAAK,MAAM,GAAG,IAAI,CAAC,GACzBwmB,IAAQxmB,EAAK,MAAM,GAAG,IAAI,CAAC;AACjC,QAAK4M,KAAUpL,MAAM,OAAS,CAACoL,KAAU2Z,MAAQ,MAAO;AACtD,YAAME,IAAKzmB,EAAK,QAAQ;AAAA,GAAM,CAAC,GACzB0mB,IAAMD,MAAO,KAAKzmB,EAAK,SAASymB;AACtC,MAAAH,EAAS,KAAK,EAAE,OAAO,GAAG,KAAAI,GAAK,GAC/B,IAAIA;AAAA,IACN,WAAW,CAAC9Z,KAAU2Z,MAAQ,MAAM;AAClC,YAAMtW,IAAQjQ,EAAK,QAAQ,MAAM,IAAI,CAAC,GAChC0mB,IAAMzW,MAAU,KAAKjQ,EAAK,SAASiQ,IAAQ;AACjD,MAAAqW,EAAS,KAAK,EAAE,OAAO,GAAG,KAAAI,GAAK,GAC/B,IAAIA;AAAA,IACN,WAAW9Z,MAAW4Z,MAAU,SAASA,MAAU,QAAQ;AACzD,YAAMvW,IAAQjQ,EAAK,QAAQwmB,GAAO,IAAI,CAAC,GACjCE,IAAMzW,MAAU,KAAKjQ,EAAK,SAASiQ,IAAQ;AACjD,MAAAoW,EAAS,KAAK,EAAE,OAAO,GAAG,KAAAK,GAAK,OAAOF,GAAO,GAC7C,IAAIE;AAAA,IACN,WAAWllB,MAAM,OAAOA,MAAM,OAAQ,CAACoL,KAAUpL,MAAM,KAAM;AAC3D,UAAImlB,IAAI,IAAI;AACZ,aAAOA,IAAI3mB,EAAK,UAAUA,EAAK2mB,CAAC,MAAMnlB,KAAG;AACvC,YAAIxB,EAAK2mB,CAAC,MAAM,KAAM,CAAAA;AAAA,iBACbnlB,MAAM,OAAOxB,EAAK2mB,CAAC,MAAM;AAAA,EAAM;AACxC,QAAAA;AAAA,MACF;AACA,YAAMD,IAAM,KAAK,IAAIC,IAAI,GAAG3mB,EAAK,MAAM;AACvC,MAAAqmB,EAAS,KAAK,EAAE,OAAO,GAAG,KAAAK,GAAK,OAAOllB,GAAG,GACzC,IAAIklB;AAAA,IACN;AACE;AAAA,EAEJ;AACA,QAAMjwB,IAAqB,CAAA;AAC3B,aAAWgN,KAAKzD,EAAK,SAASmmB,EAAM,GAAG;AACrC,UAAMnO,IAAQvU,EAAE,SAAS,GACnBijB,IAAM1O,IAAQvU,EAAE,CAAC,EAAE;AACzB,QAAI6iB,EAAS,KAAK,CAAC9kB,MAAMwW,KAASxW,EAAE,SAASwW,IAAQxW,EAAE,GAAG,EAAG;AAC7D,UAAMolB,IAAMP,EAAS,KAAK,CAAC3vB,MAAMshB,IAAQthB,EAAE,SAASshB,IAAQthB,EAAE,GAAG;AACjE,IAAAD,EAAI,KAAK;AAAA,MACP,OAAAuhB;AAAA,MACA,KAAA0O;AAAA,MACA,KAAKjjB,EAAE,CAAC;AAAA,MACR,SAASmjB,IAAM,EAAE,MAAM,UAAU,GAAGA,EAAA,IAAQ,EAAE,MAAM,OAAA;AAAA,IAAO,CAC5D;AAAA,EACH;AACA,SAAOnwB;AACT;AAGA,MAAMowB,KAAM,kFACNC,KAAO,oEAGP9P,KAAkC;AAAA,EACtC,OAAO,CAAC,OAAO,OAAO;AAAA,EACtB,OAAO,CAAC,OAAO,OAAO;AAAA,EACtB,SAAS,CAAC,OAAO,SAAS;AAAA,EAC1B,SAAS,CAAC,OAAO,SAAS;AAAA,EAC1B,OAAO,CAAC,OAAO;AAAA,EACf,KAAK,CAAC,OAAO;AAAA,EACb,MAAM,CAAC,OAAO;AAAA,EACd,OAAO,CAAC,QAAQ;AAAA,EAChB,QAAQ,CAAC,QAAQ;AACnB;AAOO,SAAS+P,GAAY7V,GAAaxE,IAA2B,cAA6B;;AAC/F,QAAMlJ,IAAO0N,EAAI,KAAA;AACjB,MAAI,CAAC2V,GAAI,KAAKrjB,CAAI,EAAG,QAAO;AAC5B,QAAMW,MAAOrP,IAAA,oBAAoB,KAAK0O,CAAI,MAA7B,gBAAA1O,EAAiC,OAAM,IAC9CqM,IAAO6V,GAAM7S,CAAI;AACvB,MAAI,CAAChD,EAAM,QAAO;AAClB,QAAM6S,IAA4B,CAAC,GAAG7S,EAAK,MAAM,CAAC,CAAC;AACnD,aAAWsC,KAAKD,EAAK,MAAMW,EAAK,MAAM,EAAE,SAAS2iB,EAAI;AACnD,IAAA9S,EAAK,KAAKvQ,EAAE,CAAC,MAAM,SAAY,OAAOA,EAAE,CAAC,CAAC,IAAKA,EAAE,CAAC,KAAKA,EAAE,CAAC,KAAKA,EAAE,CAAC,CAAE;AAEtE,QAAMujB,IAAY7lB,EAAK,CAAC,MAAM,QAAQ6S,EAAK,MAAA,IAAU7S,EAAK,CAAC;AAE3D,SAAO,GADSuL,MAAa,WAAW,QAAQ,GAC/B,QAAQ,CAACsa,GAAW,GAAGhT,CAAI,EAAE,IAAI,CAACnB,MAAQ,KAAK,UAAUA,CAAG,CAAC,EAAE,KAAK,IAAI,CAAC;AAC5F;AAoBO,SAASoU,GACdjnB,GACA0M,IAA2B,cACZ;AACf,QAAME,IAASF,MAAa;AAC5B,MAAIjW,IAAM,IACNiJ,IAAS,GACTwnB,IAAY,GACZC,IAAO;AACX,aAAW10B,KAAK2zB,GAAiBpmB,GAAM0M,CAAQ,GAAG;AAChD,UAAM0a,IAAOL,GAAYt0B,EAAE,KAAKia,CAAQ;AACxC,QAAI0a,MAAS,MAAM;AACjB,MAAAD;AACA;AAAA,IACF;AACA,UAAME,IAAM50B,EAAE;AACd,QAAI40B,EAAI,SAAS,QAAQ;AACvB,MAAA5wB,KAAOuJ,EAAK,MAAMN,GAAQjN,EAAE,KAAK,IAAI20B,GACrC1nB,IAASjN,EAAE,KACXy0B;AACA;AAAA,IACF;AACA,UAAM7kB,IAAIglB,EAAI,OACRC,IAAU70B,EAAE,UAAU40B,EAAI,QAAQhlB,EAAE,QACpCklB,IAAQ90B,EAAE,QAAQ40B,EAAI,MAAMhlB,EAAE;AACpC,QAAIilB,KAAWC;AACb,MAAA9wB,KAAOuJ,EAAK,MAAMN,GAAQ2nB,EAAI,KAAK,IAAID,GACvC1nB,IAAS2nB,EAAI,KACbH;AAAA,aACS,CAACta,KAAUvK,MAAM;AAC1B,MAAA5L,KAAO,GAAGuJ,EAAK,MAAMN,GAAQjN,EAAE,KAAK,CAAC,MAAM20B,CAAI,KAC/C1nB,IAASjN,EAAE,KACXy0B;AAAA,aACS7kB,EAAE,WAAW,KAAK,EAAEuK,KAAU,WAAW,KAAK5M,EAAKqnB,EAAI,QAAQ,CAAC,KAAK,EAAE,IAAI;AACpF,YAAMG,IAAQ5a,IAAS,OAAOwa,CAAI,MAAMA;AACxC,MAAA3wB,KAAO6wB,IACH,GAAGtnB,EAAK,MAAMN,GAAQ2nB,EAAI,KAAK,CAAC,GAAGG,CAAK,MAAMnlB,CAAC,KAC/C,GAAGrC,EAAK,MAAMN,GAAQjN,EAAE,KAAK,CAAC,GAAG4P,CAAC,MAAMmlB,CAAK,IAC7CD,IACF7nB,IAAS2nB,EAAI,OAERC,MAAS7wB,KAAO,MAAM4L,CAAC,KAC5B3C,IAASjN,EAAE,MAEby0B;AAAA,IACF;AACE,MAAAC;AAAA,EAEJ;AACA,SAAA1wB,KAAOuJ,EAAK,MAAMN,CAAM,GACjB,EAAE,MAAMjJ,GAAK,WAAAywB,GAAW,MAAAC,EAAA;AACjC;AC9LO,SAASM,GAAgB;AAAA,EAC9B,OAAAC;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAAuN;AAAA,EACA,OAAA1B;AAAA,EACA,KAAA2c;AAAA,EACA,UAAA1gB;AAAA,EACA,UAAAE;AACF,GAQG;;AACD,QAAMkG,IAAOjP,GAA0B,IAAI,GACrC,CAACwpB,GAAYC,CAAa,IAAIttB,EAAS,EAAK,GAC5CutB,IAAc5C,GAAA,GACdzR,IAAQqU,EAAY,SAAS,CAAA,GAC7Blb,IAASF,MAAa,UAEtByQ,IAAS,CAAC3Z,MAAiB;AAC/B,UAAMnN,IAAIgX,EAAK;AACf,QAAI,CAAChX,GAAG;AACN,MAAA8Q,EAAShI,IAAQqE,CAAI;AACrB;AAAA,IACF;AACA,IAAAnN,EAAE,SAASA,EAAE,MAAM,iBAAiBmN,CAAI,CAAC,GACzCnN,EAAE,MAAA;AAAA,EACJ,GAGM0xB,IAAe,CAACC,MAAoB;AACxC,UAAM9W,IAAM6M,GAAciK,CAAM;AAChC,QAAI9W,MAAQ,MAAM;AAChB,YAAMkW,IAAOL,GAAY7V,GAAKxE,CAAQ;AACtC,MAAI0a,OAAaA,CAAI;AACrB;AAAA,IACF;AACA,IAAIY,MAAW,UAAaA,MAAW,MACvC7K;AAAA,MACE,KAAK,UAAU6K,GAAQ,MAAM,CAAC,EAAE;AAAA,QAC9B;AAAA,QACA,CAACvkB,GAAG1O,MAAcgyB,GAAYhyB,GAAG2X,CAAQ,KAAKjJ;AAAA,MAAA;AAAA,IAChD;AAAA,EAEJ,GAEMwf,MAASnuB,IAAA2e,EAAM,CAAC,MAAP,gBAAA3e,EAAU,OAAM,aACzBsX,IAAUQ,IAAS,QAAQ,KAC3Bqb,IAAW;AAAA,IACf,CAAC,GAAG7b,CAAO,iBAAiB,KAAK,UAAU6W,CAAM,CAAC,eAAe,iBAAiB;AAAA,IAClF,CAAC,GAAG7W,CAAO,2BAA2B,wBAAwB;AAAA,IAC9D,CAAC,GAAGA,CAAO,8BAA8B,YAAY;AAAA,EAAA,GAEjD8b,IAAQ,KAAK,IAAI,GAAGD,EAAS,IAAI,CAAC,CAACzmB,CAAC,MAAMA,EAAE,MAAM,CAAC,GACnD2mB,IAAUvb,IAAS,MAAM;AAE/B,SACE,gBAAAxL,EAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,QAAA,EACE,UAAA;AAAA,MAAA4J;AAAA,MACA2c;AAAA,IAAA,GACH;AAAA,IACA,gBAAArsB;AAAA,MAACuR;AAAA,MAAA;AAAA,QACC,OAAA1N;AAAA,QACA,UAAA8H;AAAA,QACA,WAAU;AAAA,QACV,UAAAyF;AAAA,QACA,cAAY,GAAGgb,EAAM,GAAG;AAAA,QACxB,UAAAvgB;AAAA,QACA,gBAAgB,CAAC9Q,MAAM;AACrB,UAAAgX,EAAK,UAAUhX;AAAA,QACjB;AAAA,MAAA;AAAA,IAAA;AAAA,IAED,CAAC4Q,KACA,gBAAA7F,EAAC,OAAA,EAAI,WAAU,oCACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,UAAM;AAAA,MAC3CmY,EAAM,IAAI,CAACjY,MAAM;AAChB,cAAM4rB,IAAOL,GAAY,SAAS,KAAK,UAAUvrB,EAAE,EAAE,CAAC,YAAYkR,CAAQ,KAAK;AAC/E,eACE,gBAAApR;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,OAAO,UAAU8rB,CAAI;AAAA,YACrB,SAAS,MAAMjK,EAAOiK,CAAI;AAAA,YAE1B,UAAA,gBAAA9rB,EAAC,QAAA,EAAM,UAAAE,EAAE,GAAA,CAAG;AAAA,UAAA;AAAA,UANPA,EAAE;AAAA,QAAA;AAAA,MASb,CAAC;AAAA,MACD,gBAAAF;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAM;AAAA,UACN,cAAY,uBAAuB0P,CAAK;AAAA,UACxC,SAAS,MAAM6c,EAAc,EAAI;AAAA,UAClC,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,GACF;AAAA,IAEDH,EAAM,QAAQ,gBAAApsB,EAAC,UAAK,WAAU,YAAY,YAAM,MAAK;AAAA,IACtD,gBAAA8F,EAAC,WAAA,EAAQ,WAAU,mBACjB,UAAA;AAAA,MAAA,gBAAA9F,EAAC,WAAA,EAAQ,WAAU,uBAAsB,UAAA,oBAAgB;AAAA,MACzD,gBAAAA,EAAC,OAAA,EAAI,WAAU,4BACZ,UAAA2sB,EAAS,IAAI,CAAC,CAACjoB,GAAMooB,CAAI,MAAM,GAAGpoB,EAAK,OAAOkoB,CAAK,CAAC,KAAKC,CAAO,IAAIC,CAAI,EAAE,EAAE,KAAK;AAAA,CAAI,EAAA,CACxF;AAAA,MACA,gBAAAhnB,EAAC,QAAA,EAAK,WAAU,YACd,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,QAAA,CAAK;AAAA,QAAO;AAAA,QAAgB,gBAAAA,EAAC,UAAK,UAAA,MAAA,CAAG;AAAA,QAAO;AAAA,MAAA,GACpD;AAAA,MACA,gBAAAA,EAAC,QAAA,EAAK,WAAU,YACb,cACC,gBAAA8F,EAAAwB,IAAA,EAAE,UAAA;AAAA,QAAA;AAAA,QACI,gBAAAtH,EAAC,UAAK,UAAA,YAAA,CAAS;AAAA,QAAO;AAAA,QAAK,gBAAAA,EAAC,UAAK,UAAA,YAAA,CAAS;AAAA,QAAO;AAAA,QAAc;AAAA,QACnE,gBAAAA,EAAC,UAAK,UAAA,uBAAA,CAAoB;AAAA,QAAO;AAAA,QAAwC;AAAA,QACzE,gBAAAA,EAAC,UAAK,UAAA,OAAA,CAAI;AAAA,QAAO;AAAA,MAAA,EAAA,CACnB,IAEA,gBAAA8F,EAAAwB,IAAA,EAAE,UAAA;AAAA,QAAA;AAAA,QACI,gBAAAtH,EAAC,UAAK,UAAA,UAAA,CAAO;AAAA,QAAO;AAAA,QAAK,gBAAAA,EAAC,UAAK,UAAA,UAAA,CAAO;AAAA,QAAO;AAAA,QAAc;AAAA,QAC/D,gBAAAA,EAAC,UAAK,UAAA,uBAAA,CAAoB;AAAA,QAAO;AAAA,QAA4B,gBAAAA,EAAC,UAAK,UAAA,MAAA,CAAG;AAAA,QAAO;AAAA,QAAE;AAAA,QAC/E,gBAAAA,EAAC,UAAK,UAAA,QAAA,CAAK;AAAA,QAAO;AAAA,QAAE,gBAAAA,EAAC,UAAK,UAAA,OAAA,CAAI;AAAA,QAAO;AAAA,QAAK,gBAAAA,EAAC,UAAK,UAAA,SAAA,CAAM;AAAA,QAAO;AAAA,MAAA,EAAA,CAE/D,EAAA,CAEJ;AAAA,IAAA,GACF;AAAA,IACCssB,KACC,gBAAAtsB;AAAA,MAAC6iB;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAO;AAAA,QACP,WAAW;AAAA,QACX,SAAS2J;AAAA,QACT,YAAY9c;AAAA,QACZ,OAAK;AAAA,QACL,YAAY+c;AAAA,QACZ,SAAS,MAAMF,EAAc,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EACpC,GAEJ;AAEJ;ACjHA,SAASQ,GAAKC,GAAoC;AAChD,QAAM7xB,IAAqB,CAAA;AAC3B,aAAW8B,KAAK+vB;AACd,IAAA7xB,EAAI,KAAK8B,CAAC,GACNA,EAAE,SAAS,aAAaA,EAAE,YAAU9B,EAAI,KAAK,GAAG4xB,GAAK9vB,EAAE,QAAQ,CAAC;AAEtE,SAAO9B;AACT;AAGO,SAAS8xB,GAAkBlyB,GAAqB;AACrD,SAAIub,GAAgBvb,CAAC,KAAKia,GAAcja,CAAC,IAAU,KAEjD,OAAOA,KAAM,YACbA,MAAM,QACN,CAAC,MAAM,QAAQA,CAAC,KAChB,OAAO,UAAU,eAAe,KAAKA,GAAG,GAAG;AAE/C;AAEA,SAASmyB,GAAcjwB,GAAyB;;AAC9C,WAAQzD,IAAAyD,EAA6C,WAA7C,gBAAAzD,EAAqD,iBAAgB;AAC/E;AAGO,SAAS2zB,GAAcC,GAAsC;AAClE,SAAOL,GAAKK,CAAM,EAAE,OAAO,CAACnwB,MAAM6X,GAAsB7X,EAAE,OAAO,CAAC;AACpE;AAEA,SAASowB,GAAYpwB,GAA0B;AAC7C,SAAO6X,GAAsB7X,EAAE,OAAO,IAAKA,EAAE,QAAQ,aAAa,CAAA,IAAM,CAAA;AAC1E;AAMO,SAASqwB,GAAUF,GAAuBG,GAA4C;AAC3F,QAAMC,IAAgC,CAAA,GAChCC,IAAuB,CAAA;AAC7B,aAAWxwB,KAAK8vB,GAAKK,CAAM,GAAG;AAC5B,QAAInwB,EAAE,SAAS,UAAW;AAC1B,UAAMlC,IAAIwyB,EAAOtwB,EAAE,GAAG,MAAM,SAAYswB,EAAOtwB,EAAE,GAAG,IAAIA,EAAE;AAC1D,IAAIlC,MAAM,WACNkyB,GAAkBlyB,CAAC,IAAG0yB,EAAW,KAAKxwB,EAAE,GAAG,IAC1CuwB,EAAKvwB,EAAE,GAAG,IAAIlC;AAAA,EACrB;AACA,SAAO,EAAE,MAAAyyB,GAAM,YAAAC,EAAA;AACjB;AAQO,SAASC,GACdN,GACAG,GACA/rB,GACAmsB,GACArQ,GACuB;AACvB,QAAM,EAAE,MAAAkQ,GAAM,YAAAC,EAAA,IAAeH,GAAUF,GAAQG,CAAM,GAC/CK,IAAM,IAAI,IAAIH,CAAU,GACxBlP,IAAS4O,GAAcC,CAAM,EAChC,OAAO,CAACnwB,MAAM;AACb,UAAM4wB,IAAKR,GAAYpwB,CAAC;AACxB,WAAIuE,MAAW,YAAY,EAAEmsB,KAAW,CAAA,GAAI,KAAK,CAACzU,MAAM2U,EAAG,SAAS3U,CAAC,CAAC,IAAU,KACzE2U,EAAG,MAAM,CAAC3U,MAAM,CAAC0U,EAAI,IAAI1U,CAAC,CAAC;AAAA,EACpC,CAAC,EACA,IAAI,CAACjc,MAAMA,EAAE,GAAG;AACnB,MAAIshB,EAAO,WAAW,EAAG,QAAO;AAChC,QAAM8N,IAAsB,EAAE,QAAA7qB,GAAQ,MAAAgsB,GAAM,QAAAjP,GAAQ,YAAAkP,EAAA;AACpD,SAAIjsB,MAAW,aACb6qB,EAAI,UAAU,CAAC,GAAIsB,KAAW,CAAA,CAAG,GACjCtB,EAAI,WAAWiB,GAAUF,GAAQ9P,KAAY,CAAA,CAAE,EAAE,OAE5C+O;AACT;AAGO,SAASyB,GACd/B,GACAK,GACAoB,GACQ;AACR,SAAO,KAAK,UAAU;AAAA,IACpBzB,EAAI;AAAA,IACJA,EAAI,WAAW;AAAA,IACfA,EAAI;AAAA,IACJA,EAAI,gBAAgB;AAAA,IACpBK,EAAM;AAAA,IACNiB,GAAYjB,CAAK,EAAE,IAAI,CAAClT,MAAMsU,EAAKtU,CAAC,KAAK,IAAI;AAAA,EAAA,CAC9C;AACH;AAGO,SAAS6U,GAAY3B,GAA6B;AACvD,SAAO,EAAEtX,GAAsBsX,EAAM,OAAO,KAAKA,EAAM,QAAQ,UAAU;AAC3E;AAGO,SAAS4B,GAAc92B,GAAsBC,GAA+B;AACjF,SAAOD,EAAE,KAAK,CAACgiB,MAAM/hB,EAAE,SAAS+hB,CAAC,CAAC;AACpC;AAMO,SAAS+U,GACd7B,GACAgB,GACAG,GACAxB,GAC4E;;AAC5E,MAAI,CAACA,EAAI;AACP,WAAO,EAAE,QAAQ,iBAAiB,MAAM,qCAAA;AAE1C,QAAM6B,IAAM,IAAI,IAAIN,GAAUF,GAAQG,CAAM,EAAE,UAAU,GAClDrU,IAAImU,GAAYjB,CAAK,EAAE,KAAK,CAAC7U,MAAQqW,EAAI,IAAIrW,CAAG,CAAC;AACvD,SAAI2B,MAAM,SAAkB,OAErB;AAAA,IACL,QAAQ;AAAA,IACR,MAAM,+BAHM1f,IAAAuzB,GAAKK,CAAM,EAAE,KAAK,CAACnwB,MAAMA,EAAE,QAAQic,CAAC,MAApC,gBAAA1f,EAAuC,UAAS0f,CAGpB;AAAA,EAAA;AAE5C;AAGO,SAASgV,GACdrqB,GACAmN,GACAqP,GACY;AACZ,SAA2Bxc,KAAU,QAAQA,MAAU,KAAW,EAAE,QAAQ,OAAA,IACxEopB,GAAkBppB,CAAK,IAAU,EAAE,QAAQ,OAAA,IAC3CmN,EAAQ,KAAK,CAACiC,MAAMA,EAAE,UAAUpP,KAAS,OAAOoP,EAAE,KAAK,MAAM,OAAOpP,CAAK,CAAC,IACrE,EAAE,QAAQ,OAAA,IAEfwc,EAAK,WAAW,YAAY,CAACA,EAAK,cAAoB,EAAE,QAAQ,QAAA,IAC7D,EAAE,QAAQ,QAAQ,SAAS,+BAA+BA,EAAK,QAAQ,GAAA;AAChF;ACxIO,SAAS8N,GACdf,GACAG,GACAa,GACAviB,GACkB;;AAClB,QAAM+E,KAAUpX,IAAAiH,SAAA,gBAAAjH,EAAqB,qBAC/BuT,IAAS,GAAQqhB,KAAWxd,IAC5B,CAACyd,GAAQC,CAAS,IAAIrvB,EAAiC,CAAA,CAAE,GAEzDsvB,IAASzrB,GAAO,EAAE,QAAAsqB,GAAQ,QAAAG,GAAQ,SAAAa,GAAS,UAAAviB,GAAU,SAAA+E,GAAS;AACpE,EAAA2d,EAAO,UAAU,EAAE,QAAAnB,GAAQ,QAAAG,GAAQ,SAAAa,GAAS,UAAAviB,GAAU,SAAA+E,EAAA;AACtD,QAAM4d,IAAQ1rB,GAAO,oBAAI,KAA4B,GAC/C2rB,IAAW3rB,GAAmB,EAAE,GAEhCwL,IAAMnK;AAAA,IACV,CACE3C,GACAmsB,GACArQ,GACAoR,GACA/pB,MACG;AACH,YAAM,EAAE,QAAQgqB,GAAI,QAAQ3kB,GAAK,SAAS+hB,GAAK,SAAS6C,EAAA,IAASL,EAAO,SAClEM,IAAKlqB,KAAQqF;AACnB,UAAI,CAAC+hB,KAAO,CAAC6C,KAAQ,CAAC7C,EAAI,aAAc;AACxC,YAAM+C,IAAOpB,GAAaiB,GAAIE,GAAIrtB,GAAQmsB,GAASrQ,CAAQ;AAC3D,UAAI,CAACwR,EAAM;AACX,YAAMC,IAAQ,IAAI,IAAI5B,GAAcwB,CAAE,EAAE,IAAI,CAAC1xB,MAAM,CAACA,EAAE,KAAKA,CAAC,CAAC,CAAC,GACxD+xB,IAAoB,CAAA,GACpBC,IAAiC,CAAA,GACjC1Q,IAAmB,CAAA,GACnB2Q,IAAWnD,EAAI,WAAWA,EAAI,OAC9BoD,KAAQ,CAAC5X,GAAavG,MAA2B;AACrD,cAAM/T,KAAI8xB,EAAM,IAAIxX,CAAG;AACvB,YAAI,CAACta,GAAG;AAMR,QALUixB,GAAeW,EAAGtX,CAAG,GAAGvG,GAAS;AAAA,UACzC,aAAakc,GAAcjwB,EAAC;AAAA,UAC5B,QAAAuE;AAAA,UACA,UAAA0tB;AAAA,QAAA,CACD,EACK,WAAW,WAASF,EAAQ,KAAKzX,CAAG;AAAA,MAC5C;AACA,iBAAWA,KAAOuX,EAAK,QAAQ;AAC7B,YAAIJ,MAAS,UAAanX,MAAQmX,EAAM;AACxC,cAAMzxB,IAAI8xB,EAAM,IAAIxX,CAAG;AACvB,YAAI,CAACta,EAAG;AACR,cAAM2Z,KACJ8X,MAAS,UAAaX,GAAY9wB,CAAC,IAC/BuxB,EAAM,QAAQ,IAAIV,GAAS/B,GAAK9uB,GAAG6xB,EAAK,IAAI,CAAC,IAC7C;AACN,QAAIlY,MACFqY,EAAO1X,CAAG,IAAI,EAAE,SAASX,IAAK,SAAS,GAAA,GACvCuY,GAAM5X,GAAKX,EAAG,KACT2H,EAAO,KAAKhH,CAAG;AAAA,MACxB;AACA,YAAM6X,KAAQ,CAAChK,IAAO,OAAU;AAC9B,YAAI4J,EAAQ,WAAW,EAAG;AAE1B,cAAM7zB,IAAM,EAAE,GAAIiqB,IAAOyJ,IAAKN,EAAO,QAAQ,OAAA;AAC7C,mBAAWrV,MAAK8V,EAAS,QAAO7zB,EAAI+d,EAAC;AACrC,QAAAqV,EAAO,QAAQ,SAASpzB,CAAG;AAAA,MAC7B;AAEA,UADI,OAAO,KAAK8zB,CAAM,EAAE,SAAS,KAAGX,EAAU,CAAC70B,OAAO,EAAE,GAAGA,GAAG,GAAGw1B,IAAS,GACtE1Q,EAAO,WAAW,GAAG;AACvB,QAAA6Q,GAAM,EAAI;AACV;AAAA,MACF;AACA,iBAAW3Q,KAAKgQ,EAAS;AACvB,QAAIT,GAAcvP,EAAE,QAAQF,CAAM,KAAGE,EAAE,WAAW,MAAA;AAEpD,YAAMla,IAAa,IAAI,gBAAA,GACjBhD,IAAkB,EAAE,QAAAgd,GAAQ,YAAAha,EAAA;AAClC,MAAAkqB,EAAS,UAAU,CAAC,GAAGA,EAAS,QAAQ,OAAO,CAAChQ,MAAM,CAACA,EAAE,WAAW,OAAO,OAAO,GAAGld,CAAK,GAC1F+sB,EAAU,CAAC70B,MAAM;;AACf,cAAMgU,IAAI,EAAE,GAAGhU,EAAA;AACf,mBAAWyf,KAAKqF,EAAQ,CAAA9Q,EAAEyL,CAAC,IAAI,EAAE,UAAS1f,KAAAC,EAAEyf,CAAC,MAAH,gBAAA1f,GAAM,SAAS,SAAS,GAAA;AAClE,eAAOiU;AAAA,MACT,CAAC;AACD,YAAMnI,IAAO;AAAA,QACX,GAAGwpB;AAAA,QACH,QAAAvQ;AAAAA,QACA,cAAcwN,EAAI;AAAA,QAClB,GAAIA,EAAI,YAAY,SAAY,EAAE,SAASA,EAAI,YAAY,CAAA;AAAA,MAAC,GAExDsD,IAAO,CAAC7hB,MAAkC;AAC9C,QAAAihB,EAAS,UAAUA,EAAS,QAAQ,OAAO,CAAChQ,MAAMA,MAAMld,CAAK,GAC7D+sB,EAAU,CAAC70B,OAAO,EAAE,GAAGA,GAAG,GAAG+T,IAAQ;AAAA,MACvC;AACA,cAAQ,UACL,KAAK,MAAMohB,EAAK7C,EAAI,OAAOA,EAAI,WAAWzmB,GAAM,EAAE,QAAQf,EAAW,OAAA,CAAQ,CAAC,EAC9E,KAAK,CAAC+qB,MAAQ;;AACb,YAAI/qB,EAAW,OAAO,QAAS;AAC/B,cAAMiJ,IAAgC,CAAA;AACtC,mBAAW+J,KAAOgH,GAAQ;AACxB,gBAAMpjB,KAAM3B,KAAA81B,KAAA,gBAAAA,EAAK,WAAL,gBAAA91B,GAAc+d,IACpBta,IAAI8xB,EAAM,IAAIxX,CAAG;AACvB,cAAI,CAACpc,KAAO,CAAC8B;AACX,YAAAuQ,EAAM+J,CAAG,IAAI,EAAE,SAAS,GAAA;AAAA,mBACfpc,EAAI;AACb,YAAAqS,EAAM+J,CAAG,IAAI,EAAE,SAAS,IAAO,OAAOpc,EAAI,MAAA;AAAA,eACrC;AACL,kBAAM6V,IAAU,MAAM,QAAQ7V,EAAI,OAAO,IAAIA,EAAI,UAAU,CAAA;AAC3D,YAAAqS,EAAM+J,CAAG,IAAI,EAAE,SAAS,IAAO,SAAAvG,EAAA,GAC3B+c,GAAY9wB,CAAC,KAAGuxB,EAAM,QAAQ,IAAIV,GAAS/B,GAAK9uB,GAAG6xB,EAAK,IAAI,GAAG9d,CAAO,GAC1Eme,GAAM5X,GAAKvG,CAAO;AAAA,UACpB;AAAA,QACF;AACA,QAAAqe,EAAK7hB,CAAK,GACV4hB,GAAA;AAAA,MACF,CAAC,EACA,MAAM,CAAC/rB,MAAe;AACrB,YAAIkB,EAAW,OAAO,QAAS;AAC/B,cAAMgrB,IAAMlsB,aAAa,QAAQA,EAAE,UAAU,OAAOA,CAAC,GAC/CmK,KAAgC,CAAA;AACtC,mBAAW+J,KAAOgH,EAAQ,CAAA/Q,GAAM+J,CAAG,IAAI,EAAE,SAAS,IAAO,OAAOgY,KAAO,iBAAA;AACvE,QAAAF,EAAK7hB,EAAK;AAAA,MACZ,CAAC;AAAA,IACL;AAAA,IACA,CAAA;AAAA,EAAC,GAGGgiB,IAASpB,IACX,KAAK,UAAU,CAACA,EAAQ,OAAOA,EAAQ,WAAWA,EAAQ,SAASA,EAAQ,YAAY,CAAC,IACxF;AAEJ,EAAAlvB,GAAU,MAAM;AACd,QAAK6N;AACL,aAAAuhB,EAAU,CAAA,CAAE,GACZhgB,EAAI,MAAM,GACH,MAAM;AACX,mBAAWmQ,KAAKgQ,EAAS,QAAS,CAAAhQ,EAAE,WAAW,MAAA;AAC/C,QAAAgQ,EAAS,UAAU,CAAA;AAAA,MACrB;AAAA,EACF,GAAG,CAACe,GAAQziB,GAAQuB,CAAG,CAAC;AAGxB,QAAMmhB,IAAQ3sB,GAAO,oBAAI,KAAsC,GACzD4sB,IAASvrB;AAAA,IACb,CAACoT,GAAa1T,MAAmB;AAC/B,YAAMyZ,IAAWmS,EAAM,QAAQ,IAAIlY,CAAG,KAAKgX,EAAO,QAAQ;AAC1D,MAAAkB,EAAM,QAAQ,OAAOlY,CAAG,GACxBjJ,EAAI,UAAU,CAACiJ,CAAG,GAAG+F,GAAU,QAAW,EAAE,GAAGiR,EAAO,QAAQ,QAAQ,CAAChX,CAAG,GAAG1T,GAAO;AAAA,IACtF;AAAA,IACA,CAACyK,CAAG;AAAA,EAAA,GAEAqhB,IAAQxrB,GAAY,CAACoT,MAAgB;AACzC,IAAKkY,EAAM,QAAQ,IAAIlY,CAAG,KAAGkY,EAAM,QAAQ,IAAIlY,GAAKgX,EAAO,QAAQ,MAAM;AAAA,EAC3E,GAAG,CAAA,CAAE,GACCqB,IAAOzrB;AAAA,IACX,CAACoT,MAAgB;AACf,YAAM+F,IAAWmS,EAAM,QAAQ,IAAIlY,CAAG;AAEtC,UADAkY,EAAM,QAAQ,OAAOlY,CAAG,GACpB,CAAC+F,EAAU;AACf,YAAMuS,IAAMtB,EAAO,QAAQ;AAC3B,MAAI,KAAK,UAAUjR,EAAS/F,CAAG,CAAC,MAAM,KAAK,UAAUsY,EAAItY,CAAG,CAAC,KAC7DjJ,EAAI,UAAU,CAACiJ,CAAG,GAAG+F,CAAQ;AAAA,IAC/B;AAAA,IACA,CAAChP,CAAG;AAAA,EAAA,GAEAxJ,IAAQX,GAAY,CAACoT,MAAgBjJ,EAAI,QAAQ,QAAW,QAAWiJ,CAAG,GAAG,CAACjJ,CAAG,CAAC;AA2BxF,SAAO,EAAE,QAzBMmD,GAAQ,MAAM;AAC3B,UAAMtW,IAAyC,CAAA;AAC/C,QAAI,CAAC4R,KAAU,CAACqhB,EAAS,QAAOjzB;AAChC,UAAM+zB,IAAWd,EAAQ,WAAWA,EAAQ;AAC5C,eAAWnxB,KAAKkwB,GAAcC,CAAM,GAAG;AACrC,YAAM0C,IAAM7B,GAAchxB,GAAGmwB,GAAQG,GAAQa,CAAO;AACpD,UAAI0B,GAAK;AACP,QAAA30B,EAAI8B,EAAE,GAAG,IAAI,EAAE,SAAS,IAAO,MAAM6yB,EAAI,KAAA;AACzC;AAAA,MACF;AACA,YAAMr2B,IAAI40B,EAAOpxB,EAAE,GAAG,KAAK,EAAE,SAAS,GAAA,GAChCqpB,IAAwB,EAAE,GAAG7sB,EAAA;AACnC,UAAIA,EAAE,SAAS;AACb,cAAMs2B,IAAM7B,GAAeX,EAAOtwB,EAAE,GAAG,GAAGxD,EAAE,SAAS;AAAA,UACnD,aAAayzB,GAAcjwB,CAAC;AAAA,UAC5B,QAAQ;AAAA,UACR,UAAAiyB;AAAA,QAAA,CACD;AACD,QAAIa,EAAI,WAAW,WAAQzJ,EAAG,YAAYyJ,EAAI;AAAA,MAChD;AACA,MAAA50B,EAAI8B,EAAE,GAAG,IAAIqpB;AAAA,IACf;AACA,WAAOnrB;AAAA,EACT,GAAG,CAAC4R,GAAQqhB,GAAShB,GAAQG,GAAQc,CAAM,CAAC,GAE3B,QAAAqB,GAAQ,OAAAC,GAAO,MAAAC,GAAM,OAAA9qB,EAAA;AACxC;ACvMO,SAASkrB,GAAe5D,GAAoB6D,GAA6C;AAC9F,SAAI7D,EAAM,WAAW,KAAa,KAC7BA,EAAM,SACJ8D,GAAsB9D,EAAM,QAAQ6D,CAAQ,IADzB;AAE5B;AAYO,SAASE,GAAcnD,GAAoC;AAChE,QAAM7xB,IAAqB,CAAA;AAC3B,aAAW8B,KAAK+vB;AACd,IAAA7xB,EAAI,KAAK8B,CAAC,GACNA,EAAE,SAAS,aAAaA,EAAE,YAAU9B,EAAI,KAAK,GAAGg1B,GAAclzB,EAAE,QAAQ,CAAC;AAE/E,SAAO9B;AACT;AAEA,SAASi1B,GACPpD,GACAqD,GACa;AACb,QAAMl1B,IAAmB,CAAA;AACzB,WAASuZ,IAAI,GAAGA,IAAIsY,EAAK,UAAU;AACjC,UAAMsD,IAAQtD,EAAKtY,CAAC,EAAE;AACtB,QAAI4b,GAAO;AACT,YAAMC,IAAuB,CAAA;AAC7B,aAAO7b,IAAIsY,EAAK,UAAUA,EAAKtY,CAAC,EAAE,QAAQ4b,IAAO,CAAAC,EAAM,KAAKvD,EAAKtY,GAAG,CAAC;AACrE,MAAAvZ,EAAI;AAAA,QACF,gBAAA6E,EAAC,OAAA,EAAI,WAAU,iBACZ,UAAAuwB,EAAM,IAAIF,CAAS,EAAA,GADc,OAAOC,CAAK,EAEhD;AAAA,MAAA;AAAA,IAEJ;AACE,MAAAn1B,EAAI,KAAKk1B,EAAUrD,EAAKtY,CAAC,CAAC,CAAC,GAC3BA;AAAA,EAEJ;AACA,SAAOvZ;AACT;AAYA,SAASq1B,GACPjD,GACAkD,GACAC,GACA/kB,GAC+B;AAC/B,QAAM0kB,IAAY,CAACpzB,MACbA,EAAE,SAAS,8BACL0zB,IAAA,EAAyB,OAAO1zB,GAAG,WAAAyzB,GAAsB,WAAAL,EAAA,GAAvCpzB,EAAE,GAA2D,IAKrFA,EAAE,UAAUA,EAAE,SAAS,UAEvB,gBAAA+C;AAAA,IAAC4wB;AAAA,IAAA;AAAA,MAEC,OAAO3zB;AAAA,MACP,OAAOswB,EAAOtwB,EAAE,GAAG;AAAA,MACnB,UAAUwzB;AAAA,MACV,UAAA9kB;AAAA,IAAA;AAAA,IAJK1O,EAAE;AAAA,EAAA,IAQTA,EAAE,SAAS,WAAWA,EAAE,YAAYA,EAAE,SAAS,SAAS,IAExD,gBAAA+C;AAAA,IAAC6wB;AAAA,IAAA;AAAA,MAEC,OAAO5zB;AAAA,MACP,OAAOswB,EAAOtwB,EAAE,GAAG;AAAA,MACnB,UAAUwzB;AAAA,MACV,WAAAC;AAAA,MACA,UAAA/kB;AAAA,IAAA;AAAA,IALK1O,EAAE;AAAA,EAAA,IAUX,gBAAA+C;AAAA,IAAC8wB;AAAA,IAAA;AAAA,MAEC,OAAO7zB;AAAA,MACP,OAAOswB,EAAOtwB,EAAE,GAAG;AAAA,MACnB,UAAUwzB;AAAA,MACV,WAAAC;AAAA,MACA,UAAA/kB;AAAA,IAAA;AAAA,IALK1O,EAAE;AAAA,EAAA;AASb,SAAOozB;AACT;AAGA,MAAMU,KAAmBvyB,GAAuC,IAAI;AA0B7D,SAASwyB,GAAW,EAAE,QAAA5D,GAAQ,QAAAG,GAAQ,UAAA1hB,GAAU,UAAAF,GAAU,SAAAyiB,KAA4B;AAC3F,QAAM6C,IAAM9C,GAAiBf,GAAQG,GAAQa,GAASviB,CAAQ,GAMxDkhB,IAAOoD,GAAc/C,CAAM,GAC3BsD,IAAY,CAACnZ,MAAA;;AACjB,WAAAgW,EAAOhW,CAAG,MAAM,SAAYgW,EAAOhW,CAAG,KAAI/d,IAAAuzB,EAAK,KAAK,CAAC9vB,MAAMA,EAAE,QAAQsa,CAAG,MAA9B,gBAAA/d,EAAiC;AAAA,KAGvEyN,IAAUmmB,EACb,OAAO,CAACnwB,MAAM+yB,GAAe/yB,GAAGyzB,CAAS,CAAC,EAC1C,IAAI,CAACzzB,MAAMi0B,GAAej0B,GAAGyzB,CAAS,CAAC,GAGpCS,IAAOlqB,EAAQ,OAAO,CAAChK,MAAMA,EAAE,YAAY,CAACA,EAAE,QAAQ,GACtDm0B,IAAanqB,EAAQ,OAAO,CAAChK,MAAM,CAACA,EAAE,YAAYA,EAAE,QAAQ,GAU5DwzB,IAAM,CAAClZ,GAAa1T,MAAmB;AAC3C,QAAI0T,MAAQ,YAAY;AACtB,YAAM5S,IAAgC,EAAE,GAAG4oB,GAAQ,CAAChW,CAAG,GAAG1T,EAAA;AAC1D,iBAAW5G,KAAK8vB,GAAM;AACpB,YAAI9vB,EAAE,SAAS,OAAQ;AACvB,cAAMwS,IAAU8d,EAAOtwB,EAAE,GAAG;AAM5B,SAJEwS,MAAY,UACZA,MAAYxS,EAAE,WACdwS,MAAY4hB,MACZC,GAAqB,SAAS7hB,CAAiB,OAE/C9K,EAAK1H,EAAE,GAAG,IAAI4G,MAAU,WAAWwtB,KAAsBp0B,EAAE;AAAA,MAE/D;AACA,MAAA4O,EAASlH,CAAI;AACb;AAAA,IACF;AACA,IAAAkH,EAAS,EAAE,GAAG0hB,GAAQ,CAAChW,CAAG,GAAG1T,GAAO;AAAA,EACtC;AAEA,MAAIupB,EAAO,WAAW;AACpB,WAAO,gBAAAptB,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,oCAAgC;AAQ5E,QAAMqwB,IAAYG,GAAcjD,GAAQkD,GAAKC,GAAW/kB,CAAQ;AAEhE,SACE,gBAAA3L,EAAC+wB,GAAiB,UAAjB,EAA0B,OAAOE,GAChC,UAAA,gBAAAnrB,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAAsqB,GAAgBe,GAAMd,CAAS;AAAA,IAC/Be,EAAW,SAAS,KACnB,gBAAAtrB,EAAC,WAAA,EAAQ,WAAU,uBACjB,UAAA;AAAA,MAAA,gBAAAA,EAAC,WAAA,EAAQ,WAAU,uBAAsB,UAAA;AAAA,QAAA;AAAA,QACfsrB,EAAW;AAAA,QAAO;AAAA,MAAA,GAC5C;AAAA,MACA,gBAAApxB,EAAC,OAAA,EAAI,WAAU,aAAY,OAAO,EAAE,WAAW,EAAA,GAC5C,UAAAowB,GAAgBgB,GAAYf,CAAS,EAAA,CACxC;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,EAAA,CAEJ,EAAA,CACF;AAEJ;AAeA,SAASM,GAAa;AAAA,EACpB,OAAAvE;AAAA,EACA,WAAAsE;AAAA,EACA,WAAAL;AACF,GAIG;AACD,QAAMkB,KAAmBnF,EAAM,YAAY,CAAA,GACxC,OAAO,CAAClmB,MAAM8pB,GAAe9pB,GAAGwqB,CAAS,CAAC,EAC1C,IAAI,CAACxqB,MAAMgrB,GAAehrB,GAAGwqB,CAAS,CAAC;AAE1C,SAAItE,EAAM,YAAY,gBAElB,gBAAAtmB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,MACEsmB,EAAM,cAAc,MACnBA,EAAM,gBAAgB,MACrBmF,EAAgB,KAAK,CAACrrB,MAAM;AAC1B,cAAMnL,IAAI21B,EAAUxqB,EAAE,GAAG;AACzB,eAA0BnL,KAAM,QAAQA,MAAM;AAAA,MAChD,CAAC;AAAA,MAGL,UAAA;AAAA,QAAA,gBAAA+K,EAAC,WAAA,EAAQ,WAAU,uBACjB,UAAA;AAAA,UAAA,gBAAA9F,EAAC,QAAA,EAAK,WAAU,qBAAqB,UAAAosB,EAAM,SAASA,EAAM,SAASA,EAAM,IAAA,CAAI;AAAA,UAC5EA,EAAM,YAAY,gBAAApsB,EAAC,UAAK,WAAU,wBAAwB,YAAM,SAAA,CAAS;AAAA,QAAA,GAC5E;AAAA,0BACC,OAAA,EAAI,WAAU,8BACZ,UAAAowB,GAAgBmB,GAAiBlB,CAAS,EAAA,CAC7C;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,IAQFjE,EAAM,WAAW,0BACX,OAAA,EAAI,WAAU,iBAAiB,UAAAmF,EAAgB,IAAIlB,CAAS,GAAE,sBAEhE,OAAA,EAAI,WAAU,aAAa,UAAAD,GAAgBmB,GAAiBlB,CAAS,GAAE;AACjF;AAMA,MAAMmB,yBAA8B,IAAI,CAAC,UAAU,QAAQ,UAAU,WAAW,QAAQ,CAAC;AAEzF,SAASC,GAAoBlT,GAAgC;AAC3D,SACEA,EAAO,SAAS,KAAKA,EAAO,MAAM,CAACE,MAAM+S,GAAwB,IAAI/S,EAAE,IAAI,KAAK,CAACA,EAAE,QAAQ;AAE/F;AAsBA,SAASoS,GAAW;AAAA,EAClB,OAAAzE;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAAgI;AAAA,EACA,WAAA6kB;AAAA,EACA,UAAA/kB;AACF,GAQG;AACD,QAAMrL,IAAW8rB,EAAM,YAAY,CAAA,GAC7BsF,IAAc7tB,KAAS,CAAA,GACvB8tB,IAAW,CAACpa,GAAaxc,MAAe8Q,EAASugB,EAAM,KAAK,EAAE,GAAGsF,GAAY,CAACna,CAAG,GAAGxc,GAAG,GAIvF62B,IAAezB,GAAc7vB,CAAQ,GACrCuxB,IAAiB,CAACta,MAAyB;AAC/C,UAAMua,IAAQF,EAAa,KAAK,CAAC1rB,MAAMA,EAAE,QAAQqR,CAAG;AACpD,WAAKua,IACEJ,EAAWna,CAAG,MAAM,SAAYma,EAAWna,CAAG,IAAIua,EAAM,UAD5CpB,EAAUnZ,CAAG;AAAA,EAElC,GACMga,IAAkBjxB,EACrB,OAAO,CAAC4F,MAAM8pB,GAAe9pB,GAAG2rB,CAAc,CAAC,EAC/C,IAAI,CAAC3rB,MAAMgrB,GAAehrB,GAAG2rB,CAAc,CAAC,GACzCE,IAAiBvB,GAAckB,GAAYC,GAAUE,GAAgBlmB,CAAQ;AAEnF,SACE,gBAAA3L,EAAC+wB,GAAiB,UAAjB,EAA0B,OAAO,MAChC,UAAA,gBAAAjrB,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAA9F,EAAC,UAAK,WAAU,qBAAqB,UAAAosB,EAAM,SAASA,EAAM,KAAI;AAAA,sBAC7D,OAAA,EAAI,WAAU,8BACZ,UAAAgE,GAAgBmB,GAAiBQ,CAAc,EAAA,CAClD;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;AAeA,SAASnB,GAAY;AAAA,EACnB,OAAAxE;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAAgI;AAAA,EACA,UAAAF;AACF,GAKG;AACD,MAAIygB,EAAM,SAAS,SAAS;AAC1B,UAAM9rB,IAAW8rB,EAAM,YAAY,CAAA;AACnC,QAAI,CAACqF,GAAoBnxB,CAAQ;AAC/B,aAAO,gBAAAN,EAACgyB,IAAA,EAAe,OAAA5F,GAAc,OAAAvoB,GAAc,UAAAgI,GAAoB,UAAAF,GAAoB;AAE7F,UAAMsmB,IAA2B,EAAE,GAAG7F,GAAO,MAAM,EAAE,MAAM,UAAU,QAAQ9rB,IAAS;AACtF,6BAAQ4xB,IAAA,EAAW,OAAOD,GAAa,OAAApuB,GAAc,UAAAgI,GAAoB,UAAAF,GAAoB;AAAA,EAC/F;AACA,QAAMsmB,IAA2B;AAAA,IAC/B,GAAG7F;AAAA,IACH,MAAM,EAAE,MAAMA,EAAM,MAAM,SAAS,MAAM,QAAQA,EAAM,OAAO,IAAIA,EAAM,UAAU,OAAA;AAAA,EAAU;AAE9F,2BAAQ8F,IAAA,EAAW,OAAOD,GAAa,OAAApuB,GAAc,UAAAgI,GAAoB,UAAAF,GAAoB;AAC/F;AAKA,MAAM0lB,KAAsB;AAAA,eAMtBC,KAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAASR,GAAW5gB,GAAwB;AAC1C,QAAM+gB,IAAMnyB,GAAWiyB,EAAgB,GACjCxZ,IAAMrH,EAAM,MAAM;AAExB,SACE,gBAAAlQ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO,EAAE,SAAS,WAAA;AAAA,MAClB,gBAAgBixB,IAAM,MAAMA,EAAI,MAAM1Z,CAAG,IAAI;AAAA,MAC7C,eAAe0Z,IAAM,MAAMA,EAAI,KAAK1Z,CAAG,IAAI;AAAA,MAE3C,UAAA,gBAAAvX,EAACmyB,IAAA,EAAgB,GAAGjiB,EAAA,CAAO;AAAA,IAAA;AAAA,EAAA;AAGjC;AAUA,SAASiiB,GAAe;AAAA,EACtB,OAAA/F;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAUuuB;AAAA,EACV,WAAA1B;AAAA,EACA,UAAA/kB;AACF,GASG;;AACD,QAAM0mB,KAAkB74B,IAAAiH,SAAA,gBAAAjH,EAAqB,iBACvC84B,KAAiBtlB,IAAAvM,SAAA,gBAAAuM,EAAqB,gBACtCulB,KAAuB9f,IAAAhS,SAAA,gBAAAgS,EAAqB,sBAC5C+f,IAAkBzxB,GAAA,GAClBkwB,IAAMnyB,GAAWiyB,EAAgB,GACjC0B,IAAWxB,KAAA,gBAAAA,EAAK,OAAO7E,EAAM,MAE7Bxc,IAAO,CAACsJ,GAAWne,MAAe;AACtC,IAAAq3B,EAAYlZ,GAAGne,CAAC,GAChBk2B,KAAA,QAAAA,EAAK,OAAO/X,GAAGne;AAAA,EACjB,GACM8Q,IAAWumB,GACX1iB,IAAQ0c,EAAM,SAASA,EAAM,KAG7BC,IAAMD,EAAM,YAAYA,EAAM,SAAS,YAAY,OAAO,IAG1DsG,IAAY3e,GAAA;AAElB,MAAIqY,EAAM,SAAS,WAAW;AAC5B,UAAM3c,IAAU,GAAQ5L,KAASuoB,EAAM,WAAW;AAClD,WACE,gBAAApsB;AAAA,MAAC2yB;AAAA,MAAA;AAAA,QACC,OAAAvG;AAAA,QACA,OAAAvoB;AAAA,QACA,UAAAgI;AAAA,QACA,UAAAF;AAAA,QACA,OAAA+D;AAAA,QACA,KAAA2c;AAAA,QAKA,SAAQ;AAAA,QACR,WAAAqG;AAAA,QAEA,UAAA,gBAAA1yB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAI0yB;AAAA,YACJ,MAAK;AAAA,YACL,SAASjjB;AAAA,YACT,UAAU9D;AAAA,YACV,UAAU,CAACtI,MAAMuM,EAAKwc,EAAM,KAAK/oB,EAAE,OAAO,OAAO;AAAA,UAAA;AAAA,QAAA;AAAA,MACnD;AAAA,IAAA;AAAA,EAGN;AAIA,MAAI+oB,EAAM,SAAS,UAAUA,EAAM,SAAS;AAC1C,WAAO,gBAAApsB,EAACgyB,IAAA,EAAe,OAAA5F,GAAc,OAAAvoB,GAAc,UAAAgI,GAAoB,UAAAF,GAAoB;AAc7F,MAAIygB,EAAM,SAAS,QAAQ;AACzB,UAAMwG,IAAkBlC,KAAA,gBAAAA,EAAY,aAC9Btf,IACJwhB,MAAoB,YACpBA,MAAoB,gBACpBA,MAAoB,eAChBA,IACA,QACAC,IAAkBzhB,MAAa,WAAWigB,KAAsBjF,EAAM,SACtE3c,IAAW5L,KAASgvB,KAAmB;AAC7C,WAAIzG,EAAM,cAEN,gBAAApsB;AAAA,MAACmsB;AAAA,MAAA;AAAA,QACC,OAAAC;AAAA,QACA,OAAO,OAAO3c,CAAO;AAAA,QACrB,UAAUmjB,MAAoB,WAAW,WAAW;AAAA,QACpD,OAAAljB;AAAA,QACA,KAAA2c;AAAA,QACA,UAAA1gB;AAAA,QACA,UAAU,CAAChH,MAASkH,EAASugB,EAAM,KAAKznB,CAAI;AAAA,MAAA;AAAA,IAAA,IAKhD,gBAAAmB,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,QAAA,EACE,UAAA;AAAA,QAAA4J;AAAA,QACA2c;AAAA,MAAA,GACH;AAAA,MACA,gBAAArsB;AAAA,QAACuR;AAAA,QAAA;AAAA,UACC,OAAO,OAAO9B,CAAO;AAAA,UACrB,UAAA9D;AAAA,UACA,WAAU;AAAA,UACV,UAAAyF;AAAA,UACA,cAAY,GAAGgb,EAAM,GAAG;AAAA,UACxB,UAAU,CAACznB,MAASkH,EAASugB,EAAM,KAAKznB,CAAI;AAAA,QAAA;AAAA,MAAA;AAAA,MAE7CynB,EAAM,QAAQ,gBAAApsB,EAAC,UAAK,WAAU,YAAY,YAAM,KAAA,CAAK;AAAA,IAAA,GACxD;AAAA,EAEJ;AAIA,MAAIosB,EAAM,SAAS,iBAAiBiG;AAClC,WACE,gBAAAryB;AAAA,MAAC8yB;AAAA,MAAA;AAAA,QACC,OAAA1G;AAAA,QACA,OAAAvoB;AAAA,QACA,UAAAgI;AAAA,QACA,UAAAF;AAAA,QACA,OAAA+D;AAAA,QACA,KAAA2c;AAAA,QACA,iBAAAgG;AAAA,QACA,SAASG;AAAA,MAAA;AAAA,IAAA;AAOf,MAAIpG,EAAM,SAAS,gBAAgBkG;AACjC,WACE,gBAAAtyB;AAAA,MAAC+yB;AAAA,MAAA;AAAA,QACC,OAAA3G;AAAA,QACA,OAAAvoB;AAAA,QACA,UAAAgI;AAAA,QACA,UAAAF;AAAA,QACA,OAAA+D;AAAA,QACA,KAAA2c;AAAA,QACA,gBAAAiG;AAAA,QACA,SAASE;AAAA,MAAA;AAAA,IAAA;AAQf,QAAMQ,IAAYtC,KAAA,gBAAAA,EAAY;AAC9B,MACEtE,EAAM,SAAS,oBACfmG,KACA,OAAOS,KAAc,YACrBA,EAAU,KAAA,MAAW;AAErB,WACE,gBAAAhzB;AAAA,MAACizB;AAAA,MAAA;AAAA,QACC,OAAA7G;AAAA,QACA,OAAAvoB;AAAA,QACA,UAAAgI;AAAA,QACA,UAAAF;AAAA,QACA,OAAA+D;AAAA,QACA,KAAA2c;AAAA,QACA,OAAO2G;AAAA,QACP,sBAAAT;AAAA,QACA,SAASC;AAAA,MAAA;AAAA,IAAA;AAMf,MAAIpG,EAAM,SAAS;AACjB,WAAO,gBAAApsB,EAACkzB,IAAA,EAAU,OAAA9G,GAAc,OAAAvoB,GAAc,UAAAgI,GAAoB,UAAAF,GAAoB;AAKxF,MAAIygB,EAAM,SAAS,WAAU1Z,IAAA0Z,EAAM,WAAN,QAAA1Z,EAAc,WAAW;AACpD,UAAMjD,IAAW5L,KAASuoB,EAAM,WAAW;AAC3C,WACE,gBAAApsB;AAAA,MAAC2yB;AAAA,MAAA;AAAA,QACC,OAAAvG;AAAA,QACA,OAAAvoB;AAAA,QACA,UAAAgI;AAAA,QACA,UAAAF;AAAA,QACA,OAAA+D;AAAA,QACA,KAAA2c;AAAA,QAEA,UAAA,gBAAArsB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAM;AAAA,YACN,OAAO,OAAOyP,CAAO;AAAA,YACrB,UAAA9D;AAAA,YACA,cAAY+D;AAAA,YACZ,UAAU,CAACrM,MAAMwI,EAASugB,EAAM,KAAK/oB,EAAE,OAAO,KAAK;AAAA,UAAA;AAAA,QAAA;AAAA,MACrD;AAAA,IAAA;AAAA,EAGN;AAIA,MAAI+oB,EAAM,SAAS;AACjB,6BAAQ+G,IAAA,EAAiB,OAAA/G,GAAc,OAAAvoB,GAAc,UAAU+L,GAAM,UAAAjE,GAAoB;AAK3F,MAAIygB,EAAM,SAAS;AACjB,WAAO,gBAAApsB,EAACkyB,IAAA,EAAW,OAAA9F,GAAc,OAAAvoB,GAAc,UAAAgI,GAAoB,UAAAF,GAAoB;AAMzF,MAAIslB,KAAOwB,KAAY,CAACA,EAAS;AAC/B,WACE,gBAAAzyB;AAAA,MAACozB;AAAA,MAAA;AAAA,QACC,OAAAhH;AAAA,QACA,OAAAvoB;AAAA,QACA,UAAU+L;AAAA,QACV,UAAAjE;AAAA,QACA,OAAA+D;AAAA,QACA,KAAA2c;AAAA,QACA,OAAOoG;AAAA,QACP,OAAO,MAAMxB,EAAI,MAAM7E,EAAM,GAAG;AAAA,MAAA;AAAA,IAAA;AAItC,MAAI,MAAM,QAAQA,EAAM,OAAO,KAAKA,EAAM,QAAQ,SAAS,KAAKc,GAAcd,CAAK;AACjF,WACE,gBAAApsB;AAAA,MAACozB;AAAA,MAAA;AAAA,QACC,OAAAhH;AAAA,QACA,OAAAvoB;AAAA,QACA,UAAU+L;AAAA,QACV,UAAAjE;AAAA,QACA,OAAA+D;AAAA,QACA,KAAA2c;AAAA,QACA,OAAO,EAAE,SAAS,IAAO,SAASD,EAAM,QAAA;AAAA,MAAQ;AAAA,IAAA;AAOtD,MAAI,MAAM,QAAQA,EAAM,OAAO,KAAKA,EAAM,QAAQ,SAAS,GAAG;AAK5D,UAAMiH,IACJ,CAACjH,EAAM,YACPA,EAAM,YAAY,UAClB,OAAOA,EAAM,eAAgB,YAC7BA,EAAM,cACFA,EAAM,cACN,QACA3c,IACJ5L,KAASuoB,EAAM,YAAYiH,MAAe,SAAY,MAAKxW,IAAAuP,EAAM,QAAQ,CAAC,MAAf,gBAAAvP,EAAkB,UAAU,IACnFyW,IAAWlH,EAAM,SAAS;AAChC,WACE,gBAAApsB;AAAA,MAAC2yB;AAAA,MAAA;AAAA,QACC,OAAAvG;AAAA,QACA,OAAAvoB;AAAA,QACA,UAAAgI;AAAA,QACA,UAAAF;AAAA,QACA,OAAA+D;AAAA,QACA,KAAA2c;AAAA,QAEA,UAAA,gBAAAvmB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO,OAAO2J,CAAO;AAAA,YACrB,UAAU9D;AAAA,YACV,cAAY+D;AAAA,YACZ,UAAU,CAACrM,MAAM;AACf,oBAAMtI,IAAIsI,EAAE,OAAO;AACnB,cAAIgwB,MAAe,UAAat4B,MAAM,KAAI6U,EAAKwc,EAAM,KAAK,MAAS,MACzDA,EAAM,KAAKkH,IAAW,OAAOv4B,CAAC,IAAIA,CAAC;AAAA,YAC/C;AAAA,YAEC,UAAA;AAAA,cAAAs4B,MAAe,UAAa,gBAAArzB,EAAC,UAAA,EAAO,OAAM,IAAI,UAAAqzB,GAAW;AAAA,cACzDjH,EAAM,QAAQ,IAAI,CAACnZ,MAClB,gBAAAjT,EAAC,YAA6B,OAAO,OAAOiT,EAAE,KAAK,GAChD,UAAAA,EAAE,MAAA,GADQ,OAAOA,EAAE,KAAK,CAE3B,CACD;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAGN;AAUA,MAAImZ,EAAM,SAAS,UAAU;AAC3B,UAAM3c,IAAW5L,KAASuoB,EAAM;AAChC,WACE,gBAAAtmB,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,QAAA,EACE,UAAA;AAAA,QAAA4J;AAAA,QACA2c;AAAA,MAAA,GACH;AAAA,MACA,gBAAArsB;AAAA,QAAC6pB;AAAA,QAAA;AAAA,UACC,OAAOpa;AAAA,UACP,QAAM;AAAA,UACN,UAAA9D;AAAA,UACA,cAAY+D;AAAA,UACZ,UAAU,CAAC/K,MAASkH,EAASugB,EAAM,KAAKznB,CAAI;AAAA,QAAA;AAAA,MAAA;AAAA,MAE7CynB,EAAM,QAAQ,gBAAApsB,EAAC,UAAK,WAAU,YAAY,YAAM,KAAA,CAAK;AAAA,IAAA,GACxD;AAAA,EAEJ;AAGA,QAAMuzB,IAAYnH,EAAM,SAAS,WAAW,WAAW,QACjDrjB,IAAMlF,KAASuoB,EAAM,WAAW,IAGhCoH,IAAU,OAAOzqB,KAAQ,YAAYA,MAAQ,OAAO,KAAK,UAAUA,CAAG,IAAI,OAAOA,KAAO,EAAE;AAChG,SACE,gBAAAjD;AAAA,IAAC6sB;AAAA,IAAA;AAAA,MACC,OAAAvG;AAAA,MACA,OAAAvoB;AAAA,MACA,UAAAgI;AAAA,MACA,UAAAF;AAAA,MACA,OAAA+D;AAAA,MACA,KAAA2c;AAAA,MAEA,UAAA;AAAA,QAAA,gBAAArsB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAMuzB;AAAA,YACN,OAAOC;AAAA,YACP,UAAA7nB;AAAA,YACA,cAAY+D;AAAA,YACZ,cAAa;AAAA,YACb,gBAAe;AAAA,YACf,aAAY;AAAA,YACZ,YAAY;AAAA,YACZ,kBAAe;AAAA,YACf,iBAAc;AAAA,YACd,iBAAc;AAAA,YACd,kBAAe;AAAA,YACf,UAAU,CAACrM,MACTwI,EAASugB,EAAM,KAAKA,EAAM,SAAS,WAAW,OAAO/oB,EAAE,OAAO,KAAK,IAAIA,EAAE,OAAO,KAAK;AAAA,UAAA;AAAA,QAAA;AAAA,SAGxFovB,KAAA,gBAAAA,EAAU,SAAQ,gBAAAzyB,EAAC,UAAK,WAAU,YAAY,YAAS,KAAA,CAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGnE;AAOA,SAASozB,GAAY;AAAA,EACnB,OAAAhH;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAAgI;AAAA,EACA,UAAAF;AAAA,EACA,OAAA+D;AAAA,EACA,KAAA2c;AAAA,EACA,OAAAzuB;AAAA,EACA,OAAAkH;AACF,GASG;AACD,QAAMiE,IAAMlF,KAASuoB,EAAM,WAAW,IAChC3c,IAAU,OAAO1G,KAAQ,YAAY,OAAOA,KAAQ,WAAW,OAAOA,CAAG,IAAI;AACnF,SACE,gBAAAjD;AAAA,IAAC6sB;AAAA,IAAA;AAAA,MACC,OAAAvG;AAAA,MACA,OAAAvoB;AAAA,MACA,UAAAgI;AAAA,MACA,UAAAF;AAAA,MACA,OAAA+D;AAAA,MACA,KAAA2c;AAAA,MAEA,UAAA;AAAA,QAAA,gBAAArsB,EAAC,SAAI,WAAU,eAAc,aAAWpC,EAAM,UAAU,SAAS,SAC/D,UAAA,gBAAAoC;AAAA,UAACqT;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,gBAAgB,CAAC6Z,GAAcd,CAAK;AAAA,YACpC,cAAY1c;AAAA,YACZ,UAAU/D;AAAA,YACV,OAAO8D;AAAA,YACP,aAAa7R,EAAM,UAAU,aAAcwuB,EAAM;AAAA,YACjD,UAAUxuB,EAAM,WAAW,CAAA,GAAI,IAAI,CAACqV,OAAO,EAAE,OAAO,OAAOA,EAAE,KAAK,GAAG,OAAOA,EAAE,QAAQ;AAAA,YACtF,UAAU,CAACtO,MAASkH,EAASugB,EAAM,KAAKznB,CAAI;AAAA,UAAA;AAAA,QAAA,GAEhD;AAAA,QACC/G,EAAM,aAAa,gBAAAoC,EAAC,UAAK,WAAU,YAAY,YAAM,WAAU;AAAA,QAC/DpC,EAAM,SACL,gBAAAkI,EAAC,UAAK,MAAK,SAAQ,WAAU,YAC1B,UAAA;AAAA,UAAAlI,EAAM;AAAA,UACNkH,KACC,gBAAA9E,EAAC,UAAA,EAAO,MAAK,UAAS,SAAS8E,GAAO,UAAA,QAAA,CAEtC;AAAA,QAAA,EAAA,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;AASA,SAASguB,GAAgB;AAAA,EACvB,OAAA1G;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAAgI;AAAA,EACA,UAAAF;AAAA,EACA,OAAA+D;AAAA,EACA,KAAA2c;AAAA,EACA,iBAAAgG;AAAA,EACA,SAAAxxB;AACF,GAUG;AACD,QAAM,CAAC5G,GAAQw5B,CAAS,IAAIx0B,EAA8C,CAAA,CAAE;AAC5E,EAAAC,GAAU,MAAM;AACd,QAAI8M,IAAO;AACX,mBAAQ,QAAA,EACL,KAAK,MAAMqmB,EAAgBxxB,CAAO,CAAC,EACnC,KAAK,CAACpH,MAAMuS,KAAQynB,EAAU,MAAM,QAAQh6B,CAAC,IAAIA,IAAI,CAAA,CAAE,CAAC,EACxD,MAAM,MAAMuS,KAAQynB,EAAU,CAAA,CAAE,CAAC,GAC7B,MAAM;AACX,MAAAznB,IAAO;AAAA,IACT;AAAA,EACF,GAAG,CAACqmB,GAAiBxxB,CAAO,CAAC;AAC7B,QAAMkI,IAAMlF,KAASuoB,EAAM,WAAW;AAEtC,SACE,gBAAApsB;AAAA,IAAC2yB;AAAA,IAAA;AAAA,MACC,OAAAvG;AAAA,MACA,OAAAvoB;AAAA,MACA,UAAAgI;AAAA,MACA,UAAAF;AAAA,MACA,OAAA+D;AAAA,MACA,KAAA2c;AAAA,MAEA,UAAA,gBAAArsB;AAAA,QAACqT;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,gBAAgB;AAAA,UAChB,cAAY3D;AAAA,UACZ,UAAU/D;AAAA,UACV,OAfU,OAAO5C,KAAQ,WAAWA,IAAM;AAAA,UAgB1C,aAAY;AAAA,UACZ,SAAS9O,EAAO,IAAI,CAACR,OAAO;AAAA,YAC1B,OAAOA,EAAE;AAAA,YACT,OAAOA,EAAE,WAAW,WAAW,GAAGA,EAAE,IAAI,cAAcA,EAAE;AAAA,UAAA,EACxD;AAAA,UACF,UAAU,CAACkL,MAASkH,EAASugB,EAAM,KAAKznB,CAAI;AAAA,QAAA;AAAA,MAAA;AAAA,IAC9C;AAAA,EAAA;AAGN;AASA,SAASouB,GAAW;AAAA,EAClB,OAAA3G;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAAgI;AAAA,EACA,UAAAF;AAAA,EACA,OAAA+D;AAAA,EACA,KAAA2c;AAAA,EACA,gBAAAiG;AAAA,EACA,SAAAzxB;AACF,GAUG;AACD,QAAM,CAAC6yB,GAAQC,CAAS,IAAI10B,EAA6C,CAAA,CAAE;AAC3E,EAAAC,GAAU,MAAM;AACd,QAAI8M,IAAO;AACX,mBAAQ,QAAA,EACL,KAAK,MAAMsmB,EAAezxB,CAAO,CAAC,EAClC,KAAK,CAACpH,MAAMuS,KAAQ2nB,EAAU,MAAM,QAAQl6B,CAAC,IAAIA,IAAI,CAAA,CAAE,CAAC,EACxD,MAAM,MAAMuS,KAAQ2nB,EAAU,CAAA,CAAE,CAAC,GAC7B,MAAM;AACX,MAAA3nB,IAAO;AAAA,IACT;AAAA,EACF,GAAG,CAACsmB,GAAgBzxB,CAAO,CAAC;AAC5B,QAAMkI,IAAMlF,KAASuoB,EAAM,WAAW;AAEtC,SACE,gBAAApsB;AAAA,IAAC2yB;AAAA,IAAA;AAAA,MACC,OAAAvG;AAAA,MACA,OAAAvoB;AAAA,MACA,UAAAgI;AAAA,MACA,UAAAF;AAAA,MACA,OAAA+D;AAAA,MACA,KAAA2c;AAAA,MAEA,UAAA,gBAAArsB;AAAA,QAACqT;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,gBAAgB;AAAA,UAChB,cAAY3D;AAAA,UACZ,UAAU/D;AAAA,UACV,OAfU,OAAO5C,KAAQ,WAAWA,IAAM;AAAA,UAgB1C,aAAY;AAAA,UACZ,SAAS2qB,EAAO,IAAI,CAACxzB,OAAO,EAAE,OAAOA,EAAE,MAAM,OAAO,GAAGA,EAAE,IAAI,KAAKA,EAAE,IAAI,MAAM;AAAA,UAC9E,UAAU,CAACyE,MAASkH,EAASugB,EAAM,KAAKznB,CAAI;AAAA,QAAA;AAAA,MAAA;AAAA,IAC9C;AAAA,EAAA;AAGN;AAKO,MAAMivB,KAAiB,IAExBC,KAAwB,KACxBC,KAAgB;AAGf,SAASC,GAAiBxyB,GAAwD;AACvF,MAAI2G,IAAO;AACX,MAAI3G,EAAM,UAAU,QAAW;AAC7B,QAAI;AACF,MAAA2G,IAAO,OAAO3G,EAAM,SAAU,WAAWA,EAAM,QAAQ,KAAK,UAAUA,EAAM,KAAK;AAAA,IACnF,QAAQ;AACN,MAAA2G,IAAO,OAAO3G,EAAM,KAAK;AAAA,IAC3B;AACA,IAAA2G,IAAOA,EAAK,QAAQ,QAAQ,GAAG,GAC3BA,EAAK,SAAS4rB,OAAe5rB,IAAO,GAAGA,EAAK,MAAM,GAAG4rB,KAAgB,CAAC,CAAC;AAAA,EAC7E;AACA,QAAMt8B,IACJ,OAAO+J,EAAM,aAAc,YAAYA,EAAM,UAAU,UAAU,KAC7D,WAAWA,EAAM,UAAU,MAAM,GAAG,EAAE,EAAE,QAAQ,KAAK,GAAG,CAAC,KACzD;AACN,SAAO,CAAC2G,GAAM1Q,CAAI,EAAE,OAAO,OAAO,EAAE,KAAK,KAAK;AAChD;AASA,SAASy7B,GAAc;AAAA,EACrB,OAAA7G;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAAgI;AAAA,EACA,UAAAF;AAAA,EACA,OAAA+D;AAAA,EACA,KAAA2c;AAAA,EACA,OAAA2H;AAAA,EACA,sBAAAzB;AAAA,EACA,SAAA1xB;AACF,GAWG;AACD,QAAM,CAACzD,GAAO62B,CAAQ,IAAIh1B,EAAS,EAAE,GAC/B,CAACwF,GAAMyvB,CAAO,IAAIj1B,EAAkD,EAAE,OAAO,CAAA,GAAI,GACjF,CAACk1B,GAASC,CAAU,IAAIn1B,EAAS,EAAI;AAC3C,EAAAC,GAAU,MAAM;AACd,UAAMm1B,IAAO,IAAI,gBAAA;AACjB,IAAAD,EAAW,EAAI;AACf,UAAME,IAASl3B,EAAM,KAAA,GACfm3B,IAAQ;AAAA,MACZ,MAAM;AACJ,gBAAQ,UACL;AAAA,UAAK,MACJhC,EAAqByB,GAAO;AAAA,YAC1B,SAAAnzB;AAAA,YACA,QAAQyzB,MAAW,KAAK,SAAYA;AAAA,YACpC,OAAOV;AAAA,YACP,QAAQS,EAAK;AAAA,UAAA,CACd;AAAA,QAAA,EAEF,KAAK,CAAC56B,MAAM;AACX,UAAI46B,EAAK,OAAO,YAChBH,EAAQz6B,KAAK,MAAM,QAAQA,EAAE,KAAK,IAAIA,IAAI,EAAE,OAAO,CAAA,GAAI,GACvD26B,EAAW,EAAK;AAAA,QAClB,CAAC,EACA,MAAM,MAAM;AACX,UAAIC,EAAK,OAAO,YAChBH,EAAQ,EAAE,OAAO,CAAA,GAAI,GACrBE,EAAW,EAAK;AAAA,QAClB,CAAC;AAAA,MACL;AAAA,MACAE,MAAW,KAAK,IAAIT;AAAA,IAAA;AAEtB,WAAO,MAAM;AACX,mBAAaU,CAAK,GAClBF,EAAK,MAAA;AAAA,IACP;AAAA,EACF,GAAG,CAAC9B,GAAsByB,GAAOnzB,GAASzD,CAAK,CAAC;AAChD,QAAM2L,IAAMlF,KAASuoB,EAAM,WAAW,IAChC3c,IAAU,OAAO1G,KAAQ,WAAWA,IAAM,IAC1CyrB,IAAQp3B,EAAM,KAAA;AACpB,SACE,gBAAA4C;AAAA,IAAC2yB;AAAA,IAAA;AAAA,MACC,OAAAvG;AAAA,MACA,OAAAvoB;AAAA,MACA,UAAAgI;AAAA,MACA,UAAAF;AAAA,MACA,OAAA+D;AAAA,MACA,KAAA2c;AAAA,MAEA,UAAA,gBAAArsB;AAAA,QAACqT;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,gBAAgB;AAAA,UAChB,cAAY3D;AAAA,UACZ,UAAU/D;AAAA,UACV,OAAO8D;AAAA,UACP,aAAY;AAAA,UACZ,SAAShL,EAAK,MAAM,IAAI,CAACpB,OAAO;AAAA,YAC9B,OAAOA,EAAE;AAAA,YACT,OAAOA,EAAE;AAAA,YACT,QAAQ0wB,GAAiB1wB,CAAC,KAAK;AAAA,UAAA,EAC/B;AAAA,UACF,eAAe4wB;AAAA,UACf,WACEE,IACI,eACAK,MAAU,KACR,uBAAuBA,CAAK,gCAC5B;AAAA,UAER,QAAQ/vB,EAAK,OAAO,yCAAyC;AAAA,UAC7D,UAAU,CAACE,MAASkH,EAASugB,EAAM,KAAKznB,CAAI;AAAA,QAAA;AAAA,MAAA;AAAA,IAC9C;AAAA,EAAA;AAGN;AA4BA,SAASguB,GAAQ;AAAA,EACf,OAAAvG;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAAgI;AAAA,EACA,UAAAF;AAAA,EACA,OAAA+D;AAAA,EACA,KAAA2c;AAAA,EACA,MAAAoI;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,WAAAhC;AAAA,EACA,UAAApyB;AACF,GAiBG;;AASD,QAAMq0B,IAAKre,GAAgBzS,CAAK,GAI1Bkf,IAAYqJ,EAAM,SAAS,UAAU,CAAC,GAAC5yB,IAAA4yB,EAAM,WAAN,QAAA5yB,EAAc,YACrD,CAAC0wB,GAAWC,CAAY,IAAIlrB,EAAS,EAAK,GAG1CutB,IAAc5C,GAAA,GAiBdgL,IAASF,MAAY,YAAY,CAACC,GAClCrvB,IACJ,gBAAAQ,EAAAwB,IAAA,EACE,UAAA;AAAA,IAAA,gBAAAtH,EAAC,OAAA,EAAI,WAAW40B,IAAS,kBAAkB,cAAcD,IAAK,WAAW,EAAE,IACxE,UAAAA;AAAA;AAAA;AAAA;AAAA,MAIC,gBAAA30B;AAAA,QAAC6pB;AAAA,QAAA;AAAA,UACC,OAAAhmB;AAAA,UACA,WAAAkf;AAAA,UACA,UAAApX;AAAA,UACA,cAAY+D;AAAA,UACZ,UAAU,CAAC/K,MAASkH,EAASugB,EAAM,KAAKznB,CAAI;AAAA,QAAA;AAAA,MAAA;AAAA,QAG9C,gBAAAmB,EAAAwB,IAAA,EACG,UAAA;AAAA,MAAAhH;AAAA,MACA,CAACqL,KACA,gBAAA3L;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAM;AAAA,UACN,cAAY,yBAAyB0P,CAAK;AAAA,UAC1C,SAAS,MAAMya,EAAa,EAAI;AAAA,UACjC,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAMFyK,KACC,gBAAA9uB,EAAC,SAAA,EAAM,WAAU,uBAAsB,SAAS4sB,GAC7C,UAAA;AAAA,QAAAhjB;AAAA,QACA2c;AAAA,MAAA,EAAA,CACH;AAAA,IAAA,EAAA,CAEJ,EAAA,CAEJ;AAAA,IACCnC;AAAA;AAAA;AAAA,IAIC,gBAAAlqB;AAAA,MAAC6iB;AAAA,MAAA;AAAA,QACC,OAAAhf;AAAA,QACA,WAAAkf;AAAA,QACA,SAASyJ;AAAA,QACT,YAAY9c;AAAA,QACZ,QAAQ,CAAC/K,MAASkH,EAASugB,EAAM,KAAKznB,CAAI;AAAA,QAC1C,SAAS,MAAMwlB,EAAa,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EACnC,GAEJ;AAIF,SAAIsK,IAAanvB,IAGf,gBAAAQ,EAAC,OAAA,EAAI,WAAU,aAGZ,UAAA;AAAA,IAAA,CAAC8uB,uBACC,QAAA,EACE,UAAA;AAAA,MAAAllB;AAAA,MACA2c;AAAA,IAAA,GACH;AAAA,IAED/mB;AAAA,IACA8mB,EAAM,QAAQ,gBAAApsB,EAAC,UAAK,WAAU,YAAY,YAAM,KAAA,CAAK;AAAA,EAAA,GACxD;AAEJ;AAOA,SAASgyB,GAAe;AAAA,EACtB,OAAA5F;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAAgI;AAAA,EACA,UAAAF;AAAA,EACA,eAAAkpB;AAAA,EACA,kBAAAC;AACF,GAOG;AAID,QAAMC,IAAWtS,GAAc5e,CAAK,KAAK,IACnCmxB,IAAQD,MAAa,IACrBE,IAAOpxB,KAASuoB,EAAM,SAGtB,CAAClkB,GAAM+L,CAAO,IAAIhV;AAAA,IAAS,MAC/B+1B,KAASC,MAAS,SAAY,KAAK,KAAK,UAAUA,GAAM,MAAM,CAAC;AAAA,EAAA,GAE3D,CAACC,GAASC,CAAU,IAAIl2B,EAAS,EAAK,GACtC,CAAC6lB,GAAUC,CAAW,IAAI9lB,EAAS,EAAK,GACxC,CAACqtB,GAAYC,CAAa,IAAIttB,EAAS,EAAK,GAC5CutB,IAAc5C,GAAA,GACdwL,IAAW5I,EAAY,SAAS,CAAA;AAQtC,EAAAttB,GAAU,MAAM;AACd,QAAI81B,EAAO;AACX,QAAIvlB;AACJ,QAAI;AACF,MAAAA,IAAUvH,EAAK,WAAW,KAAK,SAAY,KAAK,MAAMA,CAAI;AAAA,IAC5D,QAAQ;AACN,MAAAuH,IAAU;AAAA,IACZ;AACA,IAAI,KAAK,UAAUA,CAAO,MAAM,KAAK,UAAUwlB,CAAI,MACjDhhB,EAAQghB,MAAS,SAAY,KAAK,KAAK,UAAUA,GAAM,MAAM,CAAC,CAAC,GAC/DE,EAAW,EAAK;AAAA,EAEpB,GAAG,CAACF,GAAM7I,EAAM,KAAK4I,CAAK,CAAC;AAE3B,QAAMK,IAAS,CAAC1wB,MAAiB;AAC/B,IAAAsP,EAAQtP,CAAI;AAAA,EACd,GACM2wB,IAAU,CAAC9iB,MAAoB;AACnC,IAAA2iB,EAAW,EAAK,GAChBL,KAAA,QAAAA,EAAmB,KACnBjpB,EAASugB,EAAM,KAAK5Z,CAAM;AAAA,EAC5B,GAGM+iB,IAAa,CAAC,EAAE,OAAAC,GAAO,OAAAxY,QAAgD;AAE3E,QADA8X,KAAA,QAAAA,EAAmBU,KAASxY,MAAU,UAClC,CAACwY,KAASxY,MAAU,SAAS;AAC/B,MAAAmY,EAAW,EAAK,GAChBtpB,EAASugB,EAAM,KAAK,MAAS;AAC7B;AAAA,IACF;AACA,IAAA+I,EAAW,CAACK,CAAK;AAAA,EACnB,GAIMC,IAAgB,MAAM;AAC1B,UAAMC,IAAUlT,GAAeta,CAAI;AACnC,IAAKwtB,MACLP,EAAW,EAAK,GAChBtpB,EAASugB,EAAM,KAAKsJ,CAAO;AAAA,EAC7B,GACMhmB,IAAQ0c,EAAM,SAASA,EAAM,KAI7BuJ,IAAQ,MAAM;AAClB,QAAIC;AACJ,QAAI;AACF,MAAAA,IAAW1tB,EAAK,WAAW,KAAK,SAAY,KAAK,MAAMA,CAAI;AAAA,IAC7D,QAAQ;AACN,MAAA0tB,IAAW;AAAA,IACb;AACA,IAAA/pB,EAASugB,EAAM,KAAKwJ,CAAQ;AAAA,EAC9B;AAEA,SACE,gBAAA9vB,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,sBACd,UAAA;AAAA,MAAA,gBAAAA,EAAC,QAAA,EACE,UAAA;AAAA,QAAA4J;AAAA,QACA0c,EAAM,WAAW,OAAO;AAAA,MAAA,GAC3B;AAAA,MACCyI;AAAA,MACA,CAACG,KACA,gBAAAh1B;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAM;AAAA,UACN,cAAY,QAAQ0P,CAAK;AAAA,UACzB,SAAS,MAAMqV,EAAY,EAAI;AAAA,UAI/B,UAAA,gBAAA/kB,EAACgQ,IAAA,EAAK,MAAK,YAAW,MAAM,GAAA,CAAI;AAAA,QAAA;AAAA,MAAA;AAAA,IAClC,GAEJ;AAAA,IAGCglB;AAAA;AAAA;AAAA;AAAA,MAIC,gBAAAh1B,EAAC,OAAA,EAAI,WAAU,sCACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,YACb,UAAA,gBAAA8F,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,QAAA,gBAAA9F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAW,kBAAkB2L,IAAW,iBAAiB,EAAE;AAAA,YAC3D,eAAY;AAAA,YAEZ,UAAA,gBAAA7F;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,aAAU;AAAA,gBACV,YAAUivB;AAAA,gBACV,OAAO,aAAaA,CAAQ;AAAA,gBAE5B,UAAA;AAAA,kBAAA,gBAAA/0B,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,KAAC;AAAA,oCACtC,QAAA,EAAK,WAAU,uBAAuB,UAAA8d,GAASiX,CAAQ,GAAE;AAAA,kBACzD,CAACppB,KACA,gBAAA3L;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,MAAK;AAAA,sBACL,WAAU;AAAA,sBACV,cAAY,6BAA6B0P,CAAK;AAAA,sBAE9C,OAAO,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,UAAA;AAAA,sBACtC,SAASimB;AAAA,sBACV,UAAA;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAED;AAAA,cAAA;AAAA,YAAA;AAAA,UAEJ;AAAA,QAAA;AAAA,QAED,CAAChqB,KACA,gBAAA3L;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,OAAM;AAAA,YACN,cAAY,uBAAuB0P,CAAK;AAAA,YACxC,SAAS,MAAM6c,EAAc,EAAI;AAAA,YAClC,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,EAAA,CAEJ,GACF,EAAA,CACF;AAAA,QAEA,gBAAAvsB;AAAA,MAACgS;AAAA,MAAA;AAAA,QACC,OAAO9J;AAAA,QACP,UAAUmtB;AAAA,QACV,QAAQI;AAAA,QACR,UAAA9pB;AAAA,QACA,WAAU;AAAA,QACV,WAAU;AAAA,QACV,cAAY,GAAGygB,EAAM,GAAG;AAAA,QACxB,eAAekJ;AAAA,QACf,kBAAkBC;AAAA,QAClB,SACE5pB,IAAW,SACT,gBAAA3L;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,OAAM;AAAA,YACN,cAAY,yBAAyB0P,CAAK;AAAA,YAC1C,SAAS,MAAM6c,EAAc,EAAI;AAAA,YAClC,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED;AAAA,IAAA;AAAA,IAKPD,KACC,gBAAAtsB;AAAA,MAAC6iB;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAO;AAAA,QACP,WAAWhf;AAAA,QACX,SAAS2oB;AAAA,QACT,YAAY9c;AAAA,QACZ,OAAO0c,EAAM;AAAA,QACb,YAAY,CAACznB,MAASkH,EAASugB,EAAM,KAAKznB,CAAI;AAAA,QAC9C,SAAS,MAAM4nB,EAAc,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,IAGrC,CAACyI,KAASE,KACT,gBAAAl1B,EAAC,QAAA,EAAK,WAAU,YAAW,OAAO,EAAE,OAAO,oBAAA,GAAuB,UAAA,eAAA,CAElE;AAAA,IAIDosB,EAAM,SAAS,CAAC4I,KAAS,CAACrpB,KAAYypB,EAAS,SAAS,KACvD,gBAAAtvB,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,qBAAiB;AAAA,MACtDo1B,EAAS,IAAI,CAACl1B,MACb,gBAAAF;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAO,QAAQ0P,CAAK,gBAAgBxP,EAAE,EAAE;AAAA,UACxC,SAAS,MAAM2L,EAASugB,EAAM,KAAK,YAAYlsB,EAAE,EAAE,YAAY;AAAA,UAE/D,UAAA,gBAAAF,EAAC,QAAA,EAAM,UAAAE,EAAE,GAAA,CAAG;AAAA,QAAA;AAAA,QANPA,EAAE;AAAA,MAAA,CAQV;AAAA,IAAA,GACH;AAAA,IAEDksB,EAAM,QAAQ,gBAAApsB,EAAC,UAAK,WAAU,YAAY,YAAM,MAAK;AAAA,IAErD8kB,KAAY,CAACkQ,KACZ,gBAAAlvB;AAAA,MAACsV;AAAA,MAAA;AAAA,QACC,OAAO1L;AAAA,QACP,UAAU,gBAAA1P,EAAC,QAAA,EAAK,UAAA,OAAA,CAAI;AAAA,QACpB,MAAK;AAAA,QACL,SAAS,MAAM+kB,EAAY,EAAK;AAAA,QAEhC,UAAA;AAAA,UAAA,gBAAA/kB,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA,gBAAAA;AAAA,YAACgS;AAAA,YAAA;AAAA,cACC,OAAO9J;AAAA,cACP,UAAUmtB;AAAA,cACV,UAAA1pB;AAAA,cACA,QAAO;AAAA,cACP,WAAU;AAAA,cACV,cAAY,GAAGygB,EAAM,GAAG;AAAA,cACxB,eAAekJ;AAAA,cACf,kBAAkBC;AAAA,YAAA;AAAA,UAAA,GAEtB;AAAA,UACCL,KACC,gBAAAl1B,EAAC,QAAA,EAAK,WAAU,YAAW,OAAO,EAAE,OAAO,uBAAuB,UAAA,eAAA,CAElE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAEJ,GAEJ;AAEJ;AASA,SAASmzB,GAAiB;AAAA,EACxB,OAAA/G;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAAgI;AAAA,EACA,UAAAF;AACF,GAKG;;AACD,QAAMqF,IAAU,MAAM,QAAQob,EAAM,OAAO,IAAIA,EAAM,UAAU,CAAA,GACzDyJ,MAAMr8B,IAAA4yB,EAAM,WAAN,gBAAA5yB,EAAc,iBAAgB,OACpCiW,IAAU5L,KAASuoB,EAAM,SACzB/0B,IAAmC,MAAM,QAAQoY,CAAO,IACzDA,IACDomB,KAAO,OAAOpmB,KAAY,WACxBA,EACG,MAAM,GAAG,EACT,IAAI,CAAC1U,MAAMA,EAAE,KAAA,CAAM,EACnB,OAAO,OAAO,IACjB,CAAA,GACA+6B,IAAe,IAAI,IAAIz+B,EAAS,IAAI,MAAM,CAAC,GAC3C0+B,IAAY/kB,EAAQ,OAAO,CAACiC,MAAM,CAAC6iB,EAAa,IAAI,OAAO7iB,EAAE,KAAK,CAAC,CAAC,GACpE+iB,IAAW,CAACj7B,MAAA;;AAChB,aAAAvB,IAAAwX,EAAQ,KAAK,CAACiC,MAAM,OAAOA,EAAE,KAAK,MAAM,OAAOlY,CAAC,CAAC,MAAjD,gBAAAvB,EAAoD,UAAS,OAAOuB,CAAC;AAAA,KACjE20B,IAAS,CAAC/qB,MAAiCkH,EAASugB,EAAM,KAAKyJ,IAAMlxB,EAAK,KAAK,GAAG,IAAIA,CAAI,GAE1FsxB,IAAM,CAACltB,MAAgB;AAC3B,QAAI,CAACA,KAAO+sB,EAAa,IAAI/sB,CAAG,EAAG;AACnC,UAAMmtB,IAAMllB,EAAQ,KAAK,CAACiC,MAAM,OAAOA,EAAE,KAAK,MAAMlK,CAAG;AACvD,IAAA2mB,EAAO,CAAC,GAAGr4B,GAAU6+B,IAAMA,EAAI,QAAQntB,CAAG,CAAC;AAAA,EAC7C,GACMotB,IAAS,CAACp7B,MAAuB20B,EAAOr4B,EAAS,OAAO,CAAC,MAAM,OAAO,CAAC,MAAM,OAAO0D,CAAC,CAAC,CAAC,GAEvFuY,IACJ,OAAO8Y,EAAM,eAAgB,YAAYA,EAAM,cAAcA,EAAM,cAAc,WAC7E1c,IAAQ0c,EAAM,SAASA,EAAM,KAC7BC,IAAMD,EAAM,WAAW,OAAO;AAEpC,SACE,gBAAApsB;AAAA,IAAC2yB;AAAA,IAAA;AAAA,MACC,OAAAvG;AAAA,MACA,OAAAvoB;AAAA,MACA,UAAAgI;AAAA,MACA,UAAAF;AAAA,MACA,OAAA+D;AAAA,MACA,KAAA2c;AAAA,MAEC,YAAM,OAAO,eACZ,gBAAAvmB,EAAC,OAAA,EAAI,WAAU,sCACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,uBAAuB,UAAA;AAAA,YAAAzO,EAAS;AAAA,YAAO;AAAA,UAAA,GAAS;AAAA,UAC/D,CAACsU,KACA,gBAAA7F,EAAAwB,IAAA,EACE,UAAA;AAAA,YAAA,gBAAAtH;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,UAAU+1B,EAAU,WAAW;AAAA,gBAC/B,SAAS,MAAMrG,EAAO,CAAC,GAAGr4B,GAAU,GAAG0+B,EAAU,IAAI,CAACK,MAAWA,EAAO,KAAK,CAAC,CAAC;AAAA,gBAChF,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAGD,gBAAAp2B;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,UAAU3I,EAAS,WAAW;AAAA,gBAC9B,SAAS,MAAMq4B,EAAO,EAAE;AAAA,gBACzB,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UAED,EAAA,CACF;AAAA,QAAA,GAEJ;AAAA,QACA,gBAAA1vB,EAAC,YAAA,EAAS,WAAU,kCAAiC,cAAY0P,GAC9D,UAAA;AAAA,UACC,GAAGsB;AAAA,UACH,GAAG3Z,EACA,OAAO,CAAC0D,MAAM,CAACiW,EAAQ,KAAK,CAACiC,MAAM,OAAOA,EAAE,KAAK,MAAM,OAAOlY,CAAC,CAAC,CAAC,EACjE,IAAI,CAACA,OAAO,EAAE,OAAOA,GAAG,OAAO,OAAOA,CAAC,IAAI;AAAA,QAAA,EAC9C,IAAI,CAACq7B,MACL,gBAAAtwB,EAAC,SAAA,EAAiC,WAAU,yBAC1C,UAAA;AAAA,UAAA,gBAAA9F;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS81B,EAAa,IAAI,OAAOM,EAAO,KAAK,CAAC;AAAA,cAC9C,UAAUzqB;AAAA,cACV,UAAU,CAACoF,MACTA,EAAM,OAAO,UAAUklB,EAAI,OAAOG,EAAO,KAAK,CAAC,IAAID,EAAOC,EAAO,KAAK;AAAA,YAAA;AAAA,UAAA;AAAA,UAG1E,gBAAAp2B,EAAC,QAAA,EAAM,UAAAo2B,EAAO,MAAA,CAAM;AAAA,QAAA,EAAA,GATV,OAAOA,EAAO,KAAK,CAU/B,CACD,EAAA,CACH;AAAA,MAAA,EAAA,CACF,4BAME,UAAA,gBAAAtwB,EAAC,OAAA,EAAI,WAAW,kBAAkB6F,IAAW,iBAAiB,EAAE,IAC7D,UAAA;AAAA,QAAAtU,EAAS,IAAI,CAAC0D,MACb,gBAAA+K,EAAC,QAAA,EAAK,WAAU,YACb,UAAA;AAAA,UAAAkwB,EAASj7B,CAAC;AAAA,UACV,CAAC4Q,KACA,gBAAA3L;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,cAAY,UAAUg2B,EAASj7B,CAAC,CAAC;AAAA,cACjC,OAAM;AAAA,cACN,SAAS,MAAMo7B,EAAOp7B,CAAC;AAAA,cACxB,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAED,KAX4B,OAAOA,CAAC,CAaxC,CACD;AAAA,QACA,CAAC4Q;AAAA;AAAA,QAGA,gBAAA7F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAM;AAAA,YACN,UAAUiwB,EAAU,WAAW;AAAA,YAC/B,cAAY,UAAU3J,EAAM,SAASA,EAAM,GAAG;AAAA,YAC9C,UAAU,CAAC/oB,MAAM4yB,EAAI5yB,EAAE,OAAO,KAAK;AAAA,YAEnC,UAAA;AAAA,cAAA,gBAAArD,EAAC,UAAA,EAAO,OAAM,IACX,UAAA+1B,EAAU,SAAS,IAChB1+B,EAAS,SACP,cACAic,IACF,eAAA,CACN;AAAA,cACCyiB,EAAU,IAAI,CAAC9iB,MACd,gBAAAjT,EAAC,YAA6B,OAAO,OAAOiT,EAAE,KAAK,GAChD,UAAAA,EAAE,MAAA,GADQ,OAAOA,EAAE,KAAK,CAE3B,CACD;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACH,EAAA,CAEJ,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAIR;AAGA,SAASojB,GAAe;AAAA,EACtB,OAAA3X;AAAA,EACA,OAAA7a;AAAA,EACA,UAAAgI;AAAA,EACA,UAAAF;AACF,GAKG;;AACD,QAAM2qB,IAAK5X,EAAM,eAAeA,EAAM,SAASA,EAAM;AACrD,MAAI,MAAM,QAAQA,EAAM,OAAO,KAAKA,EAAM,QAAQ,SAAS;AACzD,WACE,gBAAA1e;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,OAAO6D,KAAS6a,EAAM,aAAWllB,IAAAklB,EAAM,QAAQ,CAAC,MAAf,gBAAAllB,EAAkB,UAAS,EAAE;AAAA,QACrE,UAAUmS;AAAA,QACV,cAAY+S,EAAM,SAASA,EAAM;AAAA,QACjC,UAAU,CAACrb,MAAMwI,EAASxI,EAAE,OAAO,KAAK;AAAA,QAEvC,YAAM,QAAQ,IAAI,CAAC4P,MAClB,gBAAAjT,EAAC,YAA6B,OAAO,OAAOiT,EAAE,KAAK,GAChD,UAAAA,EAAE,MAAA,GADQ,OAAOA,EAAE,KAAK,CAE3B,CACD;AAAA,MAAA;AAAA,IAAA;AAIP,MAAIyL,EAAM,SAAS;AACjB,WACE,gBAAA5Y,EAAC,WAAM,WAAU,mBAAkB,OAAO4Y,EAAM,SAASA,EAAM,KAC7D,UAAA;AAAA,MAAA,gBAAA1e;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,GAAQ6D,KAAS6a,EAAM,WAAW;AAAA,UAC3C,UAAU/S;AAAA,UACV,cAAY+S,EAAM,SAASA,EAAM;AAAA,UACjC,UAAU,CAACrb,MAAMwI,EAASxI,EAAE,OAAO,OAAO;AAAA,QAAA;AAAA,MAAA;AAAA,MAE5C,gBAAArD,EAAC,QAAA,EAAM,UAAA0e,EAAM,SAASA,EAAM,IAAA,CAAI;AAAA,IAAA,GAClC;AAGJ,QAAM4U,IAAW5U,EAAM,SAAS;AAChC,SACE,gBAAA1e;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,MAAMszB,IAAW,WAAW;AAAA,MAC5B,OAAO,OAAOzvB,KAAS6a,EAAM,WAAW,EAAE;AAAA,MAC1C,aAAa4X;AAAA,MACb,cAAY5X,EAAM,SAASA,EAAM;AAAA,MACjC,UAAA/S;AAAA,MACA,UAAU,CAACtI,MAAMwI,EAASynB,IAAW,OAAOjwB,EAAE,OAAO,KAAK,IAAIA,EAAE,OAAO,KAAK;AAAA,IAAA;AAAA,EAAA;AAGlF;AAOA,SAAS6uB,GAAW;AAAA,EAClB,OAAA9F;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAAgI;AAAA,EACA,UAAAF;AACF,GAKG;AACD,QAAM0W,IAAO+J,EAAM,QAAQ,EAAE,MAAM,SAAA,GAC7BmK,IAAWlU,EAAK,SAAS,UACzBmU,IAAmB,MAAM,QAAQ3yB,CAAK,IACxCA,IACA,MAAM,QAAQuoB,EAAM,OAAO,IACxBA,EAAM,UACP,CAAA,GACAsD,IAAS,CAAC/qB,MAAoBkH,EAASugB,EAAM,KAAKznB,CAAI,GACtD8xB,IAAQ,MACZF,IACI,OAAO,aAAalU,EAAK,UAAU,CAAA,GAAI,IAAI,CAAC5D,MAAM,CAACA,EAAE,KAAKA,EAAE,WAAW,EAAE,CAAC,CAAC,IAC3E4D,EAAK,SAAS,WACZ,IACA,IACFqU,IAAU,CAACC,GAAahyB,MAC5B+qB,EAAO8G,EAAM,IAAI,CAACI,GAAIvL,MAAOA,MAAMsL,IAAMhyB,IAAOiyB,CAAG,CAAC;AAEtD,SACE,gBAAA9wB,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,QAAA,EACE,UAAA;AAAA,MAAAsmB,EAAM,SAASA,EAAM;AAAA,MACrBA,EAAM,WAAW,OAAO;AAAA,IAAA,GAC3B;AAAA,IACA,gBAAAtmB,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,MAAA0wB,EAAM,WAAW,KAAK,gBAAAx2B,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,6BAAyB;AAAA,MAClFw2B,EAAM,IAAI,CAACI,GAAID;AAAA;AAAA,QAEd,gBAAA7wB,EAAC,OAAA,EAAI,WAAU,iBACZ,UAAA;AAAA,UAAAywB,IACC,gBAAAv2B,EAAC,OAAA,EAAI,WAAU,mBACX,WAAAqiB,EAAK,UAAU,CAAA,GAAI,IAAI,CAAC,MACxB,gBAAAriB;AAAA,YAACq2B;AAAA,YAAA;AAAA,cAEC,OAAO;AAAA,cACP,OAAQO,KAAA,gBAAAA,EAAiC,EAAE;AAAA,cAC3C,UAAAjrB;AAAA,cACA,UAAU,CAACkrB,MACTH,EAAQC,GAAK,EAAE,GAAKC,KAAkC,IAAK,CAAC,EAAE,GAAG,GAAGC,GAAI;AAAA,YAAA;AAAA,YALrE,EAAE;AAAA,UAAA,CAQV,GACH,IAEA,gBAAA72B;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,MAAMqiB,EAAK,SAAS,WAAW,WAAW;AAAA,cAC1C,OAAO,OAAOuU,KAAM,EAAE;AAAA,cACtB,aAAavU,EAAK;AAAA,cAClB,UAAA1W;AAAA,cACA,UAAU,CAACtI,MACTqzB,EAAQC,GAAKtU,EAAK,SAAS,WAAW,OAAOhf,EAAE,OAAO,KAAK,IAAIA,EAAE,OAAO,KAAK;AAAA,YAAA;AAAA,UAAA;AAAA,UAIlF,CAACsI,KACA,gBAAA3L;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,cAAW;AAAA,cACX,OAAM;AAAA,cACN,SAAS,MAAM0vB,EAAO8G,EAAM,OAAO,CAACM,GAAGzL,MAAMA,MAAMsL,CAAG,CAAC;AAAA,cACxD,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAED,EAAA,GApCgCA,CAsCpC;AAAA,OACD;AAAA,MACA,CAAChrB,KACA,gBAAA3L;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM0vB,EAAO,CAAC,GAAG8G,GAAOC,EAAA,CAAO,CAAC;AAAA,UAC1C,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,GAEJ;AAAA,IACCrK,EAAM,QAAQ,gBAAApsB,EAAC,UAAK,WAAU,YAAY,YAAM,KAAA,CAAK;AAAA,EAAA,GACxD;AAEJ;AAgBA,MAAM+2B,KAAoC,CAAC,UAAU,UAAU,WAAW,MAAM,GAC1EC,KAA6B,CAAA;AAG5B,SAASC,GAAYpzB,GAAgByZ,IAAsB,IAAsB;AACtF,SAAI,MAAM,QAAQzZ,CAAK,IACdA,EAAM,MAAM,CAAC9I,MAAMA,KAAK,OAAOA,KAAM,YAAY,OAAOA,EAAE,OAAQ,QAAQ,IAC5E8I,IACD,OAGJ,CAACA,KACD,OAAOA,KAAU,YACjByS,GAAgBzS,CAAK,KACrB4e,GAAc5e,CAAK,KACnB,WAAWA,IAEJ,OAEF,OAAO,QAAQA,CAAK,EAAE,IAAI,CAAC,CAAC0T,GAAK8K,CAAI,MAAM;AAChD,UAAM6U,IAAM5Z,EAAS,KAAK,CAAC5C,MAAQA,EAAI,QAAQnD,CAAG,GAC5C4f,IAAO,OAAO9U;AACpB,WAAO;AAAA,MACL,KAAA9K;AAAA,MACA,MACE2f,KAAO,KAAK,UAAUA,EAAI,KAAK,MAAM,KAAK,UAAU7U,CAAI,IACpD6U,EAAI,OACJC,MAAS,YAAYA,MAAS,YAAYA,MAAS,YACjDA,IACA;AAAA,MACR,OAAO9U;AAAA,IAAA;AAAA,EAEX,CAAC;AACH;AAGA,SAAS+U,GAAavzB,GAAyB;AAC7C,QAAM4W,IAAO,MAAM,QAAQ5W,CAAK,IAAIozB,GAAYpzB,CAAK,IAAI;AACzD,SACE,CAAC4W,KACDA,EAAK,KAAK,CAACC,MAAQ,CAACA,EAAI,GAAG,KAC3B,IAAI,IAAID,EAAK,IAAI,CAACC,MAAQA,EAAI,GAAG,CAAC,EAAE,SAASD,EAAK,SAE3C5W,IAEF,OAAO,YAAY4W,EAAK,IAAI,CAACC,MAAQ,CAACA,EAAI,KAAKA,EAAI,KAAK,CAAC,CAAC;AACnE;AAGA,SAAS2c,GAAeF,GAAuBpuB,GAAsB;AACnE,MAAIouB,MAAS,UAAU;AACrB,QAAIpuB,EAAI,WAAW,GAAI,QAAO;AAC9B,UAAM,IAAI,OAAOA,CAAG;AACpB,WAAO,OAAO,MAAM,CAAC,IAAIA,IAAM;AAAA,EACjC;AACA,MAAIouB,MAAS,UAAW,QAAOpuB,MAAQ;AACvC,MAAIouB,MAAS;AACX,QAAI;AACF,aAAO,KAAK,MAAMpuB,CAAG;AAAA,IACvB,QAAQ;AACN,aAAOA;AAAA,IACT;AAEF,SAAOA;AACT;AAGA,SAASuuB,GAAev8B,GAAoB;AAC1C,SAAuBA,KAAM,OAAa,KACtC,OAAOA,KAAM,WAAiB,KAAK,UAAUA,CAAC,IAC3C,OAAOA,CAAC;AACjB;AAKA,SAASm4B,GAAU;AAAA,EACjB,OAAA9G;AAAA,EACA,OAAAvoB;AAAA,EACA,UAAAgI;AAAA,EACA,UAAAF;AACF,GAKG;AACD,QAAMspB,IAAOpxB,KAASuoB,EAAM,WAAW4K,IACjC9T,IAAYzR,GAAQ,MAAM2lB,GAAanC,CAAI,GAAG,CAACA,CAAI,CAAC,GACpD,CAACl2B,GAAMC,CAAO,IAAIC;AAAA,IAA4B,MAClD,MAAM,QAAQg2B,CAAI,IAAI,WAAW;AAAA,EAAA,GAE7BsC,IAAez0B,GAAkB,EAAE,GACnC,CAAC00B,GAAaC,CAAc,IAAIx4B,EAAS,EAAK,GAC9C,CAACy4B,GAAWC,CAAY,IAAI14B,EAAwB,IAAI,GACxDwb,IAAOwc,GAAYhC,GAAMsC,EAAa,OAAO,GAC7Crf,IAAOuC,KAAQ,CAAA,GACfmd,IAAW74B,MAAS,UAAU0b,MAAS,MACvC/K,IAAQ0c,EAAM,SAASA,EAAM,KAC7BjN,IACJ,gBAAArZ,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,IAAA,gBAAA9F;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAW,mCAAoC43B,IAAuB,KAAZ,SAAc;AAAA,QACxE,cAAY,QAAQloB,CAAK;AAAA,QACzB,gBAAc,CAACkoB;AAAA,QACf,UAAUJ,KAAe,CAAC,CAACE,KAAajd,MAAS;AAAA,QACjD,OACEA,MAAS,OACL,wDACA;AAAA,QAEN,SAAS,MAAM;AACb,UAAI,CAAC9O,KAAY,CAAC,MAAM,QAAQspB,CAAI,KAAGppB,EAASugB,EAAM,KAAKlU,CAAI,GAC/DlZ,EAAQ,QAAQ;AAAA,QAClB;AAAA,QACD,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGD,gBAAAgB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAW,mCAAmC43B,IAAW,YAAY,EAAE;AAAA,QACvE,cAAY,QAAQloB,CAAK;AAAA,QACzB,gBAAckoB;AAAA,QACd,SAAS,MAAM;AACb,UAAAL,EAAa,UAAUrf,GACvBlZ,EAAQ,MAAM;AAAA,QAChB;AAAA,QACD,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAED,GACF;AAEF,MAAI44B;AACF,WACE,gBAAA9xB,EAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,MAAA,gBAAA9F;AAAA,QAACgyB;AAAA,QAAA;AAAA,UACC,OAAO;AAAA,YACL,GAAG5F;AAAA,YACH,MAAM;AAAA,YACN,OAAO;AAAA,YACP,SAAS,CAAA;AAAA,YACT,MAAM;AAAA,UAAA;AAAA,UAER,OAAOlJ;AAAA,UACP,UAAAvX;AAAA,UACA,eAAewT;AAAA,UACf,kBAAkB,CAACqW,MAAUiC,EAAe,CAACjC,CAAK;AAAA,UAClD,UAAU,CAACje,GAAK5S,MAAS;AACvB,gBACEA,MAAS,UACTsyB,GAAYtyB,CAAI,MAAM,QACtB,CAAC8d,GAAc9d,CAAI,KACnB,CAAC2R,GAAgB3R,CAAI,KACrB,EAAEA,KAAQ,OAAOA,KAAS,YAAY,WAAWA,IACjD;AACA,cAAAgzB,EAAa,mEAAmE;AAChF;AAAA,YACF;AACA,YAAAA,EAAa,IAAI,GACjBF,EAAe,EAAK,GACpB5rB,EAAS0L,GAAK5S,CAAI;AAAA,UACpB;AAAA,QAAA;AAAA,MAAA;AAAA,MAED+yB,KACC,gBAAA13B,EAAC,QAAA,EAAK,WAAU,8BAA6B,aAAU,UACpD,UAAA03B,EAAA,CACH;AAAA,IAAA,GAEJ;AAGJ,QAAMhI,IAAS,CAAC/qB,MAAoBkH,EAASugB,EAAM,KAAKznB,CAAI,GACtD6I,IAAQ,CAACkH,GAAWzX,MACxByyB,EAAOxX,EAAK,IAAI,CAACnd,GAAG47B,MAASA,MAAQjiB,IAAI,EAAE,GAAG3Z,GAAG,GAAGkC,EAAA,IAAMlC,CAAE,CAAC;AAE/D,SACE,gBAAA+K,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,sBACd,UAAA;AAAA,MAAA,gBAAAA,EAAC,QAAA,EACE,UAAA;AAAA,QAAA4J;AAAA,QACA0c,EAAM,WAAW,OAAO;AAAA,MAAA,GAC3B;AAAA,MACCjN;AAAA,IAAA,GACH;AAAA,IACA,gBAAArZ,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,MAAAoS,EAAK,WAAW,KACf,gBAAAlY,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,qCAAiC;AAAA,MAErEkY,EAAK,IAAI,CAACnd,GAAG2Z;AAAA;AAAA,QAEZ,gBAAA5O,EAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,UAAA,gBAAA9F;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,aAAY;AAAA,cACZ,OAAOjF,EAAE;AAAA,cACT,UAAA4Q;AAAA,cACA,UAAU,CAACtI,MAAMmK,EAAMkH,GAAG,EAAE,KAAKrR,EAAE,OAAO,MAAA,CAAO;AAAA,YAAA;AAAA,UAAA;AAAA,UAEnD,gBAAArD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAOjF,EAAE;AAAA,cACT,UAAU4Q;AAAA,cACV,UAAU,CAACtI,MAAM;AACf,sBAAM8zB,IAAO9zB,EAAE,OAAO;AACtB,gBAAAmK,EAAMkH,GAAG,EAAE,MAAAyiB,GAAM,OAAOE,GAAeF,GAAMG,GAAev8B,EAAE,KAAK,CAAC,EAAA,CAAG;AAAA,cACzE;AAAA,cAEC,UAAAg8B,GAAe,IAAI,CAACnyB,MACnB,gBAAA5E,EAAC,YAAe,OAAO4E,GACpB,UAAAA,EAAA,GADUA,CAEb,CACD;AAAA,YAAA;AAAA,UAAA;AAAA,UAQH,gBAAA5E;AAAA,YAAC2yB;AAAA,YAAA;AAAA,cACC,MAAI;AAAA,cACJ,OAAAvG;AAAA,cACA,OAAOrxB,EAAE;AAAA,cACT,UAAU,CAAC88B,GAAMlzB,MAAS6I,EAAMkH,GAAG,EAAE,OAAO/P,GAAM;AAAA,cAClD,UAAAgH;AAAA,cACA,OAAO5Q,EAAE,OAAO;AAAA,cAChB,KAAI;AAAA,cAEH,UAAAA,EAAE,SAAS,YACV,gBAAA+K;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,OAAO/K,EAAE,UAAU,KAAO,SAAS;AAAA,kBACnC,UAAU4Q;AAAA,kBACV,UAAU,CAACtI,MAAMmK,EAAMkH,GAAG,EAAE,OAAOrR,EAAE,OAAO,UAAU,QAAQ;AAAA,kBAE9D,UAAA;AAAA,oBAAA,gBAAArD,EAAC,UAAA,EAAO,OAAM,QAAO,UAAA,QAAI;AAAA,oBACzB,gBAAAA,EAAC,UAAA,EAAO,OAAM,SAAQ,UAAA,QAAA,CAAK;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA,IAG7B,gBAAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAMjF,EAAE,SAAS,WAAW,WAAW;AAAA,kBACvC,aAAY;AAAA,kBACZ,OAAOu8B,GAAev8B,EAAE,KAAK;AAAA,kBAC7B,UAAA4Q;AAAA,kBACA,UAAU,CAACtI,MAAMmK,EAAMkH,GAAG,EAAE,OAAO2iB,GAAet8B,EAAE,MAAMsI,EAAE,OAAO,KAAK,GAAG;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC7E;AAAA,UAAA;AAAA,UAGH,CAACsI,KACA,gBAAA3L;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,cAAY,mBAAmBjF,EAAE,OAAO2Z,IAAI,CAAC;AAAA,cAC7C,OAAM;AAAA,cACN,SAAS,MAAMgb,EAAOxX,EAAK,OAAO,CAAC4e,GAAGH,MAAQA,MAAQjiB,CAAC,CAAC;AAAA,cACzD,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAED,EAAA,GAjEkCA,CAmEtC;AAAA,OACD;AAAA,MACA,CAAC/I,KACA,gBAAA3L;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM0vB,EAAO,CAAC,GAAGxX,GAAM,EAAE,KAAK,IAAI,MAAM,UAAU,OAAO,GAAA,CAAI,CAAC;AAAA,UACxE,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,GAEJ;AAAA,IACCkU,EAAM,QAAQ,gBAAApsB,EAAC,UAAK,WAAU,YAAY,YAAM,KAAA,CAAK;AAAA,EAAA,GACxD;AAEJ;AC9nEA,MAAM83B,KAAS,CAACj0B,MACd,OAAOA,KAAU,YAAYA,MAAU,QAAQ,CAAC,MAAM,QAAQA,CAAK,GAExDk0B,KAAsB;AAAA,EACjC,CAAC,WAAW,SAAS;AAAA,EACrB,CAAC,YAAY,UAAU;AAAA,EACvB,CAAC,OAAO,QAAQ;AAAA,EAChB,CAAC,OAAO,gBAAgB;AAAA,EACxB,CAAC,KAAK,cAAc;AAAA,EACpB,CAAC,MAAM,UAAU;AAAA,EACjB,CAAC,KAAK,WAAW;AAAA,EACjB,CAAC,MAAM,SAAS;AAAA,EAChB,CAAC,MAAM,IAAI;AAAA,EACX,CAAC,YAAY,gBAAgB;AAAA,EAC7B,CAAC,eAAe,wBAAwB;AAAA,EACxC,CAAC,eAAe,wBAAwB;AAC1C,GAEaC,KAAmD;AAAA,EAC9D,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,eACE;AAAA,EACF,eAAe;AACjB,GACMC,KAAY,IAAI,IAAYF,GAAoB,IAAI,CAAC,CAACG,CAAE,MAAMA,CAAE,CAAC,GACjEC,KAAyC;AAAA,EAC7C,GAAG,OAAO,YAAYJ,EAAmB;AAAA,EACzC,MAAM;AAAA,EACN,MAAM;AAAA,EACN,IAAI;AACN;AAGO,SAASK,GAAuBF,GAAoB;AACzD,SAAIA,EAAG,WAAW,MAAM,IAAU,QAAQC,GAAeD,EAAG,MAAM,CAAC,CAAC,KAAKA,EAAG,MAAM,CAAC,CAAC,MAC7EC,GAAeD,CAAE,KAAKA;AAC/B;AAgBO,MAAMG,KAAwB;AAAA,EACnC,CAAC,OAAO,cAAc;AAAA,EACtB,CAAC,MAAM,aAAa;AAAA,EACpB,CAAC,OAAO,sBAAsB;AAChC,GACMC,KAA2C,OAAO,YAAYD,EAAqB;AAGlF,SAASE,GAAyBC,GAA4B;AACnE,SAAOF,GAAiBE,CAAU,KAAKA;AACzC;AAQA,SAASC,GAAaC,GAAgBC,IAAgB,IAAuC;AAC3F,MAAI,CAACb,GAAOY,CAAK,EAAG;AACpB,QAAME,IAAU,OAAO,QAAQF,CAAK;AACpC,MAAIE,EAAQ,WAAW,EAAG;AAC1B,QAAM,CAACC,GAAUC,CAAI,IAAIF,EAAQ,CAAC;AAClC,MAAID,KAAiBE,MAAa,OAAO,MAAM,QAAQC,CAAI,KAAKA,EAAK,WAAW,GAAG;AACjF,UAAMC,IAAQN,GAAaK,EAAK,CAAC,GAAG,EAAK;AAEzC,WAAI,CAACC,KAASA,EAAM,UAAS,SACtB,EAAE,GAAGA,GAAO,SAAS,GAAA;AAAA,EAC9B;AACA,MAAI,GAACd,GAAU,IAAIY,CAAQ,KAAK,CAAC,MAAM,QAAQC,CAAI,KAAKA,EAAK,WAAW,IACxE;AAAA,QAAID,MAAa,SAAS,OAAOC,EAAK,CAAC,KAAM;AAC3C,aAAO;AAAA,QACL,MAAMA,EAAK,CAAC;AAAA,QACZ,UAAUA,EAAK,CAAC,IAAI,YAAY;AAAA,QAChC,OAAOA,EAAK,CAAC;AAAA,MAAA;AAIjB,QAAI,EAAAD,MAAa,aAAaA,MAAa;AAC3C,aAAO,EAAE,MAAMC,EAAK,CAAC,GAAc,UAAAD,GAAU,OAAOC,EAAK,CAAC,EAAA;AAAA;AAC5D;AAGO,SAASE,GAAen1B,GAAiD;AAC9E,MAAI,GAACi0B,GAAOj0B,CAAK,KAAK,OAAO,KAAKA,CAAK,EAAE,WAAW;AACpD,WAAO40B,GAAa50B,EAAM,KAAK;AACjC;AAOO,SAASo1B,GAAmBp1B,GAA4C;AAC7E,QAAMq1B,IAASF,GAAen1B,CAAK;AACnC,MAAIq1B,UAAe,EAAE,YAAY,OAAO,MAAM,CAACA,CAAM,EAAA;AACrD,MAAI,CAACpB,GAAOj0B,CAAK,KAAK,OAAO,KAAKA,CAAK,EAAE,WAAW,KAAK,CAACi0B,GAAOj0B,EAAM,KAAK,EAAG;AAC/E,QAAM+0B,IAAU,OAAO,QAAQ/0B,EAAM,KAAK;AAC1C,MAAI+0B,EAAQ,WAAW,EAAG;AAC1B,QAAM,CAACJ,GAAYM,CAAI,IAAIF,EAAQ,CAAC;AACpC,MAAI,CAAC,OAAO,OAAON,IAAkBE,CAAU,KAAK,CAAC,MAAM,QAAQM,CAAI,KAAKA,EAAK,WAAW;AAC1F;AAEF,QAAMre,IAAOqe,EAAK,IAAI,CAACzqB,MAAQoqB,GAAapqB,CAAG,CAAC;AAChD,MAAI,CAAAoM,EAAK,KAAK,CAACC,MAAQA,MAAQ,MAAS;AACxC,WAAO;AAAA,MACL,YAAA8d;AAAA,MACA,MAAA/d;AAAA,IAAA;AAEJ;AAOO,SAAS0e,GAAoB5I,GAAgC;AAClE,QAAM9V,IAAO8V,EAAM,KAChB,OAAO,CAAC7V,MAAQA,EAAI,SAAS,EAAE,EAC/B,IAAI,CAACA,MAAQ;AACZ,UAAM0e,IACJ1e,EAAI,aAAa,aAAaA,EAAI,aAAa,aAC3C,EAAE,OAAO,CAACA,EAAI,MAAMA,EAAI,aAAa,SAAS,MAC9C,EAAE,CAACA,EAAI,QAAQ,GAAG,CAACA,EAAI,MAAMA,EAAI,KAAK,EAAA;AAC5C,WAAOA,EAAI,UAAU,EAAE,KAAK,CAAC0e,CAAU,MAAMA;AAAA,EAC/C,CAAC;AACH,SAAI3e,EAAK,WAAW,IAAU,KACvB,EAAE,OAAOA,EAAK,WAAW,IAAIA,EAAK,CAAC,IAAI,EAAE,CAAC8V,EAAM,UAAU,GAAG9V,IAAK;AAC3E;AAGO,SAAS4e,GAAsBx1B,GAAkD;AACtF,MAAI,OAAOA,KAAU;AACnB,QAAI;AACF,YAAM2O,IAAS,KAAK,MAAM3O,CAAK;AAC/B,UACE2O,MAAW,QACX,MAAM,QAAQA,CAAM,KACpB,CAAC,UAAU,UAAU,SAAS,EAAE,SAAS,OAAOA,CAAM;AAEtD,eAAOA;AAAA,IACX,QAAQ;AAAA,IAER;AAEF,QAAM2C,IACJ,OAAOtR,KAAU,WACb0S,GAAoB1S,CAAK,IACzBkR,GAAYlR,CAAK,IACfA,EAAM,QACN;AACR,MAAIsR,GAAO;AACT,UAAMmkB,IAAWnkB,EAAM,IAAI,CAACwD,MACtBA,EAAK,SAAS,SAAeA,EAAK,OAClCA,EAAK,SAAS,QAAc,EAAE,KAAKA,EAAK,IAAA,IACxCA,EAAK,SAAS,WAAiB,EAAE,KAAK,WAAWA,EAAK,GAAG,GAAA,IACtDA,EAAK,SAAS,EACtB;AACD,WAAO2gB,EAAS,WAAW,IAAIA,EAAS,CAAC,IAAI,EAAE,KAAKA,EAAA;AAAA,EACtD;AAEA,SAAOz1B;AACT;AAEO,SAAS01B,GAAqB11B,GAAwB;AAC3D,SAAI,OAAOA,KAAU,WAEZw1B,GAAsBx1B,CAAK,MAAMA,IAAQA,IAAQ,KAAK,UAAUA,CAAK,IAE1Ei0B,GAAOj0B,CAAK,IACV,OAAO,KAAKA,CAAK,EAAE,WAAW,KAAK,OAAOA,EAAM,OAAQ,WACnDyR,GAAkB,CAAC,EAAE,MAAM,OAAO,KAAKzR,EAAM,IAAA,CAAK,CAAC,IAErDyR,GAAkB,CAAC,EAAE,MAAM,QAAQ,MAAMzR,EAAA,CAAO,CAAC,IAEnD,KAAK,UAAUA,CAAK,KAAK;AAClC;AC9KA,MAAM21B,KAAiC;AAAA,EACrC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,OAAO;AACT,GACMC,KAA8B,EAAE,YAAY,OAAO,MAAM,CAACD,EAAS,EAAA,GACnEE,KAAO,CAACxiC,GAAYC,MAAe,KAAK,UAAUD,CAAC,MAAM,KAAK,UAAUC,CAAC;AAOxE,SAASwiC,GAAgB;AAAA,EAC9B,QAAApM;AAAA,EACA,UAAA1hB;AAAA,EACA,UAAAF;AAAA,EACA,SAAAiuB,IAAU;AACZ,GAKG;AACD,QAAM5oB,IAAU4Y,GAAA,GACViQ,IAAYtM,EAAO,cAAc,SAAY,KAAOA,EAAO,WAC3D/a,IAASymB,GAAmBY,CAAS,GACrC,CAACC,GAAUC,CAAW,IAAI96B,EAAS,EAAK,GAIxC,CAAC+6B,GAAOC,CAAQ,IAAIh7B,EAAyBuT,KAAUinB,EAAW,GAElES,IAAUp3B,GAAO,CAAC,GAClB,CAACsa,GAAM+c,CAAO,IAAIl7B,EAAmB,MAAM+6B,EAAM,KAAK,IAAI,MAAME,EAAQ,SAAS,CAAC,GAClFE,IAAS5nB,MAAW,UAAa,OAAOqnB,KAAc,WACtDtJ,IAAQmJ,GAAKP,GAAoBa,CAAK,GAAGH,CAAS,IAAIG,IAASxnB,KAAUinB,IACzEY,IAAU9J,EAAM,KAAK,IAAI,CAACuG,GAAGpiB,MAAM0I,EAAK1I,CAAC,KAAK,KAAKA,CAAC,GACpD4lB,IAAO,CAAC31B,GAAsB41B,IAAWF,MAAY;AACzD,IAAAJ,EAASt1B,CAAI,GACbw1B,EAAQI,CAAQ,GAChB1uB,EAAS,EAAE,GAAG0hB,GAAQ,WAAW4L,GAAoBx0B,CAAI,GAAG;AAAA,EAC9D,GACM61B,IAAY,CAACC,GAAejtB,MAChC8sB,EAAK;AAAA,IACH,GAAG/J;AAAA,IACH,MAAMA,EAAM,KAAK,IAAI,CAAC7V,GAAKhG,MAAOA,MAAM+lB,IAAQ,EAAE,GAAG/f,GAAK,GAAGlN,EAAA,IAAUkN,CAAI;AAAA,EAAA,CAC5E,GACGggB,IAAS,MACbJ,EAAK,EAAE,GAAG/J,GAAO,MAAM,CAAC,GAAGA,EAAM,MAAMiJ,EAAS,KAAK,CAAC,GAAGa,GAASH,EAAQ,SAAS,CAAC,GAChFS,IAAY,CAACF,MACjBH;AAAA,IACE,EAAE,GAAG/J,GAAO,MAAMA,EAAM,KAAK,OAAO,CAACuG,GAAGpiB,MAAMA,MAAM+lB,CAAK,EAAA;AAAA,IACzDJ,EAAQ,OAAO,CAACvD,GAAGpiB,MAAMA,MAAM+lB,CAAK;AAAA,EAAA,GAElCG,IAAWrK,EAAM,KAAK,SAAS;AACrC,SACE,gBAAAzqB,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAA;AAAA,IAAAg0B,KAAY,CAACM,IACZ,gBAAAp6B;AAAA,MAACgxB;AAAA,MAAA;AAAA,QACC,QAAQ;AAAA,UACN;AAAA,YACE,KAAK;AAAA,YACL,OAAO;AAAA,YACP,MAAM;AAAA,YACN,UAAU;AAAA,UAAA;AAAA,QACZ;AAAA,QAEF,QAAAzD;AAAA,QACA,UAAA1hB;AAAA,QACA,UAAAF;AAAA,MAAA;AAAA,IAAA,IAGF,gBAAA7F,EAAC,OAAA,EAAI,WAAU,sBACZ,UAAA;AAAA,MAAA80B,KACC,gBAAA56B;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,cAAW;AAAA,UACX,UAAU2L;AAAA,UACV,OAAO4kB,EAAM;AAAA,UACb,UAAU,CAACxf,MACTupB,EAAK;AAAA,YACH,GAAG/J;AAAA,YACH,YAAYxf,EAAM,OAAO;AAAA,UAAA,CAC1B;AAAA,UAGF,UAAAsnB,GAAsB,IAAI,CAAC,CAACG,GAAY9oB,CAAK,MAC5C,gBAAA1P,EAAC,UAAA,EAAwB,OAAOw4B,GAC7B,UAAA9oB,EAAA,GADU8oB,CAEb,CACD;AAAA,QAAA;AAAA,MAAA;AAAA,MAGJjI,EAAM,KAAK,IAAI,CAAC7V,GAAK+f,MAAU;AAC9B,cAAMI,IAAengB,EAAI,aAAa,aAAaA,EAAI,aAAa;AACpE,eACE,gBAAA5U;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAW,oBAAoB80B,IAAW,iCAAiC,EAAE,GAAGC,IAAe,+BAA+B,EAAE;AAAA,YAEhI,UAAA;AAAA,cAAA,gBAAA/0B,EAAC,SAAA,EAAM,WAAU,wBAAuB,OAAM,mCAC5C,UAAA;AAAA,gBAAA,gBAAA9F;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,cAAY,oBAAoBy6B,IAAQ,CAAC;AAAA,oBACzC,SAAS/f,EAAI,WAAW;AAAA,oBACxB,UAAU/O;AAAA,oBACV,UAAU,CAACoF,MAAUypB,EAAUC,GAAO,EAAE,SAAS1pB,EAAM,OAAO,QAAA,CAAS;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBACvE;AAAA,cAAA,GAEJ;AAAA,cACA,gBAAA/Q;AAAA,gBAAC6pB;AAAA,gBAAA;AAAA,kBACC,OAAO0P,GAAqB7e,EAAI,IAAI;AAAA,kBACpC,cAAW;AAAA,kBACX,aAAY;AAAA,kBACZ,UAAA/O;AAAA,kBACA,UAAU,CAAC9H,MAAU22B,EAAUC,GAAO,EAAE,MAAMpB,GAAsBx1B,CAAK,EAAA,CAAG;AAAA,gBAAA;AAAA,cAAA;AAAA,cAE9E,gBAAA7D;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,cAAW;AAAA,kBACX,OAAOg4B,GAAyBtd,EAAI,QAAQ;AAAA,kBAC5C,UAAU/O;AAAA,kBACV,OAAO+O,EAAI;AAAA,kBACX,UAAU,CAAC3J,MACTypB,EAAUC,GAAO;AAAA,oBACf,UAAU1pB,EAAM,OAAO;AAAA,oBACvB,OACEA,EAAM,OAAO,UAAU,YACnB,KACAA,EAAM,OAAO,UAAU,aACrB,KACA8pB,IACE,KACAngB,EAAI;AAAA,kBAAA,CACf;AAAA,kBAGF,aAAoB,IAAI,CAAC,CAACwd,GAAIxoB,CAAK,MAClC,gBAAA1P,EAAC,UAAA,EAAgB,OAAOk4B,GAAI,OAAOF,GAAyBE,CAAE,GAC3D,UAAAxoB,EAAA,GADUwoB,CAEb,CACD;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEF,CAAC2C,KACA,gBAAA76B;AAAA,gBAAC6pB;AAAA,gBAAA;AAAA,kBACC,OAAO0P,GAAqB7e,EAAI,KAAK;AAAA,kBACrC,cAAW;AAAA,kBACX,aAAY;AAAA,kBACZ,UAAA/O;AAAA,kBACA,UAAU,CAAC9H,MAAU22B,EAAUC,GAAO,EAAE,OAAOpB,GAAsBx1B,CAAK,EAAA,CAAG;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGhF+2B,KAAY,CAACjvB,KACZ,gBAAA3L;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,OAAM;AAAA,kBACN,cAAY,oBAAoBy6B,IAAQ,CAAC;AAAA,kBACzC,SAAS,MAAME,EAAUF,CAAK;AAAA,kBAE9B,UAAA,gBAAAz6B,EAACgQ,IAAA,EAAK,MAAK,SAAQ,MAAM,GAAA,CAAI;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC/B;AAAA,UAAA;AAAA,UAhEGqqB,EAAQI,CAAK;AAAA,QAAA;AAAA,MAoExB,CAAC;AAAA,MACA,CAAC9uB,KACA,gBAAA3L;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS06B;AAAA,UACV,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAIH,gBAAA16B,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,kGAGnC;AAAA,MACC,CAAC,GAAG,IAAI,IAAIuwB,EAAM,KAAK,IAAI,CAAC7V,MAAQA,EAAI,QAAQ,CAAC,CAAC,EAAE;AAAA,QAAI,CAACme,MACxDb,GAAyBa,CAAQ,IAC/B,gBAAA74B,EAAC,KAAA,EAAiB,WAAU,uBACzB,UAAAg4B,GAAyBa,CAAQ,EAAA,GAD5BA,CAER,IACE;AAAA,MAAA;AAAA,IACN,GACF;AAAA,IAEDuB,KACC,gBAAAp6B;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,OAAO85B,IAAW,0BAA0B;AAAA,QAC5C,cAAYA,IAAW,0BAA0B;AAAA,QACjD,SAAS,MAAMC,EAAY,CAACD,CAAQ;AAAA,QAEpC,4BAAC9pB,IAAA,EAAK,MAAM8pB,IAAW,SAAS,QAAQ,MAAM,GAAA,CAAI;AAAA,MAAA;AAAA,IAAA;AAAA,IAGrDF,MAAY,YACX,gBAAA55B,EAAC,KAAA,EAAE,WAAU,uBACV,UAAA45B,MAAY,SACT,kDACA5oB,EAAQ,OACN,wDACA,wCAAA,CACR;AAAA,EAAA,GAEJ;AAEJ;AC7NA,MAAM8pB,KAA2C;AAAA,EAC/C,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AACZ;AASO,SAASC,GAAkB;AAAA,EAChC,OAAAl3B;AAAA,EACA,UAAAgI;AAAA,EACA,UAAAF;AAAA,EACA,QAAA0R,IAAS;AACX,GAKG;AACD,QAAM2d,IAAU,CAAC,CAACn3B,GACZo3B,KAAWp3B,KAAA,gBAAAA,EAAO,gBAAe,GACjCq3B,KAAUr3B,KAAA,gBAAAA,EAAO,YAAW,KAC5Bs3B,KAAUt3B,KAAA,gBAAAA,EAAO,YAAW,SAE5Bu3B,IAAW,CAAC5tB,MAChB3B,EAAS,EAAE,aAAaovB,GAAU,SAAAC,GAAS,SAAAC,GAAS,GAAGt3B,GAAO,GAAG2J,GAAO;AAE1E,SACE,gBAAA1H,EAAAwB,IAAA,EACE,UAAA;AAAA,IAAA,gBAAAxB,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,MAAA,gBAAAA,EAAC,QAAA,EACC,UAAA;AAAA,QAAA,gBAAA9F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAASg7B;AAAA,YACT,UAAUrvB;AAAA,YACV,UAAU,CAACtI,MACTwI,EAASxI,EAAE,OAAO,UAAU,EAAE,aAAa43B,GAAU,SAAAC,GAAS,SAAAC,EAAA,IAAY,MAAS;AAAA,UAAA;AAAA,QAAA;AAAA,QAEpF;AAAA,QAAI;AAAA,MAAA,GAET;AAAA,wBACC,QAAA,EAAK,WAAU,YAAY,UAAAL,GAAYzd,CAAM,EAAA,CAAE;AAAA,IAAA,GAClD;AAAA,IACC2d,KACC,gBAAAl1B,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,WAAA,CAAQ;AAAA,QACd,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAK;AAAA,YACL,OAAOi7B;AAAA,YACP,UAAAtvB;AAAA,YACA,UAAU,CAACtI,MAAM+3B,EAAS,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO/3B,EAAE,OAAO,KAAK,KAAK,CAAC,GAAG;AAAA,UAAA;AAAA,QAAA;AAAA,MACrF,GACF;AAAA,MACA,gBAAAyC,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,aAAA,CAAU;AAAA,QAChB,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAK;AAAA,YACL,OAAOk7B;AAAA,YACP,UAAAvvB;AAAA,YACA,UAAU,CAACtI,MAAM+3B,EAAS,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO/3B,EAAE,OAAO,KAAK,KAAK,CAAC,GAAG;AAAA,UAAA;AAAA,QAAA;AAAA,MACjF,GACF;AAAA,MACA,gBAAAyC,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,UAAA,CAAO;AAAA,QACb,gBAAA8F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAOq1B;AAAA,YACP,UAAUxvB;AAAA,YACV,UAAU,CAACtI,MAAM+3B,EAAS,EAAE,SAAS/3B,EAAE,OAAO,OAAkC;AAAA,YAEhF,UAAA;AAAA,cAAA,gBAAArD,EAAC,UAAA,EAAO,OAAM,SAAQ,UAAA,SAAK;AAAA,cAC3B,gBAAAA,EAAC,UAAA,EAAO,OAAM,eAAc,UAAA,cAAA,CAAW;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACzC,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;ACjEO,SAASq7B,GAAe;AAAA,EAC7B,QAAA1jB;AAAA,EACA,UAAA9L;AAAA,EACA,UAAAF;AAAA,EACA,UAAA2vB,IAAW;AAAA,EACX,iBAAAC,IAAkB;AAAA,EAClB,eAAAC,IAAgB;AAAA,EAChB,SAAAC;AACF,GAwCG;AACD,QAAMC,IAAU/jB,EAAO,WAAW;AAElC,SACE,gBAAA7R,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAAy1B,KACC,gBAAAz1B,EAAAwB,IAAA,EACG,UAAA;AAAA,MAAAk0B,KACC,gBAAAx7B;AAAA,QAAC+6B;AAAA,QAAA;AAAA,UACC,OAAOpjB,EAAO;AAAA,UACd,UAAU,CAAC7S,MAAU+G,EAAS,EAAE,GAAG8L,GAAQ,OAAA7S,GAAO;AAAA,UAClD,UAAA6G;AAAA,QAAA;AAAA,MAAA;AAAA,MAKJ,gBAAA7F,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,WAAA,CAAQ;AAAA,QACd,gBAAA8F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO41B;AAAA,YACP,UAAU/vB;AAAA,YACV,UAAU,CAACtI,MAAM;AACf,oBAAMtI,IAAIsI,EAAE,OAAO;AAEnB,cAAAwI,EAAS,EAAE,GAAG8L,GAAQ,SAAS5c,MAAM,SAAS,SAAYA,GAAG;AAAA,YAC/D;AAAA,YAEA,UAAA;AAAA,cAAA,gBAAAiF,EAAC,UAAA,EAAO,OAAM,QAAO,UAAA,0BAAsB;AAAA,cAC3C,gBAAAA,EAAC,UAAA,EAAO,OAAM,YAAW,UAAA,6BAAyB;AAAA,cACjDs7B,KACC,gBAAAt7B,EAAC,UAAA,EAAO,OAAM,mBAAkB,UAAA,+CAAA,CAEhC;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGHs7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAgBC,gBAAAx1B,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA;AAAA,YAAA;AAAA,YAGD,gBAAA9F,EAAC,YAAO,UAAA,WAAA,CAAQ;AAAA,YAAS;AAAA,YAAK;AAAA,YACjE,gBAAAA,EAAC,YAAO,UAAA,8BAAA,CAA+B;AAAA,YAAS;AAAA,YAC0B;AAAA,YAC1E,gBAAAA,EAAC,YAAO,UAAA,QAAA,CAAK;AAAA,YAAS;AAAA,UAAA,EAAA,CAGxB;AAAA;AAAA;AAAA;AAAA;AAAA,UAKA,gBAAA8F,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA;AAAA,YAAA;AAAA,YAIxB,gBAAA9F,EAAC,YAAO,UAAA,UAAA,CAAO;AAAA,YAAS;AAAA,UAAA,EAAA,CAEtC;AAAA;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA,GACF;AAAA,IAODy7B,KACC,gBAAA31B,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,UAAK,UAAA,qBAAA,CAAkB;AAAA,MACxB,gBAAA8F,EAAC,OAAA,EAAI,WAAU,iBACZ,UAAA;AAAA,QAAA21B,EAAQ;AAAA,QACRA,EAAQ,SACP,gBAAAz7B;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,UAAU2L;AAAA,YACV,SAAS,MAAM8vB,EAAQ,SAAS,MAAS;AAAA,YAC1C,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,GAEJ;AAAA,MACA,gBAAAz7B,EAAC,QAAA,EAAK,WAAU,YAAW,UAAA,2GAAA,CAG3B;AAAA,IAAA,GACF;AAAA,IAMF,gBAAA8F,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,MAAA,gBAAA9F,EAAC,UAAK,UAAA,QAAA,CAAK;AAAA,MACX,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAM;AAAA,UACN,OAAO2X,EAAO,SAAS;AAAA,UACvB,UAAAhM;AAAA,UACA,aAAY;AAAA,UACZ,UAAU,CAACtI,MAAMwI,EAAS,EAAE,GAAG8L,GAAQ,OAAOtU,EAAE,OAAO,SAAS,OAAA,CAAW;AAAA,QAAA;AAAA,MAAA;AAAA,IAC7E,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AC7LO,SAASs4B,GAAsBpO,GAA0C;AAC9E,SAAOA,EAAO,WAAW;AAC3B;AAGO,SAASqO,GACdrO,GAC4C;AAC5C,QAAMlpB,IAASkpB,EAAO;AACtB,MAAIlpB,MAAW,OAAW,QAAOkpB;AACjC,MACE,EAAA9K,GAAcpe,CAAM,KACpB0Q,GAAY1Q,CAAM,KAClBkV,GAAalV,CAAM,KAClB,OAAOA,KAAW,YAAYkS,GAAoBlS,CAAM;AAG3D,WACEA,KACA,OAAOA,KAAW,YAClB,CAAC,MAAM,QAAQA,CAAM,KACrB,CAAC2Q,GAAc3Q,CAAM,KACrB,EAAE,YAAYA,KAEP,EAAE,GAAGkpB,GAAQ,GAAGlpB,EAAA,IAElB;AACT;AAGO,SAASw3B,GACdh4B,GACAoV,GACA6iB,IAAiC,CAAA,GACxB;AACT,MACE/mB,GAAYlR,CAAK,KACjBmR,GAAcnR,CAAK,KACnByV,GAAazV,CAAK,KAClB0V,GAAa1V,CAAK,KAClBA,MAAU,QACV,OAAOA,KAAU;AAEjB,WAAO0W,GAAiB1W,GAAOoV,CAAK;AACtC,QAAMzO,IAAQ,CAACzP,MAAwB8gC,GAAqB9gC,GAAGke,CAAK;AACpE,SAAI,MAAM,QAAQpV,CAAK,IAAUA,EAAM,IAAI2G,CAAK,IACzC,OAAO;AAAA,IACZ,OAAO,QAAQ3G,CAAK,EAAE,IAAI,CAAC,CAAC0T,GAAKxc,CAAC,MAAM,CAACwc,GAAKukB,EAAY,SAASvkB,CAAG,IAAIxc,IAAIyP,EAAMzP,CAAC,CAAC,CAAC;AAAA,EAAA;AAE3F;ACrDO,SAASghC,GAAmB;AAAA,EACjC,QAAAxO;AAAA,EACA,UAAA1hB;AAAA,EACA,UAAAF;AACF,GAIG;AACD,SACE,gBAAA7F,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAA9F,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,iMAInC;AAAA,IACA,gBAAAA;AAAA,MAACgxB;AAAA,MAAA;AAAA,QACC,QAAQ;AAAA,UACN;AAAA,YACE,KAAK;AAAA,YACL,OAAO;AAAA,YACP,MAAM;AAAA,YACN,UAAU;AAAA,YACV,SAAS,CAAA;AAAA,YACT,OAAO;AAAA,UAAA;AAAA,QACT;AAAA,QAEF,QAAAzD;AAAA,QACA,UAAA1hB;AAAA,QACA,UAAAF;AAAA,MAAA;AAAA,IAAA;AAAA,IAEDiwB,GAAsBrO,CAAM,MAAM,QACjC,gBAAAvtB,EAAC,OAAE,MAAK,SAAQ,WAAU,mBAAkB,UAAA,gFAAA,CAE5C;AAAA,IAED,CAAC2L,KAAYgwB,GAAsBpO,CAAM,KACxC,gBAAAvtB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM;AACb,gBAAM,EAAE,QAAQg8B,GAAgB,GAAGn2B,MAAS0nB;AAC5C,UAAA1hB,EAAShG,CAAI;AAAA,QACf;AAAA,QACD,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAED,GAEJ;AAEJ;ACxBO,SAASo2B,GACd1d,GACAgP,GACyD;AACzD,QAAMpyB,IAA+B,EAAE,GAAGoyB,EAAA;AAC1C,aAAW9O,KAAKF,GAAQ;AACtB,UAAMxjB,IAAIwyB,EAAO9O,EAAE,GAAG;AACtB,QAAI,EAAAA,EAAE,SAAS,UAAU,OAAO1jB,KAAM,YAAYA,EAAE,KAAA,MAAW;AAC/D,UAAI;AACF,QAAAI,EAAIsjB,EAAE,GAAG,IAAI,KAAK,MAAM1jB,CAAC;AAAA,MAC3B,QAAQ;AACN,eAAO,EAAE,OAAO,GAAG0jB,EAAE,KAAK,8CAAA;AAAA,MAC5B;AAAA,EACF;AACA,SAAO,EAAE,QAAQtjB,EAAA;AACnB;AAMO,SAAS+gC,GAAe;AAAA,EAC7B,QAAA3d;AAAA,EACA,QAAAgP;AAAA,EACA,UAAA1hB;AAAA,EACA,kBAAAswB;AAAA,EACA,MAAAp9B,IAAO;AACT,GAAU;AACR,QAAMI,IAAS,CAACoY,GAAa1T,MAAmBgI,EAAS,EAAE,GAAG0hB,GAAQ,CAAChW,CAAG,GAAG1T,GAAO;AAEpF,SACE,gBAAAiC,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAAyY,EAAO,WAAW,KACjB,gBAAAve,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,qGAGnC;AAAA,IAEDue,EAAO,IAAI,CAACG,MAAU;AACrB,YAAM0d,IAAOr9B,MAAS,QAChB8E,IAAS0pB,EAAO7O,EAAM,GAAG,MAAM0d,IAAO,SAAY1d,EAAM,YAAY;AAI1E,UAAIA,EAAM,SAAS;AACjB,eACE,gBAAA5Y,EAAC,SAAA,EAAsB,WAAU,aAC/B,UAAA;AAAA,UAAA,gBAAAA,EAAC,QAAA,EACC,UAAA;AAAA,YAAA,gBAAA9F;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS,EAAQ6D;AAAA,gBACjB,UAAU,CAACR,MAAMlE,EAAOuf,EAAM,KAAKrb,EAAE,OAAO,OAAO;AAAA,gBAClD,GAAG84B;AAAA,cAAA;AAAA,YAAA;AAAA,YAELzd,EAAM;AAAA,YACNA,EAAM,WAAW,OAAO;AAAA,UAAA,GAC3B;AAAA,UACCA,EAAM,QAAQ,gBAAA1e,EAAC,UAAK,WAAU,YAAY,YAAM,KAAA,CAAK;AAAA,QAAA,EAAA,GAX5C0e,EAAM,GAYlB;AAGJ,YAAM2d,IAAW3d,EAAM,SAAS,YAAYA,EAAM,WAAW;AAC7D,UAAIA,EAAM,SAAS,UAAUA,EAAM,SAAS;AAK1C,eACE,gBAAA5Y,EAAC,SAAA,EAAsB,WAAU,aAC/B,UAAA;AAAA,UAAA,gBAAAA,EAAC,QAAA,EACE,UAAA;AAAA,YAAA4Y,EAAM;AAAA,YACNA,EAAM,WAAW,OAAO;AAAA,UAAA,GAC3B;AAAA,UACA,gBAAA1e;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWq8B,IAAW,qBAAqB;AAAA,cAC3C,MAAM3d,EAAM,SAAS,SAAS,IAAI;AAAA,cAClC,OAAO,OAAO7a,KAAS,EAAE;AAAA,cACzB,aAAau4B,KAAQC,IAAW,uBAAuB;AAAA,cACvD,UAAU,CAACh5B,MAAMlE,EAAOuf,EAAM,KAAKrb,EAAE,OAAO,KAAK;AAAA,cACjD,MAAM,YAAYqb,EAAM,GAAG;AAAA,cAC3B,cAAa;AAAA,cACb,gBAAe;AAAA,cACf,aAAY;AAAA,cACZ,YAAY;AAAA,cACZ,kBAAe;AAAA,cACf,iBAAc;AAAA,cACd,iBAAc;AAAA,cACd,kBAAe;AAAA,YAAA;AAAA,UAAA;AAAA,UAEhBA,EAAM,QAAQ,gBAAA1e,EAAC,UAAK,WAAU,YAAY,YAAM,KAAA,CAAK;AAAA,QAAA,EAAA,GArB5C0e,EAAM,GAsBlB;AAQJ,YAAM6U,IAAY7U,EAAM,SAAS,WAAW,WAAW;AACvD,aACE,gBAAA5Y,EAAC,SAAA,EAAsB,WAAU,aAC/B,UAAA;AAAA,QAAA,gBAAAA,EAAC,QAAA,EACE,UAAA;AAAA,UAAA4Y,EAAM;AAAA,UACNA,EAAM,WAAW,OAAO;AAAA,QAAA,GAC3B;AAAA,QACA,gBAAA1e;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAMuzB;AAAA,YACN,WAAW8I,IAAW,qBAAqB;AAAA,YAC3C,OAAO,OAAOx4B,KAAS,EAAE;AAAA,YACzB,aAAau4B,KAAQC,IAAW,uBAAuB;AAAA,YACvD,UAAU,CAACh5B,MACTlE;AAAA,cACEuf,EAAM;AAAA,cACNA,EAAM,SAAS,YAAY,EAAE0d,KAAQ/4B,EAAE,OAAO,UAAU,MACpD,OAAOA,EAAE,OAAO,KAAK,IACrBA,EAAE,OAAO;AAAA,YAAA;AAAA,YAIjB,MAAM,YAAYqb,EAAM,GAAG;AAAA,YAC3B,cAAa;AAAA,YACb,gBAAe;AAAA,YACf,aAAY;AAAA,YACZ,YAAY;AAAA,YACZ,kBAAe;AAAA,YACf,iBAAc;AAAA,YACd,iBAAc;AAAA,YACd,kBAAe;AAAA,YACd,GAAGyd;AAAA,UAAA;AAAA,QAAA;AAAA,QAELzd,EAAM,QAAQ,gBAAA1e,EAAC,UAAK,WAAU,YAAY,YAAM,KAAA,CAAK;AAAA,MAAA,EAAA,GA9B5C0e,EAAM,GA+BlB;AAAA,IAEJ,CAAC;AAAA,EAAA,GACH;AAEJ;ACzIO,SAAS4d,GAAiB;AAAA,EAC/B,aAAAC;AAAA,EACA,MAAAx9B;AAAA,EACA,cAAAy9B;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC;AAAA,EACA,gBAAAC,IAAiB;AAAA,EACjB,UAAAC;AACF,GAA0B;AACxB,QAAMltB,IAAQ,CAAC,MAAyB;AACtC,UAAM6E,IAAQ,OAAO,OAAO,EAAE,WAAW,CAAA,CAAE,EAAE,OAAO,OAAO;AAC3D,WAAOA,EAAM,SAAS,IAAI,GAAG,EAAE,IAAI,KAAKA,EAAM,KAAK,IAAI,CAAC,MAAM,EAAE;AAAA,EAClE;AACA,SACE,gBAAAzO,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAA62B,uBACE,OAAA,EAAI,WAAU,aAAY,MAAK,cAAa,cAAW,cACtD,UAAA;AAAA,MAAA,gBAAA72B,EAAC,QAAA,EAAK,UAAA;AAAA,QAAA;AAAA,QAAW82B,IAAW,KAAKA,CAAQ,MAAM;AAAA,MAAA,GAAG;AAAA,wBACjD,SAAA,EACC,UAAA;AAAA,QAAA,gBAAA58B;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,MAAK;AAAA,YACL,SAASjB,MAAS;AAAA,YAClB,UAAU,MAAMy9B,EAAa,UAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QACtC;AAAA,QAAI;AAAA,MAAA,GAET;AAAA,wBACC,SAAA,EACC,UAAA;AAAA,QAAA,gBAAAx8B;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,MAAK;AAAA,YACL,SAASjB,MAAS;AAAA,YAClB,UAAU,MAAMy9B,EAAa,KAAK;AAAA,UAAA;AAAA,QAAA;AAAA,QACjC;AAAA,QAAI;AAAA,MAAA,EAAA,CAET;AAAA,IAAA,GACF;AAAA,IAEDG,KAAkB59B,MAAS,cAC1B,gBAAA+G,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,MAAA,gBAAA9F,EAAC,UAAK,UAAA,oBAAA,CAAiB;AAAA,MACvB,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,OAAOy8B;AAAA,UACP,UAAU,CAACp5B,MAAMq5B,EAASr5B,EAAE,OAAO,KAAK;AAAA,UAEvC,UAAAk5B,EAAY,IAAI,CAAC,wBACf,UAAA,EAAkB,OAAO,EAAE,IACzB,UAAA7sB,EAAM,CAAC,EAAA,GADG,EAAE,EAEf,CACD;AAAA,QAAA;AAAA,MAAA;AAAA,IACH,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;AAQO,SAASmtB,GAAiBC,GAAuC;AACtE,QAAMC,KAAUD,EAAG,iBAAiB,CAAA,GAAI,OAAO,CAACre,MAAMA,EAAE,QAAQ,eAAe;AAC/E,SAAIqe,EAAG,kBAAkB,SAAeC,IASjC,CAPsB;AAAA,IAC3B,IAFgBD,EAAG,iBAAiB,CAAA,GAAI,KAAK,CAACre,MAAMA,EAAE,QAAQ,eAAe,KAE7D,EAAE,MAAM,SAAA;AAAA,IACxB,KAAK;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,UAAUqe,EAAG,kBAAkB;AAAA,EAAA,GAEd,GAAGC,CAAM;AAC9B;AAOO,SAASC,GACdze,GACAgP,GAC+B;AAC/B,QAAMmI,IAA6B,CAAA,GAC7BuH,IAAsD,CAAA;AAC5D,aAAWxe,KAAKF,GAAQ;AACtB,UAAMxjB,IAAIwyB,EAAO9O,EAAE,GAAG;AACtB,IAAuB1jB,KAAM,QAAQA,MAAM,OACvC0jB,EAAE,QAAQ,kBAAiBiX,EAAQ,gBAAgB,OAAO36B,CAAC,IAC1DkiC,EAASxe,EAAE,GAAG,IAAI1jB;AAAA,EACzB;AACA,SAAI,OAAO,KAAKkiC,CAAQ,EAAE,SAAS,QAAW,WAAWA,IAClD,OAAO,KAAKvH,CAAO,EAAE,SAAS,IAAIA,IAAU;AACrD;AC5GA,MAAMwH,KAAiB;AAEhB,SAASC,GAAgBC,GAAqD;AACnF,SAAO,IAAI,QAAQ,CAACxsB,GAASysB,MAAW;AACtC,UAAMC,IAAQ,OAAO,KAAKF,GAAkB,aAAaF,EAAc;AACvE,QAAI,CAACI,GAAO;AACV,MAAAD,EAAO,IAAI,MAAM,2DAA2D,CAAC;AAC7E;AAAA,IACF;AAEA,QAAIhO,IAAO;AACX,UAAMkO,IAAU,MAAM;AACpB,MAAAlO,IAAO,IACP,OAAO,oBAAoB,WAAWmO,CAAS,GAC/C,OAAO,cAAcC,CAAU;AAAA,IACjC,GAEMD,IAAY,CAACzsB,MAAwB;AACzC,YAAM2sB,IAAO3sB,EAAM;AAGnB,WAAI2sB,KAAA,gBAAAA,EAAM,SAAQ,gBAClB;AAAA,QAAAH,EAAA;AACA,YAAI;AACF,UAAAD,EAAM,MAAA;AAAA,QACR,QAAQ;AAAA,QAER;AACA,QAAII,EAAK,MAAM,OAAOA,EAAK,gBAAiB,WAC1C9sB,EAAQ,EAAE,cAAc8sB,EAAK,aAAA,CAAc,IAE3CL,EAAO,IAAI,MAAMK,EAAK,SAAS,oBAAoB,CAAC;AAAA;AAAA,IAExD;AACA,WAAO,iBAAiB,WAAWF,CAAS;AAI5C,UAAMC,IAAa,OAAO,YAAY,MAAM;AAC1C,MAAIpO,KACAiO,EAAM,WACRC,EAAA,GACAF,EAAO,IAAI,MAAM,mDAAmD,CAAC;AAAA,IAEzE,GAAG,GAAG;AAAA,EACR,CAAC;AACH;ACvDA,MAAMM,yBAA2B,IAAI;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AASD,SAASC,GAAwBvgB,GAA8B;AAC7D,SAAOA,EAAO,QAAQ,kDAAkD,MAAM;AAChF;AAmBO,SAASwgB,GACdC,GACAzd,GACkD;AAClD,SAAO;AAAA,IACL,WAAW,CAAChd,MAAkC;AAI5C,WAHIgd,KAAA,gBAAAA,EAAM,aAAY,MAClBhd,EAAE,QAAQ,WACVA,EAAE,YAAYA,EAAE,UAAUA,EAAE,WAAWA,EAAE,WACzCA,EAAE,YAAY,YAAa;AAC/B,YAAMga,IAASha,EAAE;AACjB,MAAIga,EAAO,YAAY,eACnBugB,GAAwBvgB,CAAM,KAEhCA,EAAO,YAAY,WACnBsgB,GAAqB,IAAKtgB,EAA4B,IAAI,MAI5Dha,EAAE,eAAA,GACFy6B,EAAA;AAAA,IACF;AAAA,EAAA;AAEJ;AClCO,SAASC,GAAmB7tB,GAAgC;AACjE,QAAM7P,IAAMG,GAAA,GACN,CAACw9B,GAAaC,CAAc,IAAIh/B,EAA4B,IAAI,GAChE,CAACi/B,GAAkBC,CAAmB,IAAIl/B,EAAkB,EAAQiR,EAAM,YAAa;AA8C7F,SAhCAhR,GAAU,MAAM;AACd,UAAMvF,IAAKuW,EAAM;AACjB,QAAI,CAACvW,EAAI;AACT,QAAIyJ,IAAW;AACf,UAAMuN,IAAS,CAAC3Z,MAA2B;AACzC,MAAIoM,MACJ66B,EAAejnC,CAAG,GAClBmnC,EAAoB,EAAK;AAAA,IAC3B,GACMC,IAAgB/9B,EAAI;AAC1B,QAAI+9B;AACF,aAAAA,EAAc,CAACzkC,CAAE,CAAC,EACf,KAAK,CAAC7C,MAAS6Z,EAAO7Z,EAAK,KAAK,CAACI,MAAMA,EAAE,OAAOyC,CAAE,KAAK,IAAI,CAAC,EAC5D,MAAM,MAAMgX,EAAO,IAAI,CAAC,GACpB,MAAM;AACX,QAAAvN,IAAW;AAAA,MACb;AAEF,UAAMD,IAAW9C,EAAI;AACrB,WAAI,OAAO8C,KAAa,aACtBA,EAAA,EACG,KAAK,CAACrM,MAAS6Z,EAAO7Z,EAAK,KAAK,CAACI,MAAMA,EAAE,OAAOyC,CAAE,KAAK,IAAI,CAAC,EAC5D,MAAM,MAAMgX,EAAO,IAAI,CAAC,IAE3BA,EAAO,IAAI,GAEN,MAAM;AACX,MAAAvN,IAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAK6P,EAAM,YAAY,CAAC,GAGxB8tB,IAEA,gBAAAh+B;AAAA,IAACob;AAAA,IAAA;AAAA,MACC,OAAO4iB,EAAY;AAAA,MACnB,UACE,gBAAAl4B,EAAAwB,IAAA,EACE,UAAA;AAAA,QAAA,gBAAAtH,EAAC,QAAA,EAAM,YAAY,GAAA,CAAG;AAAA,QACrBg+B,EAAY,WAAW,OAAOA,EAAY,OAAO;AAAA,MAAA,GACpD;AAAA,MAEF,SAAS9tB,EAAM;AAAA,MACf,MAAK;AAAA,MACL,WACE,gBAAAlQ;AAAA,QAACV;AAAA,QAAA;AAAA,UACC,KAAK0+B,EAAY;AAAA,UACjB,SAASA,EAAY;AAAA,UACrB,YAAYA,EAAY;AAAA,UACxB,MAAMA,EAAY;AAAA,UAClB,OAAO9tB,EAAM;AAAA,UACb,MAAM;AAAA,QAAA;AAAA,MAAA;AAAA,MAGV,aACEA,EAAM,eAAe,SACnB,gBAAAlQ;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAMi+B,EAAe,IAAI;AAAA,UACnC,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAML,UAAA,gBAAAj+B,EAACq+B,MAAiB,KAAKL,GAAa,WAAW9tB,EAAM,WAAW,SAASA,EAAM,QAAA,CAAS;AAAA,IAAA;AAAA,EAAA,IAM1FguB,sBAEC9iB,IAAA,EAAM,OAAM,kBAAiB,SAASlL,EAAM,SAAS,MAAK,MACzD,4BAAC,OAAA,EAAI,WAAU,2BACb,UAAA,gBAAAlQ,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,YAAQ,GAC7C,EAAA,CACF,IAMF,gBAAAA,EAACob,IAAA,EAAM,OAAM,kBAAiB,SAASlL,EAAM,SAAS,MAAK,MACzD,UAAA,gBAAAlQ,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA,gBAAAA;AAAA,IAACyB;AAAA,IAAA;AAAA,MACC,aAAaw8B;AAAA,MACb,OAAO/tB,EAAM;AAAA,MACb,mBAAkB;AAAA,MAClB,gBAAc;AAAA,IAAA;AAAA,EAAA,GAElB,EAAA,CACF;AAEJ;AAMA,SAASmuB,GAAiB;AAAA,EACxB,KAAArnC;AAAA,EACA,WAAAsnC;AAAA,EACA,SAAAjjB;AACF,GAIG;;AACD,QAAMhb,IAAMG,GAAA,GACN,CAAC+9B,GAAOC,CAAQ,IAAIv/B,EAA2B,IAAI,GACnD,CAACw/B,GAASC,CAAU,IAAIz/B,EAAiB,EAAE,GAC3C,CAAC0/B,GAAaC,CAAc,IAAI3/B,EAAS,EAAE,GAC3C,CAAC4/B,GAAYC,CAAa,IAAI7/B,EAAkC,CAAA,CAAE,GAClE,CAAC+d,GAAOmM,CAAQ,IAAIlqB,EAAwB,IAAI,GAChD,CAACyR,GAAS0Y,CAAU,IAAInqB,EAAS,EAAK,GAGtC,CAAC8/B,GAAQC,CAAS,IAAI//B,EAAqC,IAAI,GAC/D,CAACggC,GAAYC,CAAa,IAAIjgC,EAAoC,IAAI,GACtE,CAACw9B,GAAY0C,CAAa,IAAIlgC,EAAS,EAAE,GACzC,CAACmgC,GAAUC,CAAW,IAAIpgC,EAAS,EAAE,GACrC,CAACqgC,GAAaC,CAAc,IAAItgC,EAAkC,CAAA,CAAE,GACpEugC,IAAY18B,GAAsB,IAAI;AAE5C,EAAA5D,GAAU,MAAM;AACd,QAAIkE,IAAW;AACf,WAAAo7B,EAAS,IAAI,GACbn+B,EACG,WAAWrJ,EAAI,EAAE,EAEjB,KAAK,CAACE,MAAM,CAACkM,KAAYo7B,EAAStnC,EAAE,OAAO,CAACmoB,OAAMA,GAAE,cAAc,EAAK,CAAC,CAAC,EACzE,MAAM,CAAChc,MAAM,CAACD,KAAY+lB,EAAU9lB,EAAY,OAAO,CAAC,GACpD,MAAM;AACX,MAAAD,IAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAKrJ,EAAI,EAAE,CAAC;AAEhB,QAAM++B,IAAYwI,KAAS,CAAA,GAGrBkB,IACJ1J,EAAU,KAAK,CAAC7+B,MAAMA,EAAE,QAAQunC,CAAO,KACvC1I,EAAU,KAAK,CAAC7+B,MAAMA,EAAE,YAAY,EAAI,KACxC6+B,EAAU,CAAC,GACPxX,KAAsBkhB,KAAA,gBAAAA,EAAM,WAAU,CAAA,GACtCC,KAAUD,KAAA,gBAAAA,EAAM,UAAS,UAGzB3C,IAAK2C,KAAA,gBAAAA,EAAM,gBACXE,IAAkBt/B,EAAI,iBACtBu/B,IAAmBv/B,EAAI,kBACvBw/B,IACJ,CAACH,KACD,CAAC,CAAC5C,KACF,OAAO6C,KAAoB,cAC3B,OAAOC,KAAqB,YACxBhD,MAAWpjC,IAAAsjC,KAAA,gBAAAA,EAAI,YAAJ,gBAAAtjC,EAAc,OAAM,IAC/BsmC,MAAUf,KAAU,CAAA,GAAI,OAAO,CAAC74B,MAAMA,EAAE,aAAa02B,KAAY12B,EAAE,WAAW,QAAQ,GACtFnH,KAA2B+gC,GAAO,WAAW,IAAI,QAASb,KAAc,YACxEc,IAAWD,GAAO,KAAK,CAAC55B,MAAMA,EAAE,OAAOu2B,CAAU,IAAIA,MAAczvB,IAAA8yB,GAAO,CAAC,MAAR,gBAAA9yB,EAAW,OAAM,IACpFgzB,IAAgBH,KAAkB/C,IAAKD,GAAiBC,CAAE,IAAI,CAAA;AAEpE,EAAA59B,GAAU,MAAM;AACd,QAAI,CAAC2gC,KAAkB,CAACF,EAAiB;AACzC,QAAIv8B,IAAW;AACf,WAAA47B,EAAU,IAAI,GACdE,EAAc,IAAI,GAClBM,EAAU,UAAU,MACpBG,EACG,KAAKt/B,GAAK,EAAE,UAAAu8B,EAAA,CAAU,EACtB,KAAK,CAAC5P,MAAS,CAAC5pB,KAAY47B,EAAUhS,CAAI,CAAC,EAC3C,MAAM,MAAM,CAAC5pB,KAAY47B,EAAU,CAAA,CAAE,CAAC,GAClC,MAAM;AACX,MAAA57B,IAAW;AAAA,IACb;AAAA,EAEF,GAAG,CAAC/C,GAAKw/B,GAAgBjD,GAAU+C,CAAe,CAAC;AAUnD,QAAMM,KAAaR,KAAA,gBAAAA,EAAM,SAAQ,mBAC3BhJ,IAAQ,CAAC17B,MAAeA,MAAM,UAAaA,MAAM,IACjDmlC,IACJ,CAACR,KACD,CAACO,MACAJ,IACGd,MAAW,QACXiB,EAAc,KAAK,CAACvhB,MAAMA,EAAE,YAAYgY,EAAM6I,EAAY7gB,EAAE,GAAG,CAAC,CAAC,MAChE1f,OAAS,aACNghC,MAAa,KACbX,EAAS,WAAW,MAAM7gB,EAAO,KAAK,CAACE,MAAMA,EAAE,YAAYgY,EAAMoI,EAAWpgB,EAAE,GAAG,CAAC,CAAC,KACvFF,EAAO,KAAK,CAACE,MAAMA,EAAE,YAAYgY,EAAMoI,EAAWpgB,EAAE,GAAG,CAAC,CAAC,IAIzD0hB,IAAiB,CAACV,KAAS,CAACC,KAAW,CAACO,KAAcC,KAAoBxvB;AAEhF,iBAAe4Y,KAAS;AACtB,QAAKmW,GACL;AAAA,MAAAtW,EAAS,IAAI,GACbC,EAAW,EAAI;AACf,UAAI;AACF,YAAI6W;AACF,UAAA3B,EAAU,EAAE,cAAc,YAAYtnC,EAAI,EAAE,IAAI;AAAA,iBACvC0oC,GAAS;AAClB,gBAAM,EAAE,kBAAAtC,MAAqB,MAAM/8B,EAAI,kBAAkBrJ,EAAI,IAAIyoC,EAAK,KAAK;AAAA,YACzE,aAAad,KAAe;AAAA,UAAA,CAC7B,GACK,EAAE,cAAAyB,EAAA,IAAiB,MAAMjD,GAAgBC,CAAgB;AAC/D,UAAAkB,EAAU,EAAE,cAAA8B,GAAc;AAAA,QAC5B,WAAWP,KAAkBD,GAAkB;AAC7C,cAAIS,IAAethC,OAAS,aAAaghC,IAAWP,EAAU;AAC9D,cAAIa,MAAiB,MAAM;AACzB,kBAAM7tB,KAASypB,GAAgB1d,GAAQsgB,CAAU;AACjD,gBAAI,WAAWrsB,IAAQ;AACrB,cAAA2W,EAAS3W,GAAO,KAAK;AACrB;AAAA,YACF;AACA,kBAAM8tB,KAAO,MAAMV,EAAiB,KAAKv/B,GAAK;AAAA,cAC5C,MAAM++B,EAAS,KAAA;AAAA,cACf,UAAAxC;AAAA,cACA,QAAQpqB,GAAO;AAAA,YAAA,CAChB;AACD,YAAAgtB,EAAU,UAAUc,GAAK,IACzBD,IAAeC,GAAK;AAAA,UACtB;AACA,gBAAM5K,IAAUsH,GAAagD,GAAeV,CAAW,GACjDh6B,KAA6B;AAAA,YACjC,SAASm6B,EAAK;AAAA,YACd,cAAAY;AAAA,YACA,GAAI3K,IAAU,EAAE,SAAAA,EAAA,IAAY,CAAA;AAAA,YAC5B,GAAIiJ,IAAc,EAAE,aAAAA,MAAgB,CAAA;AAAA,UAAC,GAEjC4B,KAAO,MAAMlgC,EAAI,iBAAiBrJ,EAAI,IAAIsO,EAAI;AACpD,UAAAg5B,EAAU,EAAE,cAAciC,GAAK,GAAA,CAAI;AAAA,QACrC,OAAO;AACL,gBAAM/tB,IAASypB,GAAgB1d,GAAQsgB,CAAU;AACjD,cAAI,WAAWrsB,GAAQ;AACrB,YAAA2W,EAAS3W,EAAO,KAAK;AACrB;AAAA,UACF;AACA,gBAAM+tB,IAAO,MAAMlgC,EAAI,iBAAiBrJ,EAAI,IAAI;AAAA,YAC9C,SAASyoC,EAAK;AAAA,YACd,YAAYjtB,EAAO;AAAA,YACnB,aAAamsB,KAAe;AAAA,UAAA,CAC7B;AACD,UAAAL,EAAU,EAAE,cAAciC,EAAK,GAAA,CAAI;AAAA,QACrC;AAAA,MACF,SAASl9B,GAAG;AACV,QAAA8lB,EAAU9lB,EAAY,OAAO;AAAA,MAC/B,UAAA;AACE,QAAA+lB,EAAW,EAAK;AAAA,MAClB;AAAA;AAAA,EACF;AAEA,QAAMoX,IAAc3C,GAAevU,IAAQ,EAAE,SAAS,CAAC6W,GAAgB;AAEvE;AAAA;AAAA;AAAA;AAAA,IAIE,gBAAAr6B,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,SAAI,WAAU,kBACb,UAAA,gBAAA8F,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,QAAAy4B,MAAU,QAAQ,gBAAAv+B,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,yBAAqB;AAAA,QAE1Eu+B,MAAU,QAAQxI,EAAU,WAAW,KACtC,gBAAA/1B,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,4HAAA,CAGnC;AAAA,QAGD+1B,EAAU,SAAS,KAClB,gBAAAjwB,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,UAAA,gBAAA9F,EAAC,UAAK,UAAA,cAAA,CAAW;AAAA,UACjB,gBAAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,QAAOy/B,KAAA,gBAAAA,EAAM,QAAO;AAAA,cACpB,UAAU,CAACp8B,MAAM;AACf,gBAAAq7B,EAAWr7B,EAAE,OAAO,KAAK,GACzBy7B,EAAc,CAAA,CAAE,GAChBS,EAAe,CAAA,CAAE,GACjBC,EAAU,UAAU,MACpBrW,EAAS,IAAI;AAAA,cACf;AAAA,cAEC,UAAA4M,EAAU,IAAI,CAAC7+B,wBACb,UAAA,EAAmB,OAAOA,EAAE,KAC1B,UAAA;AAAA,gBAAAA,EAAE,eAAeA,EAAE;AAAA,gBAAI;AAAA,gBAAGA,EAAE;AAAA,gBAAK;AAAA,cAAA,EAAA,GADvBA,EAAE,GAEf,CACD;AAAA,YAAA;AAAA,UAAA;AAAA,QACH,GACF;AAAA,QAGDuoC,KACC,gBAAA35B,EAAAwB,IAAA,EACG,UAAA;AAAA,UAAA,CAAC24B,KACA,gBAAAn6B,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,YAAA,gBAAA9F,EAAC,UAAK,UAAA,eAAA,CAAY;AAAA,YAClB,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO2+B;AAAA,gBACP,UAAU,CAACt7B,MAAMu7B,EAAev7B,EAAE,OAAO,KAAK;AAAA,gBAC9C,aAAY;AAAA,gBACZ,WAAW;AAAA,gBAGX,MAAK;AAAA,gBACL,cAAa;AAAA,gBACb,kBAAe;AAAA,gBACf,iBAAc;AAAA,gBACd,iBAAc;AAAA,gBACd,kBAAe;AAAA,gBACd,GAAGm9B;AAAA,cAAA;AAAA,YAAA;AAAA,UACN,GACF;AAAA,UAEDf,EAAK,eAAe,gBAAAz/B,EAAC,OAAE,WAAU,uBAAuB,YAAK,aAAY;AAAA,UACzEigC,IAAa,OAAOP,IACnB,gBAAA55B,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA;AAAA,YAAA;AAAA,YACT,gBAAA9F,EAAC,UAAA,EAAQ,UAAAy/B,EAAK,eAAeA,EAAK,KAAI;AAAA,YAAS;AAAA,UAAA,EAAA,CAEzE,IACEI,KAAkB/C,IACpB,gBAAAh3B,EAAAwB,IAAA,EACE,UAAA;AAAA,YAAA,gBAAAtH;AAAA,cAACs8B;AAAA,cAAA;AAAA,gBACC,aAAawD;AAAA,gBACb,MAAA/gC;AAAA,gBACA,cAAc,CAACoJ,MAAM;AACnB,kBAAA+2B,EAAc/2B,CAAC,GACfq3B,EAAU,UAAU;AAAA,gBACtB;AAAA,gBACA,YAAYO;AAAA,gBACZ,UAAUZ;AAAA,gBACV,gBAAgBW,GAAO,SAAS;AAAA,gBAChC,UAAAlD;AAAA,cAAA;AAAA,YAAA;AAAA,YAEDE,EAAG,OAAO,SAAS,KAClB,gBAAAh3B,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA;AAAA,cAAA;AAAA,gCACxB,QAAA,EAAM,UAAAg3B,EAAG,OAAO,KAAK,GAAG,EAAA,CAAE;AAAA,YAAA,GACrC;AAAA,YAEDkD,EAAc,SAAS,KACtB,gBAAAhgC;AAAA,cAACk8B;AAAA,cAAA;AAAA,gBACC,QAAQ8D;AAAA,gBACR,QAAQV;AAAA,gBACR,UAAUC;AAAA,gBACV,kBAAkBiB;AAAA,cAAA;AAAA,YAAA;AAAA,YAGrBzhC,OAAS,SACR,gBAAA+G,EAAAwB,IAAA,EACE,UAAA;AAAA,cAAA,gBAAAxB,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,gBAAA,gBAAA9F,EAAC,UAAK,UAAA,oBAAA,CAAiB;AAAA,gBACvB,gBAAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,OAAOo/B;AAAA,oBACP,UAAU,CAAC/7B,MAAMg8B,EAAYh8B,EAAE,OAAO,KAAK;AAAA,oBAC3C,aAAY;AAAA,oBACZ,WAAW;AAAA,oBACX,MAAK;AAAA,oBACL,cAAa;AAAA,oBACb,kBAAe;AAAA,oBACf,iBAAc;AAAA,oBACd,iBAAc;AAAA,oBACd,kBAAe;AAAA,oBACd,GAAGm9B;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACN,GACF;AAAA,cACA,gBAAAxgC;AAAA,gBAACk8B;AAAA,gBAAA;AAAA,kBACC,QAAA3d;AAAA,kBACA,QAAQsgB;AAAA,kBACR,UAAUC;AAAA,kBACV,kBAAkB0B;AAAA,gBAAA;AAAA,cAAA;AAAA,YACpB,EAAA,CACF;AAAA,UAAA,EAAA,CAEJ,IAEA,gBAAAxgC;AAAA,YAACk8B;AAAA,YAAA;AAAA,cACC,QAAA3d;AAAA,cACA,QAAQsgB;AAAA,cACR,UAAUC;AAAA,cACV,kBAAkB0B;AAAA,YAAA;AAAA,UAAA;AAAA,QACpB,GAEJ;AAAA,QAGDxjB,KAAS,gBAAAhd,EAAC,OAAA,EAAI,WAAU,wBAAwB,UAAAgd,EAAA,CAAM;AAAA,MAAA,EAAA,CACzD,EAAA,CACF;AAAA,MACA,gBAAAlX,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,YAAO,MAAK,UAAS,WAAU,yBAAwB,SAASqb,GAAS,UAAA,SAAA,CAE1E;AAAA,QACA,gBAAArb,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,WAAU,UAAUmgC,GAAgB,SAAS7W,IAC1E,UAAA5Y,IACGuvB,IACE,YACAP,IACE,+BACA,YACJO,IACE,aACAP,IACE,iBAAgBD,KAAA,gBAAAA,EAAM,iBAAeA,KAAA,gBAAAA,EAAM,QAAO,UAAU,KAC5D,kBAAA,CACV;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA;AAEJ;AC/cO,SAASgB,GAAavwB,GAA0B;AACrD,QAAM,EAAE,OAAAR,GAAO,SAAAsL,GAAS,UAAAzH,GAAU,WAAAhL,GAAW,GAAGP,MAASkI;AACzD,SACE,gBAAAlQ;AAAA,IAAC2a;AAAA,IAAA;AAAA,MACC,OAAAjL;AAAA,MACA,SAAAsL;AAAA,MACA,UAAAzH;AAAA,MACA,WAAAhL;AAAA,MACA,QAAM;AAAA,MACN,MAAK;AAAA,MACL,eAAaP,EAAK,aAAa;AAAA,IAAA;AAAA,EAAA;AAGrC;ACzBO,SAAS04B,GAAa;AAAA,EAC3B,QAAAnT;AAAA,EACA,UAAA1hB;AAAA,EACA,UAAAF;AACF,GAIG;AACD,QAAM1R,IACJ,MAAM,QAAQszB,EAAO,MAAM,IAAIA,EAAO,SAASvwB,GAAqB7D,IAAY,OAAO,EAAE,QAErFwnC,IAAa1mC,EAAO,OAAO,CAACR,MAAM,CAACA,EAAE,OAAO,GAC5C,CAACmnC,GAASC,CAAU,IAAI5hC,EAAwB,IAAI,GACpD,CAAC6hC,GAAYC,CAAa,IAAI9hC,EAAwB,IAAI,GAC1D,CAAC+hC,GAAUC,CAAW,IAAIhiC,EAAwB,IAAI,GACtD,CAACiiC,GAAWC,CAAY,IAAIliC,EAAS,EAAE,GAEvCwmB,IAAO,CAAC9gB,MACZkH,EAAS;AAAA,IACP,GAAG0hB;AAAA,IACH,QAAQ,CAAC,GAAG5oB,GAAM,GAAG1K,EAAO,OAAO,CAACR,MAAMA,EAAE,OAAO,CAAC;AAAA,EAAA,CACrD,GACG+T,IAAQ,CAAC7T,GAAYkK,MACzB4hB,EAAKkb,EAAW,IAAI,CAAClnC,MAAOA,EAAE,OAAOE,IAAK,EAAE,GAAGF,GAAG,GAAGoK,EAAA,IAAUpK,CAAE,CAAC,GAC9DkV,IAAO,CAAChV,GAAYynC,MAAe;AACvC,UAAMvZ,IAAO8Y,EAAW,UAAU,CAAClnC,MAAMA,EAAE,OAAOE,CAAE;AACpD,QAAIkuB,IAAO,KAAKuZ,IAAK,KAAKA,KAAMT,EAAW,UAAU9Y,MAASuZ,EAAI;AAClE,UAAMz8B,IAAO,CAAC,GAAGg8B,CAAU,GACrB,CAACU,CAAK,IAAI18B,EAAK,OAAOkjB,GAAM,CAAC;AACnC,IAAAljB,EAAK,OAAOy8B,GAAI,GAAGC,CAAK,GACxB5b,EAAK9gB,CAAI;AAAA,EACX,GACM28B,IAAS,CAACD,MAAuB;AACrC,IAAIH,EAAU,UAAQ1zB,EAAM6zB,EAAM,IAAI,EAAE,OAAOH,EAAU,KAAA,GAAQ,GACjED,EAAY,IAAI;AAAA,EAClB;AACA,SACE,gBAAAn7B,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,IAAA,gBAAA9F,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,wDAAoD;AAAA,sBACtF,OAAA,EAAI,WAAU,qBACZ,UAAA2gC,EAAW,IAAI,CAACU,GAAO5G;AAAA;AAAA,MAEtB,gBAAA30B;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,WAAW,mBAAmB86B,MAAYS,EAAM,KAAK,iBAAiB,EAAE,GAAGP,MAAeO,EAAM,KAAK,oBAAoB,EAAE;AAAA,UAC3H,iBAAeA,EAAM;AAAA,UACrB,YAAY,CAACtwB,MAAU;AACrB,YAAIpF,KAAY,CAACi1B,KAAWA,MAAYS,EAAM,OAC9CtwB,EAAM,eAAA,GACNA,EAAM,aAAa,aAAa,QAChCgwB,EAAcM,EAAM,EAAE;AAAA,UACxB;AAAA,UACA,QAAQ,CAACtwB,MAAU;AACjB,YAAAA,EAAM,eAAA,GACF,CAACpF,KAAYi1B,KAASjyB,EAAKiyB,GAASnG,CAAK,GAC7CoG,EAAW,IAAI,GACfE,EAAc,IAAI;AAAA,UACpB;AAAA,UAEA,UAAA;AAAA,YAAA,gBAAAj7B,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,cAAA,gBAAA9F;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,WAAW,CAAC2L;AAAA,kBACZ,UAAUA;AAAA,kBACV,cAAY,WAAW01B,EAAM,SAASA,EAAM,EAAE;AAAA,kBAC9C,OAAM;AAAA,kBACN,aAAa,CAACtwB,MAAU;AACtB,oBAAAA,EAAM,aAAa,gBAAgB,QACnCA,EAAM,aAAa,QAAQ,cAAcswB,EAAM,EAAE;AACjD,0BAAM3mB,IAAM3J,EAAM,cAAc,QAAQ,mBAAmB;AAC3D,oBAAI2J,KAAK3J,EAAM,aAAa,aAAa2J,GAAK,IAAI,EAAE,GACpDmmB,EAAWQ,EAAM,EAAE;AAAA,kBACrB;AAAA,kBACA,WAAW,MAAM;AACf,oBAAAR,EAAW,IAAI,GACfE,EAAc,IAAI;AAAA,kBACpB;AAAA,kBACA,WAAW,CAAChwB,MAAU;AACpB,oBAAIA,EAAM,QAAQ,aAAaA,EAAM,QAAQ,gBAC7CA,EAAM,eAAA,GACNpC,EAAK0yB,EAAM,IAAI5G,KAAS1pB,EAAM,QAAQ,YAAY,KAAK,EAAE;AAAA,kBAC3D;AAAA,kBAEA,UAAA,gBAAA/Q,EAACgQ,IAAA,EAAK,MAAK,QAAO,MAAM,GAAA,CAAI;AAAA,gBAAA;AAAA,cAAA;AAAA,cAE9B,gBAAAhQ,EAAC,UAAK,WAAU,mBACb,gBAAaqhC,EAAM,MAAM,CAAC11B,IACzB,gBAAA3L;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAS;AAAA,kBACT,cAAW;AAAA,kBACX,OAAOkhC;AAAA,kBACP,UAAU,CAACnwB,MAAUowB,EAAapwB,EAAM,OAAO,KAAK;AAAA,kBACpD,QAAQ,MAAMuwB,EAAOD,CAAK;AAAA,kBAC1B,WAAW,CAACtwB,MAAU;AACpB,oBAAIA,EAAM,QAAQ,WAASuwB,EAAOD,CAAK,GACnCtwB,EAAM,QAAQ,YAAUkwB,EAAY,IAAI;AAAA,kBAC9C;AAAA,gBAAA;AAAA,cAAA,IAGF,gBAAAn7B;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,UAAU6F;AAAA,kBACV,cAAY,UAAU01B,EAAM,SAASA,EAAM,EAAE;AAAA,kBAC7C,SAAS,MAAM;AACb,oBAAAF,EAAaE,EAAM,SAASA,EAAM,EAAE,GACpCJ,EAAYI,EAAM,EAAE;AAAA,kBACtB;AAAA,kBAEC,UAAA;AAAA,oBAAAA,EAAM,SAASA,EAAM;AAAA,oBACrB,CAAC11B,KAAY,gBAAA3L,EAACgQ,MAAK,MAAK,QAAO,MAAM,GAAA,CAAI;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA,GAGhD;AAAA,cACA,gBAAAhQ;AAAA,gBAACygC;AAAA,gBAAA;AAAA,kBACC,OAAO,UAAUY,EAAM,SAASA,EAAM,EAAE;AAAA,kBACxC,UAAU11B;AAAA,kBACV,SAAS,MAAM8Z,EAAKkb,EAAW,OAAO,CAAClnC,MAAMA,EAAE,OAAO4nC,EAAM,EAAE,CAAC;AAAA,gBAAA;AAAA,cAAA;AAAA,YACjE,GACF;AAAA,YACA,gBAAArhC;AAAA,cAAC25B;AAAA,cAAA;AAAA,gBACC,QAAQ,EAAE,WAAW0H,EAAM,aAAa,GAAA;AAAA,gBACxC,UAAU,CAAC18B,MAAS6I,EAAM6zB,EAAM,IAAI,EAAE,WAAW18B,EAAK,WAAW;AAAA,gBACjE,UAAAgH;AAAA,gBACA,SAAQ;AAAA,cAAA;AAAA,YAAA;AAAA,UACV;AAAA,QAAA;AAAA,QApFK01B,EAAM;AAAA,MAAA;AAAA,KAsFd,GACH;AAAA,IACA,gBAAAv7B;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,UAAU6F;AAAA,QACV,SAAS,MAAM;AACb,cAAI8B,IAAI;AACR,iBAAOxT,EAAO,KAAK,CAACR,MAAMA,EAAE,OAAO,SAASgU,CAAC,EAAE,IAAG,CAAAA;AAClD,UAAAgY,EAAK,CAAC,GAAGkb,GAAY,EAAE,IAAI,SAASlzB,CAAC,IAAI,OAAO,SAASA,CAAC,IAAI,WAAW,GAAA,CAAO,CAAC;AAAA,QACnF;AAAA,QAEA,UAAA;AAAA,UAAA,gBAAAzN,EAAC,QAAA,EAAK,eAAY,QAAO,UAAA,KAAC;AAAA,UAAO;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACnC,GACF;AAEJ;AC/IO,SAASuhC,GAAe;AAAA,EAC7B,OAAA19B;AAAA,EACA,UAAA29B;AAAA,EACA,UAAA71B;AACF,GAIG;AACD,QAAM,CAACq1B,GAAUC,CAAW,IAAIhiC,EAAS,EAAK,GACxC,CAAC+6B,GAAOC,CAAQ,IAAIh7B,EAAS4E,CAAK,GAClC,CAACmZ,GAAOmM,CAAQ,IAAIlqB,EAAwB,IAAI,GAChDywB,IAAS,MAAM;AACnB,UAAM/1B,IAAKqgC,EAAM,KAAA,GACXyH,IAAM9nC,KAAMA,MAAOkK,IAAQ29B,EAAS7nC,CAAE,IAAI;AAChD,QAAI8nC,GAAK;AACP,MAAAtY,EAASsY,CAAG;AACZ;AAAA,IACF;AACA,IAAAtY,EAAS,IAAI,GACb8X,EAAY,EAAK;AAAA,EACnB;AACA,SACE,gBAAAn7B,EAAC,QAAA,EAAK,WAAU,mBACb,UAAA;AAAA,IAAAk7B,KAAY,CAACr1B,IACZ,gBAAA3L;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAS;AAAA,QACT,cAAW;AAAA,QACX,OAAOg6B;AAAA,QACP,UAAU,CAAC32B,MAAM;AACf,UAAA42B,EAAS52B,EAAE,OAAO,KAAK,GACvB8lB,EAAS,IAAI;AAAA,QACf;AAAA,QACA,QAAQuG;AAAA,QACR,WAAW,CAACrsB,MAAM;AAChB,UAAIA,EAAE,QAAQ,WAASqsB,EAAA,GACnBrsB,EAAE,QAAQ,aACZ42B,EAASp2B,CAAK,GACdslB,EAAS,IAAI,GACb8X,EAAY,EAAK;AAAA,QAErB;AAAA,MAAA;AAAA,IAAA,IAGF,gBAAAn7B,EAAAwB,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAtH,EAAC,UAAM,UAAA6D,EAAA,CAAM;AAAA,MACZ,CAAC8H,KACA,gBAAA3L;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAM;AAAA,UACN,cAAW;AAAA,UACX,SAAS,MAAM;AACb,YAAAi6B,EAASp2B,CAAK,GACdo9B,EAAY,EAAI;AAAA,UAClB;AAAA,UAEA,UAAA,gBAAAjhC,EAACgQ,IAAA,EAAK,MAAK,QAAO,MAAM,GAAA,CAAI;AAAA,QAAA;AAAA,MAAA;AAAA,IAC9B,GAEJ;AAAA,IAEDgN,KACC,gBAAAhd,EAAC,QAAA,EAAK,WAAU,YAAW,MAAK,SAAQ,OAAO,EAAE,OAAO,oBAAA,GACrD,UAAAgd,EAAA,CACH;AAAA,EAAA,GAEJ;AAEJ;AC7EO,SAAS0kB,GAAW;AAAA,EACzB,QAAAnU;AAAA,EACA,UAAA1hB;AAAA,EACA,UAAAF;AACF,GAIG;AACD,QAAMg2B,IAAcpU,EAAO,cAAc,UAAaA,EAAO,cAAc;AAC3E,SACE,gBAAAznB,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,MAAA,gBAAA9F,EAAC,UAAK,UAAA,YAAA,CAAS;AAAA,MACf,gBAAA8F;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,cAAW;AAAA,UACX,UAAU6F;AAAA,UACV,OAAOg2B,IAAc,cAAc;AAAA,UACnC,UAAU,CAACt+B,MAAM;AACf,kBAAMsB,IAAOtB,EAAE,OAAO,UAAU;AAChC,YAAAwI,EAAS,EAAE,GAAG0hB,GAAQ,WAAW,CAAC5oB,GAAM;AAAA,UAC1C;AAAA,UAEA,UAAA;AAAA,YAAA,gBAAA3E,EAAC,UAAA,EAAO,OAAM,UAAS,UAAA,UAAM;AAAA,YAC7B,gBAAAA,EAAC,UAAA,EAAO,OAAM,aAAY,UAAA,sBAAA,CAAmB;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAC/C,GACF;AAAA,IACC2hC,IACC,gBAAA3hC,EAAC25B,IAAA,EAAgB,QAAApM,GAAgB,UAAA1hB,GAAoB,UAAAF,GAAoB,SAAQ,OAAA,CAAO,IAExF,gBAAA3L,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,qFAAA,CAEnC;AAAA,EAAA,GAEJ;AAEJ;ACrCO,MAAM4hC,KACX;AAGK,SAASC,GAAkBC,GAAsB;AACtD,SAAO,sEAAsEF,EAAgB,KAAKE,CAAI;AACxG;AAEO,SAASC,GAAY,EAAE,MAAAD,KAA0B;AACtD,SACE,gBAAA9hC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAM;AAAA,MACN,WAAU;AAAA,MACV,SAAQ;AAAA,MACR,gBAAe;AAAA,MACf,QAAQ6hC,GAAkBC,CAAI;AAAA,IAAA;AAAA,EAAA;AAGpC;ACQA,SAASE,GAAOn+B,GAA0B;AACxC,SAAI,OAAOA,KAAU,WAAiB,WAClC,OAAOA,KAAU,WAAiB,WAClC,OAAOA,KAAU,YAAkB,YAChC;AACT;AAKA,SAASo+B,GAAWp+B,GAAwB;AAC1C,SAAOm+B,GAAOn+B,CAAK,MAAM,WAAW,KAAK,UAAUA,CAAK,IAAI,OAAOA,CAAK;AAC1E;AAEA,SAASq+B,GAAYr+B,GAA8D;AACjF,SAAO,OAAOA,KAAU,YAAYA,MAAU;AAChD;AAEA,SAASs+B,GAAWC,GAAkB30B,GAAmB;AAEvD,SAAO,GAAGA,CAAC,IADE20B,IAAU,SAAS,KACb,GAAG30B,MAAM,IAAI,KAAK,GAAG;AAC1C;AAcO,SAAS40B,GAAS,EAAE,OAAAx+B,GAAO,aAAAy+B,IAAc,KAAoB;AAClE,2BAAQC,IAAA,EAAS,OAAO,QAAW,OAAA1+B,GAAc,OAAO,GAAG,aAAAy+B,GAA0B;AACvF;AAMA,SAASC,GAASryB,GAKf;AACD,QAAM,EAAE,OAAAR,GAAO,OAAA7L,GAAO,OAAA+a,GAAO,aAAA0jB,MAAgBpyB,GACvCsyB,IAAYN,GAAYr+B,CAAK,GAC7Bu+B,IAAU,MAAM,QAAQv+B,CAAK,GAC7B+0B,IAA6C4J,IAC/CJ,IACGv+B,EAAoB,IAAI,CAAC9I,GAAG2Z,MAAM,CAACA,GAAG3Z,CAAC,CAAsB,IAC9D,OAAO,QAAQ8I,CAAgC,IACjD,CAAA,GAEE0T,IAAM7H,MAAU,SAAY,yBAAQ,QAAA,EAAK,WAAU,gBAAgB,UAAAA,EAAA,CAAM;AAE/E,SAAI8yB,KAAa5J,EAAQ,SAAS,sBAE7B,WAAA,EAAQ,WAAU,iBAAgB,MAAMha,IAAQ0jB,GAG/C,UAAA;AAAA,IAAA,gBAAAx8B,EAAC,WAAA,EACE,UAAA;AAAA,MAAAyR;AAAA,MACA6qB,IAAU,QAAQ;AAAA,MAAO;AAAA,MAC1B,gBAAApiC,EAAC,UAAK,WAAU,kBAAkB,aAAWoiC,GAASxJ,EAAQ,MAAM,EAAA,CAAE;AAAA,IAAA,GACxE;AAAA,IAEA,gBAAA54B,EAAC,OAAA,EAAI,WAAU,qBACZ,UAAA44B,EAAQ,IAAI,CAAC,CAAC1f,GAAGne,CAAC,MACjB,gBAAAiF;AAAA,MAACuiC;AAAA,MAAA;AAAA,QAEC,OAAOrpB;AAAA,QACP,OAAOne;AAAA,QACP,OAAO6jB,IAAQ;AAAA,QACf,aAAA0jB;AAAA,MAAA;AAAA,MAJK,OAAOppB,CAAC;AAAA,IAAA,CAMhB,EAAA,CACH;AAAA,EAAA,GACF,IAOF,gBAAApT,EAAC,OAAA,EAAI,WAAU,iBACZ,UAAA;AAAA,IAAAyR;AAAA,IACAA,MAAQ,OAAO,OAAO;AAAA,sBACtB,QAAA,EAAK,WAAW,YAAYirB,IAAY,SAASR,GAAOn+B,CAAK,CAAC,IAC5D,cAAau+B,IAAU,OAAO,OAAQH,GAAWp+B,CAAK,EAAA,CACzD;AAAA,EAAA,GACF;AAEJ;ACtHO,MAAM4+B,KAA0B,QAEjCC,KAAa,gBACbC,KAAW,QACXC,KAAe,4BACfC,KAAU;AAET,SAASC,GAAmBj/B,GAAgC;AACjE,MAAIA,MAAU,OAAW,QAAO,EAAE,QAAQ,QAAQ,MAAM,GAAA;AACxD,MAAI,OAAOA,KAAU,SAAU,QAAO,EAAE,QAAQ,QAAQ,MAAMA,EAAA;AAC9D,QAAM,IAAIA,EAAM,KAAA;AAChB,MAAI,EAAE,WAAW,GAAG,KAAK,EAAE,WAAW,GAAG;AACvC,QAAI;AACF,YAAM2O,IAAkB,KAAK,MAAM,CAAC;AACpC,UAAIA,MAAW,QAAQ,OAAOA,KAAW,iBAAiB,EAAE,QAAQ,QAAQ,MAAMA,EAAA;AAAA,IACpF,QAAQ;AAAA,IAER;AAEF,MAAI,mBAAmB,KAAK,CAAC,KAAK,eAAe,KAAK,CAAC,EAAG,QAAO,EAAE,QAAQ,QAAQ,MAAM3O,EAAA;AACzF,MAAI,EAAE,WAAW,GAAG,KAAK,EAAE,SAAS,GAAG,EAAG,QAAO,EAAE,QAAQ,OAAO,MAAMA,EAAA;AACxE,QAAMkG,IAAQ,EAAE,MAAM;AAAA,CAAI;AAC1B,SACEA,EAAM,KAAK,CAAC3O,MAAMsnC,GAAW,KAAKtnC,CAAC,KAAKunC,GAAS,KAAKvnC,CAAC,CAAC,KACxD2O,EAAM,OAAO,CAAC3O,MAAMwnC,GAAa,KAAKxnC,CAAC,CAAC,EAAE,UAAU,KACpDynC,GAAQ,KAAK,CAAC,IAEP,EAAE,QAAQ,YAAY,MAAMh/B,EAAA,IAE9B,EAAE,QAAQ,QAAQ,MAAMA,EAAA;AACjC;AAGO,SAASk/B,GAAev0B,GAA2B;AACxD,SAAOA,EAAE,WAAW,SAAU,KAAK,UAAUA,EAAE,MAAM,MAAM,CAAC,KAAK,KAAMA,EAAE;AAC3E;ACLA,MAAMw0B,KAA6B;AAUnC,SAASC,GAAa/6B,GAAckJ,GAA4C;AAC9E,SAAIlJ,EAAK,SAAS86B,KACT,gBAAAhjC,EAAC,OAAA,EAAI,WAAU,0BAA0B,UAAAkI,GAAK,IAEhD,gBAAAlI,EAACkjC,MAAU,MAAMh7B,GAAM,UAAAkJ,GAAoB,UAAU,IAAO,MAAI,IAAC;AAC1E;AAmCO,SAAS+xB,GAAajzB,GAA0B;AACrD,QAAM,EAAE,OAAArM,GAAO,QAAAsK,IAAS,QAAQ,WAAAi1B,IAAY,KAAK,WAAA76B,MAAc2H,GAGzD1B,IAAIiD;AAAA,IACR,MACEtD,MAAW,SAAS,EAAE,QAAQ,QAAiB,MAAMtK,EAAA,IAAUi/B,GAAmBj/B,CAAK;AAAA,IACzF,CAACA,GAAOsK,CAAM;AAAA,EAAA,GAGV,CAACpP,GAAMC,CAAO,IAAIC,EAAe,UAAU,GAI3C,CAACqjC,GAAae,CAAc,IAAIpkC,EAAS,CAAC,GAC1C,CAACqkC,GAAWC,CAAY,IAAItkC,EAAS,CAAC,GAEtCiJ,IAAOsG,EAAE,WAAW,SAAS,KAAKA,EAAE,MACpCg1B,IAAah1B,EAAE,WAAW,UAAUA,EAAE,WAAW,YACjDi1B,IAAYD,KAAct7B,EAAK,SAASu6B,IAOxCiB,IAAWjyB,GAAQ,MAAM;AAC7B,QAAI;AACF,aAAOsxB,GAAev0B,CAAC;AAAA,IACzB,QAAQ;AACN,aAAO,OAAO3K,KAAU,WAAWA,IAAQ,OAAOA,CAAK;AAAA,IACzD;AAAA,EACF,GAAG,CAAC2K,GAAG3K,CAAK,CAAC;AAEb,MAAIyB;AACJ,MAAIkJ,EAAE,WAAW;AACf,IAAAlJ,sBAAQ+8B,IAAA,EAAyB,OAAO7zB,EAAE,MAAM,aAAA8zB,KAA1BgB,CAAoD;AAAA,WACjE90B,EAAE,WAAW;AAGtB,IAAAlJ,IAAO29B,GAAaz0B,EAAE,MAAM,QAAQ;AAAA,WAC3BA,EAAE,WAAW;AACtB,IAAAlJ,IAAO,gBAAAtF,EAAC,OAAA,EAAI,WAAU,0BAA0B,YAAE,MAAK;AAAA,OAClD;AACL,UAAMoR,IAAW5C,EAAE,WAAW,SAAS,WAAW;AAClD,IAAIi1B,IAGFn+B,IACE,gBAAAQ,EAAAwB,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAtH,EAAC,OAAA,EAAI,WAAU,8CAA6C,UAAA,yCAE5D;AAAA,MACCijC,GAAaz0B,EAAE,MAAM4C,CAAQ;AAAA,IAAA,GAChC,IAEOrS,MAAS,WAClBuG,IAAO29B,GAAaz0B,EAAE,MAAM4C,CAAQ,IAC3B5C,EAAE,WAAW,SAEtBlJ,IAAO,gBAAAtF,EAAC+hC,IAAA,EAAY,MAAMvzB,EAAE,MAAM,IAElClJ,IAAO,gBAAAtF,EAACsI,IAAA,EAAS,SAASkG,EAAE,MAAM;AAAA,EAEtC;AAEA,MAAIm1B,IAAiB;AACrB,SAAIn1B,EAAE,WAAW,SACfm1B,IACE,gBAAA79B,EAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,IAAA,gBAAA9F;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM;AACb,UAAAqjC,EAAe,OAAO,iBAAiB,GACvCE,EAAa,CAAC91B,MAAMA,IAAI,CAAC;AAAA,QAC3B;AAAA,QACD,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGD,gBAAAzN;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM;AACb,UAAAqjC,EAAe,CAAC,GAChBE,EAAa,CAAC91B,MAAMA,IAAI,CAAC;AAAA,QAC3B;AAAA,QACD,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAED,GACF,IAEO+1B,KAAc,CAACC,MACxBE,IACE,gBAAA79B,EAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,IAAA,gBAAA9F;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAW,wBAAwBjB,MAAS,aAAa,YAAY,EAAE;AAAA,QACvE,aAAU;AAAA,QACV,gBAAcA,MAAS;AAAA,QACvB,SAAS,MAAMC,EAAQ,UAAU;AAAA,QAClC,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGD,gBAAAgB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAW,wBAAwBjB,MAAS,WAAW,YAAY,EAAE;AAAA,QACrE,aAAU;AAAA,QACV,gBAAcA,MAAS;AAAA,QACvB,SAAS,MAAMC,EAAQ,QAAQ;AAAA,QAChC,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAED,GACF,IAKF,gBAAA8G;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,CAAC,qBAAqByC,KAAa,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAC1E,eAAaiG,EAAE;AAAA,MAEd,UAAA;AAAA,QAAAm1B;AAAA,0BACAnb,IAAA,EAAS,OAAOkb,GAAU,OAAM,eAAc,WAAU,uBACvD,UAAA,gBAAA1jC,EAAC,SAAI,WAAU,0BAAyB,OAAO,EAAE,WAAAojC,GAAW,UAAU,UACnE,aACH,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AC1MO,SAASQ,GACdC,GACAlc,GAC4B;AAC5B,QAAMmc,IAAQD,EAAK,OAAO,CAAC,MAAM,EAAE,UAAUprC,EAAW;AACxD,SAAOqrC,EAAM,KAAK,CAAC,MAAM,EAAE,WAAWnc,CAAM,KAAKmc,EAAM,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,KAAKA,EAAM,CAAC,KAAK;AAC/F;AAGA,MAAMC,KAAmB,iEACnBC,KAAO;AAGN,SAASC,GAAeC,GAAyD;AACtF,QAAM/oC,IAA8B,CAAA;AACpC,aAAW,CAAC+d,GAAGne,CAAC,KAAK,OAAO,QAAQmpC,CAAO,EAAG,CAAA/oC,EAAI+d,CAAC,IAAI6qB,GAAiB,KAAK7qB,CAAC,IAAI8qB,KAAOjpC;AACzF,SAAOI;AACT;AAGA,MAAMgpC,KAAc;AAkBb,SAASC,GAAmB;AAAA,EACjC,YAAAtjC;AAAA,EACA,QAAA6mB;AAAA,EACA,UAAA0c;AAAA,EACA,UAAA14B;AAAA,EACA,OAAA24B;AAAA,EACA,OAAAC;AACF,GASG;AACD,QAAMlkC,IAAMG,GAAA,GAEN,CAACgkC,GAAKC,CAAM,IAAIxlC,EAAiD,MAAS,GAC1E,CAACylC,GAAUC,CAAW,IAAI1lC,EAAS,EAAK,GACxC,CAACrB,GAAOksB,CAAQ,IAAI7qB,EAAsB,EAAE,OAAO,QAAQ,GAC3D,CAAC4wB,GAAK+U,CAAM,IAAI3lC,EAAS,MAAM,KAAK,KAAK,GAEzC+M,IAAOlJ,GAA4E,IAAI;AAE7F,EAAA5D,GAAU,MAAM;AACd,UAAM8tB,IAAO3sB,EAAI;AACjB,QAAI,CAAC2sB,EAAM;AACX,QAAI5pB,IAAW;AACf,WAAA4pB,EAAKlsB,CAAU,EACZ,KAAK,CAAC+iC,MAAS,CAACzgC,KAAYqhC,EAAOb,GAAwBC,GAAMlc,CAAM,CAAC,CAAC,EACzE,MAAM,CAACtkB,MAAM,CAACD,KAAY0mB,EAAS,EAAE,OAAO,SAAS,SAAUzmB,EAAY,QAAA,CAAS,CAAC,GACjF,MAAM;AACX,MAAAD,IAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAKS,GAAY6mB,CAAM,CAAC;AAE5B,QAAMkd,IAAO1gC;AAAA,IACX,CAACkqB,MAAoB;;AACnB,YAAMrkB,IAAMgC,EAAK;AAEjB,MADAA,EAAK,UAAU,MACVhC,MACLA,EAAI,MAAM,MAAA,GACNqkB,aAAY,wCAAoBrkB,EAAI,OAAOA,EAAI,WAAW,MAAM,MAAM;AAAA,MAAC;AAAA,IAC7E;AAAA,IACA,CAAC3J,CAAG;AAAA,EAAA;AAIN,EAAAnB,GAAU,MAAM,MAAM2lC,EAAK,EAAI,GAAG,CAACA,CAAI,CAAC,GAGxC3lC,GAAU,MAAM;AACd,QAAItB,EAAM,UAAU,UAAW;AAC/B,UAAMgH,IAAI,YAAY,MAAMggC,EAAO,KAAK,IAAA,CAAK,GAAG,GAAI;AACpD,WAAO,MAAM,cAAchgC,CAAC;AAAA,EAC9B,GAAG,CAAChH,EAAM,KAAK,CAAC;AAEhB,QAAMknC,IAAY,MAAM;AACtB,UAAMC,IAAS1kC,EAAI;AACnB,IAAK0kC,MACLJ,EAAY,EAAI,GAChBI,EAAOtsC,IAAa,WAAW,EAAE,YAAAqI,GAAY,cAAc,MAAM,QAAQujC,KAAY,CAAA,EAAC,CAAG,EACtF,KAAK,CAACW,MAAYP,EAAOO,CAAO,CAAC,EACjC,MAAM,CAAC3hC,MAAMymB,EAAS,EAAE,OAAO,SAAS,SAAUzmB,EAAY,QAAA,CAAS,CAAC,EACxE,QAAQ,MAAMshC,EAAY,EAAK,CAAC;AAAA,EACrC,GAEMM,IAAS,YAAY;;AACzB,UAAMvoB,IAAQrc,EAAI,oBACZ6kC,IAAO7kC,EAAI;AACjB,QAAI,CAACmkC,KAAO,CAAC9nB,KAAS,CAACwoB,EAAM;AAC7B,IAAAL,EAAK,EAAI,GACT/a,EAAS,EAAE,OAAO,YAAY;AAC9B,QAAIqb;AACJ,QAAI;AACF,MAAAA,KAAU,MAAMzoB,EAAM8nB,EAAI,EAAE,GAAG;AAAA,IACjC,SAASnhC,GAAG;AACV,MAAAymB,EAAS,EAAE,OAAO,SAAS,SAAUzmB,EAAY,SAAS;AAC1D;AAAA,IACF;AACA,UAAM+hC,IAAQ,IAAI,gBAAA,GACZC,IAAO,EAAE,OAAOb,EAAI,IAAI,WAAWW,EAAO,IAAI,OAAAC,EAAA;AAIpD,SAHAp5B,EAAK,UAAUq5B,GACfT,EAAO,KAAK,KAAK,GACjB9a,EAAS,EAAE,OAAO,WAAW,SAASqb,GAAQ,OACrC;AACP,UAAIjlC;AACJ,UAAI;AACF,QAAAA,IAAI,MAAMglC,EAAKV,EAAI,IAAIW,EAAO,IAAI,EAAE,aAAahB,IAAa,QAAQiB,EAAM,OAAA,CAAQ;AAAA,MACtF,SAAS/hC,GAAG;AACV,YAAI2I,EAAK,YAAYq5B,EAAM;AAC3B,QAAAr5B,EAAK,UAAU,MACf8d,EAAS,EAAE,OAAO,SAAS,SAAUzmB,EAAY,SAAS;AAC1D;AAAA,MACF;AACA,UAAI2I,EAAK,YAAYq5B,EAAM;AAC3B,UAAInlC,EAAE,WAAW,cAAcA,EAAE,SAAS;AACxC,QAAA8L,EAAK,UAAU,MACf8d,EAAS,EAAE,OAAO,YAAY,SAAS5pB,GAAG,SAASA,EAAE,SAAS;AAC9D;AAAA,MACF;AACA,UAAIA,EAAE,WAAW,WAAW;AAC1B,QAAA8L,EAAK,UAAU,OACfxS,IAAA6G,EAAI,sBAAJ,QAAA7G,EAAA,KAAA6G,GAAwBmkC,EAAI,IAAIW,EAAO,IAAI,MAAM,MAAM;AAAA,QAAC,IACxDrb,EAAS,EAAE,OAAO,WAAW;AAC7B;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAEM3e,IAAO,MAAM;AACjB,IAAA05B,EAAK,EAAI,GACT/a,EAAS,EAAE,OAAO,QAAQ;AAAA,EAC5B;AAEA,MAAI,CAACzpB,EAAI,sBAAsB,CAACA,EAAI,kBAAmB,QAAO;AAC9D,QAAMsH,IAAM68B,KAAA,gBAAAA,EAAK,YACX3Y,IACJjuB,EAAM,UAAU,YACZ,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,MAAMA,EAAM,QAAQ,SAAS,IAAIiyB,KAAO,GAAI,CAAC,IACzE;AAEN,SACE,gBAAA/pB,EAAC,OAAA,EAAI,WAAU,wBAAuB,eAAY,kBAC/C,UAAA;AAAA,IAAA0+B,MAAQ,SACP,gBAAAxkC,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,WAAA,CAAQ,IACxC2H,IAYH,gBAAA7B,EAAAwB,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAtH,EAACwoB,IAAA,EAAS,OAAO7gB,GAAK,UAAQ,IAC5B,UAAA,gBAAA3H,EAAC,SAAA,EAAM,MAAK,QAAO,UAAQ,IAAC,OAAO2H,GAAK,cAAW,eAAc,GACnE;AAAA,MACC/J,EAAM,UAAU,aAAaA,EAAM,UAAU,aAC5C,gBAAAkI,EAAC,OAAA,EAAI,WAAU,sBACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,QAAA,EAAK,WAAU,oBAAmB,eAAY,QAAO;AAAA,QACtD,gBAAA8F,EAAC,UAAA,EAAO,WAAU,aAAY,UAAA;AAAA,UAAA;AAAA,UACH,gBAAA9F,EAAC,UAAM,UAAA2H,EAAA,CAAI;AAAA,UAAO;AAAA,UAC1C/J,EAAM,UAAU,aACf,gBAAAkI,EAAC,QAAA,EAAK,WAAU,aAAY,UAAA;AAAA,YAAA;AAAA,YAAEw/B,GAAWzZ,CAAI;AAAA,YAAE;AAAA,UAAA,EAAA,CAAK;AAAA,QAAA,GAExD;AAAA,QACA,gBAAA7rB,EAAC,YAAO,MAAK,UAAS,WAAU,yBAAwB,SAASmL,GAAM,UAAA,OAAA,CAEvE;AAAA,MAAA,EAAA,CACF,IAEA,gBAAArF,EAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAA,gBAAA9F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,UAAU2L;AAAA,YACV,SAAS,MAAM,KAAKs5B,EAAA;AAAA,YAEnB,UAAArnC,EAAM,UAAU,aAAa,iBAAiB;AAAA,UAAA;AAAA,QAAA;AAAA,QAEhDA,EAAM,UAAU,4BACd,QAAA,EAAK,WAAU,uBAAsB,UAAA,+EAAA,CAEtC;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA,GAEJ,IA7CA,gBAAAkI,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,4EAEnC;AAAA,MACC,CAAC2L,KAAYtL,EAAI,sBAChB,gBAAAL,EAAC,YAAO,MAAK,UAAS,WAAU,WAAU,UAAU0kC,GAAU,SAASI,GACpE,UAAAJ,IAAW,cAAc,qBAAA,CAC5B;AAAA,IAAA,EAAA,CAEJ;AAAA,IAuCD9mC,EAAM,UAAU,+BACd,KAAA,EAAE,WAAU,uBAAsB,UAAA,oEAEnC;AAAA,IAEDA,EAAM,UAAU,WAAW,gBAAAoC,EAAC,SAAI,WAAU,wBAAwB,YAAM,QAAA,CAAQ;AAAA,IAEhFpC,EAAM,UAAU,cACf,gBAAAoC;AAAA,MAACulC;AAAA,MAAA;AAAA,QACC,SAAS3nC,EAAM;AAAA,QACf,YAAYA,EAAM,QAAQ;AAAA,QAC1B,UAAA+N;AAAA,QACA,OAAA44B;AAAA,QACA,OAAO,MAAMD,EAAM1mC,EAAM,OAAO;AAAA,QAChC,QAAA+pB;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GAEJ;AAEJ;AAEA,SAAS2d,GAAWplC,GAAmB;AACrC,QAAMiI,IAAI,KAAK,MAAMjI,IAAI,EAAE;AAC3B,SAAOiI,IAAI,IAAI,GAAGA,CAAC,IAAI,OAAOjI,IAAI,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,KAAK,GAAGA,CAAC;AACjE;AAEA,SAASqlC,GAAgB;AAAA,EACvB,SAAA/gC;AAAA,EACA,YAAAghC;AAAA,EACA,UAAA75B;AAAA,EACA,OAAA44B;AAAA,EACA,OAAAD;AAAA,EACA,QAAA3c;AACF,GAOG;AACD,QAAM8d,IAAW,OAAO,KAAKjhC,EAAQ,SAAS,CAAA,CAAE,EAAE,SAAS;AAC3D,SACE,gBAAAsB,EAAC,OAAA,EAAI,WAAU,mCAAkC,eAAY,oBAC3D,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA;AAAA,MAAA;AAAA,MAEhC0/B,KACC,gBAAA1/B,EAAC,QAAA,EAAK,WAAU,aAAY,UAAA;AAAA,QAAA;AAAA,QAAI,IAAI,KAAK0/B,CAAU,EAAE,mBAAA;AAAA,MAAmB,EAAA,CAAE;AAAA,IAAA,GAE9E;AAAA,IACA,gBAAA1/B,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,QAAA,EAAM,YAAQ,OAAA,CAAO;AAAA,MAAO;AAAA,MAAC,gBAAAA,EAAC,QAAA,EAAM,UAAAwE,EAAQ,KAAA,CAAK;AAAA,IAAA,GACpD;AAAA,IACCihC,KACC,gBAAA3/B,EAAAwB,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAtH,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA,SAAK;AAAA,wBACvCmjC,IAAA,EAAa,OAAO3+B,EAAQ,OAAO,WAAW,IAAA,CAAK;AAAA,IAAA,GACtD;AAAA,IAEF,gBAAAxE,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA,WAAO;AAAA,IAC1C,gBAAAA,EAACmjC,IAAA,EAAa,OAAOc,GAAez/B,EAAQ,WAAW,EAAE,GAAG,WAAW,KAAK;AAAA,IAC5E,gBAAAxE,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA,QAAI;AAAA,sBACtCmjC,IAAA,EAAa,OAAO3+B,EAAQ,MAAM,WAAW,KAAK;AAAA,IAClD,CAACmH,KACA,gBAAA7F,EAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,WAAU,UAAUukC,GAAO,SAASD,GACjE,UAAAC,IAAQ,YAAY,oBACvB;AAAA,MACA,gBAAAz+B,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA;AAAA,QAAA;AAAA,QACkB;AAAA,QACtD,gBAAA9F,EAAC,QAAA,EAAM,UAAA,YAAY2nB,CAAM,oBAAmB;AAAA,QAAO;AAAA,MAAA,EAAA,CACrD;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;AC/RO,SAAS+d,GAAYnnB,GAAoC;AAC9D,SAAO,MAAM,QAAQA,CAAM,IAAKA,IAA+B,CAAA;AACjE;AAeO,SAASonB,GAAYxO,GAA+C;AACzE,SAAIA,MAAS,YAAYA,MAAS,UAAgB,SAC3CA,MAAS,YAAYA,MAAS,aAAaA,MAAS,SAASA,IAAO;AAC7E;AAkBO,SAASyO,GAAczO,GAA0BpuB,GAAuB;AAC7E,MAAI,EAAqBA,KAAQ,QAAQA,MAAQ,KACjD;AAAA,QAAI,OAAOA,KAAQ,SAAU,QAAOA;AACpC,QAAIouB,MAAS,UAAU;AACrB,YAAM,IAAI,OAAOpuB,CAAG;AACpB,aAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAAA,IAClC;AACA,QAAIouB,MAAS,UAAW,QAAOpuB,MAAQ,MAAQA,MAAQ;AACvD,QAAIouB,MAAS;AACX,UAAI;AACF,eAAO,KAAK,MAAM,OAAOpuB,CAAG,CAAC;AAAA,MAC/B,QAAQ;AACN;AAAA,MACF;AAEF,WAAO,OAAOA,CAAG;AAAA;AACnB;AAOO,SAAS88B,GAAeC,GAAwC;AACrE,SAAOA,EACJ,OAAO,CAACrnB,MAAM,OAAOA,EAAE,OAAQ,YAAYA,EAAE,IAAI,WAAW,EAAE,EAC9D,IAAI,CAACA,OAAO;AAAA,IACX,KAAKA,EAAE;AAAA,IACP,OAAOA,EAAE;AAAA,IACT,MAAMknB,GAAYlnB,EAAE,IAAI;AAAA,IACxB,UAAU,CAAC,CAACA,EAAE;AAAA,EAAA,EACd;AACN;AAGO,SAASsnB,GAAWD,GAAkD;AAC3E,QAAM3qC,IAA+B,CAAA;AACrC,aAAWsjB,KAAKqnB,GAAM;AACpB,QAAI,OAAOrnB,EAAE,OAAQ,YAAYA,EAAE,IAAI,KAAA,MAAW,GAAI;AACtD,UAAM1jB,IAAI6qC,GAAcnnB,EAAE,MAAMA,EAAE,OAAO;AACzC,IAAI1jB,MAAM,WAAWI,EAAIsjB,EAAE,GAAG,IAAI1jB;AAAA,EACpC;AACA,SAAOI;AACT;ACrEO,SAAS6qC,GACdvrB,GACAwrB,GACqC;AACrC,QAAMvrB,KAAOD,KAAQ,CAAA,GAAI,KAAK,CAAChhB,MAAMA,KAAKA,EAAE,WAAWwsC,CAAM;AAC7D,MAAI,CAACvrB,EAAK;AACV,QAAMwrB,IAAQxrB,EAAI;AAClB,SAAOwrB,KAAS,OAAOA,KAAU,YAAY,CAAC,MAAM,QAAQA,CAAK,IAAIA,IAAQ,CAAA;AAC/E;AAGA,SAASC,GAAUprC,GAAqB;AACtC,SAAOga,GAAYha,CAAC,KAAM,OAAOA,KAAM,YAAYA,EAAE,SAAS,IAAI;AACpE;AAQO,SAASqrC,GACd7Y,GACAH,IAAiC,IACR;AACzB,QAAMiZ,IAAa,IAAI,IAAIjZ,EAAO,OAAO,CAACnwB,MAAMA,EAAE,SAAS,QAAQ,EAAE,IAAI,CAACA,MAAMA,EAAE,GAAG,CAAC,GAChF9B,IAA+B,CAAA;AACrC,aAAW,CAAC+d,GAAGne,CAAC,KAAK,OAAO,QAAQwyB,CAAM;AACxC,IAAIxyB,MAAM,UAAaia,GAAcja,CAAC,KAClCsrC,EAAW,IAAIntB,CAAC,KAAK,CAACitB,GAAUprC,CAAC,MACrCI,EAAI+d,CAAC,IAAIne;AAEX,SAAOI;AACT;AASA,MAAMmrC,yBAAoB,IAAA;AAGnB,SAASC,GAAsB9gB,GAA8B;AAClE,QAAM+gB,IAAU/gB,EAAK;AAAA,IACnB;;IACA,MAAA;AAAA;AAAA,EAAM;AAER,SAAA6gB,GAAc,IAAIE,CAAO,GACpBA,EAAQ,KAAK,MAAMF,GAAc,OAAOE,CAAO,CAAC,GAC9C/gB;AACT;AAGA,eAAsBghB,KAAuC;AAC3D,QAAM,QAAQ,IAAI,CAAC,GAAGH,EAAa,CAAC;AACtC;AC5DO,SAASI,GACd5lC,GACAmlC,GACqB;AACrB,QAAM5lC,IAAMG,GAAA,GACNmmC,IAAY,OAAOtmC,EAAI,kBAAmB,cAAc,CAAC,CAACS,KAAc,CAAC,CAACmlC,GAC1E,CAACW,GAAQC,CAAS,IAAI5nC,EAAS,CAAC0nC,CAAS,GACzC,CAACT,GAAOY,CAAQ,IAAI7nC,EAA8C,MAAS;AACjF,EAAAC,GAAU,MAAM;AACd,QAAI,CAACynC,KAAa,CAAC7lC,KAAc,CAACmlC,KAAU,CAAC5lC,EAAI,gBAAgB;AAC/D,MAAAwmC,EAAU,EAAI;AACd;AAAA,IACF;AACA,QAAIzjC,IAAW;AACf,WAAAyjC,EAAU,EAAK,GAEfJ,KACG,KAAK,MAAA;;AAAM,eAAAjtC,IAAA6G,EAAI,mBAAJ,gBAAA7G,EAAA,KAAA6G,GAAqBS,OAAe;KAAE,EACjD,KAAK,CAAC2Z,MAAS;AACd,MAAIrX,MACJ0jC,EAASd,GAAcvrB,GAAMwrB,CAAM,CAAC,GACpCY,EAAU,EAAI;AAAA,IAChB,CAAC,EAEA,MAAM,MAAM;AACX,MAAKzjC,KAAUyjC,EAAU,EAAI;AAAA,IAC/B,CAAC,GACI,MAAM;AACX,MAAAzjC,IAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAKsmC,GAAW7lC,GAAYmlC,CAAM,CAAC;AAEvC,QAAMc,IAAQ5iC;AAAA,IACZ,CAACQ,MAAkC;AAEjC,MADAmiC,EAASniC,CAAI,GACT,GAAC7D,KAAc,CAACmlC,KAAU,OAAO5lC,EAAI,iBAAkB,eAC3DkmC,GAAmBlmC,EAAI,cAAcS,GAAYmlC,GAAQthC,CAAI,CAAC,EAAE,MAAM,CAAC88B,MAAQ;AAC7E,gBAAQ,MAAM,0BAA0BA,CAAG;AAAA,MAC7C,CAAC;AAAA,IACH;AAAA,IACA,CAACphC,GAAKS,GAAYmlC,CAAM;AAAA,EAAA,GAEpBxgB,IAAOthB;AAAA,IACX,CAACopB,GAAiCH,MAChC2Z,EAAMX,GAAkB7Y,GAAQH,CAAM,CAAC;AAAA,IACzC,CAAC2Z,CAAK;AAAA,EAAA,GAEFpR,IAAQxxB,GAAY,MAAM4iC,EAAM,CAAA,CAAE,GAAG,CAACA,CAAK,CAAC;AAClD,SAAO,EAAE,QAAAH,GAAQ,WAAAD,GAAW,OAAAT,GAAO,MAAAzgB,GAAM,OAAAkQ,EAAA;AAC3C;AAGO,SAASqR,GAAa,EAAE,SAAAC,KAAoC;AACjE,SACE,gBAAAnhC,EAAC,KAAA,EAAE,WAAU,uBAAsB,eAAY,kBAAiB,UAAA;AAAA,IAAA;AAAA,IAC3C;AAAA,IACnB,gBAAA9F,EAAC,YAAO,MAAK,UAAS,WAAU,eAAc,SAASinC,GAAS,UAAA,QAAA,CAEhE;AAAA,EAAA,GACF;AAEJ;AC/EO,MAAMC,KAAwB;AAoD9B,SAASC,GAAgB;AAAA,EAC9B,KAAAnwC;AAAA,EACA,QAAAuE;AAAA,EACA,QAAAgjB;AAAA,EACA,SAAA6oB;AAAA,EACA,QAAAnC;AACF,GAaG;AACD,QAAM5kC,IAAMG,GAAA,GAGNK,IAAUE,GAAA,GACV+kC,IAAOr0B,GAAQ,MAAMi0B,GAAYnnB,CAAM,GAAG,CAACA,CAAM,CAAC,GAClD6O,IAAS3b,GAAQ,MAAMo0B,GAAeC,CAAI,GAAG,CAACA,CAAI,CAAC,GACnDuB,IAAYja,EAAO,SAAS,GAI5B,CAACG,GAAQ+Z,CAAS,IAAIroC,EAAkC,MAAM8mC,GAAWD,CAAI,CAAC,GAE9E,CAACloC,GAAOksB,CAAQ,IAAI7qB,EAA2B,IAAI,GAKnDsoC,IAAoBH,KAAA,gBAAAA,EAAS,YAC7BI,IAAgBJ,KAAA,gBAAAA,EAAS,QAIzBK,IAAaf,GAAuBa,GAAmBC,CAAa,GACpE,CAACE,GAAWC,CAAY,IAAI1oC,EAAS,EAAK,GAI1C,CAAC2oC,GAAYC,CAAa,IAAI5oC,EAAS,EAAK,GAE5C,CAACsZ,GAAQuvB,CAAS,IAAI7oC,EAAS,CAACsoC,KAAqB,CAACC,CAAa;AAEzE,EAAAtoC,GAAU,MAAM;AACd,QAAI,CAACqoC,KAAqB,CAACC,GAAe;AACxC,MAAAM,EAAU,EAAI;AACd;AAAA,IACF;AACA,QAAI,CAACL,EAAW,OAAQ;AACxB,QAAIA,EAAW,UAAU,QAAW;AAClC,YAAMvB,IAAQuB,EAAW;AACzB,MAAI,OAAO,KAAKvB,CAAK,EAAE,SAAS,MAC9BoB,EAAU,CAACvsC,OAAO,EAAE,GAAGA,GAAG,GAAGmrC,IAAQ,GACrCyB,EAAa,EAAI,GACjBE,EAAc,EAAI,IAEpBC,EAAU,EAAI;AACd;AAAA,IACF;AACA,QAAI1kC,IAAW;AACf,WAAA/C,EACG,cAAcknC,GAAmBC,CAAa,EAC9C,KAAK,CAACO,MAAU;AACf,UAAI3kC,EAAU;AAOd,YAAMmrB,IAASwZ,EAAM,SAASA,EAAMA,EAAM,SAAS,CAAC,IAAI;AACxD,MAAIxZ,KAAA,QAAAA,EAAQ,SACV+Y,EAAU,CAACvsC,OAAO,EAAE,GAAGA,GAAG,GAAGwzB,EAAO,OAAO,GACvC,OAAO,KAAKA,EAAO,IAAI,EAAE,SAAS,OAAiB,EAAI,IAE7DuZ,EAAU,EAAI;AAAA,IAChB,CAAC,EAGA,MAAM,MAAM;AACX,MAAK1kC,KAAU0kC,EAAU,EAAI;AAAA,IAC/B,CAAC,GACI,MAAM;AACX,MAAA1kC,IAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAKknC,GAAmBC,GAAeC,EAAW,MAAM,CAAC;AAC7D,QAAM,CAACO,GAASC,CAAU,IAAIhpC,EAAS,CAAC,GAClCipC,IAAkB,MAAM;AAC5B,iBAAaC,EAAU,OAAO,GAC9BC,EAAY,UAAU,MACtBX,EAAW,MAAA,GACXE,EAAa,EAAK,GAClBL,EAAUvB,GAAWD,CAAI,CAAC,GAC1BmC,EAAW,CAAC/uB,MAAMA,IAAI,CAAC;AAAA,EACzB,GAKMkvB,IAActlC,GAAuC,IAAI,GACzDqlC,IAAYrlC,GAAkD,MAAS,GACvEulC,IAAYvlC,GAAO,MAAM;AAAA,EAAC,CAAC;AACjC,EAAAulC,EAAU,UAAU,MAAM;AACxB,iBAAaF,EAAU,OAAO;AAC9B,UAAMxjC,IAAOyjC,EAAY;AACzB,IAAAA,EAAY,UAAU,MAClBzjC,KAAM8iC,EAAW,KAAK9iC,GAAMyoB,CAAM;AAAA,EACxC,GACAluB,GAAU,MAAM,MAAMmpC,EAAU,QAAA,GAAW,CAAA,CAAE;AAC7C,QAAMC,IAAa,CAAC3jC,MAAkC;AAEpD,IADA2iC,EAAU3iC,CAAI,GACV,GAAC4iC,KAAqB,CAACC,KAAiB,CAACjvB,OAC7C6vB,EAAY,UAAUzjC,GACtB,aAAawjC,EAAU,OAAO,GAC9BA,EAAU,UAAU,WAAW,MAAME,EAAU,QAAA,GAAWnB,EAAqB;AAAA,EACjF,GAMM,CAACqB,GAAYC,CAAa,IAAIvpC,EAAS,EAAI,GAG3CwpC,IAASF,KAAcG,GAAqBtb,GAAQG,CAAM,GAE1Djf,IAAM,OAAOq6B,MAAuC;AACxD,UAAMzC,IAAQyC,KAAYpb;AAE1B,iBAAa4a,EAAU,OAAO,GAC9BC,EAAY,UAAU,MAElBhB,KAASK,EAAW,KAAKvB,GAAO9Y,CAAM,GAC1CtD,EAAS,EAAE,QAAQ,WAAW;AAC9B,QAAI8e;AACJ,QAAI;AAGF,YAAMzhB,IAAS,MAAM9mB,EAAI,aAAarJ,GAAKuE,GAAQ,EAAE,OAAA2qC,EAAA,GAAS,EAAE,SAAArlC,GAAS;AACzE,MAAA+nC,IAAU;AAAA,QACR,QAAQ;AAAA,QACR,OAAOzhB,EAAO;AAAA,QACd,MAAOA,EAA+B;AAAA,MAAA;AAAA,IAE1C,SAAS9jB,GAAG;AACV,YAAMo+B,IAAMp+B;AACZ,MAAAulC,IAAU;AAAA,QACR,QAAQ;AAAA,QACR,OAAOnH,EAAI,WAAW,OAAOp+B,CAAC;AAAA,QAC9B,WAAWo+B,EAAI;AAAA,QACf,MAAMA,EAAI;AAAA,MAAA;AAAA,IAEd;AAMA,QALA3X,EAAS8e,CAAO,GAKZxB;AACF,UAAI;AACF,cAAMyB,IAAQ,MAAMxoC,EAAI,aAAa+mC,EAAQ,YAAYA,EAAQ,QAAQ;AAAA,UACvE,OAAOA,EAAQ;AAAA,UACf,MAAMlB;AAAA,QAAA,CACP;AACD,cAAM7lC,EAAI,kBAAkB+mC,EAAQ,YAAYA,EAAQ,QAAQ;AAAA,UAC9D,YAAYyB,EAAM;AAAA,UAClB,QAAQD,EAAQ,WAAW,SAAS,cAAc;AAAA,UAClD,OAAOxB,EAAQ;AAAA,UACf,QAAQwB,EAAQ,WAAW,SAASA,EAAQ,QAAQ;AAAA,UACpD,OAAOA,EAAQ,WAAW,UAAUA,EAAQ,QAAQ;AAAA,QAAA,CACrD;AAAA,MACH,SAASnH,GAAK;AACZ,gBAAQ,MAAM,4BAA4BA,CAAG;AAAA,MAC/C;AAAA,EAEJ,GAEMqH,IAAOlrC,KAASA,EAAM,WAAW,YAAYA,EAAM,OAAO,QAG1DmrC,IAAc,CAACvkC,MAAoC;AACvD,UAAMwkC,IAAU,EAAE,GAAGxkC,EAAA;AACrB,IAAA8iC,EAAU0B,CAAO,GACZ16B,EAAI06B,CAAO;AAAA,EAClB,GACMC,KAAchE,KAAUmC,KAC5B,gBAAApnC;AAAA,IAACokC;AAAA,IAAA;AAAA,MACC,YAAYgD,EAAQ;AAAA,MACpB,QAAQA,EAAQ;AAAA,MAChB,UAAUnC,EAAO;AAAA,MACjB,UAAUA,EAAO;AAAA,MACjB,OAAO8D;AAAA,MACP,QAAOnrC,KAAA,gBAAAA,EAAO,YAAW;AAAA,IAAA;AAAA,EAAA;AAI7B,SACE,gBAAAkI,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAAmjC;AAAA,IACAA,KACC,gBAAAnjC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,eAAY;AAAA,QACZ,MAAM8hC;AAAA,QACN,UAAU,CAACvkC,MAAMwkC,EAAcxkC,EAAE,cAAc,IAAI;AAAA,QAEnD,UAAA;AAAA,UAAA,gBAAArD,EAAC,WAAA,EAAQ,WAAU,aAAY,UAAA,iCAA6B;AAAA,UAC3DkpC,GAAA;AAAA,QAAY;AAAA,MAAA;AAAA,IAAA,IAGfA,GAAA;AAAA,IAEDC,EAAA;AAAA,EAAY,GACf;AAGF,WAASD,KAAc;AACrB,WACE,gBAAApjC,EAAC,OAAA,EAAI,WAAU,aAGZ,UAAA;AAAA,MAACyS,IAGA,gBAAAzS,EAAAwB,IAAA,EACG,UAAA;AAAA,QAAAogC,KAAa,gBAAA1nC,EAACgnC,IAAA,EAAa,SAASkB,EAAA,CAAiB;AAAA,QACtD,gBAAAloC;AAAA,UAACopC;AAAA,UAAA;AAAA,YAGC,QAAAhc;AAAA,YACA,QAAAG;AAAA,YACA,UAAU+a;AAAA,YACV,kBAAkBE;AAAA,UAAA;AAAA,UAJbR;AAAA,QAAA;AAAA,QAMN,CAACX,KACA,gBAAAvhC,EAAC,QAAA,EAAK,WAAU,YAAW,UAAA;AAAA,UAAA;AAAA,UAEG,gBAAA9F,EAAC,UAAK,UAAA,QAAA,CAAK;AAAA,UAAO;AAAA,QAAA,EAAA,CAChD;AAAA,MAAA,GAEJ,IAlBA,gBAAAA,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,wBAAA,CAAqB;AAAA,wBAqBzD,OAAA,EAAI,WAAU,gBACb,UAAA,gBAAA8F,EAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,QAAA,gBAAA9F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,UAAU,CAACuY,KAAU,CAACkwB,MAAU7qC,KAAA,gBAAAA,EAAO,YAAW;AAAA,YAClD,SAAS,MAAM,KAAK0Q,EAAA;AAAA,YAEnB,WAAA1Q,KAAA,gBAAAA,EAAO,YAAW,YAAY,aAAa;AAAA,UAAA;AAAA,QAAA;AAAA,QAE7C2a,KAAU,CAACkwB,KACV,gBAAAzoC,EAAC,UAAK,WAAU,uBACb,UAAAuoC,IACG,sCACA,6CAAA,CACN;AAAA,MAAA,EAAA,CAEJ,EAAA,CACF;AAAA,IAAA,GACF;AAAA,EAEJ;AAEA,WAASY,IAAc;AACrB,WACE,gBAAArjC,EAAC,OAAA,EAAI,WAAU,gBACZ,UAAA;AAAA,OAAAlI,KAAA,gBAAAA,EAAO,YAAW,WACjB,gBAAAkI,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAA;AAAA,QAAAlI,EAAM,aACL,gBAAAoC,EAAC,OAAA,EAAI,WAAU,aAAY,OAAO,EAAE,SAAS,MAAM,cAAc,KAC/D,UAAA,gBAAAA,EAAC,QAAA,EAAM,UAAApC,EAAM,WAAU,GACzB;AAAA,QAEDA,EAAM;AAAA,MAAA,GACT;AAAA,OAEDA,KAAA,gBAAAA,EAAO,YAAW,UACjB,gBAAAkI,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA,gCAA4B;AAAA,0BAC9DmjC,IAAA,EAAa,OAAOvlC,EAAM,OAAO,WAAW,IAAA,CAAK;AAAA,MAAA,GACpD;AAAA,MAEDkrC,KAAQA,EAAK,SAAS,KACrB,gBAAAhjC,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA,kBAAc;AAAA,QACjD,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO,EAAE,YAAY,YAAY,WAAW,KAAK,UAAU,QAAQ,QAAQ,EAAA;AAAA,YAE1E,UAAA8oC,EAAK,KAAK;AAAA,CAAI;AAAA,UAAA;AAAA,QAAA;AAAA,MACjB,EAAA,CACF;AAAA,IAAA,GAEJ;AAAA,EAEJ;AACF;AC9WA,MAAMO,KAAQ;AAAA,EACZ,CAAC,KAAK,SAAS;AAAA,EACf,CAAC,KAAK,SAAS;AAAA,EACf,CAAC,KAAK,OAAO;AAAA,EACb,CAAC,KAAK,MAAM;AAAA,EACZ,CAAC,KAAK,OAAO;AACf,GACMC,KACJ;AAGK,SAASC,GAAW;AAAA,EACzB,QAAAhc;AAAA,EACA,UAAA1hB;AAAA,EACA,UAAAF;AACF,GAIG;AACD,QAAM69B,IAAWjc,EAAO,YAAY,MAC9B2L,IACJ,OAAOsQ,KAAa,WAAWA,EAAS,MAAM,6BAA6B,IAAI,MAC3E,CAACC,GAAUC,CAAW,IAAIzqC,EAAS,GAAG,GACtC,CAACF,GAAMC,CAAO,IAAIC,EAA2B,MAAM,GACnD,CAACoe,GAAQssB,CAAS,IAAI1qC,EAA+BsuB,EAAO,QAAQ,UAAU,UAAU,GACxF2H,IACJ,OAAOsU,KAAa,aACnB,CAACF,GAAgB,KAAKE,EAAS,KAAA,CAAM,KAAK,OAAO,KAAKA,EAAS,MAAM;AACxE,SACE,gBAAA1jC,EAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,SAAA,EAAM,UAAA;AAAA,MAAA;AAAA,MAEL,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,cAAW;AAAA,UACX,UAAU6F;AAAA,UACV,OAAO0R;AAAA,UACP,UAAU,CAACha,MAAM;AACf,kBAAMsB,IAAOtB,EAAE,OAAO;AACtB,YAAAsmC,EAAUhlC,CAAI,GACdkH,EAAS;AAAA,cACP,GAAG0hB;AAAA,cACH,UAAU5oB,MAAS,aAAa,OAAO;AAAA,cACvC,OAAO;AAAA,YAAA,CACR;AAAA,UACH;AAAA,UAEA,UAAA;AAAA,YAAA,gBAAA3E,EAAC,UAAA,EAAO,OAAM,YAAW,UAAA,cAAU;AAAA,YACnC,gBAAAA,EAAC,UAAA,EAAO,OAAM,SAAQ,UAAA,oBAAA,CAAiB;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACzC,GACF;AAAA,IACCqd,MAAW,UACV,gBAAArd;AAAA,MAACgxB;AAAA,MAAA;AAAA,QACC,QAAQ;AAAA,UACN;AAAA,YACE,KAAK;AAAA,YACL,OAAO;AAAA,YACP,MAAM;AAAA,YACN,MAAM;AAAA,UAAA;AAAA,QACR;AAAA,QAEF,QAAAzD;AAAA,QACA,UAAA1hB;AAAA,QACA,UAAAF;AAAA,MAAA;AAAA,IAAA,IAGF,gBAAA7F,EAAAwB,IAAA,EACE,UAAA;AAAA,MAAA,gBAAAxB,EAAC,SAAA,EAAM,UAAA;AAAA,QAAA;AAAA,QAEL,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,cAAW;AAAA,YACX,UAAU6F;AAAA,YACV,OAAO5M;AAAA,YACP,UAAU,CAACsE,MAAM;AACf,cAAI61B,KACFwQ,GAAYxQ,KAAA,gBAAAA,EAAS,GAAG,kBAAiBuQ,CAAQ,GAEnDzqC,EAAQqE,EAAE,OAAO,KAAyB;AAAA,YAC5C;AAAA,YAEA,UAAA;AAAA,cAAA,gBAAArD,EAAC,UAAA,EAAO,OAAM,QAAO,UAAA,aAAS;AAAA,gCAC7B,UAAA,EAAO,OAAM,SAAQ,UAAU,CAACk5B,GAAQ,UAAA,iBAAA,CAEzC;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACF,GACF;AAAA,MACCn6B,MAAS,UACR,gBAAA+G,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,SAAA,EAAM,UAAA;AAAA,UAAA;AAAA,UAEL,gBAAA9F;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,cAAW;AAAA,cACX,MAAK;AAAA,cACL,KAAI;AAAA,cACJ,QAAOk5B,KAAA,gBAAAA,EAAS,GAAG,kBAAiBuQ,OAAc,MAAM,QAAQ;AAAA,cAChE,UAAU99B;AAAA,cACV,QAAOutB,KAAA,gBAAAA,EAAS,OAAM;AAAA,cACtB,UAAU,CAAC71B,MACTwI,EAAS;AAAA,gBACP,GAAG0hB;AAAA,gBACH,UAAU,GAAGlqB,EAAE,OAAO,KAAK,IAAG61B,KAAA,gBAAAA,EAAS,GAAG,kBAAiBuQ,CAAQ;AAAA,cAAA,CACpE;AAAA,YAAA;AAAA,UAAA;AAAA,QAEL,GACF;AAAA,0BACC,SAAA,EAAM,UAAA;AAAA,UAAA;AAAA,UAEL,gBAAAzpC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,cAAW;AAAA,cACX,UAAU2L;AAAA,cACV,QAAOutB,KAAA,gBAAAA,EAAS,GAAG,kBAAiBuQ;AAAA,cACpC,UAAU,CAACpmC,MAAM;AACf,gBAAAqmC,EAAYrmC,EAAE,OAAO,KAAK,GAC1BwI,EAAS;AAAA,kBACP,GAAG0hB;AAAA,kBACH,UAAU,IAAG2L,KAAA,gBAAAA,EAAS,OAAM,EAAE,GAAG71B,EAAE,OAAO,KAAK;AAAA,gBAAA,CAChD;AAAA,cACH;AAAA,cAEC,UAAAgmC,GAAM,IAAI,CAAC,CAACxlC,GAAO6L,CAAK,MACvB,gBAAA1P,EAAC,UAAA,EAAmB,OAAA6D,GACjB,UAAA6L,EAAA,GADU7L,CAEb,CACD;AAAA,YAAA;AAAA,UAAA;AAAA,QACH,EAAA,CACF;AAAA,MAAA,EAAA,CACF,IAEA,gBAAA7D;AAAA,QAACgxB;AAAA,QAAA;AAAA,UACC,QAAQ;AAAA,YACN;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,cACN,SAAS;AAAA,cACT,MAAM;AAAA,YAAA;AAAA,UACR;AAAA,UAEF,QAAAzD;AAAA,UACA,UAAA1hB;AAAA,UACA,UAAAF;AAAA,QAAA;AAAA,MAAA;AAAA,MAGHupB,KACC,gBAAAl1B,EAAC,KAAA,EAAE,MAAK,SAAQ,UAAA,gFAAA,CAEhB;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,GAEJ;AAEJ;ACvJO,SAAS4pC,GAAe;AAAA,EAC7B,WAAAC;AAAA,EACA,SAAAxuB;AAAA,EACA,UAAA/a;AACF,GAaG;AACD,QAAMwpC,IAAShnC,GAAuB,IAAI,GACpC,CAACke,GAAK+oB,CAAM,IAAI9qC,EAA8D,IAAI,GAClF,CAACujC,GAAWwH,CAAY,IAAI/qC,EAA6B,IAAI;AA8BnE,SA5BAC,GAAU,MAAM;AACd,UAAMkK,IAAKygC,EAAU;AACrB,QAAI,CAACzgC,EAAI;AACT,UAAM3P,IAAI2P,EAAG,sBAAA;AACb,IAAA2gC,EAAO,EAAE,KAAKtwC,EAAE,SAAS,GAAG,MAAMA,EAAE,MAAM,OAAOA,EAAE,MAAA,CAAO,GAC1DuwC,EAAa5gC,EAAG,QAAQ,QAAQ,KAAK,SAAS,IAAI;AAAA,EACpD,GAAG,CAACygC,CAAS,CAAC,GAEd3qC,GAAU,MAAM;AACd,aAAS+qC,EAAiB5mC,GAAe;;AACvC,YAAMga,IAASha,EAAE;AACjB,OAAI7J,IAAAswC,EAAO,YAAP,QAAAtwC,EAAgB,SAAS6jB,OAGzBrQ,IAAA68B,EAAU,YAAV,QAAA78B,EAAmB,SAASqQ,MAChChC,EAAA;AAAA,IACF;AACA,aAASzG,EAAUvR,GAAkB;AACnC,MAAIA,EAAE,QAAQ,YAAUgY,EAAA;AAAA,IAC1B;AACA,oBAAS,iBAAiB,aAAa4uB,CAAgB,GACvD,SAAS,iBAAiB,WAAWr1B,CAAS,GACvC,MAAM;AACX,eAAS,oBAAoB,aAAaq1B,CAAgB,GAC1D,SAAS,oBAAoB,WAAWr1B,CAAS;AAAA,IACnD;AAAA,EACF,GAAG,CAACyG,GAASwuB,CAAS,CAAC,GAEnB,CAAC7oB,KAAO,CAACwhB,IAAkB,OACxB1yB;AAAA,IACL,gBAAA9P;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK8pC;AAAA,QACL,WAAU;AAAA,QACV,OAAO,EAAE,KAAK9oB,EAAI,KAAK,MAAMA,EAAI,MAAM,OAAOA,EAAI,MAAA;AAAA,QAEjD,UAAA1gB;AAAA,MAAA;AAAA,IAAA;AAAA,IAEHkiC;AAAA,EAAA;AAEJ;ACjCA,SAAS/oB,GAAUviB,GAAYC,GAAqB;AAClD,MAAID,MAAMC,EAAG,QAAO;AAEpB,MADI,OAAOD,KAAM,YAAY,OAAOC,KAAM,YAAYD,MAAM,QAAQC,MAAM,QACtE,MAAM,QAAQD,CAAC,MAAM,MAAM,QAAQC,CAAC,EAAG,QAAO;AAClD,QAAM+yC,IAAK,OAAO,KAAKhzC,CAAC,GAClBizC,IAAK,OAAO,KAAKhzC,CAAC;AACxB,SAAI+yC,EAAG,WAAWC,EAAG,SAAe,KAC7BD,EAAG;AAAA,IACR,CAAChxB,MACC,OAAO,UAAU,eAAe,KAAK/hB,GAAG+hB,CAAC,KACzCO,GAAWviB,EAA8BgiB,CAAC,GAAI/hB,EAA8B+hB,CAAC,CAAC;AAAA,EAAA;AAEpF;AAOO,SAASkxB,GACdrxB,GACAsxB,GACK;AACL,SAAOtxB,EAAM,IAAI,CAAC,MAAM;AACtB,UAAMpU,IAAO0lC,KAAY,OAAO,OAAOA,GAAU,EAAE,EAAE,IAAIA,EAAS,EAAE,EAAE,IAAI,QACpErgC,IAAM,EAAE,KAAK;AACnB,QAAIrF,MAAS,UAAaA,EAAK,WAAW,GAAG;AAC3C,UAAIqF,MAAQ,UAAa,EAAE,kBAAkB,EAAE,MAAO,QAAO;AAC7D,YAAM,EAAE,cAAcsgC,GAAO,GAAGtiC,EAAA,IAAS,EAAE;AAC3C,aAAO,EAAE,GAAG,GAAG,MAAMA,EAAA;AAAA,IACvB;AACA,WAAIgC,KAAOyP,GAAUzP,GAAKrF,CAAI,IAAU,IACjC,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,cAAc,gBAAgBA,CAAI,IAAE;AAAA,EACxE,CAAC;AACH;AAEA,MAAM4lC,KAA2D;AAAA,EAC/D,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,mBACE;AACJ;AAEO,SAASC,GAAmBvtC,GAAwB;AACzD,UAAQA,EAAE,MAAA;AAAA,IACR,KAAK;AACH,aAAO,cAAcA,EAAE,UAAU;AAAA,IACnC,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,oCAAoCA,EAAE,KAAK,KAAK,IAAI,CAAC;AAAA,IAC9D,KAAK,qBAAqB;AACxB,YAAMiL,IAAOqiC,GAAkBttC,EAAE,OAAO,MAAM,KAAK;AACnD,aAAOA,EAAE,OAAO,SAAS,GAAGiL,CAAI,KAAKjL,EAAE,OAAO,MAAM,MAAMiL;AAAA,IAC5D;AAAA,IACA,KAAK;AAEH,aAAO,UADO,QAAQjL,EAAE,KAAK,SAAS,IAAIA,EAAE,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,EAC3C,wBAAwBA,EAAE,KAAK,KAAK,IAAI,CAAC;AAAA,IAEjE,KAAK;AACH,aAAO,sBAAsBA,EAAE,MAAM,KAAK,IAAI,CAAC;AAAA,EAAA;AAErD;AAGO,SAASwtC,GACdlxC,GACA8wC,GACS;AACT,UACEA,KAAA,gBAAAA,EAAU;AAAA,IACR,CAACptC,MAAMA,EAAE,SAAS,wBAAwB1D,EAAK,KAAK,eAAe0D,EAAE;AAAA,QAClE;AAET;AAGO,SAASytC,GACdC,GACAC,GACAC,GACQ;AACR,MAAI,CAACF,EAAY,QAAO;AACxB,MAAIE,EAAQ,QAAO;AACnB,MAAID,MAAU,KAAM,QAAOD;AAC3B,QAAMG,IAAQF,EAAM,KAAK,CAAC1kC,MAAMA,EAAE,OAAOykC,CAAU;AACnD,SAAIG,IAAcA,EAAM,UAAU,aAAcA,EAAM,eAAeH,IAC9D;AACT;AChGO,SAASI,GACdhyB,GACAiyB,GACA5O,GACqD;AACrD,MAAIA,EAAK,SAAS,UAAU;AAE1B,UAAM6O,IAAUF,GAAwBhyB,GAAOiyB,GAAa;AAAA,MAC1D,MAAM;AAAA,MACN,KAAK5O,EAAK;AAAA,MACV,MAAMA,EAAK;AAAA,IAAA,CACZ,GACKxmB,IAAMwmB,EAAK,KAAK,KAAA,GAChB8O,IAAWH,GAAwBE,EAAQ,OAAOA,EAAQ,aAAa;AAAA,MAC3E,MAAM;AAAA,MACN,KAAAr1B;AAAA,MACA,YAAYwmB,EAAK;AAAA,IAAA,CAClB;AACD,WAAOA,EAAK,UACR2O,GAAwBG,EAAS,OAAOA,EAAS,aAAa;AAAA,MAC5D,MAAM;AAAA,MACN,KAAAt1B;AAAA,MACA,SAASwmB,EAAK;AAAA,IAAA,CACf,IACD8O;AAAA,EACN;AACA,MAAI9O,EAAK,SAAS,SAASA,EAAK,SAAS,UAAU;AACjD,UAAM18B,IAAO08B,EAAK,KAAK,KAAA;AACvB,QAAI,CAAC18B,EAAM,OAAM,IAAI,MAAM,sCAAsC;AACjE,QAAI,OAAO,OAAOsrC,GAAatrC,CAAI,MAAM08B,EAAK,SAAS,SAAS18B,MAAS08B,EAAK;AAC5E,YAAM,IAAI,MAAM,+CAA+C;AAEjE,QAAIA,EAAK,SAAS;AAChB,aAAO;AAAA,QACL,OAAArjB;AAAA,QACA,aAAa,EAAE,GAAGiyB,GAAa,CAACtrC,CAAI,GAAG,EAAE,KAAK08B,EAAK,KAAK,YAAYA,EAAK,aAAW;AAAA,MAAE;AAAA,EAG5F;AACA,MAAI,CAAC,OAAO,OAAO4O,GAAa5O,EAAK,GAAG;AACtC,UAAM,IAAI,MAAM,4CAA4C;AAC9D,QAAM+O,IAAWH,EAAY5O,EAAK,GAAG;AACrC,UAAQA,EAAK,MAAA;AAAA,IACX,KAAK;AACH,aAAO;AAAA,QACL,OAAArjB;AAAA,QACA,aAAa,EAAE,GAAGiyB,GAAa,CAAC5O,EAAK,GAAG,GAAG,EAAE,GAAG+O,GAAU,YAAY/O,EAAK,aAAW;AAAA,MAAE;AAAA,IAE5F,KAAK,UAAU;AACb,YAAM18B,IAAO08B,EAAK,KAAK,KAAA;AACvB,aAAO;AAAA,QACL,aAAa,OAAO;AAAA,UAClB,OAAO,QAAQ4O,CAAW,EAAE,IAAI,CAAC,CAACp1B,GAAK/R,CAAK,MAAM,CAAC+R,MAAQwmB,EAAK,MAAM18B,IAAOkW,GAAK/R,CAAK,CAAC;AAAA,QAAA;AAAA,QAE1F,OAAOkV,EAAM;AAAA,UAAI,CAACtL,MAChBA,EAAE,KAAK,kBAAkB2uB,EAAK,MAAMgP,GAAkB39B,GAAG/N,CAAI,IAAI+N;AAAA,QAAA;AAAA,MACnE;AAAA,IAEJ;AAAA,IACA,KAAK,UAAU;AACb,UAAIsL,EAAM,KAAK,CAACtL,MAAMA,EAAE,KAAK,kBAAkB2uB,EAAK,GAAG;AACrD,cAAM,IAAI,MAAM,wEAAwE;AAC1F,YAAM,EAAE,CAACA,EAAK,GAAG,GAAGiP,GAAU,GAAGrjC,MAASgjC;AAC1C,aAAO,EAAE,OAAAjyB,GAAO,aAAa/Q,EAAA;AAAA,IAC/B;AAAA,IACA,KAAK,UAAU;AACb,YAAM3Q,IAAW,IAAI,IAAI+kC,EAAK,OAAO;AACrC,UAAIrjB,EAAM,KAAK,CAACtL,MAAMpW,EAAS,IAAIoW,EAAE,EAAE,KAAKA,EAAE,KAAK,QAAQ09B,EAAS,GAAG;AACrE,cAAM,IAAI,MAAM,8DAA8D;AAChF,aAAO;AAAA,QACL,aAAAH;AAAA,QACA,OAAOjyB,EAAM,IAAI,CAACtL,MAAOpW,EAAS,IAAIoW,EAAE,EAAE,IAAI29B,GAAkB39B,GAAG2uB,EAAK,GAAG,IAAI3uB,CAAE;AAAA,MAAA;AAAA,IAErF;AAAA,EAAA;AAEJ;AAGO,SAAS69B,GAAgB/xC,GAAgByxC,GAAmD;AACjG,QAAM,EAAE,eAAAO,GAAe,YAAAZ,GAAY,KAAA3zC,EAAA,IAAQuC,EAAK;AAChD,MAAIgyC,MAAkB,OAAW,QAAOZ,KAAc;AACtD,QAAMppC,IACJypC,KAAe,OAAO,OAAOA,GAAaO,CAAa,IACnDP,EAAYO,CAAa,IACzB;AACN,UAAOhqC,KAAA,gBAAAA,EAAO,SAAQvK,IAAOuK,EAAM,cAAc,SAAa;AAChE;AAGO,SAASiqC,GAA2BC,GAAeT,GAAsC;AAE9F,QAAMnlC,KADU4lC,EAAM,MAAM,MAAM,EAAE,OAAO,OAAO,EAAE,GAAG,EAAE,KAAK,cAGzD,YAAA,EACA,QAAQ,gBAAgB,GAAG,EAC3B,QAAQ,YAAY,EAAE,KAAK;AAChC,MAAIhR,IAAQ;AACZ,SAAO,OAAO,OAAOuQ,GAAa,GAAGnlC,CAAI,IAAI40B,CAAK,EAAE,IAAG,CAAAA;AACvD,SAAO,GAAG50B,CAAI,IAAI40B,CAAK;AACzB;AAGO,SAASiR,GACdC,GACG;AACH,MAAIX,IAAcW,EAAS,eAAe,CAAA,GACtChe,IAAU;AACd,QAAM5U,KAAS4yB,EAAS,SAAS,CAAA,GAAI,IAAI,CAACpyC,MAAS;AACjD,QAAI,CAACA,EAAK,KAAK,cAAcA,EAAK,KAAK,kBAAkB,OAAW,QAAOA;AAE3E,UAAMgE,IAAW,OAAO,OAAOytC,GAAazxC,EAAK,EAAE,IAAIyxC,EAAYzxC,EAAK,EAAE,IAAI,QACxEge,KACJha,KAAA,gBAAAA,EAAU,SAAQhE,EAAK,KAAK,OAAOgE,EAAS,eAAehE,EAAK,KAAK,aACjEA,EAAK,KACLiyC,GAA2BjyC,EAAK,KAAK,KAAKyxC,CAAW;AAC3D,WAAAA,IAAc;AAAA,MACZ,GAAGA;AAAA,MACH,CAACzzB,CAAG,GAAG,EAAE,KAAKhe,EAAK,KAAK,KAAK,YAAYA,EAAK,KAAK,WAAA;AAAA,IAAW,GAEhEo0B,IAAU,IACHyd,GAAkB7xC,GAAMge,CAAG;AAAA,EACpC,CAAC;AACD,SAAOoW,IAAU,EAAE,GAAGge,GAAU,OAAA5yB,GAAO,aAAAiyB,MAAgBW;AACzD;AAcO,SAASP,GAAkB7xC,GAAgBgyC,GAAiC;AACjF,QAAM,EAAE,YAAYK,GAAa,GAAGhxC,EAAA,IAASrB,EAAK;AAClD,SAAO,EAAE,GAAGA,GAAM,MAAM,EAAE,GAAGqB,GAAM,eAAA2wC,IAAc;AACnD;AAGO,SAASM,GACdtyC,GACAoxC,GACA5xB,GACAiyB,GACkD;AAClD,MAAI,CAACL,GAAY;AACf,UAAM,EAAE,YAAYmB,GAAK,eAAeC,GAAM,GAAGnxC,EAAA,IAASrB,EAAK;AAC/D,WAAO,EAAE,MAAM,EAAE,GAAGA,GAAM,MAAAqB,EAAA,GAAQ,aAAAowC,EAAA;AAAA,EACpC;AACA,QAAMp1B,IAAMrc,EAAK,KAAK,eAChByyC,IAASp2B,KAAOmD,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAOlU,EAAK,MAAMkU,EAAE,KAAK,kBAAkBmI,CAAG,GAClF2B,IAAM3B,KAAO,CAACo2B,IAASp2B,IAAM41B,GAA2BjyC,EAAK,KAAK,KAAKyxC,CAAW;AACxF,SAAO;AAAA,IACL,MAAMI,GAAkB7xC,GAAMge,CAAG;AAAA,IACjC,aAAa,EAAE,GAAGyzB,GAAa,CAACzzB,CAAG,GAAG,EAAE,KAAKhe,EAAK,KAAK,KAAK,YAAAoxC,IAAW;AAAA,EAAE;AAE7E;AAiBO,SAASsB,GACdj1C,GACA2zC,GACA5xB,GACAiyB,GACY;AACZ,SAAKL,IACE5xB,EAAM,OAAO,CAACtL,MAAMA,EAAE,KAAK,QAAQzW,KAAOs0C,GAAgB79B,GAAGu9B,CAAW,MAAML,CAAU,IADvE,CAAA;AAE1B;AAGO,SAASuB,GACd3yC,GACA4yC,GACApzB,GACAiyB,GACAoB,GACiD;AACjD,MAAIA,EAAmB,QAAO,EAAE,YAAYA,EAAA;AAC5C,aAAWhiC,KAAQ,CAAC,GAAG2O,CAAK,EAAE,WAAW;AACvC,QAAI3O,EAAK,OAAO7Q,EAAK,MAAM6Q,EAAK,KAAK,QAAQ7Q,EAAK,KAAK,IAAK;AAC5D,UAAMI,IAAK2xC,GAAgBlhC,GAAM4gC,CAAW;AAC5C,QAAI,GAACrxC,KAAM,CAACwyC,EAAQ,KAAK,CAACjmC,MAAMA,EAAE,OAAOvM,KAAMuM,EAAE,UAAU3M,EAAK,KAAK,GAAG;AACxE,aAAO6Q,EAAK,KAAK,gBACb,EAAE,eAAeA,EAAK,KAAK,cAAA,IAC3B,EAAE,YAAYzQ,EAAA;AAAA,EACpB;AACA,aAAW,CAACic,GAAKu1B,CAAQ,KAAK,OAAO,QAAQH,CAAW;AACtD,QACEG,EAAS,QAAQ5xC,EAAK,KAAK,OAC3B4yC,EAAQ,KAAK,CAACjmC,MAAMA,EAAE,UAAUilC,EAAS,OAAOjlC,EAAE,OAAOilC,EAAS,UAAU;AAE5E,aAAO,EAAE,eAAev1B,EAAA;AAG5B,QAAMy2B,IAAUF,EAAQ,OAAO,CAACjmC,MAAMA,EAAE,UAAU3M,EAAK,KAAK,GAAG,GACzDlC,IAAWg1C,EAAQ,KAAK,CAACnmC,MAAMA,EAAE,OAAO,KAAKmmC,EAAQ,CAAC;AAC5D,SAAOh1C,IAAW,EAAE,YAAYA,EAAS,GAAA,IAAO,CAAA;AAClD;AAGO,SAASi1C,GACdb,GACAlN,GACA4N,GACqB;AAQrB,SAPIA,EAAQ,KAAK,CAACjmC,MAAMA,EAAE,OAAO,KAO7B,CANYq4B,EAAM;AAAA,IACpB,CAACrnC,MACCA,EAAE,cAAc,OACfA,EAAE,QAAQ,qBACRA,EAAE,kBAAkB,OAASA,EAAE,SAAS,gBAAgBA,EAAE,SAAS;AAAA,EAAA,IAErDi1C,IACd;AAAA,IACL,GAAGA;AAAA,IACH;AAAA,MACE,IAAI,YAAYV,CAAK;AAAA,MACrB,OAAAA;AAAA,MACA,SAAS;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,OAAO;AAAA,IAAA;AAAA,EACT;AAEJ;AAGO,SAASc,GACdv1C,GACAgrB,GACAlF,GACA/D,GACAiyB,GACiB;AACjB,QAAM70B,IAAO,IAAI;AAAA,IACf81B,GAAgBj1C,GAAKgrB,GAAQjJ,GAAOiyB,CAAW,EAAE,IAAI,CAACv9B,MAAMA,EAAE,KAAK,aAAa;AAAA,EAAA;AAElF,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQu9B,CAAW,EAAE,IAAI,CAAC,CAACp1B,GAAK/R,CAAK,MAAM;AAAA,MAChD+R;AAAA,MACAO,EAAK,IAAIP,CAAG,IAAI,EAAE,GAAG/R,GAAO,YAAYiZ,MAAUjZ;AAAA,IAAA,CACnD;AAAA,EAAA;AAEL;ACnRO,MAAM2oC,KAA6BhuC,GAKhC,IAAI;AAEP,SAASiuC,KAAyB;AACvC,SAAO3tC,GAAW0tC,EAA0B;AAC9C;AAGO,SAASE,GAAyB;AAAA,EACvC,MAAAnzC;AAAA,EACA,OAAAqxC;AAAA,EACA,QAAAC,IAAS;AAAA,EACT,UAAAl/B;AAAA,EACA,MAAA1B;AAAA,EACA,cAAA0iC;AAAA,EACA,WAAA9C;AAAA,EACA,oBAAA+C;AAAA,EACA,uBAAAC;AAAA,EACA,qBAAAC;AACF,GAWG;;AACD,QAAM7zB,IAAQwzB,GAAA,GACRl5B,IAAW5H,MAAYsN,KAAA,gBAAAA,EAAO,WAC9B+xB,KAAc/xB,KAAA,gBAAAA,EAAO,gBAAe,CAAA,GACpCF,KAAQE,KAAA,gBAAAA,EAAO,UAAS,CAAA,GACxBkzB,KAAWvB,KAAS,CAAA,GACvB,IAAI,CAACrK,OAAU,EAAE,MAAAA,GAAM,OAAO0L,GAAgB1yC,EAAK,KAAK,KAAKgnC,EAAK,IAAIxnB,GAAOiyB,CAAW,EAAA,EAAI,EAC5F,KAAK,CAAC9zC,GAAGC,MAAM,EAAOA,EAAE,MAAM,SAAS,KAAK,EAAOD,EAAE,MAAM,SAAS,EAAE,GACnE61C,IACJzB,GAAgB/xC,GAAMyxC,CAAW,MAChCzxC,EAAK,KAAK,kBAAkB,UACzBC,IAAAoxC,KAAA,gBAAAA,EAAO,KAAK,CAAC1kC,MAAMA,EAAE,WAAWA,EAAE,UAAU3M,EAAK,KAAK,SAAtD,gBAAAC,EAA4D,KAC5D,SACAwzC,IAAQf,GAAgB1yC,EAAK,KAAK,KAAKwzC,GAAWh0B,GAAOiyB,CAAW,EAAE;AAAA,IAC1E,CAACv9B,MAAMA,EAAE,OAAOlU,EAAK;AAAA,EAAA,GAEjB,CAACmX,GAAS0Y,CAAU,IAAInqB,EAAwB,IAAI,GACpD,CAACylC,GAAUC,CAAW,IAAI1lC,EAAS,EAAK,GAExCguC,IACJv8B,KAAWg0B,MACNjyB,KAAAzF,IAAA68B,EAAU,YAAV,gBAAA78B,EAAmB,QAAQ,cAA3B,gBAAAyF,EAAsC,kBAAiB,SAAS,OACjE,MAEA0c,IAAQ,CAACx1B,GAAYuzC,MAAiB;AAC1C,QAAI,CAAA35B,GACJ;AAAA,UAAI25B,KAAOj0B,KAAS8zB,GAAW;AAC7B,QAAA9zB,EAAM;AAAA,UACJszB,GAA0BhzC,EAAK,KAAK,KAAKwzC,GAAWpzC,GAAIof,GAAOiyB,CAAW;AAAA,QAAA;AAE5E,cAAMhW,IAAQjc,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAOlU,EAAK,EAAE,KAAKA;AACrD,QAAIy7B,EAAM,KAAK,gBAAe6X,EAAsB7X,EAAM,KAAK,aAAa,MACpDr7B,CAAE;AAAA,MAC5B,OAAO;AACL,cAAMkX,IAASo7B,GAAgB1yC,EAAK,KAAK,KAAKI,GAAIof,GAAOiyB,CAAW,EACjE,OAAO,CAACv9B,MAAMA,EAAE,OAAOlU,EAAK,MAAMkU,EAAE,KAAK,aAAa,EACtD,GAAG,EAAE,GACF09B,IAAW,OAAO,QAAQH,CAAW,EAAE;AAAA,UAC3C,CAAC,CAAA,EAAG9kC,CAAC,MAAMA,EAAE,QAAQ3M,EAAK,KAAK,OAAO2M,EAAE,eAAevM;AAAA,QAAA;AAEzD,QAAIkX,KAAA,QAAAA,EAAQ,KAAK,gBAAeg8B,EAAsBh8B,EAAO,KAAK,aAAa,IACtEs6B,IAAU0B,EAAsB1B,EAAS,CAAC,CAAC,MAC5BxxC,CAAE;AAAA,MAC5B;AACA,MAAAyvB,EAAW,IAAI,GACfujB,EAAa,EAAK;AAAA;AAAA,EACpB,GACMQ,IAAS,CAACxzC,MAAe;AAC7B,IAAI4Z,MACJo5B,EAAa,EAAK,GACdhzC,MAAOozC,MACPC,EAAM,SAAS,KAAKj0B,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAOlU,EAAK,EAAE,MAAcI,CAAE,IACrEw1B,EAAMx1B,GAAI,EAAK;AAAA,EACtB;AAEA,SACE,gBAAAmM,EAAAwB,IAAA,EACE,UAAA;AAAA,IAAA,gBAAAtH;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,cAAW;AAAA,QACX,iBAAeiK;AAAA,QACf,UAAUsJ,KAAaq3B,MAAU,QAAQ,CAACC;AAAA,QAC1C,SAAS,MAAM8B,EAAa,CAAC1iC,CAAI;AAAA,QAEjC,UAAA,gBAAAjK,EAAC,QAAA,EAAK,WAAU,uBACb,gBAAU,QAAQ,CAAC6qC,KAAU,CAACkC,IAC3B,yBACArC,GAAsBqC,GAAWnC,GAAOC,CAAM,EAAA,CACpD;AAAA,MAAA;AAAA,IAAA;AAAA,IAED5gC,KACC,gBAAAjK,EAAC4pC,IAAA,EAAe,WAAAC,GAAsB,SAAS,MAAM8C,EAAa,EAAK,GACrE,UAAA,gBAAA7mC,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,MAAA+kC,uBACE,KAAA,EAAE,MAAK,SAAQ,WAAU,mBAAkB,UAAA,8BAE5C;AAAA,MAED,OAAO,QAAQG,CAAW,EAAE,KAAK,CAAC,CAAA,EAAG9kC,CAAC,MAAMA,EAAE,QAAQ3M,EAAK,KAAK,GAAG,KAClE,gBAAAuM,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAA,EAAO,WAAU,aAAY,UAAA,wBAAoB;AAAA,QAClD,gBAAAA,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAA,OAAO,QAAQgrC,CAAW,EACxB,OAAO,CAAC,CAAA,EAAG9kC,CAAC,MAAMA,EAAE,QAAQ3M,EAAK,KAAK,GAAG,EACzC,IAAI,CAAC,CAACqc,GAAK1P,CAAC,MACX,gBAAAlG;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,UACEuT,KACA,CAACrN,EAAE,cACH,EAAC0kC,KAAA,QAAAA,EAAO,KAAK,CAACrK,MAASA,EAAK,OAAOr6B,EAAE;AAAA,YAEvC,gBAAc3M,EAAK,KAAK,kBAAkBqc;AAAA,YAC1C,uBAAqBA;AAAA,YACrB,SAAS,MAAM;AACb,cAAAi3B,EAAsBj3B,CAAG,GACzB+2B,EAAa,EAAK;AAAA,YACpB;AAAA,YAEA,UAAA,gBAAA7mC,EAAC,QAAA,EAAK,WAAU,6BACd,UAAA;AAAA,cAAA,gBAAA9F,EAAC,YAAQ,UAAA4V,EAAA,CAAI;AAAA,cACb,gBAAA5V,EAAC,QAAA,EAAK,WAAU,uBACb,UAAA0qC,GAAsBxkC,EAAE,cAAc,QAAW0kC,GAAOC,CAAM,EAAA,CACjE;AAAA,YAAA,EAAA,CACF;AAAA,UAAA;AAAA,UApBKj1B;AAAA,QAAA,CAsBR,EAAA,CACL;AAAA,MAAA,GACF;AAAA,MAEF,gBAAA5V,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAAmsC,EAAQ,IAAI,CAAC,EAAE,MAAA5L,GAAM,OAAA6M,EAAA,MAElB,gBAAAptC;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAAuT;AAAA,UACA,gBAAcgtB,EAAK,OAAOwM;AAAA,UAC1B,sBAAoBxM,EAAK;AAAA,UACzB,SAAS,MAAM4M,EAAO5M,EAAK,EAAE;AAAA,UAE7B,UAAA,gBAAAz6B,EAAC,QAAA,EAAK,WAAU,6BACd,UAAA;AAAA,YAAA,gBAAA9F,EAAC,YAAQ,UAAAugC,EAAK,UAAU,aAAaA,EAAK,eAAeA,EAAK,GAAA,CAAG;AAAA,YACjE,gBAAAvgC,EAAC,UAAK,WAAU,uBACb,YAAM,SAAS,IACZ,6BAA6BotC,EAAM,IAAI,CAAC3/B,MAAMA,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC,KAC9D8yB,EAAK,UACH,wBACAA,EAAK,MAAA,CACb;AAAA,UAAA,EAAA,CACF;AAAA,QAAA;AAAA,QAjBKA,EAAK;AAAA,MAAA,CAoBf,EAAA,CACH;AAAA,MACA,gBAAAvgC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAAuT;AAAA,UACA,SAAS,MAAM;AACb,YAAAo5B,EAAa,EAAK,GAClBhI,EAAY,EAAI;AAAA,UAClB;AAAA,UACD,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,EAAA,CACF,EAAA,CACF;AAAA,IAEDD,KACCuI,KACAn9B;AAAA,MACE,gBAAA9P;AAAA,QAAC+9B;AAAA,QAAA;AAAA,UACC,cAAcxkC,EAAK,KAAK;AAAA,UACxB,SAAS,MAAMorC,EAAY,EAAK;AAAA,UAChC,WAAW,CAAC,EAAE,cAAAvE,QAAmB;AAC/B,YAAAuE,EAAY,EAAK,GACjBmI,EAAA,GACAK,EAAO/M,CAAY;AAAA,UACrB;AAAA,QAAA;AAAA,MAAA;AAAA,MAEF6M;AAAA,IAAA;AAAA,IAEHv8B,KACCu8B,KACAn9B;AAAA,MACE,gBAAAhK,EAACsV,MAAM,OAAM,qBAAoB,SAAS,MAAMgO,EAAW,IAAI,GAC7D,UAAA;AAAA,QAAA,gBAAAtjB,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,UAAA,gBAAA9F,EAAC,OAAE,UAAA,gEAAA,CAA6D;AAAA,4BAC/D,MAAA,EACC,UAAA;AAAA,YAAA,gBAAAA,EAAC,MAAA,EAAI,UAAAzG,EAAK,MAAM,YAAW;AAAA,YAC1ByzC,EAAM,IAAI,CAACv/B,MACV,gBAAAzN,EAAC,QAAe,UAAAyN,EAAE,MAATA,EAAE,EAAU,CACtB;AAAA,UAAA,EAAA,CACH;AAAA,QAAA,GACF;AAAA,QACA,gBAAA3H,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,UAAA,gBAAA9F;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAMopB,EAAW,IAAI;AAAA,cAC/B,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGD,gBAAAtjB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,UAAAyN;AAAA,cACA,SAAS,MAAM4b,EAAMze,GAAS,EAAI;AAAA,cACnC,UAAA;AAAA,gBAAA;AAAA,gBACMs8B,EAAM,SAAS;AAAA,gBAAE;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAExB,gBAAAhtC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,UAAAuT;AAAA,cACA,SAAS,MAAM4b,EAAMze,GAAS,EAAK;AAAA,cACpC,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAED,EAAA,CACF;AAAA,MAAA,GACF;AAAA,MACAu8B;AAAA,IAAA;AAAA,EACF,GACJ;AAEJ;AClOA,SAASI,GAAaze,GAAqB6L,GAAuB;AAChE,SAAO,GAAG7L,EAAK,MAAM,IAAIA,EAAK,OAAOA,EAAK,IAAI,IAAI6L,CAAK;AACzD;AAaO,SAAS6S,GAAc,EAAE,OAAAC,GAAO,aAAAC,GAAa,OAAAC,GAAO,OAAA1yB,KAA6B;AACtF,MAAIwyB,EAAM,WAAW,EAAG,QAAO;AAC/B,QAAMh2B,IAAMk2B,KAASJ;AACrB,SACE,gBAAAvnC,EAAC,SAAI,WAAU,aAAY,OAAO,EAAE,KAAK,KACtC,UAAA;AAAA,IAAAiV,MAAU,MACT,gBAAA/a,EAAC,UAAA,EAAO,WAAU,aACf,eACC,gBAAA8F,EAAAwB,IAAA,EAAE,UAAA;AAAA,MAAA;AAAA,MACKimC,EAAM,WAAW,IAAI,SAAS;AAAA,MAAQ;AAAA,MAAGA,EAAM;AAAA,MAAO;AAAA,IAAA,EAAA,CAC7D,EAAA,CAEJ;AAAA,IAEDA,EAAM,IAAI,CAAC3e,GAAMla,MAChB,gBAAA5O;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,MAAM0nC;AAAA,QACN,WAAU;AAAA,QACV,OAAO,EAAE,SAAS,EAAA;AAAA,QAElB,UAAA;AAAA,UAAA,gBAAAxtC,EAAC,WAAA,EAAQ,OAAO,EAAE,QAAQ,aACxB,UAAA,gBAAA8F,EAAC,QAAA,EAAK,WAAU,aACb,UAAA;AAAA,YAAA8oB,EAAK;AAAA,YAAO;AAAA,YAAEA,EAAK,OAAOA,EAAK;AAAA,YAAK;AAAA,YAAG;AAAA,8BACvC,UAAA,EAAQ,UAAAA,EAAK,QAAQ,WAAWA,EAAK,QAAO;AAAA,YAC5CA,EAAK,eAAe,UACnB,gBAAA9oB,EAAC,QAAA,EAAK,WAAU,aAAY,UAAA;AAAA,cAAA;AAAA,cAAI8oB,EAAK;AAAA,cAAW;AAAA,YAAA,EAAA,CAAE;AAAA,UAAA,EAAA,CAEtD,EAAA,CACF;AAAA,UACA,gBAAA9oB,EAAC,OAAA,EAAI,WAAU,aAAY,OAAO,EAAE,KAAK,GAAG,WAAW,EAAA,GACpD,UAAA;AAAA,YAAA8oB,EAAK,SAAS,gBAAA5uB,EAAC,OAAA,EAAI,WAAU,uBAAuB,YAAK,OAAM;AAAA,YAChE,gBAAAA,EAAC,OAAA,EAAI,WAAU,uBAAsB,UAAA,mBAAe;AAAA,YACpD,gBAAAA,EAAC,OAAA,EAAI,WAAU,cAAc,UAAA,KAAK,UAAU4uB,EAAK,kBAAkB,CAAA,GAAI,MAAM,CAAC,EAAA,CAAE;AAAA,YAC/EA,EAAK,eACJ,gBAAA9oB,EAAAwB,IAAA,EACE,UAAA;AAAA,cAAA,gBAAAtH,EAAC,OAAA,EAAI,WAAU,uBAAsB,UAAA,gBAAY;AAAA,gCAChDmjC,IAAA,EAAa,OAAOvU,EAAK,aAAa,WAAW,IAAA,CAAK;AAAA,YAAA,GACzD;AAAA,YAEF,gBAAA5uB,EAAC,OAAA,EAAI,WAAU,uBAAsB,UAAA,oBAAgB;AAAA,YACrD,gBAAAA,EAAC,OAAA,EAAI,WAAU,cAAc,UAAA,KAAK,UAAU4uB,EAAK,mBAAmB,CAAA,GAAI,MAAM,CAAC,EAAA,CAAE;AAAA,YAChFA,EAAK,gBACJ,gBAAA9oB,EAAAwB,IAAA,EACE,UAAA;AAAA,cAAA,gBAAAtH,EAAC,OAAA,EAAI,WAAU,uBAAsB,UAAA,iBAAa;AAAA,gCACjDmjC,IAAA,EAAa,OAAOvU,EAAK,cAAc,WAAW,IAAA,CAAK;AAAA,YAAA,GAC1D;AAAA,YAEDA,EAAK,aACJ,gBAAA5uB,EAAC,OAAA,EAAI,WAAU,uBAAsB,UAAA,2DAAA,CAErC;AAAA,UAAA,EAAA,CAEJ;AAAA,QAAA;AAAA,MAAA;AAAA,MArCKuX,EAAIqX,GAAMla,CAAC;AAAA,IAAA,CAuCnB;AAAA,EAAA,GACH;AAEJ;ACvGO,SAASg5B,GAAwB;AAAA,EACtC,SAAAvB;AAAA,EACA,UAAAtgC;AAAA,EACA,UAAAF;AACF,GAIG;AACD,QAAMtU,IAAW,IAAI,IAAI80C,EAAQ,QAAQ,GACnCe,IAAMf,EAAQ,QAAQ,MAAM,CAACl5B,MAAM5b,EAAS,IAAI4b,EAAE,KAAK,CAAC,GACxDjC,IAAU;AAAA,IACd,GAAGm7B,EAAQ;AAAA,IACX,GAAGA,EAAQ,SACR,OAAO,CAACtoC,MAAU,CAACsoC,EAAQ,QAAQ,KAAK,CAACl5B,MAAMA,EAAE,UAAUpP,CAAK,CAAC,EACjE,IAAI,CAACA,OAAW,EAAE,OAAAA,GAAO,OAAOA,IAAQ;AAAA,EAAA;AAE7C,SACE,gBAAAiC,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAA9F,EAAC,UAAK,UAAA,aAAA,CAAU;AAAA,IAChB,gBAAA8F,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,SAAA,EAAM,WAAU,yBACf,UAAA;AAAA,UAAA,gBAAA9F;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAASktC;AAAA,cACT,KAAK,CAAC9jC,MAAO;AACX,gBAAIA,MAAIA,EAAG,gBAAgB,CAAC8jC,KAAO71C,EAAS,OAAO;AAAA,cACrD;AAAA,cACA,UAAUsU;AAAA,cACV,UAAU,CAACtI,MACTwI,EAASxI,EAAE,OAAO,UAAU8oC,EAAQ,QAAQ,IAAI,CAACl5B,MAAMA,EAAE,KAAK,IAAI,CAAA,CAAE;AAAA,YAAA;AAAA,UAAA;AAAA,UAGxE,gBAAAjT,EAAC,UAAK,UAAA,aAAA,CAAU;AAAA,QAAA,GAClB;AAAA,QACA,gBAAA8F,EAAC,QAAA,EAAK,WAAU,uBAAuB,UAAA;AAAA,UAAAzO,EAAS;AAAA,UAAK;AAAA,QAAA,EAAA,CAAS;AAAA,MAAA,GAChE;AAAA,MACA,gBAAA2I,EAAC,YAAA,EAAS,WAAU,kCAAiC,cAAW,qBAC7D,UAAAgR,EAAQ,IAAI,CAAColB,MACZ,gBAAAtwB,EAAC,SAAA,EAAyB,WAAU,yBAClC,UAAA;AAAA,QAAA,gBAAA9F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS3I,EAAS,IAAI++B,EAAO,KAAK;AAAA,YAClC,UAAUzqB;AAAA,YACV,UAAU,CAACtI,MACTwI;AAAA,cACExI,EAAE,OAAO,UACL,CAAC,GAAG8oC,EAAQ,UAAU/V,EAAO,KAAK,IAClC+V,EAAQ,SAAS,OAAO,CAACpxC,MAAMA,MAAMq7B,EAAO,KAAK;AAAA,YAAA;AAAA,UACvD;AAAA,QAAA;AAAA,QAGJ,gBAAAp2B,EAAC,QAAA,EAAM,UAAAo2B,EAAO,MAAA,CAAM;AAAA,MAAA,KAbVA,EAAO,KAcnB,CACD,EAAA,CACH;AAAA,IAAA,GACF;AAAA,IACA,gBAAAp2B,EAAC,QAAA,EAAK,WAAU,YAAW,UAAA,sDAAA,CAAmD;AAAA,EAAA,GAChF;AAEJ;ACjDO,SAAS2tC,GAAa,EAAE,MAAA9yB,GAAM,MAAAlb,IAAO,MAAuC;AACjF,SACE,gBAAAK;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,OAAOL;AAAA,QACP,QAAQA;AAAA,QACR,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,OAAO;AAAA,MAAA;AAAA,MAGT,UAAA,gBAAAK;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAO,KAAK,MAAML,IAAO,GAAG;AAAA,UAC5B,QAAQ,KAAK,MAAMA,IAAO,GAAG;AAAA,UAC7B,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,QAAO;AAAA,UACP,aAAY;AAAA,UACZ,eAAc;AAAA,UACd,gBAAe;AAAA,UAEf,yBAAyB,EAAE,QAAQkb,EAAA;AAAA,QAAK;AAAA,MAAA;AAAA,IAC1C;AAAA,EAAA;AAGN;ACnCO,SAAS+yB,GACdnC,GACAoC,GACAC,GACAvgB,GACiC;;AACjC,MAAIke,MAAU,oBAAqB,QAAO;AAC1C,QAAMsC,IAAWF,KAAA,gBAAAA,EAAU,KAAK,CAACjpC,MAAMA,EAAE,QAAQ,aAC3CopC,KAAUx0C,IAAAu0C,KAAA,gBAAAA,EAAU,WAAV,gBAAAv0C,EAAkB,KAAK,CAACyD,MAAMA,EAAE,QAAQ,aAAaA,EAAE,SAAS;AAChF,MAAI,CAAC8wC,KAAY,CAAC,MAAM,QAAQC,KAAA,gBAAAA,EAAS,OAAO,KAAK,CAACA,EAAQ,QAAQ,OAAQ,QAAO;AACrF,QAAMh9B,IAAUg9B,EAAQ,QAAQ,IAAI,CAAC5X,MAAW;;AAC9C,UAAMvyB,IAAQ,OAAOuyB,EAAO,KAAK,GAC3B7e,IAAM1T,EAAM,QAAQ,SAAS,GAAG;AACtC,WAAO;AAAA,MACL,OAAAA;AAAA,MACA,SAAOrK,IAAAq0C,KAAA,gBAAAA,EAAU,KAAK,CAACjpC,MAAMA,EAAE,QAAQ2S,OAAhC,gBAAA/d,EAAsC,UAAS48B,EAAO;AAAA,MAC7D,YAAY7e;AAAA,IAAA;AAAA,EAEhB,CAAC,GACK02B,IAAQj9B,EAAQ,KAAK,CAACiC,MAAMA,EAAE,eAAe66B,CAAU;AAI7D,SAHIA,KAAcA,MAAeC,EAAS,OAAO,CAACE,KAG9CH,MAAeC,EAAS,OAAOxgB,EAAO,WAAW,QAAQ,CAAC,MAAM,QAAQA,EAAO,OAAO,IACjF,OAEF;AAAA,IACL,YAAYwgB,EAAS;AAAA,IACrB,SAAS/8B,EAAQ,KAAK,CAAC9Z,GAAGC,MAAMD,EAAE,MAAM,cAAcC,EAAE,KAAK,CAAC;AAAA,IAC9D,UAAU82C,IACN,CAACA,EAAM,KAAK,IACZ,MAAM,QAAQ1gB,EAAO,OAAO,IAC1BA,EAAO,QAAQ,OAAO,CAACxyB,MAAmB,OAAOA,KAAM,QAAQ,IAC/D,CAAA;AAAA,EAAC;AAEX;ACPO,SAASmzC,GAAc30C,GAAqC;;AACjE,WAAOC,IAAAD,KAAA,gBAAAA,EAAM,SAAN,gBAAAC,EAAY,SAAQpB,MAAemB,EAAK,KAAK,WAAW;AACjE;AAEA,SAAS40C,GAAc50C,GAAqC;;AAC1D,WAAOC,IAAAD,KAAA,gBAAAA,EAAM,SAAN,gBAAAC,EAAY,SAAQpB;AAC7B;AAGA,SAASg2C,GAAe70C,GAAqC;;AAC3D,UAAIA,KAAA,gBAAAA,EAAM,KAAK,SAAQJ,KAAmB,KAExC,CAACg1C,GAAc50C,CAAI,MAClBA,KAAA,gBAAAA,EAAM,KAAK,YAAW,UAAQC,IAAAD,EAAK,SAAL,gBAAAC,EAAW,UAAS,YAAawT,IAAAzT,EAAK,SAAL,gBAAAyT,EAAW,UAAS;AAExF;AAMO,SAASqhC,GAAgB90C,GAA0B;AACxD,MAAI,CAAC40C,GAAc50C,CAAI,UAAU,CAAA;AACjC,QAAM8P,IAAI9P,EAAK,QAAQ,CAAA,GACjB4B,IAAgB,CAAA,GAChBmzC,IAAU,CAACvzC,MAAe;AAC9B,QAAI,OAAOA,KAAM,SAAU,CAAAI,EAAI,KAAKJ,CAAC;AAAA,aAC5B,MAAM,QAAQA,CAAC,cAAcqO,KAAMrO,KAAWqO,CAAE;AAAA,EAC3D;AACA,SAAAklC,EAAQjlC,EAAE,IAAI,GACdilC,EAAQjlC,EAAE,QAAQ,GAClBilC,EAAQjlC,EAAE,IAAI,GACdilC,EAAQjlC,EAAE,IAAI,GACPlO;AACT;AAGO,SAASozC,GAAap2B,GAAyC;AACpE,QAAMq2B,wBAAY,IAAA;AAClB,aAAWtuC,KAAKiY,EAAO,YAAWxe,KAAM00C,GAAgBnuC,CAAC,EAAG,CAAAsuC,EAAM,IAAI70C,CAAE;AACxE,SAAO60C;AACT;AAGO,SAASC,GACd5mB,GACAuZ,GACAsN,GACArN,GACM;AACN,SAAO;AAAA,IACL,IAAIsN,GAAW9mB,GAAMuZ,GAAI,QAAQC,CAAK;AAAA,IACtC,QAAQxZ;AAAA,IACR,QAAQuZ;AAAA,IACR,cACEC,MAAU,SAAY3nC,GAAY2nC,CAAK,IAAIqN,IAAgB72C,KAAqB;AAAA,IAClF,UAAU;AAAA,IACV,MAAM,EAAE,MAAM,QAAQ,GAAIwpC,MAAU,SAAY,CAAA,IAAK,EAAE,OAAAA,IAAM;AAAA,IAC7D,GAAG9pC,GAAY,QAAQ,MAAS;AAAA,EAAA;AAEpC;AAIA,MAAMq3C,KAAU,CAAC;;AACf,kBAAOp1C,IAAA,EAAE,SAAF,gBAAAA,EAAQ,UAAU,WAAW,EAAE,KAAK,QAAQ;AAAA;AAW9C,SAASq1C,GACdC,GACA/1B,GACAg2B,GACAC,GACU;AACV,QAAMC,IAAS,IAAI,IAAIl2B,EAAM,IAAI,CAACtL,MAAMA,EAAE,EAAE,CAAC,GACvCyhC,IAAOH,EAAM,OAAO,CAAC1rC,MAAM8rC,GAAS9rC,CAAC,MAAM,MAAM,GACjD5F,IAAO,oBAAI,IAAY,CAACqxC,CAAS,CAAC,GAClChE,IAAkB,CAAA,GAClBsE,IAAQ,CAACN,CAAS;AACxB,WAAS/nC,IAAI,GAAGA,IAAIqoC,EAAM,QAAQroC;AAChC,eAAW1D,KAAK6rC;AACd,MAAI7rC,EAAE,WAAW+rC,EAAMroC,CAAC,MACpB,CAACkoC,EAAO,IAAI5rC,EAAE,MAAM,KAAK5F,EAAK,IAAI4F,EAAE,MAAM,KAAK2rC,KAAA,QAAAA,EAAS,IAAI3rC,EAAE,YAClE5F,EAAK,IAAI4F,EAAE,MAAM,GACjBynC,EAAM,KAAKznC,EAAE,MAAM,GACnB+rC,EAAM,KAAK/rC,EAAE,MAAM;AAGvB,QAAMgsC,IAAQ,IAAI,IAAIvE,EAAM,IAAI,CAACnxC,GAAI+a,MAAM,CAAC/a,GAAI+a,CAAC,CAAC,CAAC,GAC7C46B,IAAWJ,EAAK;AAAA,IACpB,CAAC7rC,MAAMA,EAAE,WAAWyrC,KAAaO,EAAM,IAAIhsC,EAAE,MAAM,KAAKgsC,EAAM,IAAIhsC,EAAE,MAAM;AAAA,EAAA,GAEtEksC,IAAQ,IAAI,IAAIzE,EAAM,IAAI,CAACnxC,MAAO,CAACA,GAAI,CAAC,CAAC,CAAC;AAChD,aAAW0J,KAAKisC,EAAU,CAAAC,EAAM,IAAIlsC,EAAE,SAASksC,EAAM,IAAIlsC,EAAE,MAAM,KAAK,KAAK,CAAC;AAC5E,QAAMlI,IAAgB,CAAA,GAChBk0B,wBAAW,IAAA;AACjB,aAAS;AACP,UAAM1qB,IAAOmmC,EAAM,KAAK,CAACnxC,MAAO,CAAC01B,EAAK,IAAI11B,CAAE,KAAK41C,EAAM,IAAI51C,CAAE,MAAM,CAAC;AACpE,QAAIgL,MAAS,OAAW;AACxB,IAAA0qB,EAAK,IAAI1qB,CAAI,GACbxJ,EAAI,KAAKwJ,CAAI;AACb,eAAWtB,KAAKisC;AACd,MAAIjsC,EAAE,WAAWsB,KAAM4qC,EAAM,IAAIlsC,EAAE,SAASksC,EAAM,IAAIlsC,EAAE,MAAM,KAAK,KAAK,CAAC;AAAA,EAC7E;AACA,aAAW1J,KAAMmxC,EAAO,CAAKzb,EAAK,IAAI11B,CAAE,KAAGwB,EAAI,KAAKxB,CAAE;AACtD,SAAOwB;AACT;AAGO,SAASq0C,GAAkBlqC,GAAyBypC,GAAgC;AACzF,QAAM9wC,IAAM,IAAI,IAAIqH,CAAI;AACxB,SAAOypC,EAAM,OAAO,CAAC1rC,MAAM8rC,GAAS9rC,CAAC,MAAM,UAAUpF,EAAI,IAAIoF,EAAE,MAAM,KAAKpF,EAAI,IAAIoF,EAAE,MAAM,CAAC;AAC7F;AAOO,SAASosC,GAAYnqC,GAAyBypC,GAAiC;AACpF,QAAMO,IAAWE,GAAkBlqC,GAAMypC,CAAK,GACxCW,wBAAW,IAAA;AACjB,aAAWrsC,KAAKisC,GAAU;AACxB,QAAIV,GAAQvrC,CAAC,MAAM,UAAaqsC,EAAK,IAAIrsC,EAAE,MAAM,EAAG,QAAO;AAC3D,IAAAqsC,EAAK,IAAIrsC,EAAE,MAAM;AAAA,EACnB;AACA,SAAO;AACT;AAGO,SAASssC,GACd52B,GACAg2B,GACY;AACZ,QAAM5zC,IAAkB,CAAA;AACxB,aAAWmK,KAAQsqC,GAAW72B,GAAOg2B,CAAK,EAAE;AAC1C,QAAI,CAAAU,GAAYnqC,GAAMypC,CAAK;AAC3B,iBAAW1rC,KAAKmsC,GAAkBlqC,GAAMypC,CAAK,GAAG;AAC9C,cAAM1N,IAAQuN,GAAQvrC,CAAC;AACvB,QAAAlI,EAAI,KAAK,EAAE,MAAMkI,EAAE,QAAQ,IAAIA,EAAE,QAAQ,GAAIg+B,MAAU,SAAY,CAAA,IAAK,EAAE,OAAAA,EAAA,GAAU;AAAA,MACtF;AAEF,SAAOlmC;AACT;AAGO,SAASy0C,GACd72B,GACAg2B,GACuB;;AACvB,QAAM5zC,wBAAU,IAAA,GACV6zC,wBAAc,IAAA;AACpB,aAAWvhC,KAAKsL,GAAO;AACrB,QAAI,CAACm1B,IAAc10C,IAAAiU,EAAE,SAAF,gBAAAjU,EAAQ,IAAI,EAAG;AAClC,UAAMykB,IAAQ4wB,GAASphC,EAAE,IAAIsL,GAAOg2B,GAAOC,CAAO;AAClD,eAAWr1C,KAAMskB,EAAO,CAAA+wB,EAAQ,IAAIr1C,CAAE;AACtC,IAAAwB,EAAI,IAAIsS,EAAE,IAAIwQ,CAAK;AAAA,EACrB;AACA,SAAO9iB;AACT;AAGO,SAAS00C,GACd92B,GACAg2B,GACwB;AACxB,QAAM5zC,IAA8B,CAAA;AACpC,aAAW,CAAC20C,GAAK7xB,CAAK,KAAK2xB,GAAW72B,GAAOg2B,CAAK,EAAG,YAAWp1C,KAAMskB,EAAO,CAAA9iB,EAAIxB,CAAE,IAAIm2C;AACvF,SAAO30C;AACT;AAUO,SAAS40C,GACdp2C,GACAof,GACAg2B,GACQ;AACR,QAAMiB,IAAW,CAAC3sC,MAAYA,EAAE,WAAW1J,KAAM0J,EAAE,WAAW1J,GACxDs2C,IAAQlB,EAAM,OAAO,CAAC1rC,MAAM,CAAC2sC,EAAS3sC,CAAC,CAAC;AAE9C,MAAI6qC,IADW,CAACgC,MAAA;;AAAgB,YAAAljC,KAAAxT,IAAAuf,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAOyiC,CAAG,MAA9B,gBAAA12C,EAAiC,SAAjC,gBAAAwT,EAAuC;AAAA,KAC9CrT,CAAE,CAAC,GAAG;AAC7B,UAAM2L,IAAOupC,GAASl1C,GAAIof,GAAOg2B,CAAK,GAChCoB,IAAS,IAAI,IAAI7qC,CAAI;AAC3B,WAAO2qC,EAAM;AAAA,MACX,CAAC5sC,MACC,EACE8rC,GAAS9rC,CAAC,MAAM,WACfA,EAAE,WAAW1J,KAAMw2C,EAAO,IAAI9sC,EAAE,MAAM,MACvC8sC,EAAO,IAAI9sC,EAAE,MAAM;AAAA,IAAA;AAAA,EAG3B;AACA,QAAMysC,IAAMD,GAAe92B,GAAOg2B,CAAK,EAAEp1C,CAAE;AAC3C,MAAIm2C,MAAQ,OAAW,QAAOG;AAC9B,QAAMG,IAAMrB,EAAM,OAAO,CAAC1rC,MAAMA,EAAE,WAAW1J,KAAMw1C,GAAS9rC,CAAC,MAAM,MAAM,GACnEqsC,IAAOX,EAAM,OAAO,CAAC1rC,MAAMA,EAAE,WAAW1J,KAAMw1C,GAAS9rC,CAAC,MAAM,MAAM;AAC1E,MAAI+sC,EAAI,WAAW,KAAKV,EAAK,WAAW,EAAG,QAAOO;AAClD,QAAM1pC,IAAO6pC,EAAI,CAAC,EAAE,QACdzrC,IAAO+qC,EAAK,CAAC,EAAE;AACrB,SAAIO,EAAM,KAAK,CAAC5sC,MAAMA,EAAE,WAAWkD,KAAQlD,EAAE,WAAWsB,KAAQwqC,GAAS9rC,CAAC,MAAM,MAAM,IAC7E4sC,IAEF,CAAC,GAAGA,GAAOxB,GAAaloC,GAAM5B,GAAM4B,MAASupC,GAAKlB,GAAQwB,EAAI,CAAC,CAAC,CAAC,CAAC;AAC3E;AAGO,SAASC,GAAmE92C,GAAY;AAC7F,MAAI,CAAC20C,GAAc30C,CAAI,KAAK,CAACA,EAAK,QAAQ,EAAE,UAAUA,EAAK,MAAO,QAAOA;AACzE,QAAM,EAAE,MAAM+2C,GAAO,GAAGtoC,EAAA,IAASzO,EAAK;AACtC,SAAO,EAAE,GAAGA,GAAM,MAAMyO,EAAA;AAC1B;AAmBO,SAASuoC,GACd1/B,GACAwM,GACA3lB,GACAqhB,GACAg2B,GAC0B;AAC1B,QAAMyB,IAAIX,GAAe92B,GAAOg2B,CAAK;AACrC,MAAIr3C,MAAS;AACX,WAAO84C,EAAE3/B,CAAM,MAAM,UAAa2/B,EAAEnzB,CAAM,MAAM,SAAY,uBAAuB;AAErF,MAAI3lB,MAAS,UAAW,QAAO84C,EAAEnzB,CAAM,MAAM,SAAY,oBAAoB;AAC7E,QAAMozB,IAAS,CAAC92C,MAAA;;AAAe,YAAAqT,KAAAxT,IAAAuf,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAO9T,CAAE,MAA7B,gBAAAH,EAAgC,SAAhC,gBAAAwT,EAAsC;AAAA,KAC/D0jC,IAAQxC,GAAcuC,EAAO5/B,CAAM,CAAC,IAAIA,IAAS2/B,EAAE3/B,CAAM;AAC/D,MAAI6/B,MAAU,OAAW,QAAO;AAChC,MAAIrzB,MAAWqzB,EAAO,QAAO;AAI7B,QAAMC,IAAW,MACf9/B,MAAW6/B,KAAS,CAAC3B,EAAM,KAAK,CAAC1rC,MAAMA,EAAE,WAAWwN,KAAUs+B,GAAS9rC,CAAC,MAAM,MAAM;AACtF,SAAImtC,EAAEnzB,CAAM,MAAMqzB,IAEZ7/B,MAAW6/B,KACXE,GAAQvzB,GAAQxM,GAAQk+B,CAAK,IAAU,eACpC4B,EAAA,IAAa,OAAO,gBAEzBH,EAAEnzB,CAAM,MAAM,SAAkB,oBAC/B+wB,GAAeqC,EAAOpzB,CAAM,CAAC,IAC7BszB,EAAA,IACD5B,EAAM,KAAK,CAAC1rC,MAAMA,EAAE,WAAWga,KAAUha,EAAE,WAAWga,CAAM,IAAU,cACnE,OAFiB,gBADoB;AAI9C;AAGA,SAASuzB,GAAQ/oB,GAAcuZ,GAAY2N,GAAiC;AAC1E,QAAMtxC,IAAO,oBAAI,IAAY,CAACoqB,CAAI,CAAC,GAC7BxG,IAAQ,CAACwG,CAAI;AACnB,SAAOxG,EAAM,SAAS,KAAG;AACvB,UAAMrX,IAAMqX,EAAM,IAAA;AAClB,QAAIrX,MAAQo3B,EAAI,QAAO;AACvB,eAAW/9B,KAAK0rC;AACd,MAAI1rC,EAAE,WAAW2G,KAAOmlC,GAAS9rC,CAAC,MAAM,UAAU5F,EAAK,IAAI4F,EAAE,MAAM,MACnE5F,EAAK,IAAI4F,EAAE,MAAM,GACjBge,EAAM,KAAKhe,EAAE,MAAM;AAAA,EAEvB;AACA,SAAO;AACT;AAGA,MAAMwtC,KAA2D;AAAA,EAC/D,oBACE;AAAA,EACF,iBACE;AAAA,EACF,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,iBACE;AAAA,EACF,aACE;AAAA,EACF,WACE;AACJ;AAEO,SAASC,GAAmBtvC,GAAmC;AACpE,SAAOqvC,GAAsBrvC,CAAM;AACrC;AAMO,SAASuvC,GAAYh4B,GAAmBg2B,GAA2B;AACxE,QAAMyB,IAAIX,GAAe92B,GAAOg2B,CAAK;AACrC,MAAIphB,IAAU;AACd,QAAMxyB,IAAM4d,EAAM,IAAI,CAACtL,MAAM;AAC3B,UAAMujC,IAAOR,EAAE/iC,EAAE,EAAE;AACnB,QAAIA,EAAE,KAAK,WAAWujC,EAAM,QAAOvjC;AAEnC,QADAkgB,IAAU,IACNqjB,MAAS,QAAW;AACtB,YAAM,EAAE,QAAQ1G,GAAO,GAAG5M,EAAA,IAASjwB,EAAE;AACrC,aAAO,EAAE,GAAGA,GAAG,MAAAiwB,EAAA;AAAA,IACjB;AACA,WAAO,EAAE,GAAGjwB,GAAG,MAAM,EAAE,GAAGA,EAAE,MAAM,QAAQujC,IAAK;AAAA,EACjD,CAAC;AACD,SAAOrjB,IAAUxyB,IAAM4d;AACzB;AAGO,SAASk4B,GAAkBt3C,GAAYof,GAAmBg2B,GAAuB;;AACtF,QAAMlpC,IAAO,gBAAgBlM,CAAE,uCACzBJ,KAAOyT,KAAAxT,IAAAuf,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAO9T,CAAE,MAA7B,gBAAAH,EAAgC,SAAhC,gBAAAwT,EAAsC;AACnD,MAAI,CAACkhC,GAAc30C,CAAI,EAAG,QAAOsM;AACjC,QAAMP,IAAOupC,GAASl1C,GAAIof,GAAOg2B,CAAK;AACtC,SAAIzpC,EAAK,WAAW,IAAUO,IACvB,GAAGA,CAAI,wBAAwBP,EAAK,IAAI,CAACnO,MAAM,IAAIA,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;AAC5E;AAoBO,SAAS+5C,GAAeC,GAA8B;AAC3D,MAAIA,EAAG,MAAO,QAAOA,EAAG;AACxB,QAAM3C,IAAQD,GAAa4C,EAAG,KAAK,GAC7BhgB,IAAOggB,EAAG,MAAM,OAAO,CAACjxC,MAAM,CAACsuC,EAAM,IAAItuC,EAAE,EAAE,CAAC,GAC9C/E,IAAkB,CAAA;AACxB,WAASuZ,IAAI,GAAGA,IAAIyc,EAAK,SAAS,GAAGzc,OAAS,KAAK,EAAE,MAAMyc,EAAKzc,CAAC,EAAE,IAAI,IAAIyc,EAAKzc,IAAI,CAAC,EAAE,IAAI;AAC3F,SAAOvZ;AACT;AAEA,MAAMi2C,KAAY,CAAC,OAAiB,EAAE,QAAQ,eAAe,WAGhDC,KAAa,CAAC,MAAyB,EAAE,UAAUt5C,MAAsBq5C,GAAU,CAAC;AAS1F,SAASE,GAAgBH,GAA8C;AAC5E,QAAMI,IAAO,IAAI,IAAIJ,EAAG,MAAM,IAAI,CAACjxC,MAAM,CAACA,EAAE,IAAIA,CAAC,CAAC,CAAC,GAC7CsxC,wBAAa,IAAA;AACnB,aAAWtxC,KAAKixC,EAAG;AACjB,eAAW3M,KAAO6J,GAAgBnuC,CAAC,GAAG;AACpC,YAAMuwB,IAAM+gB,EAAO,IAAIhN,CAAG,yBAAS,IAAA;AACnC,MAAA/T,EAAI,IAAIvwB,EAAE,EAAE,GACZsxC,EAAO,IAAIhN,GAAK/T,CAAG;AAAA,IACrB;AAEF,QAAMse,IAAQmC,GAAeC,CAAE,GACzBM,IAAWN,EAAG,SAAS,CAAA,GACvBh2C,IAAkC,CAAA;AAExC,aAAWsjB,KAAK0yB,EAAG,OAAO;AACxB,QAAI,CAACjD,GAAczvB,CAAC,EAAG;AACvB,UAAMpV,IAAIoV,EAAE,QAAQ,CAAA;AACpB,QAAI,UAAUpV,GAAG;AACf,MAAAlO,EAAIsjB,EAAE,EAAE,IAAIizB,EAAYjzB,EAAE,IAAIpV,EAAE,IAAI;AACpC;AAAA,IACF;AACA,IAAAlO,EAAIsjB,EAAE,EAAE,IAAIkzB,EAAWlzB,EAAE,EAAE;AAAA,EAC7B;AACA,SAAOtjB;AAEP,WAASu2C,EAAY5B,GAAaxqC,GAA2B;AAC3D,UAAMsoB,IAAM,CAACpsB,GAA2BmmB,OAAiC;AAAA,MACvE,SAASA,MAAW,SAAY,EAAE,QAAAnmB,MAAW,EAAE,QAAAA,GAAQ,QAAAmmB,EAAA;AAAA,IAAO;AAEhE,QAAI,CAAC,MAAM,QAAQriB,CAAI,KAAKA,EAAK,KAAK,CAACnO,MAAM,OAAOA,KAAM,QAAQ;AAChE,aAAOy2B,EAAI,kBAAkB;AAE/B,UAAM3vB,IAAMqH,GACN6qC,IAAS,IAAI,IAAIlyC,CAAG,GACpBR,wBAAW,IAAA;AACjB,eAAW9D,KAAMsE,GAAK;AACpB,UAAI,CAACszC,EAAK,IAAI53C,CAAE,EAAG,QAAOi0B,EAAI,qBAAqBj0B,CAAE;AACrD,UAAIA,MAAOm2C,EAAK,QAAOliB,EAAI,aAAaj0B,CAAE;AAC1C,UAAI8D,EAAK,IAAI9D,CAAE,EAAG,QAAOi0B,EAAI,kBAAkBj0B,CAAE;AAEjD,UADA8D,EAAK,IAAI9D,CAAE,GACP,CAACy0C,GAAemD,EAAK,IAAI53C,CAAE,CAAC,EAAG,QAAOi0B,EAAI,yBAAyBj0B,CAAE;AACzE,YAAMi4C,IAAMJ,EAAO,IAAI73C,CAAE;AACzB,UAAIi4C,KAAO,CAAC,GAAGA,CAAG,EAAE,KAAK,CAAC3+B,MAAMA,MAAM68B,CAAG,EAAG,QAAOliB,EAAI,sBAAsBj0B,CAAE;AAAA,IACjF;AAIA,UAAMk4C,IAAwB,CAAA;AAC9B,eAAWxuC,KAAKouC,GAAU;AAGxB,UAFIJ,GAAWhuC,CAAC,KAAKA,EAAE,SAASysC,KAAOzsC,EAAE,OAAOpF,EAAI,CAAC,KAEjD,EADYkyC,EAAO,IAAI9sC,EAAE,IAAI,KAAK8sC,EAAO,IAAI9sC,EAAE,EAAE,GACvC;AAEd,UAAI,EADa8sC,EAAO,IAAI9sC,EAAE,IAAI,KAAK8sC,EAAO,IAAI9sC,EAAE,EAAE,KAAK+tC,GAAU/tC,CAAC,KAAKA,EAAE,OAAOpF,EAAI,CAAC,GAC1E,QAAO2vB,EAAI,uBAAuBuiB,EAAO,IAAI9sC,EAAE,IAAI,IAAIA,EAAE,OAAOA,EAAE,EAAE;AACnF,MAAAwuC,EAAU,KAAKxuC,CAAC;AAAA,IAClB;AACA,WAAOwuC,EAAU,SAAS,IACtB,EAAE,MAAM5zC,GAAK,QAAQ,QAAQ,OAAO4zC,MACpC,EAAE,MAAM5zC,GAAK,QAAQ,OAAA;AAAA,EAC3B;AAEA,WAAS0zC,EAAW7B,GAAyB;;AAE3C,UAAMgC,IAAO/C,EAAM,OAAO,CAAC1rC,MAAMA,EAAE,SAASysC,KAAOsB,GAAU/tC,CAAC,KAAKA,EAAE,UAAU,MAAS;AACxF,QAAIyuC,EAAK,WAAW,EAAG,QAAO,EAAE,MAAM,CAAA,GAAI,QAAQ,OAAA;AAClD,UAAMlkB,IAAM,CAACjG,OAAgC;AAAA,MAC3C,SAAS,EAAE,QAAQ,qBAAqB,QAAAA,EAAA;AAAA,IAAO;AAEjD,QAAImqB,EAAK,SAAS,EAAG,QAAOlkB,EAAIkiB,CAAG;AACnC,UAAM7xB,IAAkB,CAAA,GAClBxgB,IAAO,oBAAI,IAAY,CAACqyC,CAAG,CAAC;AAClC,QAAIvpC,IAAOupC,GACPnrC,IAA2BmtC,EAAK,CAAC,EAAE;AACvC,WAAOntC,MAAS,UAAW;AACzB,YAAM8I,IAAY9I,GACZpL,IAAOg4C,EAAK,IAAI9jC,CAAC;AACvB,UAAI,CAAClU,KAAQkE,EAAK,IAAIgQ,CAAC,KAAK,CAAC2gC,GAAe70C,CAAI,KAAKi4C,EAAO,IAAI/jC,CAAC,EAAG,QAAOmgB,EAAIngB,CAAC;AAChF,YAAMskC,IAAUhD,EAAM,OAAO,CAAC1rC,MAAMA,EAAE,OAAOoK,CAAC;AAC9C,UAAIskC,EAAQ,WAAW,KAAKA,EAAQ,CAAC,EAAE,SAASxrC,EAAM,QAAOqnB,EAAIngB,CAAC;AAClE,YAAMukC,IAAWjD,EAAM,OAAO,CAAC1rC,MAAMA,EAAE,SAASoK,CAAC;AACjD,UAAIukC,EAAS,SAAS,KAAMA,EAAS,WAAW,KAAK,CAACZ,GAAUY,EAAS,CAAC,CAAC,EAAI,QAAOpkB,EAAIngB,CAAC;AAC3F,MAAAhQ,EAAK,IAAIgQ,CAAC,GACVwQ,EAAM,KAAKxQ,CAAC,GACZlH,IAAOkH,GACP9I,KAAOnL,IAAAw4C,EAAS,CAAC,MAAV,gBAAAx4C,EAAa;AAAA,IACtB;AACA,WAAO,EAAE,MAAMykB,GAAO,QAAQ,SAAA;AAAA,EAChC;AACF;ACrdO,SAASkxB,GAAS,GAAqB;;AAC5C,QAAM33C,KAAQgC,IAAA,EAAE,SAAF,gBAAAA,EAA0C;AACxD,SAAOhC,MAAS,UAAU,UAAUA,MAAS,SAAS,SAAS;AACjE;AAiCA,SAASy6C,GAAgBC,GAAmBv4C,GAA2B;;AACrE,WAAOH,IAAA04C,EAAU,KAAK,CAAC7uC,MAAMA,EAAE,OAAO1J,CAAE,MAAjC,gBAAAH,EAAoC,OAAM;AACnD;AAwBO,SAAS24C,GACdthC,GACAwM,GACAtE,GACAg2B,GACAzzC,GACA+lC,GACS;;AAET,MADI,CAACxwB,KAAU,CAACwM,KAAUxM,MAAWwM,KACjC0xB,EAAM,KAAK,CAAC1rC,MAAA;;AAAM,WAAAA,EAAE,WAAWwN,KAAUxN,EAAE,WAAWga,OAAU7jB,IAAA6J,EAAE,SAAF,gBAAA7J,EAAQ,WAAU6nC;AAAA,GAAK;AACzF,WAAO;AACT,QAAM+Q,KAAU54C,IAAAuf,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAOoD,CAAM,MAAjC,gBAAArX,EAAoC,KAAK,MACnD64C,KAAUrlC,IAAA+L,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAO4P,CAAM,MAAjC,gBAAArQ,EAAoC,KAAK;AACzD,MAAI,CAAColC,KAAW,CAACC,EAAS,QAAO;AAEjC,QAAMC,IAAWj3C,GAAiB+2C,GAAS92C,CAAM,GAC3Ci3C,IAAWl3C,GAAiBg3C,GAAS/2C,CAAM;AACjD,SAAOg3C,EAAS,OAAO,KAAKC,EAAS,MAAM;AAC7C;AAUA,SAASC,GACP3hC,GACAwM,GACAtE,GACAg2B,GACAv3C,GACA8D,GACAm3C,GAC+F;;AAE/F,QAAMC,IACJl7C,MAAS,aAAa02C,IAAc10C,IAAAuf,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAOoD,CAAM,MAAjC,gBAAArX,EAAoC,KAAK,IAAI,GAC7E6nC,IAAQqR,KAAeD,MAAe,SAAY36C,KAAqB26C;AAC7E,MAAI,CAACN,GAAWthC,GAAQwM,GAAQtE,GAAOg2B,GAAOzzC,GAAQ+lC,CAAK,KAAK,CAACxwB,KAAU,CAACwM,EAAQ,QAAO;AAC3F,QAAM+0B,KAAUplC,IAAA+L,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAOoD,CAAM,MAAjC,gBAAA7D,EAAoC,KAAK,MACnDqlC,KAAU5/B,IAAAsG,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAO4P,CAAM,MAAjC,gBAAA5K,EAAoC,KAAK;AACzD,MAAI,CAAC2/B,KAAW,CAACC,EAAS,QAAO;AACjC,QAAMM,IAAUr4C,GAAS83C,CAAO;AAChC,MAAIM;AACF,QAAIrR,MAAUvpC,GAAoB,QAAO;AAAA,aAChCs6C,EAAQ,KAAK,QAAQj5C,MAAc3B,MAAS;AACrD,QAAI,CAAC8B,GAAc84C,CAAO,EAAE,KAAK,CAAC34C,MAAMA,EAAE,OAAO4nC,CAAK,EAAG,QAAO;AAAA,aACvDsR,KAAWn7C,MAAS;AAE7B,QAAI6pC,MAAU,UAAaA,MAAUhnC,GAAgB,QAAO;AAAA,aACnDgnC,MAAU,OAAW,QAAO;AAGvC,QAAM8O,IAASN,GAAe92B,GAAOg2B,CAAK,EAAEl+B,CAAM,MAAM,QAClD+hC,IAAsBp7C,MAAS,aAAa24C,IAAS,SAAS34C;AAGpE,MAAIo7C,MAAY,UAAU,CAACzC,KAAU,CAACjC,GAAckE,CAAO,EAAG,QAAO;AAGrE,QAAMS,IAAatC,GAAY1/B,GAAQwM,GAAQu1B,GAAS75B,GAAOg2B,CAAK;AACpE,MAAI8D;AACF,WAAO,EAAE,MAAM9D,GAAO,UAAU,MAAM,SAAS,EAAE,SAAS,QAAQ,QAAQ8D,EAAA,EAAW;AAEvF,QAAMP,IAAWj3C,GAAiB+2C,GAAS92C,CAAM,GAC3CqJ,IAAOoqC,GAGP+D,IAAUnuC,EAAK;AAAA,IACnB,CAACtB,MAAA;;AAAM,aAAAA,EAAE,WAAWwN,KAAUs+B,GAAS9rC,CAAC,MAAMuvC,OAAWp5C,IAAA6J,EAAE,SAAF,gBAAA7J,EAAQ,WAAU6nC;AAAA;AAAA,EAAA,GAGvE0R,IAAM1R,MAAU,UAAasR,KAAWD,IAAcJ,EAAS,MAAM;AAC3E,MAAIQ,EAAQ,UAAUC;AACpB,WAAO,EAAE,MAAMhE,GAAO,UAAU,MAAM,SAAS,EAAE,SAAS,WAAW,KAAAgE,IAAI;AAiB3E,QAAMp5C,IAAKg1C,GAAW99B,GAAQwM,GAAQu1B,GAASvR,CAAK,GAG9C2R,IAAeJ,MAAY,UAAUzC,IAAS,SAAYn4C,GAAoB46C,CAAO;AAC3F,SAAO;AAAA,IACL,MAAMK;AAAA,MACJ;AAAA,QACE,QAAApiC;AAAA,QACA,QAAAwM;AAAA,QACA,IAAA1jB;AAAA,QACA,cAAc0nC,MAAU,SAAY2R,IAAet5C,GAAY2nC,CAAK;AAAA,QACpE,MAAM,EAAE,MAAMuR,GAAS,GAAIvR,MAAU,SAAY,CAAA,IAAK,EAAE,OAAAA,IAAM;AAAA;AAAA;AAAA;AAAA,QAI9D,GAAG9pC,GAAYq7C,GAAS,MAAS;AAAA,MAAA;AAAA,MAEnCjuC;AAAA,IAAA;AAAA,IAEF,UAAUstC,GAAgBttC,GAAMhL,CAAE;AAAA,IAClC,SAAS;AAAA,EAAA;AAEb;AA+BO,SAASu5C,GACdriC,GACAwM,GACAtE,GACAg2B,GACAv3C,IAAmB,WACnB8D,GACA+lC,GACe;AACf,QAAMvS,IAAO0jB,GAAY3hC,GAAQwM,GAAQtE,GAAOg2B,GAAOv3C,GAAM8D,GAAQ+lC,CAAK;AAC1E,SAAI,CAACvS,KAAQA,EAAK,YAAYA,EAAK,UAAgB,OAC5CA,EAAK;AACd;AAYO,SAASqkB,GACdtiC,GACAwM,GACAtE,GACAg2B,GACAv3C,IAAmB,WACnB8D,GACA+lC,GACe;;AACf,WAAO7nC,IAAAg5C,GAAY3hC,GAAQwM,GAAQtE,GAAOg2B,GAAOv3C,GAAM8D,GAAQ+lC,CAAK,MAA7D,gBAAA7nC,EAAgE,aAAY;AACrF;AAOO,SAAS45C,GACdviC,GACAwM,GACAtE,GACAg2B,GACAv3C,IAAmB,WACnB8D,GACA+lC,GACoC;;AACpC,WAAO7nC,IAAAg5C,GAAY3hC,GAAQwM,GAAQtE,GAAOg2B,GAAOv3C,GAAM8D,GAAQ+lC,CAAK,MAA7D,gBAAA7nC,EAAgE,YAAW;AACpF;AAaA,SAAS65C,GACPtE,GACAuE,GACA97C,GACAuhB,GACAzd,GACiF;;AAQjF,QAAMi4C,IAAUxE,EAAM,OAAO,CAAC1rC,MAAMA,EAAE,OAAOiwC,CAAM;AACnD,MAAIC,EAAQ,WAAW,EAAG,QAAO;AACjC,QAAMC,IAAKD,EAAQ,CAAC;AAGpB,MAAIpE,GAASqE,CAAE,MAAM,OAAQ,QAAO;AACpC,QAAMpB,KAAU54C,IAAAuf,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAO+lC,EAAG,MAAM,MAApC,gBAAAh6C,EAAuC,KAAK;AAE5D,MADI,CAAC44C,KACDA,EAAQ,KAAK,QAAQj5C,MAAci5C,EAAQ,KAAK,QAAQh5C,GAAU,QAAO;AAC7E,QAAM+B,IAAME,GAAiB+2C,GAAS92C,CAAM,EAAE,KAYxCyhC,IAASgS,EAAM,OAAO,CAAC1rC,MAAMA,EAAE,OAAOiwC,CAAM;AAKlD,OAHEnE,GAASqE,CAAE,MAAMh8C,IACb,CAAA,IACAulC,EAAO,OAAO,CAAC15B,MAAMA,EAAE,WAAWmwC,EAAG,UAAUrE,GAAS9rC,CAAC,MAAM7L,CAAI,GAC5D,UAAU2D;AACrB,WAAO,EAAE,MAAM4zC,GAAO,UAAU,MAAM,SAAS,EAAE,SAAS,WAAW,KAAK5zC,EAAA,EAAI;AAYhF,QAAMs4C,IAAUl8C,GAAYC,GAAM,MAAS,GAErCghB,IAAU01B,GAAckE,CAAO,GAC/B/iB,IAAO7W,KAAWhhB,MAAS,YAAYM,KAAqB,QAC5D,EAAE,OAAO47C,GAAQ,GAAGC,MAAcH,EAAG,QAAQ,CAAA,GAC7CI,IAAgB;AAAA,IACpB,GAAGJ;AAAA,IACH,IAAI7E,GAAW6E,EAAG,QAAQA,EAAG,QAAQh8C,GAAM63B,CAAI;AAAA,IAC/C,MAAM7W,IAAU,EAAE,GAAGm7B,GAAU,MAAAn8C,GAAM,GAAI63B,IAAO,EAAE,OAAOA,EAAA,IAAS,CAAA,EAAC,IAAO,EAAE,GAAGmkB,EAAG,MAAM,MAAAh8C,EAAA;AAAA,IACxF,WAAWi8C,EAAQ;AAAA,IACnB,OAAOA,EAAQ;AAAA,IACf,cAAcpkB,IAAO31B,GAAY21B,CAAI,IAAIr3B,GAAoBR,CAAI;AAAA,EAAA,GAG7Dq8C,IAAW5B,GAAgBlV,GAAQ6W,EAAQ,EAAE;AACnD,SAAO;AAAA;AAAA,IAEL,MAAM7E,EAAM,IAAI,CAAC1rC,MAAOA,EAAE,OAAOiwC,IAASM,IAAUvwC,CAAE;AAAA,IACtD,UAAAwwC;AAAA,IACA,SAAS;AAAA,EAAA;AAEb;AAwBO,SAASC,GACd/E,GACAuE,GACA97C,GACAuhB,GACAzd,GACe;AACf,QAAMwzB,IAAOukB,GAAWtE,GAAOuE,GAAQ97C,GAAMuhB,GAAOzd,CAAM;AAC1D,SAAI,CAACwzB,KAAQA,EAAK,YAAYA,EAAK,UAAgB,OAC5CA,EAAK;AACd;AAQO,SAASilB,GACdhF,GACAuE,GACA97C,GACAuhB,GACAzd,GACe;;AACf,WAAO9B,IAAA65C,GAAWtE,GAAOuE,GAAQ97C,GAAMuhB,GAAOzd,CAAM,MAA7C,gBAAA9B,EAAgD,aAAY;AACrE;AAGO,SAASw6C,GACdjF,GACAuE,GACA97C,GACAuhB,GACAzd,GACsB;;AACtB,WAAO9B,IAAA65C,GAAWtE,GAAOuE,GAAQ97C,GAAMuhB,GAAOzd,CAAM,MAA7C,gBAAA9B,EAAgD,YAAW;AACpE;AAaO,SAASy6C,GAAkBlF,GAAemF,GAAgB1jC,GAAwB;AACvF,SAAOu+B,EAAM,IAAI,CAAC1rC,MAAM;;AACtB,UAAMwN,IAASxN,EAAE,WAAW6wC,IAAS1jC,IAASnN,EAAE,QAC1Cga,IAASha,EAAE,WAAW6wC,IAAS1jC,IAASnN,EAAE;AAChD,WAAO;AAAA,MACL,GAAGA;AAAA,MACH,QAAAwN;AAAA,MACA,QAAAwM;AAAA,MACA,IAAIsxB;AAAA,QACF99B;AAAA,QACAwM;AAAA,QACA8xB,GAAS9rC,CAAC;AAAA,QACV,SAAO7J,IAAA6J,EAAE,SAAF,gBAAA7J,EAAQ,UAAU,WAAW6J,EAAE,KAAK,QAAQ;AAAA,MAAA;AAAA,IACrD;AAAA,EAEJ,CAAC;AACH;AChYO,SAASsrC,GAAW9mB,GAAcuZ,GAAY5pC,GAAmB6pC,GAAwB;AAC9F,QAAMx7B,IAAOrO,MAAS,UAAU,GAAGqwB,CAAI,KAAKuZ,CAAE,WAAW,GAAGvZ,CAAI,KAAKuZ,CAAE;AACvE,SAAOC,MAAU,SAAYx7B,IAAO,GAAGA,CAAI,UAAU,mBAAmBw7B,CAAK,CAAC;AAChF;AAOO,SAAS8S,GAAYx6C,GAA2B;AACrD,SAAOA,EAAG,SAAS,GAAG,IAAI,uCAAuC;AACnE;AAOO,SAASy6C,GAAcz6C,GAAY06C,GAAwC;AAChF,QAAM5S,IAAM0S,GAAYx6C,CAAE;AAC1B,MAAI8nC,EAAK,QAAOA;AAChB,aAAW6S,KAASD,EAAO,KAAIC,MAAU36C,EAAI,QAAO,iBAAiBA,CAAE;AACvE,SAAO;AACT;AAwDO,SAAS46C,GACd3qC,GACAjQ,GACA66C,GACQ;AACR,QAAMC,IAAS,CAAC5sB,GAAiCuZ,MAC/C,CAACvZ,KAAQ,CAACuZ,IACN,SACAuN,GAAW9mB,GAAMuZ,CAAE,MAAMznC,IACvB,YACAg1C,GAAW9mB,GAAMuZ,GAAI,OAAO,MAAMznC,IAChC,UACA,QACJ+6C,IAAQD,EAAOD,EAAS,CAAC,GAAGA,EAAS,CAAC,CAAC,GACvCG,IAAUF,EAAOD,EAAS,CAAC,GAAGA,EAAS,CAAC,CAAC,GACzCI,IAAWF,MAAU,UAAaA,MAAUC,GAC5CE,IAAYH,MAAU,UAAaC,MAAY,UAAaD,MAAUC,GAGtEG,IAAgBJ,MAAU,YAAYF,EAAS,CAAC,IAAIA,EAAS,CAAC,GAC9DO,IAAUH,IACZJ,EAAS,KAAK,CAACt0C,MAAmB,CAAC,CAACA,KAAKA,EAAE,SAAS,IAAI,CAAC,IACzD20C,MAAaC,KAAA,QAAAA,EAAe,SAAS,aACnCA,IACA,QAIAE,IACJD,MAAY,SACR,yDACAH,IACE,wHAAwHG,CAAO,uBAC/H,2HAA2HA,CAAO;AAC1I,SAAO,GAAGnrC,CAAI,aAAajQ,CAAE,uCAAuCq7C,CAAK;AAC3E;AAGA,MAAMC,KAAe,KACfC,KAAa,KACbC,KAAW,IACXC,KAAW;AAkBjB,SAASC,GAAaC,GAAa56B,GAAuC;AACxE,SAAO,EAAE,GAAGy6B,KAAWG,IAAML,IAAc,GAAGG,KAAW16B,IAAMw6B,GAAA;AACjE;AAkDA,SAASK,GAAcp9B,GAAmB42B,GAAwC;;AAChF,QAAMyG,wBAAY,IAAA,GACZh4C,wBAAe,IAAA;AACrB,aAAW0C,KAAKiY;AACd,IAAAq9B,EAAM,IAAIt1C,EAAE,IAAI,CAAC,GACjB1C,EAAS,IAAI0C,EAAE,IAAI,CAAA,CAAE;AAEvB,aAAWmD,KAAK0rC;AACd,KAAAv1C,IAAAgE,EAAS,IAAI6F,EAAE,EAAE,MAAjB,QAAA7J,EAAoB,KAAK6J,EAAE;AAI7B,QAAMoyC,IAAYt9B,EAAM,SAAS;AACjC,MAAIu9B,IAAS,GACT/nB,IAAU;AACd,SAAOA,KAAW+nB,IAASD,KAAW;AACpC,IAAAC,KACA/nB,IAAU;AACV,eAAWztB,KAAKiY,GAAO;AACrB,YAAMw9B,IAAQn4C,EAAS,IAAI0C,EAAE,EAAE,KAAK,CAAA;AACpC,UAAIy1C,EAAM,WAAW,EAAG;AACxB,YAAMhxC,IAAOgxC,EAAM,OAAO,CAACC,GAAK34C,MAAM,KAAK,IAAI24C,IAAMJ,EAAM,IAAIv4C,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC;AAC/E,OAAKu4C,EAAM,IAAIt1C,EAAE,EAAE,KAAK,KAAKyE,MAC3B6wC,EAAM,IAAIt1C,EAAE,IAAIyE,CAAI,GACpBgpB,IAAU;AAAA,IAEd;AAAA,EACF;AACA,MAAIA,GAAS;AAGX,UAAMkoB,IAAa,KAAK,IAAI,GAAG19B,EAAM,SAAS,CAAC;AAC/C,eAAW,CAACxe,GAAI27C,CAAG,KAAKE;AACtB,MAAIF,IAAMO,KAAYL,EAAM,IAAI77C,GAAIk8C,CAAU;AAAA,EAElD;AACA,SAAOL;AACT;AAaA,SAASM,GACP39B,GACA42B,GACuC;;AACvC,QAAMyG,IAAQD,GAAcp9B,GAAO42B,CAAK,GAClCM,IAAQ,IAAI,IAAIl3B,EAAM,IAAI,CAACjY,GAAGwU,MAAM,CAACxU,EAAE,IAAIwU,CAAC,CAAC,CAAC,GAC9CmL,wBAAa,IAAA;AACnB,aAAW,EAAE,MAAAgI,GAAM,IAAAuZ,EAAA,KAAQ2N,GAAO;AAChC,UAAMgH,IAAUP,EAAM,IAAI3tB,CAAI,GACxBmuB,IAAQR,EAAM,IAAIpU,CAAE;AAC1B,QAAI2U,MAAY,UAAaC,MAAU,UAAaD,KAAWC,EAAO;AACtE,UAAMzvC,IAAOsZ,EAAO,IAAIuhB,CAAE;AAC1B,KACE76B,MAAS,UACTwvC,KAAWP,EAAM,IAAIjvC,CAAI,KAAK,MAC7BwvC,MAAYP,EAAM,IAAIjvC,CAAI,MAAM8oC,EAAM,IAAIxnB,CAAI,KAAK,MAAMwnB,EAAM,IAAI9oC,CAAI,KAAK,OAE7EsZ,EAAO,IAAIuhB,GAAIvZ,CAAI;AAAA,EAEvB;AACA,QAAMvnB,IAAW,IAAI,IAAI6X,EAAM,IAAI,CAACjY,MAAM,CAACA,EAAE,IAAI,CAAA,CAAc,CAAC,CAAC;AACjE,aAAW,CAACsK,GAAOqd,CAAI,KAAKhI,UAAiB,IAAIgI,CAAI,gBAAG,KAAKrd;AAC7D,aAAWyrC,KAAY31C,EAAS;AAC9B,IAAA21C,EAAS;AAAA,MACP,CAAC/+C,GAAGC,OACDq+C,EAAM,IAAIr+C,CAAC,KAAK,MAAMq+C,EAAM,IAAIt+C,CAAC,KAAK,OAAOm4C,EAAM,IAAIn4C,CAAC,KAAK,MAAMm4C,EAAM,IAAIl4C,CAAC,KAAK;AAAA,IAAA;AAG1F,QAAM++C,wBAAgB,IAAA;AACtB,MAAIx7B,IAAM;AACV,aAAW7R,KAAQsP,EAAM,OAAO,CAACjY,MAAM,CAAC2f,EAAO,IAAI3f,EAAE,EAAE,CAAC,GAAG;AACzD,UAAMmhB,IAAQ,CAACxY,EAAK,EAAE;AACtB,WAAOwY,EAAM,UAAQ;AACnB,YAAM1nB,IAAK0nB,EAAM,IAAA;AACjB,UAAI1nB,MAAO,OAAW;AACtB,MAAAu8C,EAAU,IAAIv8C,GAAI07C,GAAaG,EAAM,IAAI77C,CAAE,KAAK,GAAG+gB,CAAG,CAAC;AACvD,YAAMzC,IAAS3X,EAAS,IAAI3G,CAAE,KAAK,CAAA;AACnC,UAAIse,EAAO,WAAW,EAAG,CAAAyC;AAAA,UACpB,UAAShG,IAAIuD,EAAO,SAAS,GAAGvD,KAAK,GAAGA,IAAK,CAAA2M,EAAM,KAAKpJ,EAAOvD,CAAC,CAAC;AAAA,IACxE;AAAA,EACF;AACA,SAAOwhC;AACT;AAeA,SAASC,GAAe58C,GAAsD;AAC5E,QAAM0D,IAAI1D,EAAK;AACf,MAAI,GAAC0D,KAAK,CAAC,OAAO,SAASA,EAAE,CAAC,KAAK,CAAC,OAAO,SAASA,EAAE,CAAC;AACvD,WAAO,EAAE,GAAGA,EAAE,GAAG,GAAGA,EAAE,EAAA;AACxB;AAGO,SAASm5C,GAAelQ,GAAwC;AACrE,QAAMjzB,IAAIizB;AACV,MAAIjzB,EAAE,UAAU,UAAaA,EAAE,UAAU;AACvC,UAAM,IAAI,MAAM,uCAAuC;AAEzD,QAAM,EAAE,OAAOojC,GAAI,GAAGruC,MAASk+B;AAC/B,SAAO,EAAE,GAAGl+B,GAAM,OAAOiL,EAAE,SAASA,EAAE,SAAS,GAAC;AAClD;AAcO,SAASqjC,GAAepQ,GAAgE;AAC7F,QAAMiL,IAAKiF,GAAelQ,CAAK,GACzBJ,IAAOqL,EAAG;AAChB,MAAIpC,IAAoBmC,GAAeC,CAAE;AAKzC,QAAMoF,IAAoB,CAAA,GACpBC,wBAAa,IAAA,GACbC,wBAAiB,IAAA,GACjBC,wBAAW,IAAA;AACjB,aAAW,CAAC5G,GAAKhqB,CAAI,KAAK,OAAO,QAAQwrB,GAAgBH,CAAE,CAAC,GAAG;AAC7D,QAAI,aAAarrB,EAAM;AACvB,QAAIvf,IAAOupC;AACX,QAAIhqB,EAAK,SAASA,EAAK,KAAK,SAAS,GAAG;AAEtC,MAAAywB,EAAU,KAAK9H,GAAaqB,GAAKhqB,EAAK,KAAK,CAAC,GAAG,EAAI,CAAC;AACpD,iBAAWziB,KAAKyiB,EAAK;AACnB,QAAA4wB,EAAK,IAAIrzC,CAAC,GACVkzC,EAAU,KAAK9H,GAAaprC,EAAE,MAAMA,EAAE,IAAI,IAAOA,EAAE,KAAK,CAAC;AAE3D,iBAAW1J,KAAMmsB,EAAK,KAAM,CAAA0wB,EAAO,IAAI78C,GAAIm2C,CAAG;AAC9C;AAAA,IACF;AACA,eAAWn2C,KAAMmsB,EAAK,MAAM;AAC1B,UAAIA,EAAK,WAAW,UAAU;AAC5B,cAAMziB,IAAI0rC,EAAM;AAAA,UACd,CAAC1vB,MAAMA,EAAE,SAAS9Y,KAAQ8Y,EAAE,OAAO1lB,MAAO0lB,EAAE,QAAQ,eAAe;AAAA,QAAA;AAErE,QAAIhc,KAAGqzC,EAAK,IAAIrzC,CAAC;AAAA,MACnB;AACA,MAAAkzC,EAAU,KAAK9H,GAAaloC,GAAM5M,GAAI4M,MAASupC,CAAG,CAAC,GACnD0G,EAAO,IAAI78C,GAAIm2C,CAAG,GAClBvpC,IAAO5M;AAAA,IACT;AACA,IAAImsB,EAAK,WAAW,YAAU2wB,EAAW,IAAI3G,CAAG;AAAA,EAClD;AAEA,QAAM6G,IAAa,IAAI,IAAI7Q,EAAK,OAAOoI,EAAa,EAAE,IAAI,CAAChuC,MAAMA,EAAE,EAAE,CAAC;AACtE,aAAWmD,KAAK0rC,EAAO,CAAI4H,EAAW,IAAItzC,EAAE,IAAI,KAAKguC,GAAWhuC,CAAC,KAAGqzC,EAAK,IAAIrzC,CAAC;AAC9E,EAAIqzC,EAAK,OAAO,MAAG3H,IAAQA,EAAM,OAAO,CAAC1rC,MAAM,CAACqzC,EAAK,IAAIrzC,CAAC,CAAC;AAC3D,QAAM6yC,IAAYJ,GAAiBhQ,GAAM;AAAA,IACvC,GAAGiJ;AAAA,IACH,GAAGwH,EAAU,IAAI,CAAClzC,OAAO,EAAE,MAAMA,EAAE,QAAQ,IAAIA,EAAE,OAAA,EAAS;AAAA,EAAA,CAC3D,GACK0V,IAAoB+sB,EAAK,IAAI,CAACvsC,MAAS;AAC3C,UAAMq9C,IAAap8C,GAAcjB,EAAK,KAAK,GAAG;AAC9C,WAAO;AAAA,MACL,IAAIA,EAAK;AAAA,MACT,MAAMq9C,IAAa,YAAY;AAAA,MAC/B,UAAUT,GAAe58C,CAAI,KAAK28C,EAAU,IAAI38C,EAAK,EAAE,KAAK87C,GAAa,GAAG,CAAC;AAAA,MAC7E,MAAM;AAAA,QACJ,MAAA97C;AAAA,QACA,YAAAq9C;AAAA,QACA,GAAIJ,EAAO,IAAIj9C,EAAK,EAAE,IAAI,EAAE,QAAQi9C,EAAO,IAAIj9C,EAAK,EAAE,EAAA,IAAM,CAAA;AAAA,QAC5D,GAAIk9C,EAAW,IAAIl9C,EAAK,EAAE,IAAI,EAAE,YAAY,OAAS,CAAA;AAAA,MAAC;AAAA,IACxD;AAAA,EAEJ,CAAC,GAIKs9C,IAAQ,IAAI,IAAI/Q,EAAK,OAAOxrC,EAAQ,EAAE,IAAI,CAAC4F,MAAMA,EAAE,EAAE,CAAC,GAEtD42C,IAAoB/H,EAAM,IAAI,CAAClG,MAAU;AAC7C,UAAMxlC,IACJwlC,EAAM,SAAS,WAAWA,EAAM,UAAU,UAAagO,EAAM,IAAIhO,EAAM,IAAI,IACvE,EAAE,MAAMA,EAAM,MAAM,IAAIA,EAAM,IAAI,OAAOxuC,GAAA,IACzCs8C,EAAW,IAAI9N,EAAM,IAAI,KAAKA,EAAM,UAAU,UAAaA,EAAM,SAAS,UACxE,EAAE,GAAGA,GAAO,OAAO/wC,OACnB+wC,GAkBFrxC,IAAO6L,EAAE,QAAQ;AACvB,WAAO;AAAA,MACL,IAAIsrC,GAAWtrC,EAAE,MAAMA,EAAE,IAAI7L,GAAM6L,EAAE,KAAK;AAAA,MAC1C,QAAQA,EAAE;AAAA,MACV,QAAQA,EAAE;AAAA,MACV,cAAcA,EAAE,UAAU,SAAYrL,GAAoBR,CAAI,IAAI,SAAS6L,EAAE,KAAK;AAAA,MAClF,UAAU;AAAA,MACV,MAAM,EAAE,MAAA7L,GAAM,GAAI6L,EAAE,UAAU,SAAY,CAAA,IAAK,EAAE,OAAOA,EAAE,QAAM;AAAA;AAAA;AAAA;AAAA;AAAA,MAKhE,GAAG9L,GAAYC,GAAM,MAAS;AAAA,IAAA;AAAA,EAElC,CAAC;AAED,SAAO,EAAE,OAAAuhB,GAAO,OAAO,CAAC,GAAG+9B,GAAW,GAAGP,CAAS,EAAA;AACpD;AA2BO,SAASQ,GAAch+B,GAAmBg2B,GAA2B;AAK1E,QAAM52B,IAAoBY,EAAM,IAAI,CAACtL,OAAO,EAAE,GAAGA,EAAE,KAAK,MAAM,IAAIA,EAAE,KAAK,GACnEyoC,IAAYJ;AAAA,IAChB39B;AAAA,IACA42B,EAAM,IAAI,CAAC1rC,OAAO,EAAE,MAAMA,EAAE,QAAQ,IAAIA,EAAE,SAAS;AAAA,EAAA;AAErD,SAAO0V,EAAM,IAAI,CAACtL,OAAO,EAAE,GAAGA,GAAG,UAAUyoC,EAAU,IAAIzoC,EAAE,EAAE,KAAK4nC,GAAa,GAAG,CAAC,IAAI;AACzF;AAmBO,SAAS2B,GACdC,GACAl+B,GACAg2B,GACc;;AAEd,QAAM3yB,IAAWg6B,GAAea,CAAa,GACvCC,MAAe19C,IAAA4iB,EAAS,aAAT,gBAAA5iB,EAAmB,kBAAiB,IACnD29C,IAAW,IAAI,IAAsBp+B,EAAM,IAAI,CAACtL,MAAM,CAACA,EAAE,IAAIA,CAAC,CAAC,CAAC,GAehE2pC,IAAe,CAAC79C,MAA6B;;AACjD,QAAI,CAAC29C,EAAc,QAAO39C;AAC1B,UAAM0D,KAAIzD,IAAA29C,EAAS,IAAI59C,EAAK,EAAE,MAApB,gBAAAC,EAAuB;AACjC,WAAI,CAACyD,KAAK,CAAC,OAAO,SAASA,EAAE,CAAC,KAAK,CAAC,OAAO,SAASA,EAAE,CAAC,IAAU1D,IAC1D,EAAE,GAAGA,GAAM,UAAU,EAAE,GAAG,KAAK,MAAM0D,EAAE,CAAC,GAAG,GAAG,KAAK,MAAMA,EAAE,CAAC,IAAE;AAAA,EACvE,GAGMo6C,wBAAe,IAAA;AACrB,aAAWn3C,KAAKkc,EAAS,SAAgB,IAAIlc,EAAE,IAAIA,CAAC;AACpD,aAAWuN,KAAKsL,EAAO,EAAI/L,IAAAS,EAAE,SAAF,QAAAT,EAAQ,QAAMqqC,EAAS,IAAI5pC,EAAE,IAAIA,EAAE,KAAK,IAAI;AAIvE,QAAM6pC,IAAU1H,GAAW72B,GAAOg2B,CAAK,GACjCwI,IAAgBjG,GAAgBl1B,CAAQ,GACxCo7B,IAAe,IAAI,IAAsBp7B,EAAS,MAAM,IAAI,CAAClc,MAAM,CAACA,EAAE,IAAIA,CAAC,CAAC,CAAC,GAC7Eu3C,wBAAkB,IAAA;AACxB,aAAWp0C,KAAK0rC,EAAO,CAAII,GAAS9rC,CAAC,MAAM,aAAWo0C,EAAY,IAAIp0C,EAAE,MAAM;AAC9E,QAAMq0C,IAAW,CAACn+C,MAA6B;AAC7C,QAAI,CAAC20C,GAAc30C,CAAI,EAAG,QAAOA;AACjC,UAAM0kB,IAAQq5B,EAAQ,IAAI/9C,EAAK,EAAE,KAAK,CAAA,GAChCo+C,IAAOH,EAAa,IAAIj+C,EAAK,EAAE,GAC/BusB,IAAOyxB,EAAch+C,EAAK,EAAE;AAClC,QAAI+gC;AACJ,IAAIrc,EAAM,SAAS,IAAGqc,IAAO,EAAE,OAAOrc,EAAA,IAC7B6H,KAAQ,aAAaA,KAAQA,EAAK,QAAQ,WAAW,sBAC5DwU,IAAOqd,KAAA,QAAAA,EAAM,QAAQ,UAAUA,EAAK,OAAO,EAAE,OAAOA,EAAK,KAAK,KAAA,IAAS,OAC9D7xB,KAAQ,aAAaA,IAAMwU,IAAO,OACpCmd,EAAY,IAAIl+C,EAAK,EAAE,KAAMo+C,KAAA,QAAAA,EAAM,QAAQ,UAAUA,EAAK,OAAOrd,IAAO,EAAE,OAAO,CAAA,EAAC,IACtFA,IAAO;AACZ,UAAMjxB,IAAI9P,EAAK,QAAQ,CAAA;AACvB,WAAI+gC,MAAS,OACL,UAAUjxB,IACTgnC,GAAU92C,CAAI,IADMA,IAItB,EAAE,GAAGA,GAAM,MAAM,EAAE,GAAG8P,GAAG,MAAMixB,EAAK,QAAM;AAAA,EACnD,GACMsd,IAAU,CAAC13C,MAA0Bk3C,EAAaM,EAASx3C,CAAC,CAAC,GAE7D23C,IAAwB,CAAA,GACxBp6C,wBAAW,IAAA;AACjB,aAAWyC,KAAKkc,EAAS,OAAO;AAC9B,UAAM3M,IAAU4nC,EAAS,IAAIn3C,EAAE,EAAE;AACjC,IAAIuP,KAAWsJ,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAOvN,EAAE,EAAE,MAC5C23C,EAAU,KAAKD,EAAQnoC,CAAO,CAAC,GAC/BhS,EAAK,IAAIyC,EAAE,EAAE;AAAA,EAEjB;AACA,aAAWuN,KAAKsL,GAAO;AACrB,QAAItb,EAAK,IAAIgQ,EAAE,EAAE,EAAG;AACpB,UAAMvN,IAAIm3C,EAAS,IAAI5pC,EAAE,EAAE;AAC3B,IAAIvN,KAAG23C,EAAU,KAAKD,EAAQ13C,CAAC,CAAC;AAAA,EAClC;AASA,QAAM43C,wBAAc,IAAA;AACpB,aAAW75B,KAASq5B,EAAQ,qBAAqB39C,KAAMskB,EAAO,CAAA65B,EAAQ,IAAIn+C,CAAE;AAC5E,QAAMg9C,IAAa,IAAI,IAAI59B,EAAM,OAAO,CAACtL;;AAAM,WAAAygC,IAAc10C,IAAAiU,EAAE,SAAF,gBAAAjU,EAAQ,IAAI;AAAA,GAAC,EAAE,IAAI,CAACiU,MAAMA,EAAE,EAAE,CAAC,GACtFsqC,IAAyBhJ,EAC5B,OAAO,CAAC1rC,MAAM8rC,GAAS9rC,CAAC,MAAM,UAAU,CAACy0C,EAAQ,IAAIz0C,EAAE,MAAM,KAAK,CAACy0C,EAAQ,IAAIz0C,EAAE,MAAM,CAAC,EACxF,IAAI,CAACA,MAAgB;;AACpB,UAAMg+B,IACJ,SAAO7nC,IAAA6J,EAAE,SAAF,gBAAA7J,EAAQ,UAAU,WACrB6J,EAAE,KAAK,QACPszC,EAAW,IAAItzC,EAAE,MAAM,KAAK8rC,GAAS9rC,CAAC,MAAM,YAC1CvL,KACA;AACR,WAAO;AAAA,MACL,MAAMuL,EAAE;AAAA,MACR,IAAIA,EAAE;AAAA,MACN,GAAI8rC,GAAS9rC,CAAC,MAAM,UAAU,EAAE,MAAM,QAAA,IAAqB,CAAA;AAAA,MAC3D,GAAIg+B,MAAU,SAAY,CAAA,IAAK,EAAE,OAAAA,EAAA;AAAA,IAAM;AAAA,EAE3C,CAAC,GAGG2W,IAAwB,CAAA;AAC9B,aAAW,CAAClI,GAAK7xB,CAAK,KAAKq5B;AACzB,IAAIr5B,EAAM,SAAS,KAAG+5B,EAAU,KAAK,EAAE,MAAMlI,GAAK,IAAI7xB,EAAM,CAAC,GAAG,OAAOlmB,IAAoB;AAI7F,QAAMkgD,IAAY,CAAC,GAAGF,GAAY,GAAGC,GAAW,GAAGrI,GAAwB52B,GAAOg2B,CAAK,CAAC;AAExF,SAAOrD,GAAsB,EAAE,GAAGtvB,GAAU,OAAOy7B,GAAW,OAAOI,GAAW;AAClF;AAuBO,SAASC,GAAe/G,GAA8C;;AAC3E,QAAMp2C,KAAIvB,IAAA23C,EAAG,aAAH,gBAAA33C,EAAa;AACvB,MAAI,GAACuB,KAAK,CAAC,OAAO,SAASA,EAAE,CAAC,KAAK,CAAC,OAAO,SAASA,EAAE,CAAC,KAAK,CAAC,OAAO,SAASA,EAAE,IAAI;AAGnF,WAAO,EAAE,GAAGA,EAAE,GAAG,GAAGA,EAAE,GAAG,MAAMA,EAAE,KAAA;AACnC;AAoCO,SAASo9C,GAAahH,GAAkBiH,GAAkC;;AAI/E,MADI,IADiB5+C,IAAA23C,EAAG,aAAH,gBAAA33C,EAAa,kBAAiB,OAE/C,CAAC,OAAO,SAAS4+C,EAAG,CAAC,KAAK,CAAC,OAAO,SAASA,EAAG,CAAC,KAAK,CAAC,OAAO,SAASA,EAAG,IAAI,EAAG,QAAOjH;AAC1F,QAAMxsC,IAAuB;AAAA,IAC3B,GAAG,KAAK,MAAMyzC,EAAG,CAAC;AAAA,IAClB,GAAG,KAAK,MAAMA,EAAG,CAAC;AAAA,IAClB,MAAM,KAAK,MAAMA,EAAG,OAAO,GAAI,IAAI;AAAA,EAAA,GAE/B3oC,IAAUyoC,GAAe/G,CAAE;AACjC,MAAI1hC,KAAWA,EAAQ,MAAM9K,EAAK,KAAK8K,EAAQ,MAAM9K,EAAK,KAAK8K,EAAQ,SAAS9K,EAAK;AACnF,WAAOwsC;AAIT,QAAM5qC,IACJ,OAAO4qC,EAAG,YAAa,YAAYA,EAAG,aAAa,QAAQ,CAAC,MAAM,QAAQA,EAAG,QAAQ,IACjFA,EAAG,WACH;AACN,SAAO,EAAE,GAAGA,GAAI,UAAU,EAAE,GAAG5qC,GAAM,UAAU5B,IAAK;AACtD;AAYO,SAAS0zC,GAAa3oC,GAAuB;AAKlD,SAJaA,EACV,YAAA,EACA,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE,KACV;AACjB;AAUO,SAAS4oC,GAAcv/B,GAAmBg2B,GAAqC;AACpF,QAAMwJ,IAAc,IAAI,IAAIxJ,EAAM,IAAI,CAAC1rC,MAAMA,EAAE,MAAM,CAAC;AACtD,SAAO0V,EAAM,KAAK,CAACtL,MAAM,CAAC8qC,EAAY,IAAI9qC,EAAE,EAAE,CAAC;AACjD;AASO,SAAS+qC,GAAcz/B,GAAmBg2B,GAAqC;AACpF,QAAM0J,IAAc,IAAI,IAAI1J,EAAM,IAAI,CAAC1rC,MAAMA,EAAE,MAAM,CAAC;AACtD,WAASqR,IAAIqE,EAAM,SAAS,GAAGrE,KAAK,GAAGA;AACrC,QAAI,CAAC+jC,EAAY,IAAI1/B,EAAMrE,CAAC,EAAE,EAAE,EAAG,QAAOqE,EAAMrE,CAAC;AAGrD;AAGO,SAASgkC,GAAcn7C,GAAoB+2B,IAAS,QAAgB;AACzE,QAAM7D,IAAM,IAAI,IAAIlzB,CAAQ;AAC5B,WAASmX,IAAI,GAAGA,IAAI,KAAMA,KAAK;AAC7B,UAAM/a,IAAK,GAAG26B,CAAM,IAAI5f,CAAC;AACzB,QAAI,CAAC+b,EAAI,IAAI92B,CAAE,EAAG,QAAOA;AAAA,EAC3B;AACA,SAAO,GAAG26B,CAAM,IAAI,OAAO,aAAa,MAAM,GAAG,CAAC,CAAC;AACrD;AAiCO,SAASqkB,GAAWp/C,GAAwB;AAEjD,SAAO,KAAK,UAAU82C,GAAU92C,CAAI,GAAG,MAAM,CAAC;AAChD;ACr0BA,MAAMq/C,KAAY,GAEZC,KAAa;AAEnB,SAASC,GAAc/9C,GAA0C;AAC/D,SAAO,OAAOA,KAAM,YAAYA,MAAM,QAAQ,CAAC,MAAM,QAAQA,CAAC;AAChE;AAOO,SAASg+C,GAAqBC,GAA+C;AAClF,MAAI,CAAC,MAAM,QAAQA,CAAM,EAAG;AAC5B,QAAMz6B,IAA2B,CAAA,GAC3B9gB,wBAAW,IAAA,GACXw4B,IAAM,CAACxX,MAAsB;AACjC,IAAIhhB,EAAK,IAAIghB,EAAE,GAAG,MAClBhhB,EAAK,IAAIghB,EAAE,GAAG,GACdF,EAAO,KAAKE,CAAC;AAAA,EACf;AACA,aAAWA,KAAKu6B,GAAQ;AACtB,QAAI,CAACF,GAAcr6B,CAAC,KAAK,OAAOA,EAAE,OAAQ,YAAYA,EAAE,QAAQ,GAAI;AACpE,UAAM/O,IAAQ,OAAO+O,EAAE,SAAU,YAAYA,EAAE,UAAU,KAAKA,EAAE,QAAQ;AAKxE,QAJAwX,EAAI,EAAE,KAAKxX,EAAE,KAAK,GAAI/O,IAAQ,EAAE,OAAAA,MAAU,CAAA,GAAK,MAAM,IAAM,GAIvD+O,EAAE,SAAS,WAAW,MAAM,QAAQA,EAAE,KAAK;AAC7C,iBAAWmY,KAAMnY,EAAE,OAAO;AACxB,YAAI,CAACq6B,GAAcliB,CAAE,KAAK,OAAOA,EAAG,OAAQ,YAAYA,EAAG,QAAQ,GAAI;AACvE,cAAMqiB,IAAK,OAAOriB,EAAG,SAAU,YAAYA,EAAG,UAAU,KAAKA,EAAG,QAAQ;AACxE,QAAAX,EAAI,EAAE,KAAK,GAAGxX,EAAE,GAAG,MAAMmY,EAAG,GAAG,IAAI,GAAIqiB,IAAK,EAAE,OAAOA,EAAA,IAAO,IAAK,MAAM,IAAM;AAAA,MAC/E;AAAA,EAEJ;AACA,SAAO16B,EAAO,SAAS,IAAIA,IAAS;AACtC;AAMO,SAAS26B,GAAmBF,GAAiBzhC,GAA2C;;AAC7F,MAAI,CAAC,MAAM,QAAQyhC,CAAM,EAAG;AAC5B,QAAMv6B,IAAIu6B,EAAO,KAAK,CAAC,MAAMF,GAAc,CAAC,KAAK,EAAE,QAAQvhC,CAAG;AAC9D,MAAI,GAACuhC,GAAcr6B,CAAC,KAAK,CAAC,MAAM,QAAQA,EAAE,KAAK;AAC/C,YAAOjlB,IAAAu/C,GAAqB,CAAC,EAAE,KAAAxhC,GAAK,MAAM,SAAS,OAAOkH,EAAE,MAAA,CAAO,CAAC,MAA7D,gBAAAjlB,EACH,OAAO,CAAC6lB,MAAMA,EAAE,QAAQ9H,GACzB,IAAI,CAAC8H,OAAO,EAAE,GAAGA,GAAG,KAAKA,EAAE,IAAI,MAAM9H,EAAI,SAAS,CAAC;AACxD;AAQO,SAAS4hC,GAAkBt1C,GAA8C;AAC9E,MAAI,CAACi1C,GAAcj1C,CAAK,EAAG;AAC3B,QAAM0a,IAA2B,CAAA,GAC3BpU,IAAO,CAACqX,GAA8B8S,GAAgB1V,MAAkB;AAC5E,eAAW,CAAC1F,GAAGne,CAAC,KAAK,OAAO,QAAQymB,CAAG,GAAG;AACxC,UAAIjD,EAAO,UAAUs6B,GAAY;AACjC,YAAMthC,IAAM+c,IAAS,GAAGA,CAAM,IAAIpb,CAAC,KAAKA;AACxC,MAAAqF,EAAO,KAAK,EAAE,KAAAhH,GAAK,MAAM,IAAM,GAC3BuhC,GAAc/9C,CAAC,KAAK6jB,IAAQg6B,MAAWzuC,EAAKpP,GAAGwc,GAAKqH,IAAQ,CAAC;AAAA,IACnE;AAAA,EACF;AACA,SAAAzU,EAAKtG,GAAO,IAAI,CAAC,GACV0a,EAAO,SAAS,IAAIA,IAAS;AACtC;AAGO,SAAS66B,GAAYv1C,GAAgB6U,GAAuB;AACjE,MAAI1O,IAAenG;AACnB,aAAWsW,KAAOzB,EAAK,MAAM,GAAG,GAAG;AACjC,QAAI,CAACogC,GAAc9uC,CAAG,KAAK,EAAEmQ,KAAOnQ,GAAM;AAC1C,IAAAA,IAAMA,EAAImQ,CAAG;AAAA,EACf;AACA,SAAOnQ;AACT;AAkBO,SAASqvC,GACd99C,GACA+9C,GACAC,GACmE;AACnE,QAAM9H,IAAWsH,GAAqBx9C,KAAA,gBAAAA,EAAQ,MAAM,GAC9Ci+C,IAAcL,GAAkBG,CAAK,GACrCG,IAAaD,KAAeL,GAAkBI,CAAS;AAC7D,MAAIE,GAAY;AACd,UAAM1qB,IAAQ,IAAI,KAAK0iB,KAAY,CAAA,GAAI,IAAI,CAACjjC,MAAM,CAACA,EAAE,KAAKA,CAAC,CAAC,CAAC,GACvDkrC,IAAO,IAAI,IAAID,EAAW,IAAI,CAACh7B,MAAMA,EAAE,GAAG,CAAC,GAC3CjV,IAA2BiwC,EAAW,IAAI,CAACh7B,MAAM;AACrD,YAAMjQ,IAAIugB,EAAM,IAAItQ,EAAE,GAAG;AACzB,aAAOjQ,KAAA,QAAAA,EAAG,QAAQ,EAAE,GAAGiQ,GAAG,OAAOjQ,EAAE,UAAUiQ;AAAA,IAC/C,CAAC;AACD,eAAWjQ,KAAKijC,KAAY,CAAA,EAAI,CAAKiI,EAAK,IAAIlrC,EAAE,GAAG,OAAU,KAAK,EAAE,GAAGA,GAAG,cAAc,IAAM;AAC9F,WAAO,EAAE,QAAQhF,GAAQ,MAAMgwC,IAAc,UAAU,YAAA;AAAA,EACzD;AACA,MAAI/H,EAAU,QAAO,EAAE,QAAQA,GAAU,MAAM,WAAA;AAC/C,QAAMkI,IAAaR,GAAkB59C,KAAA,gBAAAA,EAAQ,MAAM;AACnD,MAAIo+C,EAAY,QAAO,EAAE,QAAQA,GAAY,MAAM,SAAA;AAErD;AClEO,SAASC,GAAYC,GAAgB9K,GAA4B;AACtE,QAAM+K,wBAAc,IAAA;AACpB,aAAWz2C,KAAK0rC,GAAO;AACrB,UAAMgL,IAAMD,EAAQ,IAAIz2C,EAAE,MAAM,KAAK,CAAA;AACrC,IAAA02C,EAAI,KAAK12C,EAAE,MAAM,GACjBy2C,EAAQ,IAAIz2C,EAAE,QAAQ02C,CAAG;AAAA,EAC3B;AACA,QAAMC,wBAAgB,IAAA,GAChB34B,IAAQ,CAACw4B,CAAM;AACrB,SAAOx4B,EAAM,UAAQ;AACnB,UAAM1nB,IAAK0nB,EAAM,IAAA;AACjB,eAAWpkB,KAAK68C,EAAQ,IAAIngD,CAAE,KAAK,CAAA;AACjC,MAAKqgD,EAAU,IAAI/8C,CAAC,MAClB+8C,EAAU,IAAI/8C,CAAC,GACfokB,EAAM,KAAKpkB,CAAC;AAAA,EAGlB;AACA,SAAO+8C;AACT;AAQA,SAASC,GACPh8C,GACA8a,GACAmhC,IAA2B,CAAA,GAM3B;;AACA,QAAM/hC,IAAgC,CAAA;AACtC,MAAIgiC,IAAa,IACbC;AACJ,aAAW3sC,KAAKsL,GAAO;AACrB,QAAI,CAAC9a,EAAI,IAAIwP,EAAE,EAAE,EAAG;AACpB,UAAMlU,IAAOkU,EAAE,KAAK;AAGpB,QAAIlU,EAAK,KAAK,QAAQL,GAAU;AAChC,UAAMmhD,MAAY7gD,IAAAiC,GAAgBlC,EAAK,KAAK,KAAKA,EAAK,KAAK,MAAM,MAA/C,gBAAAC,EAAkD,WAAU,WAGxE8gD,KAAattC,IAAAktC,EAAO,gBAAP,gBAAAltC,EAAqBzT,EAAK,KACvCghD,KAAkB9nC,IAAAynC,EAAO,qBAAP,gBAAAznC,EAA0BlZ,EAAK;AACvD,QAAIA,EAAK,KAAK,YAAY,IAAM;AAI9B,MAAA4gD,IAAa;AACb,YAAMK,IAAQnB;AAAA,SACZ3mC,IAAAwnC,EAAO,eAAP,gBAAAxnC,EAAA,KAAAwnC,GAAoB3gD,EAAK,KAAK,KAAKA,EAAK,KAAK;AAAA,QAC7C+gD;AAAA,QACAC;AAAA,MAAA;AAIF,UAFAH,UAAeI,IAEXA,MAAUA,EAAM,SAAS,WAAWA,EAAM,SAAS,cAAc;AACnE,QAAAriC,EAAM,KAAK,EAAE,IAAI5e,EAAK,IAAI,OAAOA,EAAK,IAAI,SAASihD,EAAM,QAAQ,aAAaA,EAAM,MAAM;AAC1F;AAAA,MACF;AAAA,IACF;AACA,IAAIH,MAIFF,IAAa;AAiBf,UAAMM,IAAkBJ,KAAa9gD,EAAK,KAAK,QAAQhB,IACjDk5C,IAA8CgJ,IAChD5U,GAAeH,IAAY7oB,IAAAtjB,EAAK,SAAL,gBAAAsjB,EAAW,MAAM,CAAC,EAAE,IAAI,CAAC5f,OAAO;AAAA,MACzD,KAAKA,EAAE;AAAA,MACP,OAAOA,EAAE;AAAA,IAAA,EACT,MACDy9C,IAAAj/C,GAAgBlC,EAAK,KAAK,KAAKA,EAAK,KAAK,MAAM,MAA/C,gBAAAmhD,EAAkD,WAAU,CAAA,GAC3D7pC,IAA+B,EAAE,IAAItX,EAAK,IAAI,OAAOA,EAAK,GAAA;AAIhE,QAAIk4C,EAAS,SAAS,GAAG;AACvB,MAAAt5B,EAAM,KAAK,EAAE,GAAGtH,GAAQ,SAAS4gC,GAAU;AAC3C;AAAA,IACF;AAMA,QAAI4I,GAAW;AACb,YAAMM,IAAOtB,GAAmB,QAAWiB,GAAYC,CAAe;AACtE,MAAII,KAAQ,CAACF,MAAiBL,UAAeO,KAC7CxiC,EAAM,KAAKwiC,IAAO,EAAE,GAAG9pC,GAAQ,SAAS8pC,EAAK,QAAQ,aAAaA,EAAK,KAAA,IAAS9pC,CAAM;AACtF;AAAA,IACF;AACA,QAAIrW,GAAcjB,EAAK,KAAK,GAAG,GAAG;AAGhC,YAAMohD,IAAOtB,GAAmB,QAAWiB,GAAYC,CAAe;AACtE,MAAApiC,EAAM,KAAKwiC,IAAO,EAAE,GAAG9pC,GAAQ,SAAS8pC,EAAK,QAAQ,aAAaA,EAAK,KAAA,IAAS9pC,CAAM;AACtF;AAAA,IACF;AAIA,UAAMtV,KAASq/C,IAAAV,EAAO,cAAP,gBAAAU,EAAA,KAAAV,GAAmB3gD,EAAK,KAAK,KAAKA,EAAK,KAAK,SACrDihD,IAAQnB,GAAmB99C,GAAQ++C,GAAYC,CAAe,GAG9D3iC,IAAOre,EAAK,KAAK,IAAI,WAAW,KAAK,EAAE,SAAS,GAAA,IAAkB,CAAA;AACxE,IAAIihD,IACFriC,EAAM,KAAK,EAAE,GAAGtH,GAAQ,SAAS2pC,EAAM,QAAQ,aAAaA,EAAM,MAAM,GAAG5iC,EAAA,CAAM,IAEjFO,EAAM,KAAK5c,IAAS,EAAE,GAAGsV,GAAQ,WAAW,IAAM,GAAG+G,EAAA,IAAS,EAAE,GAAG/G,GAAQ,GAAG+G,GAAM;AAAA,EAExF;AACA,SAAO;AAAA,IACL,OAAAO;AAAA,IACA,YAAAgiC;AAAA,IACA,GAAIC,IAAa,EAAE,cAAcA,EAAW,QAAQ,kBAAkBA,EAAW,SAAS,CAAA;AAAA,EAAC;AAE/F;AAQO,SAASS,GACdrkB,GACAskB,GACuB;AACvB,QAAM3iC,IAA8C,CAAA;AACpD,aAAW,CAACxe,GAAIq/C,CAAM,KAAK,OAAO,QAAQ8B,CAAW,EAAG,CAAA3iC,EAAMxe,CAAE,IAAI,EAAE,QAAAq/C,EAAA;AACtE,SAAO+B,GAAwBvkB,GAAO,EAAE,OAAAre,GAAO;AACjD;AAOO,SAAS4iC,GACdvkB,GACA54B,GACuB;AACvB,MAAI6kB,GAAc+T,CAAK,MAAM,MAAM;AACjC,UAAM7X,IAAOnF,GAAkBgd,GAAOhf,GAAkB,QAAW5Z,CAAK,CAAC,GACnEuc,IAAMwE,EAAK,WAAW,IAAIA,EAAK,CAAC,IAAI;AAC1C,YAAOxE,KAAA,gBAAAA,EAAK,YAAW,cAAc,MAAM,QAAQA,EAAI,KAAK,IAAIA,EAAI,QAAQ;AAAA,EAC9E;AACA,SAAO,MAAM,QAAQqc,CAAK,IAAIA,IAAQ;AACxC;AAGO,MAAMwkB,KAA0B;AAQhC,SAASC,GACdzkB,GACA0P,GACmE;AACnE,SAAO;AAAA,IACL,OAAAA;AAAA,IACA,MAAM,EAAE,OAAO1P,EAAM,MAAM,GAAGwkB,EAAuB,GAAG,WAAWxkB,EAAM,OAAA;AAAA,EAAO;AAEpF;AAGO,SAAS0kB,GAAkBC,GAA0D;;AAC1F,QAAM3kB,KAAQh9B,IAAA2hD,KAAA,gBAAAA,EAAM,SAAN,gBAAA3hD,EAAY;AAC1B,SAAO,MAAM,QAAQg9B,CAAK,KAAKA,EAAM,SAAS,IAAIA,IAAQ;AAC5D;AAWA,SAAS4kB,GACPn9C,GACAo9C,GACAtiC,GACAg2B,GACAmL,IAA2B,IAO3B;AACA,QAAMoB,IAAazL,GAAe92B,GAAOg2B,CAAK,GACxC9nC,wBAAc,IAAA;AACpB,aAAWtN,KAAMsE,GAAK;AACpB,QAAItE,MAAO0hD,EAAS;AACpB,UAAM3K,IAAQ4K,EAAW3hD,CAAE;AAC3B,IAAI+2C,MAAU,UAAaA,MAAU2K,KACrCp0C,EAAQ,IAAItN,CAAE;AAAA,EAChB;AACA,QAAM4hD,IAAYtB,GAAmBhzC,GAAS8R,GAAOmhC,CAAM,GACrDsB,IAAS5L,GAAW72B,GAAOg2B,CAAK,GAChC0M,IAAkB,CAAA;AA2BxB,SAAO;AAAA,IACL,OA3BYF,EAAU,MAAM,IAAI,CAACj1B,MAA6B;;AAC9D,YAAMhhB,IAAOk2C,EAAO,IAAIl1B,EAAG,EAAE;AAC7B,UAAI,CAAChhB,KAAQA,EAAK,WAAW,EAAG,QAAOghB;AACvC,YAAM7c,IAAOnE,EAAKA,EAAK,SAAS,CAAC,GAC3Bo2C,KAAWliD,IAAAuf,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAOhE,CAAI,MAA/B,gBAAAjQ,EAAkC,KAAK,MAClDshD,IAAcZ,EAAO,eAAe,CAAA,GACpCM,IAAQkB,IACVrC;AAAA,SACErsC,IAAAktC,EAAO,cAAP,gBAAAltC,EAAA,KAAAktC,GAAmBwB,EAAS,KAAK,KAAKA,EAAS,KAAK;AAAA,QACpDZ,EAAYrxC,CAAI;AAAA,SAChBgJ,IAAAynC,EAAO,qBAAP,gBAAAznC,EAA0BhJ;AAAA,MAAI,IAEhC;AACJ,MAAKgyC,EAAM,SAAShyC,CAAI,KAAGgyC,EAAM,KAAKhyC,CAAI;AAC1C,YAAM8U,MAAUi8B,KAAA,gBAAAA,EAAO,WAAU,CAAA,GAAI,IAAI,CAAC/7B,OAAO;AAAA,QAC/C,KAAK,WAAWA,EAAE,GAAG;AAAA,QACrB,MAAM;AAAA,QACN,GAAIA,EAAE,eAAe,EAAE,cAAc,GAAA,IAAkB,CAAA;AAAA,MAAC,EACxD;AACF,aAAO;AAAA,QACL,IAAI6H,EAAG;AAAA,QACP,OAAOA,EAAG;AAAA,QACV,SAAS,CAAC,EAAE,KAAK,SAAS,MAAM,GAAA,GAAQ,GAAG/H,CAAM;AAAA,QACjD,GAAIi8B,IAAQ,EAAE,aAAaA,EAAM,KAAA,IAAS,CAAA;AAAA,MAAC;AAAA,IAE/C,CAAC;AAAA,IAGC,YAAYe,EAAU;AAAA,IACtB,gBAAgBE;AAAA,IAChB,GAAIF,EAAU,eACV,EAAE,cAAcA,EAAU,cAAc,kBAAkBA,EAAU,qBACpE,CAAA;AAAA,EAAC;AAET;AAGA,SAASI,GAAe/lC,GAAuD;AAC7E,QAAM+I,IAAO/I,EAAI,KAAA,EAAO,MAAM,GAAG;AACjC,MAAK,EAAA+I,EAAK,CAAC,MAAM,WAAWA,EAAK,CAAC,MAAM,WAAYA,EAAK,SAAS,KAAKA,EAAK,CAAC,MAAM;AAGnF,WAAO,EAAE,IAAIA,EAAK,CAAC,GAAG,MAAMA,EAAK,MAAM,CAAC,EAAE,KAAK,GAAG,EAAA;AACpD;AAGA,SAASi9B,GACPplB,GACAzd,GACAmhC,GAC6E;;AAC7E,QAAMtkC,IAAM6M,GAAc+T,CAAK,GACzBrhB,IAAQS,IAAM+lC,GAAe/lC,CAAG,IAAI,QACpCrc,IAAO4b,KAAQ3b,IAAAuf,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAO0H,EAAM,EAAE,MAAnC,gBAAA3b,EAAsC,KAAK,OAAO;AACvE,MAAI,CAAC2b,KAAS,CAAC5b,EAAM;AACrB,QAAMsiD,KAAM7uC,IAAAktC,EAAO,cAAP,gBAAAltC,EAAA,KAAAktC,GAAmB3gD,EAAK,KAAK,KAAKA,EAAK,KAAK,SAClDuiD,IAAU1C,GAAYyC,KAAA,gBAAAA,EAAK,QAAQ1mC,EAAM,IAAI,GAC7C8G,IAAQ,MAAM,QAAQ6/B,CAAO,KAAKA,EAAQ,SAAS,IAAIA,EAAQ,CAAC,IAAI,QAEpEC,IADgB7C,GAAmB2C,KAAA,gBAAAA,EAAK,QAAQ1mC,EAAM,IAAI,KAC3BgkC,GAAkBl9B,CAAK;AAC5D,MAAI,EAAAA,MAAU,UAAa,CAAC8/B;AAC5B,WAAO;AAAA,MACL,GAAI9/B,MAAU,SAAY,EAAE,YAAYA,EAAA,IAAU,CAAA;AAAA,MAClD,GAAI8/B,IAAc,EAAE,aAAAA,MAAgB,CAAA;AAAA,IAAC;AAEzC;AAGA,SAASC,GACPlN,GACA/1B,GACAmhC,IAA2B,CAAA,GACL;;AACtB,QAAMp0B,IAA6B,EAAE,WAAAgpB,EAAA,GAC/BtY,KAAQxpB,KAAAxT,IAAAuf,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAOqhC,CAAS,MAApC,gBAAAt1C,EAAuC,KAAK,KAAK,SAAjD,gBAAAwT,EAAuD,OAI/D2tC,IAAO,EAAE,GAAIT,EAAO,oBAAoB,CAAA,GAAK,GAAIA,EAAO,eAAe,GAAC,GACxEluC,IAAO6uC,GAAiBrkB,GAAOmkB,CAAI,GACnCZ,IAAM/tC,KAAQA,EAAK,SAAS,IAAIA,KAAOyG,IAAAynC,EAAO,gBAAP,gBAAAznC,EAAqBq8B;AAClE,MAAIiL,KAAOA,EAAI,SAAS,GAAG;AACzB,IAAAj0B,EAAK,aAAai0B,EAAI,CAAC;AACvB,UAAMkC,IAAU9C,GAAkBY,EAAI,CAAC,CAAC;AACxC,WAAIkC,QAAc,cAAcA,IACzBn2B;AAAA,EACT;AAGA,QAAM2rB,IAAWmK,GAAkBplB,GAAOzd,GAAOmhC,CAAM;AACvD,UAAIzI,KAAA,gBAAAA,EAAU,gBAAe,WAAW3rB,EAAK,aAAa2rB,EAAS,aAC/DA,KAAA,QAAAA,EAAU,gBAAa3rB,EAAK,cAAc2rB,EAAS,cAChD3rB;AACT;AA2CO,SAASo2B,GACdC,GACApjC,GACAg2B,GACAmL,GACAkC,GAcA;AAKA,MAAIC,IAASF;AAQb,MANE,CAACE,KACDD,MACCrN,EAAM,KAAK,CAAC1rC,MAAMA,EAAE,WAAW+4C,CAAO,KAAKvM,GAAe92B,GAAOg2B,CAAK,EAAEqN,CAAO,MAAM,YAEtFC,IAASD,IAEP,CAACC,EAAQ,QAAOpC,GAAmB,IAAI,IAAIlhC,EAAM,IAAI,CAACtL,MAAMA,EAAE,EAAE,CAAC,GAAGsL,GAAOmhC,CAAM;AACrF,QAAMmB,IAAUxL,GAAe92B,GAAOg2B,CAAK,EAAEsN,CAAM,GAC7ClhD,IAAMigD,GAAiBxB,GAAYyC,GAAQtN,CAAK,GAAGsM,GAAStiC,GAAOg2B,GAAOmL,CAAM;AACtF,SAAImB,KAAW,CAAClgD,EAAI,eAAe,SAASkgD,CAAO,KAAGlgD,EAAI,eAAe,KAAKkgD,CAAO,GAC9E;AAAA,IACL,OAAOlgD,EAAI;AAAA,IACX,YAAYA,EAAI;AAAA,IAChB,GAAIA,EAAI,eACJ,EAAE,cAAcA,EAAI,cAAc,kBAAkBA,EAAI,iBAAA,IACxD,CAAA;AAAA,IACJ,GAAIkgD,IAAU,EAAE,MAAMW,GAAcX,GAAStiC,GAAOmhC,CAAM,EAAA,IAAM,CAAA;AAAA,IAChE,GAAI/+C,EAAI,eAAe,SAAS,IAAI,EAAE,gBAAgBA,EAAI,mBAAmB,CAAA;AAAA,EAAC;AAElF;AAkBO,SAASmhD,GACdC,GACAxjC,GACAg2B,GACAmL,GACwB;AACxB,MAAI,CAACqC,KAAkBA,EAAe,eAAe,iBAAiB,CAAA;AACtE,QAAMt+C,IAAM27C,GAAY2C,EAAe,QAAQxN,CAAK;AACpD,EAAA9wC,EAAI,IAAIs+C,EAAe,MAAM;AAC7B,QAAMlB,IAAUmB,GAAeD,GAAgBxjC,GAAOg2B,CAAK;AAC3D,SAAOqM,GAAiBn9C,GAAKo9C,GAAStiC,GAAOg2B,GAAOmL,CAAM,EAAE;AAC9D;AAOA,SAASsC,GACPD,GACAxjC,GACAg2B,GACoB;AACpB,QAAMnO,IAAU7nB,EAAM,KAAK,CAACtL,MAAMA,EAAE,OAAO8uC,EAAe,MAAM;AAChE,SAAOA,EAAe,SAAS,UAAUrO,GAActN,KAAA,gBAAAA,EAAS,KAAK,IAAI,IACrE2b,EAAe,SACf1M,GAAe92B,GAAOg2B,CAAK,EAAEwN,EAAe,MAAM;AACxD;AAGO,SAASE,GACdF,GACAxjC,GACAg2B,GACAmL,GACkC;AAClC,MAAI,CAACqC,KAAkBA,EAAe,eAAe,SAAU;AAC/D,QAAMlB,IAAUmB,GAAeD,GAAgBxjC,GAAOg2B,CAAK;AAC3D,SAAOsM,IAAUW,GAAcX,GAAStiC,GAAOmhC,CAAM,IAAI;AAC3D;AAgBA,eAAsBwC,GACpBC,GACAC,GACuB;AAYvB,UAXgB,MAAM,QAAQ;AAAA,IAC5BA,EAAc,IAAI,OAAO,MAAkC;AACzD,UAAI;AACF,cAAM7U,IAAQ,MAAM4U,EAAc,EAAE,EAAE,GAChCpuB,IAASwZ,EAAM,SAASA,EAAMA,EAAM,SAAS,CAAC,IAAI;AACxD,eAAOxZ,IAAS,EAAE,QAAQ,EAAE,IAAI,OAAO,EAAE,SAAS,EAAE,IAAI,MAAMA,EAAA,IAAW;AAAA,MAC3E,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EAAA,GAEY,OAAO,CAAC90B,MAAuBA,MAAM,IAAI;AAC1D;AAsBO,SAASojD,GACdr/B,GACAsI,GAC4B;AAC5B,QAAM3N,IAA+D,CAAA;AACrE,aAAWjY,KAAKsd,GAAO;AACrB,UAAMw7B,IAAS94C,EAAE,KAAK,eAChB48C,IAAoC9D,KAAW;AAKrD,QAAI,CAAC8D,KAAa58C,EAAE,KAAK,kBAAkB,YAAa;AACxD,UAAM0X,IAAO1X,EAAE,KAAK;AACpB,IAAAiY,EAAMjY,EAAE,MAAM,IAAI,EAAE,QAAQ48C,IAAY9D,IAAS,MAAM,GAAIphC,IAAO,EAAE,MAAAA,EAAA,IAAS,CAAA,EAAC;AAAA,EAChF;AACA,QAAMmlC,IAAW,OAAO,KAAK5kC,CAAK,EAAE,SAAS;AAE7C,SAAK2N,IAGE;AAAA,IACL,GAAIi3B,IAAW,EAAE,OAAA5kC,EAAA,IAAU,CAAA;AAAA,IAC3B,SAAS,EAAE,GAAI2N,EAAK,SAAS,SAAY,EAAE,MAAMA,EAAK,KAAA,IAAS,CAAA,GAAK,OAAOA,EAAK,SAAS,EAAA;AAAA,EAAE,IAL3Ei3B,IAAW,EAAE,OAAA5kC,MAAU;AAO3C;AAGO,SAAS6kC,GACdl3B,GACgD;AAChD,MAAKA;AACL,WAAO,EAAE,GAAI,gBAAgBA,IAAO,EAAE,MAAMA,EAAK,eAAe,CAAA,GAAK,OAAO,EAAA;AAC9E;AAGO,SAASm3B,GAAan3B,GAAgD;AAC3E,SAAI,CAACA,KAAQ,EAAE,gBAAgBA,KAAc,KACtC,KAAK,UAAUA,EAAK,YAAY,MAAM,CAAC,KAAK;AACrD;AAOO,SAASo3B,GACdC,GACAC,GACuF;AACvF,MAAI/6B;AACJ,MAAI86B,EAAS,KAAA,MAAW;AACtB,QAAI;AACF,MAAA96B,IAAO,KAAK,MAAM86B,CAAQ;AAAA,IAC5B,QAAQ;AACN,aAAO,EAAE,IAAI,IAAO,OAAO,uCAAA;AAAA,IAC7B;AAEF,QAAMxmB,IAAMymB,EAAU,WAAW,KAAK,IAAI,OAAOA,EAAU,MAAM;AACjE,SAAI,CAAC,OAAO,UAAUzmB,CAAG,KAAKA,IAAM,IAC3B,EAAE,IAAI,IAAO,OAAO,+CAAA,IAEtB,EAAE,IAAI,IAAM,OAAO,EAAE,GAAItU,MAAS,SAAY,EAAE,MAAAA,MAAS,CAAA,GAAK,OAAOsU,IAAI;AAClF;AAOO,SAAS0mB,GACd11B,GACA/P,GACyB;AACzB,MAAI,CAACA,EAAM,QAAO,CAAA;AAClB,QAAMzc,IAA+B,CAAA;AAErC,aAAW0N,KAAQ,CAAC,SAAS,OAAO,GAAG;AACrC,UAAM5L,IAAI,GAAG4L,CAAI,IAAI8e,CAAM;AAC3B,IAAAxsB,EAAI,GAAG8B,CAAC,MAAM,IAAI2a,EAAK,KACvBzc,EAAI,GAAG8B,CAAC,UAAU,IAAI2a,EAAK,SAC3Bzc,EAAI,GAAG8B,CAAC,SAAS,IAAI2a,EAAK,QAC1Bzc,EAAI,GAAG8B,CAAC,eAAe,IAAI2a,EAAK;AAAA,EAClC;AACA,SAAOzc;AACT;AASO,SAASmiD,GACdnlC,GACA2iC,GACAyC,GACAz3B,GACA03B,GACyB;AACzB,SAAOC,GAAoBtlC,GAAO2iC,GAAayC,GAAWz3B,GAAM03B,CAAK,EAAE;AACzE;AAcO,SAASE,GACdvlC,GACA2iC,GACAyC,GACAz3B,GACA03B,GACkD;AAClD,SAAOC,GAAoBtlC,GAAO2iC,GAAayC,GAAWz3B,GAAM03B,CAAK,EAAE;AACzE;AAOO,SAASG,GACd5kC,GACAmhC,GACuD;;AACvD,QAAMvjC,IAAmC,CAAA;AACzC,MAAI5F;AACJ,aAAWtD,KAAKsL,GAAO;AACrB,UAAM6kC,IAAInwC,EAAE,KAAK,KAAK;AACtB,QAAImwC,EAAE,YAAY,IAAM;AACtB,YAAM7iD,KAAIiS,KAAAxT,IAAA0gD,EAAO,eAAP,gBAAA1gD,EAAA,KAAA0gD,GAAoB0D,EAAE,KAAKA,EAAE,YAA7B,gBAAA5wC,EAAsC;AAChD,MAAI+D,MAAU,UAAahW,MAAM,WAAWgW,IAAQhW;AACpD;AAAA,IACF;AACA,QAAIP,GAAcojD,EAAE,GAAG,EAAG;AAC1B,UAAM7iD,KAAI2X,KAAAD,IAAAynC,EAAO,cAAP,gBAAAznC,EAAA,KAAAynC,GAAmB0D,EAAE,KAAKA,EAAE,YAA5B,gBAAAlrC,EAAqC;AAC/C,IAAI3X,MAAM,WAAW4b,EAAQlJ,EAAE,EAAE,IAAI1S;AAAA,EACvC;AACA,SAAO,EAAE,SAAA4b,GAAS,GAAI5F,MAAU,SAAY,EAAE,OAAAA,EAAA,IAAU,GAAC;AAC3D;AAEA,SAAS0sC,GACPtlC,GACA2iC,GACAyC,GACAz3B,GACA03B,IAAqB,IAC2E;;AAChG,QAAM74C,IAAgC,CAAA,GAChCk5C,IAA4D,CAAA;AAClE,aAAWv3B,KAAMnO,GAAO;AACtB,WAAO,OAAOxT,GAAM04C,GAAqB/2B,EAAG,IAAIi3B,EAAUj3B,EAAG,EAAE,CAAC,CAAC;AAEjE,UAAMrrB,IAAS;AAAA,MACb,CAAC,WAAUzB,IAAAgkD,EAAM,YAAN,gBAAAhkD,EAAgB8sB,EAAG,GAAG;AAAA,MACjC,CAAC,cAAatZ,IAAAwwC,EAAM,cAAN,gBAAAxwC,EAAkBsZ,EAAG,GAAG;AAAA,MACtC,CAAC,SAASw0B,EAAYx0B,EAAG,EAAE,CAAC;AAAA,IAAA;AAE9B,eAAW,CAACe,GAAM2xB,CAAM,KAAK/9C,GAAQ;AACnC,UAAI+9C,MAAW,OAAW;AAC1B,YAAM8E,IAAM,CAACplC,GAAc7U,MAAmB;AAC5C,mBAAWgF,KAAQ,CAAC,SAAS,OAAO;AAClC,UAAAlE,EAAK,GAAGkE,CAAI,IAAI6P,CAAI,EAAE,IAAI7U,GAC1Bg6C,EAAQ,GAAGh1C,CAAI,IAAI6P,CAAI,EAAE,IAAI2O;AAAA,MAEjC;AAEA,UADAy2B,EAAI,GAAGx3B,EAAG,EAAE,WAAW0yB,CAAM,GACzB,OAAOA,KAAW,YAAYA,MAAW,QAAQ,CAAC,MAAM,QAAQA,CAAM;AACxE,mBAAW,CAAC9/B,GAAGne,CAAC,KAAK,OAAO,QAAQi+C,CAAiC;AACnE,UAAA8E,EAAI,GAAGx3B,EAAG,EAAE,WAAWpN,CAAC,IAAIne,CAAC;AAGjC,iBAAWkY,KAAKqT,EAAG,WAAW,CAAA,GAAI;AAChC,YAAI,CAACrT,EAAE,QAAQ,CAACA,EAAE,IAAI,SAAS,GAAG,EAAG;AACrC,cAAMlY,IAAIq+C,GAAYJ,GAAQ/lC,EAAE,GAAG;AACnC,QAAIlY,MAAM,UAAW+iD,EAAI,GAAGx3B,EAAG,EAAE,WAAWrT,EAAE,GAAG,IAAIlY,CAAC;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AACA,MAAIyiD,EAAM,UAAU,QAAW;AAC7B,UAAMM,IAAM,CAACloC,GAAa/R,MAAmB;AAC3C,MAAAc,EAAKiR,CAAG,IAAI/R,GACZg6C,EAAQjoC,CAAG,IAAI;AAAA,IACjB;AAEA,QADAkoC,EAAI,iBAAiBN,EAAM,KAAK,GAC5B,OAAOA,EAAM,SAAU,YAAYA,EAAM,UAAU,QAAQ,CAAC,MAAM,QAAQA,EAAM,KAAK;AACvF,iBAAW,CAACtkC,GAAGne,CAAC,KAAK,OAAO,QAAQyiD,EAAM,KAAgC;AACxE,QAAAM,EAAI,iBAAiB5kC,CAAC,IAAIne,CAAC;AAG/B,eAAW0jB,KAAK06B,GAAkBqE,EAAM,KAAK,KAAK,CAAA,GAAI;AACpD,YAAMziD,IAAIq+C,GAAYoE,EAAM,OAAO/+B,EAAE,GAAG;AACxC,MAAI1jB,MAAM,UAAW+iD,EAAI,iBAAiBr/B,EAAE,GAAG,IAAI1jB,CAAC;AAAA,IACtD;AAAA,EACF;AACA,MAAI+qB,KAAQ,gBAAgBA,GAAM;AAChC,IAAAnhB,EAAK,cAAc,IAAImhB,EAAK;AAC5B,eAAW7S,KAAK6S,EAAK,eAAe,CAAA,GAAI;AACtC,YAAM/qB,IAAIq+C,GAAYtzB,EAAK,YAAY7S,EAAE,GAAG;AAC5C,MAAIlY,MAAM,WAAW4J,EAAK,gBAAgBsO,EAAE,GAAG,EAAE,IAAIlY;AAAA,IACvD;AACA,IAAA4J,EAAK,eAAe,IAAI;AAAA,EAC1B;AACA,SAAO,EAAE,QAAQA,GAAM,SAAAk5C,EAAA;AACzB;AAGA,SAASE,GAAehjD,GAAqB;AAC3C,MAAI,OAAOA,KAAM,YAAYA,MAAM,QAAQ,MAAM,QAAQA,CAAC,EAAG,QAAO;AACpE,QAAMkY,IAAIlY;AACV,MAAIkY,EAAE,SAAS,YAAYA,EAAE,SAAS,OAAQ,QAAO;AACrD,QAAMmK,IAAO,OAAO,KAAKnK,CAAC;AAC1B,SAAOmK,EAAK,WAAW,KAAKA,EAAK,CAAC,MAAM;AAC1C;AAQO,SAAS4gC,GAAkBjlC,GAAqD;AACrF,QAAM5d,IAAwC,CAAA;AAC9C,aAAW,KAAK4d,GAAO;AACrB,UAAMxf,IAAO,EAAE,KAAK,MACd6jB,IAAO,OAAO,QAAQ7jB,EAAK,QAAQ,EAAE,EACxC,OAAO,CAAC,GAAGwB,CAAC,MAAMA,MAAM,UAAa,CAACgjD,GAAehjD,CAAC,CAAC,EACvD,IAAI,CAAC,CAACme,CAAC,MAAMA,CAAC;AAEjB,KADkB3f,EAAK,KAAK,QAAQd,MAAec,EAAK,KAAK,YAAY,OACxD,CAAC6jB,EAAK,SAAS,KAAK,KAAGA,EAAK,QAAQ,KAAK,GACtDA,EAAK,SAAS,KAAGjiB,EAAI,KAAK,EAAE,IAAI5B,EAAK,IAAI,MAAA6jB,GAAM;AAAA,EACrD;AACA,SAAOjiB;AACT;AAGA,SAAS8iD,GAAYljD,GAAqB;AACxC,MAAI,EAAAga,GAAYha,CAAC,KAAKia,GAAcja,CAAC,IACrC;AAAA,QAAI,MAAM,QAAQA,CAAC,EAAG,QAAOA,EAAE,IAAIkjD,EAAW,EAAE,OAAO,CAAC5+B,MAAMA,MAAM,MAAS;AAC7E,QAAI,OAAOtkB,KAAM,YAAYA,MAAM,MAAM;AACvC,YAAMkY,IAAIlY,GACJqiB,IAAO,OAAO,KAAKnK,CAAC;AAC1B,UAAImK,EAAK,WAAW,KAAKA,EAAK,CAAC,MAAM,OAAO,OAAOnK,EAAE,KAAM,SAAU;AACrE,YAAM9X,IAA+B,CAAA;AACrC,iBAAW,CAAC+d,GAAGmG,CAAC,KAAK,OAAO,QAAQpM,CAAC,GAAG;AACtC,cAAMmF,IAAK6lC,GAAY5+B,CAAC;AACxB,QAAIjH,MAAO,WAAWjd,EAAI+d,CAAC,IAAId;AAAA,MACjC;AACA,aAAOjd;AAAA,IACT;AACA,WAAOJ;AAAA;AACT;AASO,SAASmjD,GACdnlC,GACA8qB,GACyC;AACzC,QAAM1oC,IAA+C,CAAA;AACrD,aAAWsS,KAAKsL,GAAO;AACrB,UAAMxf,IAAOkU,EAAE,KAAK,MACdkK,IAAS,EAAE,GAAKsmC,GAAY1kD,EAAK,QAAQ,CAAA,CAAE,KAAK,GAAC,GACjDirC,IAAM2Z,GAAgB5kD,GAAMsqC,CAAI;AACtC,IAAIW,KAAA,QAAAA,EAAK,eAAY7sB,EAAO,MAAM6sB,EAAI,aAClC,OAAO,KAAK7sB,CAAM,EAAE,SAAS,MAAGxc,EAAI5B,EAAK,EAAE,IAAIoe;AAAA,EACrD;AACA,SAAOxc;AACT;AAMA,SAASgjD,GACP5kD,GACAsqC,GACiC;AACjC,MAAI,EAAAtqC,EAAK,KAAK,QAAQd,MAAec,EAAK,KAAK,YAAY;AAC3D,WACEsqC,EAAK,KAAK,CAAC3jC,MAAMA,EAAE,WAAW3G,EAAK,EAAE,MACpCA,EAAK,KAAK,QAAQd,KAAcorC,EAAK,KAAK,CAAC3jC,MAAMA,EAAE,UAAUzH,EAAW,IAAI;AAEjF;AAWO,SAAS2lD,GACdrlC,GACA8qB,GACA/sC,GACAk0C,GACyC;;AACzC,QAAM7vC,IAA+C,CAAA;AACrD,aAAWsS,KAAKsL,GAAO;AACrB,UAAMxf,IAAOkU,EAAE,KAAK;AACpB,QAAI,CAAClU,EAAK,KAAK,IAAK;AACpB,UAAMqe,IAAgC;AAAA,MACpC,KAAKre,EAAK,KAAK;AAAA,MACf,QAAQA,EAAK,KAAK;AAAA,MAClB,cAAc+xC,GAAgB/xC,GAAMyxC,CAAW,KAAK;AAAA,IAAA,GAEhDqT,KAAU7kD,IAAA1C,KAAA,gBAAAA,EAAM,IAAIyC,EAAK,KAAK,SAApB,gBAAAC,EAA0B;AAC1C,IAAI6kD,QAAc,UAAUA;AAC5B,UAAM7Z,IAAM2Z,GAAgB5kD,GAAMsqC,CAAI;AACtC,IAAIW,MAAK5sB,EAAK,iBAAiB4sB,EAAI,KAC/BA,KAAA,QAAAA,EAAK,eAAY5sB,EAAK,MAAM4sB,EAAI,aACpCrpC,EAAI5B,EAAK,EAAE,IAAIqe;AAAA,EACjB;AACA,SAAOzc;AACT;AAMO,SAASmjD,GACd1mC,GACyB;AACzB,QAAMzc,IAA+B,CAAA;AACrC,aAAW,CAACxB,GAAIwO,CAAC,KAAK,OAAO,QAAQyP,CAAI;AACvC,eAAW,CAACsB,GAAGne,CAAC,KAAK,OAAO,QAAQoN,CAAC;AACnC,MAAAhN,EAAI,SAASxB,CAAE,SAASuf,CAAC,EAAE,IAAIne,GAC/BI,EAAI,SAASxB,CAAE,SAASuf,CAAC,EAAE,IAAIne;AAGnC,SAAOI;AACT;AC/6BO,SAASojD,GACdz9C,GACA87C,GACA4B,GACc;AACd,QAAMn+C,IAAMG,GAAA,GACN,CAACi+C,GAAaC,CAAc,IAAIz/C,EAAuB,CAAA,CAAE,GACzD0D,IAAS,KAAK,UAAUi6C,EAAc,IAAI,CAAC18C,MAAM,CAACA,EAAE,IAAIA,EAAE,KAAK,CAAC,CAAC;AACvE,SAAAhB,GAAU,MAAM;AACd,UAAMjB,IAAM,KAAK,MAAM0E,CAAM;AAC7B,QAAI,CAAC67C,KAAWvgD,EAAI,WAAW,GAAG;AAChC,MAAAygD,EAAe,CAAA,CAAE;AACjB;AAAA,IACF;AACA,QAAIt7C,IAAW;AACf,WAAAs5C;AAAA,MACE,CAAC/0B,MAAWtnB,EAAI,cAAcS,GAAY6mB,CAAM;AAAA,MAChD1pB,EAAI,IAAI,CAAC,CAACtE,GAAI+V,CAAK,OAAO,EAAE,IAAA/V,GAAI,OAAA+V,IAAQ;AAAA,IAAA,EACxC,KAAK,CAAC8N,MAAU;AAChB,MAAKpa,KAAUs7C,EAAelhC,CAAK;AAAA,IACrC,CAAC,GACM,MAAM;AACX,MAAApa,IAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAKS,GAAY6B,GAAQ67C,CAAO,CAAC,GAC9BC;AACT;AC4MA,MAAME,KAAoB,CAAC,YAAY,UAAU,GAM3CC,KAA0D;AAAA,EAC9D,UACE;AAAA,EACF,UAAU;AACZ,GAyBMC,KAA4E;AAAA,EAChF,OAAO,EAAE,OAAO,QAAQ,MAAM,OAAA;AAAA,EAC9B,MAAM,EAAE,OAAO,QAAQ,MAAM,OAAA;AAAA,EAC7B,eAAe,EAAE,OAAO,eAAe,MAAM,SAAA;AAAA,EAC7C,QAAQ,EAAE,OAAO,iBAAiB,MAAM,aAAA;AAC1C,GAGMC,KAAiC,CAAC,SAAS,QAAQ,eAAe,QAAQ;AAYzE,SAASC,GAAiB;AAAA,EAC/B,MAAAhtC;AAAA,EACA,UAAAlG;AAAA,EACA,UAAA0H;AAAA,EACA,OAAAyrC,IAAQF;AAAA,EACR,YAAAG,IAAa;AACf,GAOG;AACD,QAAMC,IAAM,CAACnkD,MACX,gBAAAiF;AAAA,IAAC;AAAA,IAAA;AAAA,MAEC,MAAK;AAAA,MACL,OAAO6+C,GAAmB9jD,CAAC,EAAE;AAAA,MAC7B,cAAY8jD,GAAmB9jD,CAAC,EAAE;AAAA,MAClC,gBAAcgX,MAAShX;AAAA,MACvB,UAAAwY;AAAA,MACA,WAAW,eAAexB,MAAShX,KAAK,CAACwY,IAAW,YAAY,EAAE;AAAA,MAClE,SAAS,MAAM1H,EAAS9Q,CAAC;AAAA,MAEzB,UAAA,gBAAAiF,EAACgQ,MAAK,MAAM6uC,GAAmB9jD,CAAC,EAAE,MAAM,MAAM,GAAA,CAAI;AAAA,IAAA;AAAA,IAT7CA;AAAA,EAAA;AAYT,SACE,gBAAA+K,EAAC,OAAA,EAAI,WAAU,mBACZ,UAAA;AAAA,IAAAm5C,KACC,gBAAAj/C;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,UAAAuT;AAAA,QACA,SAAS,MAAM1H,EAAS,aAAa;AAAA,QACrC,OAAM;AAAA,QACP,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAIFmzC,EAAM,IAAIE,CAAG;AAAA,EAAA,GAChB;AAEJ;AAUO,SAASC,GAAiB;AAAA,EAC/B,SAAA9jC;AAAA,EACA,OAAA+jC;AAAA,EACA,eAAAC;AAAA,EACA,OAAAz/C;AAAA,EACA,UAAA0/C;AAAA,EACA,WAAAC,IAAYZ;AAAA,EACZ,YAAAa;AAAA,EACA,OAAAzkC;AAAA,EACA,YAAAja;AAAA,EACA,QAAA6mB;AAAA,EACA,eAAAi1B,IAAgB,CAAA;AAAA,EAChB,MAAA92B;AAAA,EACA,YAAA25B;AAAA,EACA,eAAAC;AAAA,EACA,mBAAAtT;AAAA,EACA,aAAAuT;AAAA,EACA,YAAAC;AAAA,EACA,SAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,aAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,SAAAC,IAAU,CAAA;AACZ,GAA0B;AAGxB,QAAM,CAACC,GAAUC,CAAW,IAAInhD,EAAwB,IAAI,GACtD,CAACohD,GAAUC,CAAW,IAAIrhD,EAAwB,IAAI,GACtDshD,IAAYz9C,GAAyB,IAAI,GACzC09C,IAAW,CAACjnD,MAAoB;AACpC,UAAMI,IAAKylD,EAAM7lD,CAAI;AACrB,WAAI,OAAOI,KAAO,aAChB4mD,EAAU,UAAUhnD,GACpB6mD,EAAYzmD,CAAE,GACd2mD,EAAY,IAAI,IAEX3mD;AAAA,EACT,GACM8mD,IAAapB,IACf,CAAC1lD,GAAYJ,MAAoB;AAC/B,IAAAgnD,EAAU,UAAUhnD,GACpB8lD,EAAc1lD,GAAIJ,CAAI;AAAA,EACxB,IACA,QACEoX,IAAS,MAAM;AACnB,IAAIwvC,KAAYE,KAAYA,MAAaF,KAAYM,KAAcF,EAAU,WAC3EE,EAAWN,GAAU,EAAE,GAAGI,EAAU,SAAS,IAAIF,GAAU,GAE7DhlC,EAAA;AAAA,EACF,GACMqlC,IAAS,CAAChxC,MACdywC,KAAYd,IACV,gBAAAv5C,EAAC,QAAA,EAAK,WAAU,yBACb,UAAA;AAAA,IAAA4J;AAAA,IACD,gBAAA1P;AAAA,MAACuhC;AAAA,MAAA;AAAA,QACC,OAAO8e,KAAYF;AAAA,QACnB,UAAU,CAACxmD,MAAO;AAChB,gBAAM8nC,KAAM2S;AAAA,YACVz6C;AAAA,YACAumD,EAAQ,OAAO,CAAC5L,OAAUA,OAAU6L,CAAQ;AAAA,UAAA;AAE9C,iBAAK1e,MAAK6e,EAAY3mD,CAAE,GACjB8nC;AAAA,QACT;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,EAAA,CACF,IAEA/xB,GAIE,CAACixC,GAAKC,CAAM,IAAI3hD,EAAcugD,KAAc,WAAW,GACvD,CAACpiD,GAAO62B,CAAQ,IAAIh1B,EAAS,EAAE,GAI/B,CAAC++B,IAAaC,EAAc,IAAIh/B,EAA4BwgD,KAAc,IAAI,GAG9E,CAACoB,GAAcC,CAAe,IAAI7hD,EAAiC,IAAI,GAIvE,CAAC8hD,GAAoBC,CAAqB,IAAI/hD,EAA4B,IAAI,GAI9E,CAACgiD,GAAkBC,CAAmB,IAAIjiD,EAItC,IAAI,GAMRkiD,KAAa,CAAC,CAACtB,KAAWA,EAAQ,SAAS,GAC3CuB,IAAaC,GAAc9B,GAAWK,GAAYI,GAAoBH,CAAO,GAC7EyB,IAAgBF,EAAW,UAAU;AAO3C,MAJAliD,GAAU,MAAM;AACd,IAAI,CAACoiD,KAAiBX,MAAQ,iBAAoB,MAAM;AAAA,EAC1D,GAAG,CAACW,GAAeX,CAAG,CAAC,GAEnBM;AACF,WACE,gBAAAjhD;AAAA,MAACob;AAAA,MAAA;AAAA,QACC,OAAOslC,EAAOO,EAAiB,KAAK;AAAA,QACpC,WAAWA,EAAiB;AAAA,QAC5B,UAAU,gBAAAjhD,EAAC,QAAA,EAAM,UAAAihD,EAAiB,IAAG;AAAA,QACrC,SAAA5lC;AAAA,QACA,MAAK;AAAA,QACL,aACE,gBAAArb;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,SAAS,MAAMkhD,EAAoB,IAAI;AAAA,YACxC,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAKH,UAAA,gBAAAlhD,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA,gBAAAA;AAAA,UAACuhD;AAAA,UAAA;AAAA,YACC,QAAQN,EAAiB;AAAA,YACzB,UAAUA,EAAiB;AAAA,YAC3B,aAAaA,EAAiB;AAAA,YAC9B,OAAOT;AAAA,YACP,SAAAnlC;AAAA,YACA,QAAQ1K;AAAA,YACR,eAAe8vC;AAAA,UAAA;AAAA,QAAA,EACjB,CACF;AAAA,MAAA;AAAA,IAAA;AAKN,MAAII;AACF,WACE,gBAAA7gD;AAAA,MAACob;AAAA,MAAA;AAAA,QACC,OAAOslC,EAAOG,EAAa,eAAeA,EAAa,cAAcA,EAAa,KAAK;AAAA,QACvF,WAAWA,EAAa,eAAeA,EAAa,cAAcA,EAAa;AAAA,QAC/E,WAAW,gBAAA7gD,EAAC2tC,IAAA,EAAa,MAAMkT,EAAa,MAAM,MAAM,IAAI;AAAA,QAC5D,4BACG,QAAA,EACE,UAAA;AAAA,UAAAA,EAAa;AAAA,UACb,CAACA,EAAa,gBAAgB,MAAMA,EAAa,MAAM;AAAA,QAAA,GAC1D;AAAA,QAEF,SAAAxlC;AAAA,QACA,MAAK;AAAA,QACL,aACE,gBAAArb;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,SAAS,MAAM8gD,EAAgB,IAAI;AAAA,YACpC,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAKH,UAAA,gBAAA9gD,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA,gBAAAA;AAAA,UAACwhD;AAAA,UAAA;AAAA,YACC,MAAMX;AAAA,YACN,OAAOL;AAAA,YACP,SAAAnlC;AAAA,YACA,QAAQ1K;AAAA,YACR,eAAe8vC;AAAA,YACf,YAAAR;AAAA,YACA,YAAAn/C;AAAA,YACA,eAAA87C;AAAA,YACA,MAAA92B;AAAA,UAAA;AAAA,QAAA,EACF,CACF;AAAA,MAAA;AAAA,IAAA;AAKN,QAAM27B,IAAYV,KAAsB/iB;AACxC,MAAIyjB,GAAW;AACb,UAAM/yC,IAAOqyC,IAAqB,YAAY,UACxCW,IAAY,MAAM;AACtB,MAAAzjB,GAAe,IAAI,GACnB+iB,EAAsB,IAAI;AAAA,IAC5B;AACA,WACE,gBAAAhhD;AAAA,MAACob;AAAA,MAAA;AAAA,QACC,OAAOslC,EAAOe,EAAU,WAAW;AAAA,QACnC,WAAWA,EAAU;AAAA,QACrB,UACE,gBAAA37C,EAAAwB,IAAA,EACE,UAAA;AAAA,UAAA,gBAAAtH,EAAC,QAAA,EAAM,YAAU,GAAA,CAAG;AAAA,UACnByhD,EAAU,WAAW,OAAOA,EAAU,OAAO;AAAA,QAAA,GAChD;AAAA,QAEF,SAAApmC;AAAA,QACA,MAAK;AAAA,QACL,WACE,gBAAArb;AAAA,UAACV;AAAA,UAAA;AAAA,YACC,KAAKmiD,EAAU;AAAA,YACf,SAASA,EAAU;AAAA,YACnB,YAAYA,EAAU;AAAA,YACtB,MAAMA,EAAU;AAAA,YAChB,OAAA7hD;AAAA,YACA,MAAM;AAAA,UAAA;AAAA,QAAA;AAAA,QAIV,4BAAC,OAAA,EAAI,WAAU,0BAGZ,UAAAkgD,KAAkBpxC,MAAS,WAC1B,gBAAA1O;AAAA,UAAC2hD;AAAA,UAAA;AAAA,YACC,OAAOF,EAAU;AAAA,YACjB,KAAKA;AAAA,YACL,SAAApmC;AAAA,YACA,aAAaqmC;AAAA,YACb,OAAA9hD;AAAA,YACA,mBAAAwsC;AAAA,YACA,aAAa,CAAChM,IAAcppC,OAAQ+oD,KAAA,gBAAAA,EAAc3f,IAAcppC;AAAA,UAAG;AAAA,QAAA,IAGrE,gBAAAgJ;AAAA,UAAC4hD;AAAA,UAAA;AAAA,YACC,MAAAlzC;AAAA,YACA,YAAAuxC;AAAA,YACA,OAAOwB,EAAU;AAAA,YACjB,KAAKA;AAAA,YACL,OAAOjB;AAAA,YACP,SAAAnlC;AAAA,YACA,QAAQ1K;AAAA,YACR,eAAe8vC;AAAA,YACf,aAAaiB;AAAA,YACb,OAAA9hD;AAAA,YACA,YAAAkB;AAAA,YACA,QAAA6mB;AAAA,YACA,eAAAi1B;AAAA,YACA,MAAA92B;AAAA,YAGC,GAAIpX,MAAS,WAAW,EAAE,eAAAgxC,GAAe,mBAAAtT,GAAmB,aAAAuT,EAAA,IAAgB,CAAA;AAAA,UAAC;AAAA,QAAA,EAChF,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AAEA,SACE,gBAAA3/C,EAACob,IAAA,EAAM,OAAOL,KAAS,cAAc,SAAAM,GAAkB,MAAK,MAC1D,UAAA,gBAAAvV,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,IAAA,gBAAA9F;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,cAAW;AAAA,QACX,aAAY;AAAA,QACZ,OAAO5C;AAAA,QACP,UAAU,CAACiG,MAAM4wB,EAAS5wB,EAAE,OAAO,KAAK;AAAA,MAAA;AAAA,IAAA;AAAA,IAE1C,gBAAAyC,EAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BAQZ,UAAA;AAAA,QAAAw7C,KACC,gBAAAthD;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAW,sBAAsB2gD,MAAQ,cAAc,YAAY,EAAE;AAAA,YACrE,SAAS,MAAMC,EAAO,WAAW;AAAA,YAClC,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAIH,gBAAA5gD;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAW,sBAAsB2gD,MAAQ,SAAS,YAAY,EAAE;AAAA,YAChE,SAAS,MAAMC,EAAO,MAAM;AAAA,YAC7B,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGD,gBAAA5gD;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAW,sBAAsB2gD,MAAQ,OAAO,YAAY,EAAE;AAAA,YAC9D,SAAS,MAAMC,EAAO,IAAI;AAAA,YAC3B,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGArB,EAAU,SAAS,UAAU,KAC5B,gBAAAv/C;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAW,sBAAsB2gD,MAAQ,cAAc,YAAY,EAAE;AAAA,YACrE,SAAS,MAAMC,EAAO,WAAW;AAAA,YAClC,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAIFrB,EAAU,SAAS,UAAU,KAC5B,gBAAAv/C;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAW,sBAAsB2gD,MAAQ,cAAc,YAAY,EAAE;AAAA,YACrE,SAAS,MAAMC,EAAO,WAAW;AAAA,YAClC,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAIF,CAACtB,KACA,gBAAAx5C,EAAAwB,IAAA,EACE,UAAA;AAAA,UAAA,gBAAAtH;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAW,sBAAsB2gD,MAAQ,aAAa,YAAY,EAAE;AAAA,cACpE,SAAS,MAAMC,EAAO,UAAU;AAAA,cACjC,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGD,gBAAA5gD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAW,sBAAsB2gD,MAAQ,aAAa,YAAY,EAAE;AAAA,cACpE,SAAS,MAAMC,EAAO,UAAU;AAAA,cACjC,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGD,gBAAA5gD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAW,sBAAsB2gD,MAAQ,cAAc,YAAY,EAAE;AAAA,cACrE,SAAS,MAAMC,EAAO,WAAW;AAAA,cAClC,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGD,gBAAA5gD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAW,sBAAsB2gD,MAAQ,SAAS,YAAY,EAAE;AAAA,cAChE,SAAS,MAAMC,EAAO,MAAM;AAAA,cAC7B,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAED,EAAA,CACF;AAAA,MAAA,GAEJ;AAAA,MACA,gBAAA5gD,EAAC,OAAA,EAAI,WAAU,2BACZ,gBAAQ,cACP,gBAAAA;AAAA,QAAC6hD;AAAA,QAAA;AAAA,UACC,MAAMT;AAAA,UACN,OAAAhkD;AAAA,UACA,YAAAwiD;AAAA,UACA,aAAa3hB;AAAA,UACb,kBAAkBijB;AAAA,UAClB,OAAAthD;AAAA,QAAA;AAAA,MAAA,IAEA+gD,MAAQ,cACV,gBAAA3gD;AAAA,QAAC8hD;AAAA,QAAA;AAAA,UACC,QAAO;AAAA,UACP,OAAA1kD;AAAA,UACA,YAAY4iD;AAAA,UACZ,UAAU,CAACp7C,MAAMs8C,EAAoB,EAAE,QAAQ,YAAY,GAAGt8C,EAAA,CAAG;AAAA,QAAA;AAAA,MAAA,IAEjE+7C,MAAQ,cACV,gBAAA3gD;AAAA,QAAC8hD;AAAA,QAAA;AAAA,UACC,QAAO;AAAA,UACP,OAAA1kD;AAAA,UACA,YAAY4iD;AAAA,UACZ,UAAU,CAACp7C,MAAMs8C,EAAoB,EAAE,QAAQ,YAAY,GAAGt8C,EAAA,CAAG;AAAA,QAAA;AAAA,MAAA,IAEjE+7C,MAAQ,SACV,gBAAA3gD;AAAA,QAACyB;AAAA,QAAA;AAAA,UACC,QAAQ;AAAA,UACR,aAAarE;AAAA,UACb,aAAa6gC;AAAA,UACb,OAAAr+B;AAAA,UACA,QAAQggD;AAAA,UACR,KAAKC;AAAA,QAAA;AAAA,MAAA,IAELc,MAAQ,OACV,gBAAA3gD;AAAA,QAACyB;AAAA,QAAA;AAAA,UACC,QAAQ;AAAA,UACR,aAAarE;AAAA,UACb,aAAa6gC;AAAA,UACb,OAAAr+B;AAAA,UAKA,UAAUuhD,KAAa,SAAY;AAAA,UACnC,KAAKtB;AAAA,UAIL,QAAQ,CAAC3oD,MAAA;;AACN,qBAAA0oD,KAAA,gBAAAA,EAAa1oD,OAAM,QACnBiqD,SAAe3nD,IAAAtC,EAAE,eAAF,gBAAAsC,EAAc,SAAS,UAAS;AAAA;AAAA,UAElD,cAAa;AAAA,QAAA;AAAA,MAAA,IAEbmnD,MAAQ,aACV,gBAAA3gD;AAAA,QAAC+hD;AAAA,QAAA;AAAA,UACC,OAAA3kD;AAAA,UACA,UAAU0jD;AAAA,UACV,aAAaE;AAAA,UACb,OAAAphD;AAAA,UACA,YAAAggD;AAAA,UACA,SAAAC;AAAA,QAAA;AAAA,MAAA,IAEAc,MAAQ,aACV,gBAAA3gD,EAACgiD,MAAa,OAAA5kD,GAAc,UAAU0jD,EAAA,CAAiB,IACrDH,MAAQ,2BACTsB,IAAA,EAAS,OAAA7kD,GAAc,UAAU0jD,EAAA,CAAiB,sBAElDoB,IAAA,EAAc,OAAA9kD,GAAc,UAAU0jD,EAAA,CAAiB,EAAA,CAE5D;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;AAEA,SAASqB,GAAmB/kD,MAAkBmwB,GAA4C;AACxF,QAAMrlB,IAAOqlB,EAAO,OAAO,OAAO,EAAE,KAAK,GAAG,EAAE,YAAA;AAC9C,SAAOnwB,EACJ,KAAA,EACA,YAAA,EACA,MAAM,KAAK,EACX,MAAM,CAACxG,MAASsR,EAAK,SAAStR,CAAI,CAAC;AACxC;AAEA,SAASwrD,GAAiBh4C,GAAuBhN,GAAwB;AACvE,SAAO+kD,GAAmB/kD,GAAOgN,EAAK,OAAOA,EAAK,aAAaA,EAAK,KAAKA,EAAK,MAAM;AACtF;AAKA,SAASi4C,GAAS;AAAA,EAChB,OAAAtpC;AAAA,EACA,UAAA2jB;AAAA,EACA,OAAAt/B;AACF,GAIG;AACD,QAAMK,wBAAW,IAAA,GACXwJ,IAAU8R,EAAM,OAAO,CAACtL,MACvB20C,GAAiB30C,GAAGrQ,CAAK,IACzBqQ,EAAE,eACHhQ,EAAK,IAAIgQ,EAAE,GAAG,IAAU,MAC5BhQ,EAAK,IAAIgQ,EAAE,GAAG,GACP,MAHqB,KADY,EAKzC;AACD,SAAKxG,EAAQ,SAEX,gBAAAjH,EAAC,SAAI,WAAU,wBACZ,YAAQ,IAAI,CAACyN,MACZ,gBAAAzN,EAACsiD,IAAA,EAAqC,MAAM70C,GAAG,UAAAivB,KAAjC,GAAGjvB,EAAE,GAAG,IAAIA,EAAE,MAAM,EAAiC,CACpE,EAAA,CACH,IAN0B,gBAAA3H,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA;AAAA,IAAA;AAAA,IAAiB1I;AAAA,IAAM;AAAA,EAAA,GAAE;AAQ1F;AAGA,SAASklD,GAAQ;AAAA,EACf,MAAM70C;AAAA,EACN,UAAAivB;AACF,GAGG;AACD,SACE,gBAAA52B,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,wBAAuB,SAAS,MAAM42B,EAASjvB,CAAC,GAC9E,UAAA;AAAA,IAAA,gBAAAzN,EAAC2tC,IAAA,EAAa,MAAMlgC,EAAE,MAAM,MAAM,IAAI;AAAA,IACtC,gBAAA3H,EAAC,QAAA,EAAK,WAAU,6BACd,UAAA;AAAA,MAAA,gBAAA9F,EAAC,YAAQ,UAAAyN,EAAE,eAAeA,EAAE,cAAcA,EAAE,OAAM;AAAA,MAClD,gBAAA3H,EAAC,QAAA,EAAK,WAAU,uBACb,UAAA;AAAA,QAAA2H,EAAE;AAAA,QACF,CAACA,EAAE,gBAAgB,MAAMA,EAAE,MAAM;AAAA,MAAA,EAAA,CACpC;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAmBA,SAASs0C,GAAa;AAAA,EACpB,OAAA3kD;AAAA,EACA,UAAAs/B;AAAA,EACA,aAAAh7B;AAAA,EACA,OAAA9B;AAAA,EACA,YAAAggD;AAAA,EACA,SAAAC;AACF,GAOG;;AACD,QAAMx/C,IAAMG,GAAA,GACNuY,IAAQnc,GAAe,OAAO,CAAC6Q,MAAMA,EAAE,UAAU,aAAa20C,GAAiB30C,GAAGrQ,CAAK,CAAC,GACxF,CAACmlD,GAAWC,CAAY,IAAIvjD,EAAS,EAAK,GAG1Cy+B,IAAO2jB,GAAc,CAAA,GAAIzB,GAAY,QAAWC,GAAS,EAAE,eAAe,IAAM;AAEtF,MAAI0C;AACF,WACE,gBAAAz8C,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAA9F;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAMwiD,EAAa,EAAK;AAAA,UAClC,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAGD,gBAAAxiD;AAAA,QAACyB;AAAA,QAAA;AAAA,UACC,aAAAC;AAAA,UACA,OAAA9B;AAAA,UACA,QAAQggD;AAAA,UACR,KAAKC,IAAU,CAAC,GAAGA,CAAO,IAAI;AAAA,UAC9B,aAAW;AAAA,UACX,QAAQ;AAAA,UACR,aAAaziD;AAAA,UACb,cAAa;AAAA,QAAA;AAAA,MAAA;AAAA,IACf,GACF;AAOJ,QAAMqlD,IAHO/kB,EAAK,KACf,OAAO,CAACxmC,OAAOA,EAAE,gBAAgB,KAAK,KAAKirD,GAAmB/kD,GAAOlG,EAAE,aAAaA,EAAE,EAAE,CAAC,EACzF,KAAKwrD,GAAQ,CAACxrD,MAAkBA,EAAE,WAAW,CAAC,EACd,IAAI,CAACA,MACtC,gBAAA8I,EAAC2iD,IAAA,EAAkB,KAAKzrD,GAAG,OAAA0I,GAAc,UAAU8B,EAAA,GAAtCxK,EAAE,EAAiD,CACjE;AACD,EAAIwmC,EAAK,YACP+kB,EAAS;AAAA,IACP,gBAAAziD;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS09B,EAAK;AAAA,QACf,UAAA;AAAA,MAAA;AAAA,MAJK;AAAA,IAAA;AAAA,EAMN;AAGJ,MAAIklB;AACJ,SAAIllB,EAAK,UAAU,UACjBklB,IAAW,gBAAA5iD,EAAC,OAAA,EAAI,WAAU,wBAAwB,YAAK,OAAM,IACpD09B,EAAK,UAAU,YACxBklB,IAAW,gBAAA5iD,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,YAAQ,IAC7C5C,EAAM,KAAA,OAAU5D,IAAAkkC,EAAK,WAAL,QAAAlkC,EAAa,WAAU,OAAO6G,EAAI,gBAAiB,aAC5EuiD,IACE,gBAAA5iD;AAAA,IAACyB;AAAA,IAAA;AAAA,MACC,QAAQ;AAAA,MACR,aAAarE;AAAA,MACb,KAAKsgC,EAAK;AAAA,MACV,aAAW;AAAA,MACX,QAAQkiB;AAAA,MACR,aAAAl+C;AAAA,MACA,OAAA9B;AAAA,IAAA;AAAA,EAAA,IAGK6iD,EAAS,WAAW,IAC7BG,IACE,gBAAA98C,EAAC,KAAA,EAAE,WAAU,4CACV,UAAA;AAAA,IAAA1I,EAAM,KAAA,IACH,4BAA4BA,CAAK,OACjC;AAAA,IAAuC;AAAA,IAAI;AAAA,IAC7C;AAAA,IACF,gBAAA4C,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,eAAc,SAAS,MAAMwiD,EAAa,EAAI,GAAG,UAAA,kBAAA,CAEjF;AAAA,EAAA,GACF,IAGFI,IAAW,gBAAA5iD,EAAC,OAAA,EAAI,WAAU,+CAA+C,UAAAyiD,GAAS,GAGlF,gBAAA38C,EAAC,OAAA,EAAI,WAAU,sBACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,kBAAiB,aAAW,GACzC,UAAA;AAAA,MAAA,gBAAAA,EAAC,WAAA,EAAQ,WAAU,sBAAqB,YAAS,aAC/C,UAAA;AAAA,QAAA,gBAAA9F,EAAC,MAAA,EAAG,WAAU,0BAAyB,UAAA,aAAS;AAAA,QAC/C4iD;AAAA,MAAA,GACH;AAAA,MACA,gBAAA5iD,EAAC,SAAI,WAAU,wBACb,4BAAC,WAAA,EAAQ,WAAU,sBAAqB,YAAS,YAC/C,UAAA;AAAA,QAAA,gBAAAA,EAAC,MAAA,EAAG,WAAU,0BAAyB,UAAA,YAAQ;AAAA,QAC/C,gBAAA8F,EAAC,OAAA,EAAI,WAAU,+CACZ,UAAA;AAAA,UAAAiT,EAAM,WAAW,KAChB,gBAAAjT,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA;AAAA,YAAA;AAAA,YAA6B1I;AAAA,YAAM;AAAA,UAAA,GAAE;AAAA,UAEzE2b,EAAM,IAAI,CAACtL,MACV,gBAAAzN,EAACsiD,MAAqC,MAAM70C,GAAG,UAAAivB,EAAA,GAAjC,GAAGjvB,EAAE,GAAG,IAAIA,EAAE,MAAM,EAAiC,CACpE;AAAA,QAAA,EAAA,CACH;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,IAAA,GACF;AAAA,sBACC,OAAA,EAAI,WAAU,yBACb,UAAA,gBAAAzN,EAAC,YAAO,MAAK,UAAS,WAAU,WAAU,SAAS,MAAMwiD,EAAa,EAAI,GAAG,6BAE7E,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAGA,SAASR,GAAa;AAAA,EACpB,UAAAtlB;AAAA,EACA,OAAAt/B;AACF,GAAiE;AAC/D,QAAM2b,IAAQnc,GAAe,OAAO,CAAC6Q,MAAMA,EAAE,UAAU,aAAa,CAACA,EAAE,MAAM;AAC7E,SACE,gBAAA3H,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAA9F,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,4FAEnC;AAAA,IACA,gBAAAA,EAACqiD,IAAA,EAAS,OAAAtpC,GAAc,UAAA2jB,GAAoB,OAAAt/B,EAAA,CAAc;AAAA,EAAA,GAC5D;AAEJ;AAGA,SAAS8kD,GAAc;AAAA,EACrB,UAAAxlB;AAAA,EACA,OAAAt/B;AACF,GAAiE;AAC/D,QAAM2b,IAAQnc,GAAe;AAAA,IAC3B,CAAC6Q,MACCA,EAAE,UAAU,aACZA,EAAE,UAAU,aACZA,EAAE,QAAQnV,MACVmV,EAAE,QAAQ5U,MACV4U,EAAE,QAAQxU,MACV,CAACwU,EAAE;AAAA,EAAA;AAEP,SACE,gBAAA3H,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAA9F,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,qGAGnC;AAAA,IACA,gBAAAA,EAACqiD,IAAA,EAAS,OAAAtpC,GAAc,UAAA2jB,GAAoB,OAAAt/B,EAAA,CAAc;AAAA,EAAA,GAC5D;AAEJ;AAGA,SAAS6kD,GAAS;AAAA,EAChB,UAAAvlB;AAAA,EACA,OAAAt/B;AACF,GAAiE;AAC/D,QAAM2b,IAAQnc,GAAe;AAAA,IAC3B,CAAC6Q,OAAOA,EAAE,QAAQnV,MAAYmV,EAAE,QAAQxU,MAAawU,EAAE,QAAQ5U,OAAiB,CAAC4U,EAAE;AAAA,EAAA;AAErF,SACE,gBAAA3H,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,gBAAA9F,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,iFAEnC;AAAA,IACA,gBAAAA,EAACqiD,IAAA,EAAS,OAAAtpC,GAAc,UAAA2jB,GAAoB,OAAAt/B,EAAA,CAAc;AAAA,EAAA,GAC5D;AAEJ;AAOO,SAASokD,GAAkB;AAAA,EAChC,MAAMqB;AAAA,EACN,OAAAzD;AAAA,EACA,SAAA/jC;AAAA,EACA,QAAAynC;AAAA,EACA,eAAAzD;AAAA,EACA,YAAAY;AAAA,EACA,YAAAn/C;AAAA,EACA,eAAA87C,IAAgB,CAAA;AAAA,EAChB,MAAA92B;AACF,GAgBG;AACD,QAAM,CAAC1b,GAAM24C,CAAO,IAAI9jD,EAAS4jD,CAAW,GACtC7U,IAAU6U,EAAY,eACxBjmD,GAAe,OAAO,CAAComD,MAAcA,EAAU,QAAQH,EAAY,OAAO,CAACG,EAAU,MAAM,IAC3F,CAAA,GACE,CAACC,GAAYC,CAAa,IAAIjkD;AAAA,IAAkC,MACpEjC,GAAqBoN,EAAK,KAAKA,EAAK,MAAM;AAAA,EAAA,GAItC+4C,IAAW,CAAC1oD,GAAa2P,EAAK,GAAG,GAOjCq0C,IAAcF,GAAez9C,KAAc,IAAI87C,GAAeuG,KAAY,CAAC,CAACriD,CAAU,GACtF4W,IAAiBmlC,GAAoB4B,GAAazB,GAAmBl3B,CAAI,CAAC,GAC1E,CAAC66B,GAAKC,CAAM,IAAI3hD,EAA+B,WAAW,GAC1D,CAACmkD,GAAYC,CAAa,IAAIpkD,EAAqB,OAAO,GAE1D,CAACqkD,GAAUC,CAAW,IAAItkD,EAAS,IAAI,GACvC,CAACukD,GAAaC,CAAc,IAAIxkD,EAAqB,CAAA,CAAE,GACvDykD,IAAiBhb,GAAqBt+B,EAAK,QAAQ64C,CAAU,GAM7D,CAACU,GAAaC,CAAc,IAAI3kD,EAAwB,IAAI,GAC5D4kD,IAAY,OAAkB;AAAA,IAClC,MAAM,EAAE,KAAKz5C,EAAK,KAAK,QAAQA,EAAK,OAAA;AAAA,IACpC,MAAM64C;AAAA,IACN,GAAGO;AAAA,EAAA;AAML,EAAAtkD,GAAU,MAAM;AACd,QAAI,CAACmgD,EAAe;AACpB,UAAM1lD,IAAKylD,EAAMyE,GAAW;AAC5B,IAAIlqD,OAAmBA,CAAE,GACrBA,KAAMyQ,EAAK,QAAQ3R,sBAA0BkB;AAAA,EACnD,GAAG,CAAA,CAAE,GAKLuF,GAAU,MAAM;AACd,IAAI,CAACmgD,KAAiBsE,MAAgB,QACtCtE,EAAcsE,GAAaE,GAAW;AAAA,EACxC,GAAG,CAACF,GAAaV,GAAYO,GAAap5C,CAAI,CAAC;AAE/C,QAAM05C,IAAmB,CAAC/oD,MAAkB;AAC1C,IAAIA,MAAM,UAAQwoD,EAAY5K,GAAWkL,EAAA,CAAW,CAAC,GACrDR,EAActoD,CAAC;AAAA,EACjB,GACMk7B,IAAM,MAAMmpB,EAAMyE,GAAW;AAEnC,SACE,gBAAA/9C,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAA9F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAW,aAAa2gD,MAAQ,cAAc,YAAY,EAAE;AAAA,YAC5D,SAAS,MAAMC,EAAO,WAAW;AAAA,YAClC,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGAuC,KACC,gBAAAnjD;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,UAAU,CAAC0jD;AAAA,YACX,OAAOA,IAAiB,SAAY;AAAA,YACpC,WAAW,aAAa/C,MAAQ,SAAS,YAAY,EAAE;AAAA,YACvD,SAAS,MAAM+C,KAAkB9C,EAAO,MAAM;AAAA,YAC/C,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,GAEJ;AAAA,MACA,gBAAA5gD;AAAA,QAAC++C;AAAA,QAAA;AAAA,UACC,MAAMqE;AAAA,UACN,YAAYznB,GAAsBsnB,CAAU;AAAA,UAC5C,UAAUa;AAAA,UACV,UAAUnD,MAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACpB,GACF;AAAA,IAEA,gBAAA76C,EAAC,OAAA,EAAI,WAAU,uBACZ,UAAA;AAAA,MAAA66C,MAAQ,eAAeyC,MAAe,WAAWpV,EAAQ,SAAS,KACjE,gBAAAloC,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,SAAA,CAAM;AAAA,QACZ,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,cAAW;AAAA,YACX,OAAOoK,EAAK;AAAA,YACZ,UAAU,CAAC2G,MAAU;AACnB,oBAAMpM,IAAOqpC,EAAQ,KAAK,CAACgV,MAAcA,EAAU,WAAWjyC,EAAM,OAAO,KAAK;AAChF,kBAAI,CAACpM,EAAM;AACX,oBAAMo/C,IAAW/mD,GAAqB2H,EAAK,KAAKA,EAAK,MAAM;AAC3D,cAAAu+C;AAAA,gBACE,OAAO;AAAA,kBACLv+C,EAAK,OAAO;AAAA,oBAAQ,CAACynB,MACnBA,EAAM,OAAO62B,IACT,CAAC,CAAC72B,EAAM,KAAK62B,EAAW72B,EAAM,GAAG,CAAC,CAAC,IACnCA,EAAM,OAAO23B,IACX,CAAC,CAAC33B,EAAM,KAAK23B,EAAS33B,EAAM,GAAG,CAAC,CAAC,IACjC,CAAA;AAAA,kBAAC;AAAA,gBACT;AAAA,cACF,GAEF22B,EAAQp+C,CAAI;AAAA,YACd;AAAA,YAEC,UAAAqpC,EAAQ,IAAI,CAACzyC,MACZ,gBAAAyE,EAAC,UAAA,EAA2B,OAAOzE,EAAO,QACvC,UAAAA,EAAO,MAAA,GADGA,EAAO,MAEpB,CACD;AAAA,UAAA;AAAA,QAAA;AAAA,MACH,GACF;AAAA,MAEDolD,MAAQ,gBACNyC,MAAe,UACdh5C,EAAK,QAAQhR,KACX,gBAAA4G,EAAC,KAAA,EAAE,WAAU,uBAAuB,UAAA3G,GAAA,CAAiB,IACnD+Q,EAAK,WAAW,UAAU3P,GAAa2P,EAAK,GAAG,IACjD,gBAAApK,EAACupC,IAAA,EAAW,QAAQ0Z,GAAY,UAAUC,EAAA,CAAe,IACvD94C,EAAK,WAAW,QAAQ3P,GAAa2P,EAAK,GAAG,IAC/C,gBAAApK,EAAC25B,IAAA,EAAgB,QAAQspB,GAAY,UAAUC,EAAA,CAAe,IAC5D94C,EAAK,QAAQlR,KACf,gBAAA8G,EAAC0hC,IAAA,EAAW,QAAQuhB,GAAY,UAAUC,EAAA,CAAe,IACvD94C,EAAK,QAAQjR,KACf,gBAAA6G,EAAC0gC,IAAA,EAAa,QAAQuiB,GAAY,UAAUC,GAAe,IAE3D,gBAAAljD,EAACgxB,IAAA,EAAW,QAAQ5mB,EAAK,QAAQ,QAAQ64C,GAAY,UAAUC,EAAA,CAAe,IAE9EE,MAAe;AAAA;AAAA;AAAA,QAGjB,gBAAApjD;AAAA,UAACgS;AAAA,UAAA;AAAA,YACC,OAAOsxC;AAAA,YACP,UAAU,MAAM;AAAA,YAAC;AAAA,YACjB,UAAQ;AAAA,YACR,WAAU;AAAA,YACV,QAAO;AAAA,YACP,cAAW;AAAA,YACX,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,UAERF,MAAe,gBACjB,gBAAApjD,EAAC+7B,IAAA,EAAmB,QAAQknB,GAAY,UAAUC,GAAe,IAEjE,gBAAAljD;AAAA,QAACq7B;AAAA,QAAA;AAAA,UACC,QAAQmoB;AAAA,UACR,UAAUC;AAAA,UAGV,iBAAiB,CAAC/oD,GAAa0P,EAAK,GAAG;AAAA,UAGvC,eAAe,CAAC3P,GAAa2P,EAAK,GAAG,KAAKA,EAAK,QAAQxR;AAAA,QAAA;AAAA,MAAA;AAAA,MAG5D+nD,MAAQ,UACPwC,MACCzoD,GAAa0P,EAAK,GAAG,IACpB,gBAAApK,EAACmnC,IAAA,EAAgB,KAAK/8B,EAAK,KAAK,QAAQA,EAAK,QAAQ,QAAQ64C,EAAW,QAAQ,IAEhF,gBAAAjjD;AAAA,QAACgkD;AAAA,QAAA;AAAA,UACC,KAAK55C,EAAK;AAAA,UACV,QAAQA,EAAK;AAAA,UACb,QAAQ64C;AAAA,UACR,QAAQS;AAAA,UACR,OAAOhsC;AAAA,QAAA;AAAA,MAAA;AAAA,IACT,GAEN;AAAA,IAGA,gBAAA5R,EAAC,OAAA,EAAI,WAAU,2CACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,YAAO,MAAK,UAAS,WAAU,yBAAwB,SAASqb,GAAS,UAAA,SAAA,CAE1E;AAAA,MACCslC,MAAQ,eAAewC,IACtB,gBAAAnjD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,CAAC0jD;AAAA,UACX,SAAS,MAAM9C,EAAO,MAAM;AAAA,UAC7B,UAAA;AAAA,QAAA;AAAA,MAAA,IAID,gBAAA5gD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS2jD,MAAgB,OAAQb,KAAUznC,IAAW4a;AAAA,UAErD,UAAA0tB,MAAgB,OAAO,SAAS;AAAA,QAAA;AAAA,MAAA;AAAA,IACnC,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;AAmBA,SAAS7B,GAAa;AAAA,EACpB,QAAAmC;AAAA,EACA,OAAA7mD;AAAA,EACA,YAAA8mD;AAAA,EACA,UAAAxnB;AACF,GAMG;AACD,QAAMr8B,IAAMG,GAAA,GACN,CAACg2B,GAAO2tB,CAAQ,IAAIllD,EAA0D,IAAI,GAClF,CAAC+d,GAAOmM,CAAQ,IAAIlqB,EAAwB,IAAI,GAChDoqB,IAAO46B,MAAW,aAAa,cAAc;AAEnD,EAAA/kD,GAAU,MAAM;AACd,QAAIkE,IAAW;AAEf,YADU6gD,MAAW,aAAa5jD,EAAI,cAAA,IAAkBA,EAAI,cAAA,GAC1D,KAAK,CAAC5G,MAAM,CAAC2J,KAAY+gD,EAAS1qD,CAAC,CAAC,EAAE;AAAA,MACtC,CAAC4J,MAAM,CAACD,KAAY+lB,EAAU9lB,EAAY,OAAO;AAAA,IAAA,GAE5C,MAAM;AACX,MAAAD,IAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAK4jD,CAAM,CAAC;AAKhB,QAAM5+C,IAAO,CAACC,wBAAqB,OAAA,EAAI,WAAU,sBAAsB,UAAAA,GAAK;AAE5E,MAAI0X,UAAc3X,EAAK,gBAAArF,EAAC,SAAI,WAAU,wBAAwB,aAAM,CAAM;AAC1E,MAAIw2B,MAAU;AACZ,WAAOnxB,EAAK,gBAAAS,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA;AAAA,MAAA;AAAA,MAASujB,EAAK,YAAA;AAAA,MAAc;AAAA,IAAA,EAAA,CAAC,CAAI;AAElF,MAAImN,EAAM,WAAW;AACnB,WAAOnxB,EAAK,gBAAAS,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA;AAAA,MAAA;AAAA,MAAIujB,EAAK,YAAA;AAAA,MAAc;AAAA,IAAA,EAAA,CAAgB,CAAI;AAK5F,QAAM3Z,IAAQ00C,IACRr9C,IAAI3J,EAAM,KAAA,EAAO,YAAA,GACjB0J,IAASu9C,GAAW7tB,GAAO0tB,CAAU,EAAE,KAAKxB,GAAQhzC,CAAK,CAAC,GAC1DzI,IAAUF,IACZD,EAAO,OAAO,CAAC8vB,MAAOlnB,EAAMknB,CAAE,EAAE,YAAA,EAAc,SAAS7vB,CAAC,KAAK6vB,EAAG,GAAG,cAAc,SAAS7vB,CAAC,CAAC,IAC5FD;AAEJ,SAAOzB;AAAA,IACL,gBAAArF,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAAiH,EAAQ,WAAW,IAClB,gBAAAnB,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA;AAAA,MAAA;AAAA,MAC7BujB,EAAK,YAAA;AAAA,MAAc;AAAA,MAASjsB;AAAA,MAAM;AAAA,IAAA,GACxC,IAEA,gBAAA4C,EAAC,OAAA,EAAI,WAAU,+CAIZ,UAAAiH,EAAQ,IAAI,CAAC2vB,wBACX0tB,IAAA,EAAwB,QAAAL,GAAgB,MAAMrtB,GAAI,UAAA8F,EAAA,GAAjC9F,EAAG,EAAkD,CACxE,GACH,EAAA,CAEJ;AAAA,EAAA;AAEJ;AASA,MAAM2tB,KAAyC,CAAC,UAAU,UAAU,WAAW,MAAM;AAE9E,SAASC,GAAgBrT,GAAmC;;AACjE,QAAM53C,KAAQ43C,EAAG,SAASA,EAAG,SAAS,CAAA,GAAI,KAAK,CAACjxC,MAAMxF,GAAawF,EAAE,KAAK,GAAG,CAAC,GACxE6I,KAAMvP,IAAAD,KAAA,gBAAAA,EAAM,SAAN,gBAAAC,EAAY;AACxB,MAAI,CAAC,MAAM,QAAQuP,CAAG,UAAU,CAAA;AAChC,QAAM5N,IAAqB,CAAA;AAC3B,aAAWknB,KAAQtZ,GAAK;AACtB,QAAI,OAAOsZ,KAAS,YAAYA,MAAS,KAAM;AAC/C,UAAM0N,IAAM1N,GACN9K,IAAM,OAAOwY,EAAI,OAAQ,WAAWA,EAAI,MAAM;AACpD,QAAI,CAACxY,EAAK;AACV,UAAM4f,IAAO,OAAOpH,EAAI,QAAS,WAAWA,EAAI,OAAO;AACvD,IAAA50B,EAAI,KAAK;AAAA,MACP,KAAAoc;AAAA,MACA,OAAOA;AAAA,MACP,MAAOgtC,GAAoB,SAASptB,CAAI,IAAIA,IAAO;AAAA,MACnD,SAASpH,EAAI;AAAA,MACb,UAAU,EAAQA,EAAI;AAAA,IAAQ,CAC/B;AAAA,EACH;AACA,SAAO50B;AACT;AAcO,SAASomD,GAAmB;AAAA,EACjC,QAAA0C;AAAA,EACA,UAAAQ;AAAA,EACA,aAAAC;AAAA,EACA,OAAAtF;AAAA,EACA,SAAA/jC;AAAA,EACA,QAAAynC;AAAA,EACA,eAAAzD;AACF,GAWG;AACD,QAAMh/C,IAAMG,GAAA,GACN,CAAC+d,GAAQomC,CAAS,IAAI1lD,EAA+B,IAAI,GACzD,CAAC2lD,GAAaC,CAAc,IAAI5lD,EAAwB,IAAI,GAC5D,CAAC2mB,GAAQk/B,CAAS,IAAI7lD,EAAkC,CAAA,CAAE,GAC1D,CAAC8lD,GAAMC,CAAO,IAAI/lD,EAAS,EAAI,GAC/B,CAAC0hD,GAAKC,CAAM,IAAI3hD,EAA+B,WAAW,GAG1D,CAAC0kD,GAAaC,CAAc,IAAI3kD,EAAwB,IAAI;AAIlE,EAAAC,GAAU,MAAM;AACd,QAAIkE,IAAW;AACf,WAAAuhD,EAAU,IAAI,GACdE,EAAe,IAAI,IAEjBZ,MAAW,aACP5jD,EAAI,YAAYokD,CAAQ,EAAE,KAAK,CAACj2C,MAAMA,EAAE,MAAM,IAC9CnO,EAAI,YAAYokD,CAAQ,EAAE,KAAKD,EAAe,GAClD,KAAK,CAAC/lC,MAAM,CAACrb,KAAYuhD,EAAUlmC,CAAC,CAAC,EAAE;AAAA,MACvC,CAACpb,MAAM,CAACD,KAAYyhD,EAAgBxhD,EAAY,OAAO;AAAA,IAAA,GAElD,MAAM;AACX,MAAAD,IAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAK4jD,GAAQQ,CAAQ,CAAC;AAE1B,QAAMf,IAAiBnlC,MAAW,QAAQmqB,GAAqBnqB,GAAQqH,CAAM,GAEvEi+B,IAAY,OAAkB;AAAA,IAClC,MAAM,EAAE,KAAKjrD,IAAU,QAAQ,OAAA;AAAA,IAC/B,MAAM,EAAE,YAAYqrD,GAAQ,UAAAQ,GAAU,QAAA7+B,GAAQ,MAAAm/B,EAAA;AAAA,EAAK;AASrD,EAAA7lD,GAAU,MAAM;AACd,QAAI,CAACmgD,EAAe;AACpB,UAAM1lD,IAAKylD,EAAMyE,GAAW;AAC5B,IAAIlqD,OAAmBA,CAAE;AAAA,EAC3B,GAAG,CAAA,CAAE,GAILuF,GAAU,MAAM;AACd,IAAI,CAACmgD,KAAiBsE,MAAgB,QACtCtE,EAAcsE,GAAaE,GAAW;AAAA,EACxC,GAAG,CAACF,GAAa/9B,GAAQm/B,CAAI,CAAC;AAE9B,QAAM9uB,IAAM,MAAMmpB,EAAMyE,GAAW;AAEnC,SACE,gBAAA/9C,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,IAAA,gBAAA9F,EAAC,SAAI,WAAU,eACb,UAAA,gBAAA8F,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAA9F;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAW,aAAa2gD,MAAQ,cAAc,YAAY,EAAE;AAAA,UAC5D,SAAS,MAAMC,EAAO,WAAW;AAAA,UAClC,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAGD,gBAAA5gD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU,CAAC0jD;AAAA,UACX,OAAOA,IAAiB,SAAY;AAAA,UACpC,WAAW,aAAa/C,MAAQ,SAAS,YAAY,EAAE;AAAA,UACvD,SAAS,MAAM+C,KAAkB9C,EAAO,MAAM;AAAA,UAC/C,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,EAAA,CACF,EAAA,CACF;AAAA,IAEA,gBAAA5gD,EAAC,SAAI,WAAU,uBACZ,gBAAQ,cACP,gBAAA8F,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,MAAA8+C,IACC,gBAAA5kD,EAAC,OAAA,EAAI,WAAU,wBAAwB,UAAA4kD,EAAA,CAAY,IACjDrmC,MAAW,OACb,gBAAAzY,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA;AAAA,QAAA;AAAA,QAAS4+C;AAAA,QAAY;AAAA,MAAA,GAAU,IAChEnmC,EAAO,WAAW,IACpB,gBAAAzY,EAAC,KAAA,EAAE,WAAU,uBACV,UAAA;AAAA,QAAA4+C;AAAA,QAAY;AAAA,MAAA,EAAA,CACf,sBAEC1zB,IAAA,EAAW,QAAQzS,GAAQ,QAAQqH,GAAQ,UAAUk/B,GAAW;AAAA,MAEnE,gBAAAh/C,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,QAAA,gBAAAA,EAAC,QAAA,EACC,UAAA;AAAA,UAAA,gBAAA9F,EAAC,SAAA,EAAM,MAAK,YAAW,SAAS+kD,GAAM,UAAU,CAAC1hD,MAAM2hD,EAAQ3hD,EAAE,OAAO,OAAO,EAAA,CAAG;AAAA,UAAG;AAAA,UAAI;AAAA,QAAA,GAE3F;AAAA,QACA,gBAAArD,EAAC,QAAA,EAAK,WAAU,YAAW,UAAA,qGAAA,CAG3B;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,EAAA,CACF,IAEA,gBAAAA;AAAA,MAACilD;AAAA,MAAA;AAAA,QACC,QAAAhB;AAAA,QACA,UAAAQ;AAAA,QACA,QAAA7+B;AAAA,QACA,QAAQ89B;AAAA,MAAA;AAAA,IAAA,GAGd;AAAA,IAGA,gBAAA59C,EAAC,OAAA,EAAI,WAAU,2CACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,YAAO,MAAK,UAAS,WAAU,yBAAwB,SAASqb,GAAS,UAAA,SAAA,CAE1E;AAAA,MACCslC,MAAQ,cACP,gBAAA3gD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,CAAC0jD;AAAA,UACX,SAAS,MAAM9C,EAAO,MAAM;AAAA,UAC7B,UAAA;AAAA,QAAA;AAAA,MAAA,IAID,gBAAA5gD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS2jD,MAAgB,OAAQb,KAAUznC,IAAW4a;AAAA,UAErD,UAAA0tB,MAAgB,OAAO,SAAS;AAAA,QAAA;AAAA,MAAA;AAAA,IACnC,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;AAUA,SAASsB,GAAgB;AAAA,EACvB,QAAAhB;AAAA,EACA,UAAAQ;AAAA,EACA,QAAA7+B;AAAA,EACA,QAAA6iB;AACF,GAKG;AACD,QAAMpoC,IAAMG,GAAA,GACN,CAAC5C,GAAOksB,CAAQ,IAAI7qB,EAKxB,IAAI,GAEAqP,IAAM,YAAY;AACtB,QAAI,GAACm6B,MAAU7qC,KAAA,gBAAAA,EAAO,YAAW,YACjC;AAAA,MAAAksB,EAAS,EAAE,QAAQ,WAAW;AAC9B,UAAI;AACF,YAAIm6B,MAAW,YAAY;AACzB,gBAAMjL,IAAS,MAAM34C,EAAI,eAAeokD,GAAU7+B,CAAM;AACxD,UAAAkE,EAAS,EAAE,QAAQ,QAAQ,QAAAkvB,GAAQ,UAAU,IAAM;AAAA,QACrD,OAAO;AACL,gBAAMv/C,IAAI,MAAM4G,EAAI,YAAYokD,GAAU,EAAE,OAAO7+B,GAAQ;AAC3D,UAAAkE,EAAS;AAAA,YACP,QAAQ;AAAA,YACR,QAAQrwB,EAAE;AAAA,YACV,OAAOA,EAAE;AAAA,YACT,UAAUA,EAAE;AAAA,YACZ,OAAOA,EAAE;AAAA,UAAA,CACV;AAAA,QACH;AAAA,MACF,SAAS4J,GAAG;AACV,QAAAymB,EAAS,EAAE,QAAQ,SAAS,OAAQzmB,EAA2B,WAAW,OAAOA,CAAC,GAAG;AAAA,MACvF;AAAA;AAAA,EACF;AAEA,SACE,gBAAAyC,EAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,MAAA,gBAAA9F;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,CAACyoC,MAAU7qC,KAAA,gBAAAA,EAAO,YAAW;AAAA,UACvC,SAAS0Q;AAAA,UAER,WAAA1Q,KAAA,gBAAAA,EAAO,YAAW,YAAY,aAAa;AAAA,QAAA;AAAA,MAAA;AAAA,MAE7C,CAAC6qC,KAAU,gBAAAzoC,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,oCAAA,CAAiC;AAAA,IAAA,GACrF;AAAA,KACCpC,KAAA,gBAAAA,EAAO,YAAW,WAAW,gBAAAoC,EAAC,SAAI,WAAU,wBAAwB,YAAM,MAAA,CAAM;AAAA,KAChFpC,KAAA,gBAAAA,EAAO,YAAW,UAAU,CAACA,EAAM,YAClC,gBAAAkI,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA,iBAAa;AAAA,MAChD,gBAAA8F,EAAC,OAAA,EAAI,WAAU,cAAa,UAAA;AAAA,QAAA;AAAA,QACtB,gBAAA9F,EAAC,QAAA,EAAM,UAAApC,EAAM,MAAA,CAAM;AAAA,QAAO;AAAA,MAAA,EAAA,CAEhC;AAAA,IAAA,GACF;AAAA,KAEDA,KAAA,gBAAAA,EAAO,YAAW,UAAUA,EAAM,YAAYA,EAAM,UAAU,UAC7D,gBAAAkI,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA,cAAU;AAAA,MAC7C,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,EAAE,YAAY,YAAY,WAAW,KAAK,UAAU,QAAQ,QAAQ,EAAA;AAAA,UAE1E,UAAA,KAAK,UAAUpC,EAAM,OAAO,MAAM,CAAC;AAAA,QAAA;AAAA,MAAA;AAAA,IACtC,GACF;AAAA,KAEDA,KAAA,gBAAAA,EAAO,YAAW,UAAUA,EAAM,YAAYA,EAAM,UAAU,UAC7D,gBAAAkI,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA,UAAM;AAAA,wBACxCmjC,IAAA,EAAa,OAAOvlC,EAAM,QAAQ,WAAW,IAAA,CAAK;AAAA,IAAA,EAAA,CACrD;AAAA,EAAA,GAEJ;AAEJ;AASO,SAASsnD,GAAmB93B,GAAgD;AACjF,QAAMjyB,IAA+B,CAAA;AACrC,aAAW8B,KAAKmwB;AACd,IAAI9W,GAAgBrZ,EAAE,OAAO,QAAOA,EAAE,GAAG,IAAIA,EAAE;AAEjD,SAAO9B;AACT;AAgBO,SAASutC,GACdtb,GACAG,GACS;AACT,QAAM43B,IAAkBvpB,GAAsBrO,CAAM;AACpD,MAAI43B,MAAoB,KAAM,QAAO;AACrC,MAAIA,MAAoB,OAAW,QAAO;AAI1C,QAAMp4B,IAAOoD,GAAc/C,CAAM,GAC3BsD,IAAY,CAACnZ,MAAA;;AACjB,WAAA4tC,EAAgB5tC,CAAG,MAAM,SACrB4tC,EAAgB5tC,CAAG,KACnB/d,IAAAuzB,EAAK,KAAK,CAAC9vB,MAAMA,EAAE,QAAQsa,CAAG,MAA9B,gBAAA/d,EAAiC;AAAA,KAEjC4rD,IAAQ,CACZp4B,GACAq4B,GACAC,MAEAt4B,EAAK,MAAM,CAACnnB,MAAS;AAEnB,UAAM5I,IAAIi0B,GAAerrB,GAAMy/C,CAAG;AAIlC,QAAIroD,EAAE,SAAS,UAAW,QAAOmoD,EAAMnoD,EAAE,YAAY,CAAA,GAAIooD,GAAMC,CAAG;AAOlE,QAAIroD,EAAE,SAAS,SAAS;AACtB,YAAMqD,IAAWrD,EAAE,YAAY,CAAA,GACzB20B,IAAezB,GAAc7vB,CAAQ,GACrCilD,IACJ,CAACC,MACD,CAACjuC,MAAyB;AACxB,cAAMua,IAAQF,EAAa,KAAK,CAAC1rB,MAAMA,EAAE,QAAQqR,CAAG;AACpD,eAAKua,IACE0zB,EAAUjuC,CAAG,MAAM,SAAYiuC,EAAUjuC,CAAG,IAAIua,EAAM,UAD1CwzB,EAAI/tC,CAAG;AAAA,MAE5B;AACF,UAAIta,EAAE,QAAQ;AACZ,cAAMwd,IAAO,MAAM,QAAQ4qC,EAAKpoD,EAAE,GAAG,CAAC,IAAKooD,EAAKpoD,EAAE,GAAG,IAAkB,CAAA;AAEvE,eAAIwd,EAAK,WAAW,IAAU,CAACxd,EAAE,WAC1Bwd,EAAK,MAAM,CAACC,MAAQ;AACzB,gBAAM+qC,IAAW/qC,KAAO,CAAA;AACxB,iBAAO0qC,EAAM9kD,GAAUmlD,GAASF,EAAOE,CAAO,CAAC;AAAA,QACjD,CAAC;AAAA,MACH;AACA,YAAMD,IAAaH,EAAKpoD,EAAE,GAAG,KAAK,CAAA;AAClC,aAAOmoD,EAAM9kD,GAAUklD,GAAWD,EAAOC,CAAS,CAAC;AAAA,IACrD;AAEA,QADI,CAACvoD,EAAE,YACH,CAAC+yB,GAAenqB,GAAMy/C,CAAG,EAAG,QAAO;AACvC,UAAMvqD,IAAIsqD,EAAKpoD,EAAE,GAAG,KAAKA,EAAE;AAC3B,WAAuBlC,KAAM,OAAa,KACtC,OAAOA,KAAM,WAAiBA,EAAE,WAAW,KACxC;AAAA,EACT,CAAC;AACH,SAAOqqD,EAAMh4B,GAAQ+3B,GAAiBz0B,CAAS;AACjD;AAYO,SAASg1B,GAAeC,GAA2B;AACxD,QAAMC,IAAQD,KAAA,gBAAAA,EAA2D;AACzE,SAAO,OAAOC,KAAS,YAAYA,IAAO;AAC5C;AAsBA,SAASC,GAAY,GAAqB;AACxC,QAAMpkB,IAAM;AACZ,UAAOA,KAAA,gBAAAA,EAAK,UAAQA,KAAA,gBAAAA,EAAK,QAAO,EAAE,OAAOA,KAAA,gBAAAA,EAAK,MAAM,UAASA,KAAA,gBAAAA,EAAK,YAAW,OAAO,CAAC,EAAA;AACvF;AAEA,SAASqkB,GAAWxgD,GAAgC;AAClD,QAAMioC,IAASjoC,KAAA,gBAAAA,EAAwC;AACvD,SAAO,MAAM,QAAQioC,CAAK,IAAKA,IAA4B,CAAA;AAC7D;AAGA,SAASwY,GAAgB,EAAE,KAAAC,GAAK,SAAA3qC,KAAqD;AACnF,2BACGD,IAAA,EAAM,OAAM,gBAAe,UAAU4qC,EAAI,WAAW,MAAK,QAAO,SAAA3qC,GAC/D,UAAA,gBAAAvV,EAAC,SAAI,WAAU,4BAA2B,OAAO,EAAE,KAAK,MACtD,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA;AAAA,QAAA;AAAA,QACfkgD,EAAI,QAAQ;AAAA,QAAO;AAAA,QAAEA,EAAI,QAAQ;AAAA,MAAA,GACrD;AAAA,wBACC7iB,IAAA,EAAa,OAAO6iB,EAAI,QAAQ,MAAM,WAAW,IAAA,CAAK;AAAA,IAAA,GACzD;AAAA,IACA,gBAAAlgD,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA;AAAA,QAAA;AAAA,QACb;AAAA,QACnBkgD,EAAI,SAAS,KACV,OACA,SAASA,EAAI,SAAS,SAAS,UAAUA,EAAI,SAAS,MAAM,MAAM,EAAE;AAAA,QAAI;AAAA,QAAI;AAAA,QAC7EA,EAAI;AAAA,QAAW;AAAA,MAAA,GACpB;AAAA,wBACC7iB,IAAA,EAAa,OAAO6iB,EAAI,SAAS,MAAM,WAAW,IAAA,CAAK;AAAA,IAAA,GAC1D;AAAA,IACA,gBAAAlgD,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA;AAAA,QAAA;AAAA,QAAqBkgD,EAAI,SAAS;AAAA,QAAO;AAAA,MAAA,GAAC;AAAA,MAC5EA,EAAI,SAAS,SAAS,IACrB,gBAAAhmD,EAACstC,MAAc,OAAO0Y,EAAI,UAAU,OAAO,IAAO,aAAW,GAAA,CAAC,IAE9D,gBAAAlgD,EAAC,OAAA,EAAI,WAAU,uBAAsB,UAAA;AAAA,QAAA;AAAA,QAElCkgD,EAAI,SAAS,KAAK,2BAA2B;AAAA,QAA6B;AAAA,MAAA,EAAA,CAC7E;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;AA8BO,MAAMhC,KAAcppC,GA4BzB,SACA;AAAA,EACE,KAAA5jB;AAAA,EACA,QAAAuE;AAAA,EACA,cAAA6kC;AAAA,EACA,QAAA7S;AAAA,EACA,QAAAkb;AAAA,EACA,eAAAwd;AAAA,EACA,SAAA7e;AAAA,EACA,OAAO8e;AAAA,EACP,cAAAC;AAAA,EACA,UAAAC;AACF,GACAxwC,GACA;AACA,QAAMvV,IAAMG,GAAA,GAGNK,IAAUE,GAAA,GAEVD,IAAaE,GAAA,GACb,CAACpD,GAAOksB,CAAQ,IAAI7qB,EAA2B,IAAI,GACnD,CAAC+mD,GAAKK,CAAM,IAAIpnD,EAA4B,IAAI,GAChD,CAACqnD,GAASC,CAAU,IAAItnD,EAAS,EAAK,GAEtCunD,IAAS1jD,GAAO,EAAK,GAErB,CAAC2jD,GAAYC,CAAa,IAAIznD,EAAwB,IAAI,GAI1DsoC,IAAoBH,KAAA,gBAAAA,EAAS,YAC7BI,IAAgBJ,KAAA,gBAAAA,EAAS,QAEzBphB,IAAW4D,KAAuB,UAClC+8B,IAAanf,IAAgBxhB,KAAA,gBAAAA,EAAWwhB,KAAiB;AAC/D,EAAAtoC,GAAU,MAAM;AACd,QAAI,CAACqoC,KAAqB,CAACC,EAAe;AAC1C,QAAIpkC,IAAW;AACf,WAAA/C,EACG,cAAcknC,GAAmBC,CAAa,EAC9C,KAAK,CAAC/sB,MAAS;AACd,UAAIC;AACJ,iBAAWjhB,KAAKghB;AACd,QAAI,CAAChhB,EAAE,aAAa,CAACA,EAAE,kBACnB,CAACihB,KAAO,KAAK,MAAMjhB,EAAE,SAAS,IAAI,KAAK,MAAMihB,EAAI,SAAmB,OAAGA,IAAMjhB;AAEnF,MAAI,CAACihB,KAAO,CAACA,EAAI,aAAatX,KAAYojD,EAAO,YAC7C9rC,EAAI,kBAAkB,cACxBoP,EAAS;AAAA,QACP,QAAQ;AAAA,QACR,OAAOpP,EAAI;AAAA,QACX,GAAIA,EAAI,cAAc,EAAE,MAAMA,EAAI,YAAA,IAAgB,CAAA;AAAA,MAAC,CACpD,IAEDoP,EAAS;AAAA,QACP,QAAQ;AAAA,QACR,OACE,OAAOpP,EAAI,gBAAiB,WACxBA,EAAI,eACJA,EAAI,gBAAgB,OAClB,gBACA,KAAK,UAAUA,EAAI,YAAY;AAAA,MAAA,CACxC,GAEHgsC,EAAchsC,EAAI,SAAS;AAAA,IAC7B,CAAC,EACA,MAAM,MAAM;AAAA,IAAC,CAAC,GACV,MAAM;AACX,MAAAtX,IAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAKknC,GAAmBC,CAAa,CAAC;AAE1C,QAAMl5B,IAAM,YAAY;;AACtB,QAAI,CAACm6B,MAAU7qC,KAAA,gBAAAA,EAAO,YAAW,UAAW;AAC5C,IAAA4oD,EAAO,UAAU,IACjBE,EAAc,IAAI,GAClB58B,EAAS,EAAE,QAAQ,WAAW,GAC9Bq8B,KAAA,QAAAA,EAAe;AACf,QAAIvd;AACJ,UAAMge,wBAAgB,KAAA,GAChBpiD,IAAiC;AAAA,MACrC,QAAQ;AAAA,MACR,MAAM,SAAS,mBAAmBxN,CAAG,CAAC,YAAY,mBAAmBuE,CAAM,CAAC;AAAA;AAAA,MAE5E,MAAM;AAAA,QACJ,QAAQgyB;AAAA,QACR,GAAI6S,IAAe,EAAE,cAAAA,EAAA,IAAiB,CAAA;AAAA,QACtC,GAAIv/B,IAAU,EAAE,SAAAA,EAAA,IAAY,CAAA;AAAA,QAC5B,GAAIqlD,IAAa,EAAE,OAAOA,EAAA,IAAe,CAAA;AAAA,QACzC,GAAIplD,IAAa,EAAE,YAAAA,MAAe,CAAA;AAAA,MAAC;AAAA,IACrC,GAEI+lD,IAAY,CAACC,MACjBT,EAAO;AAAA,MACL,WAAWO,EAAU,eAAA;AAAA,MACrB,YAAY,KAAK,QAAQA,EAAU,QAAA;AAAA,MACnC,SAAApiD;AAAA,MACA,UAAAsiD;AAAA,MACA,UAAUhB,GAAWgB,EAAS,IAAI;AAAA,IAAA,CACnC;AACH,QAAI;AACF,YAAM3/B,IAAS,MAAM9mB,EAAI,aAAarJ,GAAKuE,GAAQgyB,GAAQ;AAAA,QACzD,GAAI6S,IAAe,EAAE,cAAAA,EAAA,IAAiB,CAAA;AAAA,QACtC,SAAAv/B;AAAA;AAAA;AAAA,QAGA,GAAIqlD,IAAa,EAAE,OAAOA,EAAA,IAAe,CAAA;AAAA,QACzC,GAAIplD,IAAa,EAAE,YAAAA,MAAe,CAAA;AAAA,MAAC,CACpC;AACD,MAAA+lD,EAAU,EAAE,IAAI,IAAM,MAAM1/B,GAAQ,GACpCyhB,IAAU;AAAA,QACR,QAAQ;AAAA,QACR,OAAOzhB,EAAO;AAAA,QACd,MAAOA,EAA+B;AAAA,QACtC,GAAIA,EAAO,OAAO,EAAE,MAAMA,EAAO,KAAA,IAAS,CAAA;AAAA,MAAC;AAAA,IAE/C,SAAS9jB,GAAG;AACV,YAAMo+B,KAAMp+B;AACZ,MAAAwjD,EAAU;AAAA,QACR,IAAI;AAAA,QACJ,GAAI,OAAOplB,GAAI,UAAW,WAAW,EAAE,QAAQA,GAAI,OAAA,IAAW,CAAA;AAAA,QAC9D,MAAMokB,GAAYxiD,CAAC;AAAA,MAAA,CACpB,GACDulC,IAAU;AAAA,QACR,QAAQ;AAAA,QACR,OAAOnH,GAAI,WAAW,OAAOp+B,CAAC;AAAA,QAC9B,WAAWo+B,GAAI;AAAA,QACf,MAAMA,GAAI;AAAA,MAAA;AAAA,IAEd;AAKA,QAJA3X,EAAS8e,CAAO,GAChBwd,KAAA,QAAAA,EAAWxd,EAAQ,WAAW,SAG1BxB,GAAS;AAGX,OAAA5tC,IAAA6G,EACG,kBADH,QAAA7G,EAAA,KAAA6G,GACmB+mC,EAAQ,YAAYA,EAAQ,QAAQhB,GAAkBgB,EAAQ,KAAK,GACnF,MAAM,CAAC3F,MAAQ,QAAQ,MAAM,0BAA0BA,CAAG;AAC7D,UAAI;AACF,cAAMoH,IAAQ,MAAMxoC,EAAI,aAAa+mC,EAAQ,YAAYA,EAAQ,QAAQ;AAAA,UACvE,OAAOA,EAAQ;AAAA,UACf,MAAM7Z;AAAA,QAAA,CACP;AACD,cAAMltB,EAAI,kBAAkB+mC,EAAQ,YAAYA,EAAQ,QAAQ;AAAA,UAC9D,YAAYyB,EAAM;AAAA,UAClB,QAAQD,EAAQ,WAAW,SAAS,cAAc;AAAA,UAClD,OAAOxB,EAAQ;AAAA,UACf,QAAQwB,EAAQ,WAAW,SAASA,EAAQ,QAAQ;AAAA,UACpD,OAAOA,EAAQ,WAAW,UAAUA,EAAQ,QAAQ;AAAA,UACpD,GAAIA,EAAQ,WAAW,UAAUA,EAAQ,OAAO,EAAE,MAAMA,EAAQ,SAAS,CAAA;AAAA,QAAC,CAC3E;AAAA,MACH,SAASnH,GAAK;AACZ,gBAAQ,MAAM,4BAA4BA,CAAG;AAAA,MAC/C;AAAA,IACF;AACA,IAAA0kB,KAAA,QAAAA,EAAe;AAAA,EACjB;AAEA,EAAAY,GAAoBnxC,GAAK,OAAO,EAAE,KAAAtH,EAAA,EAAM;AAExC,QAAMw6B,IAAOlrC,KAASA,EAAM,WAAW,YAAYA,EAAM,OAAO;AAEhE,SACE,gBAAAkI,EAAC,OAAA,EAAI,WAAU,gBACX,UAAA;AAAA,KAAA,CAACmgD,KAAiBD,MAClB,gBAAAlgD,EAAC,OAAA,EAAI,WAAU,oBACZ,UAAA;AAAA,MAAA,CAACmgD,KACA,gBAAAjmD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,CAACyoC,MAAU7qC,KAAA,gBAAAA,EAAO,YAAW;AAAA,UACvC,SAAS0Q;AAAA,UAER,WAAA1Q,KAAA,gBAAAA,EAAO,YAAW,YAAY,aAAa;AAAA,QAAA;AAAA,MAAA;AAAA,MAG/CooD,MAAOpoD,KAAA,gBAAAA,EAAO,YAAW,aACxB,gBAAAkI;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAMygD,EAAW,EAAI;AAAA,UAC9B,OAAM;AAAA,UACP,UAAA;AAAA,YAAA;AAAA,YACKP,EAAI,SAAS,SAAS,IAAI,KAAKA,EAAI,SAAS,MAAM,MAAM;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAG/D,CAACC,KAAiB,CAACxd,uBACjB,QAAA,EAAK,WAAU,uBAAsB,UAAA,oCAAA,CAAiC;AAAA,IAAA,GAE3E;AAAA,IAED6d,KAAWN,KAAO,gBAAAhmD,EAAC+lD,IAAA,EAAgB,KAAAC,GAAU,SAAS,MAAMO,EAAW,EAAK,GAAG;AAAA,IAC/EE,OAAe7oD,KAAA,gBAAAA,EAAO,YAAW,WAAUA,KAAA,gBAAAA,EAAO,YAAW,YAC5D,gBAAAkI,EAAC,OAAA,EAAI,WAAU,4CAA2C,UAAA;AAAA,MAAA;AAAA,MAC5C,IAAI,KAAK2gD,CAAU,EAAE,eAAA;AAAA,IAAe,GAClD;AAAA,KAED7oD,KAAA,gBAAAA,EAAO,YAAW,WACjB,gBAAAkI,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAA;AAAA,MAAAlI,EAAM,aACL,gBAAAoC,EAAC,OAAA,EAAI,WAAU,aAAY,OAAO,EAAE,SAAS,MAAM,cAAc,KAC/D,UAAA,gBAAAA,EAAC,QAAA,EAAM,UAAApC,EAAM,WAAU,GACzB;AAAA,MAEDA,EAAM;AAAA,IAAA,GACT;AAAA,KAEDA,KAAA,gBAAAA,EAAO,YAAW,UACjB,gBAAAkI,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA,yBAAqB;AAAA,wBACvDmjC,IAAA,EAAa,OAAOvlC,EAAM,OAAO,WAAW,KAAK;AAAA,OAChDA,EAAM,QAAQ+oD,MACd,gBAAA7gD,EAAAwB,IAAA,EACE,UAAA;AAAA,QAAA,gBAAAtH,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA,YAAQ;AAAA,QAC3C,gBAAAA,EAACmjC,IAAA,EAAa,OAAO,EAAE,GAAGwjB,GAAY,GAAG/oD,EAAM,KAAA,GAAQ,WAAW,IAAA,CAAK;AAAA,MAAA,EAAA,CACzE;AAAA,IAAA,GAEJ;AAAA,KAEDA,KAAA,gBAAAA,EAAO,YAAW,WAAUA,KAAA,gBAAAA,EAAO,YAAW,aAAa+oD,KAC1D,gBAAA7gD,EAAC,OAAA,EAAI,WAAU,eAAc,eAAY,wBACvC,UAAA;AAAA,MAAA,gBAAA9F,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA,YAAQ;AAAA,MAC3C,gBAAAA,EAACmjC,IAAA,EAAa,OAAOwjB,GAAY,WAAW,IAAA,CAAK;AAAA,IAAA,GACnD;AAAA,IAED7d,KAAQA,EAAK,SAAS,KACrB,gBAAAhjC,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,OAAA,EAAI,WAAU,qBAAoB,UAAA,kBAAc;AAAA,MACjD,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,EAAE,YAAY,YAAY,WAAW,KAAK,UAAU,QAAQ,QAAQ,EAAA;AAAA,UAE1E,UAAA8oC,EAAK,KAAK;AAAA,CAAI;AAAA,QAAA;AAAA,MAAA;AAAA,IACjB,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ,CAAC,GA8BKke,KAAwB,IAGxBC,yBAAwC,IAAA;AA+CvC,SAAS5F,GACd9B,GACAK,GACAsE,GACArE,GAGAx/B,GACY;AAEZ,QAAM6mC,IAAQrH,KAAWA,EAAQ,SAAS,IAAI,IAAI,IAAIA,CAAO,IAAI,MAC3DsH,IAAU,CAACjwD,OAAmBgwD,IAAQA,EAAM,IAAIhwD,EAAE,EAAE,IAAI,SAAU0oD,KAAA,gBAAAA,EAAa1oD,OAAM,KACrFmJ,IAAMG,GAAA,GACN,CAAC4mD,GAAcC,CAAe,IAAIpoD,EAA0B,IAAI,GAChE,CAACqoD,GAASC,CAAU,IAAItoD,EAA8B,IAAI,GAC1D,CAACuoD,GAAQC,CAAM,IAAIxoD,EAAmC,IAAI,GAC1D,CAACyoD,GAAQC,CAAM,IAAI1oD,EAAmC,IAAI,GAC1D,CAAC+d,GAAOmM,CAAQ,IAAIlqB,EAAwB,IAAI,GAChD,CAACX,GAAUspD,CAAW,IAAI3oD,EAAkC,MAAM,oBAAI,KAAK,GAC3E,CAAC4oD,GAAcC,CAAe,IAAI7oD,EAAsB,MAAM,oBAAI,KAAK,GAIvE,CAAC8oD,GAAaC,CAAc,IAAI/oD,EAA8BgoD,EAAY,GAC1EgB,IAAcnlD,GAA4BmkD,EAAY,GACtDiB,IAAc/jD,GAAY,CAACQ,MAA8B;AAC7D,IAAAsjD,EAAY,UAAUtjD,GACtBqjD,EAAerjD,CAAI;AAAA,EACrB,GAAG,CAAA,CAAE,GAECwjD,IAAerlD,GAA4BmkD,EAAY,GAEvDmB,IAAU7I,EAAU,SAAS,UAAU,GACvC8I,IAAU9I,EAAU,SAAS,UAAU,GACvC+I,IAAU,OAAOjoD,EAAI,iBAAkB;AAE7C,EAAAnB,GAAU,MAAM;AACd,QAAIkE,IAAW;AACf,UAAMmlD,IAAO,CAACllD,MAAe,CAACD,KAAY+lB,EAAU9lB,EAAY,OAAO;AACvE,WAAAhD,EACG,gBAAA,EACA,KAAK,CAACuqC,MAAU;AACf,UAAIxnC,EAAU;AACd,YAAMnF,IAAgB,CAAA,GAChBR,wBAAW,IAAA,GACXm3B,yBAAa,IAAA;AACnB,iBAAW1uB,KAAK0kC;AACd,QAAIpwC,GAAc0L,EAAE,KAAK,MACrBoiD,KAAW,EAACjoC,KAAA,QAAAA,EAAM,kBAAiBna,EAAE,OAAO,CAAC0uB,GAAO,IAAI1uB,EAAE,KAAK,KACjE0uB,GAAO,IAAI1uB,EAAE,OAAO,EAAE,GAAGA,EAAE,KAAK,IAAIA,EAAE,OAAO,GAE3C,CAAAzI,EAAK,IAAIyI,EAAE,KAAK,MACpBzI,EAAK,IAAIyI,EAAE,KAAK,GAChBjI,EAAI,KAAKiI,EAAE,KAAK;AAElB,MAAI0uB,GAAO,OAAO,MAChBuzB,EAAa,UAAU,IAAI,IAAIvzB,GAAO,MAAM,GAC5CgzB,EAAY,CAACrhD,MAAS,IAAI,IAAI,CAAC,GAAGA,GAAM,GAAGquB,EAAM,CAAC,CAAC,GACnDkzB,EAAgB,CAACvhD,MAAS,oBAAI,IAAI,CAAC,GAAGA,GAAM,GAAGquB,GAAO,KAAA,CAAM,CAAC,CAAC,IAEhEyyB,EAAgBppD,CAAG;AAAA,IACrB,CAAC,EACA,MAAMsqD,CAAI,GAGTH,IACF/nD,EACG,cAAA,EACA,KAAK,CAAC5G,MAAM,CAAC2J,KAAYqkD,EAAOhuD,CAAC,CAAC,EAClC,MAAM8uD,CAAI,IACRd,EAAO,EAAE,GACZY,IACFhoD,EACG,cAAA,EACA,KAAK,CAAC5G,MAAM,CAAC2J,KAAYukD,EAAOluD,CAAC,CAAC,EAClC,MAAM8uD,CAAI,IACRZ,EAAO,EAAE,GACT,MAAM;AACX,MAAAvkD,IAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAKioD,GAASF,GAASC,GAAShoC,KAAA,gBAAAA,EAAM,aAAa,CAAC,GAIxDnhB,GAAU,MAAM;AACd,QAAIopD,EAAS;AACb,UAAMnlD,IAAW9C,EAAI;AAKrB,QAAI,OAAO8C,KAAa,YAAY;AAClC,MAAAokD,EAAW,CAAA,CAAE;AACb;AAAA,IACF;AACA,QAAInkD,IAAW;AACf,WAAAD,EAAA,EACG,KAAK,CAAC1J,MAAM,CAAC2J,KAAYmkD,EAAW9tD,CAAC,CAAC,EACtC,MAAM,CAAC4J,MAAM,CAACD,KAAY+lB,EAAU9lB,EAAY,OAAO,CAAC,GACpD,MAAM;AACX,MAAAD,IAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAKioD,CAAO,CAAC;AAIjB,QAAME,IAAa1lD,GAAO,EAAI;AAC9B,EAAA5D,GAAU,OACRspD,EAAW,UAAU,IACd,MAAM;AACX,IAAAA,EAAW,UAAU;AAAA,EACvB,IACC,CAAA,CAAE;AAEL,QAAMC,IAAetkD;AAAA,IACnB,CAAC/F,MAAoB;AACnB,YAAMggC,IAAgB/9B,EAAI;AAC1B,MAAI,CAAC+9B,KAAiBhgC,EAAM,WAAW,KAAK6pD,EAAY,QAAQ,OAAO,MACvEC,EAAY,IAAI,IAAI9pD,CAAK,CAAC,GAC1BggC,EAAchgC,CAAK,EAChB,KAAK,CAACtH,MAAS;AACd,QAAK0xD,EAAW,YAChBN,EAAYjB,EAAY,GAMxBW,EAAY,CAACrhD,MAAS;AACpB,gBAAM5B,IAAO,IAAI,IAAI4B,CAAI;AACzB,qBAAWrP,MAAKJ,EAAM,CAAA6N,EAAK,IAAIzN,GAAE,IAAIA,EAAC;AACtC,iBAAOyN;AAAA,QACT,CAAC,GACDmjD,EAAgB,CAACvhD,MAAS,oBAAI,IAAI,CAAC,GAAGA,GAAM,GAAGnI,CAAK,CAAC,CAAC;AAAA,MACxD,CAAC,EACA,MAAM,CAACiF,MAAMmlD,EAAW,WAAWr/B,EAAU9lB,EAAY,OAAO,CAAC;AAAA,IACtE;AAAA,IACA,CAAChD,GAAK6nD,CAAW;AAAA,EAAA,GAQbQ,IAAuB5lD,GAAO,EAAK;AACzC,EAAA5D,GAAU,MAAM;AACd,QAAI,CAACopD,KAAWlB,MAAiB,QAAQsB,EAAqB,QAAS;AACvE,UAAMtqD,IAAQJ,GAAYopD,GAAce,EAAa,SAASnB,EAAqB;AACnF,IAAI5oD,EAAM,WAAW,MACrBsqD,EAAqB,UAAU,IAC/BD,EAAarqD,CAAK;AAAA,EACpB,GAAG,CAACkqD,GAASlB,GAAcqB,CAAY,CAAC;AAExC,QAAME,IAAe,MAAM;AAEzB,QADI,CAACL,KAAWlB,MAAiB,QAC7Ba,EAAY,QAAQ,OAAO,EAAG;AAClC,UAAMW,wBAAc,IAAI,CAAC,GAAGf,GAAc,GAAGI,EAAY,OAAO,CAAC;AACjE,IAAAQ,EAAazqD,GAAYopD,GAAcwB,GAAS5B,EAAqB,CAAC;AAAA,EACxE;AAEA,MAAIhqC;AACF,WAAO,EAAE,OAAO,SAAS,OAAAA,GAAO,MAAM,CAAA,GAAI,KAAK,CAAA,GAAI,KAAK,CAAA,GAAI,UAAU,IAAO,cAAA2rC,EAAA;AAC/E,MAAInB,MAAW,QAAQE,MAAW;AAChC,WAAO,EAAE,OAAO,WAAW,MAAM,CAAA,GAAI,KAAK,CAAA,GAAI,KAAK,CAAA,GAAI,UAAU,IAAO,cAAAiB,EAAA;AAI1E,QAAME,IAAMxE,GAAWmD,GAAQtD,CAAU,GACnC4E,IAAMzE,GAAWqD,GAAQxD,CAAU;AAEzC,MAAIoE,GAAS;AACX,QAAIlB,MAAiB;AACnB,aAAO,EAAE,OAAO,WAAW,MAAM,CAAA,GAAI,KAAAyB,GAAK,KAAAC,GAAK,UAAU,IAAO,cAAAH,EAAA;AAElE,QAAIvB,EAAa,SAAS,KAAKS,EAAa,SAAS;AACnD,aAAO,EAAE,OAAO,WAAW,MAAM,CAAA,GAAI,KAAAgB,GAAK,KAAAC,GAAK,UAAU,IAAO,cAAAH,EAAA;AAElE,UAAM7xD,IAAOuH,GAAkB+oD,GAAc9oD,CAAQ,EAAE,OAAO6oD,CAAO,GAC/D4B,IACJhB,EAAY,SAAS,KACrB/pD,GAAYopD,GAAc,oBAAI,IAAI,CAAC,GAAGS,GAAc,GAAGE,CAAW,CAAC,GAAG,CAAC,EAAE,SAAS;AAEpF,WAAO;AAAA,MACL,OAFYjxD,EAAK,WAAW,KAAK+xD,EAAI,WAAW,KAAKC,EAAI,WAAW,KAAK,CAACC,IAE3D,UAAU;AAAA,MACzB,MAAAjyD;AAAAA,MACA,QAAQswD,EAAa,OAAO,CAACztD,MAAO,CAACutD,KAASA,EAAM,IAAIvtD,CAAE,CAAC;AAAA,MAC3D,KAAAkvD;AAAA,MACA,KAAAC;AAAA,MACA,UAAAC;AAAA,MACA,cAAAJ;AAAA,IAAA;AAAA,EAEJ;AAEA,MAAIrB,MAAY;AACd,WAAO,EAAE,OAAO,WAAW,MAAM,CAAA,GAAI,KAAAuB,GAAK,KAAAC,GAAK,UAAU,IAAO,cAAAH,EAAA;AAalE,QAAMK,KAAe,IAAI,IAAI5B,KAAgB,CAAA,CAAE,GACzCtwD,KAAOwwD,EAAQ;AAAA,IACnB,CAACpwD,MACC,CAACsD,GAActD,EAAE,EAAE,KAAKiwD,EAAQjwD,CAAC,MAAM8xD,GAAa,IAAI9xD,EAAE,EAAE,KAAKA,EAAE,mBAAmB;AAAA,EAAA;AAG1F,SAAO,EAAE,OADKJ,GAAK,WAAW,KAAK+xD,EAAI,WAAW,KAAKC,EAAI,WAAW,IAC9C,UAAU,SAAS,MAAAhyD,IAAM,KAAA+xD,GAAK,KAAAC,GAAK,UAAU,IAAO,cAAAH,EAAA;AAC9E;AAIO,SAAStE,GACd7tB,GACAv4B,GACK;AACL,SAAOA,KAAOA,EAAI,SAAS,IAAIu4B,EAAM,OAAO,CAACI,MAAO,CAAC34B,EAAI,SAAS24B,EAAG,EAAE,CAAC,IAAI,CAAC,GAAGJ,CAAK;AACvF;AAGA,SAASksB,GAAWhzC,GAAyB;AAC3C,SAAO,CAACxY,GAAMC,MAASuY,EAAMxY,CAAC,EAAE,cAAcwY,EAAMvY,CAAC,GAAG,QAAW,EAAE,aAAa,QAAQ;AAC5F;AAGA,SAASitD,GAAcxtB,GAA+C;AACpE,QAAMqyB,IAAKryB,EAAG;AACd,SAAIqyB,KAAA,QAAAA,EAAI,SAAeA,IAChB,UAAUryB,IAAKA,EAAG,OAAOA,EAAG;AACrC;AAQA,SAAS0tB,GAAY;AAAA,EACnB,QAAAL;AAAA,EACA,MAAA5hC;AAAA,EACA,UAAAqa;AACF,GAIG;AACD,QAAMhtB,IAAQ00C,GAAc/hC,CAAI;AAChC,SACE,gBAAAvc;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,aAAWm+C;AAAA,MACX,SAAS,MAAMvnB,EAAS,EAAE,IAAIra,EAAK,IAAI,OAAA3S,GAAO;AAAA,MAE9C,UAAA;AAAA,QAAA,gBAAA1P,EAAC2tC,MAAa,MAAMiR,GAAeqF,CAAM,GAAG,MAAM,IAAI;AAAA,QACtD,gBAAAn+C,EAAC,QAAA,EAAK,WAAU,6BACd,UAAA;AAAA,UAAA,gBAAA9F,EAAC,YAAQ,UAAA0P,EAAA,CAAM;AAAA,UACf,gBAAA1P,EAAC,QAAA,EAAK,WAAU,uBAAuB,YAAK,GAAA,CAAG;AAAA,QAAA,EAAA,CACjD;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AA+BA,SAASkpD,GAAiBnuC,GAAeN,GAAmB;AAC1D,SAAOA,EAAK,WAAW,IAAI,OACzB,gBAAA3U,EAAC,WAAA,EAAoB,WAAU,sBAC7B,UAAA;AAAA,IAAA,gBAAA9F,EAAC,MAAA,EAAG,WAAU,0BAA0B,UAAA+a,GAAM;AAAA,IAC9C,gBAAA/a,EAAC,OAAA,EAAI,WAAU,+CAA+C,UAAAya,EAAA,CAAK;AAAA,EAAA,EAAA,GAFvDM,CAGd;AAEJ;AAGA,SAAS4nC,GAAO;AAAA,EACd,KAAKzrD;AAAA,EACL,OAAA0I;AAAA,EACA,UAAA88B;AACF,GAIG;AACD,SACE,gBAAA52B;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,aAAU;AAAA,MACV,SAAS,MAAM42B,EAASxlC,CAAC;AAAA,MAEzB,UAAA;AAAA,QAAA,gBAAA8I;AAAA,UAACV;AAAA,UAAA;AAAA,YACC,KAAKpI,EAAE;AAAA,YACP,SAASA,EAAE;AAAA,YACX,YAAYA,EAAE;AAAA,YACd,MAAMA,EAAE;AAAA,YACR,OAAA0I;AAAA,YACA,MAAM;AAAA,UAAA;AAAA,QAAA;AAAA,QAER,gBAAAkG,EAAC,QAAA,EAAK,WAAU,6BACd,UAAA;AAAA,UAAA,gBAAA9F,EAAC,UAAA,EAAQ,YAAE,YAAA,CAAY;AAAA,UACvB,gBAAAA,EAAC,QAAA,EAAK,WAAU,uBAAuB,YAAE,GAAA,CAAG;AAAA,QAAA,EAAA,CAC9C;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,SAAS6hD,GAAe;AAAA,EACtB,MAAAnkB;AAAA,EACA,OAAAtgC;AAAA,EACA,YAAAwiD;AAAA,EACA,aAAAl+C;AAAA,EACA,kBAAAynD;AAAA,EACA,OAAAvpD;AACF,GAOG;;AACD,QAAMS,IAAMG,GAAA,GAIN6E,IAAO,CAACC,wBAAqB,OAAA,EAAI,WAAU,sBAAsB,UAAAA,GAAK;AAE5E,MAAIo4B,EAAK,UAAU;AACjB,WAAOr4B,EAAK,gBAAArF,EAAC,OAAA,EAAI,WAAU,wBAAwB,UAAA09B,EAAK,OAAM,CAAM;AAEtE,MAAIA,EAAK,UAAU,UAAW,QAAOr4B,oBAAM,KAAA,EAAE,WAAU,uBAAsB,UAAA,WAAA,CAAQ,CAAI;AAEzF,QAAMvO,IAAO4mC,EAAK,KACf,OAAO,CAACxmC,MAAMirD,GAAmB/kD,GAAOlG,EAAE,aAAaA,EAAE,EAAE,CAAC,EAC5D,KAAKwrD,GAAQ,CAACxrD,MAAkBA,EAAE,WAAW,CAAC,GAC3C2xD,IAAMnrB,EAAK,IACd,OAAO,CAACjf,MAAM0jC,GAAmB/kD,GAAOgnD,GAAc3lC,CAAC,GAAGA,EAAE,EAAE,CAAC,EAC/D,KAAKikC,GAAQ0B,EAAa,CAAC,GACxB0E,IAAMprB,EAAK,IACd,OAAO,CAACr0B,MAAM84C,GAAmB/kD,GAAOgnD,GAAc/6C,CAAC,GAAGA,EAAE,EAAE,CAAC,EAC/D,KAAKq5C,GAAQ0B,EAAa,CAAC,GAExBgF,IAASF,IAETzG,IAAwB3rD,EAAK,IAAI,CAACI,MACtC,gBAAA8I,EAAC2iD,IAAA,EAAkB,KAAKzrD,GAAG,OAAA0I,GAAc,UAAU8B,EAAA,GAAtCxK,EAAE,EAAiD,CACjE;AAGD,EAAIwmC,EAAK,YACP+kB,EAAS;AAAA,IACP,gBAAAziD;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS09B,EAAK;AAAA,QACf,UAAA;AAAA,MAAA;AAAA,MAJK;AAAA,IAAA;AAAA,EAMN;AAGJ,QAAM7R,IACJzuB,EAAM,KAAA,OAAU5D,IAAAkkC,EAAK,WAAL,QAAAlkC,EAAa,WAAU,OAAO6G,EAAI,gBAAiB,aACjE,gBAAAyF,EAAC,WAAA,EAAQ,WAAU,sBACjB,UAAA;AAAA,IAAA,gBAAA9F,EAAC,MAAA,EAAG,WAAU,0BAAyB,UAAA,kBAAc;AAAA,IACrD,gBAAAA;AAAA,MAACyB;AAAA,MAAA;AAAA,QACC,QAAQ;AAAA,QACR,aAAarE;AAAA,QACb,KAAKsgC,EAAK;AAAA,QACV,QAAQkiB;AAAA,QACR,aAAAl+C;AAAA,QACA,OAAA9B;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,EAAA,CACF,IAEAwpD,EAAO,kBAAkB3G,CAAQ,GAI/B4G,IAAQ;AAAA,IACZD;AAAA,MACE;AAAA,MACAP,EAAI,IAAI,CAACpqC,MACP,gBAAAze;AAAA,QAACskD;AAAA,QAAA;AAAA,UAEC,QAAO;AAAA,UACP,MAAM7lC;AAAA,UACN,UAAU,CAAC7Z,MAAMukD,EAAiB,EAAE,QAAQ,YAAY,GAAGvkD,EAAA,CAAG;AAAA,QAAA;AAAA,QAHzD6Z,EAAE;AAAA,MAAA,CAKV;AAAA,IAAA;AAAA,IAEH2qC;AAAA,MACE;AAAA,MACAN,EAAI,IAAI,CAACz/C,MACP,gBAAArJ;AAAA,QAACskD;AAAA,QAAA;AAAA,UAEC,QAAO;AAAA,UACP,MAAMj7C;AAAA,UACN,UAAU,CAACzE,MAAMukD,EAAiB,EAAE,QAAQ,YAAY,GAAGvkD,EAAA,CAAG;AAAA,QAAA;AAAA,QAHzDyE,EAAE;AAAA,MAAA,CAKV;AAAA,IAAA;AAAA,EACH,EACA,OAAO,OAAO,GAKVigD,KAAQz9B,IAAO,IAAI,MAAMw9B,EAAM,SAAS,IAAI,IAAI;AACtD,SAEOhkD;AAAA,IAFFikD,IAGH,gBAAAxjD,EAAC,OAAA,EAAI,WAAU,kBAAiB,aAAWwjD,GACxC,UAAA;AAAA,MAAAz9B;AAAA,MACAw9B,EAAM,SAAS,uBAAM,OAAA,EAAI,WAAU,wBAAwB,UAAAA,EAAA,CAAM;AAAA,IAAA,EAAA,CACpE,IALY,gBAAAvjD,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA;AAAA,MAAA;AAAA,MAA+B1I;AAAA,MAAM;AAAA,IAAA,EAAA,CAAE;AAAA,EAKtF;AAEJ;AAIO,SAASmsD,GAAelpD,GAAaorC,GAAqC;;AAC/E,YAAQjyC,IAAA6G,EAAI,mBAAJ,gBAAA7G,EAAA,KAAA6G,GAAqBorC,OAAU,QAAQ,QAAQ,CAAA,CAAE,GAAG;AAAA,IAAK,CAAC+d,MAChEA,EAAG,IAAI,CAAC5kD,OAAO;AAAA,MACb,KAAKA,EAAE;AAAA,MACP,OAAOA,EAAE;AAAA,MACT,aAAaA,EAAE;AAAA,MACf,QAASA,EAAE,UAAU,CAAA;AAAA,IAAC,EACtB;AAAA,EAAA;AAEN;AAGO,SAAS6kD,GAAmB,EAAE,OAAA1uC,GAAO,KAAA/jB,KAAuC;AACjF,SACE,gBAAA8O,EAAC,KAAA,EAAE,WAAU,uBACX,UAAA;AAAA,IAAA,gBAAA9F,EAAC,YAAQ,UAAA+a,EAAA,CAAM;AAAA,IAAS;AAAA,IAAY/jB;AAAA,IAAI;AAAA,EAAA,GAE1C;AAEJ;AAEO,SAAS4qD,GAAc;AAAA,EAC5B,MAAAlzC,IAAO;AAAA,EACP,YAAAuxC;AAAA,EACA,OAAAxU;AAAA,EACA,KAAAz0C;AAAA,EACA,OAAAooD;AAAA,EACA,SAAA/jC;AAAA,EACA,QAAAynC;AAAA,EACA,eAAAzD;AAAA,EACA,aAAAqK;AAAA,EACA,OAAA9pD;AAAA,EACA,YAAAkB;AAAA,EACA,QAAA6mB;AAAA,EACA,eAAAi1B,IAAgB,CAAA;AAAA,EAChB,MAAA92B;AAAA,EACA,eAAA45B;AAAA,EACA,mBAAAtT;AAAA,EACA,aAAAuT;AACF,GAkCG;AACD,QAAMt/C,IAAMG,GAAA,GACN65C,IAAY3rC,MAAS,WACrBi7C,IAAQtP,IAAY,cAAc,aAClC,CAAC9b,GAAOC,CAAQ,IAAIv/B,EAA2B,IAAI,GACnD,CAAC2rC,GAAOgf,CAAQ,IAAI3qD,EAAqC,IAAI,GAC7D,CAAC+uC,GAAS6b,CAAU,IAAI5qD,EAA6B,IAAI,GACzD,CAAC6qD,GAAWC,CAAY,IAAI9qD,EAAwB,IAAI,GAExD,CAAC+qD,GAAWC,CAAY,IAAIhrD,EAAiBmtC,KAAqB,EAAE,GACpE,CAACb,GAAe2e,CAAgB,IAAIjrD,EAAA,GACpCkrD,IAAkB1d,GAAA,GAClB2d,IAAqBtnD,GAAOqnD,CAAe;AACjD,EAAAC,EAAmB,UAAUD;AAC7B,QAAM/pB,IAAemL,IAChBD;AAAA,IACC,EAAoB,MAAM,EAAE,KAAKG,GAAO,QAAQ,IAAI,eAAAF,IAAc;AAAA,IAClE4e,KAAA,gBAAAA,EAAiB;AAAA,EAAA,KACd,KACLH,GACEK,IAAkBlmD,GAAY,CAACxK,OAA4C;AAC/E,IAAAuwD,EAAiB,MAAS,GAC1BD,EAAatwD,EAAE;AAAA,EACjB,GAAG,CAAA,CAAE,GACC,CAAC2wD,IAAWC,EAAY,IAAItrD,EAAiBygD,KAAiB,EAAE,GAChE,CAACuD,GAAYC,CAAa,IAAIjkD,EAAkC0gD,KAAe,CAAA,CAAE,GACjF6K,IAAS1nD,GAAuB,IAAI,GACpC,CAAC2nD,GAAsBC,CAAuB,IAAIzrD,EAAS,EAAK,GAIhE,CAAC0hD,GAAKC,EAAM,IAAI3hD;AAAA,IACpBygD,KAAiBC,IAAc,cAAc;AAAA,EAAA,GAIzC,CAACyD,GAAYC,CAAa,IAAIpkD,EAAqB,OAAO,GAE1D,CAACqkD,GAAUC,CAAW,IAAItkD,EAAS,IAAI,GAEvC,CAACukD,GAAaC,EAAc,IAAIxkD,EAAqB,CAAA,CAAE;AAG7D,EAAAC,GAAU,MAAM;AACd,QAAIkE,KAAW;AACf,IAAA2mD,EAAa,IAAI;AACjB,UAAMY,IAAYtQ,IAAYkP,GAAelpD,GAAKorC,CAAK,IAAIprC,EAAI,cAAcorC,CAAK;AAClF,mBAAQ,IAAI,CAACprC,EAAI,WAAWorC,CAAK,GAAGprC,EAAI,sBAAsBorC,CAAK,GAAGkf,CAAS,CAAC,EAC7E,KAAK,CAAC,CAACC,IAAIC,IAAIC,EAAE,MAAM;AACtB,UAAI1nD,GAAU;AACd,YAAM+oC,KAAUG,GAAsBb,GAAOmf,IAAIC,EAAE;AACnD,MAAArsB,EAASosB,EAAE,GACXhB,EAASzd,EAAO,GAChB0d,EAAWiB,EAAE;AACb,YAAM7xC,KAAQmxC,EAAmB,SAC3B/yD,KAAW60C;AAAA,QACf,EAAE,IAAIvkB,KAAU,IAAI,MAAM,EAAE,KAAK8jB,GAAO,QAAQ,KAAG;AAAA,QACnDU;AAAA,SACAlzB,MAAA,gBAAAA,GAAO,UAAS,CAAA;AAAA,SAChBA,MAAA,gBAAAA,GAAO,gBAAe,CAAA;AAAA,QACtBmzB;AAAA,MAAA;AAEF,MAAI/0C,GAAS,gBAAe6yD,EAAiB7yD,GAAS,aAAa,IAC9DgzD,EAAgBhzD,GAAS,cAAc,EAAE;AAAA,IAChD,CAAC,EACA,MAAM,CAACgM,OAAM,CAACD,MAAY2mD,EAAc1mD,GAAY,OAAO,CAAC,GACxD,MAAM;AACX,MAAAD,KAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAKorC,GAAO4O,GAAWgQ,GAAiBje,GAAmBzkB,CAAM,CAAC;AAEtE,QAAMojC,KAAe,YAAY;AAC/B,UAAMF,KAAK,MAAMxqD,EAAI,sBAAsBorC,CAAK;AAChD,IAAAme,EAAStd,GAAsBb,GAAOlN,KAAS,CAAA,GAAIssB,EAAE,CAAC;AAAA,EACxD,GAEMG,MAAkBzsB,KAAS,IAAI,OAAO,CAACrnC,OAAMA,GAAE,cAAc,EAAK,GAElE+zD,KAAgBD,GAAe;AAAA,IACnC,CAAC9zD,OAAMA,GAAE,kBAAkB,OAASA,GAAE,SAAS,gBAAgBA,GAAE,SAAS;AAAA,EAAA,GAKtEg0D,KACJD,MACA,CAACD,GAAe,KAAK,CAAC9zD,OAAMA,GAAE,kBAAkB,MAAQA,GAAE,SAAS,YAAY,GAC3Ei0D,KAAkBH,GAAe,SAAS,KAAK,CAACC,IAChDG,MAAiBxgB,KAAS,CAAA,GAAI,SAAS,GACvCygB,MAAkBrd,KAAW,IAAI,KAAK,CAAC92C,OAAMA,GAAE,QAAQozD,EAAS,GAChEgB,KAAejR,IACjBzM,GAAyBnC,GAAOuC,GAASsc,IAAWrH,CAAU,IAC9D,MAGEsI,KAAgB,CAAC,GAAIvd,KAAW,CAAA,CAAG,EAAE;AAAA,IAAK,CAAC92C,IAAGC,OACjDD,GAAE,SAASA,GAAE,KAAK,cAAcC,EAAE,SAASA,EAAE,KAAK,QAAW,EAAE,aAAa,QAAQ;AAAA,EAAA,GAOjFq0D,KAAe9F,GAAe1uD,CAAG,GACjC,CAACy0D,IAAYC,EAAa,IAAIzsD,EAAS,EAAK;AAClD,EAAAC,GAAU,MAAM;AACd,QAAI,CAACssD,MAAgB,CAAC1qD,KAAc,CAAC6mB,EAAQ;AAC7C,QAAIvkB,KAAW;AACf,WAAA/C,EACG,cAAcS,GAAY6mB,CAAM,EAChC,KAAK,CAACogB,MAAU;AACf,MAAI,CAAC3kC,MAAY2kC,EAAM,KAAK,CAACnjC,OAAMA,GAAE,kBAAkB,WAAW,KAAG8mD,GAAc,EAAI;AAAA,IACzF,CAAC,EACA,MAAM,MAAM;AAAA,IAAC,CAAC,GACV,MAAM;AACX,MAAAtoD,KAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAKmrD,IAAc1qD,GAAY6mB,CAAM,CAAC;AAS1C,QAAM82B,KAAcF,GAAez9C,KAAc,IAAI87C,GAAe,CAAC,CAAC97C,CAAU,GAC1E4W,KAAiBmlC,GAAoB4B,IAAazB,GAAmBl3B,CAAI,CAAC,GAK1E6lC,KACJ,CAAC,CAACrB,OAJwB,CAACa,MAAoBC,MAAiB,CAAC,CAAChrB,OAI3B,CAACkrB,MAAgBA,GAAa,SAAS,SAAS,IACnF5H,KACJiI,MACA,CAAC,CAACN,MACF3iB,GAAqB2iB,GAAe,UAAU,CAAA,GAAIpI,CAAU,GAIxD2I,KAASD,IAETE,MAAgBjhB,KAAS,IAAI,KAAK,CAAC1kC,OAAMA,GAAE,OAAOk6B,CAAY;AAEpE,WAASyjB,KAAuB;AAC9B,WAAO;AAAA,MACL,MAAM;AAAA,QACJ,KAAKpY;AAAA,QACL,SAAQ4f,MAAA,gBAAAA,GAAgB,QAAOf;AAAA;AAAA,QAE/B,GAAI/e,IAAgB,EAAE,eAAAA,EAAA,IAAkBnL,IAAe,EAAE,YAAYA,EAAA,IAAiB,CAAA;AAAA,QACtF,GAAIia,IAAY,EAAE,SAAS,OAAkB,CAAA;AAAA,MAAC;AAAA,MAEhD,MAAM4I;AAAA,MACN,GAAGO;AAAA,IAAA;AAAA,EAEP;AACA,WAASvtB,KAAM;AACb,IAAKo1B,MACLjM,EAAMyE,IAAW;AAAA,EACnB;AAKA,QAAM,CAACF,IAAaC,EAAc,IAAI3kD,EAAwB,IAAI;AAKlE,EAAAC,GAAU,MAAM;AAId,QAHI,CAACmgD,KAAiBsE,OAAgB,QAAQ,CAACgI,MAG3CL,MAAgB3K,MAAQ,QAAS;AACrC,UAAMhnD,KAAKylD,EAAMyE,IAAW;AAC5B,IAAIlqD,SAAmBA,EAAE,GACrBA,MAAM0gD,MAAW4F,KAAA,QAAAA,EAAatmD;AAAA,EACpC,GAAG,CAAC0lD,GAAesE,IAAagI,IAAehL,CAAG,CAAC,GAKnDzhD,GAAU,MAAM;AACd,IAAI,CAACmgD,KAAiBsE,OAAgB,QACtCtE,EAAcsE,IAAaE,IAAW;AAAA,EACxC,GAAG,CAACF,IAAaV,GAAYO,GAAapjB,GAAcmL,CAAa,CAAC;AAEtE,QAAMuY,KAAmB,CAAC/oD,OAAkB;AAC1C,IAAIA,OAAM,UAAQwoD,EAAY5K,GAAWkL,GAAA,CAAW,CAAC,GACrDR,EAActoD,EAAC;AAAA,EACjB;AAEA,SACE,gBAAA+K,EAAC,OAAA,EAAI,WAAU,kBAGb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAA9F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAW,aAAa2gD,MAAQ,UAAU,YAAY,EAAE;AAAA,YACxD,SAAS,MAAMC,GAAO,OAAO;AAAA,YAC9B,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGD,gBAAA5gD;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,UAAU,CAAC2rD;AAAA,YACX,OAAOA,KAAgB,SAAY;AAAA,YACnC,WAAW,aAAahL,MAAQ,cAAc,YAAY,EAAE;AAAA,YAC5D,SAAS,MAAMgL,MAAiB/K,GAAO,WAAW;AAAA,YACnD,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGD,gBAAA5gD;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,UAAU,CAAC0jD;AAAA,YACX,OAAOA,KAAiB,SAAY;AAAA,YACpC,WAAW,aAAa/C,MAAQ,SAAS,YAAY,EAAE;AAAA,YACvD,SAAS,MAAM+C,MAAkB9C,GAAO,MAAM;AAAA,YAC/C,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,GACF;AAAA,MACA,gBAAA5gD;AAAA,QAAC++C;AAAA,QAAA;AAAA,UACC,MAAMqE;AAAA,UACN,YAAYznB,GAAsBsnB,CAAU;AAAA,UAC5C,UAAUa;AAAA,UACV,UAAUnD,MAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,IACpB,GACF;AAAA,IAEA,gBAAA76C,EAAC,OAAA,EAAI,WAAU,uBAEZ,UAAA;AAAA,MAAA66C,MAAQ,WACP,gBAAA76C,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,QAAAgkD,KAAa,gBAAA9pD,EAAC,OAAA,EAAI,WAAU,wBAAwB,UAAA8pD,GAAU;AAAA,QAC9DvrB,MAAU,QAAQ,CAACurB,uBAAc,KAAA,EAAE,WAAU,uBAAsB,UAAA,YAAQ;AAAA,QAE5E,gBAAAhkD,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,UAAA,gBAAA9F,EAAC,UAAK,UAAA,MAAA,CAAG;AAAA,UACT,gBAAA8F,EAAC,OAAA,EAAI,WAAU,oBAAmB,KAAK0kD,GACrC,UAAA;AAAA,YAAA,gBAAA1kD;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,cAAW;AAAA,gBACX,SAAS4jD;AAAA,gBACT,UAAU,CAACA;AAAA,gBAEV,UAAA;AAAA,kBAAA1yD,KACC,gBAAAgJ;AAAA,oBAACV;AAAA,oBAAA;AAAA,sBACC,KAAKtI,EAAI;AAAA,sBACT,SAASA,EAAI;AAAA,sBACb,YAAYA,EAAI;AAAA,sBAChB,MAAMA,EAAI;AAAA,sBACV,OAAA4I;AAAA,sBACA,MAAM;AAAA,oBAAA;AAAA,kBAAA;AAAA,oCAGT,QAAA,EAAK,WAAU,uBAAuB,WAAA5I,KAAA,gBAAAA,EAAK,gBAAey0C,EAAA,CAAM;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAEnE,gBAAAzrC;AAAA,cAAC0sC;AAAA,cAAA;AAAA,gBACC,MAAM;AAAA,kBACJ,IAAIiX,MAAeh8B,KAAU;AAAA,kBAC7B,MAAM;AAAA,oBACJ,KAAK8jB;AAAA,oBACL,QAAQ6e;AAAA,oBACR,GAAI/e,IACA,EAAE,eAAAA,EAAA,IACF,EAAE,YAAYnL,KAAgB,OAAA;AAAA,kBAAU;AAAA,gBAC9C;AAAA,gBAEF,OAAAwK;AAAA,gBACA,QAAQ,CAAC,CAACkf;AAAA,gBACV,MAAMW;AAAA,gBACN,cAAcC;AAAA,gBACd,WAAWF;AAAA,gBACX,oBAAoBH;AAAA,gBACpB,uBAAuBH;AAAA,gBACvB,qBAAqB,MAAM;AACzB,kBAAKa,GAAA;AAAA,gBACP;AAAA,cAAA;AAAA,YAAA;AAAA,UACF,GACF;AAAA,UACCG,OAAyBW,MAAA,gBAAAA,GAAc,8BACrC,QAAA,EAAK,WAAU,YAAW,UAAA,2FAG3B;AAAA,UAEDttB,MAAU,QAAQ4sB,MAAmB,CAACC,MACrC,gBAAAprD,EAAC,QAAA,EAAK,WAAU,YAAW,UAAA,0DAAA,CAE3B;AAAA,QAAA,GAEJ;AAAA,QAGCguC,MAAY,SACVA,EAAQ,WAAW,IAClB,gBAAAhuC,EAAC,KAAA,EAAE,WAAU,uBACV,UAAAq6C,IAAY,mCAAmC,+BAAA,CAClD,IACEiR,KACF,gBAAAtrD;AAAA,UAAC0tC;AAAA,UAAA;AAAA,YACC,SAAS4d;AAAA,YACT,UAAU,CAACj0D,OAAa;AACtB,cAAAkzD,GAAae,GAAa,UAAU,GACpCpI,EAAc,CAAC38C,OAAU,EAAE,GAAGA,GAAM,SAASlP,KAAW;AAAA,YAC1D;AAAA,UAAA;AAAA,QAAA;AAAA;AAAA,UAIF,gBAAAyO,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,YAAA,gBAAAA,EAAC,QAAA,EACE,UAAA;AAAA,cAAAu0C,IAAY,YAAY;AAAA,cACxBiQ,KAAY,KAAK;AAAA,YAAA,GACpB;AAAA,YACA,gBAAAtqD;AAAA,cAACqT;AAAA,cAAA;AAAA,gBACC,OAAOi3C;AAAA,gBACP,aAAa,UAAUX,CAAK;AAAA,gBAI5B,MAAK;AAAA,gBAGL,eAAe;AAAA,gBACf,UAAU,CAACpyC,OAAQ;;AACjB,kBAAAgzC,GAAahzC,EAAG,GAChB2rC;AAAA,oBACEgC;AAAA,wBACG1rD,KAAAw0C,KAAW,IAAI,KAAK,CAAC92C,OAAMA,GAAE,QAAQqgB,EAAG,MAAxC,gBAAA/d,EAA2C,WAAU,CAAA;AAAA,oBAAC;AAAA,kBACzD,GAGFkyD,GAAc,EAAK;AAAA,gBACrB;AAAA,gBACA,SAASH,GAAc,IAAI,CAACr0D,QAAO;AAAA,kBACjC,OAAOA,GAAE;AAAA,kBACT,OAAO,GAAGA,GAAE,SAASA,GAAE,GAAG,KAAKA,GAAE,GAAG;AAAA,gBAAA,EACpC;AAAA,cAAA;AAAA,YAAA;AAAA,aAEHm0D,MAAA,gBAAAA,GAAgB,gBACf,gBAAArrD,EAAC,UAAK,WAAU,YAAY,aAAe,YAAA,CAAY;AAAA,UAAA,EAAA,CAE3D;AAAA;AAAA,MAAA,GAEN;AAAA,MAMD2gD,MAAQ,gBACL0K,KAEEjI,MAAe,UACjB,gBAAApjD;AAAA,QAACgxB;AAAA,QAAA;AAAA,UACC,QAAQq6B,GAAe,UAAU,CAAA;AAAA,UACjC,QAAQpI;AAAA,UACR,UAAUC;AAAA,UACV,SAAS;AAAA,YACP,OAAAzX;AAAA,YACA,WAAW4f,GAAe;AAAA,YAC1B,cAAcjrB,KAAgB;AAAA,YAC9B,SAASppC,KAAA,gBAAAA,EAAK;AAAA,UAAA;AAAA,QAChB;AAAA,MAAA,IAEAosD,MAAe;AAAA;AAAA;AAAA,QAGjB,gBAAApjD;AAAA,UAACgS;AAAA,UAAA;AAAA,YACC,OAAOsxC;AAAA,YACP,UAAU,MAAM;AAAA,YAAC;AAAA,YACjB,UAAQ;AAAA,YACR,WAAU;AAAA,YACV,QAAO;AAAA,YACP,cAAW;AAAA,YACX,UAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,UAERF,MAAe,gBACjB,gBAAApjD,EAAC+7B,MAAmB,QAAQknB,GAAY,UAAUC,GAAe;AAAA;AAAA,QAGjE,gBAAAljD;AAAA,UAACq7B;AAAA,UAAA;AAAA,YACC,QAAQmoB;AAAA,YACR,UAAUC;AAAA,YACV,iBAAiB,CAACpJ;AAAA,UAAA;AAAA,QAAA;AAAA,UAhCpB,gBAAAv0C,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA;AAAA,QAAA;AAAA,QAAM6jD;AAAA,QAAM;AAAA,MAAA,GAAgB;AAAA,MAqClEhJ,MAAQ,WACN0K,MAAkBhR,IACjB,gBAAAr6C;AAAA,QAACypD;AAAA,QAAA;AAAA,UACC,OAAO4B,GAAe,SAASA,GAAe;AAAA,UAC9C,MAAKr0D,KAAA,gBAAAA,EAAK,gBAAey0C;AAAA,QAAA;AAAA,MAAA,IAEzB4f,KACF,gBAAArrD;AAAA,QAACgkD;AAAA,QAAA;AAAA,UACC,KAAKvY;AAAA,UACL,QAAQ4f,GAAe;AAAA,UACvB,cAAcjrB,KAAgB;AAAA,UAC9B,QAAQ6iB;AAAA,UACR,QACE0I,MAAiBjjB,GAAqB2iB,GAAe,UAAU,CAAA,GAAIpI,CAAU;AAAA,UAE/E,OAAOvrC;AAAA,UACP,UAAUg0C;AAAA,QAAA;AAAA,MAAA,IAGZ,gBAAA1rD,EAAC,KAAA,EAAE,WAAU,uBAAsB,UAAA,kCAA8B;AAAA,IAAA,GAEvE;AAAA,IAMC2gD,MAAQ,UACP,gBAAA3gD,EAAC,OAAA,EAAI,WAAU,2BACZ,UAAAwrD,MAAgB,CAACC,MAChB,gBAAAzrD,EAAC,QAAA,EAAK,WAAU,uBAAsB,qEAEtC,GAEJ;AAAA,IAKF,gBAAA8F,EAAC,OAAA,EAAI,WAAU,2CACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,YAAO,MAAK,UAAS,WAAU,yBAAwB,SAASqb,GAAS,UAAA,SAAA,CAE1E;AAAA,MACCslC,MAAQ,SACP,gBAAA3gD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU2jD,OAAgB,QAAQ,CAACiI;AAAA,UACnC,SAASjI,OAAgB,OAAQb,KAAUznC,IAAW4a;AAAA,UAErD,UAAA0tB,OAAgB,OAAO,SAAS;AAAA,QAAA;AAAA,MAAA,IAGnC,gBAAA3jD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU2gD,MAAQ,UAAU,CAACgL,KAAgB,CAACjI;AAAA,UAC9C,SAAS,MAAM9C,GAAOD,MAAQ,UAAU,cAAc,MAAM;AAAA,UAC7D,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ;AAWO,SAASgB,GAAwB;AAAA,EACtC,OAAAlW;AAAA,EACA,KAAAz0C;AAAA,EACA,SAAAqkB;AAAA,EACA,aAAAquC;AAAA,EACA,OAAA9pD;AAAA,EACA,mBAAAwsC;AAAA,EACA,aAAA2T;AACF,GAUG;AACD,QAAM1/C,IAAMG,GAAA,GACN,CAAC+9B,GAAOC,CAAQ,IAAIv/B,EAA2B,IAAI,GACnD,CAAC2rC,GAAOgf,CAAQ,IAAI3qD,EAAqC,IAAI,GAC7D,CAAC6qD,GAAWC,CAAY,IAAI9qD,EAAwB,IAAI,GAExD,CAACmhC,GAAciqB,CAAe,IAAIprD,EAAiBmtC,KAAqB,EAAE,GAC1E,CAAC0f,GAAeC,CAAgB,IAAI9sD,EAAS,EAAK,GAGlD,CAAC+sD,GAAcC,CAAe,IAAIhtD,EAAS,EAAK;AAKtD,EAAAC,GAAU,MAAM;AACd,QAAIkE,IAAW;AACf,WAAA2mD,EAAa,IAAI,GACjB,QAAQ,IAAI,CAAC1pD,EAAI,WAAWorC,CAAK,GAAGprC,EAAI,sBAAsBorC,CAAK,CAAC,CAAC,EAClE,KAAK,CAAC,CAACmf,GAAIC,CAAE,MAAM;AAClB,UAAIznD,EAAU;AACd,MAAAo7B,EAASosB,CAAE,GACXhB,EAASiB,CAAE,GAIP,EADaD,KAAM,IAAI,KAAK,CAAC1zD,MAAMA,EAAE,kBAAkB,EAAI,KAC/C2zD,EAAG,SAAS,KAAGR,EAAgBQ,EAAG,CAAC,EAAE,EAAE;AAAA,IACzD,CAAC,EACA,MAAM,CAACxnD,MAAM,CAACD,KAAY2mD,EAAc1mD,EAAY,OAAO,CAAC,GACxD,MAAM;AACX,MAAAD,IAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC/C,GAAKorC,CAAK,CAAC;AAEf,QAAMsf,IAAe,YAAY;AAC/B,UAAMF,IAAK,MAAMxqD,EAAI,sBAAsBorC,CAAK;AAChD,IAAAme,EAASiB,CAAE,GACPA,EAAG,SAAS,KAAGR,EAAgB,CAAC9jD,MAASA,KAAQskD,EAAG,CAAC,EAAE,EAAE;AAAA,EAC/D,GAEMG,KAAkBzsB,KAAS,IAAI,OAAO,CAACrnC,MAAMA,EAAE,cAAc,EAAK,GAClE+zD,IAAgBD,EAAe;AAAA,IACnC,CAAC9zD,MAAMA,EAAE,kBAAkB,OAASA,EAAE,SAAS,gBAAgBA,EAAE,SAAS;AAAA,EAAA,GAKtEg0D,IACJD,KACA,CAACD,EAAe,KAAK,CAAC9zD,MAAMA,EAAE,kBAAkB,MAAQA,EAAE,SAAS,YAAY,GAC3Ei0D,IAAkBH,EAAe,SAAS,KAAK,CAACC,GAChDG,KAAiBxgB,KAAS,CAAA,GAAI,SAAS,GACvCshB,IAAsB,CAACf,KAAoBC,KAAiB,CAAC,CAAChrB,GAE9DyrB,KAAgBjhB,KAAS,IAAI,KAAK,CAAC1kC,MAAMA,EAAE,OAAOk6B,CAAY,GAG9D+rB,IAAiBH,KAAgB,CAAC5rB;AAExC,SACE,gBAAAt6B,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,IAAA,gBAAA9F,EAAC,SAAI,WAAU,uBACb,UAAA,gBAAA8F,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,MAAAgkD,KAAa,gBAAA9pD,EAAC,OAAA,EAAI,WAAU,wBAAwB,UAAA8pD,GAAU;AAAA,MAC9DvrB,MAAU,QAAQ,CAACurB,uBAAc,KAAA,EAAE,WAAU,uBAAsB,UAAA,YAAQ;AAAA,MAG5E,gBAAAhkD,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,MAAA,CAAG;AAAA,QACT,gBAAA8F,EAAC,OAAA,EAAI,WAAU,kBACZ,UAAA;AAAA,UAAA9O,KACC,gBAAAgJ;AAAA,YAACV;AAAA,YAAA;AAAA,cACC,KAAKtI,EAAI;AAAA,cACT,SAASA,EAAI;AAAA,cACb,YAAYA,EAAI;AAAA,cAChB,MAAMA,EAAI;AAAA,cACV,OAAA4I;AAAA,cACA,MAAM;AAAA,YAAA;AAAA,UAAA;AAAA,4BAGT,QAAA,EAAK,WAAU,uBAAuB,WAAA5I,KAAA,gBAAAA,EAAK,gBAAey0C,GAAM;AAAA,UAChEie,KACC,gBAAA1pD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS0pD;AAAA,cACV,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAED,EAAA,CAEJ;AAAA,MAAA,GACF;AAAA,MAMCnrB,MAAU,QAAQ0sB,KACjB,gBAAAnlD,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,aAAA,CAAU;AAAA,QAChB,gBAAA8F,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,UAAA,gBAAA9F,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,iFAEtC;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAM+rD,EAAiB,EAAI;AAAA,cACrC,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAED,GACF;AAAA,QAGCb,KACC,gBAAAlrD,EAAC,QAAA,EAAK,WAAU,YAAW,UAAA,6JAAA,CAG3B;AAAA,MAAA,GAEJ;AAAA,MAIDu+B,MAAU,QACT4sB,MACEC,IASEe,IACF,gBAAArmD,EAAC,SAAA,EAAM,WAAU,aACf,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,aAAA,CAAU;AAAA,QAChB,gBAAA8F,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,KAClC,UAAA;AAAA,UAAA,gBAAA9F;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAOogC;AAAA,cACP,UAAU,CAAC/8B,MAAM;AACf,gBAAAgnD,EAAgBhnD,EAAE,OAAO,KAAK,GAC9B4oD,EAAgB,EAAK;AAAA,cACvB;AAAA,cACA,OAAO,EAAE,MAAM,EAAA;AAAA,cAEb,WAAArhB,KAAS,IAAI,IAAI,CAAC1kC,MAClB,gBAAAJ,EAAC,UAAA,EAAkB,OAAOI,EAAE,IACzB,UAAA;AAAA,gBAAAA,EAAE,eAAeA,EAAE;AAAA,gBAAG;AAAA,gBAAEA,EAAE,QAAQ,IAAIA,EAAE,KAAK,MAAM;AAAA,cAAA,EAAA,GADzCA,EAAE,EAEf,CACD;AAAA,YAAA;AAAA,UAAA;AAAA,UAEH,gBAAAlG;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAM+rD,EAAiB,EAAI;AAAA,cACrC,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAED,EAAA,CACF;AAAA,MAAA,EAAA,CACF,IAEA,gBAAAjmD,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,UAAK,UAAA,aAAA,CAAU;AAAA,QAChB,gBAAA8F,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,uBACb,UAAA;AAAA,aAAA+lD,KAAA,gBAAAA,EAAc,iBAAeA,KAAA,gBAAAA,EAAc,OAAMzrB;AAAA,YACjDyrB,KAAA,QAAAA,EAAc,QAAQ,KAAKA,EAAa,KAAK,MAAM;AAAA,UAAA,GACtD;AAAA,UACA,gBAAA7rD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAMisD,EAAgB,EAAI;AAAA,cACpC,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGD,gBAAAjsD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAM+rD,EAAiB,EAAI;AAAA,cACrC,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAED,EAAA,CACF;AAAA,MAAA,GACF,IA1DA,gBAAAjmD,EAAC,OAAA,EAAI,WAAU,wCACb,UAAA;AAAA,QAAA,gBAAA9F,EAAC,SAAI,OAAO,EAAE,cAAc,EAAA,GAAK,UAAA,2DAEjC;AAAA,QACA,gBAAAA,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,WAAU,SAAS,MAAM+rD,EAAiB,EAAI,GAAG,UAAA,oBAAA,CAEjF;AAAA,MAAA,EAAA,CACF;AAAA,IAmDA,EAAA,CAEN,EAAA,CACF;AAAA,IAQA,gBAAAjmD,EAAC,OAAA,EAAI,WAAU,2CACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,YAAO,MAAK,UAAS,WAAU,yBAAwB,SAASqb,GAAS,UAAA,SAAA,CAE1E;AAAA,MACA,gBAAArb;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,CAACksD,KAAuB,CAACl1D;AAAA,UACnC,SAAS,MAAMA,KAAO+oD,EAAY3f,GAAcppC,CAAG;AAAA,UACpD,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,GACF;AAAA,IAEC80D,KACC,gBAAA9rD;AAAA,MAAC+9B;AAAA,MAAA;AAAA,QACC,OAAAn+B;AAAA,QACA,cAAc6rC;AAAA,QACd,SAAS,MAAMsgB,EAAiB,EAAK;AAAA,QACrC,WAAW,OAAO,EAAE,cAAcpyD,QAAS;AACzC,UAAAoyD,EAAiB,EAAK,GACtB1B,EAAgB1wD,CAAE,GAClBsyD,EAAgB,EAAK,GACrB,MAAMlB,EAAA;AAAA,QACR;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GAEJ;AAEJ;AC54GA,MAAMqB,KAAQ,CAAC,SAAS,MAAM;AAgC9B,SAASC,GAAY75C,GAAoD;AACvE,SAAOA,MAAW,QAAQ,OAAOA,KAAW,YAAY,CAAC,MAAM,QAAQA,CAAM;AAC/E;AA8BO,SAAS42B,GAAkB;AAAA,EAChC,QAAAhc;AAAA,EACA,QAAAG;AAAA,EACA,UAAA1hB;AAAA,EACA,kBAAAipB;AAAA,EACA,UAAAnpB;AAAA,EACA,aAAA2gD,IAAc;AAChB,GAA2B;AACzB,QAAMjlB,IAAYja,EAAO,SAAS,GAC5B,CAACrb,GAAMw6C,CAAO,IAAIttD,EAAoBqtD,CAAW,GAEjDE,IAAW,CAACnlB,KAAat1B,MAAS,QAKlC,CAAC7J,GAAM+L,CAAO,IAAIhV,EAAS,MAAMwtD,GAAWl/B,CAAM,CAAC,GAGnD,CAACgb,GAAYC,CAAa,IAAIvpC,EAAS,EAAI,GAC3CytD,IAAW5pD,GAAO,EAAI,GACtB6pD,IAAY,CAAChoD,MAAkB;AACnC,IAAIA,MAAS+nD,EAAS,YACtBA,EAAS,UAAU/nD,GACnB6jC,EAAc7jC,CAAI,GAClBmwB,KAAA,QAAAA,EAAmBnwB;AAAA,EACrB,GAEMioD,IAAW,CAACjoD,MAAoB;AAGpC,IAAIA,MAAS,UAAQsP,EAAQw4C,GAAWl/B,CAAM,CAAC,GAC/Co/B,EAAU,EAAI,GACdJ,EAAQ5nD,CAAI;AAAA,EACd,GAIM+K,IAAQ23B,IAAY,kBAAkB;AAE5C,SACE,gBAAAvhC,EAAC,OAAA,EAAI,WAAU,aAIZ,UAAA;AAAA,IAAAuhC,KACC,gBAAArnC,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,gBAAgB,cAC7C,UAAA,gBAAAA;AAAA,MAAC++C;AAAA,MAAA;AAAA,QACC,MAAAhtC;AAAA,QACA,OAAO,CAAC,GAAGq6C,EAAK;AAAA,QAChB,UAAU,CAACrxD,MAAM6xD,EAAS7xD,CAAc;AAAA,MAAA;AAAA,IAAA,GAE5C;AAAA,IAGDyxD,IACC,gBAAA1mD,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAA9F,EAAC,UAAM,UAAA0P,EAAA,CAAM;AAAA,MACb,gBAAA1P;AAAA,QAACgS;AAAA,QAAA;AAAA,UACC,OAAO9J;AAAA,UACP,UAAU+L;AAAA,UACV,UAAAtI;AAAA,UACA,WAAU;AAAA,UACV,cAAY,GAAG+D,CAAK;AAAA,UACpB,eAAe,CAAC8C,MAAW;AAKzB,kBAAMsP,IAAKuqC,GAAY75C,CAAM;AAC7B,YAAAm6C,EAAU7qC,CAAE,GACRA,OAAatP,CAAM;AAAA,UACzB;AAAA,UAEA,kBAAkB,CAAC/Y,MAAM;AACvB,YAAKA,EAAE,SAAOkzD,EAAU,EAAK;AAAA,UAC/B;AAAA,QAAA;AAAA,MAAA;AAAA,MAED,CAACpkB,KACA,gBAAAvoC,EAAC,QAAA,EAAK,WAAU,YAAW,UAAA,uFAAA,CAE3B;AAAA,IAAA,EAAA,CAEJ,IAEA,gBAAAA,EAACgxB,IAAA,EAAW,QAAA5D,GAAgB,QAAAG,GAAgB,UAAA1hB,GAAoB,UAAAF,EAAA,CAAoB;AAAA,EAAA,GAExF;AAEJ;AAGA,SAAS8gD,GAAWl/B,GAAyC;AAC3D,SAAO,KAAK,UAAUA,KAAU,CAAA,GAAI,MAAM,CAAC;AAC7C;AChIO,SAASs/B,GAAa;AAAA,EAC3B,OAAA9xC;AAAA,EACA,SAAA+xC;AAAA,EACA,WAAAC;AAAA,EACA,SAAA1xC;AAAA,EACA,cAAA2xC,IAAe;AAAA,EACf,aAAAC,IAAc;AAAA,EACd,aAAAC,IAAc;AAAA,EACd,SAAAx8C,IAAU;AAAA,EACV,UAAApQ;AACF,GAAsB;AACpB,SACE,gBAAAwF;AAAA,IAACsV;AAAA,IAAA;AAAA,MACC,OAAAL;AAAA,MACA,SAAS,MAAM;AACb,QAAKrK,KAAS2K,EAAA;AAAA,MAChB;AAAA,MAIA,UAAA;AAAA,QAAA,gBAAAvV,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,UAAA,gBAAA9F,EAAC,KAAA,EAAE,WAAU,uBAAuB,UAAA8sD,GAAQ;AAAA,UAC3CxsD;AAAA,QAAA,GACH;AAAA,QACA,gBAAAwF,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,UAAA,gBAAA9F;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAASqb;AAAA,cACT,UAAU3K;AAAA,cAET,UAAAu8C;AAAA,YAAA;AAAA,UAAA;AAAA,UAEH,gBAAAjtD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAWktD,IAAc,2BAA2B;AAAA,cACpD,SAASH;AAAA,cACT,UAAUr8C;AAAA,cAET,UAAAs8C;AAAA,YAAA;AAAA,UAAA;AAAA,QACH,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AC3CO,SAASG,GAAgB3S,GAAuC;AACrE,MAAI,CAACA,KAAS,OAAOA,KAAU,SAAU,QAAO;AAChD,UAAQA,EAAM,MAAA;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK,UAAU;AACb,YAAMr/C,IAA+B,CAAA;AACrC,iBAAW,CAAC+d,GAAGne,CAAC,KAAK,OAAO,QAAQy/C,EAAM,UAAU,CAAA,CAAE,EAAG,CAAAr/C,EAAI+d,CAAC,IAAIi0C,GAAgBpyD,CAAC;AACnF,aAAOI;AAAA,IACT;AAAA,IACA,KAAK;AACH,aAAOq/C,EAAM,QAAQ,CAAC2S,GAAgB3S,EAAM,KAAK,CAAC,IAAI,CAAA;AAAA,IACxD;AACE,aAAO;AAAA,EAAA;AAEb;AAGO,SAAS4S,GACdz2C,GAC4B;AAC5B,QAAMxb,IAAkC,CAAA;AACxC,aAAW+E,KAAKyW,KAAW;AACzB,IAAIzW,KAAK,OAAOA,EAAE,UAAW,YAAYA,EAAE,WAAW,OAAI/E,EAAI+E,EAAE,MAAM,IAAIA;AAE5E,SAAO/E;AACT;AAGA,SAASkyD,GAAentD,GAAwB;AAC9C,SAAOA,EAAE,kBAAkB,MAAQ,YAAYA,KAAKA,EAAE,WAAW;AACnE;AAGA,SAASotD,GAAiBrwD,GAAeswD,GAA6C;AACpF,MAAI,CAACA,EAAS,QAAO;AACrB,QAAMr2D,IAAI,KAAK,MAAM+F,EAAE,SAAS,GAC1B9F,IAAI,KAAK,MAAMo2D,CAAO;AAC5B,SAAO,OAAO,SAASr2D,CAAC,KAAK,OAAO,SAASC,CAAC,KAAKD,IAAIC;AACzD;AAOO,SAASq2D,GACdvnB,GACAqT,GACAC,GACAgU,GACS;AACT,QAAM9uC,IAAI66B,EAAMrT,CAAM,GAChBhpC,IAAIs8C,EAAUtT,CAAM;AAE1B,SADIxnB,MAAM,WAAc,CAACxhB,KAAK,CAACqwD,GAAiBrwD,GAAGswD,KAAA,gBAAAA,EAAUtnB,EAAO,MAChE,CAAChpC,IAAUwhB,IACR4uC,GAAepwD,CAAC,IAAIA,EAAE,SAASkwD,GAAgBlwD,EAAE,KAAK;AAC/D;AAOO,SAASwwD,GACdnU,GACAC,GACAgU,GACyB;AACzB,QAAMpyD,IAA+B,CAAA;AACrC,aAAWxB,KAAM,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK2/C,CAAK,GAAG,GAAG,OAAO,KAAKC,CAAS,CAAC,CAAC,GAAG;AAC5E,UAAMx+C,IAAIyyD,GAAoB7zD,GAAI2/C,GAAOC,GAAWgU,CAAO;AAC3D,IAAIxyD,MAAM,WAAWI,EAAIxB,CAAE,IAAIoB;AAAA,EACjC;AACA,SAAOI;AACT;AAOO,SAASuyD,GACdpU,GACAC,GACAgU,GACyB;AACzB,QAAMpyD,IAA+B,EAAE,GAAGm+C,EAAA;AAC1C,aAAW,CAAC3/C,GAAIsD,CAAC,KAAK,OAAO,QAAQs8C,CAAS;AAC5C,IAAK8T,GAAepwD,CAAC,MACjBq8C,EAAM3/C,CAAE,MAAM,UAAa2zD,GAAiBrwD,GAAGswD,KAAA,gBAAAA,EAAU5zD,EAAG,OAAGwB,EAAIxB,CAAE,IAAIsD,EAAE;AAEjF,SAAO9B;AACT;AASO,SAASwyD,GACdrU,GACAC,GACAgU,GACwE;AACxE,QAAMK,IAAoC,EAAE,GAAGtU,EAAA,GACzCuU,IAAwC,CAAA;AAC9C,aAAW,CAACl0D,GAAIsD,CAAC,KAAK,OAAO,QAAQs8C,CAAS;AAC5C,IAAID,EAAM3/C,CAAE,MAAM,UAAa,CAAC2zD,GAAiBrwD,GAAGswD,KAAA,gBAAAA,EAAU5zD,EAAG,MACjE,OAAOi0D,EAASj0D,CAAE,GAClBk0D,EAAal0D,CAAE,IAAI0zD,GAAepwD,CAAC,IAAIA,EAAE,SAASkwD,GAAgBlwD,EAAE,KAAK;AAE3E,SAAO,EAAE,OAAO2wD,GAAU,WAAWC,EAAA;AACvC;AAMO,SAASC,GACdxU,GACAC,GACAgU,GACwE;AACxE,QAAMK,IAAoC,EAAE,GAAGtU,EAAA,GACzCuU,IAAwC,CAAA;AAC9C,aAAW,CAACl0D,GAAIsD,CAAC,KAAK,OAAO,QAAQs8C,CAAS;AAC5C,IAAK8T,GAAepwD,CAAC,MACjBq8C,EAAM3/C,CAAE,MAAM,UAAa2zD,GAAiBrwD,GAAGswD,KAAA,gBAAAA,EAAU5zD,EAAG,OAC9D,OAAOi0D,EAASj0D,CAAE,GAClBk0D,EAAal0D,CAAE,IAAIsD,EAAE;AAGzB,SAAO,EAAE,OAAO2wD,GAAU,WAAWC,EAAA;AACvC;ACvJO,SAASE,GACdpjB,GACA4G,GAC2B;AAC3B,MAAI5G,EAAW,IAAK,QAAOA,EAAW;AACtC,MAAIA,EAAW,QAAQ;AACvB,WAAO4G,EAAK,IAAI5G,EAAW,KAAK;AAClC;AAOO,SAASqjB,GAAyBhjB,GAAkD;AACzF,QAAMvtC,wBAAW,IAAA;AACjB,aAAWyI,KAAK8kC;AACd,IAAI9kC,EAAE,QAAQ,UAAWzI,EAAK,IAAIyI,EAAE,KAAK;AAE3C,SAAO,CAAC,GAAGzI,CAAI;AACjB;"}