@w6w/embed 0.2.1 → 0.2.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/README.md +22 -5
  2. package/dist/ConfirmModal-Pv2-A_3U.js +186 -0
  3. package/dist/ConfirmModal-Pv2-A_3U.js.map +1 -0
  4. package/dist/{CreateFunctionModal-DRsFx-FB.js → CreateFunctionModal-DScxp_LN.js} +25 -25
  5. package/dist/{CreateFunctionModal-DRsFx-FB.js.map → CreateFunctionModal-DScxp_LN.js.map} +1 -1
  6. package/dist/{DocumentFormModal-BExK1V-B.js → DocumentFormModal-Br4s8wmi.js} +5 -5
  7. package/dist/{DocumentFormModal-BExK1V-B.js.map → DocumentFormModal-Br4s8wmi.js.map} +1 -1
  8. package/dist/ImportSpecModal-Cpzp8ndt.js +251 -0
  9. package/dist/ImportSpecModal-Cpzp8ndt.js.map +1 -0
  10. package/dist/ModelRoutesManager-1Ac5wcas.js +345 -0
  11. package/dist/ModelRoutesManager-1Ac5wcas.js.map +1 -0
  12. package/dist/WorkflowEditor-CmhXHRxi.js +1109 -0
  13. package/dist/WorkflowEditor-CmhXHRxi.js.map +1 -0
  14. package/dist/apps-ItBvnWX3.js +92 -0
  15. package/dist/apps-ItBvnWX3.js.map +1 -0
  16. package/dist/{callables-3mFrMVG_.js → callables-tOlflvbl.js} +11 -11
  17. package/dist/{callables-3mFrMVG_.js.map → callables-tOlflvbl.js.map} +1 -1
  18. package/dist/chrome/ConfirmModal.d.ts +4 -1
  19. package/dist/chrome/DangerZone.d.ts +4 -3
  20. package/dist/chrome/ExecutionProfileHeader.d.ts +3 -3
  21. package/dist/chrome/JsonToggle.d.ts +29 -20
  22. package/dist/chrome/Modal.d.ts +3 -1
  23. package/dist/chrome/RightRail.d.ts +6 -1
  24. package/dist/chrome/VersionHistoryModal.d.ts +2 -0
  25. package/dist/chrome/index.d.ts +1 -0
  26. package/dist/chrome/workspace.d.ts +36 -1
  27. package/dist/coerce-input-DFJ4n_wc.js +150 -0
  28. package/dist/coerce-input-DFJ4n_wc.js.map +1 -0
  29. package/dist/connections-CzsCyIxY.js +119 -0
  30. package/dist/connections-CzsCyIxY.js.map +1 -0
  31. package/dist/credentials-Cn92LGhJ.js +171 -0
  32. package/dist/credentials-Cn92LGhJ.js.map +1 -0
  33. package/dist/data-stores-UeQvwVCa.js +170 -0
  34. package/dist/data-stores-UeQvwVCa.js.map +1 -0
  35. package/dist/document-sources-DNmBojx6.js +169 -0
  36. package/dist/document-sources-DNmBojx6.js.map +1 -0
  37. package/dist/draft/use-workflow-draft.d.ts +2 -0
  38. package/dist/draft.mjs +2 -2
  39. package/dist/editor/BindingBanner.d.ts +13 -0
  40. package/dist/editor/CallableEditorFrame.d.ts +7 -0
  41. package/dist/editor/EndpointCards.d.ts +4 -1
  42. package/dist/editor/PublishControl.d.ts +19 -0
  43. package/dist/editor/PublishTooltip.d.ts +7 -0
  44. package/dist/editor/SetupIncompleteBanner.d.ts +12 -0
  45. package/dist/editor/StartingStateModal.d.ts +14 -0
  46. package/dist/editor/TargetSelector.d.ts +15 -0
  47. package/dist/editor/TargetSelector.types.d.ts +2 -0
  48. package/dist/editor/WorkflowSettingsModal.d.ts +6 -1
  49. package/dist/editor/WorkflowVariablesEditor.d.ts +6 -0
  50. package/dist/editor/definition.d.ts +6 -0
  51. package/dist/editor/json-apply.d.ts +29 -0
  52. package/dist/editor/step-problems-feed.d.ts +5 -0
  53. package/dist/editor/types.d.ts +2 -2
  54. package/dist/editor-apps-DkkC7wOQ.js +152 -0
  55. package/dist/editor-apps-DkkC7wOQ.js.map +1 -0
  56. package/dist/editor-tools-BR27RGto.js +1683 -0
  57. package/dist/editor-tools-BR27RGto.js.map +1 -0
  58. package/dist/editor.mjs +1 -1
  59. package/dist/editors.mjs +855 -650
  60. package/dist/editors.mjs.map +1 -1
  61. package/dist/{endpoints-B2ynbZo-.js → endpoints-DSRo1Lc5.js} +113 -107
  62. package/dist/endpoints-DSRo1Lc5.js.map +1 -0
  63. package/dist/fields-DvS8XZFc.js +21 -0
  64. package/dist/fields-DvS8XZFc.js.map +1 -0
  65. package/dist/forms/ModelBudgetsManager.d.ts +9 -0
  66. package/dist/forms/ModelRoutesManager.d.ts +14 -0
  67. package/dist/forms.d.ts +4 -0
  68. package/dist/forms.mjs +611 -212
  69. package/dist/forms.mjs.map +1 -1
  70. package/dist/{rail-settings-XYGToh00.js → import-bindings-EUtxZ9Ti.js} +90 -24
  71. package/dist/import-bindings-EUtxZ9Ti.js.map +1 -0
  72. package/dist/index.mjs +154 -117
  73. package/dist/index.mjs.map +1 -1
  74. package/dist/lib/binding-problems.d.ts +42 -0
  75. package/dist/lib/code-rail.d.ts +4 -2
  76. package/dist/lib/history-query.d.ts +45 -0
  77. package/dist/lib/import-bindings.d.ts +89 -0
  78. package/dist/lib/index.d.ts +4 -0
  79. package/dist/lib/invoke-error.d.ts +1 -0
  80. package/dist/lib/rail-settings.d.ts +1 -1
  81. package/dist/lib/sdk-snippets.d.ts +1 -1
  82. package/dist/lib/setup-incomplete.d.ts +22 -0
  83. package/dist/lib/starting-data.d.ts +31 -0
  84. package/dist/lib/state-panel.d.ts +29 -0
  85. package/dist/lib/target-fields.d.ts +11 -15
  86. package/dist/lib/trigger-preview.d.ts +1 -0
  87. package/dist/lib/workflow-live-run.d.ts +93 -8
  88. package/dist/lib/workflow-nodes.d.ts +5 -0
  89. package/dist/lib/workflow-validity.d.ts +65 -16
  90. package/dist/lib/workflow-variables.d.ts +1 -1
  91. package/dist/lib/workflow-version.d.ts +2 -0
  92. package/dist/lib.mjs +86 -69
  93. package/dist/lists/ConnectionDependents.d.ts +31 -0
  94. package/dist/lists/ConnectionDetail.d.ts +4 -1
  95. package/dist/lists/ConnectionList.d.ts +4 -1
  96. package/dist/lists/CredentialDetail.d.ts +15 -0
  97. package/dist/lists/CredentialList.d.ts +14 -0
  98. package/dist/lists/DataStoreList.d.ts +17 -0
  99. package/dist/lists/DataStoreView.d.ts +19 -0
  100. package/dist/lists/Logs.d.ts +19 -0
  101. package/dist/lists/ModelCatalog.d.ts +12 -0
  102. package/dist/lists/ModelUsage.d.ts +12 -0
  103. package/dist/lists.d.ts +14 -0
  104. package/dist/lists.mjs +1766 -609
  105. package/dist/lists.mjs.map +1 -1
  106. package/dist/models-bAayQPJ_.js +270 -0
  107. package/dist/models-bAayQPJ_.js.map +1 -0
  108. package/dist/{project-context-BiCjv_E3.js → project-context-Tvp-La7A.js} +3 -3
  109. package/dist/{project-context-BiCjv_E3.js.map → project-context-Tvp-La7A.js.map} +1 -1
  110. package/dist/rail/ConnectionsTool.d.ts +2 -0
  111. package/dist/rail/HistoryTool.d.ts +2 -0
  112. package/dist/rail/StartingStateTool.d.ts +2 -0
  113. package/dist/rail/settings-sections.d.ts +4 -1
  114. package/dist/rail.mjs +4 -4
  115. package/dist/repos/agents-studio-agents.d.ts +52 -0
  116. package/dist/repos/agents-studio-assets.d.ts +68 -0
  117. package/dist/repos/connections.d.ts +30 -12
  118. package/dist/repos/constants.d.ts +12 -0
  119. package/dist/repos/credentials.d.ts +83 -0
  120. package/dist/repos/data-stores.d.ts +84 -0
  121. package/dist/repos/endpoints.d.ts +9 -3
  122. package/dist/repos/fields.d.ts +34 -0
  123. package/dist/repos/functions.d.ts +7 -5
  124. package/dist/repos/history.d.ts +9 -0
  125. package/dist/repos/index.d.ts +7 -0
  126. package/dist/repos/models.d.ts +289 -0
  127. package/dist/repos/spec-export.d.ts +3 -3
  128. package/dist/repos/spec-import.d.ts +30 -1
  129. package/dist/repos/step-tests.d.ts +2 -0
  130. package/dist/repos/webhook-listen.d.ts +35 -0
  131. package/dist/repos/workflows.d.ts +105 -2
  132. package/dist/repos.mjs +655 -176
  133. package/dist/repos.mjs.map +1 -1
  134. package/dist/setup-incomplete-BHs3Lpfy.js +199 -0
  135. package/dist/setup-incomplete-BHs3Lpfy.js.map +1 -0
  136. package/dist/{slug-C4ktDPdy.js → slug-BVdgiP_L.js} +64 -60
  137. package/dist/slug-BVdgiP_L.js.map +1 -0
  138. package/dist/{spec-export-Cf3VQSQS.js → spec-export-DGy5ijps.js} +73 -60
  139. package/dist/spec-export-DGy5ijps.js.map +1 -0
  140. package/dist/spec-import-SWOonsNr.js +116 -0
  141. package/dist/spec-import-SWOonsNr.js.map +1 -0
  142. package/dist/{step-tests-CivICmTq.js → step-tests-B4E4W3ly.js} +8 -7
  143. package/dist/step-tests-B4E4W3ly.js.map +1 -0
  144. package/dist/theme-context-E2ZhlXDX.js +6 -0
  145. package/dist/theme-context-E2ZhlXDX.js.map +1 -0
  146. package/dist/theme-context.d.ts +2 -0
  147. package/dist/{use-callable-draft-zHLpcr-b.js → use-callable-draft-DCauHt5o.js} +23 -23
  148. package/dist/{use-callable-draft-zHLpcr-b.js.map → use-callable-draft-DCauHt5o.js.map} +1 -1
  149. package/dist/use-workflow-draft-l3P5KZzw.js +338 -0
  150. package/dist/use-workflow-draft-l3P5KZzw.js.map +1 -0
  151. package/dist/{workflow-blank-DyL3_RUA.js → workflow-blank-DFpGObrn.js} +6 -6
  152. package/dist/{workflow-blank-DyL3_RUA.js.map → workflow-blank-DFpGObrn.js.map} +1 -1
  153. package/dist/workflows-BZN4Hyz1.js +623 -0
  154. package/dist/workflows-BZN4Hyz1.js.map +1 -0
  155. package/package.json +3 -2
  156. package/src/styles.css +155 -7
  157. package/dist/ConfirmModal-RLbZT5_k.js +0 -181
  158. package/dist/ConfirmModal-RLbZT5_k.js.map +0 -1
  159. package/dist/ImportSpecModal-BDQIf6rg.js +0 -136
  160. package/dist/ImportSpecModal-BDQIf6rg.js.map +0 -1
  161. package/dist/WorkflowEditor-DlbVv6Fs.js +0 -854
  162. package/dist/WorkflowEditor-DlbVv6Fs.js.map +0 -1
  163. package/dist/apps-1FNUwbGv.js +0 -77
  164. package/dist/apps-1FNUwbGv.js.map +0 -1
  165. package/dist/coerce-input-BicYr7nc.js +0 -139
  166. package/dist/coerce-input-BicYr7nc.js.map +0 -1
  167. package/dist/connections-CjjYeRqb.js +0 -78
  168. package/dist/connections-CjjYeRqb.js.map +0 -1
  169. package/dist/document-sources-C0grrtdq.js +0 -86
  170. package/dist/document-sources-C0grrtdq.js.map +0 -1
  171. package/dist/editor-apps-BdenSV1o.js +0 -95
  172. package/dist/editor-apps-BdenSV1o.js.map +0 -1
  173. package/dist/editor-tools-RxmY5iyi.js +0 -1279
  174. package/dist/editor-tools-RxmY5iyi.js.map +0 -1
  175. package/dist/endpoints-B2ynbZo-.js.map +0 -1
  176. package/dist/rail-settings-XYGToh00.js.map +0 -1
  177. package/dist/slug-C4ktDPdy.js.map +0 -1
  178. package/dist/spec-export-Cf3VQSQS.js.map +0 -1
  179. package/dist/spec-import-CjmxyZDR.js +0 -465
  180. package/dist/spec-import-CjmxyZDR.js.map +0 -1
  181. package/dist/step-tests-CivICmTq.js.map +0 -1
  182. package/dist/trigger-preview-VPkrryDl.js +0 -120
  183. package/dist/trigger-preview-VPkrryDl.js.map +0 -1
  184. package/dist/use-workflow-draft-DzAyUeA6.js +0 -316
  185. package/dist/use-workflow-draft-DzAyUeA6.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"editor-tools-RxmY5iyi.js","sources":["../src/chrome/workspace.tsx","../src/chrome/RightRail.tsx","../src/rail/ExpressionScope.tsx","../src/rail/CodeTool.tsx","../src/rail/rail-env.tsx","../src/rail/ErrorHandlingTool.tsx","../src/lib/tag-editor.ts","../src/chrome/TagEditor.tsx","../src/chrome/CallableSettingsModal.tsx","../src/chrome/VersionHistoryModal.tsx","../src/chrome/DangerZone.tsx","../src/rail/settings-sections.tsx","../src/rail/SettingsTool.tsx","../src/rail/editor-tools.ts"],"sourcesContent":["import type { CallablePolicy, SnippetInput, TriggerPreview } from \"@w6w/embed/lib\";\n/**\n * `WorkspaceContext` — what resource (if any) the currently-viewed page has\n * open. The right rail (`chrome/RightRail.tsx`) and every registered\n * `RailTool`'s `Panel` read this via `useWorkspaceCallable`; a page publishes\n * into it via `useWorkspace`.\n *\n * Route-scoped, not root-scoped — mirrors `ProjectContext.tsx`'s precedent\n * (the only other context in this codebase deliberately scoped below the app\n * root): mounted around `Layout()`'s own returned tree (`components/Layout.tsx`),\n * next to its only reader, the rail.\n *\n * The publish idiom (compute a value during render, `useEffect` keyed on a\n * stable serialization of it, clear on unmount) mirrors the shape of the\n * human's uncommitted `src/ui/useDocumentTitle.ts` — copied here as a\n * PATTERN, never imported: that file is one of this project's 23 uncommitted\n * human files and a merged branch cannot depend on it.\n */\nimport { type ReactNode, createContext, useContext, useEffect, useMemo, useState } from \"react\";\n\n/**\n * T2.1.2: widened to a discriminated union, one arm per kind — every new\n * field OPTIONAL, no new required member, so every existing producer keeps\n * compiling and behaving identically (`{kind, id}` alone still satisfies any\n * arm). The extra fields are what `CodeTool`'s snippet panel needs per kind\n * (mirrors `lib/sdk-snippets.ts`'s `SnippetCallable`, field-for-field where\n * the names match — see `lib/code-rail.ts`'s `toSnippetCallable` for the one\n * field that doesn't, `label` -> `displayName`).\n */\nexport type WorkspaceCallable =\n | {\n kind: \"function\";\n id: string;\n label?: string;\n key?: string;\n inputs?: readonly SnippetInput[];\n alias?: string;\n /**\n * The Function's / Endpoint's run-level error policy and its writer, published by an\n * editor that owns the definition buffer (`useCallableDraft`) so the rail's Error handling\n * tool edits and saves THAT buffer (pending edits ride along) instead of racing it. Same\n * ⚠️ as the workflow arm: `onPolicyChange` MUST be referentially stable\n * (`useCallableDraft`'s is).\n */\n policy?: CallablePolicy;\n onPolicyChange?: (policy: CallablePolicy) => void;\n }\n | {\n kind: \"endpoint\";\n id: string;\n label?: string;\n key?: string;\n invokeUrl?: string;\n invokeUrlByKey?: string;\n urlForm?: \"id\" | \"key\";\n alias?: string;\n inputs?: readonly SnippetInput[];\n /**\n * The Function's / Endpoint's run-level error policy and its writer, published by an\n * editor that owns the definition buffer (`useCallableDraft`) so the rail's Error handling\n * tool edits and saves THAT buffer (pending edits ride along) instead of racing it. Same\n * ⚠️ as the workflow arm: `onPolicyChange` MUST be referentially stable\n * (`useCallableDraft`'s is).\n */\n policy?: CallablePolicy;\n onPolicyChange?: (policy: CallablePolicy) => void;\n }\n | {\n kind: \"workflow\";\n id: string;\n label?: string;\n key?: string;\n triggers?: TriggerPreview[];\n /**\n * The workflow's run-level error policy, and the writer that applies it\n * (core Workflow RFC — *Amendment — 2026-08-21: the run-level error\n * handler*). Published ONLY by the page that owns the definition buffer\n * — the canvas editor — so the rail's Error handling tool edits the same\n * text the editor is about to save instead of racing it over the wire.\n * `ErrorHandlingTool` is the only reader; see `lib/settings-rail.ts`'s\n * `isAvailable` for why the tool hides itself when they are absent.\n *\n * ⚠️ `onPolicyChange` MUST be referentially stable across renders (a\n * `useCallback` reading through a ref). `useWorkspace` keys its publish\n * effect on `JSON.stringify(resource)`, which drops functions — so the\n * stored callback is whichever one was current when some OTHER field\n * last changed, and a closure that captured stale editor state would\n * write stale bytes.\n */\n policy?: CallablePolicy;\n onPolicyChange?: (policy: CallablePolicy) => void;\n }\n | { kind: \"connection\"; id: string; label?: string }\n | null;\n\n/** Derived from {@link WorkspaceCallable}, never redeclared — the arm a\n * `RailTool.isAvailable`/route wrapper narrows on. */\nexport type WorkspaceKind = Exclude<WorkspaceCallable, null>[\"kind\"];\n\ninterface WorkspaceContextValue {\n resource: WorkspaceCallable;\n /** Publishes the OVERRIDE slot; `null` clears it, which restores the provider's `base`. */\n setCallable: (resource: WorkspaceCallable) => void;\n}\n\nconst WorkspaceContext = createContext<WorkspaceContextValue | null>(null);\n\n/**\n * Two layers: `base` (a prop — the host-owned `{kind, id}` a `<CallableWorkspace>` publishes) and\n * an override (what a mounted page publishes with `useWorkspace`). The override wins while it is\n * set; when its publisher unmounts it is cleared and the base is shown again — never empty. With no\n * `base` (Studio's layout, the editor's own nested provider) the behaviour is exactly the old\n * single-slot one: override or `null`.\n */\nexport function WorkspaceProvider({\n children,\n base = null,\n}: { children: ReactNode; base?: WorkspaceCallable }) {\n const [override, setCallable] = useState<WorkspaceCallable>(null);\n const resource = override ?? base;\n const value = useMemo(() => ({ resource, setCallable }), [resource]);\n return <WorkspaceContext.Provider value={value}>{children}</WorkspaceContext.Provider>;\n}\n\n/** Non-throwing probe: is there an enclosing {@link WorkspaceProvider}? */\nexport function useHasWorkspace(): boolean {\n return useContext(WorkspaceContext) !== null;\n}\n\n/** Publisher. Compute during render, effect-write, clear on unmount. */\nexport function useWorkspace(resource: WorkspaceCallable): void {\n const ctx = useContext(WorkspaceContext);\n if (!ctx) throw new Error(\"useWorkspace must be used within <WorkspaceProvider>\");\n const { setCallable } = ctx;\n // A stable serialization, not `resource` itself: a fresh object literal on\n // every render of the calling page (e.g. `{kind:\"workflow\", id}` rebuilt\n // each render) must not re-fire this effect every render — only a genuine\n // change to some field's VALUE should. T2.1.2: widened from a bespoke\n // `kind:id:label` template to a full `JSON.stringify` once the union grew\n // per-kind fields (`key`/`invokeUrl`/`invokeUrlByKey`/`urlForm`/`inputs`/\n // `triggers`) a caller can update after its first publish — e.g. the\n // Endpoint editor's id/key URL-form toggle or a picked tenant domain, both\n // of which change nothing about kind/id/label. A template keyed on\n // kind/id/label alone would miss those and leave `CodeTool`'s panel showing\n // the value from the FIRST render forever (same content -> same string ->\n // no re-fire, so this preserves the original's intent exactly, just over\n // every field instead of three of them).\n const key = resource ? JSON.stringify(resource) : \"\";\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on the stable serialized `key`, not `resource`'s object identity — see the comment above.\n useEffect(() => {\n setCallable(resource);\n return () => setCallable(null);\n }, [key, setCallable]);\n}\n\n/** Reader — used by the rail and by every tool `Panel`. Throws outside the provider. */\nexport function useWorkspaceCallable(): WorkspaceCallable {\n const ctx = useContext(WorkspaceContext);\n if (!ctx) throw new Error(\"useWorkspaceCallable must be used within <WorkspaceProvider>\");\n return ctx.resource;\n}\n","import { restoreRailState } from \"@w6w/embed/lib\";\n/**\n * Third `.workspace` grid column: a 48px strip of the tools it is handed plus, when one is open,\n * its panel. Iterates `tools` with a single `.map` — never a per-tool JSX branch — so adding a\n * tool is a registry append in the host (Studio: `StudioRightRail`), nothing here changes.\n */\nimport { type ComponentType, useEffect, useState } from \"react\";\nimport { type WorkspaceCallable, useWorkspaceCallable } from \"./workspace.tsx\";\n\nexport interface RailTool {\n /** Stable; used as the persisted `activeTool`. */\n id: string;\n /** Strip tooltip + panel heading. */\n title: string;\n /** The strip glyph, as a component — built-in tools render a 16×16 `<Icon name=\"…\" />`\n * from `@w6w/ui`'s shared set; a tool may bring its own glyph instead. A component,\n * not an `IconName`, so this seam never narrows to the shared set. */\n Icon: ComponentType;\n isAvailable(ctx: WorkspaceCallable): boolean;\n /** Panel renders its own heading when it includes section actions. */\n rendersHeading?: boolean;\n Panel: ComponentType<{ ctx: WorkspaceCallable }>;\n}\n\ninterface RailState {\n open: boolean;\n activeTool: string | null;\n}\n\nconst CLOSED: RailState = { open: false, activeTool: null };\n\n/**\n * T4.1.1/A2: every mount starts CLOSED, unconditionally — `open` is no\n * longer read out of storage at all (D-I0-2). `restoreRailState`\n * (`../lib/rail-settings.ts`) only ever returns `activeTool`; its return\n * type has no `open` member, so a pre-existing `{\"open\":true,…}` value\n * written before this task has nothing here to reopen the rail with.\n */\nfunction readStoredState(key: string): RailState {\n if (typeof localStorage === \"undefined\") return CLOSED;\n const raw = localStorage.getItem(key);\n const { activeTool } = restoreRailState(raw);\n return { open: false, activeTool };\n}\n\n/** Presentational: the strip + (when open) the active tool's panel. Shared by\n * the persisted and not-yet-persistable (pin 12) render paths below. */\nfunction RailShell({\n tools,\n ctx,\n state,\n onToggle,\n}: {\n tools: readonly RailTool[];\n ctx: WorkspaceCallable;\n state: RailState;\n onToggle: (id: string) => void;\n}) {\n const activeTool = state.open ? (tools.find((t) => t.id === state.activeTool) ?? null) : null;\n return (\n <aside className=\"right-rail\">\n <div className=\"right-rail-strip\">\n {tools.map((tool) => (\n <button\n key={tool.id}\n type=\"button\"\n data-testid={`rail-tool-${tool.id}`}\n className={`right-rail-tool-btn${activeTool?.id === tool.id ? \" active\" : \"\"}`}\n title={tool.title}\n aria-label={tool.title}\n aria-pressed={activeTool?.id === tool.id}\n onClick={() => onToggle(tool.id)}\n >\n <tool.Icon />\n </button>\n ))}\n </div>\n {activeTool && (\n <div className=\"right-rail-panel\" data-testid={`rail-panel-${activeTool.id}`}>\n {!activeTool.rendersHeading && (\n <div className=\"right-rail-panel-head\">\n <h3>{activeTool.title}</h3>\n </div>\n )}\n <activeTool.Panel ctx={ctx} />\n </div>\n )}\n </aside>\n );\n}\n\n/** Owns the persisted open/activeTool state. Split out from `RightRail` and\n * `key`ed on `storageKey` (pin 11/12): `currentProject` resolves from a\n * query, so a `useState` initializer that ran before it resolved would read\n * `w6w.rail.undefined.undefined`. `RightRail` renders this component only\n * once `storageKey` is non-null, and `key={storageKey}` forces a fresh\n * mount — and so a fresh synchronous read of the RESOLVED key — whenever the\n * account/project changes. */\nfunction PersistedRail({\n storageKey,\n tools,\n ctx,\n}: {\n storageKey: string;\n tools: readonly RailTool[];\n ctx: WorkspaceCallable;\n}) {\n const [state, setState] = useState<RailState>(() => readStoredState(storageKey));\n\n // A2: only `activeTool` is ever persisted — `open` is never written to\n // storage (D-I0-2), so a fresh mount always starts closed regardless of\n // whether the rail happened to be open when the tab last closed.\n useEffect(() => {\n if (typeof localStorage === \"undefined\") return;\n localStorage.setItem(storageKey, JSON.stringify({ activeTool: state.activeTool }));\n }, [storageKey, state.activeTool]);\n\n function onToggle(id: string) {\n setState((prev) =>\n prev.open && prev.activeTool === id\n ? { open: false, activeTool: id }\n : { open: true, activeTool: id },\n );\n }\n\n return <RailShell tools={tools} ctx={ctx} state={state} onToggle={onToggle} />;\n}\n\n/** `storageKey === null`: no key to persist under yet (pin 12) — the strip renders closed and\n * nothing is written to localStorage. No available tool ⇒ no rail element at all (C/D-C3). */\nexport function RightRail({\n tools,\n storageKey,\n}: {\n tools: readonly RailTool[];\n storageKey: string | null;\n}) {\n const ctx = useWorkspaceCallable();\n const available = tools.filter((t) => t.isAvailable(ctx));\n if (available.length === 0) return null;\n if (storageKey === null) {\n return <RailShell tools={available} ctx={ctx} state={CLOSED} onToggle={() => {}} />;\n }\n return <PersistedRail key={storageKey} storageKey={storageKey} tools={available} ctx={ctx} />;\n}\n","import { type ExpressionOptions, ExpressionOptionsProvider } from \"@w6w/ui\";\nimport type { ReactNode } from \"react\";\nimport { useMemo } from \"react\";\nimport { documentSampleValues, projectDocumentSources } from \"../lib/document-sources.ts\";\n/**\n * The APP-LEVEL contribution to the ƒx expression scope — the rail every\n * expression editor starts from (Studio binds `project` to its `ProjectContext`; an embedder\n * passes its own, `null` disabling the project-scoped queries), wherever it is opened.\n *\n * ## Why this is a provider and not a hook each page calls\n *\n * The scope used to travel as an `exprOptions` PROP: each page built the same\n * ~40-line object and handed it to the one or two components it happened to\n * think of. Two things went wrong with that, and both are user-visible:\n *\n * 1. **A field the prop had not reached opened an empty editor.** On a\n * Function's Implementation card, the `ƒx` toggle on a mapping row offered\n * no variables, no secrets and no inputs — while the very same editor,\n * reached through that card's \"Change\" button, offered all of them,\n * because only the modal had been wrapped in a provider.\n * 2. **Five pages carried a copy of the same object.** `FunctionsPage`,\n * `EndpointsPage`, `AliasesPage`, `WorkflowsPage` and the connection\n * tester each restated vars, secrets, documents, `sampleValues`,\n * `sealSecret`, `createVar` and `createSecret` — because the only way to\n * add one page-specific key (`inputs`) was to restate the rest alongside\n * it.\n *\n * Mounted ONCE, inside `ProjectProvider` and around `Layout`, this fixes both:\n * every route inherits it, and a page contributes only what is genuinely its\n * own by nesting a second `ExpressionOptionsProvider` (which LAYERS — see that\n * component's own doc). A page's `inputs` therefore cannot reach a sibling\n * route or a region above it; navigating away drops it with the subtree.\n *\n * ## What belongs here, and what does not\n *\n * Here: anything true for the whole **project** — its variables, its secret\n * NAMES, its document keys, the sample values the Result pane previews against,\n * and the three host callbacks the picker's \"+ Add\"/seal affordances need.\n *\n * Not here: anything that is only true inside one editor. A Function's declared\n * `inputs`, an Endpoint's declared `input`, the upstream `steps` leading to one\n * workflow node — those are contributed by the page or the region that knows\n * about them, and must not be visible anywhere else.\n *\n * `ui` components stay pure (they never fetch): this is the host side, and only\n * names/refs cross the boundary — secret plaintext never reaches the client.\n */\nimport {\n useCreateSecretMutation,\n useCreateVarMutation,\n useDocumentsQuery,\n useSealSecret,\n useSecretsQuery,\n useVarsQuery,\n} from \"../repos/index.ts\";\n\n/**\n * The current project's expression sources, as an `ExpressionOptions`.\n *\n * Exported because a surface that renders OUTSIDE `ProjectExpressionScope` —\n * or one that needs the values themselves rather than the context — can still\n * build the same object. Inside the scope, prefer inheriting it.\n */\nexport function useProjectExpressionOptions(project: string | null): ExpressionOptions {\n const projectId = project;\n\n // Vars/secrets are subject-scoped (no project param on the secret list); the\n // vault list is masked name-only summaries, so nothing secret reaches the\n // client. Documents are project-scoped.\n const varsQuery = useVarsQuery(projectId ?? undefined, projectId != null);\n const secretsQuery = useSecretsQuery();\n const documentsQuery = useDocumentsQuery(projectId ?? undefined, projectId != null);\n const sealSecretFn = useSealSecret();\n // \"+ Add\" (T1.2.4): both mutations already invalidate the exact key their\n // `useQuery` reads (repos/vars.ts, repos/vault.ts), so a create's success\n // alone refreshes the rail — no refetch(), no local list state.\n const createVarMut = useCreateVarMutation();\n const createSecretMut = useCreateSecretMutation();\n\n return useMemo(\n () => ({\n vars: (varsQuery.data ?? []).map((v) => v.name),\n secrets: (secretsQuery.data ?? []).map((s) => s.name),\n // `document-sources.ts` owns the `format === \"json\"` gate and the raw\n // field enumeration — no parsing, no gate logic, and no filtering here\n // (A5c); `isRefSafeKey` filtering happens once, downstream, at the\n // modal's render site.\n documents: projectDocumentSources(documentsQuery.data ?? []),\n // Real project values so the ƒx Result preview substitutes them for\n // `vars.<name>` / `documents.<key>` / `documents.<key>.<field>` refs\n // instead of the raw template.\n sampleValues: {\n ...Object.fromEntries((varsQuery.data ?? []).map((v) => [`vars.${v.name}`, v.value])),\n ...documentSampleValues(documentsQuery.data ?? []),\n },\n sealSecret: sealSecretFn,\n // A created var carries the SAME project the read above carried (B3) —\n // it must land in the project whose rail asked for it. `type: \"string\"`\n // is pinned (a string type's `raw` passes through untouched) — the modal\n // has no type field.\n createVar: (input: { name: string; value: string; description?: string }) =>\n createVarMut\n .mutateAsync({\n input: {\n name: input.name,\n type: \"string\",\n value: input.value,\n description: input.description,\n },\n project: projectId ?? undefined,\n })\n .then(() => undefined),\n // Secrets carry NO project (B4) — `vault_secrets` has no `project`\n // column and the routes read no `?project=`. Plaintext in, the server\n // encrypts; the resolved value is referenced nowhere (B5).\n createSecret: (input: { name: string; value: string; description?: string }) =>\n createSecretMut\n .mutateAsync({ name: input.name, value: input.value, description: input.description })\n .then(() => undefined),\n }),\n [\n varsQuery.data,\n secretsQuery.data,\n documentsQuery.data,\n sealSecretFn,\n createVarMut.mutateAsync,\n createSecretMut.mutateAsync,\n projectId,\n ],\n );\n}\n\n/**\n * Provide the current project's expression sources to every route below.\n *\n * Mount once, inside `ProjectProvider` (it reads the active project) and around\n * `Layout` (so every page inherits). It contributes no `inputs` and no `steps`\n * on purpose — see the module doc.\n */\nexport function ProjectExpressionScope({\n project,\n children,\n}: {\n project: string | null;\n children: ReactNode;\n}) {\n const options = useProjectExpressionOptions(project);\n return <ExpressionOptionsProvider value={options}>{children}</ExpressionOptionsProvider>;\n}\n","import { Icon } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport {\n CallFromCodeBody,\n type SnippetTabId,\n snippetTabsFor,\n} from \"../chrome/CallFromCodeButton.tsx\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport type { RailTool } from \"../chrome/RightRail.tsx\";\nimport type { WorkspaceCallable } from \"../chrome/workspace.tsx\";\nimport { isAvailable, toSnippetCallable } from \"../lib/code-rail.ts\";\nimport { unavailableReason } from \"../lib/sdk-snippets.ts\";\n/**\n * The Code tool — the right rail's second registered client of T3.1.1's\n * registry seam (`src/ui/railTools.ts`), and T2.1.2's \"use code\" move: the\n * page-header \"Call from code\" button on Functions/Endpoints/Workflow-detail/\n * the flow-editor canvas becomes this strip icon + panel instead.\n *\n * The two pure decisions — is a snippet meaningful for this context, and\n * what `SnippetCallable` it converts to — live in `./../lib/code-rail.ts` so\n * `node --test` can gate them. This module owns presentation only.\n *\n * The panel is a LANGUAGE PICKER, not a snippet. It used to render\n * `CallFromCodeBody` inline, and a snippet is not readable in a ~395px\n * column: it scrolled sideways, and wrapping it (the first fix) turned the\n * CLI snippet's deliberate `\\`-continuations into what reads as separate\n * commands. Both are symptoms of the same thing — the snippet needs width the\n * rail does not have.\n *\n * So the rail shows one icon per language the resource can be called in, and\n * each opens the full-width modal ALREADY ON THAT LANGUAGE: one click to the\n * thing you came for, rather than open-then-hunt-for-the-tab. The set of\n * languages comes from `snippetTabsFor`, the same filter the modal's own tab\n * strip applies, so the rail can never offer a language the modal would not.\n */\n\nfunction CodePanel({ ctx }: { ctx: WorkspaceCallable }) {\n // Which language the modal opens on, or `null` for closed. ONE piece of\n // state, not an `open` flag beside a `tab`: the two can never disagree, and\n // \"closed\" cannot carry a stale language into the next open.\n const [openTab, setOpenTab] = useState<SnippetTabId | null>(null);\n const snippetCallable = toSnippetCallable(ctx);\n // Defensive: `isAvailable` already keeps this tool off the strip for a\n // `ctx` this can't build a snippet for — mirrors `SettingsTool.tsx`'s own\n // note about `Panel` still needing to handle a ctx `isAvailable` would\n // have excluded (a persisted `activeTool` plus an in-app transition to a\n // non-publishing route can still render this Panel).\n if (!snippetCallable) return null;\n const triggers = ctx?.kind === \"workflow\" ? ctx.triggers : undefined;\n const tabs = snippetTabsFor(snippetCallable);\n\n // No languages means no snippet at all — say why, rather than draw an empty\n // row of icons. Same sentence the body itself would have shown.\n if (tabs.length === 0) return <p className=\"muted\">{unavailableReason(snippetCallable)}</p>;\n\n return (\n <div>\n {/* A LANGUAGE PICKER, not a snippet.\n\n The rail's panel is ~395px wide, and a snippet rendered into it was\n unreadable at that width — first because it scrolled sideways, then,\n once wrapped, because a wrapped shell command reads as two commands.\n Neither is fixable in 395px: the snippet needs the room.\n\n So the panel stops trying to show one. It shows the languages this\n resource can be called in, and each opens the full-width modal\n ALREADY ON THAT LANGUAGE — one click to the thing you came for,\n instead of open-then-hunt-for-the-tab. The languages come from\n `snippetTabsFor`, so a resource with no public URL simply has no curl\n icon rather than an icon that opens an empty tab.\n\n Still not the double-chrome `CallFromCodeButton.tsx`'s header warns\n about: that trap was wrapping the rail's own panel in a modal by\n DEFAULT. The panel is its own content here; the modal is opt-in. */}\n <p className=\"muted small\" style={{ marginTop: 0 }}>\n Call this from:\n </p>\n <div className=\"rail-code-langs\">\n {tabs.map(({ id, label, icon }) => (\n <button\n key={id}\n type=\"button\"\n className=\"rail-code-lang\"\n data-testid={`rail-code-lang-${id}`}\n title={`Show the ${label} snippet`}\n aria-label={`Show the ${label} snippet`}\n onClick={() => setOpenTab(id)}\n >\n <Icon name={icon} size={20} />\n <span>{label}</span>\n </button>\n ))}\n </div>\n\n {/* Conditionally rendered, so each open MOUNTS the body afresh and\n `initialTab` seeds it again — picking Python, closing, then picking\n Node lands on Node. A body kept mounted would keep the first pick. */}\n {openTab !== null && (\n <Modal title=\"Call from code\" wide onClose={() => setOpenTab(null)}>\n <div style={{ height: 450 }}>\n <CallFromCodeBody resource={snippetCallable} triggers={triggers} initialTab={openTab} />\n </div>\n </Modal>\n )}\n </div>\n );\n}\n\nfunction CodeToolIcon() {\n return <Icon name=\"code\" />;\n}\n\nexport const codeTool: RailTool = {\n id: \"code\",\n title: \"Code\",\n Icon: CodeToolIcon,\n isAvailable: (ctx) => isAvailable(ctx),\n Panel: CodePanel,\n};\n","/**\n * The rail's host environment — the two things a rail tool needs from the host that it cannot\n * own: which project the surface is looking at, and how to move the host somewhere after a\n * rail action (archive / delete land on the list; an import opens the imported row).\n *\n * Studio binds both to its router and `ProjectContext`; an embedder binds them to its own. A\n * rail tool never imports a router: it calls `onNavigate` with a target and the host decides what\n * that means. The default (no provider mounted) is inert — no project, navigation ignored — so a\n * tool rendered outside a provider cannot save into the wrong project or throw.\n *\n * `project` is passed through to every write VERBATIM; `null` means \"no project\", on which the\n * package hooks refuse to save (never a fallback to the account default, C/D-C2).\n */\nimport { type ReactNode, createContext, useContext } from \"react\";\nimport type { SpecImportKind } from \"../lib/spec-import-invalidation.ts\";\n\n/** Where the host should go after a rail action. */\nexport type RailNavigation =\n | { type: \"list\" }\n | { type: \"imported\"; kind: SpecImportKind; id: string };\n\nexport interface RailEnv {\n project: string | null;\n onNavigate(to: RailNavigation): void;\n}\n\nconst DEFAULT_ENV: RailEnv = { project: null, onNavigate: () => {} };\n\nconst RailEnvContext = createContext<RailEnv>(DEFAULT_ENV);\n\nexport function RailEnvProvider({\n project,\n onNavigate,\n children,\n}: RailEnv & { children: ReactNode }) {\n return (\n <RailEnvContext.Provider value={{ project, onNavigate }}>{children}</RailEnvContext.Provider>\n );\n}\n\nexport function useRailEnv(): RailEnv {\n return useContext(RailEnvContext);\n}\n","import { ApiError } from \"@w6w/sdk\";\n/**\n * The Error handling tool — the right rail's tool for choosing **what runs when a call fails**.\n *\n * It is a BUTTON, not a form. Clicking it opens the F-2.0 picker modal (`StepBuilderModal`) with\n * its Functions and Workflows tabs, and the pick becomes the resource's `reroute.target`. All\n * three handler shapes are offered: an app Action, a Function, or a Workflow.\n *\n * This module owns two things:\n * - `ErrorHandlerSection` — the shared body (picker, handler label lookup, self-decision,\n * retry / reroute fields and the inline error). It calls no definition query and no save\n * mutation: the caller hands in the `policy` it read and an `onPersist` that writes.\n * - `errorHandlingTool` — the registry entry for all three kinds. A Workflow, and a Function /\n * Endpoint whose editor published `ctx.onPolicyChange`, hand the policy back to the surface\n * that owns the definition buffer, which folds it into the JSON it is already saving (the\n * rail makes zero writes — racing an editor's own save is not an option, see\n * `lib/settings-rail.ts`'s `isAvailable`). A Function / Endpoint with NO published writer\n * reads the cached record (`callableRecord`) and read-modify-writes the whole definition\n * (`definitionWithPolicy`) through the guarded save with that record's `updatedAt`.\n *\n * For a Workflow this is the handler for the RUN AS A WHOLE (core Workflow RFC — *Amendment —\n * 2026-08-21: the run-level error handler*), which is a different question from a step's own\n * `onError` on the canvas and from an `Edge.when: \"error\"`. `retry` IS authored here, through\n * `@w6w/ui`'s `RetryPolicyFields` (core Workflow RFC R-2, \"one retry shape everywhere\").\n */\nimport { type BuiltStep, Icon, RetryPolicyFields, StepBuilderModal } from \"@w6w/ui\";\nimport { useEffect, useState } from \"react\";\nimport type { RailTool } from \"../chrome/RightRail.tsx\";\nimport type { WorkspaceCallable } from \"../chrome/workspace.tsx\";\nimport { callableRecord } from \"../lib/callable-record.ts\";\nimport { errorHandlerSelfDecision } from \"../lib/error-handler-self.ts\";\nimport {\n type CallablePolicy,\n isAvailable as isSettingsRailAvailable,\n policyFromDefinition,\n} from \"../lib/settings-rail.ts\";\nimport { definitionWithPolicy } from \"../lib/settings-rail.ts\";\nimport { useEndpointQuery, useGuardedSaveEndpointMutation } from \"../repos/endpoints.ts\";\nimport {\n useFunctionQuery,\n useFunctionsQuery,\n useGuardedSaveFunctionMutation,\n} from \"../repos/functions.ts\";\nimport { useWorkflowsQuery } from \"../repos/workflows.ts\";\nimport { useRailEnv } from \"./rail-env.tsx\";\n\n/**\n * `@w6w/ui/flow`'s `CALL_APP`, restated: a VALUE import from the flow subpath would put the whole\n * canvas on the editor's eager path (the editor loads it with a dynamic `import()` only). A test\n * (`workflow-editor.test.ts`) pins the two spellings equal.\n */\nexport const CALL_APP = \"@w6w/call\";\n\ntype ErrorHandlerTarget = NonNullable<NonNullable<CallablePolicy[\"reroute\"]>[\"target\"]>;\n\nexport type ErrorHandlerKind = \"function\" | \"endpoint\" | \"workflow\";\n\n/** The id a handler target names, whichever of the three arms it is. */\nfunction refOf(target: ErrorHandlerTarget | undefined): string {\n if (!target) return \"\";\n if (target.kind === \"workflow\") return target.workflow;\n if (target.kind === \"function\") return target.function;\n return `${target.uses.app}/${target.uses.action}`;\n}\n\n/** The noun shown under a bound handler. */\nfunction nounOf(target: ErrorHandlerTarget | undefined): string {\n if (target?.kind === \"workflow\") return \"Workflow (asynchronous)\";\n if (target?.kind === \"function\") return \"Function (synchronous)\";\n return \"App action (synchronous)\";\n}\n\nexport interface ErrorHandlerSectionProps {\n kind: ErrorHandlerKind;\n id: string;\n /** The policy as currently stored (already read off the definition or buffer). */\n policy: CallablePolicy;\n /** The definition (or buffer) the policy was read from is present. */\n ready: boolean;\n saving: boolean;\n /** Write a whole new policy. `onError` shows a refusal inline. */\n onPersist(next: CallablePolicy, onError: (message: string) => void): void;\n}\n\nexport function ErrorHandlerSection({\n kind,\n id,\n policy,\n ready,\n saving,\n onPersist,\n}: ErrorHandlerSectionProps) {\n // Name the bound handler rather than showing a bare id. Both lists are already cached by the\n // picker itself, so this costs no extra round-trip in the common case.\n const functionsQuery = useFunctionsQuery(true);\n // The editor's project (RailEnv, as the Settings tool reads it), never the provider's default:\n // a project-less list would go out as the provider's project, not the one being edited.\n const { project } = useRailEnv();\n const workflowsQuery = useWorkflowsQuery(project ?? undefined, true);\n\n const [pickerOpen, setPickerOpen] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const target = policy.reroute?.target;\n const ref = refOf(target);\n const selfDecision = target\n ? errorHandlerSelfDecision({\n resource: { kind, id },\n target: { kind: target.kind, id: ref },\n hasAdapter: policy.reroute?.with !== undefined,\n })\n : \"allow\";\n const label =\n target?.kind === \"workflow\"\n ? (workflowsQuery.data?.find((w) => w.id === ref)?.displayName ?? undefined)\n : (() => {\n const fn = functionsQuery.data?.find((f) => f.id === ref);\n return fn ? fn.displayName || fn.key : undefined;\n })();\n\n // The rail remains mounted while its resource changes. A refusal belonging to the previous\n // resource must not obscure the current policy.\n useEffect(() => {\n if (id && kind) setError(null);\n }, [id, kind]);\n\n /** Persist a whole new policy — the one write path, shared by pick and clear. */\n function persist(next: CallablePolicy) {\n setError(null);\n onPersist(next, setError);\n }\n\n /**\n * The picker's `onAdd`. Two shapes reach here, because all three handler arms are offered:\n * - a callable → `{ uses: {app: \"@w6w/call\", …}, with: {targetKind, targetId} }`\n * - an action → `{ uses: {app, action, connection}, with }`\n * A graph-only internal node (`@w6w/script`, `@w6w/control`, …) is refused — `appsOnly` means no\n * such tab is rendered, but a `BuiltStep` is a wide type and a silent mis-write would be\n * invisible.\n */\n function pickHandler(built: BuiltStep) {\n let nextTarget: ErrorHandlerTarget;\n if (built.uses.app === CALL_APP) {\n const w = (built.with ?? {}) as { targetKind?: unknown; targetId?: unknown };\n const nextId = typeof w.targetId === \"string\" ? w.targetId : \"\";\n if (!nextId) return;\n nextTarget =\n w.targetKind === \"workflow\"\n ? { kind: \"workflow\", workflow: nextId }\n : { kind: \"function\", function: nextId };\n } else if (!built.uses.app.startsWith(\"@w6w/\")) {\n // The app arm. `with` is the action's own param map, straight from the picker's Configure\n // stage — it is `ActionTarget.with`, which `error-handler.ts` reads in preference to the\n // general `reroute.with`.\n nextTarget = {\n kind: \"action\",\n uses: {\n app: built.uses.app,\n action: built.uses.action,\n connection: built.uses.connection ?? undefined,\n },\n ...(built.with ? { with: built.with } : {}),\n };\n } else {\n return;\n }\n const nextDecision = errorHandlerSelfDecision({\n resource: { kind, id },\n target: { kind: nextTarget.kind, id: refOf(nextTarget) },\n hasAdapter: policy.reroute?.with !== undefined,\n });\n if (nextDecision === \"block\") {\n setError(\n \"This handler would call itself with the same inputs and can loop forever. Choose another handler or keep a differing imported adapter.\",\n );\n setPickerOpen(false);\n return;\n }\n // Preserve `reroute.with` if one was already authored elsewhere — this tool changes WHICH\n // handler runs, never the mapping onto it.\n persist({ ...policy, reroute: { ...policy.reroute, target: nextTarget } });\n setPickerOpen(false);\n }\n\n if (!ready && !saving) {\n return <p className=\"muted small\">Loading…</p>;\n }\n\n return (\n <div className=\"w6w-stack\" data-testid=\"rail-errorhandling-body\">\n {/* Retries run BEFORE the handler below, so the section renders first. */}\n <section data-testid=\"rail-retry-section\">\n <RetryPolicyFields\n value={policy.retry}\n onChange={(next) => persist({ ...policy, retry: next })}\n readOnly={saving}\n target={kind}\n />\n {kind === \"workflow\" && (\n <p className=\"muted small\" data-testid=\"rail-retry-run-warning\">\n Retrying re-runs the whole workflow from its first step, so steps that already succeeded\n run again. For a step that must not repeat (a send or a charge), set retry on that step\n instead.\n </p>\n )}\n </section>\n\n <p className=\"muted small\">\n {kind === \"workflow\"\n ? \"What runs when this workflow's run fails, after every step's own retry is spent.\"\n : \"What runs when this call fails, after retry (if any) is exhausted.\"}\n </p>\n\n {ref ? (\n <div className=\"row\" style={{ alignItems: \"center\", gap: 8 }}>\n <span className=\"list-main\">\n <strong>{label ?? ref}</strong> <code className=\"muted\">{ref}</code>\n <span className=\"muted small block\">{nounOf(target)}</span>\n </span>\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid=\"rail-errorhandling-change\"\n disabled={saving}\n onClick={() => setPickerOpen(true)}\n >\n Change\n </button>\n </div>\n ) : (\n <button\n type=\"button\"\n className=\"btn\"\n data-testid=\"rail-errorhandling-choose\"\n disabled={saving}\n onClick={() => setPickerOpen(true)}\n >\n + Choose what runs on failure\n </button>\n )}\n\n {ref && (\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid=\"rail-errorhandling-clear\"\n disabled={saving}\n onClick={() => persist({ ...policy, reroute: undefined })}\n >\n Remove handler\n </button>\n )}\n\n {selfDecision === \"warn\" && (\n <div className=\"result error\" data-testid=\"rail-errorhandling-self-caution\">\n This handler targets itself. Its imported input adapter is preserved; the server will\n refuse it if it resolves to the failed call's same inputs.\n </div>\n )}\n\n {error && (\n <div className=\"error\" data-testid=\"rail-errorhandling-error\">\n {error}\n </div>\n )}\n\n {pickerOpen && (\n <StepBuilderModal\n appsOnly\n callables={[\"function\", \"workflow\"] as const}\n title=\"Choose what runs on failure\"\n onClose={() => setPickerOpen(false)}\n onAdd={pickHandler}\n />\n )}\n </div>\n );\n}\n\n/**\n * The buffer arm: policy read off the host's buffer (`ctx.policy`), written back through\n * `ctx.onPolicyChange`. A workflow's only arm; a function / endpoint's when an editor owns the\n * buffer.\n */\nfunction BufferErrorHandlingPanel({ ctx }: { ctx: Exclude<WorkspaceCallable, null> }) {\n const policy = \"policy\" in ctx ? ctx.policy : undefined;\n const onPolicyChange = \"onPolicyChange\" in ctx ? ctx.onPolicyChange : undefined;\n return (\n <ErrorHandlerSection\n kind={ctx.kind as ErrorHandlerKind}\n id={ctx.id}\n policy={policy ? policyFromDefinition(policy) : {}}\n ready={Boolean(onPolicyChange)}\n saving={false}\n onPersist={(next) => onPolicyChange?.(next)}\n />\n );\n}\n\n/** The cache arm: a function / endpoint with no published writer saves from the cached record. */\nfunction CachedErrorHandlingPanel({ id, kind }: { id: string; kind: \"function\" | \"endpoint\" }) {\n const fnQuery = useFunctionQuery(id, kind === \"function\");\n const epQuery = useEndpointQuery(id, kind === \"endpoint\");\n const saveFnMut = useGuardedSaveFunctionMutation();\n const saveEpMut = useGuardedSaveEndpointMutation();\n\n const record = callableRecord(kind, kind === \"function\" ? fnQuery.data : epQuery.data);\n const saving = kind === \"function\" ? saveFnMut.isPending : saveEpMut.isPending;\n\n return (\n <ErrorHandlerSection\n kind={kind}\n id={id}\n policy={record ? policyFromDefinition(record.definition) : {}}\n ready={Boolean(record)}\n saving={saving}\n onPersist={(next, onError) => {\n if (!record) return;\n const vars = {\n definition: definitionWithPolicy(record.definition, next),\n ifUnmodifiedSince: record.updatedAt,\n };\n const settled = {\n onError: (e: unknown) => onError(e instanceof ApiError ? e.message : String(e)),\n };\n if (kind === \"function\") saveFnMut.mutate(vars, settled);\n else saveEpMut.mutate(vars, settled);\n }}\n />\n );\n}\n\nfunction ErrorHandlingPanel({ ctx }: { ctx: WorkspaceCallable }) {\n // Defensive: a persisted `activeTool` can render this Panel with a ctx this tool has no handler\n // for.\n if (ctx?.kind !== \"workflow\" && ctx?.kind !== \"function\" && ctx?.kind !== \"endpoint\") {\n return null;\n }\n if (ctx.kind === \"workflow\" || typeof ctx.onPolicyChange === \"function\") {\n return <BufferErrorHandlingPanel ctx={ctx} />;\n }\n return <CachedErrorHandlingPanel id={ctx.id} kind={ctx.kind} />;\n}\n\nfunction ErrorHandlingToolIcon() {\n return <Icon name=\"warning\" />;\n}\n\nexport const errorHandlingTool: RailTool = {\n id: \"error-handling\",\n title: \"Error handling\",\n Icon: ErrorHandlingToolIcon,\n isAvailable: (ctx) => isSettingsRailAvailable(ctx),\n Panel: ErrorHandlingPanel,\n};\n","/**\n * Pure decision logic behind `../components/TagEditor.tsx` — kept out of the\n * component so `node --test` can exercise it directly\n * (`__tests__/tag-editor.test.ts`) without touching React, mirroring\n * `alias-rail.ts`/`rail-settings.ts`'s own split. Carries over the retiring\n * `WorkflowsPage.tsx`'s retired tags-editing modal's data contract verbatim:\n * `string[]`, trim, dedupe-on-add, drop empties.\n */\n\n/**\n * Applies a chip input's freeform text to the committed tag list. Called on\n * every change to the trailing, not-yet-committed input — `typed` is always\n * the FULL current value of just that one input, which resets to `\"\"` after\n * a commit, so a single keystroke never carries more than the one character\n * just typed.\n *\n * A comma anywhere in `typed` is the commit signal: every comma-delimited\n * segment is trimmed and, if non-empty and not already present, appended as\n * a chip — in order, regardless of whether it sits before or after the last\n * comma. That is what makes both shapes work from the one rule: typing\n * `\"alpha,\"` one character at a time commits `\"alpha\"` the moment the comma\n * lands, and pasting `\"a,b,c\"` in one go (no trailing comma at all) still\n * commits all three, because nothing here treats \"the last segment\" as\n * special. The returned `typed` is always `\"\"` once a comma triggered a\n * commit. With no comma present at all, nothing commits and `typed` passes\n * through unchanged, so the caller can just store it as the next draft.\n */\nexport function commitTag(tags: string[], typed: string): { tags: string[]; typed: string } {\n if (!typed.includes(\",\")) return { tags, typed };\n let next = tags;\n for (const raw of typed.split(\",\")) {\n const t = raw.trim();\n if (t && !next.includes(t)) next = [...next, t];\n }\n return { tags: next, typed: \"\" };\n}\n\n/**\n * Removes exactly one tag by VALUE, never by position — a list carrying both\n * a tag and a second tag that merely contains it as a prefix (`[\"ab\", \"b\"]`)\n * only ever loses the exact match.\n */\nexport function removeTag(tags: string[], tag: string): string[] {\n return tags.filter((t) => t !== tag);\n}\n","import { IconButton } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { commitTag, removeTag } from \"../lib/tag-editor.ts\";\n\n/**\n * A chip input for a workflow's free-form tags: type text, `,` commits the\n * typed value as a chip (or paste a whole comma-separated list to commit\n * several at once — `../lib/tag-editor.ts`'s `commitTag`), each chip carries\n * an `×` to remove it, and a still-typable tail follows the chips — one\n * control, not a stacked input-above-list.\n *\n * Built fresh (T2.2.1) rather than extended from the retiring\n * `WorkflowsPage.tsx` tags-editing modal: that component was a submit-button\n * \"Add\" form with its own inline add/remove branching, a different\n * interaction shape from a comma-commits chip editor. The shared data\n * contract (trim, dedupe-on-add, drop empties) now lives in\n * `../lib/tag-editor.ts`'s\n * `commitTag`/`removeTag`, so this component holds no branching of its own —\n * it only calls them and renders the result. Controlled, mirroring\n * `InputListEditor.tsx`'s shape: the caller owns `tags`, this component owns\n * only the not-yet-committed typed tail.\n */\nexport interface TagEditorProps {\n tags: string[];\n onChange: (next: string[]) => void;\n}\n\nexport function TagEditor({ tags, onChange }: TagEditorProps) {\n const [typed, setTyped] = useState(\"\");\n\n function handleTypedChange(value: string) {\n const result = commitTag(tags, value);\n setTyped(result.typed);\n if (result.tags !== tags) onChange(result.tags);\n }\n\n return (\n <div className=\"tag-list\" data-testid=\"tag-editor\">\n {tags.map((t) => (\n <span key={t} className=\"tag removable\">\n {t}\n <IconButton\n danger\n icon=\"close\"\n label={`Remove tag ${t}`}\n title={`Remove ${t}`}\n onClick={() => onChange(removeTag(tags, t))}\n />\n </span>\n ))}\n <input\n type=\"text\"\n value={typed}\n placeholder=\"Add a tag…\"\n aria-label=\"New tag\"\n onChange={(e) => handleTypedChange(e.target.value)}\n />\n </div>\n );\n}\n","import { filterKeyInput, isEndpointKey } from \"@w6w/embed/lib\";\n/**\n * Unified settings modal for editing name, key, and tags (workflow only)\n * in a single dialog. Replaces separate Edit Key and Edit Tags modals.\n * Supports Function, Endpoint, and Workflow kinds.\n *\n * T4.2.1: every kind-shaped decision this component used to make inline — may\n * the key be typed at all, does this kind store tags, which placeholder goes in\n * which field — now comes from `CALLABLE_DESCRIPTORS[kind].settings`\n * (`lib/callable-descriptors.ts`). There is deliberately **no `kind ===` left in\n * this file**: a fourth kind, or a copy change, is an edit to the descriptor\n * table and to nothing else. The rendered output is byte-identical to before —\n * same labels, same placeholders, same hint sentence, same conditional Tags\n * section.\n */\nimport { descriptorFor } from \"@w6w/embed/repos\";\nimport { ApiError } from \"@w6w/sdk\";\nimport { useEnterSubmit } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { Modal } from \"./Modal.tsx\";\nimport { TagEditor } from \"./TagEditor.tsx\";\n\ninterface CallableSettingsModalProps {\n kind: \"function\" | \"endpoint\" | \"workflow\";\n id: string;\n initial: {\n displayName: string;\n key: string | null;\n tags?: string[]; // workflow only\n };\n onSave: (data: {\n displayName: string;\n key: string | null;\n tags?: string[];\n }) => Promise<void>;\n onClose: () => void;\n}\n\nexport function CallableSettingsModal(props: CallableSettingsModalProps) {\n // The one kind lookup this component makes. `settings` then answers every\n // per-kind question below, including which of the three `initial` fields this\n // kind even has.\n const settings = descriptorFor(props.kind).settings;\n const { initial } = props;\n const [displayName, setDisplayName] = useState(initial.displayName);\n const [key, setKey] = useState(initial.key ?? \"\");\n const [tags, setTags] = useState<string[]>(initial.tags ?? []);\n const [isSaving, setIsSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const displayNameChanged = displayName !== initial.displayName;\n const keyChanged = key !== (initial.key ?? \"\");\n const tagsChanged =\n settings.hasTags && JSON.stringify(tags) !== JSON.stringify(initial.tags ?? []);\n const isDirty = displayNameChanged || keyChanged || tagsChanged;\n\n // Key can be edited for function/workflow only (not endpoint)\n const canEditKey = settings.canEditKey;\n const keyGrammarOk = key === \"\" || isEndpointKey(key);\n const canSubmit = isDirty && keyGrammarOk && !isSaving;\n\n async function handleSave() {\n if (!canSubmit) return;\n setError(null);\n setIsSaving(true);\n try {\n await props.onSave({\n displayName: displayName.trim(),\n key: canEditKey && keyChanged ? key : initial.key,\n tags: settings.hasTags ? tags : undefined,\n });\n props.onClose();\n } catch (e) {\n setError(e instanceof ApiError ? e.message : String(e));\n } finally {\n setIsSaving(false);\n }\n }\n\n const enterSubmit = useEnterSubmit(handleSave, { enabled: canSubmit });\n\n return (\n <Modal title=\"Edit settings\" onClose={props.onClose}>\n <div className=\"modal-body\">\n <label className=\"field\">\n <span>Name</span>\n <input\n type=\"text\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n placeholder={settings.namePlaceholder}\n autoFocus\n {...enterSubmit}\n />\n </label>\n\n {canEditKey && (\n <label className=\"field\">\n <span>Key</span>\n <input\n type=\"text\"\n value={key}\n onChange={(e) => setKey(filterKeyInput(e.target.value))}\n placeholder={settings.keyPlaceholder}\n {...enterSubmit}\n />\n <span className=\"muted small\">\n Lowercase, kebab-case, 3–39 characters.\n {settings.keyHintSuffix}\n </span>\n </label>\n )}\n\n {settings.hasTags && (\n <div>\n <p className=\"muted small\" style={{ marginBottom: \"8px\" }}>\n Tags\n </p>\n <TagEditor tags={tags} onChange={setTags} />\n </div>\n )}\n\n {error && <div className=\"error\">{error}</div>}\n </div>\n\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Cancel\n </button>\n <button type=\"button\" className=\"btn\" disabled={!canSubmit} onClick={handleSave}>\n {isSaving ? \"Saving…\" : \"Save\"}\n </button>\n </div>\n </Modal>\n );\n}\n","import {\n type VersionsKind,\n useInvokeVersionMutation,\n useRevertMutation,\n useVersionQuery,\n} from \"@w6w/embed/repos\";\nimport { ApiError } from \"@w6w/sdk\";\nimport { CodeBlock } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { ConfirmModal } from \"./ConfirmModal.tsx\";\nimport { Modal } from \"./Modal.tsx\";\n\n/**\n * P2's `<collection>-version-*` testid scheme, spelled out literally per kind rather than built\n * by string interpolation — mirrors `ImportSpecModal.tsx`'s own `TESTIDS` reasoning: this file's\n * own kind arms stay the exact byte strings a page-guard suite would assert against, verifiable\n * by a plain substring search rather than only by running the browser suite.\n */\nconst TESTIDS: Record<\n VersionsKind,\n {\n json: string;\n error: string;\n revertButton: string;\n invokeButton: string;\n invokeJson: string;\n invokeError: string;\n }\n> = {\n function: {\n json: \"functions-version-json\",\n error: \"functions-version-error\",\n revertButton: \"functions-version-revert\",\n invokeButton: \"functions-version-invoke\",\n invokeJson: \"functions-version-invoke-json\",\n invokeError: \"functions-version-invoke-error\",\n },\n workflow: {\n json: \"workflows-version-json\",\n error: \"workflows-version-error\",\n revertButton: \"workflows-version-revert\",\n invokeButton: \"workflows-version-invoke\",\n invokeJson: \"workflows-version-invoke-json\",\n invokeError: \"workflows-version-invoke-error\",\n },\n endpoint: {\n json: \"endpoints-version-json\",\n error: \"endpoints-version-error\",\n revertButton: \"endpoints-version-revert\",\n invokeButton: \"endpoints-version-invoke\",\n invokeJson: \"endpoints-version-invoke-json\",\n invokeError: \"endpoints-version-invoke-error\",\n },\n};\n\n/**\n * Version viewer for Function/Workflow/Endpoint (T3.1.1, extended by T5.3.1): one\n * kind-parametrized component, mirroring `ImportSpecModal.tsx:12-46`'s established shape (a\n * `kind` prop plus per-kind `TESTIDS`, one component mounted from more than one place rather than\n * three near-copies). This project mounts it from `SettingsTool.tsx` only — the component\n * boundary exists so a second mount point later costs one line.\n *\n * Renders the version's own read-only definition through the same two primitives\n * `SettingsTool.tsx`'s existing Export modal already uses — the studio-local `Modal` and\n * `@w6w/ui`'s `CodeBlock` — plus, since T5.3.1, two live actions:\n *\n * - **\"Revert to this version\"** — confirmed via the studio-local `ConfirmModal` (P2-D4:\n * `./ConfirmModal.tsx`, never `@w6w/ui`'s), rendered as a SIBLING of `<Modal>` in\n * the returned fragment, never nested inside it. Overwrites the LIVE resource's `definition`\n * with this version's content, preserving its `key`/address (HITL-4's pinned default).\n * - **\"Invoke this version\"** — one click, NO confirm (ruling #12: an invoke is a call, not a\n * write to the resource, and the LIVE invoke action it mirrors carries no confirm either). Runs\n * this version's own archived definition, never the live one, and renders the response body\n * inline via `CodeBlock`, or a failure inline via the `ApiError` idiom (never a thrown error, a\n * blank modal, or a browser dialog).\n *\n * Both actions read `kind`/`id`/`versionNumber` from props, and both mutations are fresh\n * `useMutation` instances scoped to this component instance — since `SettingsTool.tsx`'s\n * `openVersion` gate fully unmounts/remounts this component per version rather than swapping\n * props on a surviving instance, any prior invoke result or error is gone the moment a different\n * version is opened.\n *\n * Amendments #5/#6 (project.md, Phase 2) supersede the earlier pin that made both of the above\n * out of scope (HITL-2's \"invocation always runs the live definition\"; Amendment #5's \"restore is\n * out of scope, not even a disabled button\").\n */\nexport function VersionHistoryModal(props: {\n kind: VersionsKind;\n id: string;\n versionNumber: number;\n onClose: () => void;\n}) {\n const { kind, id, versionNumber } = props;\n const testids = TESTIDS[kind];\n // Always enabled: this component only ever mounts once a specific version has been picked\n // (the caller renders it conditionally), mirroring the Export modal's own \"mounted while open\"\n // gate rather than re-deriving a second `enabled` flag here.\n const versionQuery = useVersionQuery(kind, id, versionNumber, true);\n const revertMut = useRevertMutation(kind);\n const invokeMut = useInvokeVersionMutation(kind);\n const [confirmingRevert, setConfirmingRevert] = useState(false);\n\n return (\n <>\n <Modal title={`Version ${versionNumber}`} onClose={props.onClose} wide>\n <div className=\"modal-body\">\n {versionQuery.isLoading ? (\n <p className=\"muted small\">Loading…</p>\n ) : versionQuery.isError ? (\n <div className=\"error\" data-testid={testids.error}>\n {versionQuery.error instanceof Error\n ? versionQuery.error.message\n : String(versionQuery.error)}\n </div>\n ) : versionQuery.data ? (\n <div data-testid={testids.json}>\n <CodeBlock\n code={JSON.stringify(versionQuery.data.definition, null, 2)}\n language=\"json\"\n maxHeight=\"420px\"\n copyable\n />\n </div>\n ) : null}\n\n {invokeMut.data !== undefined && (\n <div data-testid={testids.invokeJson}>\n <CodeBlock\n code={JSON.stringify(invokeMut.data, null, 2)}\n language=\"json\"\n maxHeight=\"240px\"\n copyable\n />\n </div>\n )}\n {invokeMut.isError && (\n <div className=\"error\" data-testid={testids.invokeError}>\n {invokeMut.error instanceof ApiError\n ? invokeMut.error.message\n : String(invokeMut.error)}\n </div>\n )}\n </div>\n\n <div className=\"modal-actions\">\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid={testids.invokeButton}\n disabled={invokeMut.isPending}\n onClick={() => invokeMut.mutate({ id, versionNumber })}\n >\n {invokeMut.isPending ? \"Invoking…\" : \"Invoke this version\"}\n </button>\n <button\n type=\"button\"\n className=\"btn danger\"\n data-testid={testids.revertButton}\n disabled={revertMut.isPending}\n onClick={() => setConfirmingRevert(true)}\n >\n {revertMut.isPending ? \"Reverting…\" : \"Revert to this version\"}\n </button>\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Close\n </button>\n </div>\n </Modal>\n {confirmingRevert && (\n <ConfirmModal\n title=\"Revert to this version\"\n message={`Revert to version ${versionNumber}? This restores its content onto the resource's current draft; the resource's key and address stay unchanged.`}\n confirmLabel=\"Revert\"\n destructive\n onConfirm={() => {\n setConfirmingRevert(false);\n revertMut.mutate({ id, versionNumber });\n }}\n onClose={() => setConfirmingRevert(false)}\n />\n )}\n </>\n );\n}\n","/**\n * T4.1.1/A3: the rail Settings panel's bottom \"danger zone\" — Archive (until\n * archived) then Delete, behind a visibly red confirmation panel — extracted\n * out of `src/ui/rail/SettingsTool.tsx` so Function, Endpoint and Workflow\n * render the EXACT same markup instead of three near-identical branches.\n * T1.3.1 had already moved all three kinds' Archive/Delete into one file, but\n * left them as three separate JSX arms that had drifted out of sync — only\n * Workflow's delete copy said the deletion was permanent (A5). This\n * extraction is what stops a fourth kind (or a future edit to one arm) from\n * silently reintroducing that gap: per-kind variance arrives entirely as\n * props, and there is exactly one archive-vs-delete branch to read.\n *\n * Presentational only, mirroring `@w6w/ui`'s own `DeleteButton` (HITL-1,\n * binding there): takes plain `onClick` callbacks, never an `onConfirm` and\n * never renders a confirm dialog itself — the caller (`SettingsTool.tsx`)\n * owns the `ConfirmModal`s and the archive/delete mutations, exactly as it\n * did before this extraction.\n *\n * A4: `DeleteButton`'s own `label` prop renders as `title`/`aria-label`\n * ONLY, never visible text (`packages/ui/src/components/IconButton.tsx`) —\n * so the visible word \"Delete\" here is this component's OWN sibling\n * `<span>`, not something passed through to `DeleteButton`.\n */\nimport { DeleteButton } from \"@w6w/ui\";\n\nexport interface DangerZoneProps {\n /** Whether the resource is archived yet. `true` renders Delete; `false`\n * renders Archive. Every kind has an archive-before-delete step as of\n * T4.1.1 (Function/Endpoint newly, Workflow already did). */\n archived: boolean;\n /** Accessible name for the Delete icon button — `title`/`aria-label` only\n * (`IconButton.tsx`), e.g. \"Delete this function\". */\n deleteLabel: string;\n /** `data-testid` for the Delete control. Kind-specific — page guards key\n * on these directly (e.g. `delete-function`, `wf-settings-delete`). */\n deleteTestId: string;\n /** `data-testid` for the Archive control. Kind-specific. */\n archiveTestId: string;\n onRequestDelete: () => void;\n onRequestArchive: () => void;\n deleteError: string | null;\n archiveError: string | null;\n}\n\nexport function DangerZone(props: DangerZoneProps) {\n const {\n archived,\n deleteLabel,\n deleteTestId,\n archiveTestId,\n onRequestDelete,\n onRequestArchive,\n deleteError,\n archiveError,\n } = props;\n return (\n <div className=\"rail-danger-zone rail-danger-zone--panel\" data-testid=\"rail-danger-zone-panel\">\n {/* A2/M4's kill: mutually exclusive, never both rendered — Delete only\n once archived, Archive otherwise. */}\n {archived ? (\n <span className=\"rail-danger-zone-delete\">\n <DeleteButton label={deleteLabel} data-testid={deleteTestId} onClick={onRequestDelete} />\n <span>Delete</span>\n </span>\n ) : (\n <button\n type=\"button\"\n className=\"btn danger\"\n data-testid={archiveTestId}\n onClick={onRequestArchive}\n >\n Archive\n </button>\n )}\n {deleteError && (\n <div className=\"error\" data-testid=\"rail-delete-error\">\n {deleteError}\n </div>\n )}\n {archiveError && (\n <div className=\"error\" data-testid=\"rail-archive-error\">\n {archiveError}\n </div>\n )}\n </div>\n );\n}\n","/**\n * The presentational sections of the rail Settings panel, rendered by EVERY arm — the workflow\n * and function/endpoint arms in `./SettingsTool.tsx` — so the markup, test ids and copy exist\n * exactly once.\n *\n * Every section takes data and callbacks as props. There is no query or mutation hook in this\n * file: the arms own their data access (through `../repos/*`). `useState`-free too — open/close state lives in the arm, so a\n * section is a pure function of its props.\n *\n * Moved verbatim from the pre-split `SettingsPanel`: the `rail-meta` definition-list grid, the\n * version-history link + Publish/Enable block and its \"All versions\" list modal (kept as two\n * separate open states in the arm — see `SettingsTool.tsx`), the Export/Edit JSON/Import chooser\n * shell, and the Delete/Archive danger zone with its per-kind confirm copy.\n */\nimport { ConfirmModal, EditButton, Icon, IconButton } from \"@w6w/ui\";\nimport type { ReactNode } from \"react\";\nimport { DangerZone } from \"../chrome/DangerZone.tsx\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport type { RailSettingsKind } from \"../lib/rail-settings.ts\";\nimport type { VersionSummary, VersionsEnvelope } from \"../repos/versions.ts\";\n\n/** The three kinds the Settings panel renders for. */\nexport type SettingsKind = Extract<RailSettingsKind, \"function\" | \"endpoint\" | \"workflow\">;\n\n/** Heading row: the title and the \"Edit settings\" trigger for the unified settings modal. */\nexport function SettingsHeading(props: { onEdit: () => void }) {\n return (\n <div className=\"right-rail-panel-head rail-settings-head\">\n <h3>Settings</h3>\n <EditButton label=\"Edit settings\" data-testid=\"rail-settings-edit\" onClick={props.onEdit} />\n </div>\n );\n}\n\n/**\n * id + key + updated (+ tags, workflow only) — and nothing else. No createdAt, ever. A two-column\n * label/value GRID (`dl`/`dt`/`dd`); `.rail-meta-list` is the rail-scoped grid and there is\n * deliberately no global `dl`/`dt`/`dd` rule.\n */\nexport function MetadataSection(props: {\n id: string;\n displayName: string;\n /** `metadataFieldsForKind(kind)`. */\n fields: ReadonlyArray<\"id\" | \"key\" | \"updatedAt\">;\n /** The already-cached list row (carries key/updatedAt); `undefined` until the list loads. */\n row: { key?: string | null; updatedAt: string } | undefined;\n /** Workflow only: the tag chips. `undefined` hides the row (function/endpoint). */\n tags?: readonly string[];\n}) {\n const { id, displayName, fields, row, tags } = props;\n return (\n <div className=\"rail-meta\">\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"flex-start\",\n gap: \"8px\",\n }}\n >\n <dl className=\"rail-meta-list\">\n {displayName && (\n <>\n <dt>Name</dt>\n <dd data-testid=\"rail-meta-name\">\n <code>{displayName}</code>\n </dd>\n </>\n )}\n <dt>ID</dt>\n <dd data-testid=\"rail-meta-id\">\n <code>{id}</code>\n </dd>\n {fields.includes(\"key\") && row && (\n <>\n <dt>Key</dt>\n <dd data-testid=\"rail-meta-key\">\n <code>{row.key || \"unset\"}</code>\n </dd>\n </>\n )}\n {fields.includes(\"updatedAt\") && row && (\n <>\n <dt>Updated</dt>\n <dd data-testid=\"rail-meta-updated\" data-value={row.updatedAt}>\n {new Date(row.updatedAt).toLocaleString()}\n </dd>\n </>\n )}\n {tags !== undefined && row && (\n <>\n <dt>Tags</dt>\n <dd data-testid=\"rail-meta-tags\">\n {tags.length > 0\n ? tags.map((t) => (\n <span key={t} className=\"tag\">\n {t}\n </span>\n ))\n : \"No tags\"}\n </dd>\n </>\n )}\n </dl>\n </div>\n </div>\n );\n}\n\n/**\n * A5: one icon opens the combined Export/Edit JSON/Import chooser. Nothing here grows with the\n * size of the resource's definition — the definition renders in neither vessel here, only inside\n * a modal.\n */\nexport function SpecActionsTrigger(props: { onOpen: () => void }) {\n return (\n <div className=\"rail-spec-actions\">\n <IconButton\n icon=\"file-text\"\n label=\"Export, edit, or import\"\n data-testid=\"rail-spec-actions-open\"\n onClick={props.onOpen}\n />\n </div>\n );\n}\n\n/**\n * The chooser shell: Import always (it creates a NEW resource and navigates to it, never an\n * in-place replacement), plus a slot an arm fills with extra definition actions (the\n * function/endpoint arm adds Export + Edit JSON). Picking an item closes THIS modal and opens that\n * item's own — nothing is ever nested inside this one's body.\n */\nexport function SpecChooserModal(props: {\n kind: SettingsKind;\n /** Extra definition actions, rendered above the Import row. */\n children?: ReactNode;\n onImport: () => void;\n onClose: () => void;\n}) {\n const { kind, children, onImport, onClose } = props;\n return (\n <Modal title=\"Definition\" onClose={onClose}>\n <div className=\"modal-body\">\n {children}\n <p className=\"muted small\">\n Import a spec document to create a NEW {kind} and navigate to it — this does not replace\n the {kind} you have open.\n </p>\n <div className=\"rail-spec-menu-row\">\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid=\"rail-spec-import\"\n onClick={onImport}\n >\n Import\n </button>\n </div>\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={onClose}>\n Close\n </button>\n </div>\n </Modal>\n );\n}\n\n/**\n * Version history (A4): a link-styled icon, ALWAYS enabled (\"no earlier versions\" is an empty\n * state INSIDE the list modal, never a disabled control). Once opened (`open`), the un-carded\n * \"Published: vN\" line and Publish / Enable-Disable stay in the main panel.\n */\nexport function VersionSection(props: {\n open: boolean;\n versions: VersionsEnvelope | undefined;\n publishing: boolean;\n togglingEnabled: boolean;\n publishError: string | null;\n enableError: string | null;\n onShow: () => void;\n onPublish: () => void;\n onToggleEnabled: () => void;\n}) {\n const { open, versions } = props;\n return (\n <div className=\"rail-version-section\">\n <button\n type=\"button\"\n className=\"rail-link-icon\"\n data-testid=\"rail-history-show\"\n aria-label=\"Version history\"\n title=\"Version history\"\n onClick={props.onShow}\n >\n <Icon name=\"clock\" size={14} />\n <span>Version history</span>\n </button>\n {open && (\n <>\n <p className=\"muted small\" data-testid=\"rail-version-published\">\n {versions?.currentPublishedVersion != null\n ? `Published: v${versions.currentPublishedVersion}`\n : \"Never published\"}\n </p>\n <div className=\"rail-version-actions\">\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid=\"rail-publish\"\n disabled={props.publishing}\n onClick={props.onPublish}\n >\n {props.publishing ? \"Publishing…\" : \"Publish\"}\n </button>{\" \"}\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid=\"rail-enable-toggle\"\n disabled={props.togglingEnabled || versions === undefined}\n onClick={props.onToggleEnabled}\n >\n {props.togglingEnabled ? \"Saving…\" : versions?.enabled ? \"Disable\" : \"Enable\"}\n </button>\n </div>\n {props.publishError && (\n <div className=\"error\" data-testid=\"rail-publish-error\">\n {props.publishError}\n </div>\n )}\n {props.enableError && (\n <div className=\"error\" data-testid=\"rail-enable-error\">\n {props.enableError}\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n\n/**\n * The \"All versions\" list modal — deliberately NOT titled \"Version history\" (which would share\n * the `Version …` aria-label prefix the per-version detail viewer's own dialogs use).\n */\nexport function VersionListModal(props: {\n loading: boolean;\n versions: readonly VersionSummary[] | undefined;\n onSelect: (versionNumber: number) => void;\n onClose: () => void;\n}) {\n const { loading, versions } = props;\n return (\n <Modal title=\"All versions\" onClose={props.onClose} wide>\n <div className=\"modal-body\">\n {loading && <p className=\"muted small\">Loading…</p>}\n {versions?.length === 0 && <p className=\"muted small\">No versions yet.</p>}\n {versions && versions.length > 0 && (\n <ul className=\"list\">\n {versions.map((v) => (\n <li key={v.versionNumber} className=\"selectable\">\n <button\n type=\"button\"\n className=\"row-select\"\n data-testid=\"rail-version-row\"\n onClick={() => props.onSelect(v.versionNumber)}\n >\n <div className=\"list-main\">\n <code>v{v.versionNumber}</code>{\" \"}\n {v.isCurrentPublished && (\n <span className=\"badge\" data-testid=\"rail-version-current\">\n Published\n </span>\n )}\n <div className=\"muted small\">{new Date(v.createdAt).toLocaleString()}</div>\n </div>\n </button>\n </li>\n ))}\n </ul>\n )}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Done\n </button>\n </div>\n </Modal>\n );\n}\n\nconst DANGER_COPY: Record<\n SettingsKind,\n {\n deleteTitle: string;\n deleteMessage: string;\n archiveTitle: string;\n archiveMessage: string;\n deleteLabel: string;\n deleteTestId: string;\n archiveTestId: string;\n }\n> = {\n function: {\n deleteTitle: \"Delete function\",\n deleteMessage:\n \"Delete this function permanently? Any endpoint, workflow, or call pointing to it will start failing with a not-found error the next time it runs, and this cannot be undone.\",\n archiveTitle: \"Archive function\",\n archiveMessage:\n \"Archive this function? It stops being invocable and can no longer be edited. Archiving is one-way — there is no unarchive — and only an archived function can be deleted.\",\n deleteLabel: \"Delete this function\",\n deleteTestId: \"delete-function\",\n archiveTestId: \"archive-function\",\n },\n endpoint: {\n deleteTitle: \"Delete endpoint\",\n deleteMessage:\n \"Delete this endpoint permanently? Any alias, workflow, or call pointing to it will start failing with a not-found error the next time it runs, and this cannot be undone.\",\n archiveTitle: \"Archive endpoint\",\n archiveMessage:\n \"Archive this endpoint? It stops being invocable and can no longer be edited. Archiving is one-way — there is no unarchive — and only an archived endpoint can be deleted.\",\n deleteLabel: \"Delete this endpoint\",\n deleteTestId: \"delete-endpoint\",\n archiveTestId: \"archive-endpoint\",\n },\n workflow: {\n deleteTitle: \"Delete workflow\",\n deleteMessage:\n \"Delete this workflow permanently? Its run history is discarded immediately via cascading deletes and cannot be recovered.\",\n archiveTitle: \"Archive workflow\",\n archiveMessage:\n \"Archive this workflow? It stops running and can no longer be published. Archiving is one-way — there is no unarchive — and only an archived workflow can be deleted.\",\n deleteLabel: \"Delete this workflow\",\n deleteTestId: \"wf-settings-delete\",\n archiveTestId: \"wf-settings-archive\",\n },\n};\n\n/**\n * The bottom \"danger zone\": Archive (until archived) then Delete, with the two confirm modals.\n * Per-kind variance (copy, test ids) is the table above; the caller owns the mutations and the\n * confirm/error state, and renders this only when `hasDelete(kind)`.\n */\nexport function SettingsDangerZone(props: {\n kind: SettingsKind;\n archived: boolean;\n deleteConfirming: boolean;\n archiveConfirming: boolean;\n deleteError: string | null;\n archiveError: string | null;\n onRequestDelete: () => void;\n onRequestArchive: () => void;\n onConfirmDelete: () => void;\n onConfirmArchive: () => void;\n onCloseDelete: () => void;\n onCloseArchive: () => void;\n}) {\n const copy = DANGER_COPY[props.kind];\n return (\n <>\n <DangerZone\n archived={props.archived}\n deleteLabel={copy.deleteLabel}\n deleteTestId={copy.deleteTestId}\n archiveTestId={copy.archiveTestId}\n onRequestDelete={props.onRequestDelete}\n onRequestArchive={props.onRequestArchive}\n deleteError={props.deleteError}\n archiveError={props.archiveError}\n />\n {props.deleteConfirming && (\n <ConfirmModal\n title={copy.deleteTitle}\n message={copy.deleteMessage}\n confirmLabel=\"Delete\"\n onConfirm={props.onConfirmDelete}\n onClose={props.onCloseDelete}\n />\n )}\n {props.archiveConfirming && (\n <ConfirmModal\n title={copy.archiveTitle}\n message={copy.archiveMessage}\n confirmLabel=\"Archive\"\n onConfirm={props.onConfirmArchive}\n onClose={props.onCloseArchive}\n />\n )}\n </>\n );\n}\n","/**\n * The Settings rail tool — what a resource's right-rail Settings panel does, owned by the package\n * so `<WorkflowEditor>`, a host's `<CallableRail>` and Studio's own rail all render ONE tool:\n * `settingsTool` is a stateful shell (it owns the three open flags) that dispatches by kind to\n * `WorkflowSettingsPanel` or `CallableSettingsPanel` (function / endpoint). Both render the same\n * presentational sections (`./settings-sections.tsx`).\n *\n * Workflow arm, unchanged:\n * - metadata (name / id / key / tags) read off the cached workflow list row;\n * - the unified settings modal saves the WHOLE stored definition (`useWorkflowQuery`'s\n * `workflow`, `displayName` / `key` / `tags` replaced) with `ifUnmodifiedSince` from that\n * query's `updatedAt`, and `project` passed VERBATIM — `useSaveWorkflowMutation` refuses\n * without one, because an unscoped write would silently relocate the workflow into the\n * account's default project (C/D-C2). A 409/400 renders inline, never a thrown error;\n * - the Import chooser → `ImportSpecModal` (creates a NEW workflow and opens it);\n * - version history / Publish / Enable are gated on the section's OWN open state, so opening\n * the panel issues zero `/versions` requests;\n * - Archive → Delete. Both land on the list via `onNavigate({ type: \"list\" })`.\n *\n * Function / endpoint arm: the same sections over `../repos/functions.ts` / `endpoints.ts`, plus\n * Export (`useSpecQuery`, gated on the export modal being open) and Edit JSON. Every write built\n * from a cached definition takes the definition from `callableRecord(kind, query.data)` — the ONE\n * strip of `valid` / `updatedAt` — and saves through the guarded hook with the stale-write token\n * OF THE RECORD THE WRITTEN TEXT CAME FROM: the name/key modal uses the current record's\n * `updatedAt`; Edit JSON uses the token captured when its text was seeded (`openEdit`), never one\n * read at save time over older text (that would silently overwrite a write that landed meanwhile).\n * A refusal (409 `function_stale` / `endpoint_stale`, 400…) renders inline and is never retried.\n *\n * Host seams: `project` and `onNavigate` arrive as props on the arms, and the `settingsTool` Panel\n * reads them from `useRailEnv()` (`./rail-env.tsx`). Archive / delete land on the list through\n * `onNavigate({ type: \"list\" })`; an import opens `{ type: \"imported\", kind, id }`. No router, no\n * `client.console`, no module-scope browser globals.\n *\n * ⚠️ The strip id is `\"settings\"`; `activeTool` is persisted.\n */\nimport { ApiError } from \"@w6w/sdk\";\nimport { CodeBlock, Icon, JsonEditor } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { CallableSettingsModal } from \"../chrome/CallableSettingsModal.tsx\";\nimport { ImportSpecModal } from \"../chrome/ImportSpecModal.tsx\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport type { RailTool } from \"../chrome/RightRail.tsx\";\nimport { VersionHistoryModal } from \"../chrome/VersionHistoryModal.tsx\";\nimport type { WorkspaceCallable } from \"../chrome/workspace.tsx\";\nimport { callableRecord } from \"../lib/callable-record.ts\";\nimport {\n evaluateEdit,\n hasDefinitionActions,\n hasDelete,\n hasVersionHistory,\n metadataFieldsForKind,\n specCollectionForKind,\n} from \"../lib/rail-settings.ts\";\nimport {\n endpointsKey,\n useArchiveEndpointMutation,\n useDeleteEndpointMutation,\n useEndpointQuery,\n useEndpointsQuery,\n useGuardedSaveEndpointMutation,\n} from \"../repos/endpoints.ts\";\nimport {\n functionsKey,\n useArchiveFunctionMutation,\n useDeleteFunctionMutation,\n useFunctionQuery,\n useFunctionsQuery,\n useGuardedSaveFunctionMutation,\n} from \"../repos/functions.ts\";\nimport { useSpecQuery } from \"../repos/spec-export.ts\";\nimport {\n type VersionsKind,\n usePublishMutation,\n useSetEnabledMutation,\n useVersionsQuery,\n} from \"../repos/versions.ts\";\nimport {\n useArchiveWorkflowMutation,\n useDeleteWorkflowMutation,\n useSaveWorkflowMutation,\n useWorkflowQuery,\n useWorkflowsQuery,\n workflowsKey,\n} from \"../repos/workflows.ts\";\nimport { type RailNavigation, useRailEnv } from \"./rail-env.tsx\";\nimport {\n MetadataSection,\n SettingsDangerZone,\n SettingsHeading,\n SpecActionsTrigger,\n SpecChooserModal,\n VersionListModal,\n VersionSection,\n} from \"./settings-sections.tsx\";\n\n/** The Import modal's three list keys — the repos' own exports, never literals. */\nconst IMPORT_LIST_KEYS = { functionsKey, endpointsKey, workflowsKey };\n\n/**\n * The three open flags a Settings panel shows: the Name/Key/Tags modal, the history section, and\n * the version list modal. They are OWNED BY THE CALLER (a stateful shell above every kind's arm),\n * not by the arm: a rail that stays mounted across a kind change (function -> workflow ->\n * endpoint) swaps arm component types, and state held in the arm would be remounted away,\n * closing an open modal. Lifting them keeps the modal open exactly as the pre-split single\n * component did.\n */\nexport type SettingsOpenState = {\n editingSettings: boolean;\n setEditingSettings: (v: boolean) => void;\n historyOpen: boolean;\n setHistoryOpen: (v: boolean) => void;\n versionListOpen: boolean;\n setVersionListOpen: (v: boolean) => void;\n};\n\nexport function WorkflowSettingsPanel({\n ctx,\n project,\n onNavigate,\n open,\n}: {\n ctx: WorkspaceCallable;\n project: string | null;\n onNavigate: (to: RailNavigation) => void;\n open: SettingsOpenState;\n}) {\n const {\n editingSettings,\n setEditingSettings,\n historyOpen,\n setHistoryOpen,\n versionListOpen,\n setVersionListOpen,\n } = open;\n const workflowsQuery = useWorkflowsQuery(project ?? undefined);\n const isWorkflow = ctx?.kind === \"workflow\";\n const id = ctx?.id ?? \"\";\n\n // The Key / Tags / Name save needs the WHOLE stored definition (never a `{id,key}` stub) plus\n // the `updatedAt` precondition — both come from this query.\n const wfDefQuery = useWorkflowQuery(id, isWorkflow);\n // MUST carry the current project, verbatim: the hook refuses a missing one (no default).\n const saveWfMut = useSaveWorkflowMutation(project ?? undefined);\n const archiveWfMut = useArchiveWorkflowMutation();\n const deleteWfMut = useDeleteWorkflowMutation();\n\n const [specMenuOpen, setSpecMenuOpen] = useState(false);\n const [importing, setImporting] = useState(false);\n const [deleteConfirming, setDeleteConfirming] = useState(false);\n const [archiveConfirming, setArchiveConfirming] = useState(false);\n const [deleteError, setDeleteError] = useState<string | null>(null);\n const [archiveError, setArchiveError] = useState<string | null>(null);\n\n // `versionListOpen` is DELIBERATELY separate from `historyOpen` (both arrive via `open`): a\n // native `<dialog>` opened via `showModal()` makes the rest of the page inert, so sharing one\n // boolean would hide Publish/Enable-Disable the moment the list modal closes. The entry icon\n // sets both true; only the list modal's own close clears `versionListOpen`.\n // Gated on the section's OWN open state: opening this panel issues zero `/versions` requests.\n const versionsQuery = useVersionsQuery(\"workflow\", id, historyOpen && isWorkflow);\n const publishMut = usePublishMutation(\"workflow\");\n const setEnabledMut = useSetEnabledMutation(\"workflow\");\n const [publishError, setPublishError] = useState<string | null>(null);\n const [enableError, setEnableError] = useState<string | null>(null);\n // Keyed by resource id: falls back to closed the instant `ctx.id` no longer matches, so a\n // transition never carries a stale version from a DIFFERENT resource.\n const [openVersion, setOpenVersion] = useState<{ id: string; versionNumber: number } | null>(\n null,\n );\n\n if (!ctx || ctx.kind !== \"workflow\") {\n return <p className=\"muted small\">Open a workflow to see its settings.</p>;\n }\n\n const listRow = workflowsQuery.data?.find((w) => w.id === ctx.id);\n const displayName =\n listRow && typeof (listRow as { displayName?: unknown }).displayName === \"string\"\n ? (listRow as { displayName: string }).displayName\n : \"\";\n const tags = (listRow as { tags?: string[] } | undefined)?.tags ?? [];\n const archived = (listRow as { status?: string } | undefined)?.status === \"archived\";\n\n function onDelete() {\n setDeleteError(null);\n deleteWfMut.mutate(id, {\n onSuccess: () => {\n setDeleteConfirming(false);\n onNavigate({ type: \"list\" });\n },\n onError: (e: unknown) => {\n setDeleteConfirming(false);\n setDeleteError(e instanceof ApiError ? e.message : String(e));\n },\n });\n }\n\n function onArchive() {\n setArchiveError(null);\n archiveWfMut.mutate(id, {\n onSuccess: () => {\n setArchiveConfirming(false);\n onNavigate({ type: \"list\" });\n },\n onError: (e: unknown) => {\n setArchiveConfirming(false);\n setArchiveError(e instanceof ApiError ? e.message : String(e));\n },\n });\n }\n\n return (\n <div className=\"rail-settings-panel\">\n <SettingsHeading onEdit={() => setEditingSettings(true)} />\n <MetadataSection\n id={ctx.id}\n displayName={displayName}\n fields={metadataFieldsForKind(\"workflow\")}\n row={listRow}\n tags={tags}\n />\n\n <SpecActionsTrigger onOpen={() => setSpecMenuOpen(true)} />\n\n <VersionSection\n open={historyOpen}\n versions={versionsQuery.data}\n publishing={publishMut.isPending}\n togglingEnabled={setEnabledMut.isPending}\n publishError={publishError}\n enableError={enableError}\n onShow={() => {\n setHistoryOpen(true);\n setVersionListOpen(true);\n }}\n onPublish={() => {\n setPublishError(null);\n publishMut.mutate(id, {\n onError: (e) => setPublishError(e instanceof ApiError ? e.message : String(e)),\n });\n }}\n onToggleEnabled={() => {\n setEnableError(null);\n setEnabledMut.mutate(\n { id, enabled: !versionsQuery.data?.enabled },\n { onError: (e) => setEnableError(e instanceof ApiError ? e.message : String(e)) },\n );\n }}\n />\n\n {versionListOpen && (\n <VersionListModal\n loading={versionsQuery.isLoading}\n versions={versionsQuery.data?.versions}\n onSelect={(versionNumber) => setOpenVersion({ id, versionNumber })}\n onClose={() => setVersionListOpen(false)}\n />\n )}\n\n {openVersion && openVersion.id === id && (\n <VersionHistoryModal\n kind=\"workflow\"\n id={id}\n versionNumber={openVersion.versionNumber}\n onClose={() => setOpenVersion(null)}\n />\n )}\n\n {specMenuOpen && (\n <SpecChooserModal\n kind=\"workflow\"\n onClose={() => setSpecMenuOpen(false)}\n onImport={() => {\n setSpecMenuOpen(false);\n setImporting(true);\n }}\n />\n )}\n\n {/* Unified settings modal for name, key, and tags. */}\n {editingSettings && listRow && (\n <CallableSettingsModal\n // `key={id}` remounts (not merely re-renders) when an in-app navigation swaps the rail\n // to a different resource while this modal is open — the modal's `useState`\n // initializers never re-run on a prop change, so without it a save would mix the first\n // resource's stale fields with the new `id`.\n key={id}\n kind=\"workflow\"\n id={id}\n initial={{\n displayName,\n key: (listRow as { key?: string | null }).key ?? null,\n tags,\n }}\n onSave={async (data) => {\n if (!wfDefQuery.data) throw new Error(\"Unable to save settings\");\n const stored = wfDefQuery.data;\n return new Promise((resolve, reject) => {\n const updated: Record<string, unknown> = {\n ...stored.workflow,\n displayName: data.displayName,\n };\n if (data.key !== undefined) {\n updated.key = data.key;\n }\n if (data.tags !== undefined) {\n updated.tags = data.tags;\n }\n saveWfMut.mutate(\n { definition: updated, ifUnmodifiedSince: stored.updatedAt },\n { onSuccess: () => resolve(), onError: reject },\n );\n });\n }}\n onClose={() => setEditingSettings(false)}\n />\n )}\n\n <SettingsDangerZone\n kind=\"workflow\"\n archived={archived}\n deleteConfirming={deleteConfirming}\n archiveConfirming={archiveConfirming}\n deleteError={deleteError}\n archiveError={archiveError}\n onRequestDelete={() => setDeleteConfirming(true)}\n onRequestArchive={() => setArchiveConfirming(true)}\n onConfirmDelete={onDelete}\n onConfirmArchive={onArchive}\n onCloseDelete={() => setDeleteConfirming(false)}\n onCloseArchive={() => setArchiveConfirming(false)}\n />\n\n {importing && (\n <ImportSpecModal\n kind=\"workflow\"\n project={project ?? undefined}\n listKeys={IMPORT_LIST_KEYS}\n onOpenImported={(kind, newId) => onNavigate({ type: \"imported\", kind, id: newId })}\n onClose={() => setImporting(false)}\n />\n )}\n </div>\n );\n}\n\n/**\n * Stateful shell: owns the three open flags ABOVE every arm and passes them down. The kind branch\n * picks a component TYPE (so each arm's data hooks stay per-kind), and an arm remounts on a kind\n * change — but the modal / version-list flags live here, so they survive the swap (rail guards\n * K6/V6).\n */\nfunction SettingsToolPanel({ ctx }: { ctx: WorkspaceCallable }) {\n const { project, onNavigate } = useRailEnv();\n const [editingSettings, setEditingSettings] = useState(false);\n const [historyOpen, setHistoryOpen] = useState(false);\n const [versionListOpen, setVersionListOpen] = useState(false);\n const open: SettingsOpenState = {\n editingSettings,\n setEditingSettings,\n historyOpen,\n setHistoryOpen,\n versionListOpen,\n setVersionListOpen,\n };\n return ctx?.kind === \"workflow\" ? (\n <WorkflowSettingsPanel ctx={ctx} project={project} onNavigate={onNavigate} open={open} />\n ) : (\n <CallableSettingsPanel ctx={ctx} project={project} onNavigate={onNavigate} open={open} />\n );\n}\n\nexport function CallableSettingsPanel({\n ctx,\n project,\n onNavigate,\n open,\n}: {\n ctx: WorkspaceCallable;\n project: string | null;\n onNavigate: (to: RailNavigation) => void;\n open: SettingsOpenState;\n}) {\n const {\n editingSettings,\n setEditingSettings,\n historyOpen,\n setHistoryOpen,\n versionListOpen,\n setVersionListOpen,\n } = open;\n const kind0 = ctx?.kind;\n const endpointsQuery = useEndpointsQuery(kind0 === \"endpoint\");\n const functionsQuery = useFunctionsQuery(kind0 === \"function\");\n\n const [editing, setEditing] = useState(false);\n const [editText, setEditText] = useState(\"\");\n const [editError, setEditError] = useState<string | null>(null);\n // The stale-write token of the record `editText` was seeded from (`openEdit`). Read at SAVE time\n // it would guard text seeded from an older copy with a newer token — a silent overwrite.\n const [editToken, setEditToken] = useState<string | null>(null);\n // A5: one chooser icon opens ONE combined Modal (Export + Edit JSON +\n // Import); picking an item there closes the chooser and opens THAT item's\n // own modal as a sibling — never nested inside the chooser's own body.\n const [specMenuOpen, setSpecMenuOpen] = useState(false);\n const [exporting, setExporting] = useState(false);\n const [importing, setImporting] = useState(false);\n const [deleteConfirming, setDeleteConfirming] = useState(false);\n const [archiveConfirming, setArchiveConfirming] = useState(false);\n const [deleteError, setDeleteError] = useState<string | null>(null);\n const [archiveError, setArchiveError] = useState<string | null>(null);\n\n // Gated on `ctx.kind` alone, never additionally on the edit modal being\n // open — ST6's post-save freshness proof needs the `[\"function\", id]` cache\n // entry to exist before the save happens.\n const fnDefQuery = useFunctionQuery(ctx?.id ?? \"\", ctx?.kind === \"function\");\n const epDefQuery = useEndpointQuery(ctx?.id ?? \"\", ctx?.kind === \"endpoint\");\n const saveFnMut = useGuardedSaveFunctionMutation();\n const saveEpMut = useGuardedSaveEndpointMutation();\n const deleteFnMut = useDeleteFunctionMutation();\n const deleteEpMut = useDeleteEndpointMutation();\n // A7: Function/Endpoint have the archive-before-delete step too.\n const archiveFnMut = useArchiveFunctionMutation();\n const archiveEpMut = useArchiveEndpointMutation();\n // Gated on the export modal's own open state, so opening this panel issues\n // zero `/spec` requests. `specCollectionForKind` returns `null` for\n // `workflow`/`connection`, which disables the query regardless of `exporting`.\n const specCollection = ctx ? specCollectionForKind(ctx.kind) : null;\n const specQuery = useSpecQuery(specCollection, ctx?.id ?? \"\", exporting);\n\n // ── The History section ─────────────────────────────────────────────────\n // `null` for a kind with no version history (`connection`).\n const versionsKind: VersionsKind | null =\n ctx && hasVersionHistory(ctx.kind) ? (ctx.kind as VersionsKind) : null;\n // Gated on the section's OWN open state (`historyOpen`): never fires on mount.\n const versionsQuery = useVersionsQuery(versionsKind, ctx?.id ?? \"\", historyOpen);\n // `usePublishMutation`/`useSetEnabledMutation` need a fixed, non-null kind\n // per hook instance; the fallback is never reached by an actual request —\n // the buttons that call `.mutate` only render inside the\n // `hasVersionHistory(ctx.kind)`-gated block.\n const publishMut = usePublishMutation(versionsKind ?? \"function\");\n const setEnabledMut = useSetEnabledMutation(versionsKind ?? \"function\");\n const [publishError, setPublishError] = useState<string | null>(null);\n const [enableError, setEnableError] = useState<string | null>(null);\n // Keyed by resource id: falls back to closed the instant `ctx.id` no longer\n // matches, so a kind/id transition (V6) never carries a stale version.\n const [openVersion, setOpenVersion] = useState<{ id: string; versionNumber: number } | null>(\n null,\n );\n\n // `isAvailable` already keeps this tool off the strip for a `ctx` this has\n // no settings for — but a persisted `activeTool` plus an in-app transition\n // to a non-publishing route can still render this Panel with `ctx === null`\n // (or a `connection`). The rail must never blank out or crash.\n if (!ctx || (ctx.kind !== \"function\" && ctx.kind !== \"endpoint\")) {\n return (\n <p className=\"muted small\">Open a workflow, function, or endpoint to see its settings.</p>\n );\n }\n\n const kind = ctx.kind;\n const id = ctx.id;\n const listRow =\n kind === \"function\"\n ? functionsQuery.data?.find((f) => f.id === id)\n : endpointsQuery.data?.find((e) => e.id === id);\n // The cached record split ONCE (`callableRecord`): the editable definition (no `valid` /\n // `updatedAt`) and the stale-write token it was read with.\n const record = callableRecord(kind, kind === \"function\" ? fnDefQuery.data : epDefQuery.data);\n const def = record?.definition ?? null;\n // Display name (the human-readable label shown in the list)\n const displayName = listRow\n ? typeof (listRow as { displayName?: unknown }).displayName === \"string\"\n ? (listRow as { displayName: string }).displayName\n : \"\"\n : \"\";\n\n const defJson = def ? JSON.stringify(def, null, 2) : \"\";\n\n function openEdit() {\n setEditError(null);\n setEditText(defJson);\n setEditToken(record?.updatedAt ?? null);\n setEditing(true);\n }\n\n const editEval = def\n ? evaluateEdit(editText, { id: String(def.id), key: String(def.key) })\n : { parsed: null, blockedReason: \"No definition loaded yet.\" };\n const savingDef = kind === \"function\" ? saveFnMut.isPending : saveEpMut.isPending;\n\n function onSaveEdit() {\n if (!editEval.parsed || editEval.blockedReason) return;\n setEditError(null);\n const onSettled = {\n onSuccess: () => setEditing(false),\n onError: (e: unknown) => setEditError(e instanceof ApiError ? e.message : String(e)),\n };\n const vars = { definition: editEval.parsed, ifUnmodifiedSince: editToken };\n if (kind === \"function\") {\n saveFnMut.mutate(vars, onSettled);\n } else {\n saveEpMut.mutate(vars, onSettled);\n }\n }\n\n // ── Delete/Archive — the bottom \"danger zone\" ────────────────────────────\n // Function/Endpoint signal \"already archived\" via the `archivedAt` column.\n const archived = (listRow as { archivedAt?: string | null } | undefined)?.archivedAt != null;\n\n function onDelete() {\n setDeleteError(null);\n const onSettled = {\n onSuccess: () => {\n setDeleteConfirming(false);\n onNavigate({ type: \"list\" });\n },\n onError: (e: unknown) => {\n setDeleteConfirming(false);\n setDeleteError(e instanceof ApiError ? e.message : String(e));\n },\n };\n if (kind === \"function\") deleteFnMut.mutate(id, onSettled);\n else deleteEpMut.mutate(id, onSettled);\n }\n\n // A1/D-I0-1: archive reuses `onDelete`'s land-on-the-list idiom.\n function onArchive() {\n setArchiveError(null);\n const onSettled = {\n onSuccess: () => {\n setArchiveConfirming(false);\n onNavigate({ type: \"list\" });\n },\n onError: (e: unknown) => {\n setArchiveConfirming(false);\n setArchiveError(e instanceof ApiError ? e.message : String(e));\n },\n };\n if (kind === \"function\") archiveFnMut.mutate(id, onSettled);\n else archiveEpMut.mutate(id, onSettled);\n }\n\n return (\n <div className=\"rail-settings-panel\">\n <SettingsHeading onEdit={() => setEditingSettings(true)} />\n <MetadataSection\n id={id}\n displayName={displayName}\n fields={metadataFieldsForKind(kind)}\n row={listRow}\n />\n\n {hasDefinitionActions(kind) && <SpecActionsTrigger onOpen={() => setSpecMenuOpen(true)} />}\n\n {hasVersionHistory(kind) && (\n <VersionSection\n open={historyOpen}\n versions={versionsQuery.data}\n publishing={publishMut.isPending}\n togglingEnabled={setEnabledMut.isPending}\n publishError={publishError}\n enableError={enableError}\n onShow={() => {\n setHistoryOpen(true);\n setVersionListOpen(true);\n }}\n onPublish={() => {\n setPublishError(null);\n publishMut.mutate(id, {\n onError: (e) => setPublishError(e instanceof ApiError ? e.message : String(e)),\n });\n }}\n onToggleEnabled={() => {\n setEnableError(null);\n setEnabledMut.mutate(\n { id, enabled: !versionsQuery.data?.enabled },\n { onError: (e) => setEnableError(e instanceof ApiError ? e.message : String(e)) },\n );\n }}\n />\n )}\n\n {versionListOpen && (\n <VersionListModal\n loading={versionsQuery.isLoading}\n versions={versionsQuery.data?.versions}\n onSelect={(versionNumber) => setOpenVersion({ id, versionNumber })}\n onClose={() => setVersionListOpen(false)}\n />\n )}\n\n {openVersion && openVersion.id === id && (\n <VersionHistoryModal\n kind={kind}\n id={id}\n versionNumber={openVersion.versionNumber}\n onClose={() => setOpenVersion(null)}\n />\n )}\n\n {/* The chooser — Export + Edit JSON (function/endpoint only, PL-2) fill\n the shell's slot; Import is the shell's own. */}\n {specMenuOpen && (\n <SpecChooserModal\n kind={kind}\n onClose={() => setSpecMenuOpen(false)}\n onImport={() => {\n setSpecMenuOpen(false);\n setImporting(true);\n }}\n >\n {hasDefinitionActions(kind) && (\n <>\n <p className=\"muted small\">\n Export a portable definition — the same shape Import accepts — or Edit JSON to\n change what's stored directly.\n </p>\n <div className=\"rail-spec-menu-row\">\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid=\"rail-spec-export\"\n onClick={() => {\n setSpecMenuOpen(false);\n setExporting(true);\n }}\n >\n Export\n </button>{\" \"}\n <button\n type=\"button\"\n className=\"btn ghost\"\n disabled={!def}\n data-testid=\"rail-json-edit\"\n onClick={() => {\n setSpecMenuOpen(false);\n openEdit();\n }}\n >\n Edit JSON\n </button>\n </div>\n </>\n )}\n </SpecChooserModal>\n )}\n\n {/* Export — a read-only modal carrying the `/spec` route's `spec` field\n verbatim, via `@w6w/ui`'s `CodeBlock`, never a second editable text\n box. The request fires only while this modal is open. */}\n {exporting && (\n <Modal title=\"Export spec document\" onClose={() => setExporting(false)} wide>\n <div className=\"modal-body\">\n {specQuery.isLoading ? (\n <p className=\"muted small\">Loading…</p>\n ) : specQuery.isError ? (\n <div className=\"error\" data-testid=\"rail-spec-error\">\n {specQuery.error instanceof Error\n ? specQuery.error.message\n : String(specQuery.error)}\n </div>\n ) : specQuery.data ? (\n <div data-testid=\"rail-spec-json\">\n <CodeBlock\n code={JSON.stringify(specQuery.data, null, 2)}\n language=\"json\"\n maxHeight=\"420px\"\n copyable\n />\n </div>\n ) : null}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={() => setExporting(false)}>\n Close\n </button>\n </div>\n </Modal>\n )}\n\n {/* Self-contained — Save lives inside this modal, mirroring\n `WorkflowDetailPage.tsx`'s read-only card, never `WorkflowsPage.tsx`'s\n Save-less `showJson` modal. */}\n {editing && (\n <Modal title=\"Edit definition\" onClose={() => setEditing(false)} wide>\n <div className=\"modal-body\">\n <JsonEditor\n value={editText}\n onChange={setEditText}\n minHeight=\"320px\"\n aria-label=\"Edit definition JSON\"\n />\n {editEval.blockedReason && (\n <p className=\"muted small\" data-testid=\"rail-edit-reason\">\n {editEval.blockedReason}\n </p>\n )}\n {editError && <div className=\"error\">{editError}</div>}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={() => setEditing(false)}>\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"btn\"\n disabled={editEval.blockedReason !== null || savingDef}\n data-testid=\"rail-json-save\"\n onClick={onSaveEdit}\n >\n {savingDef ? \"Saving…\" : \"Save\"}\n </button>\n </div>\n </Modal>\n )}\n\n {/* Unified settings modal for name and key. */}\n {editingSettings && listRow && (\n <CallableSettingsModal\n // `key={id}` forces a remount (not a re-render) when an in-app\n // navigation swaps the rail to a different resource while this modal\n // is open — the modal's `useState` initializers never re-run on a\n // prop change, so a save would mix stale fields with the new `id`.\n key={id}\n kind={kind}\n id={id}\n initial={{\n displayName,\n key: (listRow as { key?: string | null }).key ?? null,\n tags: [],\n }}\n onSave={async (data) => {\n if (!record) throw new Error(\"Unable to save settings\");\n // Definition AND token from the same record, read now: the text written is this\n // record's own fields plus the modal's edits.\n const base = record.definition;\n const edited =\n kind === \"function\"\n ? // `canEditKey: true` for function (`callable-descriptors.ts`): `data.key` must\n // reach the server (the modal falls back to `initial.key` when unchanged).\n { ...base, displayName: data.displayName, key: data.key ?? base.key }\n : { ...base, displayName: data.displayName };\n const vars = { definition: edited, ifUnmodifiedSince: record.updatedAt };\n return new Promise((resolve, reject) => {\n const settled = { onSuccess: () => resolve(), onError: reject };\n if (kind === \"function\") saveFnMut.mutate(vars, settled);\n else saveEpMut.mutate(vars, settled);\n });\n }}\n onClose={() => setEditingSettings(false)}\n />\n )}\n\n {hasDelete(kind) && (\n <SettingsDangerZone\n kind={kind}\n archived={archived}\n deleteConfirming={deleteConfirming}\n archiveConfirming={archiveConfirming}\n deleteError={deleteError}\n archiveError={archiveError}\n onRequestDelete={() => setDeleteConfirming(true)}\n onRequestArchive={() => setArchiveConfirming(true)}\n onConfirmDelete={onDelete}\n onConfirmArchive={onArchive}\n onCloseDelete={() => setDeleteConfirming(false)}\n onCloseArchive={() => setArchiveConfirming(false)}\n />\n )}\n\n {importing && (\n <ImportSpecModal\n kind={kind}\n project={project ?? undefined}\n listKeys={IMPORT_LIST_KEYS}\n onOpenImported={(k, newId) => onNavigate({ type: \"imported\", kind: k, id: newId })}\n onClose={() => setImporting(false)}\n />\n )}\n </div>\n );\n}\n\nfunction SettingsToolIcon() {\n return <Icon name=\"settings\" />;\n}\n\n/** The package's Settings tool — workflow, function and endpoint. */\nexport const settingsTool: RailTool = {\n id: \"settings\",\n title: \"Settings\",\n rendersHeading: true,\n Icon: SettingsToolIcon,\n isAvailable: (ctx) =>\n ctx?.kind === \"workflow\" || ctx?.kind === \"function\" || ctx?.kind === \"endpoint\",\n Panel: SettingsToolPanel,\n};\n","/**\n * The rail tools `<WorkflowEditor>`, `<CallableRail>` and Studio's rail mount, in display order.\n * Each serves workflow, function and endpoint resources (`isAvailable` decides per context); the\n * Aliases tool is deliberately absent (alias management is Studio-only). Reachable from the `chrome` subpath, never from the package root barrel — the\n * Error handling tool pulls in `@w6w/ui/flow`.\n */\nimport type { RailTool } from \"../chrome/RightRail.tsx\";\nimport { codeTool } from \"./CodeTool.tsx\";\nimport { errorHandlingTool } from \"./ErrorHandlingTool.tsx\";\nimport { settingsTool } from \"./SettingsTool.tsx\";\n\nexport const editorRailTools: readonly RailTool[] = [settingsTool, codeTool, errorHandlingTool];\n"],"names":["WorkspaceContext","createContext","WorkspaceProvider","children","base","override","setCallable","useState","resource","value","useMemo","jsx","useHasWorkspace","useContext","useWorkspace","ctx","key","useEffect","useWorkspaceCallable","CLOSED","readStoredState","raw","activeTool","restoreRailState","RailShell","tools","state","onToggle","t","jsxs","tool","PersistedRail","storageKey","setState","id","prev","RightRail","available","useProjectExpressionOptions","project","projectId","varsQuery","useVarsQuery","secretsQuery","useSecretsQuery","documentsQuery","useDocumentsQuery","sealSecretFn","useSealSecret","createVarMut","useCreateVarMutation","createSecretMut","useCreateSecretMutation","v","s","projectDocumentSources","documentSampleValues","input","ProjectExpressionScope","options","ExpressionOptionsProvider","CodePanel","openTab","setOpenTab","snippetCallable","toSnippetCallable","triggers","tabs","snippetTabsFor","unavailableReason","label","icon","Icon","Modal","CallFromCodeBody","CodeToolIcon","codeTool","isAvailable","DEFAULT_ENV","RailEnvContext","RailEnvProvider","onNavigate","useRailEnv","CALL_APP","refOf","target","nounOf","ErrorHandlerSection","kind","policy","ready","saving","onPersist","functionsQuery","useFunctionsQuery","workflowsQuery","useWorkflowsQuery","pickerOpen","setPickerOpen","error","setError","_a","ref","selfDecision","errorHandlerSelfDecision","_b","_d","_c","w","fn","f","persist","next","pickHandler","built","nextTarget","nextId","RetryPolicyFields","StepBuilderModal","BufferErrorHandlingPanel","onPolicyChange","policyFromDefinition","CachedErrorHandlingPanel","fnQuery","useFunctionQuery","epQuery","useEndpointQuery","saveFnMut","useGuardedSaveFunctionMutation","saveEpMut","useGuardedSaveEndpointMutation","record","callableRecord","onError","vars","definitionWithPolicy","settled","e","ApiError","ErrorHandlingPanel","ErrorHandlingToolIcon","errorHandlingTool","isSettingsRailAvailable","commitTag","tags","typed","removeTag","tag","TagEditor","onChange","setTyped","handleTypedChange","result","IconButton","CallableSettingsModal","props","settings","descriptorFor","initial","displayName","setDisplayName","setKey","setTags","isSaving","setIsSaving","displayNameChanged","keyChanged","tagsChanged","isDirty","canEditKey","keyGrammarOk","isEndpointKey","canSubmit","handleSave","enterSubmit","useEnterSubmit","filterKeyInput","TESTIDS","VersionHistoryModal","versionNumber","testids","versionQuery","useVersionQuery","revertMut","useRevertMutation","invokeMut","useInvokeVersionMutation","confirmingRevert","setConfirmingRevert","Fragment","CodeBlock","ConfirmModal","DangerZone","archived","deleteLabel","deleteTestId","archiveTestId","onRequestDelete","onRequestArchive","deleteError","archiveError","DeleteButton","SettingsHeading","EditButton","MetadataSection","fields","row","SpecActionsTrigger","SpecChooserModal","onImport","onClose","VersionSection","open","versions","VersionListModal","loading","DANGER_COPY","SettingsDangerZone","copy","IMPORT_LIST_KEYS","functionsKey","endpointsKey","workflowsKey","WorkflowSettingsPanel","editingSettings","setEditingSettings","historyOpen","setHistoryOpen","versionListOpen","setVersionListOpen","isWorkflow","wfDefQuery","useWorkflowQuery","saveWfMut","useSaveWorkflowMutation","archiveWfMut","useArchiveWorkflowMutation","deleteWfMut","useDeleteWorkflowMutation","specMenuOpen","setSpecMenuOpen","importing","setImporting","deleteConfirming","setDeleteConfirming","archiveConfirming","setArchiveConfirming","setDeleteError","setArchiveError","versionsQuery","useVersionsQuery","publishMut","usePublishMutation","setEnabledMut","useSetEnabledMutation","publishError","setPublishError","enableError","setEnableError","openVersion","setOpenVersion","listRow","onDelete","onArchive","metadataFieldsForKind","data","stored","resolve","reject","updated","ImportSpecModal","newId","SettingsToolPanel","CallableSettingsPanel","kind0","endpointsQuery","useEndpointsQuery","editing","setEditing","editText","setEditText","editError","setEditError","editToken","setEditToken","exporting","setExporting","fnDefQuery","epDefQuery","deleteFnMut","useDeleteFunctionMutation","deleteEpMut","useDeleteEndpointMutation","archiveFnMut","useArchiveFunctionMutation","archiveEpMut","useArchiveEndpointMutation","specCollection","specCollectionForKind","specQuery","useSpecQuery","versionsKind","hasVersionHistory","def","defJson","openEdit","editEval","evaluateEdit","savingDef","onSaveEdit","onSettled","hasDefinitionActions","JsonEditor","hasDelete","k","SettingsToolIcon","settingsTool","editorRailTools"],"mappings":";;;;;;;;;;;;;;AAyGA,MAAMA,KAAmBC,GAA4C,IAAI;AASlE,SAASC,GAAkB;AAAA,EAChC,UAAAC;AAAA,EACA,MAAAC,IAAO;AACT,GAAsD;AACpD,QAAM,CAACC,GAAUC,CAAW,IAAIC,EAA4B,IAAI,GAC1DC,IAAWH,KAAYD,GACvBK,IAAQC,GAAQ,OAAO,EAAE,UAAAF,GAAU,aAAAF,MAAgB,CAACE,CAAQ,CAAC;AACnE,SAAO,gBAAAG,EAACX,GAAiB,UAAjB,EAA0B,OAAAS,GAAe,UAAAN,EAAA,CAAS;AAC5D;AAGO,SAASS,KAA2B;AACzC,SAAOC,GAAWb,EAAgB,MAAM;AAC1C;AAGO,SAASc,GAAaN,GAAmC;AAC9D,QAAMO,IAAMF,GAAWb,EAAgB;AACvC,MAAI,CAACe,EAAK,OAAM,IAAI,MAAM,sDAAsD;AAChF,QAAM,EAAE,aAAAT,MAAgBS,GAclBC,IAAMR,IAAW,KAAK,UAAUA,CAAQ,IAAI;AAElD,EAAAS,GAAU,OACRX,EAAYE,CAAQ,GACb,MAAMF,EAAY,IAAI,IAC5B,CAACU,GAAKV,CAAW,CAAC;AACvB;AAGO,SAASY,KAA0C;AACxD,QAAMH,IAAMF,GAAWb,EAAgB;AACvC,MAAI,CAACe,EAAK,OAAM,IAAI,MAAM,8DAA8D;AACxF,SAAOA,EAAI;AACb;ACnIA,MAAMI,KAAoB,EAAE,MAAM,IAAO,YAAY,KAAA;AASrD,SAASC,GAAgBJ,GAAwB;AAC/C,MAAI,OAAO,eAAiB,IAAa,QAAOG;AAChD,QAAME,IAAM,aAAa,QAAQL,CAAG,GAC9B,EAAE,YAAAM,EAAA,IAAeC,GAAiBF,CAAG;AAC3C,SAAO,EAAE,MAAM,IAAO,YAAAC,EAAA;AACxB;AAIA,SAASE,GAAU;AAAA,EACjB,OAAAC;AAAA,EACA,KAAAV;AAAA,EACA,OAAAW;AAAA,EACA,UAAAC;AACF,GAKG;AACD,QAAML,IAAaI,EAAM,OAAQD,EAAM,KAAK,CAACG,MAAMA,EAAE,OAAOF,EAAM,UAAU,KAAK,OAAQ;AACzF,SACE,gBAAAG,EAAC,SAAA,EAAM,WAAU,cACf,UAAA;AAAA,IAAA,gBAAAlB,EAAC,SAAI,WAAU,oBACZ,UAAAc,EAAM,IAAI,CAACK,MACV,gBAAAnB;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,MAAK;AAAA,QACL,eAAa,aAAamB,EAAK,EAAE;AAAA,QACjC,WAAW,uBAAsBR,KAAA,gBAAAA,EAAY,QAAOQ,EAAK,KAAK,YAAY,EAAE;AAAA,QAC5E,OAAOA,EAAK;AAAA,QACZ,cAAYA,EAAK;AAAA,QACjB,iBAAcR,KAAA,gBAAAA,EAAY,QAAOQ,EAAK;AAAA,QACtC,SAAS,MAAMH,EAASG,EAAK,EAAE;AAAA,QAE/B,UAAA,gBAAAnB,EAACmB,EAAK,MAAL,CAAA,CAAU;AAAA,MAAA;AAAA,MATNA,EAAK;AAAA,IAAA,CAWb,GACH;AAAA,IACCR,uBACE,OAAA,EAAI,WAAU,oBAAmB,eAAa,cAAcA,EAAW,EAAE,IACvE,UAAA;AAAA,MAAA,CAACA,EAAW,kBACX,gBAAAX,EAAC,OAAA,EAAI,WAAU,yBACb,UAAA,gBAAAA,EAAC,MAAA,EAAI,UAAAW,EAAW,MAAA,CAAM,GACxB;AAAA,MAEF,gBAAAX,EAACW,EAAW,OAAX,EAAiB,KAAAP,EAAA,CAAU;AAAA,IAAA,EAAA,CAC9B;AAAA,EAAA,GAEJ;AAEJ;AASA,SAASgB,GAAc;AAAA,EACrB,YAAAC;AAAA,EACA,OAAAP;AAAA,EACA,KAAAV;AACF,GAIG;AACD,QAAM,CAACW,GAAOO,CAAQ,IAAI1B,EAAoB,MAAMa,GAAgBY,CAAU,CAAC;AAK/E,EAAAf,GAAU,MAAM;AACd,IAAI,OAAO,eAAiB,OAC5B,aAAa,QAAQe,GAAY,KAAK,UAAU,EAAE,YAAYN,EAAM,WAAA,CAAY,CAAC;AAAA,EACnF,GAAG,CAACM,GAAYN,EAAM,UAAU,CAAC;AAEjC,WAASC,EAASO,GAAY;AAC5B,IAAAD;AAAA,MAAS,CAACE,MACRA,EAAK,QAAQA,EAAK,eAAeD,IAC7B,EAAE,MAAM,IAAO,YAAYA,EAAA,IAC3B,EAAE,MAAM,IAAM,YAAYA,EAAA;AAAA,IAAG;AAAA,EAErC;AAEA,SAAO,gBAAAvB,EAACa,IAAA,EAAU,OAAAC,GAAc,KAAAV,GAAU,OAAAW,GAAc,UAAAC,GAAoB;AAC9E;AAIO,SAASS,GAAU;AAAA,EACxB,OAAAX;AAAA,EACA,YAAAO;AACF,GAGG;AACD,QAAMjB,IAAMG,GAAA,GACNmB,IAAYZ,EAAM,OAAO,CAACG,MAAMA,EAAE,YAAYb,CAAG,CAAC;AACxD,SAAIsB,EAAU,WAAW,IAAU,OAC/BL,MAAe,OACV,gBAAArB,EAACa,MAAU,OAAOa,GAAW,KAAAtB,GAAU,OAAOI,IAAQ,UAAU,MAAM;AAAA,EAAC,GAAG,sBAE3EY,IAAA,EAA+B,YAAAC,GAAwB,OAAOK,GAAW,KAAAtB,KAAtDiB,CAAgE;AAC7F;ACjFO,SAASM,GAA4BC,GAA2C;AACrF,QAAMC,IAAYD,GAKZE,IAAYC,GAAaF,KAAa,QAAWA,KAAa,IAAI,GAClEG,IAAeC,GAAA,GACfC,IAAiBC,GAAkBN,KAAa,QAAWA,KAAa,IAAI,GAC5EO,IAAeC,GAAA,GAIfC,IAAeC,GAAA,GACfC,IAAkBC,GAAA;AAExB,SAAO1C;AAAA,IACL,OAAO;AAAA,MACL,OAAO+B,EAAU,QAAQ,CAAA,GAAI,IAAI,CAACY,MAAMA,EAAE,IAAI;AAAA,MAC9C,UAAUV,EAAa,QAAQ,CAAA,GAAI,IAAI,CAACW,MAAMA,EAAE,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,MAKpD,WAAWC,GAAuBV,EAAe,QAAQ,CAAA,CAAE;AAAA;AAAA;AAAA;AAAA,MAI3D,cAAc;AAAA,QACZ,GAAG,OAAO,aAAaJ,EAAU,QAAQ,CAAA,GAAI,IAAI,CAACY,MAAM,CAAC,QAAQA,EAAE,IAAI,IAAIA,EAAE,KAAK,CAAC,CAAC;AAAA,QACpF,GAAGG,GAAqBX,EAAe,QAAQ,CAAA,CAAE;AAAA,MAAA;AAAA,MAEnD,YAAYE;AAAA;AAAA;AAAA;AAAA;AAAA,MAKZ,WAAW,CAACU,MACVR,EACG,YAAY;AAAA,QACX,OAAO;AAAA,UACL,MAAMQ,EAAM;AAAA,UACZ,MAAM;AAAA,UACN,OAAOA,EAAM;AAAA,UACb,aAAaA,EAAM;AAAA,QAAA;AAAA,QAErB,SAASjB,KAAa;AAAA,MAAA,CACvB,EACA,KAAK,MAAA;AAAA,OAAe;AAAA;AAAA;AAAA;AAAA,MAIzB,cAAc,CAACiB,MACbN,EACG,YAAY,EAAE,MAAMM,EAAM,MAAM,OAAOA,EAAM,OAAO,aAAaA,EAAM,aAAa,EACpF,KAAK;OAAe;AAAA,IAAA;AAAA,IAE3B;AAAA,MACEhB,EAAU;AAAA,MACVE,EAAa;AAAA,MACbE,EAAe;AAAA,MACfE;AAAA,MACAE,EAAa;AAAA,MACbE,EAAgB;AAAA,MAChBX;AAAA,IAAA;AAAA,EACF;AAEJ;AASO,SAASkB,GAAuB;AAAA,EACrC,SAAAnB;AAAA,EACA,UAAApC;AACF,GAGG;AACD,QAAMwD,IAAUrB,GAA4BC,CAAO;AACnD,SAAO,gBAAA5B,EAACiD,IAAA,EAA0B,OAAOD,GAAU,UAAAxD,EAAA,CAAS;AAC9D;AChHA,SAAS0D,GAAU,EAAE,KAAA9C,KAAmC;AAItD,QAAM,CAAC+C,GAASC,CAAU,IAAIxD,EAA8B,IAAI,GAC1DyD,IAAkBC,GAAkBlD,CAAG;AAM7C,MAAI,CAACiD,EAAiB,QAAO;AAC7B,QAAME,KAAWnD,KAAA,gBAAAA,EAAK,UAAS,aAAaA,EAAI,WAAW,QACrDoD,IAAOC,GAAeJ,CAAe;AAI3C,SAAIG,EAAK,WAAW,IAAU,gBAAAxD,EAAC,OAAE,WAAU,SAAS,UAAA0D,GAAkBL,CAAe,EAAA,CAAE,sBAGpF,OAAA,EAkBC,UAAA;AAAA,IAAA,gBAAArD,EAAC,KAAA,EAAE,WAAU,eAAc,OAAO,EAAE,WAAW,EAAA,GAAK,UAAA,kBAAA,CAEpD;AAAA,IACA,gBAAAA,EAAC,OAAA,EAAI,WAAU,mBACZ,UAAAwD,EAAK,IAAI,CAAC,EAAE,IAAAjC,GAAI,OAAAoC,GAAO,MAAAC,EAAA,MACtB,gBAAA1C;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,eAAa,kBAAkBK,CAAE;AAAA,QACjC,OAAO,YAAYoC,CAAK;AAAA,QACxB,cAAY,YAAYA,CAAK;AAAA,QAC7B,SAAS,MAAMP,EAAW7B,CAAE;AAAA,QAE5B,UAAA;AAAA,UAAA,gBAAAvB,EAAC6D,GAAA,EAAK,MAAMD,GAAM,MAAM,IAAI;AAAA,UAC5B,gBAAA5D,EAAC,UAAM,UAAA2D,EAAA,CAAM;AAAA,QAAA;AAAA,MAAA;AAAA,MATRpC;AAAA,IAAA,CAWR,GACH;AAAA,IAKC4B,MAAY,QACX,gBAAAnD,EAAC8D,GAAA,EAAM,OAAM,kBAAiB,MAAI,IAAC,SAAS,MAAMV,EAAW,IAAI,GAC/D,UAAA,gBAAApD,EAAC,OAAA,EAAI,OAAO,EAAE,QAAQ,IAAA,GACpB,UAAA,gBAAAA,EAAC+D,IAAA,EAAiB,UAAUV,GAAiB,UAAAE,GAAoB,YAAYJ,EAAA,CAAS,EAAA,CACxF,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;AAEA,SAASa,KAAe;AACtB,SAAO,gBAAAhE,EAAC6D,GAAA,EAAK,MAAK,OAAA,CAAO;AAC3B;AAEO,MAAMI,KAAqB;AAAA,EAChC,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAMD;AAAA,EACN,aAAa,CAAC5D,MAAQ8D,GAAY9D,CAAG;AAAA,EACrC,OAAO8C;AACT,GC5FMiB,KAAuB,EAAE,SAAS,MAAM,YAAY,MAAM;AAAC,EAAA,GAE3DC,KAAiB9E,GAAuB6E,EAAW;AAElD,SAASE,GAAgB;AAAA,EAC9B,SAAAzC;AAAA,EACA,YAAA0C;AAAA,EACA,UAAA9E;AACF,GAAsC;AACpC,SACE,gBAAAQ,EAACoE,GAAe,UAAf,EAAwB,OAAO,EAAE,SAAAxC,GAAS,YAAA0C,KAAe,UAAA9E,GAAS;AAEvE;AAEO,SAAS+E,KAAsB;AACpC,SAAOrE,GAAWkE,EAAc;AAClC;ACSO,MAAMI,KAAW;AAOxB,SAASC,GAAMC,GAAgD;AAC7D,SAAKA,IACDA,EAAO,SAAS,aAAmBA,EAAO,WAC1CA,EAAO,SAAS,aAAmBA,EAAO,WACvC,GAAGA,EAAO,KAAK,GAAG,IAAIA,EAAO,KAAK,MAAM,KAH3B;AAItB;AAGA,SAASC,GAAOD,GAAgD;AAC9D,UAAIA,KAAA,gBAAAA,EAAQ,UAAS,aAAmB,6BACpCA,KAAA,gBAAAA,EAAQ,UAAS,aAAmB,2BACjC;AACT;AAcO,SAASE,GAAoB;AAAA,EAClC,MAAAC;AAAA,EACA,IAAAtD;AAAA,EACA,QAAAuD;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,WAAAC;AACF,GAA6B;;AAG3B,QAAMC,IAAiBC,GAAkB,EAAI,GAGvC,EAAE,SAAAvD,EAAA,IAAY2C,GAAA,GACda,IAAiBC,GAAkBzD,KAAW,QAAW,EAAI,GAE7D,CAAC0D,GAAYC,CAAa,IAAI3F,EAAS,EAAK,GAC5C,CAAC4F,GAAOC,CAAQ,IAAI7F,EAAwB,IAAI,GAEhD8E,KAASgB,IAAAZ,EAAO,YAAP,gBAAAY,EAAgB,QACzBC,IAAMlB,GAAMC,CAAM,GAClBkB,IAAelB,IACjBmB,GAAyB;AAAA,IACvB,UAAU,EAAE,MAAAhB,GAAM,IAAAtD,EAAA;AAAA,IAClB,QAAQ,EAAE,MAAMmD,EAAO,MAAM,IAAIiB,EAAA;AAAA,IACjC,cAAYG,IAAAhB,EAAO,YAAP,gBAAAgB,EAAgB,UAAS;AAAA,EAAA,CACtC,IACD,SACEnC,KACJe,KAAA,gBAAAA,EAAQ,UAAS,eACZqB,KAAAC,IAAAZ,EAAe,SAAf,gBAAAY,EAAqB,KAAK,CAACC,MAAMA,EAAE,OAAON,OAA1C,gBAAAI,EAAgD,gBAAe,UAC/D,MAAM;;AACL,UAAMG,KAAKR,IAAAR,EAAe,SAAf,gBAAAQ,EAAqB,KAAK,CAACS,MAAMA,EAAE,OAAOR;AACrD,WAAOO,IAAKA,EAAG,eAAeA,EAAG,MAAM;AAAA,EACzC,GAAA;AAIN,EAAA5F,GAAU,MAAM;AACd,IAAIiB,KAAMsD,KAAMY,EAAS,IAAI;AAAA,EAC/B,GAAG,CAAClE,GAAIsD,CAAI,CAAC;AAGb,WAASuB,EAAQC,GAAsB;AACrC,IAAAZ,EAAS,IAAI,GACbR,EAAUoB,GAAMZ,CAAQ;AAAA,EAC1B;AAUA,WAASa,EAAYC,GAAkB;;AACrC,QAAIC;AACJ,QAAID,EAAM,KAAK,QAAQ/B,IAAU;AAC/B,YAAMyB,IAAKM,EAAM,QAAQ,CAAA,GACnBE,IAAS,OAAOR,EAAE,YAAa,WAAWA,EAAE,WAAW;AAC7D,UAAI,CAACQ,EAAQ;AACb,MAAAD,IACEP,EAAE,eAAe,aACb,EAAE,MAAM,YAAY,UAAUQ,EAAA,IAC9B,EAAE,MAAM,YAAY,UAAUA,EAAA;AAAA,IACtC,WAAW,CAACF,EAAM,KAAK,IAAI,WAAW,OAAO;AAI3C,MAAAC,IAAa;AAAA,QACX,MAAM;AAAA,QACN,MAAM;AAAA,UACJ,KAAKD,EAAM,KAAK;AAAA,UAChB,QAAQA,EAAM,KAAK;AAAA,UACnB,YAAYA,EAAM,KAAK,cAAc;AAAA,QAAA;AAAA,QAEvC,GAAIA,EAAM,OAAO,EAAE,MAAMA,EAAM,KAAA,IAAS,CAAA;AAAA,MAAC;AAAA;AAG3C;AAOF,QALqBV,GAAyB;AAAA,MAC5C,UAAU,EAAE,MAAAhB,GAAM,IAAAtD,EAAA;AAAA,MAClB,QAAQ,EAAE,MAAMiF,EAAW,MAAM,IAAI/B,GAAM+B,CAAU,EAAA;AAAA,MACrD,cAAYd,IAAAZ,EAAO,YAAP,gBAAAY,EAAgB,UAAS;AAAA,IAAA,CACtC,MACoB,SAAS;AAC5B,MAAAD;AAAA,QACE;AAAA,MAAA,GAEFF,EAAc,EAAK;AACnB;AAAA,IACF;AAGA,IAAAa,EAAQ,EAAE,GAAGtB,GAAQ,SAAS,EAAE,GAAGA,EAAO,SAAS,QAAQ0B,EAAA,GAAc,GACzEjB,EAAc,EAAK;AAAA,EACrB;AAEA,SAAI,CAACR,KAAS,CAACC,IACN,gBAAAhF,EAAC,KAAA,EAAE,WAAU,eAAc,UAAA,YAAQ,IAI1C,gBAAAkB,EAAC,OAAA,EAAI,WAAU,aAAY,eAAY,2BAErC,UAAA;AAAA,IAAA,gBAAAA,EAAC,WAAA,EAAQ,eAAY,sBACnB,UAAA;AAAA,MAAA,gBAAAlB;AAAA,QAAC0G;AAAA,QAAA;AAAA,UACC,OAAO5B,EAAO;AAAA,UACd,UAAU,CAACuB,MAASD,EAAQ,EAAE,GAAGtB,GAAQ,OAAOuB,GAAM;AAAA,UACtD,UAAUrB;AAAA,UACV,QAAQH;AAAA,QAAA;AAAA,MAAA;AAAA,MAETA,MAAS,cACR,gBAAA7E,EAAC,KAAA,EAAE,WAAU,eAAc,eAAY,0BAAyB,UAAA,4LAAA,CAIhE;AAAA,IAAA,GAEJ;AAAA,sBAEC,KAAA,EAAE,WAAU,eACV,UAAA6E,MAAS,aACN,qFACA,sEACN;AAAA,IAECc,IACC,gBAAAzE,EAAC,OAAA,EAAI,WAAU,OAAM,OAAO,EAAE,YAAY,UAAU,KAAK,EAAA,GACvD,UAAA;AAAA,MAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,aACd,UAAA;AAAA,QAAA,gBAAAlB,EAAC,UAAA,EAAQ,eAAS2F,EAAA,CAAI;AAAA,QAAS;AAAA,QAAC,gBAAA3F,EAAC,QAAA,EAAK,WAAU,SAAS,UAAA2F,GAAI;AAAA,0BAC5D,QAAA,EAAK,WAAU,qBAAqB,UAAAhB,GAAOD,CAAM,EAAA,CAAE;AAAA,MAAA,GACtD;AAAA,MACA,gBAAA1E;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,eAAY;AAAA,UACZ,UAAUgF;AAAA,UACV,SAAS,MAAMO,EAAc,EAAI;AAAA,UAClC,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,EAAA,CACF,IAEA,gBAAAvF;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,eAAY;AAAA,QACZ,UAAUgF;AAAA,QACV,SAAS,MAAMO,EAAc,EAAI;AAAA,QAClC,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAKFI,KACC,gBAAA3F;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,eAAY;AAAA,QACZ,UAAUgF;AAAA,QACV,SAAS,MAAMoB,EAAQ,EAAE,GAAGtB,GAAQ,SAAS,QAAW;AAAA,QACzD,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAKFc,MAAiB,UAChB,gBAAA5F,EAAC,OAAA,EAAI,WAAU,gBAAe,eAAY,mCAAkC,UAAA,mJAAA,CAG5E;AAAA,IAGDwF,KACC,gBAAAxF,EAAC,OAAA,EAAI,WAAU,SAAQ,eAAY,4BAChC,UAAAwF,GACH;AAAA,IAGDF,KACC,gBAAAtF;AAAA,MAAC2G;AAAA,MAAA;AAAA,QACC,UAAQ;AAAA,QACR,WAAW,CAAC,YAAY,UAAU;AAAA,QAClC,OAAM;AAAA,QACN,SAAS,MAAMpB,EAAc,EAAK;AAAA,QAClC,OAAOe;AAAA,MAAA;AAAA,IAAA;AAAA,EACT,GAEJ;AAEJ;AAOA,SAASM,GAAyB,EAAE,KAAAxG,KAAkD;AACpF,QAAM0E,IAAS,YAAY1E,IAAMA,EAAI,SAAS,QACxCyG,IAAiB,oBAAoBzG,IAAMA,EAAI,iBAAiB;AACtE,SACE,gBAAAJ;AAAA,IAAC4E;AAAA,IAAA;AAAA,MACC,MAAMxE,EAAI;AAAA,MACV,IAAIA,EAAI;AAAA,MACR,QAAQ0E,IAASgC,GAAqBhC,CAAM,IAAI,CAAA;AAAA,MAChD,OAAO,EAAQ+B;AAAA,MACf,QAAQ;AAAA,MACR,WAAW,CAACR,MAASQ,KAAA,gBAAAA,EAAiBR;AAAA,IAAI;AAAA,EAAA;AAGhD;AAGA,SAASU,GAAyB,EAAE,IAAAxF,GAAI,MAAAsD,KAAuD;AAC7F,QAAMmC,IAAUC,GAAiB1F,GAAIsD,MAAS,UAAU,GAClDqC,IAAUC,GAAiB5F,GAAIsD,MAAS,UAAU,GAClDuC,IAAYC,GAAA,GACZC,IAAYC,GAAA,GAEZC,IAASC,GAAe5C,GAAMA,MAAS,aAAamC,EAAQ,OAAOE,EAAQ,IAAI,GAC/ElC,IAASH,MAAS,aAAauC,EAAU,YAAYE,EAAU;AAErE,SACE,gBAAAtH;AAAA,IAAC4E;AAAA,IAAA;AAAA,MACC,MAAAC;AAAA,MACA,IAAAtD;AAAA,MACA,QAAQiG,IAASV,GAAqBU,EAAO,UAAU,IAAI,CAAA;AAAA,MAC3D,OAAO,EAAQA;AAAA,MACf,QAAAxC;AAAA,MACA,WAAW,CAACqB,GAAMqB,MAAY;AAC5B,YAAI,CAACF,EAAQ;AACb,cAAMG,IAAO;AAAA,UACX,YAAYC,GAAqBJ,EAAO,YAAYnB,CAAI;AAAA,UACxD,mBAAmBmB,EAAO;AAAA,QAAA,GAEtBK,IAAU;AAAA,UACd,SAAS,CAACC,MAAeJ,EAAQI,aAAaC,IAAWD,EAAE,UAAU,OAAOA,CAAC,CAAC;AAAA,QAAA;AAEhF,QAAIjD,MAAS,aAAYuC,EAAU,OAAOO,GAAME,CAAO,IAClDP,EAAU,OAAOK,GAAME,CAAO;AAAA,MACrC;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,SAASG,GAAmB,EAAE,KAAA5H,KAAmC;AAG/D,UAAIA,KAAA,gBAAAA,EAAK,UAAS,eAAcA,KAAA,gBAAAA,EAAK,UAAS,eAAcA,KAAA,gBAAAA,EAAK,UAAS,aACjE,OAELA,EAAI,SAAS,cAAc,OAAOA,EAAI,kBAAmB,aACpD,gBAAAJ,EAAC4G,MAAyB,KAAAxG,GAAU,sBAErC2G,IAAA,EAAyB,IAAI3G,EAAI,IAAI,MAAMA,EAAI,MAAM;AAC/D;AAEA,SAAS6H,KAAwB;AAC/B,SAAO,gBAAAjI,EAAC6D,GAAA,EAAK,MAAK,UAAA,CAAU;AAC9B;AAEO,MAAMqE,KAA8B;AAAA,EACzC,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,MAAMD;AAAA,EACN,aAAa,CAAC7H,MAAQ+H,GAAwB/H,CAAG;AAAA,EACjD,OAAO4H;AACT;ACvUO,SAASI,GAAUC,GAAgBC,GAAkD;AAC1F,MAAI,CAACA,EAAM,SAAS,GAAG,EAAG,QAAO,EAAE,MAAAD,GAAM,OAAAC,EAAA;AACzC,MAAIjC,IAAOgC;AACX,aAAW3H,KAAO4H,EAAM,MAAM,GAAG,GAAG;AAClC,UAAMrH,IAAIP,EAAI,KAAA;AACd,IAAIO,KAAK,CAACoF,EAAK,SAASpF,CAAC,MAAGoF,IAAO,CAAC,GAAGA,GAAMpF,CAAC;AAAA,EAChD;AACA,SAAO,EAAE,MAAMoF,GAAM,OAAO,GAAA;AAC9B;AAOO,SAASkC,GAAUF,GAAgBG,GAAuB;AAC/D,SAAOH,EAAK,OAAO,CAAC,MAAM,MAAMG,CAAG;AACrC;ACjBO,SAASC,GAAU,EAAE,MAAAJ,GAAM,UAAAK,KAA4B;AAC5D,QAAM,CAACJ,GAAOK,CAAQ,IAAI/I,EAAS,EAAE;AAErC,WAASgJ,EAAkB9I,GAAe;AACxC,UAAM+I,IAAST,GAAUC,GAAMvI,CAAK;AACpC,IAAA6I,EAASE,EAAO,KAAK,GACjBA,EAAO,SAASR,KAAMK,EAASG,EAAO,IAAI;AAAA,EAChD;AAEA,SACE,gBAAA3H,EAAC,OAAA,EAAI,WAAU,YAAW,eAAY,cACnC,UAAA;AAAA,IAAAmH,EAAK,IAAI,CAACpH,MACT,gBAAAC,EAAC,QAAA,EAAa,WAAU,iBACrB,UAAA;AAAA,MAAAD;AAAA,MACD,gBAAAjB;AAAA,QAAC8I;AAAA,QAAA;AAAA,UACC,QAAM;AAAA,UACN,MAAK;AAAA,UACL,OAAO,cAAc7H,CAAC;AAAA,UACtB,OAAO,UAAUA,CAAC;AAAA,UAClB,SAAS,MAAMyH,EAASH,GAAUF,GAAMpH,CAAC,CAAC;AAAA,QAAA;AAAA,MAAA;AAAA,IAC5C,EAAA,GARSA,CASX,CACD;AAAA,IACD,gBAAAjB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAOsI;AAAA,QACP,aAAY;AAAA,QACZ,cAAW;AAAA,QACX,UAAU,CAACR,MAAMc,EAAkBd,EAAE,OAAO,KAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EACnD,GACF;AAEJ;ACrBO,SAASiB,GAAsBC,GAAmC;AAIvE,QAAMC,IAAWC,GAAcF,EAAM,IAAI,EAAE,UACrC,EAAE,SAAAG,MAAYH,GACd,CAACI,GAAaC,CAAc,IAAIzJ,EAASuJ,EAAQ,WAAW,GAC5D,CAAC9I,GAAKiJ,CAAM,IAAI1J,EAASuJ,EAAQ,OAAO,EAAE,GAC1C,CAACd,GAAMkB,CAAO,IAAI3J,EAAmBuJ,EAAQ,QAAQ,EAAE,GACvD,CAACK,GAAUC,CAAW,IAAI7J,EAAS,EAAK,GACxC,CAAC4F,GAAOC,CAAQ,IAAI7F,EAAwB,IAAI,GAEhD8J,IAAqBN,MAAgBD,EAAQ,aAC7CQ,IAAatJ,OAAS8I,EAAQ,OAAO,KACrCS,IACJX,EAAS,WAAW,KAAK,UAAUZ,CAAI,MAAM,KAAK,UAAUc,EAAQ,QAAQ,CAAA,CAAE,GAC1EU,IAAUH,KAAsBC,KAAcC,GAG9CE,IAAab,EAAS,YACtBc,IAAe1J,MAAQ,MAAM2J,GAAc3J,CAAG,GAC9C4J,IAAYJ,KAAWE,KAAgB,CAACP;AAE9C,iBAAeU,IAAa;AAC1B,QAAKD,GACL;AAAA,MAAAxE,EAAS,IAAI,GACbgE,EAAY,EAAI;AAChB,UAAI;AACF,cAAMT,EAAM,OAAO;AAAA,UACjB,aAAaI,EAAY,KAAA;AAAA,UACzB,KAAKU,KAAcH,IAAatJ,IAAM8I,EAAQ;AAAA,UAC9C,MAAMF,EAAS,UAAUZ,IAAO;AAAA,QAAA,CACjC,GACDW,EAAM,QAAA;AAAA,MACR,SAASlB,GAAG;AACV,QAAArC,EAASqC,aAAaC,IAAWD,EAAE,UAAU,OAAOA,CAAC,CAAC;AAAA,MACxD,UAAA;AACE,QAAA2B,EAAY,EAAK;AAAA,MACnB;AAAA;AAAA,EACF;AAEA,QAAMU,IAAcC,GAAeF,GAAY,EAAE,SAASD,GAAW;AAErE,2BACGnG,GAAA,EAAM,OAAM,iBAAgB,SAASkF,EAAM,SAC1C,UAAA;AAAA,IAAA,gBAAA9H,EAAC,OAAA,EAAI,WAAU,cACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,QAAA,gBAAAlB,EAAC,UAAK,UAAA,OAAA,CAAI;AAAA,QACV,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAOoJ;AAAA,YACP,UAAU,CAACtB,MAAMuB,EAAevB,EAAE,OAAO,KAAK;AAAA,YAC9C,aAAamB,EAAS;AAAA,YACtB,WAAS;AAAA,YACR,GAAGkB;AAAA,UAAA;AAAA,QAAA;AAAA,MACN,GACF;AAAA,MAECL,KACC,gBAAA5I,EAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,QAAA,gBAAAlB,EAAC,UAAK,UAAA,MAAA,CAAG;AAAA,QACT,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAOK;AAAA,YACP,UAAU,CAACyH,MAAMwB,EAAOe,GAAevC,EAAE,OAAO,KAAK,CAAC;AAAA,YACtD,aAAamB,EAAS;AAAA,YACrB,GAAGkB;AAAA,UAAA;AAAA,QAAA;AAAA,QAEN,gBAAAjJ,EAAC,QAAA,EAAK,WAAU,eAAc,UAAA;AAAA,UAAA;AAAA,UAE3B+H,EAAS;AAAA,QAAA,EAAA,CACZ;AAAA,MAAA,GACF;AAAA,MAGDA,EAAS,WACR,gBAAA/H,EAAC,OAAA,EACC,UAAA;AAAA,QAAA,gBAAAlB,EAAC,KAAA,EAAE,WAAU,eAAc,OAAO,EAAE,cAAc,MAAA,GAAS,UAAA,OAAA,CAE3D;AAAA,QACA,gBAAAA,EAACyI,IAAA,EAAU,MAAAJ,GAAY,UAAUkB,EAAA,CAAS;AAAA,MAAA,GAC5C;AAAA,MAGD/D,KAAS,gBAAAxF,EAAC,OAAA,EAAI,WAAU,SAAS,UAAAwF,EAAA,CAAM;AAAA,IAAA,GAC1C;AAAA,IAEA,gBAAAtE,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAA,gBAAAlB,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,aAAY,SAASgJ,EAAM,SAAS,UAAA,SAAA,CAEpE;AAAA,MACA,gBAAAhJ,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,OAAM,UAAU,CAACiK,GAAW,SAASC,GAClE,UAAAV,IAAW,YAAY,OAAA,CAC1B;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;ACrHA,MAAMc,KAUF;AAAA,EACF,UAAU;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,cAAc;AAAA,IACd,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,aAAa;AAAA,EAAA;AAAA,EAEf,UAAU;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,cAAc;AAAA,IACd,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,aAAa;AAAA,EAAA;AAAA,EAEf,UAAU;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,cAAc;AAAA,IACd,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,aAAa;AAAA,EAAA;AAEjB;AAiCO,SAASC,GAAoBvB,GAKjC;AACD,QAAM,EAAE,MAAAnE,GAAM,IAAAtD,GAAI,eAAAiJ,EAAA,IAAkBxB,GAC9ByB,IAAUH,GAAQzF,CAAI,GAItB6F,IAAeC,GAAgB9F,GAAMtD,GAAIiJ,GAAe,EAAI,GAC5DI,IAAYC,GAAkBhG,CAAI,GAClCiG,IAAYC,GAAyBlG,CAAI,GACzC,CAACmG,GAAkBC,CAAmB,IAAIrL,EAAS,EAAK;AAE9D,SACE,gBAAAsB,EAAAgK,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAhK,EAAC4C,GAAA,EAAM,OAAO,WAAW0G,CAAa,IAAI,SAASxB,EAAM,SAAS,MAAI,IACpE,UAAA;AAAA,MAAA,gBAAA9H,EAAC,OAAA,EAAI,WAAU,cACZ,UAAA;AAAA,QAAAwJ,EAAa,YACZ,gBAAA1K,EAAC,KAAA,EAAE,WAAU,eAAc,UAAA,WAAA,CAAQ,IACjC0K,EAAa,UACf,gBAAA1K,EAAC,OAAA,EAAI,WAAU,SAAQ,eAAayK,EAAQ,OACzC,UAAAC,EAAa,iBAAiB,QAC3BA,EAAa,MAAM,UACnB,OAAOA,EAAa,KAAK,EAAA,CAC/B,IACEA,EAAa,OACf,gBAAA1K,EAAC,OAAA,EAAI,eAAayK,EAAQ,MACxB,UAAA,gBAAAzK;AAAA,UAACmL;AAAA,UAAA;AAAA,YACC,MAAM,KAAK,UAAUT,EAAa,KAAK,YAAY,MAAM,CAAC;AAAA,YAC1D,UAAS;AAAA,YACT,WAAU;AAAA,YACV,UAAQ;AAAA,UAAA;AAAA,QAAA,GAEZ,IACE;AAAA,QAEHI,EAAU,SAAS,4BACjB,OAAA,EAAI,eAAaL,EAAQ,YACxB,UAAA,gBAAAzK;AAAA,UAACmL;AAAA,UAAA;AAAA,YACC,MAAM,KAAK,UAAUL,EAAU,MAAM,MAAM,CAAC;AAAA,YAC5C,UAAS;AAAA,YACT,WAAU;AAAA,YACV,UAAQ;AAAA,UAAA;AAAA,QAAA,GAEZ;AAAA,QAEDA,EAAU,WACT,gBAAA9K,EAAC,SAAI,WAAU,SAAQ,eAAayK,EAAQ,aACzC,UAAAK,EAAU,iBAAiB/C,IACxB+C,EAAU,MAAM,UAChB,OAAOA,EAAU,KAAK,EAAA,CAC5B;AAAA,MAAA,GAEJ;AAAA,MAEA,gBAAA5J,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,QAAA,gBAAAlB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,eAAayK,EAAQ;AAAA,YACrB,UAAUK,EAAU;AAAA,YACpB,SAAS,MAAMA,EAAU,OAAO,EAAE,IAAAvJ,GAAI,eAAAiJ,GAAe;AAAA,YAEpD,UAAAM,EAAU,YAAY,cAAc;AAAA,UAAA;AAAA,QAAA;AAAA,QAEvC,gBAAA9K;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,eAAayK,EAAQ;AAAA,YACrB,UAAUG,EAAU;AAAA,YACpB,SAAS,MAAMK,EAAoB,EAAI;AAAA,YAEtC,UAAAL,EAAU,YAAY,eAAe;AAAA,UAAA;AAAA,QAAA;AAAA,QAExC,gBAAA5K,EAAC,YAAO,MAAK,UAAS,WAAU,aAAY,SAASgJ,EAAM,SAAS,UAAA,QAAA,CAEpE;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IACCgC,KACC,gBAAAhL;AAAA,MAACoL;AAAA,MAAA;AAAA,QACC,OAAM;AAAA,QACN,SAAS,qBAAqBZ,CAAa;AAAA,QAC3C,cAAa;AAAA,QACb,aAAW;AAAA,QACX,WAAW,MAAM;AACf,UAAAS,EAAoB,EAAK,GACzBL,EAAU,OAAO,EAAE,IAAArJ,GAAI,eAAAiJ,EAAA,CAAe;AAAA,QACxC;AAAA,QACA,SAAS,MAAMS,EAAoB,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EAC1C,GAEJ;AAEJ;AC3IO,SAASI,GAAWrC,GAAwB;AACjD,QAAM;AAAA,IACJ,UAAAsC;AAAA,IACA,aAAAC;AAAA,IACA,cAAAC;AAAA,IACA,eAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,aAAAC;AAAA,IACA,cAAAC;AAAA,EAAA,IACE7C;AACJ,SACE,gBAAA9H,EAAC,OAAA,EAAI,WAAU,4CAA2C,eAAY,0BAGnE,UAAA;AAAA,IAAAoK,IACC,gBAAApK,EAAC,QAAA,EAAK,WAAU,2BACd,UAAA;AAAA,MAAA,gBAAAlB,EAAC8L,MAAa,OAAOP,GAAa,eAAaC,GAAc,SAASE,GAAiB;AAAA,MACvF,gBAAA1L,EAAC,UAAK,UAAA,SAAA,CAAM;AAAA,IAAA,EAAA,CACd,IAEA,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,eAAayL;AAAA,QACb,SAASE;AAAA,QACV,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAIFC,KACC,gBAAA5L,EAAC,OAAA,EAAI,WAAU,SAAQ,eAAY,qBAChC,UAAA4L,GACH;AAAA,IAEDC,KACC,gBAAA7L,EAAC,OAAA,EAAI,WAAU,SAAQ,eAAY,sBAChC,UAAA6L,EAAA,CACH;AAAA,EAAA,GAEJ;AAEJ;AC7DO,SAASE,GAAgB/C,GAA+B;AAC7D,SACE,gBAAA9H,EAAC,OAAA,EAAI,WAAU,4CACb,UAAA;AAAA,IAAA,gBAAAlB,EAAC,QAAG,UAAA,WAAA,CAAQ;AAAA,IACZ,gBAAAA,EAACgM,MAAW,OAAM,iBAAgB,eAAY,sBAAqB,SAAShD,EAAM,OAAA,CAAQ;AAAA,EAAA,GAC5F;AAEJ;AAOO,SAASiD,GAAgBjD,GAS7B;AACD,QAAM,EAAE,IAAAzH,GAAI,aAAA6H,GAAa,QAAA8C,GAAQ,KAAAC,GAAK,MAAA9D,MAASW;AAC/C,SACE,gBAAAhJ,EAAC,OAAA,EAAI,WAAU,aACb,UAAA,gBAAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,SAAS;AAAA,QACT,gBAAgB;AAAA,QAChB,YAAY;AAAA,QACZ,KAAK;AAAA,MAAA;AAAA,MAGP,UAAA,gBAAAkB,EAAC,MAAA,EAAG,WAAU,kBACX,UAAA;AAAA,QAAAkI,KACC,gBAAAlI,EAAAgK,GAAA,EACE,UAAA;AAAA,UAAA,gBAAAlL,EAAC,QAAG,UAAA,OAAA,CAAI;AAAA,4BACP,MAAA,EAAG,eAAY,kBACd,UAAA,gBAAAA,EAAC,QAAA,EAAM,aAAY,EAAA,CACrB;AAAA,QAAA,GACF;AAAA,QAEF,gBAAAA,EAAC,QAAG,UAAA,KAAA,CAAE;AAAA,0BACL,MAAA,EAAG,eAAY,gBACd,UAAA,gBAAAA,EAAC,QAAA,EAAM,aAAG,EAAA,CACZ;AAAA,QACCkM,EAAO,SAAS,KAAK,KAAKC,KACzB,gBAAAjL,EAAAgK,GAAA,EACE,UAAA;AAAA,UAAA,gBAAAlL,EAAC,QAAG,UAAA,MAAA,CAAG;AAAA,UACP,gBAAAA,EAAC,QAAG,eAAY,iBACd,4BAAC,QAAA,EAAM,UAAAmM,EAAI,OAAO,QAAA,CAAQ,EAAA,CAC5B;AAAA,QAAA,GACF;AAAA,QAEDD,EAAO,SAAS,WAAW,KAAKC,KAC/B,gBAAAjL,EAAAgK,GAAA,EACE,UAAA;AAAA,UAAA,gBAAAlL,EAAC,QAAG,UAAA,UAAA,CAAO;AAAA,UACX,gBAAAA,EAAC,MAAA,EAAG,eAAY,qBAAoB,cAAYmM,EAAI,WACjD,UAAA,IAAI,KAAKA,EAAI,SAAS,EAAE,iBAAe,CAC1C;AAAA,QAAA,GACF;AAAA,QAED9D,MAAS,UAAa8D,KACrB,gBAAAjL,EAAAgK,GAAA,EACE,UAAA;AAAA,UAAA,gBAAAlL,EAAC,QAAG,UAAA,OAAA,CAAI;AAAA,4BACP,MAAA,EAAG,eAAY,kBACb,UAAAqI,EAAK,SAAS,IACXA,EAAK,IAAI,CAACpH,MACR,gBAAAjB,EAAC,UAAa,WAAU,OACrB,eADQiB,CAEX,CACD,IACD,UAAA,CACN;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ;AAOO,SAASmL,GAAmBpD,GAA+B;AAChE,SACE,gBAAAhJ,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA,gBAAAA;AAAA,IAAC8I;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,MACZ,SAASE,EAAM;AAAA,IAAA;AAAA,EAAA,GAEnB;AAEJ;AAQO,SAASqD,GAAiBrD,GAM9B;AACD,QAAM,EAAE,MAAAnE,GAAM,UAAArF,GAAU,UAAA8M,GAAU,SAAAC,MAAYvD;AAC9C,SACE,gBAAA9H,EAAC4C,GAAA,EAAM,OAAM,cAAa,SAAAyI,GACxB,UAAA;AAAA,IAAA,gBAAArL,EAAC,OAAA,EAAI,WAAU,cACZ,UAAA;AAAA,MAAA1B;AAAA,MACD,gBAAA0B,EAAC,KAAA,EAAE,WAAU,eAAc,UAAA;AAAA,QAAA;AAAA,QACe2D;AAAA,QAAK;AAAA,QACxCA;AAAA,QAAK;AAAA,MAAA,GACZ;AAAA,MACA,gBAAA7E,EAAC,OAAA,EAAI,WAAU,sBACb,UAAA,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,eAAY;AAAA,UACZ,SAASsM;AAAA,UACV,UAAA;AAAA,QAAA;AAAA,MAAA,EAED,CACF;AAAA,IAAA,GACF;AAAA,IACA,gBAAAtM,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA,gBAAAA,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,aAAY,SAASuM,GAAS,mBAE9D,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAOO,SAASC,GAAexD,GAU5B;AACD,QAAM,EAAE,MAAAyD,GAAM,UAAAC,EAAA,IAAa1D;AAC3B,SACE,gBAAA9H,EAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,IAAA,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,eAAY;AAAA,QACZ,cAAW;AAAA,QACX,OAAM;AAAA,QACN,SAAS8H,EAAM;AAAA,QAEf,UAAA;AAAA,UAAA,gBAAAhJ,EAAC6D,GAAA,EAAK,MAAK,SAAQ,MAAM,IAAI;AAAA,UAC7B,gBAAA7D,EAAC,UAAK,UAAA,kBAAA,CAAe;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAEtByM,KACC,gBAAAvL,EAAAgK,GAAA,EACE,UAAA;AAAA,MAAA,gBAAAlL,EAAC,KAAA,EAAE,WAAU,eAAc,eAAY,0BACpC,WAAA0M,KAAA,gBAAAA,EAAU,4BAA2B,OAClC,eAAeA,EAAS,uBAAuB,KAC/C,mBACN;AAAA,MACA,gBAAAxL,EAAC,OAAA,EAAI,WAAU,wBACb,UAAA;AAAA,QAAA,gBAAAlB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,eAAY;AAAA,YACZ,UAAUgJ,EAAM;AAAA,YAChB,SAASA,EAAM;AAAA,YAEd,UAAAA,EAAM,aAAa,gBAAgB;AAAA,UAAA;AAAA,QAAA;AAAA,QAC5B;AAAA,QACV,gBAAAhJ;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,eAAY;AAAA,YACZ,UAAUgJ,EAAM,mBAAmB0D,MAAa;AAAA,YAChD,SAAS1D,EAAM;AAAA,YAEd,UAAAA,EAAM,kBAAkB,YAAY0D,KAAA,QAAAA,EAAU,UAAU,YAAY;AAAA,UAAA;AAAA,QAAA;AAAA,MACvE,GACF;AAAA,MACC1D,EAAM,gBACL,gBAAAhJ,EAAC,OAAA,EAAI,WAAU,SAAQ,eAAY,sBAChC,UAAAgJ,EAAM,aAAA,CACT;AAAA,MAEDA,EAAM,eACL,gBAAAhJ,EAAC,OAAA,EAAI,WAAU,SAAQ,eAAY,qBAChC,UAAAgJ,EAAM,YAAA,CACT;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,GAEJ;AAEJ;AAMO,SAAS2D,GAAiB3D,GAK9B;AACD,QAAM,EAAE,SAAA4D,GAAS,UAAAF,EAAA,IAAa1D;AAC9B,SACE,gBAAA9H,EAAC4C,KAAM,OAAM,gBAAe,SAASkF,EAAM,SAAS,MAAI,IACtD,UAAA;AAAA,IAAA,gBAAA9H,EAAC,OAAA,EAAI,WAAU,cACZ,UAAA;AAAA,MAAA0L,KAAW,gBAAA5M,EAAC,KAAA,EAAE,WAAU,eAAc,UAAA,YAAQ;AAAA,OAC9C0M,KAAA,gBAAAA,EAAU,YAAW,uBAAM,KAAA,EAAE,WAAU,eAAc,UAAA,oBAAgB;AAAA,MACrEA,KAAYA,EAAS,SAAS,uBAC5B,MAAA,EAAG,WAAU,QACX,UAAAA,EAAS,IAAI,CAAChK,MACb,gBAAA1C,EAAC,MAAA,EAAyB,WAAU,cAClC,UAAA,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,eAAY;AAAA,UACZ,SAAS,MAAMgJ,EAAM,SAAStG,EAAE,aAAa;AAAA,UAE7C,UAAA,gBAAAxB,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,YAAA,gBAAAA,EAAC,QAAA,EAAK,UAAA;AAAA,cAAA;AAAA,cAAEwB,EAAE;AAAA,YAAA,GAAc;AAAA,YAAQ;AAAA,YAC/BA,EAAE,sBACD,gBAAA1C,EAAC,QAAA,EAAK,WAAU,SAAQ,eAAY,wBAAuB,UAAA,YAAA,CAE3D;AAAA,YAEF,gBAAAA,EAAC,OAAA,EAAI,WAAU,eAAe,UAAA,IAAI,KAAK0C,EAAE,SAAS,EAAE,eAAA,EAAe,CAAE;AAAA,UAAA,EAAA,CACvE;AAAA,QAAA;AAAA,MAAA,KAfKA,EAAE,aAiBX,CACD,EAAA,CACH;AAAA,IAAA,GAEJ;AAAA,IACA,gBAAA1C,EAAC,OAAA,EAAI,WAAU,iBACb,4BAAC,UAAA,EAAO,MAAK,UAAS,WAAU,aAAY,SAASgJ,EAAM,SAAS,kBAEpE,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,MAAM6D,KAWF;AAAA,EACF,UAAU;AAAA,IACR,aAAa;AAAA,IACb,eACE;AAAA,IACF,cAAc;AAAA,IACd,gBACE;AAAA,IACF,aAAa;AAAA,IACb,cAAc;AAAA,IACd,eAAe;AAAA,EAAA;AAAA,EAEjB,UAAU;AAAA,IACR,aAAa;AAAA,IACb,eACE;AAAA,IACF,cAAc;AAAA,IACd,gBACE;AAAA,IACF,aAAa;AAAA,IACb,cAAc;AAAA,IACd,eAAe;AAAA,EAAA;AAAA,EAEjB,UAAU;AAAA,IACR,aAAa;AAAA,IACb,eACE;AAAA,IACF,cAAc;AAAA,IACd,gBACE;AAAA,IACF,aAAa;AAAA,IACb,cAAc;AAAA,IACd,eAAe;AAAA,EAAA;AAEnB;AAOO,SAASC,GAAmB9D,GAahC;AACD,QAAM+D,IAAOF,GAAY7D,EAAM,IAAI;AACnC,SACE,gBAAA9H,EAAAgK,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAlL;AAAA,MAACqL;AAAA,MAAA;AAAA,QACC,UAAUrC,EAAM;AAAA,QAChB,aAAa+D,EAAK;AAAA,QAClB,cAAcA,EAAK;AAAA,QACnB,eAAeA,EAAK;AAAA,QACpB,iBAAiB/D,EAAM;AAAA,QACvB,kBAAkBA,EAAM;AAAA,QACxB,aAAaA,EAAM;AAAA,QACnB,cAAcA,EAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAErBA,EAAM,oBACL,gBAAAhJ;AAAA,MAACoL;AAAAA,MAAA;AAAA,QACC,OAAO2B,EAAK;AAAA,QACZ,SAASA,EAAK;AAAA,QACd,cAAa;AAAA,QACb,WAAW/D,EAAM;AAAA,QACjB,SAASA,EAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAGlBA,EAAM,qBACL,gBAAAhJ;AAAA,MAACoL;AAAAA,MAAA;AAAA,QACC,OAAO2B,EAAK;AAAA,QACZ,SAASA,EAAK;AAAA,QACd,cAAa;AAAA,QACb,WAAW/D,EAAM;AAAA,QACjB,SAASA,EAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EACjB,GAEJ;AAEJ;ACvSA,MAAMgE,KAAmB,EAAE,cAAAC,IAAc,cAAAC,IAAc,cAAAC,GAAA;AAmBhD,SAASC,GAAsB;AAAA,EACpC,KAAAhN;AAAA,EACA,SAAAwB;AAAA,EACA,YAAA0C;AAAA,EACA,MAAAmI;AACF,GAKG;;AACD,QAAM;AAAA,IACJ,iBAAAY;AAAA,IACA,oBAAAC;AAAA,IACA,aAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,oBAAAC;AAAA,EAAA,IACEjB,GACErH,IAAiBC,GAAkBzD,KAAW,MAAS,GACvD+L,KAAavN,KAAA,gBAAAA,EAAK,UAAS,YAC3BmB,KAAKnB,KAAA,gBAAAA,EAAK,OAAM,IAIhBwN,IAAaC,GAAiBtM,GAAIoM,CAAU,GAE5CG,IAAYC,GAAwBnM,KAAW,MAAS,GACxDoM,IAAeC,GAAA,GACfC,IAAcC,GAAA,GAEd,CAACC,GAAcC,CAAe,IAAIzO,EAAS,EAAK,GAChD,CAAC0O,GAAWC,CAAY,IAAI3O,EAAS,EAAK,GAC1C,CAAC4O,GAAkBC,CAAmB,IAAI7O,EAAS,EAAK,GACxD,CAAC8O,GAAmBC,CAAoB,IAAI/O,EAAS,EAAK,GAC1D,CAACgM,GAAagD,CAAc,IAAIhP,EAAwB,IAAI,GAC5D,CAACiM,GAAcgD,CAAe,IAAIjP,EAAwB,IAAI,GAO9DkP,IAAgBC,GAAiB,YAAYxN,GAAIgM,KAAeI,CAAU,GAC1EqB,IAAaC,GAAmB,UAAU,GAC1CC,KAAgBC,GAAsB,UAAU,GAChD,CAACC,IAAcC,EAAe,IAAIzP,EAAwB,IAAI,GAC9D,CAAC0P,IAAaC,EAAc,IAAI3P,EAAwB,IAAI,GAG5D,CAAC4P,GAAaC,CAAc,IAAI7P;AAAA,IACpC;AAAA,EAAA;AAGF,MAAI,CAACQ,KAAOA,EAAI,SAAS;AACvB,WAAO,gBAAAJ,EAAC,KAAA,EAAE,WAAU,eAAc,UAAA,wCAAoC;AAGxE,QAAM0P,KAAUhK,IAAAN,EAAe,SAAf,gBAAAM,EAAqB,KAAK,CAACO,MAAMA,EAAE,OAAO7F,EAAI,KACxDgJ,KACJsG,KAAW,OAAQA,EAAsC,eAAgB,WACpEA,EAAoC,cACrC,IACArH,MAAQqH,KAAA,gBAAAA,EAA6C,SAAQ,CAAA,GAC7DpE,MAAYoE,KAAA,gBAAAA,EAA6C,YAAW;AAE1E,WAASC,KAAW;AAClB,IAAAf,EAAe,IAAI,GACnBV,EAAY,OAAO3M,GAAI;AAAA,MACrB,WAAW,MAAM;AACf,QAAAkN,EAAoB,EAAK,GACzBnK,EAAW,EAAE,MAAM,QAAQ;AAAA,MAC7B;AAAA,MACA,SAAS,CAACwD,MAAe;AACvB,QAAA2G,EAAoB,EAAK,GACzBG,EAAe9G,aAAaC,IAAWD,EAAE,UAAU,OAAOA,CAAC,CAAC;AAAA,MAC9D;AAAA,IAAA,CACD;AAAA,EACH;AAEA,WAAS8H,KAAY;AACnB,IAAAf,EAAgB,IAAI,GACpBb,EAAa,OAAOzM,GAAI;AAAA,MACtB,WAAW,MAAM;AACf,QAAAoN,EAAqB,EAAK,GAC1BrK,EAAW,EAAE,MAAM,QAAQ;AAAA,MAC7B;AAAA,MACA,SAAS,CAACwD,MAAe;AACvB,QAAA6G,EAAqB,EAAK,GAC1BE,EAAgB/G,aAAaC,IAAWD,EAAE,UAAU,OAAOA,CAAC,CAAC;AAAA,MAC/D;AAAA,IAAA,CACD;AAAA,EACH;AAEA,SACE,gBAAA5G,EAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,IAAA,gBAAAlB,EAAC+L,IAAA,EAAgB,QAAQ,MAAMuB,EAAmB,EAAI,GAAG;AAAA,IACzD,gBAAAtN;AAAA,MAACiM;AAAA,MAAA;AAAA,QACC,IAAI7L,EAAI;AAAA,QACR,aAAAgJ;AAAA,QACA,QAAQyG,GAAsB,UAAU;AAAA,QACxC,KAAKH;AAAA,QACL,MAAArH;AAAA,MAAA;AAAA,IAAA;AAAA,sBAGD+D,IAAA,EAAmB,QAAQ,MAAMiC,EAAgB,EAAI,GAAG;AAAA,IAEzD,gBAAArO;AAAA,MAACwM;AAAA,MAAA;AAAA,QACC,MAAMe;AAAA,QACN,UAAUuB,EAAc;AAAA,QACxB,YAAYE,EAAW;AAAA,QACvB,iBAAiBE,GAAc;AAAA,QAC/B,cAAAE;AAAA,QACA,aAAAE;AAAA,QACA,QAAQ,MAAM;AACZ,UAAA9B,EAAe,EAAI,GACnBE,EAAmB,EAAI;AAAA,QACzB;AAAA,QACA,WAAW,MAAM;AACf,UAAA2B,GAAgB,IAAI,GACpBL,EAAW,OAAOzN,GAAI;AAAA,YACpB,SAAS,CAACuG,MAAMuH,GAAgBvH,aAAaC,IAAWD,EAAE,UAAU,OAAOA,CAAC,CAAC;AAAA,UAAA,CAC9E;AAAA,QACH;AAAA,QACA,iBAAiB,MAAM;;AACrB,UAAAyH,GAAe,IAAI,GACnBL,GAAc;AAAA,YACZ,EAAE,IAAA3N,GAAI,SAAS,GAACmE,IAAAoJ,EAAc,SAAd,QAAApJ,EAAoB,SAAA;AAAA,YACpC,EAAE,SAAS,CAACoC,MAAMyH,GAAezH,aAAaC,IAAWD,EAAE,UAAU,OAAOA,CAAC,CAAC,EAAA;AAAA,UAAE;AAAA,QAEpF;AAAA,MAAA;AAAA,IAAA;AAAA,IAGD2F,KACC,gBAAAzN;AAAA,MAAC2M;AAAA,MAAA;AAAA,QACC,SAASmC,EAAc;AAAA,QACvB,WAAUhJ,IAAAgJ,EAAc,SAAd,gBAAAhJ,EAAoB;AAAA,QAC9B,UAAU,CAAC0E,MAAkBiF,EAAe,EAAE,IAAAlO,GAAI,eAAAiJ,GAAe;AAAA,QACjE,SAAS,MAAMkD,EAAmB,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,IAI1C8B,KAAeA,EAAY,OAAOjO,KACjC,gBAAAvB;AAAA,MAACuK;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,IAAAhJ;AAAA,QACA,eAAeiO,EAAY;AAAA,QAC3B,SAAS,MAAMC,EAAe,IAAI;AAAA,MAAA;AAAA,IAAA;AAAA,IAIrCrB,KACC,gBAAApO;AAAA,MAACqM;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,MAAMgC,EAAgB,EAAK;AAAA,QACpC,UAAU,MAAM;AACd,UAAAA,EAAgB,EAAK,GACrBE,EAAa,EAAI;AAAA,QACnB;AAAA,MAAA;AAAA,IAAA;AAAA,IAKHlB,KAAmBqC,KAClB,gBAAA1P;AAAA,MAAC+I;AAAA,MAAA;AAAA,QAMC,MAAK;AAAA,QACL,IAAAxH;AAAA,QACA,SAAS;AAAA,UACP,aAAA6H;AAAA,UACA,KAAMsG,EAAoC,OAAO;AAAA,UACjD,MAAArH;AAAA,QAAA;AAAA,QAEF,QAAQ,OAAOyH,MAAS;AACtB,cAAI,CAAClC,EAAW,KAAM,OAAM,IAAI,MAAM,yBAAyB;AAC/D,gBAAMmC,IAASnC,EAAW;AAC1B,iBAAO,IAAI,QAAQ,CAACoC,IAASC,OAAW;AACtC,kBAAMC,IAAmC;AAAA,cACvC,GAAGH,EAAO;AAAA,cACV,aAAaD,EAAK;AAAA,YAAA;AAEpB,YAAIA,EAAK,QAAQ,WACfI,EAAQ,MAAMJ,EAAK,MAEjBA,EAAK,SAAS,WAChBI,EAAQ,OAAOJ,EAAK,OAEtBhC,EAAU;AAAA,cACR,EAAE,YAAYoC,GAAS,mBAAmBH,EAAO,UAAA;AAAA,cACjD,EAAE,WAAW,MAAMC,GAAA,GAAW,SAASC,GAAA;AAAA,YAAO;AAAA,UAElD,CAAC;AAAA,QACH;AAAA,QACA,SAAS,MAAM3C,EAAmB,EAAK;AAAA,MAAA;AAAA,MA5BlC/L;AAAA,IAAA;AAAA,IAgCT,gBAAAvB;AAAA,MAAC8M;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,UAAAxB;AAAA,QACA,kBAAAkD;AAAA,QACA,mBAAAE;AAAA,QACA,aAAA9C;AAAA,QACA,cAAAC;AAAA,QACA,iBAAiB,MAAM4C,EAAoB,EAAI;AAAA,QAC/C,kBAAkB,MAAME,EAAqB,EAAI;AAAA,QACjD,iBAAiBgB;AAAA,QACjB,kBAAkBC;AAAA,QAClB,eAAe,MAAMnB,EAAoB,EAAK;AAAA,QAC9C,gBAAgB,MAAME,EAAqB,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,IAGjDL,KACC,gBAAAtO;AAAA,MAACmQ;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAASvO,KAAW;AAAA,QACpB,UAAUoL;AAAA,QACV,gBAAgB,CAACnI,GAAMuL,MAAU9L,EAAW,EAAE,MAAM,YAAY,MAAAO,GAAM,IAAIuL,GAAO;AAAA,QACjF,SAAS,MAAM7B,EAAa,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EACnC,GAEJ;AAEJ;AAQA,SAAS8B,GAAkB,EAAE,KAAAjQ,KAAmC;AAC9D,QAAM,EAAE,SAAAwB,GAAS,YAAA0C,EAAA,IAAeC,GAAA,GAC1B,CAAC8I,GAAiBC,CAAkB,IAAI1N,EAAS,EAAK,GACtD,CAAC2N,GAAaC,CAAc,IAAI5N,EAAS,EAAK,GAC9C,CAAC6N,GAAiBC,CAAkB,IAAI9N,EAAS,EAAK,GACtD6M,IAA0B;AAAA,IAC9B,iBAAAY;AAAA,IACA,oBAAAC;AAAA,IACA,aAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,oBAAAC;AAAA,EAAA;AAEF,UAAOtN,KAAA,gBAAAA,EAAK,UAAS,aACnB,gBAAAJ,EAACoN,MAAsB,KAAAhN,GAAU,SAAAwB,GAAkB,YAAA0C,GAAwB,MAAAmI,GAAY,IAEvF,gBAAAzM,EAACsQ,IAAA,EAAsB,KAAAlQ,GAAU,SAAAwB,GAAkB,YAAA0C,GAAwB,MAAAmI,GAAY;AAE3F;AAEO,SAAS6D,GAAsB;AAAA,EACpC,KAAAlQ;AAAA,EACA,SAAAwB;AAAA,EACA,YAAA0C;AAAA,EACA,MAAAmI;AACF,GAKG;;AACD,QAAM;AAAA,IACJ,iBAAAY;AAAA,IACA,oBAAAC;AAAA,IACA,aAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,oBAAAC;AAAA,EAAA,IACEjB,GACE8D,IAAQnQ,KAAA,gBAAAA,EAAK,MACboQ,IAAiBC,GAAkBF,MAAU,UAAU,GACvDrL,IAAiBC,GAAkBoL,MAAU,UAAU,GAEvD,CAACG,GAASC,CAAU,IAAI/Q,EAAS,EAAK,GACtC,CAACgR,GAAUC,CAAW,IAAIjR,EAAS,EAAE,GACrC,CAACkR,GAAWC,CAAY,IAAInR,EAAwB,IAAI,GAGxD,CAACoR,GAAWC,CAAY,IAAIrR,EAAwB,IAAI,GAIxD,CAACwO,GAAcC,CAAe,IAAIzO,EAAS,EAAK,GAChD,CAACsR,GAAWC,CAAY,IAAIvR,EAAS,EAAK,GAC1C,CAAC0O,GAAWC,CAAY,IAAI3O,EAAS,EAAK,GAC1C,CAAC4O,GAAkBC,CAAmB,IAAI7O,EAAS,EAAK,GACxD,CAAC8O,GAAmBC,CAAoB,IAAI/O,EAAS,EAAK,GAC1D,CAACgM,IAAagD,EAAc,IAAIhP,EAAwB,IAAI,GAC5D,CAACiM,IAAcgD,EAAe,IAAIjP,EAAwB,IAAI,GAK9DwR,KAAanK,IAAiB7G,KAAA,gBAAAA,EAAK,OAAM,KAAIA,KAAA,gBAAAA,EAAK,UAAS,UAAU,GACrEiR,IAAalK,IAAiB/G,KAAA,gBAAAA,EAAK,OAAM,KAAIA,KAAA,gBAAAA,EAAK,UAAS,UAAU,GACrEgH,IAAYC,GAAA,GACZC,IAAYC,GAAA,GACZ+J,KAAcC,GAAA,GACdC,KAAcC,GAAA,GAEdC,KAAeC,GAAA,GACfC,KAAeC,GAAA,GAIfC,KAAiB1R,IAAM2R,GAAsB3R,EAAI,IAAI,IAAI,MACzD4R,IAAYC,GAAaH,KAAgB1R,KAAA,gBAAAA,EAAK,OAAM,IAAI8Q,CAAS,GAIjEgB,IACJ9R,KAAO+R,GAAkB/R,EAAI,IAAI,IAAKA,EAAI,OAAwB,MAE9D0O,IAAgBC,GAAiBmD,IAAc9R,KAAA,gBAAAA,EAAK,OAAM,IAAImN,CAAW,GAKzEyB,IAAaC,GAAmBiD,KAAgB,UAAU,GAC1DhD,KAAgBC,GAAsB+C,KAAgB,UAAU,GAChE,CAAC9C,IAAcC,CAAe,IAAIzP,EAAwB,IAAI,GAC9D,CAAC0P,IAAaC,EAAc,IAAI3P,EAAwB,IAAI,GAG5D,CAAC4P,IAAaC,EAAc,IAAI7P;AAAA,IACpC;AAAA,EAAA;AAOF,MAAI,CAACQ,KAAQA,EAAI,SAAS,cAAcA,EAAI,SAAS;AACnD,WACE,gBAAAJ,EAAC,KAAA,EAAE,WAAU,eAAc,UAAA,+DAA2D;AAI1F,QAAM6E,IAAOzE,EAAI,MACXmB,IAAKnB,EAAI,IACTsP,IACJ7K,MAAS,cACLa,KAAAR,EAAe,SAAf,gBAAAQ,GAAqB,KAAK,CAAC,MAAM,EAAE,OAAOnE,MAC1CuE,KAAA0K,EAAe,SAAf,gBAAA1K,GAAqB,KAAK,CAACgC,MAAMA,EAAE,OAAOvG,IAG1CiG,IAASC,GAAe5C,GAAMA,MAAS,aAAauM,GAAW,OAAOC,EAAW,IAAI,GACrFe,KAAM5K,KAAA,gBAAAA,EAAQ,eAAc,MAE5B4B,KAAcsG,KAChB,OAAQA,EAAsC,eAAgB,WAC3DA,EAAoC,cAEvC,IAEE2C,KAAUD,IAAM,KAAK,UAAUA,GAAK,MAAM,CAAC,IAAI;AAErD,WAASE,KAAW;AAClB,IAAAvB,EAAa,IAAI,GACjBF,EAAYwB,EAAO,GACnBpB,GAAazJ,KAAA,gBAAAA,EAAQ,cAAa,IAAI,GACtCmJ,EAAW,EAAI;AAAA,EACjB;AAEA,QAAM4B,IAAWH,IACbI,GAAa5B,GAAU,EAAE,IAAI,OAAOwB,EAAI,EAAE,GAAG,KAAK,OAAOA,EAAI,GAAG,EAAA,CAAG,IACnE,EAAE,QAAQ,MAAM,eAAe,4BAAA,GAC7BK,KAAY5N,MAAS,aAAauC,EAAU,YAAYE,EAAU;AAExE,WAASoL,KAAa;AACpB,QAAI,CAACH,EAAS,UAAUA,EAAS,cAAe;AAChD,IAAAxB,EAAa,IAAI;AACjB,UAAM4B,IAAY;AAAA,MAChB,WAAW,MAAMhC,EAAW,EAAK;AAAA,MACjC,SAAS,CAAC7I,OAAeiJ,EAAajJ,cAAaC,IAAWD,GAAE,UAAU,OAAOA,EAAC,CAAC;AAAA,IAAA,GAE/EH,IAAO,EAAE,YAAY4K,EAAS,QAAQ,mBAAmBvB,EAAA;AAC/D,IAAInM,MAAS,aACXuC,EAAU,OAAOO,GAAMgL,CAAS,IAEhCrL,EAAU,OAAOK,GAAMgL,CAAS;AAAA,EAEpC;AAIA,QAAMrH,MAAYoE,KAAA,gBAAAA,EAAwD,eAAc;AAExF,WAASC,KAAW;AAClB,IAAAf,GAAe,IAAI;AACnB,UAAM+D,IAAY;AAAA,MAChB,WAAW,MAAM;AACf,QAAAlE,EAAoB,EAAK,GACzBnK,EAAW,EAAE,MAAM,QAAQ;AAAA,MAC7B;AAAA,MACA,SAAS,CAACwD,MAAe;AACvB,QAAA2G,EAAoB,EAAK,GACzBG,GAAe9G,aAAaC,IAAWD,EAAE,UAAU,OAAOA,CAAC,CAAC;AAAA,MAC9D;AAAA,IAAA;AAEF,IAAIjD,MAAS,aAAYyM,GAAY,OAAO/P,GAAIoR,CAAS,IACpDnB,GAAY,OAAOjQ,GAAIoR,CAAS;AAAA,EACvC;AAGA,WAAS/C,KAAY;AACnB,IAAAf,GAAgB,IAAI;AACpB,UAAM8D,IAAY;AAAA,MAChB,WAAW,MAAM;AACf,QAAAhE,EAAqB,EAAK,GAC1BrK,EAAW,EAAE,MAAM,QAAQ;AAAA,MAC7B;AAAA,MACA,SAAS,CAACwD,MAAe;AACvB,QAAA6G,EAAqB,EAAK,GAC1BE,GAAgB/G,aAAaC,IAAWD,EAAE,UAAU,OAAOA,CAAC,CAAC;AAAA,MAC/D;AAAA,IAAA;AAEF,IAAIjD,MAAS,aAAY6M,GAAa,OAAOnQ,GAAIoR,CAAS,IACrDf,GAAa,OAAOrQ,GAAIoR,CAAS;AAAA,EACxC;AAEA,SACE,gBAAAzR,EAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,IAAA,gBAAAlB,EAAC+L,IAAA,EAAgB,QAAQ,MAAMuB,EAAmB,EAAI,GAAG;AAAA,IACzD,gBAAAtN;AAAA,MAACiM;AAAA,MAAA;AAAA,QACC,IAAA1K;AAAA,QACA,aAAA6H;AAAA,QACA,QAAQyG,GAAsBhL,CAAI;AAAA,QAClC,KAAK6K;AAAA,MAAA;AAAA,IAAA;AAAA,IAGNkD,GAAqB/N,CAAI,KAAK,gBAAA7E,EAACoM,MAAmB,QAAQ,MAAMiC,EAAgB,EAAI,GAAG;AAAA,IAEvF8D,GAAkBtN,CAAI,KACrB,gBAAA7E;AAAA,MAACwM;AAAA,MAAA;AAAA,QACC,MAAMe;AAAA,QACN,UAAUuB,EAAc;AAAA,QACxB,YAAYE,EAAW;AAAA,QACvB,iBAAiBE,GAAc;AAAA,QAC/B,cAAAE;AAAA,QACA,aAAAE;AAAA,QACA,QAAQ,MAAM;AACZ,UAAA9B,EAAe,EAAI,GACnBE,EAAmB,EAAI;AAAA,QACzB;AAAA,QACA,WAAW,MAAM;AACf,UAAA2B,EAAgB,IAAI,GACpBL,EAAW,OAAOzN,GAAI;AAAA,YACpB,SAAS,CAACuG,MAAMuH,EAAgBvH,aAAaC,IAAWD,EAAE,UAAU,OAAOA,CAAC,CAAC;AAAA,UAAA,CAC9E;AAAA,QACH;AAAA,QACA,iBAAiB,MAAM;;AACrB,UAAAyH,GAAe,IAAI,GACnBL,GAAc;AAAA,YACZ,EAAE,IAAA3N,GAAI,SAAS,GAACmE,IAAAoJ,EAAc,SAAd,QAAApJ,EAAoB,SAAA;AAAA,YACpC,EAAE,SAAS,CAACoC,MAAMyH,GAAezH,aAAaC,IAAWD,EAAE,UAAU,OAAOA,CAAC,CAAC,EAAA;AAAA,UAAE;AAAA,QAEpF;AAAA,MAAA;AAAA,IAAA;AAAA,IAIH2F,KACC,gBAAAzN;AAAA,MAAC2M;AAAA,MAAA;AAAA,QACC,SAASmC,EAAc;AAAA,QACvB,WAAU9I,KAAA8I,EAAc,SAAd,gBAAA9I,GAAoB;AAAA,QAC9B,UAAU,CAACwE,MAAkBiF,GAAe,EAAE,IAAAlO,GAAI,eAAAiJ,GAAe;AAAA,QACjE,SAAS,MAAMkD,EAAmB,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,IAI1C8B,MAAeA,GAAY,OAAOjO,KACjC,gBAAAvB;AAAA,MAACuK;AAAA,MAAA;AAAA,QACC,MAAA1F;AAAA,QACA,IAAAtD;AAAA,QACA,eAAeiO,GAAY;AAAA,QAC3B,SAAS,MAAMC,GAAe,IAAI;AAAA,MAAA;AAAA,IAAA;AAAA,IAMrCrB,KACC,gBAAApO;AAAA,MAACqM;AAAA,MAAA;AAAA,QACC,MAAAxH;AAAA,QACA,SAAS,MAAMwJ,EAAgB,EAAK;AAAA,QACpC,UAAU,MAAM;AACd,UAAAA,EAAgB,EAAK,GACrBE,EAAa,EAAI;AAAA,QACnB;AAAA,QAEC,UAAAqE,GAAqB/N,CAAI,KACxB,gBAAA3D,EAAAgK,GAAA,EACE,UAAA;AAAA,UAAA,gBAAAlL,EAAC,KAAA,EAAE,WAAU,eAAc,UAAA,iHAG3B;AAAA,UACA,gBAAAkB,EAAC,OAAA,EAAI,WAAU,sBACb,UAAA;AAAA,YAAA,gBAAAlB;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,eAAY;AAAA,gBACZ,SAAS,MAAM;AACb,kBAAAqO,EAAgB,EAAK,GACrB8C,EAAa,EAAI;AAAA,gBACnB;AAAA,gBACD,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAES;AAAA,YACV,gBAAAnR;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,UAAU,CAACoS;AAAA,gBACX,eAAY;AAAA,gBACZ,SAAS,MAAM;AACb,kBAAA/D,EAAgB,EAAK,GACrBiE,GAAA;AAAA,gBACF;AAAA,gBACD,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UAED,EAAA,CACF;AAAA,QAAA,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,IAQLpB,KACC,gBAAAhQ,EAAC4C,GAAA,EAAM,OAAM,wBAAuB,SAAS,MAAMqN,EAAa,EAAK,GAAG,MAAI,IAC1E,UAAA;AAAA,MAAA,gBAAAnR,EAAC,OAAA,EAAI,WAAU,cACZ,UAAAgS,EAAU,YACT,gBAAAhS,EAAC,KAAA,EAAE,WAAU,eAAc,sBAAQ,IACjCgS,EAAU,UACZ,gBAAAhS,EAAC,SAAI,WAAU,SAAQ,eAAY,mBAChC,YAAU,iBAAiB,QACxBgS,EAAU,MAAM,UAChB,OAAOA,EAAU,KAAK,EAAA,CAC5B,IACEA,EAAU,OACZ,gBAAAhS,EAAC,OAAA,EAAI,eAAY,kBACf,UAAA,gBAAAA;AAAA,QAACmL;AAAA,QAAA;AAAA,UACC,MAAM,KAAK,UAAU6G,EAAU,MAAM,MAAM,CAAC;AAAA,UAC5C,UAAS;AAAA,UACT,WAAU;AAAA,UACV,UAAQ;AAAA,QAAA;AAAA,MAAA,EACV,CACF,IACE,MACN;AAAA,wBACC,OAAA,EAAI,WAAU,iBACb,UAAA,gBAAAhS,EAAC,YAAO,MAAK,UAAS,WAAU,aAAY,SAAS,MAAMmR,EAAa,EAAK,GAAG,mBAEhF,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAMDT,KACC,gBAAAxP,EAAC4C,GAAA,EAAM,OAAM,mBAAkB,SAAS,MAAM6M,EAAW,EAAK,GAAG,MAAI,IACnE,UAAA;AAAA,MAAA,gBAAAzP,EAAC,OAAA,EAAI,WAAU,cACb,UAAA;AAAA,QAAA,gBAAAlB;AAAA,UAAC6S;AAAA,UAAA;AAAA,YACC,OAAOjC;AAAA,YACP,UAAUC;AAAA,YACV,WAAU;AAAA,YACV,cAAW;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZ0B,EAAS,iBACR,gBAAAvS,EAAC,KAAA,EAAE,WAAU,eAAc,eAAY,oBACpC,UAAAuS,EAAS,cAAA,CACZ;AAAA,QAEDzB,KAAa,gBAAA9Q,EAAC,OAAA,EAAI,WAAU,SAAS,UAAA8Q,EAAA,CAAU;AAAA,MAAA,GAClD;AAAA,MACA,gBAAA5P,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,QAAA,gBAAAlB,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,aAAY,SAAS,MAAM2Q,EAAW,EAAK,GAAG,UAAA,SAAA,CAE9E;AAAA,QACA,gBAAA3Q;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,UAAUuS,EAAS,kBAAkB,QAAQE;AAAA,YAC7C,eAAY;AAAA,YACZ,SAASC;AAAA,YAER,eAAY,YAAY;AAAA,UAAA;AAAA,QAAA;AAAA,MAC3B,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IAIDrF,KAAmBqC,KAClB,gBAAA1P;AAAA,MAAC+I;AAAA,MAAA;AAAA,QAMC,MAAAlE;AAAA,QACA,IAAAtD;AAAA,QACA,SAAS;AAAA,UACP,aAAA6H;AAAA,UACA,KAAMsG,EAAoC,OAAO;AAAA,UACjD,MAAM,CAAA;AAAA,QAAC;AAAA,QAET,QAAQ,OAAOI,MAAS;AACtB,cAAI,CAACtI,EAAQ,OAAM,IAAI,MAAM,yBAAyB;AAGtD,gBAAM/H,IAAO+H,EAAO,YAOdG,KAAO,EAAE,YALb9C,MAAS;AAAA;AAAA;AAAA,YAGL,EAAE,GAAGpF,GAAM,aAAaqQ,EAAK,aAAa,KAAKA,EAAK,OAAOrQ,EAAK,IAAA;AAAA,cAChE,EAAE,GAAGA,GAAM,aAAaqQ,EAAK,YAAA,GACA,mBAAmBtI,EAAO,UAAA;AAC7D,iBAAO,IAAI,QAAQ,CAACwI,IAASC,OAAW;AACtC,kBAAMpI,KAAU,EAAE,WAAW,MAAMmI,GAAA,GAAW,SAASC,GAAA;AACvD,YAAIpL,MAAS,aAAYuC,EAAU,OAAOO,IAAME,EAAO,IAClDP,EAAU,OAAOK,IAAME,EAAO;AAAA,UACrC,CAAC;AAAA,QACH;AAAA,QACA,SAAS,MAAMyF,EAAmB,EAAK;AAAA,MAAA;AAAA,MA1BlC/L;AAAA,IAAA;AAAA,IA8BRuR,GAAUjO,CAAI,KACb,gBAAA7E;AAAA,MAAC8M;AAAA,MAAA;AAAA,QACC,MAAAjI;AAAA,QACA,UAAAyG;AAAA,QACA,kBAAAkD;AAAA,QACA,mBAAAE;AAAA,QACA,aAAA9C;AAAA,QACA,cAAAC;AAAA,QACA,iBAAiB,MAAM4C,EAAoB,EAAI;AAAA,QAC/C,kBAAkB,MAAME,EAAqB,EAAI;AAAA,QACjD,iBAAiBgB;AAAA,QACjB,kBAAkBC;AAAA,QAClB,eAAe,MAAMnB,EAAoB,EAAK;AAAA,QAC9C,gBAAgB,MAAME,EAAqB,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,IAInDL,KACC,gBAAAtO;AAAA,MAACmQ;AAAA,MAAA;AAAA,QACC,MAAAtL;AAAA,QACA,SAASjD,KAAW;AAAA,QACpB,UAAUoL;AAAA,QACV,gBAAgB,CAAC+F,GAAG3C,MAAU9L,EAAW,EAAE,MAAM,YAAY,MAAMyO,GAAG,IAAI3C,EAAA,CAAO;AAAA,QACjF,SAAS,MAAM7B,EAAa,EAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EACnC,GAEJ;AAEJ;AAEA,SAASyE,KAAmB;AAC1B,SAAO,gBAAAhT,EAAC6D,GAAA,EAAK,MAAK,WAAA,CAAW;AAC/B;AAGO,MAAMoP,KAAyB;AAAA,EACpC,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,MAAMD;AAAA,EACN,aAAa,CAAC5S,OACZA,KAAA,gBAAAA,EAAK,UAAS,eAAcA,KAAA,gBAAAA,EAAK,UAAS,eAAcA,KAAA,gBAAAA,EAAK,UAAS;AAAA,EACxE,OAAOiQ;AACT,GChxBa6C,KAAuC,CAACD,IAAchP,IAAUiE,EAAiB;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"endpoints-B2ynbZo-.js","sources":["../src/lib/new-id.ts","../src/lib/callable-descriptors.ts","../src/repos/functions.ts","../src/repos/endpoints.ts"],"sourcesContent":["/**\n * Platform id minter (studio copy). Algorithm is byte-identical to the server's\n * `packages/ids/ids.ts`: alphabet base62, drop byte b >= 248 (largest multiple of 62\n * that fits a byte), keep ALPHABET[b % 62]. No modulo bias.\n */\n\nexport const ID_ALPHABET = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\n/** Largest multiple of 62 <= 256; bytes at or above it are rejected. */\nconst REJECT_AT = 248;\n\n/** Byte source seam; defaults to `crypto.getRandomValues`. */\nexport type ByteSource = (n: number) => Uint8Array;\n\nconst defaultBytes: ByteSource = (n) => crypto.getRandomValues(new Uint8Array(n));\n\n/** `<prefix>_<len chars of base62>`. */\nexport function newId(prefix: string, len = 16, bytes: ByteSource = defaultBytes): string {\n let out = \"\";\n while (out.length < len) {\n for (const b of bytes(Math.max(len - out.length, 8))) {\n if (b >= REJECT_AT) continue;\n out += ID_ALPHABET[b % 62];\n if (out.length === len) break;\n }\n }\n return `${prefix}_${out}`;\n}\n","/**\n * `CALLABLE_DESCRIPTORS` — the ONE place the three resource kinds' chrome copy,\n * their Settings-modal behaviour and their id minting are named (T4.2.1,\n * `building-blocks.F3.md` §F-3).\n *\n * Before this file, every \"is this a workflow?\" branch lived inline at its call\n * site: `CallableSettingsModal.tsx` carried seven `kind ===` conditionals for\n * three different questions (may the key be edited? does this kind have tags?\n * which placeholder does the name field use?), and each list page repeated the\n * same title/description/empty-state/`data-testid` literals. A fourth kind — or\n * a rename — meant finding them all by hand.\n *\n * **Data only, never JSX.** A `Descriptor` holds strings, booleans and the one\n * id prefix; the kind-specific *editor body* stays React code in its own page\n * (`src/pages/FunctionsPage.tsx`), because this file is `.ts` and is loaded by\n * `node --test` (`.tsx` cannot be — `package.json`'s `test:unit` glob), exactly\n * the constraint `src/lib/save-invalidation.ts` and `src/lib/alias-rail.ts`\n * document for themselves. So `kind ===` moves OUT of the modal and the pages\n * and INTO a total `Record`, never into a render function.\n *\n * The wire plumbing these descriptors describe — collection segment, query keys,\n * the SDK call per kind — lives one layer down, in `src/repos/callables.ts`,\n * which owns its own total `Record` per kind (mirroring `src/repos/versions.ts`'s\n * `COLLECTION_PATH`). `callable-descriptors.test.ts` asserts the two tables name\n * the same three kinds and the same three collections, so they cannot drift.\n */\nimport type { CallableKind } from \"./callable-kind.ts\";\nimport { newId } from \"./new-id.ts\";\n\nexport type { CallableKind };\n\n/** The Settings modal's own per-kind behaviour (T4.2.1's formalization of the\n * seven `kind ===` conditionals `CallableSettingsModal.tsx` used to carry). */\nexport interface CallableSettingsDescriptor {\n /** May the `key` be typed here at all? Function/Workflow yes, Endpoint no\n * (`rfcs/endpoint.md` — an Endpoint's address is its identity). */\n canEditKey: boolean;\n /** Does this kind store tags? Workflow only. */\n hasTags: boolean;\n /** Placeholder for the Name field. */\n namePlaceholder: string;\n /** Placeholder for the Key field (read only when {@link canEditKey}). */\n keyPlaceholder: string;\n /** Appended to the shared \"Lowercase, kebab-case, 3–39 characters.\" hint —\n * `\"\"` for a kind that cannot unset its key, the \"Leave empty to unset.\"\n * sentence for the one that can. */\n keyHintSuffix: string;\n}\n\n/** The editor chrome's own per-kind copy. */\nexport interface CallableEditorDescriptor {\n /** The back control's label, e.g. `\"← Functions\"`. */\n backLabel: string;\n /** Heading fallback while the definition is still hydrating. */\n newTitle: string;\n /** Rendered in place of the form when the hydration GET 404s. */\n notFoundTitle: string;\n /** The Save button's idle label. */\n saveLabel: string;\n}\n\nexport interface CallableDescriptor {\n kind: CallableKind;\n /** The list page's `<h2>`, and the editor document title's second segment. */\n listTitle: string;\n /** The list page's explanatory paragraph. */\n listDescription: string;\n /** The empty-state paragraph (verbatim, including its typographic quotes). */\n emptyCopy: string;\n /** The create button's label, e.g. `\"+ New function\"`. */\n newLabel: string;\n /** The synthetic id's own prefix — `fn_…`/`ep_…`/`wf_…`, never user-edited. */\n newIdPrefix: string;\n /** `data-testid` of the list's Import affordance. */\n importOpenTestId: string;\n /** `data-testid` of the list's \"Show archived\" checkbox. */\n showArchivedTestId: string;\n /** `data-testid` of a row's \"archived\" badge. */\n archivedBadgeTestId: string;\n /** The row button's `title` tooltip (T4.2.3 — replaces the shared template literal\n * `` `Open this ${kind} in the editor.` ``, since Workflow's own row opens the visual editor,\n * not \"the editor\"). */\n openRowTitle: string;\n editor: CallableEditorDescriptor;\n settings: CallableSettingsDescriptor;\n}\n\n/**\n * The three kinds, every arm named explicitly — a total `Record<CallableKind,\n * …>`, so a fourth kind fails to compile here rather than silently rendering\n * another kind's copy (the same reasoning `COLLECTION_PATH` gives in\n * `src/repos/versions.ts`).\n *\n * Only the `function` arm is consumed today: Endpoints and Workflows keep their\n * own pages until T4.2.2/T4.2.3. Their arms are filled from those pages'\n * current literals so the later nodes are a deletion, not a re-derivation.\n */\nexport const CALLABLE_DESCRIPTORS: Record<CallableKind, CallableDescriptor> = {\n function: {\n kind: \"function\",\n listTitle: \"Functions\",\n listDescription:\n 'A Function is a reusable, vendor-abstracted operation — \"Send Email\", \"Create Contact\" — ' +\n \"with a stable interface bound to one swappable app action. Switch provider by \" +\n \"re-binding; callers never change.\",\n emptyCopy:\n \"None yet — click “New function” to create one, or “Import” to bring in a spec document.\",\n newLabel: \"+ New function\",\n newIdPrefix: \"fn\",\n importOpenTestId: \"functions-import-open\",\n showArchivedTestId: \"functions-show-archived\",\n archivedBadgeTestId: \"function-archived\",\n openRowTitle: \"Open this function in the editor.\",\n editor: {\n backLabel: \"← Functions\",\n newTitle: \"New function\",\n notFoundTitle: \"Function not found\",\n saveLabel: \"Save\",\n },\n settings: {\n canEditKey: true,\n hasTags: false,\n namePlaceholder: \"Send Email\",\n keyPlaceholder: \"send-email\",\n keyHintSuffix: \"\",\n },\n },\n endpoint: {\n kind: \"endpoint\",\n listTitle: \"Endpoints\",\n listDescription:\n \"An Endpoint is a named, stable entry point that dispatches to one app action, Function, \" +\n \"or Workflow. Callers bind to the Endpoint; the target behind it can change — promote an \" +\n \"action to a Function or a Workflow, or re-bind it — without breaking a single caller.\",\n emptyCopy: \"None yet — click “New endpoint” to create one.\",\n newLabel: \"+ New endpoint\",\n newIdPrefix: \"ep\",\n importOpenTestId: \"endpoints-import-open\",\n showArchivedTestId: \"endpoints-show-archived\",\n archivedBadgeTestId: \"endpoint-archived\",\n openRowTitle: \"Open this endpoint in the editor.\",\n editor: {\n backLabel: \"← Endpoints\",\n newTitle: \"New endpoint\",\n notFoundTitle: \"Endpoint not found\",\n saveLabel: \"Save\",\n },\n settings: {\n canEditKey: false,\n hasTags: false,\n namePlaceholder: \"My endpoint\",\n keyPlaceholder: \"send-email\",\n keyHintSuffix: \"\",\n },\n },\n workflow: {\n kind: \"workflow\",\n listTitle: \"Workflows\",\n listDescription:\n \"A Workflow is a durable, multi-step run: each step calls an app action, a Function, or \" +\n \"another Workflow, and a run keeps its own state, history and error handling.\",\n emptyCopy: \"None yet — click “New workflow” to create one.\",\n newLabel: \"+ New workflow\",\n newIdPrefix: \"wf\",\n importOpenTestId: \"workflows-import-open\",\n showArchivedTestId: \"workflows-show-archived\",\n archivedBadgeTestId: \"workflow-archived\",\n openRowTitle: \"Open this workflow in the visual editor.\",\n editor: {\n backLabel: \"← Workflows\",\n newTitle: \"New workflow\",\n notFoundTitle: \"Workflow not found\",\n saveLabel: \"Save\",\n },\n settings: {\n canEditKey: true,\n hasTags: true,\n namePlaceholder: \"My workflow\",\n keyPlaceholder: \"unset\",\n keyHintSuffix: \" Leave empty to unset.\",\n },\n },\n};\n\n/** Look a descriptor up by kind. A plain index, never a `switch`: the `Record`\n * above already made every arm total. */\nexport function descriptorFor(kind: CallableKind): CallableDescriptor {\n return CALLABLE_DESCRIPTORS[kind];\n}\n\n/**\n * A fresh synthetic id for a create-modal's first POST — `fn_<uuid>` for a\n * Function (verbatim the `newFunctionId` `FunctionsPage.tsx` used to hold),\n * `ep_`/`wf_` for the other two, whose pages mint the same shapes today. The\n * prefix comes from the descriptor, so \"which kind is this?\" is answered by the\n * same table that answers every other kind question.\n */\nexport function newCallableId(kind: CallableKind): string {\n return newId(descriptorFor(kind).newIdPrefix);\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { type W6WClient, isFunctionRun } from \"@w6w/sdk\";\nimport type { FunctionSummary as SdkFunctionSummary } from \"@w6w/sdk/console\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\n/**\n * The Function-bound facade over the kind-parametrised repo (`src/repos/callables.ts`, T4.2.1).\n *\n * Everything here that is not Function-specific is one line delegating to `callables.ts` with\n * `\"function\"` bound in — the list/get queries, the save mutation, archive and delete — so the\n * Function arm of every kind-wide behaviour has exactly ONE implementation to fix. What stays is\n * what only a Function has: the `manifestVersion: \"2\"` literal, the SDK's Function type re-exports,\n * the `valid`-carrying summary widening, and the run-plane invoke (`client.run`, `isFunctionRun`)\n * that no other kind's page uses.\n *\n * The delegations keep their original names and call shapes on purpose: `ui/rail/SettingsTool.tsx`,\n * `ui/rail/AliasesTool.tsx`, `ui/rail/ErrorHandlingTool.tsx`, `components/TargetSelector.tsx`,\n * `components/FunctionIdentityModal.tsx` and `api/w6wApiFacade.tsx` all import from here, and this\n * node moves no behaviour — only where the code lives.\n */\nimport { callableKey } from \"../lib/callable-kind.ts\";\nimport { invalidateSavedCallable } from \"../lib/save-invalidation.ts\";\nimport {\n callableListKey,\n useArchiveCallableMutation,\n useCallableListQuery,\n useCallableQuery,\n useDeleteCallableMutation,\n useSaveCallableMutation,\n} from \"./callables.ts\";\n\nexport type {\n FunctionDef,\n FunctionImpl,\n FunctionInput,\n FunctionOutputField,\n} from \"@w6w/sdk/console\";\n\n/** A Function list row — the SDK's own summary (it carries `archivedAt` since W-12). */\nexport type FunctionSummary = SdkFunctionSummary;\n\n/** The list key {@link useFunctionsQuery} reads — `callables.ts`'s own\n * `callableListKey(\"function\")`, kept as a named export because\n * `lib/spec-import-invalidation.ts` invalidates it by value. */\nexport const functionsKey = callableListKey(\"function\");\n\n/** Function definitions carry `manifestVersion: \"2\"` - the one literal, shared\n * by the editor's blank draft and the create modal's first POST. */\nexport const FUNCTION_MANIFEST_VERSION = \"2\";\n\nexport function listFunctions(client: W6WClient) {\n return client.console.functions.list();\n}\n\nexport function useFunctionsQuery(enabled = true) {\n return useCallableListQuery<FunctionSummary>(\"function\", enabled);\n}\n\nexport const functionKey = (id: string) => callableKey(\"function\", id);\n\n/** The Function arm's own reader: the SDK's typed `get`, whose `{...function, valid}` splice is\n * what `FunctionEditor` hydrates its draft from (pin 5 — the server computes `valid`; studio\n * never reimplements the check). */\nexport function getFunction(client: W6WClient, id: string) {\n return client.console.functions.get(id);\n}\n\nexport function useFunctionQuery(id: string, enabled = true) {\n return useCallableQuery<Awaited<ReturnType<typeof getFunction>>>(\"function\", id, enabled);\n}\n\nexport function useSaveFunctionMutation() {\n return useSaveCallableMutation(\"function\");\n}\n\n/**\n * The GUARDED Function save: `console.functions.upsert(definition, {ifUnmodifiedSince})`, so a\n * save made from a stale copy answers `409 function_stale` instead of overwriting the newer one.\n * `ifUnmodifiedSince` is REQUIRED in the variables (pass `null` to opt out explicitly) so a call\n * site cannot forget the token; it is the `updatedAt` of the copy the definition was edited from\n * (`callableRecord(\"function\", …).updatedAt`). Same invalidation as {@link useSaveFunctionMutation}\n * (list + the saved resource's key); resolves `{id, key, updatedAt}`. Additive: the unguarded\n * hook's `mutate(definition)` shape is unchanged.\n */\nexport function useGuardedSaveFunctionMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { definition: unknown; ifUnmodifiedSince: string | null }) =>\n apiClient.console.functions.upsert(vars.definition as never, {\n ifUnmodifiedSince: vars.ifUnmodifiedSince,\n }),\n onSuccess: (saved) => invalidateSavedCallable(qc, functionsKey, functionKey(saved.id)),\n });\n}\n\n/**\n * One test invoke's result: the Function's own output, plus the platform's\n * record of the attempt.\n *\n * The two are kept apart rather than merged because they answer different\n * questions, and merging them is what the invocation envelope exists to stop:\n * a vendor payload reading `{\"statusCode\": 202}` is SendGrid describing its own\n * request, while `status` here is whether w6w considered the call a success.\n * The frame fields are optional — an older server sends only the output.\n */\nexport interface FunctionInvokeResult {\n output: unknown;\n invocationId?: string;\n status?: string;\n durationMs?: number;\n}\n\n/**\n * `fn_…` ids are already URN-shaped, so the base dispatcher resolves them\n * directly — no id translation. `isFunctionRun` narrows the open\n * `RunEnvelope`; a `fn_…` URN can only ever resolve to the `function` arm\n * server-side, so the `else` branch is defensive, not a real code path.\n */\nexport function invokeFunction(\n client: W6WClient,\n id: string,\n inputs: Record<string, unknown>,\n): Promise<FunctionInvokeResult> {\n return client.run({ urn: id, payload: inputs }).then((env) => {\n if (!isFunctionRun(env)) {\n throw new Error(`expected a function-kind run envelope for \"${id}\", got \"${env.kind}\"`);\n }\n return {\n output: env.output,\n invocationId: env.invocationId,\n status: env.status,\n durationMs: env.durationMs,\n };\n });\n}\n\nexport function useInvokeFunctionMutation() {\n const apiClient = useEmbedClient();\n return useMutation({\n mutationFn: (vars: { id: string; inputs: Record<string, unknown> }) =>\n invokeFunction(apiClient, vars.id, vars.inputs),\n });\n}\n\n/**\n * T4.1.1/A7/D-I0-7: `POST /functions/:id/archive`, `DELETE /functions/:id` — the Function arm of\n * `callables.ts`'s generic pair (the plain `apiClient.request()` escape hatch, NOT a typed\n * `@w6w/sdk` method, which would drag `packages/wrappers` into this task's scope for two internal\n * routes). Both invalidate `functionsKey`, so the list's `archivedAt` refreshes and the rail's\n * Delete control appears in Archive's place.\n */\nexport function useArchiveFunctionMutation() {\n return useArchiveCallableMutation(\"function\");\n}\n\nexport function useDeleteFunctionMutation() {\n return useDeleteCallableMutation(\"function\");\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport type { W6WClient } from \"@w6w/sdk\";\nimport type {\n EndpointDef as SdkEndpointDef,\n EndpointSummary as SdkEndpointSummary,\n EndpointTarget as SdkEndpointTarget,\n} from \"@w6w/sdk/console\";\n/**\n * The Endpoint-bound facade over the kind-parametrised repo (`src/repos/callables.ts`, T4.2.2).\n *\n * Everything here that is not Endpoint-specific is one line delegating to `callables.ts` with\n * `\"endpoint\"` bound in — the list/get queries, archive and delete — so the Endpoint arm of every\n * kind-wide behaviour has exactly ONE implementation to fix (the shape `repos/functions.ts` took in\n * T4.2.1, and the \"keep the facade's exports\" rule that module documents). What stays is what only\n * an Endpoint has: the `manifestVersion: \"2\"` literal, the SDK's Endpoint type re-exports, the\n * `status`/`incomplete`/`archivedAt`-carrying summary widening with its one reader\n * {@link isEndpointDraft}, the server-rendered `invokeUrls[]` widening, the synchronous invoke\n * (`client.console.endpoints.invoke`), and the SAVE — whose 201 carries those `invokeUrls[]` back to\n * the editor's URL card, which is why its `mutationFn` is the one arm the generic `saveCallable`\n * cannot serve.\n *\n * The delegations keep their original names and call shapes on purpose: `ui/rail/SettingsTool.tsx`,\n * `ui/rail/AliasesTool.tsx`, `ui/rail/ErrorHandlingTool.tsx`, `components/TargetSelector.tsx`,\n * `components/EndpointIdentityModal.tsx`, `repos/versions.ts` (the revert arm's `endpointKey`) and\n * `repos/spec-import.ts` (`endpointsKey`) all import from here, and this node moves no behaviour —\n * only where the code lives. The two key exports stay byte-identical because both are the builders\n * `callables.ts` already documents as frozen (`[\"endpoints\"]`, `[\"endpoint\", id]`).\n */\nimport { callableKey } from \"../lib/callable-kind.ts\";\nimport { invalidateSavedCallable } from \"../lib/save-invalidation.ts\";\n\nexport type {\n ActionTarget,\n CallableRef,\n CallableOnError,\n ErrorHandlerTarget,\n EndpointAuthMode,\n EndpointInput,\n EndpointInvokeResult,\n EndpointSecurity,\n EndpointTarget,\n ErrorReroute,\n Exposure,\n RetryPolicy,\n} from \"@w6w/sdk/console\";\nexport { SECRET_MASK } from \"@w6w/sdk/console\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\nimport {\n callableListKey,\n useArchiveCallableMutation,\n useCallableListQuery,\n useCallableQuery,\n useDeleteCallableMutation,\n} from \"./callables.ts\";\n\n/** An Endpoint's OWN target: the alias-only `endpoint` arm excluded, mirroring the\n * server fence in admin/endpoints.ts's validateDefinition. Aliases use the full union\n * (`EndpointTarget`, re-exported above verbatim). */\nexport type EndpointOwnTarget = Exclude<SdkEndpointTarget, { kind: \"endpoint\" }>;\nexport type EndpointDef = Omit<SdkEndpointDef, \"target\"> & { target: EndpointOwnTarget };\n\n/**\n * One entry of the `invokeUrls[]` array the server renders on `GET\n * /endpoints/:id` and the `POST /endpoints` 201 (T3.4.1, `admin/endpoints.ts`'s\n * `InvokeUrlEntry` — the shapes are kept in sync by hand, not shared, because\n * `@w6w/sdk` does not type this field yet: it is server-fresh and\n * `packages/wrappers` publishes in lockstep at one `VERSION` across four\n * languages, outside this project's boundary (HITL-10). `entries[0]` is always\n * the platform entry; every entry after it is one of the tenant's domains.\n * `default` mirrors the tenant's stored default domain and, since D-S1\n * (intake T-0.2), it is what CHOOSES the open-on entry: absent an\n * in-session pick, the URL card opens on whichever entry carries it,\n * falling back to `entries[0]` only when no entry does. `resolves` is a\n * static host comparison the server already made; the client never\n * re-derives it.\n */\nexport interface InvokeUrlOption {\n domain: string;\n default: boolean;\n url: string;\n urlByKey?: string;\n resolves: boolean;\n}\n\n/** The two SDK-typed URL fields, widened with the untyped `invokeUrls[]`\n * array — the ONE seam `getEndpoint`, the save mutation and the editor's own\n * 201 read all widen through, so `EndpointsPage.tsx` never casts. */\ntype WithInvokeUrls = {\n invokeUrl: string;\n invokeUrlByKey?: string;\n invokeUrls?: InvokeUrlOption[];\n};\n\n/** An Endpoint list row — the SDK's own summary (`status`, `incomplete` and `archivedAt` are\n * on it since W-12), read for draft-ness only through {@link isEndpointDraft}. */\nexport type EndpointSummary = SdkEndpointSummary;\n\n/** Is this row a draft — not authorised to dispatch (HITL-7/HITL-8,\n * `rfcs/endpoint.md` § Amendment — 2026-08-14b)? Prefers the server's `status`\n * field (`!== \"ready\"`), falling back to the older `incomplete` boolean only\n * when `status` is absent (a server that has not shipped it yet). The sole\n * reader of both fields in studio; every \"unfinished\" UI decision (the\n * list's tag, and any future one) calls this rather than reading either\n * field inline. */\nexport function isEndpointDraft(ep: Pick<EndpointSummary, \"status\" | \"incomplete\">): boolean {\n return ep.status !== undefined ? ep.status !== \"ready\" : ep.incomplete === true;\n}\n\n/** Endpoint definitions carry `manifestVersion: \"2\"` — the one literal, shared\n * by the editor's blank draft and the create modal's first POST. */\nexport const ENDPOINT_MANIFEST_VERSION = \"2\";\n\n/** The list key {@link useEndpointsQuery} reads — `callables.ts`'s own\n * `callableListKey(\"endpoint\")` (byte-identical `[\"endpoints\"]`), kept as a named export because\n * `repos/spec-import.ts` invalidates it by value. */\nexport const endpointsKey = callableListKey(\"endpoint\");\n\nexport function useEndpointsQuery(enabled = true) {\n return useCallableListQuery<EndpointSummary>(\"endpoint\", enabled);\n}\n\n/** Fetch one Endpoint. Widens the SDK's return once — the server sends\n * `invokeUrls[]` (T3.4.1) that `@w6w/sdk`'s typed `get()` does not know about\n * yet; see {@link WithInvokeUrls}. */\nexport function getEndpoint(\n client: W6WClient,\n id: string,\n): Promise<{ endpoint: EndpointDef } & WithInvokeUrls> {\n return client.console.endpoints.get(id) as Promise<{ endpoint: EndpointDef } & WithInvokeUrls>;\n}\n\n/** The single-resource key — `callables.ts`'s own `callableKey(\"endpoint\", id)` (byte-identical\n * `[\"endpoint\", id]`), kept as a named export because `repos/versions.ts`'s revert arm invalidates\n * it by value. */\nexport const endpointKey = (id: string) => callableKey(\"endpoint\", id);\n\n/** `TargetSelector`'s `endpoint` arm needs one Endpoint's own `input` contract\n * to project into fields — mirrors `useFunctionQuery`/`useWorkflowQuery`\n * (`repos/functions.ts`/`repos/workflows.ts`) exactly. */\nexport function useEndpointQuery(id: string, enabled = true) {\n return useCallableQuery<Awaited<ReturnType<typeof getEndpoint>>>(\"endpoint\", id, enabled);\n}\n\n/**\n * The Endpoint arm's SAVE — the one delegated name whose `mutationFn` is NOT `callables.ts`'s\n * `saveCallable`: that helper normalises every kind's success envelope down to `{id, key}` for the\n * invalidation below, while this kind's 201 also carries the fresh server-rendered `invokeUrl`/\n * `invokeUrlByKey`/`invokeUrls[]` the editor's URL card renders from (`onSaveSuccess` in\n * `EndpointsPage.tsx`). Its KEYS and its invalidation, though, are the generic pair's — so the\n * \"which keys does an Endpoint save refresh\" answer still has one home.\n */\nexport function useSaveEndpointMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n // Same widening as `getEndpoint` — the save's 201 carries `invokeUrls[]` too.\n mutationFn: (definition: unknown) =>\n apiClient.console.endpoints.upsert(definition as never) as Promise<\n { endpoint: { id: string; key: string } } & WithInvokeUrls\n >,\n onSuccess: (saved) => invalidateSavedCallable(qc, endpointsKey, endpointKey(saved.endpoint.id)),\n });\n}\n\n/**\n * The GUARDED Endpoint save: `console.endpoints.upsert(definition, {ifUnmodifiedSince})`, so a\n * save from a stale copy answers `409 endpoint_stale`. Variables and invalidation as\n * {@link useSaveEndpointMutation}'s, plus the required token (`null` opts out explicitly; it is\n * `callableRecord(\"endpoint\", …).updatedAt`, the envelope's TOP-LEVEL `updatedAt`). Resolves the\n * verbatim upsert body (`{endpoint:{id,key}, invokeUrl, …, updatedAt}`). Additive: the unguarded\n * hook's `mutate(definition)` shape is unchanged.\n */\nexport function useGuardedSaveEndpointMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { definition: unknown; ifUnmodifiedSince: string | null }) =>\n apiClient.console.endpoints.upsert(vars.definition as never, {\n ifUnmodifiedSince: vars.ifUnmodifiedSince,\n }) as Promise<{ endpoint: { id: string; key: string }; updatedAt: string } & WithInvokeUrls>,\n onSuccess: (saved) => invalidateSavedCallable(qc, endpointsKey, endpointKey(saved.endpoint.id)),\n });\n}\n\nexport function invokeEndpoint(client: W6WClient, id: string, input: Record<string, unknown>) {\n return client.console.endpoints.invoke(id, input);\n}\n\nexport function useInvokeEndpointMutation() {\n const apiClient = useEmbedClient();\n return useMutation({\n mutationFn: (vars: { id: string; input: Record<string, unknown> }) =>\n invokeEndpoint(apiClient, vars.id, vars.input),\n });\n}\n\n/**\n * T4.1.1/A7/D-I0-7: `POST /endpoints/:id/archive` — the Endpoint arm of `callables.ts`'s generic\n * pair (the plain `apiClient.request()` escape hatch, NOT a typed `@w6w/sdk` method, which would\n * drag `packages/wrappers` into this task's scope for one internal route). Invalidates\n * `endpointsKey`, so the list's `archivedAt` refreshes and the rail's Delete control appears in\n * Archive's place.\n */\nexport function useArchiveEndpointMutation() {\n return useArchiveCallableMutation(\"endpoint\");\n}\n\n/** `DELETE /endpoints/:id` — the Endpoint arm of the same generic pair. */\nexport function useDeleteEndpointMutation() {\n return useDeleteCallableMutation(\"endpoint\");\n}\n"],"names":["ID_ALPHABET","REJECT_AT","defaultBytes","newId","prefix","len","bytes","out","b","CALLABLE_DESCRIPTORS","descriptorFor","kind","newCallableId","functionsKey","callableListKey","FUNCTION_MANIFEST_VERSION","listFunctions","client","useFunctionsQuery","enabled","useCallableListQuery","functionKey","id","callableKey","getFunction","useFunctionQuery","useCallableQuery","useSaveFunctionMutation","useSaveCallableMutation","useGuardedSaveFunctionMutation","apiClient","useEmbedClient","qc","useQueryClient","useMutation","vars","saved","invalidateSavedCallable","invokeFunction","inputs","env","isFunctionRun","useInvokeFunctionMutation","useArchiveFunctionMutation","useArchiveCallableMutation","useDeleteFunctionMutation","useDeleteCallableMutation","isEndpointDraft","ep","ENDPOINT_MANIFEST_VERSION","endpointsKey","useEndpointsQuery","getEndpoint","endpointKey","useEndpointQuery","useSaveEndpointMutation","definition","useGuardedSaveEndpointMutation","invokeEndpoint","input","useInvokeEndpointMutation","useArchiveEndpointMutation","useDeleteEndpointMutation"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"rail-settings-XYGToh00.js","sources":["../src/lib/import-paste.ts","../src/lib/rail-settings.ts"],"sourcesContent":["/**\n * Pure decision behind `ImportSpecModal`'s Submit gate (T1.2.1, generalizing T3.2.1's A3 over all\n * three spec kinds).\n *\n * `/spec/import` accepts all three spec kinds at one route (T2.1.2 §B), and this affordance is now\n * mounted on the Functions, Endpoints and Workflows lists alike — each instance passing its own\n * `expectedKind`. Pasting a document of the WRONG kind onto a given list would still create a row\n * server-side and then send the operator to e.g. `functions/<ep_…>`, which 404s in the target\n * page's editor. So this module refuses, client-side, before any request is ever sent: (1) text\n * that isn't JSON, (2) a parse result that isn't a plain object, (3) a parsed `kind` that doesn't\n * match `expectedKind`.\n *\n * Nothing beyond that is checked here — `specVersion`, `callable`'s shape,\n * connection/reference resolvability, all of it is the SERVER's job\n * (T2.1.2 §B); duplicating any of it here would drift from what the route\n * actually enforces.\n *\n * `node --test` throws `ERR_UNKNOWN_FILE_EXTENSION` on anything reaching the\n * `@w6w/ui` import graph (`src/lib/alias-rail.ts`'s docblock), so this module\n * takes no value import at all — it has no dependency to avoid in the first\n * place.\n */\n\n/** The parsed paste, once it is confirmed to be a plain JSON object. */\nexport type ParsedSpecDocument = Record<string, unknown>;\n\n/** The one kind a given mount of the Import affordance expects — see `ImportSpecModal`'s `kind` prop. */\nexport type ExpectedSpecKind = \"function\" | \"endpoint\" | \"workflow\";\n\nexport interface ImportPasteResult {\n /**\n * The parsed JSON when it is a plain object — populated even when\n * `blockedReason` names a wrong `kind`, so a caller could still inspect\n * what was found. `null` when the text didn't even parse to an object.\n */\n parsed: ParsedSpecDocument | null;\n /** `null` exactly when the paste is a plausible spec document of `expectedKind`. */\n blockedReason: string | null;\n}\n\n/**\n * Total: never throws, always returns. `JSON.parse` is the only thing here\n * that can throw, and it is caught.\n */\nexport function parseImportPaste(text: string, expectedKind: ExpectedSpecKind): ImportPasteResult {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n return { parsed: null, blockedReason: \"Not valid JSON.\" };\n }\n\n if (value === null || Array.isArray(value) || typeof value !== \"object\") {\n return { parsed: null, blockedReason: \"Expected a JSON object, not a bare value or a list.\" };\n }\n\n const parsed = value as ParsedSpecDocument;\n\n if (parsed.kind !== expectedKind) {\n const found = typeof parsed.kind === \"string\" ? parsed.kind : \"unknown\";\n return {\n parsed,\n blockedReason: `This document's kind is \"${found}\", not \"${expectedKind}\" — paste a \"${expectedKind}\" spec document here.`,\n };\n }\n\n return { parsed, blockedReason: null };\n}\n","/**\n * Pure decisions behind the right rail's Settings tool (`src/ui/rail/SettingsTool.tsx`,\n * `id: \"aliases\"`, `title: \"Settings\"` since T3.1.2 — the tool widened past aliases alone\n * into a resource Settings panel: a metadata block and, for Functions and Endpoints, an\n * Export / Edit JSON action row (T3.3.1 — the definition itself no longer renders in the\n * panel, only the two buttons that open it in a modal), alongside the alias list\n * `../lib/alias-rail.ts` already decides). Split out so `node --test` can gate them\n * directly — same reasoning as\n * `alias-rail.ts`'s own header: `node --test` throws `ERR_UNKNOWN_FILE_EXTENSION` on\n * anything reaching the `@w6w/ui` / `Layout.tsx` import graph, and `src/ui/workspace.tsx`\n * sits one hop from that barrel through `Layout.tsx`'s import graph. So this module\n * declares its own structural mirror of the kinds it cares about instead of importing\n * `WorkspaceKind`, and takes only `import type` throughout.\n *\n * T4.1.1 widens this file's scope past the Settings tool itself: `restoreRailState`\n * (A2, `RightRail.tsx`'s persisted-state read path) and `isRowArchived`/`visibleRows`\n * (A6, the three listing pages' \"Show archived\" toggle) are pure decisions with the\n * exact same `node --test`-reachability constraint, so they land here rather than in\n * a new sibling module the contract's `inputs.touch` list didn't ask for.\n */\n\n/** Structural mirror of `WorkspaceCallable[\"kind\"]` (`src/ui/workspace.tsx`) — every kind\n * the rail can have open, not only the two this tool's action-row/metadata sections\n * apply to. */\nexport type RailSettingsKind = \"workflow\" | \"function\" | \"endpoint\" | \"connection\";\n\n/**\n * A4/T3.1.1: which metadata rows the Settings panel shows for this kind. `id` always\n * (every kind the tool is available on carries one). `key` for `function`/`endpoint`\n * (unchanged) AND, since T3.1.1, `workflow` too — `GET /workflows` now carries `key`\n * on every row (`string | null`, D-1: nullable, no backfill), and the panel renders it\n * as an editable control for `function`/`workflow` and the existing read-only `<code>`\n * for `endpoint` (`SettingsTool.tsx` gates that render choice on `ctx.kind` directly,\n * never on this array — an Endpoint's `key` entry here must not be read as \"editable\").\n * `updatedAt` stays `function`/`endpoint`-only: nothing asks for a Workflow Updated row,\n * and adding one would be a second, unrelated rail row. Deliberately never `createdAt`\n * (note 6): neither `GET /functions/:id` nor `GET /endpoints/:id` returns it, so\n * surfacing it would take a server change for one cosmetic field — this function's own\n * absence of a `createdAt` arm is half of that gate, the other half is the negative\n * assertion in the caller's markup.\n */\nexport function metadataFieldsForKind(\n kind: RailSettingsKind,\n): ReadonlyArray<\"id\" | \"key\" | \"updatedAt\"> {\n switch (kind) {\n case \"function\":\n case \"endpoint\":\n return [\"id\", \"key\", \"updatedAt\"];\n case \"workflow\":\n return [\"id\", \"key\"];\n case \"connection\":\n return [\"id\"];\n }\n}\n\n/**\n * A2/A5: the Export / Edit JSON action row exists for `function`/`endpoint` only. A\n * Workflow already has its own read-only Definition card\n * (`pages/WorkflowDetailPage.tsx:371-388`); a Connection has no stored definition shaped\n * like these two to show at all. (T3.3.1: renamed from the panel's earlier JSON-section\n * name — there is no JSON section left in the panel to describe, only the two buttons\n * that open one in a modal.)\n */\nexport function hasDefinitionActions(kind: RailSettingsKind): boolean {\n return kind === \"function\" || kind === \"endpoint\";\n}\n\n/**\n * A1/T3.1.1: does this kind have a version-history browser (the read-only browse list plus\n * Publish and Enable/Disable) in the Settings panel? `true` for `function`/`workflow`/`endpoint`,\n * `false` for `connection` — written as a `switch` naming every one of the four `RailSettingsKind`\n * arms explicitly, with no `default:`, matching {@link specCollectionForKind}'s shape and the\n * reason its own docblock gives (`:69` below — \"every one of the four `RailSettingsKind` arms is\n * named explicitly below\" so a kind can never silently fall through). Deliberately NOT derived\n * from {@link hasDefinitionActions}, which is `function`/`endpoint`-only: History covers Workflow\n * too, so deriving one from the other would silently drop it.\n */\nexport function hasVersionHistory(kind: RailSettingsKind): boolean {\n switch (kind) {\n case \"function\":\n case \"workflow\":\n case \"endpoint\":\n return true;\n case \"connection\":\n return false;\n }\n}\n\n/**\n * A1/T1.3.1: does this kind get a Delete (or, for `workflow`, Archive-then-Delete) affordance at\n * the bottom of the Settings panel? `true` for `function`/`workflow`/`endpoint`, `false` for\n * `connection` — written as a named `switch` naming every one of the four `RailSettingsKind` arms\n * explicitly, with no `default:`, matching {@link hasVersionHistory}'s exact shape (`:72-81` above)\n * for the same reason its own doc comment gives: a kind can never silently fall through. Deliberately\n * NOT derived from {@link hasVersionHistory} even though the two currently agree on every arm — a\n * future kind that gets history but not deletion (or vice versa) must not silently inherit the\n * wrong answer from a sibling predicate.\n */\nexport function hasDelete(kind: RailSettingsKind): boolean {\n switch (kind) {\n case \"function\":\n case \"workflow\":\n case \"endpoint\":\n return true;\n case \"connection\":\n return false;\n }\n}\n\n/**\n * A4: which `/<collection>/:id/spec` route the Export button's `useSpecQuery`\n * (`../repos/spec-export.ts`) must call for this kind — `null` for the two kinds A2's\n * action row never renders on. Kept in lockstep with {@link hasDefinitionActions}\n * (both are `function`/`endpoint`-only) but expressed as its own total function rather\n * than derived from it, so a Function can never be exported through\n * `/endpoints/:id/spec` by a wrong `if`/`else` fallthrough — every one of the four\n * `RailSettingsKind` arms is named explicitly below.\n */\nexport function specCollectionForKind(kind: RailSettingsKind): \"functions\" | \"endpoints\" | null {\n switch (kind) {\n case \"function\":\n return \"functions\";\n case \"endpoint\":\n return \"endpoints\";\n case \"workflow\":\n case \"connection\":\n return null;\n }\n}\n\n/** What A8's `evaluateEdit` needs to know about the row already on screen — deliberately\n * narrower than a whole `FunctionDef`/`EndpointDef`: the two fields a hand-edit must not\n * be allowed to change out from under the row it opened on. */\nexport interface EditStored {\n id: string;\n key: string;\n}\n\n/** A8's total function's result: the parsed body (when parseable and a plain object, even\n * if it goes on to fail arm 2 or 3 — the modal still has something to inspect for the\n * render, just never something Save may submit) plus the one reason Save is refused, or\n * `null` when the edit is allowed through. */\nexport interface EditEvaluation {\n parsed: Record<string, unknown> | null;\n blockedReason: string | null;\n}\n\n/**\n * A8: is this edited text a Save the rail may submit? A total function over the modal's\n * OWN text state — never `JsonEditor`'s `onValidityChange` (note 10: the only browser\n * harness this repo has stubs `JsonEditor` with a callback that is wired but never\n * invoked, so a Save gated on it would look gated and be inert; parsing `text` here is\n * behaviourally identical and fully observable by a page guard).\n *\n * Three refusals, evaluated in order, each named for the near-miss it kills:\n * 1. the text does not parse as JSON, or parses to something that is not a plain object\n * (`null` and an array both fail here, not a dedicated fourth arm — a\n * `FunctionDef`/`EndpointDef` is never legitimately either);\n * 2. `parsed.id !== stored.id` (note 9 — `FunctionsRepo.upsert` selects the row by\n * `definition.id`, so an edited id does not edit this row, it creates or hijacks a\n * different one);\n * 3. `parsed.key !== stored.key` (note 8 — `POST /endpoints` 409s on a changed key while\n * `POST /functions` silently accepts one; locking it here keeps both kinds behaving\n * the same from this one modal).\n */\nexport function evaluateEdit(text: string, stored: EditStored): EditEvaluation {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n return { parsed: null, blockedReason: \"Not valid JSON.\" };\n }\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return { parsed: null, blockedReason: \"Not valid JSON.\" };\n }\n const parsed = value as Record<string, unknown>;\n if (parsed.id !== stored.id) {\n return { parsed, blockedReason: \"id cannot be changed here.\" };\n }\n if (parsed.key !== stored.key) {\n return { parsed, blockedReason: \"key cannot be changed here.\" };\n }\n return { parsed, blockedReason: null };\n}\n\n/** A7/D-3's total function's result: may the save proceed, and if not, why —\n * rendered verbatim in `WorkflowsPage.tsx`'s existing error/banner idiom. */\nexport interface KeyEditEvaluation {\n allowed: boolean;\n reason: string | null;\n}\n\n/**\n * D-3: is a Workflow save carrying this `key` one `WorkflowsPage.tsx`'s raw-JSON\n * editor may submit? The right rail's Key control (`SettingsTool.tsx`) is the ONLY\n * path allowed to assign or change a workflow's key (see this project's Requirement);\n * this total function is what keeps a hand-edit of the JSON — via the Save button OR\n * auto-save, both of which must fold this in (see `WorkflowsPage.tsx`'s `canSave`) —\n * from doing it silently instead.\n *\n * `loadedKey` is the key `WorkflowsPage.tsx` most recently loaded FROM THE SERVER\n * (its own `loadedKeyRef`, captured at both of its load sites — the initial `editId`\n * effect and `reloadFromServer`). `undefined` means nothing has loaded yet, which\n * refuses unconditionally: there is nothing yet to compare the parsed text against,\n * so allowing the save through would let an unloaded/stale comparison pass by\n * accident. Once loaded, `loadedKey` is `string | null` (P5's unset state, D-1).\n *\n * `parsedKey` is whatever the parsed JSON text's own `key` field currently holds.\n * `undefined` (the field is absent from the text) is treated exactly like an\n * explicit `null` — both mean \"no key\" on the wire, and a definition that dropped\n * the field entirely must be refused exactly like one that changed it, never waved\n * through as \"nothing to compare\".\n */\nexport function workflowKeyEditAllowed(\n loadedKey: string | null | undefined,\n parsedKey: unknown,\n): KeyEditEvaluation {\n if (loadedKey === undefined) {\n return { allowed: false, reason: \"Workflow not loaded yet.\" };\n }\n const normalizedParsed = parsedKey === undefined ? null : parsedKey;\n if (normalizedParsed !== loadedKey) {\n return {\n allowed: false,\n reason: \"key cannot be changed here — use the Settings panel's Key field.\",\n };\n }\n return { allowed: true, reason: null };\n}\n\n/**\n * T4.1.1/A2: the shape actually written to `localStorage` for the right\n * rail's persisted state (`RightRail.tsx`'s `PersistedRail`) — `activeTool`\n * ONLY. `open` is deliberately absent from this interface, not merely\n * unwritten: {@link restoreRailState} below has nothing to read it FROM, so\n * a pre-existing `{\"open\":true,…}` value written before this task cannot\n * reopen the rail even by accident.\n */\nexport interface StoredRailState {\n activeTool: string | null;\n}\n\n/**\n * A2: parses `localStorage`'s raw rail entry into {@link StoredRailState}.\n * Missing/unparsable input, or a non-string `activeTool`, all fall back to\n * `{ activeTool: null }` — the same defensive shape `RightRail.tsx`'s own\n * `readStoredState` used before this task, minus the `open` field entirely.\n * `RightRail.tsx` is the one caller; it combines this result with a hardcoded\n * `open: false` on every read (D-I0-2) — that combination happens there, not\n * here, because `open`'s absence from THIS function's return type is the\n * proof a page guard can pin: there is no `open` member left to misread.\n */\nexport function restoreRailState(raw: string | null): StoredRailState {\n if (!raw) return { activeTool: null };\n try {\n const parsed = JSON.parse(raw) as Partial<Record<string, unknown>>;\n return { activeTool: typeof parsed.activeTool === \"string\" ? parsed.activeTool : null };\n } catch {\n return { activeTool: null };\n }\n}\n\n/**\n * A6: a listing row either Workflow, Function or Endpoint's list carries —\n * whichever archived signal the row's own kind uses. Workflow rows signal\n * archived via the existing `status === \"archived\"` (`WorkflowSummary`);\n * Function/Endpoint rows via the new `archivedAt` column T1.1.1 ships\n * (`string | null`). Both fields optional so one predicate below covers all\n * three wire shapes without a per-kind branch at each listing page's call\n * site.\n */\nexport interface ArchivableRow {\n status?: string;\n archivedAt?: string | null;\n}\n\n/**\n * A6: is this row archived? Archived when the row's `status` is `\"archived\"` OR it carries a\n * non-null `archivedAt` (Endpoint rows carry both fields; Workflow rows carry a `status` that is\n * `\"archived\"` exactly when `archivedAt` is set).\n */\nexport function isRowArchived(row: ArchivableRow): boolean {\n return row.status === \"archived\" || row.archivedAt != null;\n}\n\n/**\n * A6: which rows a listing page's \"Show archived\" toggle should render.\n * `showArchived` false (the default) drops every archived row; `true`\n * reveals them ALONGSIDE the live ones — an include, never a toggle that\n * hides the rest (the contract's mutation M6: a toggle that hides LIVE rows\n * once ON must fail the \"both a live and an archived row survive together\"\n * case below; M7: defaulting to showing archived rows must fail the\n * toggle-OFF case). One pure function shared by `WorkflowsPage.tsx`,\n * `FunctionsPage.tsx` and `EndpointsPage.tsx` rather than three inline\n * `.filter`s.\n */\nexport function visibleRows<T extends ArchivableRow>(\n rows: readonly T[],\n showArchived: boolean,\n): T[] {\n return showArchived ? rows.slice() : rows.filter((row) => !isRowArchived(row));\n}\n"],"names":["parseImportPaste","text","expectedKind","value","parsed","found","metadataFieldsForKind","kind","hasDefinitionActions","hasVersionHistory","hasDelete","specCollectionForKind","evaluateEdit","stored","workflowKeyEditAllowed","loadedKey","parsedKey","restoreRailState","raw","isRowArchived","row","visibleRows","rows","showArchived"],"mappings":"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"}