@executor-js/plugin-mcp 1.4.29 → 1.4.31

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 (46) hide show
  1. package/dist/{AddMcpSource-TLAL463B.js → AddMcpSource-3HUBFR3K.js} +68 -141
  2. package/dist/AddMcpSource-3HUBFR3K.js.map +1 -0
  3. package/dist/{EditMcpSource-FAWEECNU.js → EditMcpSource-UVGSSC2R.js} +106 -83
  4. package/dist/EditMcpSource-UVGSSC2R.js.map +1 -0
  5. package/dist/McpSourceSummary-UWVCAJOU.js +171 -0
  6. package/dist/McpSourceSummary-UWVCAJOU.js.map +1 -0
  7. package/dist/api/group.d.ts +92 -180
  8. package/dist/api/index.d.ts +97 -382
  9. package/dist/{chunk-4ORPFRLI.js → chunk-2A4H3UVR.js} +21 -80
  10. package/dist/chunk-2A4H3UVR.js.map +1 -0
  11. package/dist/{chunk-M6REVU6O.js → chunk-3TGDWTNE.js} +14 -40
  12. package/dist/chunk-3TGDWTNE.js.map +1 -0
  13. package/dist/{chunk-2DOCEPYN.js → chunk-H5PLTEMB.js} +632 -713
  14. package/dist/chunk-H5PLTEMB.js.map +1 -0
  15. package/dist/chunk-PZ5AY32C.js +10 -0
  16. package/dist/chunk-PZ5AY32C.js.map +1 -0
  17. package/dist/{chunk-SKSXXFOA.js → chunk-TW44CBXJ.js} +12 -1
  18. package/dist/chunk-TW44CBXJ.js.map +1 -0
  19. package/dist/client.js +5 -4
  20. package/dist/client.js.map +1 -1
  21. package/dist/core.js +4 -6
  22. package/dist/index.js +4 -2
  23. package/dist/promise.d.ts +1 -1
  24. package/dist/react/atoms.d.ts +198 -236
  25. package/dist/react/client.d.ts +91 -179
  26. package/dist/sdk/binding-store.d.ts +3 -163
  27. package/dist/sdk/index.d.ts +2 -2
  28. package/dist/sdk/plugin.d.ts +172 -225
  29. package/dist/sdk/presets.d.ts +1 -0
  30. package/dist/sdk/testing-fixtures.test.d.ts +1 -0
  31. package/dist/sdk/types.d.ts +58 -83
  32. package/dist/{stdio-connector-AA5S6UUJ.js → stdio-connector-MDW6PW36.js} +3 -1
  33. package/dist/{stdio-connector-AA5S6UUJ.js.map → stdio-connector-MDW6PW36.js.map} +1 -1
  34. package/dist/testing/index.d.ts +1 -1
  35. package/dist/testing/server.d.ts +70 -4
  36. package/dist/testing.js +14085 -30
  37. package/dist/testing.js.map +1 -1
  38. package/package.json +3 -4
  39. package/dist/AddMcpSource-TLAL463B.js.map +0 -1
  40. package/dist/EditMcpSource-FAWEECNU.js.map +0 -1
  41. package/dist/McpSourceSummary-257JNETP.js +0 -85
  42. package/dist/McpSourceSummary-257JNETP.js.map +0 -1
  43. package/dist/chunk-2DOCEPYN.js.map +0 -1
  44. package/dist/chunk-4ORPFRLI.js.map +0 -1
  45. package/dist/chunk-M6REVU6O.js.map +0 -1
  46. package/dist/chunk-SKSXXFOA.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@executor-js/plugin-mcp",
3
- "version": "1.4.29",
3
+ "version": "1.4.31",
4
4
  "homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/plugins/mcp",
5
5
  "bugs": {
6
6
  "url": "https://github.com/RhysSullivan/executor/issues"
@@ -54,15 +54,14 @@
54
54
  "dependencies": {
55
55
  "@cfworker/json-schema": "^4.1.1",
56
56
  "@effect/platform-node": "4.0.0-beta.59",
57
- "@executor-js/config": "1.4.29",
58
- "@executor-js/sdk": "1.4.29",
57
+ "@executor-js/config": "1.4.31",
58
+ "@executor-js/sdk": "1.4.31",
59
59
  "@modelcontextprotocol/sdk": "^1.29.0",
60
60
  "effect": "4.0.0-beta.59"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@effect/atom-react": "4.0.0-beta.59",
64
64
  "@effect/vitest": "4.0.0-beta.59",
65
- "@executor-js/storage-core": "1.4.29",
66
65
  "@types/node": "^24.3.1",
67
66
  "@types/react": "^19.1.0",
68
67
  "bun-types": "^1.2.22",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/react/AddMcpSource.tsx"],"sourcesContent":["import { useReducer, useCallback, useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { useAtomSet } from \"@effect/atom-react\";\nimport * as Exit from \"effect/Exit\";\nimport * as Match from \"effect/Match\";\nimport * as Option from \"effect/Option\";\nimport * as Schema from \"effect/Schema\";\n\nimport { useScope } from \"@executor-js/react/api/scope-context\";\nimport { Button } from \"@executor-js/react/components/button\";\nimport {\n CardStack,\n CardStackContent,\n CardStackEntry,\n CardStackEntryField,\n} from \"@executor-js/react/components/card-stack\";\nimport { FieldLabel } from \"@executor-js/react/components/field\";\nimport { FilterTabs } from \"@executor-js/react/components/filter-tabs\";\nimport { FloatActions } from \"@executor-js/react/components/float-actions\";\nimport { Input } from \"@executor-js/react/components/input\";\nimport { Label } from \"@executor-js/react/components/label\";\nimport { Spinner } from \"@executor-js/react/components/spinner\";\nimport { Textarea } from \"@executor-js/react/components/textarea\";\nimport {\n emptyHttpCredentials,\n httpCredentialsValid,\n HttpCredentialsEditor,\n serializeScopedHttpCredentials,\n serializeHttpCredentials,\n} from \"@executor-js/react/plugins/http-credentials\";\nimport {\n sourceDisplayNameFromUrl,\n slugifyNamespace,\n SourceIdentityFields,\n useSourceIdentity,\n} from \"@executor-js/react/plugins/source-identity\";\nimport { useSecretPickerSecrets } from \"@executor-js/react/plugins/use-secret-picker-secrets\";\nimport {\n oauthCallbackUrl,\n oauthConnectionId,\n useOAuthPopupFlow,\n type OAuthCompletionPayload,\n} from \"@executor-js/react/plugins/oauth-sign-in\";\nimport {\n CredentialControlField,\n CredentialUsageRow,\n useCredentialTargetScope,\n} from \"@executor-js/react/plugins/credential-target-scope\";\n\ntype RemoteAuthMode = \"none\" | \"oauth2\";\nimport { sourceWriteKeys } from \"@executor-js/react/api/reactivity-keys\";\nimport { probeMcpEndpoint, addMcpSourceOptimistic } from \"./atoms\";\nimport { McpRemoteSourceFields } from \"./McpRemoteSourceFields\";\nimport { mcpPresets, type McpPreset } from \"../sdk/presets\";\nimport { MCP_OAUTH_CONNECTION_SLOT, type McpCredentialInput } from \"../sdk/types\";\n\nconst ErrorMessage = Schema.Struct({ message: Schema.String });\nconst decodeErrorMessage = Schema.decodeUnknownOption(ErrorMessage);\n\nconst errorMessageFromExit = (exit: Exit.Exit<unknown, unknown>, fallback: string): string =>\n Option.match(Option.flatMap(Exit.findErrorOption(exit), decodeErrorMessage), {\n onNone: () => fallback,\n onSome: ({ message }) => message,\n });\n\n// ---------------------------------------------------------------------------\n// Preset lookup\n// ---------------------------------------------------------------------------\n\nfunction findPreset(id: string | undefined): McpPreset | undefined {\n if (!id) return undefined;\n return mcpPresets.find((p) => p.id === id);\n}\n\n// ---------------------------------------------------------------------------\n// State machine (remote flow)\n// ---------------------------------------------------------------------------\n\ntype OAuthTokens = OAuthCompletionPayload;\n\ntype ProbeResult = {\n connected: boolean;\n requiresOAuth: boolean;\n supportsDynamicRegistration: boolean;\n name: string;\n namespace: string;\n toolCount: number | null;\n serverName: string | null;\n};\n\ntype PlainHeader = {\n name: string;\n value: string;\n};\n\ntype State =\n | { step: \"url\"; url: string }\n | { step: \"probing\"; url: string; probe: ProbeResult | null }\n | { step: \"probed\"; url: string; probe: ProbeResult }\n | { step: \"oauth-starting\"; url: string; probe: ProbeResult }\n | {\n step: \"oauth-waiting\";\n url: string;\n probe: ProbeResult;\n sessionId: string;\n }\n | { step: \"oauth-done\"; url: string; probe: ProbeResult; tokens: OAuthTokens }\n | {\n step: \"adding\";\n url: string;\n probe: ProbeResult;\n tokens: OAuthTokens | null;\n }\n | {\n step: \"error\";\n url: string;\n probe: ProbeResult | null;\n tokens: OAuthTokens | null;\n error: string;\n };\n\ntype Action =\n | { type: \"set-url\"; url: string }\n | { type: \"probe-start\" }\n | { type: \"probe-ok\"; probe: ProbeResult }\n | { type: \"probe-fail\"; error: string }\n | { type: \"oauth-start\" }\n | { type: \"oauth-waiting\"; sessionId: string }\n | { type: \"oauth-ok\"; tokens: OAuthTokens }\n | { type: \"oauth-fail\"; error: string }\n | { type: \"oauth-cancelled\" }\n | { type: \"oauth-reset\" }\n | { type: \"add-start\" }\n | { type: \"add-fail\"; error: string }\n | { type: \"retry\" };\n\nconst init: State = { step: \"url\", url: \"\" };\n\nfunction reducer(state: State, action: Action): State {\n return Match.value(action).pipe(\n Match.discriminator(\"type\")(\"set-url\", (a): State => ({ step: \"url\", url: a.url })),\n Match.discriminator(\"type\")(\n \"probe-start\",\n (): State => ({\n step: \"probing\",\n url: state.url,\n probe: \"probe\" in state ? state.probe : null,\n }),\n ),\n Match.discriminator(\"type\")(\n \"probe-ok\",\n (a): State => ({ step: \"probed\", url: state.url, probe: a.probe }),\n ),\n Match.discriminator(\"type\")(\n \"probe-fail\",\n (a): State => ({\n step: \"error\",\n url: state.url,\n probe: null,\n tokens: null,\n error: a.error,\n }),\n ),\n Match.discriminator(\"type\")(\"oauth-start\", (): State => {\n if (state.step !== \"probed\" && state.step !== \"error\") return state;\n return {\n step: \"oauth-starting\",\n url: state.url,\n probe: state.step === \"probed\" ? state.probe : state.probe!,\n };\n }),\n Match.discriminator(\"type\")(\"oauth-waiting\", (a): State => {\n if (state.step !== \"oauth-starting\") return state;\n return {\n step: \"oauth-waiting\",\n url: state.url,\n probe: state.probe,\n sessionId: a.sessionId,\n };\n }),\n Match.discriminator(\"type\")(\"oauth-ok\", (a): State => {\n if (state.step !== \"oauth-waiting\") return state;\n return {\n step: \"oauth-done\",\n url: state.url,\n probe: state.probe,\n tokens: a.tokens,\n };\n }),\n Match.discriminator(\"type\")(\"oauth-fail\", (a): State => {\n if (state.step !== \"oauth-starting\" && state.step !== \"oauth-waiting\") return state;\n return {\n step: \"error\",\n url: state.url,\n probe: state.probe,\n tokens: null,\n error: a.error,\n };\n }),\n Match.discriminator(\"type\")(\"oauth-cancelled\", (): State => {\n if (state.step !== \"oauth-waiting\") return state;\n return { step: \"probed\", url: state.url, probe: state.probe };\n }),\n Match.discriminator(\"type\")(\"oauth-reset\", (): State => {\n if (\"probe\" in state && state.probe) {\n return { step: \"probed\", url: state.url, probe: state.probe };\n }\n return state;\n }),\n Match.discriminator(\"type\")(\"add-start\", (): State => {\n const tokens =\n state.step === \"oauth-done\" ? state.tokens : state.step === \"probed\" ? null : null;\n const probe = \"probe\" in state ? state.probe : null;\n if (!probe) return state;\n return { step: \"adding\", url: state.url, probe, tokens };\n }),\n Match.discriminator(\"type\")(\"add-fail\", (a): State => {\n if (state.step !== \"adding\") return state;\n return {\n step: \"error\",\n url: state.url,\n probe: state.probe,\n tokens: state.tokens,\n error: a.error,\n };\n }),\n Match.discriminator(\"type\")(\"retry\", (): State => {\n if (state.step !== \"error\") return state;\n return state.probe\n ? state.tokens\n ? {\n step: \"oauth-done\",\n url: state.url,\n probe: state.probe,\n tokens: state.tokens,\n }\n : { step: \"probed\", url: state.url, probe: state.probe }\n : { step: \"url\", url: state.url };\n }),\n Match.exhaustive,\n );\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport default function AddMcpSource(props: {\n onComplete: () => void;\n onCancel: () => void;\n initialUrl?: string;\n initialPreset?: string;\n /** Whether the stdio transport is enabled on the server. */\n allowStdio?: boolean;\n}) {\n const allowStdio = props.allowStdio ?? false;\n const rawPreset = findPreset(props.initialPreset);\n // Drop stdio presets when stdio is disabled — the caller should have\n // already filtered these out, but defence-in-depth.\n const preset = rawPreset?.transport === \"stdio\" && !allowStdio ? undefined : rawPreset;\n const isStdioPreset = preset?.transport === \"stdio\";\n\n const [transport, setTransport] = useState<\"remote\" | \"stdio\">(\n isStdioPreset && allowStdio ? \"stdio\" : \"remote\",\n );\n\n // --- Stdio state ---\n const [stdioCommand, setStdioCommand] = useState(isStdioPreset ? preset.command : \"\");\n const [stdioArgs, setStdioArgs] = useState(\n isStdioPreset && preset.args ? preset.args.join(\" \") : \"\",\n );\n const [stdioEnv, setStdioEnv] = useState(\"\");\n const stdioIdentity = useSourceIdentity({\n fallbackName: isStdioPreset ? preset.name : stdioCommand,\n });\n const [stdioAdding, setStdioAdding] = useState(false);\n const [stdioError, setStdioError] = useState<string | null>(null);\n\n // --- Remote state ---\n const remoteUrl =\n !isStdioPreset && preset?.transport === undefined && preset?.url\n ? preset.url\n : (props.initialUrl ?? \"\");\n\n const [state, dispatch] = useReducer(\n reducer,\n remoteUrl ? { step: \"url\" as const, url: remoteUrl } : init,\n );\n\n const scopeId = useScope();\n const { credentialTargetScope: requestCredentialTargetScope } = useCredentialTargetScope();\n const {\n credentialTargetScope: oauthCredentialTargetScope,\n setCredentialTargetScope: setOAuthCredentialTargetScope,\n credentialScopeOptions,\n } = useCredentialTargetScope();\n const doProbe = useAtomSet(probeMcpEndpoint, { mode: \"promiseExit\" });\n const doAdd = useAtomSet(addMcpSourceOptimistic(scopeId), {\n mode: \"promiseExit\",\n });\n const secretList = useSecretPickerSecrets();\n const oauth = useOAuthPopupFlow<OAuthCompletionPayload>({\n popupName: \"mcp-oauth\",\n popupBlockedMessage: \"OAuth popup was blocked\",\n detectPopupClosed: false,\n startErrorMessage: \"Failed to start OAuth\",\n });\n\n const [remoteAuthMode, setRemoteAuthMode] = useState<RemoteAuthMode>(\"none\");\n const [remoteHeaders, setRemoteHeaders] = useState<PlainHeader[]>([]);\n const [remoteCredentials, setRemoteCredentials] = useState(() => emptyHttpCredentials());\n\n const probe = \"probe\" in state ? state.probe : null;\n const tokens = \"tokens\" in state ? state.tokens : null;\n\n const remoteIdentity = useSourceIdentity({\n fallbackName:\n sourceDisplayNameFromUrl(state.url, \"MCP\") ?? probe?.serverName ?? probe?.name ?? \"\",\n });\n const isProbing = state.step === \"probing\";\n const isAdding = state.step === \"adding\";\n const isOAuthBusy =\n state.step === \"oauth-starting\" || state.step === \"oauth-waiting\" || oauth.busy;\n const canUseNone = probe?.requiresOAuth !== true || probe.supportsDynamicRegistration === false;\n const remoteHeadersComplete = remoteHeaders.every(\n (header) => header.name.trim() && header.value.trim(),\n );\n const remoteCredentialsComplete = httpCredentialsValid(remoteCredentials);\n const authReady = remoteAuthMode === \"none\" ? canUseNone : tokens !== null;\n const canAdd =\n Boolean(probe) &&\n authReady &&\n remoteHeadersComplete &&\n remoteCredentialsComplete &&\n !isAdding &&\n !isOAuthBusy;\n // Probe failures are shown inline on the URL field; other failures\n // (OAuth start, add source) render in the bottom error block.\n const probeError = state.step === \"error\" && state.probe === null ? state.error : null;\n const otherError = state.step === \"error\" && state.probe !== null ? state.error : null;\n\n // ---- Remote actions ----\n\n const handleProbe = useCallback(async () => {\n dispatch({ type: \"probe-start\" });\n const { headers, queryParams } = serializeHttpCredentials(remoteCredentials);\n const exit = await doProbe({\n params: { scopeId },\n payload: {\n endpoint: state.url.trim(),\n ...(Object.keys(headers).length > 0 ? { headers } : {}),\n ...(Object.keys(queryParams).length > 0 ? { queryParams } : {}),\n },\n });\n if (Exit.isFailure(exit)) {\n dispatch({\n type: \"probe-fail\",\n error: errorMessageFromExit(exit, \"Failed to connect\"),\n });\n return;\n }\n setRemoteAuthMode(exit.value.requiresOAuth ? \"oauth2\" : \"none\");\n dispatch({ type: \"probe-ok\", probe: exit.value });\n }, [state.url, scopeId, doProbe, remoteCredentials]);\n\n // Keep the latest handleProbe in a ref so the debounced effect can call it\n // without depending on its identity (which changes every render).\n const handleProbeRef = useRef(handleProbe);\n handleProbeRef.current = handleProbe;\n\n // Auto-probe whenever the URL changes (debounced) while we're on the\n // remote transport and not already probing/probed.\n useEffect(() => {\n if (transport !== \"remote\") return;\n if (state.step !== \"url\") return;\n const trimmed = state.url.trim();\n if (!trimmed) return;\n const handle = setTimeout(() => {\n handleProbeRef.current();\n }, 400);\n return () => clearTimeout(handle);\n }, [transport, state.step, state.url]);\n\n const handleRemoteCredentialsChange = useCallback((next: typeof remoteCredentials) => {\n setRemoteCredentials(next);\n }, []);\n\n const handleOAuth = useCallback(async () => {\n dispatch({ type: \"oauth-start\" });\n const namespaceSlug =\n slugifyNamespace(remoteIdentity.namespace) ||\n slugifyNamespace(probe?.namespace ?? \"\") ||\n \"mcp\";\n const { headers, queryParams } = serializeHttpCredentials(remoteCredentials);\n await oauth.start({\n payload: {\n endpoint: state.url.trim(),\n ...(Object.keys(headers).length > 0 ? { headers } : {}),\n ...(Object.keys(queryParams).length > 0 ? { queryParams } : {}),\n redirectUrl: oauthCallbackUrl(),\n connectionId: oauthConnectionId({\n pluginId: \"mcp\",\n namespace: namespaceSlug,\n }),\n tokenScope: oauthCredentialTargetScope,\n strategy: { kind: \"dynamic-dcr\" },\n pluginId: \"mcp\",\n identityLabel: `${remoteIdentity.name.trim() || probe?.serverName || probe?.name || \"MCP\"} OAuth`,\n },\n onSuccess: (result) => {\n dispatch({\n type: \"oauth-ok\",\n tokens: {\n connectionId: result.connectionId,\n expiresAt: result.expiresAt,\n scope: result.scope,\n },\n });\n },\n onAuthorizationStarted: (result) =>\n dispatch({ type: \"oauth-waiting\", sessionId: result.sessionId }),\n onError: (error) => dispatch({ type: \"oauth-fail\", error }),\n });\n }, [state.url, remoteIdentity, probe, remoteCredentials, oauth, oauthCredentialTargetScope]);\n\n const handleCancelOAuth = useCallback(() => {\n oauth.cancel();\n dispatch({ type: \"oauth-cancelled\" });\n }, [oauth]);\n\n const handleAddRemote = useCallback(async () => {\n if (!probe) return;\n dispatch({ type: \"add-start\" });\n const auth =\n remoteAuthMode === \"oauth2\"\n ? tokens\n ? {\n kind: \"oauth2\" as const,\n connectionId: tokens.connectionId,\n }\n : {\n kind: \"oauth2\" as const,\n connectionSlot: MCP_OAUTH_CONNECTION_SLOT,\n }\n : { kind: \"none\" as const };\n const headers = Object.fromEntries(\n remoteHeaders\n .map((header) => [header.name.trim(), header.value.trim()] as const)\n .filter(([name, value]) => name && value),\n );\n const credentials = serializeScopedHttpCredentials(\n remoteCredentials,\n requestCredentialTargetScope,\n );\n const remoteRequestHeaders: Record<string, McpCredentialInput> = {\n ...headers,\n ...credentials.headers,\n };\n const displayName = remoteIdentity.name.trim() || probe.serverName || probe.name;\n const slugNamespace = slugifyNamespace(remoteIdentity.namespace);\n const exit = await doAdd({\n params: { scopeId },\n payload: {\n targetScope: scopeId,\n transport: \"remote\" as const,\n name: displayName,\n namespace: slugNamespace || undefined,\n endpoint: state.url.trim(),\n auth,\n credentialTargetScope:\n remoteAuthMode === \"oauth2\" && tokens\n ? oauthCredentialTargetScope\n : requestCredentialTargetScope,\n ...(Object.keys(remoteRequestHeaders).length > 0 ? { headers: remoteRequestHeaders } : {}),\n ...(Object.keys(credentials.queryParams).length > 0\n ? { queryParams: credentials.queryParams }\n : {}),\n },\n reactivityKeys: sourceWriteKeys,\n });\n if (Exit.isFailure(exit)) {\n dispatch({\n type: \"add-fail\",\n error: errorMessageFromExit(exit, \"Failed to add source\"),\n });\n return;\n }\n props.onComplete();\n }, [\n probe,\n remoteAuthMode,\n remoteHeaders,\n remoteCredentials,\n remoteIdentity,\n tokens,\n state.url,\n doAdd,\n props,\n scopeId,\n requestCredentialTargetScope,\n oauthCredentialTargetScope,\n ]);\n\n // ---- Stdio actions ----\n\n const parseStdioArgs = (raw: string): string[] => {\n if (!raw.trim()) return [];\n const args: string[] = [];\n const regex = /[^\\s\"]+|\"([^\"]*)\"/g;\n let match;\n while ((match = regex.exec(raw)) !== null) {\n args.push(match[1] ?? match[0]);\n }\n return args;\n };\n\n const parseStdioEnv = (raw: string): Record<string, string> | undefined => {\n if (!raw.trim()) return undefined;\n const env: Record<string, string> = {};\n for (const line of raw.split(\"\\n\")) {\n const eq = line.indexOf(\"=\");\n if (eq > 0) {\n env[line.slice(0, eq).trim()] = line.slice(eq + 1).trim();\n }\n }\n return Object.keys(env).length > 0 ? env : undefined;\n };\n\n const handleAddStdio = useCallback(async () => {\n const cmd = stdioCommand.trim();\n if (!cmd) return;\n setStdioAdding(true);\n setStdioError(null);\n const displayName = stdioIdentity.name.trim() || cmd;\n const slugNamespace = slugifyNamespace(stdioIdentity.namespace);\n const exit = await doAdd({\n params: { scopeId },\n payload: {\n targetScope: scopeId,\n transport: \"stdio\" as const,\n name: displayName,\n namespace: slugNamespace || undefined,\n command: cmd,\n args: parseStdioArgs(stdioArgs),\n env: parseStdioEnv(stdioEnv),\n },\n reactivityKeys: sourceWriteKeys,\n });\n if (Exit.isFailure(exit)) {\n setStdioError(errorMessageFromExit(exit, \"Failed to add source\"));\n setStdioAdding(false);\n return;\n }\n props.onComplete();\n }, [stdioCommand, stdioArgs, stdioEnv, stdioIdentity, doAdd, scopeId, props]);\n\n // ---- Render ----\n\n return (\n <div className=\"flex flex-1 flex-col gap-6\">\n <div>\n <h1 className=\"text-xl font-semibold text-foreground\">Add MCP Source</h1>\n <p className=\"mt-1 text-[13px] text-muted-foreground\">\n Connect to an MCP server to discover and use its tools.\n </p>\n </div>\n\n {/* Transport toggle — only shown when stdio is enabled server-side */}\n {allowStdio && (\n <div className=\"flex gap-1 rounded-lg border border-border bg-muted/30 p-1\">\n <Button\n variant=\"ghost\"\n type=\"button\"\n onClick={() => setTransport(\"remote\")}\n className={`flex-1 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${\n transport === \"remote\"\n ? \"bg-background text-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Remote\n </Button>\n <Button\n variant=\"ghost\"\n type=\"button\"\n onClick={() => setTransport(\"stdio\")}\n className={`flex-1 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${\n transport === \"stdio\"\n ? \"bg-background text-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Stdio\n </Button>\n </div>\n )}\n\n {transport === \"remote\" ? (\n <>\n <McpRemoteSourceFields\n url={state.url}\n onUrlChange={(url) => dispatch({ type: \"set-url\", url })}\n identity={remoteIdentity}\n preview={probe}\n probing={isProbing}\n error={probeError}\n onRetry={handleProbe}\n />\n\n <HttpCredentialsEditor\n credentials={remoteCredentials}\n onChange={handleRemoteCredentialsChange}\n existingSecrets={secretList}\n sourceName={remoteIdentity.name}\n targetScope={requestCredentialTargetScope}\n credentialScopeOptions={credentialScopeOptions}\n bindingScopeOptions={credentialScopeOptions}\n labels={{\n headers: \"Request headers\",\n queryParams: \"Query parameters\",\n }}\n />\n\n {/* Authentication */}\n {probe && (\n <section className=\"space-y-2.5\">\n <div className=\"flex items-center justify-between gap-3\">\n <FieldLabel>Authentication</FieldLabel>\n <FilterTabs<RemoteAuthMode>\n tabs={\n probe.requiresOAuth && probe.supportsDynamicRegistration\n ? [{ value: \"oauth2\", label: \"OAuth\" }]\n : [\n { value: \"none\", label: \"None\" },\n { value: \"oauth2\", label: \"OAuth\" },\n ]\n }\n value={remoteAuthMode}\n onChange={setRemoteAuthMode}\n />\n </div>\n\n {remoteAuthMode === \"oauth2\" && (\n <CredentialUsageRow\n value={oauthCredentialTargetScope}\n options={credentialScopeOptions}\n onChange={(targetScope) => {\n setOAuthCredentialTargetScope(targetScope);\n dispatch({ type: \"oauth-reset\" });\n }}\n label=\"Connection saved to\"\n help=\"Choose who can use the OAuth connection.\"\n >\n <CredentialControlField\n label=\"Connect via OAuth\"\n help=\"Start the provider OAuth flow.\"\n >\n {!tokens &&\n state.step === \"probed\" &&\n (probe.supportsDynamicRegistration ? (\n <Button\n type=\"button\"\n onClick={handleOAuth}\n variant=\"outline\"\n className=\"w-full\"\n >\n Sign in\n </Button>\n ) : (\n <div className=\"rounded-md border border-border bg-muted/30 px-3 py-2 text-xs text-muted-foreground\">\n This server requires OAuth, but its authorization server does not support\n dynamic client registration. Use request headers with a bearer token, or\n save the source and connect a supported OAuth connection later.\n </div>\n ))}\n\n {!tokens && state.step === \"oauth-starting\" && (\n <div className=\"flex min-h-9 items-center gap-2 rounded-md border border-border bg-muted/30 px-3 py-2\">\n <Spinner className=\"size-3.5\" />\n <span className=\"text-xs text-muted-foreground\">\n Starting authorization...\n </span>\n </div>\n )}\n\n {!tokens && state.step === \"oauth-waiting\" && (\n <div className=\"flex min-h-9 items-center gap-2 rounded-md border border-blue-500/30 bg-blue-500/5 px-3 py-2\">\n <Spinner className=\"size-3.5 text-blue-500\" />\n <span className=\"text-xs text-blue-600 dark:text-blue-400\">\n Waiting for authorization...\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleCancelOAuth}\n className=\"ml-auto h-7 px-2 text-xs\"\n >\n Cancel\n </Button>\n </div>\n )}\n\n {tokens && (\n <div className=\"flex min-h-9 items-center gap-2 rounded-md border border-emerald-500/30 bg-emerald-500/5 px-3 py-2\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" className=\"size-3.5 text-emerald-500\">\n <path\n d=\"M3 8.5l3 3 7-7\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n <span className=\"text-xs font-medium text-emerald-600 dark:text-emerald-400\">\n Authenticated\n </span>\n </div>\n )}\n </CredentialControlField>\n </CredentialUsageRow>\n )}\n </section>\n )}\n\n {/* Additional headers */}\n {probe && (\n <section className=\"space-y-2.5\">\n <div>\n <Label>Additional headers</Label>\n <p className=\"mt-1 text-[12px] text-muted-foreground\">\n Plaintext headers sent with every request. Use request headers above for\n secret-backed values.\n </p>\n </div>\n\n <CardStack>\n <CardStackContent>\n {remoteHeaders.length === 0 ? (\n <AddPlainHeaderRow\n leading={<span>No headers</span>}\n onClick={() =>\n setRemoteHeaders((headers) => [...headers, { name: \"\", value: \"\" }])\n }\n />\n ) : (\n <>\n {remoteHeaders.map((header, index) => (\n <CardStackEntry key={index} className=\"flex-col items-stretch gap-2\">\n <div className=\"flex items-center justify-between\">\n <Label className=\"text-[10px] uppercase tracking-wider text-muted-foreground\">\n Header\n </Label>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"xs\"\n className=\"text-muted-foreground hover:text-destructive\"\n onClick={() =>\n setRemoteHeaders((headers) =>\n headers.filter((_, headerIndex) => headerIndex !== index),\n )\n }\n >\n Remove\n </Button>\n </div>\n <div className=\"grid grid-cols-2 gap-2\">\n <div className=\"space-y-1\">\n <Label className=\"text-[10px] uppercase tracking-wider text-muted-foreground\">\n Name\n </Label>\n <Input\n value={header.name}\n onChange={(event) =>\n setRemoteHeaders((headers) =>\n headers.map((current, headerIndex) =>\n headerIndex === index\n ? {\n ...current,\n name: (event.target as HTMLInputElement).value,\n }\n : current,\n ),\n )\n }\n placeholder=\"X-Organization-Id\"\n className=\"h-8 text-xs font-mono\"\n />\n </div>\n <div className=\"space-y-1\">\n <Label className=\"text-[10px] uppercase tracking-wider text-muted-foreground\">\n Value\n </Label>\n <Input\n value={header.value}\n onChange={(event) =>\n setRemoteHeaders((headers) =>\n headers.map((current, headerIndex) =>\n headerIndex === index\n ? {\n ...current,\n value: (event.target as HTMLInputElement).value,\n }\n : current,\n ),\n )\n }\n placeholder=\"workspace-id\"\n className=\"h-8 text-xs font-mono\"\n />\n </div>\n </div>\n </CardStackEntry>\n ))}\n <AddPlainHeaderRow\n onClick={() =>\n setRemoteHeaders((headers) => [...headers, { name: \"\", value: \"\" }])\n }\n />\n </>\n )}\n </CardStackContent>\n </CardStack>\n </section>\n )}\n\n {/* Error (OAuth / add source). Probe errors show inline on the field. */}\n {otherError && (\n <div className=\"space-y-2\">\n <div className=\"rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2\">\n <p className=\"text-[12px] text-destructive\">{otherError}</p>\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => dispatch({ type: \"retry\" })}\n className=\"text-xs\"\n >\n Try again\n </Button>\n </div>\n )}\n\n <FloatActions>\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => {\n oauth.cancel();\n props.onCancel();\n }}\n disabled={isAdding}\n >\n Cancel\n </Button>\n {(probe || isProbing) && (\n <Button type=\"button\" onClick={handleAddRemote} disabled={!canAdd}>\n {isAdding ? (\n <>\n <Spinner className=\"size-3.5\" /> Adding…\n </>\n ) : (\n \"Add source\"\n )}\n </Button>\n )}\n </FloatActions>\n </>\n ) : (\n <>\n {/* Stdio form */}\n <CardStack>\n <CardStackContent className=\"border-t-0\">\n <CardStackEntryField\n label=\"Command\"\n description=\"- The executable to run (e.g. npx, uvx, node).\"\n >\n <Input\n value={stdioCommand}\n onChange={(e) => setStdioCommand((e.target as HTMLInputElement).value)}\n placeholder=\"npx\"\n className=\"font-mono text-sm\"\n />\n </CardStackEntryField>\n\n <CardStackEntryField\n label=\"Arguments\"\n description=\"- Space-separated arguments passed to the command.\"\n >\n <Input\n value={stdioArgs}\n onChange={(e) => setStdioArgs((e.target as HTMLInputElement).value)}\n placeholder=\"-y chrome-devtools-mcp@latest\"\n className=\"font-mono text-sm\"\n />\n </CardStackEntryField>\n\n <CardStackEntryField\n label=\"Environment variables\"\n description=\"- One per line, KEY=value format.\"\n >\n <Textarea\n value={stdioEnv}\n onChange={(e) => setStdioEnv((e.target as HTMLTextAreaElement).value)}\n placeholder={\"KEY=value\\nANOTHER=value\"}\n rows={3}\n maxRows={10}\n className=\"font-mono text-sm\"\n />\n </CardStackEntryField>\n </CardStackContent>\n </CardStack>\n\n <SourceIdentityFields identity={stdioIdentity} namePlaceholder=\"My MCP Server\" />\n\n {/* Stdio error */}\n {stdioError && (\n <div className=\"rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2\">\n <p className=\"text-[12px] text-destructive\">{stdioError}</p>\n </div>\n )}\n\n <FloatActions>\n <Button type=\"button\" variant=\"ghost\" onClick={props.onCancel} disabled={stdioAdding}>\n Cancel\n </Button>\n <Button\n type=\"button\"\n onClick={handleAddStdio}\n disabled={!stdioCommand.trim() || stdioAdding}\n >\n {stdioAdding ? (\n <>\n <Spinner className=\"size-3.5\" /> Adding…\n </>\n ) : (\n \"Add source\"\n )}\n </Button>\n </FloatActions>\n </>\n )}\n </div>\n );\n}\n\nfunction AddPlainHeaderRow({\n onClick,\n leading,\n}: {\n readonly onClick: () => void;\n readonly leading?: ReactNode;\n}) {\n return (\n // oxlint-disable-next-line react/forbid-elements\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onClick();\n }}\n aria-label=\"Add header\"\n className=\"flex w-full items-center justify-between gap-4 px-4 py-3 text-sm text-muted-foreground outline-none transition-[background-color] duration-150 ease-[cubic-bezier(0.23,1,0.32,1)] hover:bg-accent/40 focus-visible:bg-accent/40\"\n >\n <span className=\"min-w-0 flex-1 text-left\">{leading}</span>\n <svg aria-hidden viewBox=\"0 0 16 16\" fill=\"none\" className=\"size-4 shrink-0\">\n <path d=\"M8 3.5v9M3.5 8h9\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAAA,SAAS,YAAY,aAAa,WAAW,QAAQ,gBAAgC;AACrF,SAAS,kBAAkB;AAC3B,YAAY,UAAU;AACtB,YAAY,WAAW;AACvB,YAAY,YAAY;AACxB,YAAY,YAAY;AAExB,SAAS,gBAAgB;AACzB,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,8BAA8B;AACvC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,uBAAuB;AA8f1B,SA0Lc,UAzLZ,KADF;AAxfN,IAAM,eAAsB,cAAO,EAAE,SAAgB,cAAO,CAAC;AAC7D,IAAM,qBAA4B,2BAAoB,YAAY;AAElE,IAAM,uBAAuB,CAAC,MAAmC,aACxD,aAAa,eAAa,qBAAgB,IAAI,GAAG,kBAAkB,GAAG;AAAA,EAC3E,QAAQ,MAAM;AAAA,EACd,QAAQ,CAAC,EAAE,QAAQ,MAAM;AAC3B,CAAC;AAMH,SAAS,WAAW,IAA+C;AACjE,MAAI,CAAC,GAAI,QAAO;AAChB,SAAO,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAC3C;AAgEA,IAAM,OAAc,EAAE,MAAM,OAAO,KAAK,GAAG;AAE3C,SAAS,QAAQ,OAAc,QAAuB;AACpD,SAAa,YAAM,MAAM,EAAE;AAAA,IACnB,oBAAc,MAAM,EAAE,WAAW,CAAC,OAAc,EAAE,MAAM,OAAO,KAAK,EAAE,IAAI,EAAE;AAAA,IAC5E,oBAAc,MAAM;AAAA,MACxB;AAAA,MACA,OAAc;AAAA,QACZ,MAAM;AAAA,QACN,KAAK,MAAM;AAAA,QACX,OAAO,WAAW,QAAQ,MAAM,QAAQ;AAAA,MAC1C;AAAA,IACF;AAAA,IACM,oBAAc,MAAM;AAAA,MACxB;AAAA,MACA,CAAC,OAAc,EAAE,MAAM,UAAU,KAAK,MAAM,KAAK,OAAO,EAAE,MAAM;AAAA,IAClE;AAAA,IACM,oBAAc,MAAM;AAAA,MACxB;AAAA,MACA,CAAC,OAAc;AAAA,QACb,MAAM;AAAA,QACN,KAAK,MAAM;AAAA,QACX,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,OAAO,EAAE;AAAA,MACX;AAAA,IACF;AAAA,IACM,oBAAc,MAAM,EAAE,eAAe,MAAa;AACtD,UAAI,MAAM,SAAS,YAAY,MAAM,SAAS,QAAS,QAAO;AAC9D,aAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,MAAM;AAAA,QACX,OAAO,MAAM,SAAS,WAAW,MAAM,QAAQ,MAAM;AAAA,MACvD;AAAA,IACF,CAAC;AAAA,IACK,oBAAc,MAAM,EAAE,iBAAiB,CAAC,MAAa;AACzD,UAAI,MAAM,SAAS,iBAAkB,QAAO;AAC5C,aAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,MAAM;AAAA,QACX,OAAO,MAAM;AAAA,QACb,WAAW,EAAE;AAAA,MACf;AAAA,IACF,CAAC;AAAA,IACK,oBAAc,MAAM,EAAE,YAAY,CAAC,MAAa;AACpD,UAAI,MAAM,SAAS,gBAAiB,QAAO;AAC3C,aAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,MAAM;AAAA,QACX,OAAO,MAAM;AAAA,QACb,QAAQ,EAAE;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,IACK,oBAAc,MAAM,EAAE,cAAc,CAAC,MAAa;AACtD,UAAI,MAAM,SAAS,oBAAoB,MAAM,SAAS,gBAAiB,QAAO;AAC9E,aAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,MAAM;AAAA,QACX,OAAO,MAAM;AAAA,QACb,QAAQ;AAAA,QACR,OAAO,EAAE;AAAA,MACX;AAAA,IACF,CAAC;AAAA,IACK,oBAAc,MAAM,EAAE,mBAAmB,MAAa;AAC1D,UAAI,MAAM,SAAS,gBAAiB,QAAO;AAC3C,aAAO,EAAE,MAAM,UAAU,KAAK,MAAM,KAAK,OAAO,MAAM,MAAM;AAAA,IAC9D,CAAC;AAAA,IACK,oBAAc,MAAM,EAAE,eAAe,MAAa;AACtD,UAAI,WAAW,SAAS,MAAM,OAAO;AACnC,eAAO,EAAE,MAAM,UAAU,KAAK,MAAM,KAAK,OAAO,MAAM,MAAM;AAAA,MAC9D;AACA,aAAO;AAAA,IACT,CAAC;AAAA,IACK,oBAAc,MAAM,EAAE,aAAa,MAAa;AACpD,YAAM,SACJ,MAAM,SAAS,eAAe,MAAM,SAAS,MAAM,SAAS,WAAW,OAAO;AAChF,YAAM,QAAQ,WAAW,QAAQ,MAAM,QAAQ;AAC/C,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,EAAE,MAAM,UAAU,KAAK,MAAM,KAAK,OAAO,OAAO;AAAA,IACzD,CAAC;AAAA,IACK,oBAAc,MAAM,EAAE,YAAY,CAAC,MAAa;AACpD,UAAI,MAAM,SAAS,SAAU,QAAO;AACpC,aAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,MAAM;AAAA,QACX,OAAO,MAAM;AAAA,QACb,QAAQ,MAAM;AAAA,QACd,OAAO,EAAE;AAAA,MACX;AAAA,IACF,CAAC;AAAA,IACK,oBAAc,MAAM,EAAE,SAAS,MAAa;AAChD,UAAI,MAAM,SAAS,QAAS,QAAO;AACnC,aAAO,MAAM,QACT,MAAM,SACJ;AAAA,QACE,MAAM;AAAA,QACN,KAAK,MAAM;AAAA,QACX,OAAO,MAAM;AAAA,QACb,QAAQ,MAAM;AAAA,MAChB,IACA,EAAE,MAAM,UAAU,KAAK,MAAM,KAAK,OAAO,MAAM,MAAM,IACvD,EAAE,MAAM,OAAO,KAAK,MAAM,IAAI;AAAA,IACpC,CAAC;AAAA,IACK;AAAA,EACR;AACF;AAMe,SAAR,aAA8B,OAOlC;AACD,QAAM,aAAa,MAAM,cAAc;AACvC,QAAM,YAAY,WAAW,MAAM,aAAa;AAGhD,QAAM,SAAS,WAAW,cAAc,WAAW,CAAC,aAAa,SAAY;AAC7E,QAAM,gBAAgB,QAAQ,cAAc;AAE5C,QAAM,CAAC,WAAW,YAAY,IAAI;AAAA,IAChC,iBAAiB,aAAa,UAAU;AAAA,EAC1C;AAGA,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,gBAAgB,OAAO,UAAU,EAAE;AACpF,QAAM,CAAC,WAAW,YAAY,IAAI;AAAA,IAChC,iBAAiB,OAAO,OAAO,OAAO,KAAK,KAAK,GAAG,IAAI;AAAA,EACzD;AACA,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,EAAE;AAC3C,QAAM,gBAAgB,kBAAkB;AAAA,IACtC,cAAc,gBAAgB,OAAO,OAAO;AAAA,EAC9C,CAAC;AACD,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AACpD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAwB,IAAI;AAGhE,QAAM,YACJ,CAAC,iBAAiB,QAAQ,cAAc,UAAa,QAAQ,MACzD,OAAO,MACN,MAAM,cAAc;AAE3B,QAAM,CAAC,OAAO,QAAQ,IAAI;AAAA,IACxB;AAAA,IACA,YAAY,EAAE,MAAM,OAAgB,KAAK,UAAU,IAAI;AAAA,EACzD;AAEA,QAAM,UAAU,SAAS;AACzB,QAAM,EAAE,uBAAuB,6BAA6B,IAAI,yBAAyB;AACzF,QAAM;AAAA,IACJ,uBAAuB;AAAA,IACvB,0BAA0B;AAAA,IAC1B;AAAA,EACF,IAAI,yBAAyB;AAC7B,QAAM,UAAU,WAAW,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACpE,QAAM,QAAQ,WAAW,uBAAuB,OAAO,GAAG;AAAA,IACxD,MAAM;AAAA,EACR,CAAC;AACD,QAAM,aAAa,uBAAuB;AAC1C,QAAM,QAAQ,kBAA0C;AAAA,IACtD,WAAW;AAAA,IACX,qBAAqB;AAAA,IACrB,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,EACrB,CAAC;AAED,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAyB,MAAM;AAC3E,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAwB,CAAC,CAAC;AACpE,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAS,MAAM,qBAAqB,CAAC;AAEvF,QAAM,QAAQ,WAAW,QAAQ,MAAM,QAAQ;AAC/C,QAAM,SAAS,YAAY,QAAQ,MAAM,SAAS;AAElD,QAAM,iBAAiB,kBAAkB;AAAA,IACvC,cACE,yBAAyB,MAAM,KAAK,KAAK,KAAK,OAAO,cAAc,OAAO,QAAQ;AAAA,EACtF,CAAC;AACD,QAAM,YAAY,MAAM,SAAS;AACjC,QAAM,WAAW,MAAM,SAAS;AAChC,QAAM,cACJ,MAAM,SAAS,oBAAoB,MAAM,SAAS,mBAAmB,MAAM;AAC7E,QAAM,aAAa,OAAO,kBAAkB,QAAQ,MAAM,gCAAgC;AAC1F,QAAM,wBAAwB,cAAc;AAAA,IAC1C,CAAC,WAAW,OAAO,KAAK,KAAK,KAAK,OAAO,MAAM,KAAK;AAAA,EACtD;AACA,QAAM,4BAA4B,qBAAqB,iBAAiB;AACxE,QAAM,YAAY,mBAAmB,SAAS,aAAa,WAAW;AACtE,QAAM,SACJ,QAAQ,KAAK,KACb,aACA,yBACA,6BACA,CAAC,YACD,CAAC;AAGH,QAAM,aAAa,MAAM,SAAS,WAAW,MAAM,UAAU,OAAO,MAAM,QAAQ;AAClF,QAAM,aAAa,MAAM,SAAS,WAAW,MAAM,UAAU,OAAO,MAAM,QAAQ;AAIlF,QAAM,cAAc,YAAY,YAAY;AAC1C,aAAS,EAAE,MAAM,cAAc,CAAC;AAChC,UAAM,EAAE,SAAS,YAAY,IAAI,yBAAyB,iBAAiB;AAC3E,UAAM,OAAO,MAAM,QAAQ;AAAA,MACzB,QAAQ,EAAE,QAAQ;AAAA,MAClB,SAAS;AAAA,QACP,UAAU,MAAM,IAAI,KAAK;AAAA,QACzB,GAAI,OAAO,KAAK,OAAO,EAAE,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,QACrD,GAAI,OAAO,KAAK,WAAW,EAAE,SAAS,IAAI,EAAE,YAAY,IAAI,CAAC;AAAA,MAC/D;AAAA,IACF,CAAC;AACD,QAAS,eAAU,IAAI,GAAG;AACxB,eAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,qBAAqB,MAAM,mBAAmB;AAAA,MACvD,CAAC;AACD;AAAA,IACF;AACA,sBAAkB,KAAK,MAAM,gBAAgB,WAAW,MAAM;AAC9D,aAAS,EAAE,MAAM,YAAY,OAAO,KAAK,MAAM,CAAC;AAAA,EAClD,GAAG,CAAC,MAAM,KAAK,SAAS,SAAS,iBAAiB,CAAC;AAInD,QAAM,iBAAiB,OAAO,WAAW;AACzC,iBAAe,UAAU;AAIzB,YAAU,MAAM;AACd,QAAI,cAAc,SAAU;AAC5B,QAAI,MAAM,SAAS,MAAO;AAC1B,UAAM,UAAU,MAAM,IAAI,KAAK;AAC/B,QAAI,CAAC,QAAS;AACd,UAAM,SAAS,WAAW,MAAM;AAC9B,qBAAe,QAAQ;AAAA,IACzB,GAAG,GAAG;AACN,WAAO,MAAM,aAAa,MAAM;AAAA,EAClC,GAAG,CAAC,WAAW,MAAM,MAAM,MAAM,GAAG,CAAC;AAErC,QAAM,gCAAgC,YAAY,CAAC,SAAmC;AACpF,yBAAqB,IAAI;AAAA,EAC3B,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc,YAAY,YAAY;AAC1C,aAAS,EAAE,MAAM,cAAc,CAAC;AAChC,UAAM,gBACJ,iBAAiB,eAAe,SAAS,KACzC,iBAAiB,OAAO,aAAa,EAAE,KACvC;AACF,UAAM,EAAE,SAAS,YAAY,IAAI,yBAAyB,iBAAiB;AAC3E,UAAM,MAAM,MAAM;AAAA,MAChB,SAAS;AAAA,QACP,UAAU,MAAM,IAAI,KAAK;AAAA,QACzB,GAAI,OAAO,KAAK,OAAO,EAAE,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,QACrD,GAAI,OAAO,KAAK,WAAW,EAAE,SAAS,IAAI,EAAE,YAAY,IAAI,CAAC;AAAA,QAC7D,aAAa,iBAAiB;AAAA,QAC9B,cAAc,kBAAkB;AAAA,UAC9B,UAAU;AAAA,UACV,WAAW;AAAA,QACb,CAAC;AAAA,QACD,YAAY;AAAA,QACZ,UAAU,EAAE,MAAM,cAAc;AAAA,QAChC,UAAU;AAAA,QACV,eAAe,GAAG,eAAe,KAAK,KAAK,KAAK,OAAO,cAAc,OAAO,QAAQ,KAAK;AAAA,MAC3F;AAAA,MACA,WAAW,CAAC,WAAW;AACrB,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,cAAc,OAAO;AAAA,YACrB,WAAW,OAAO;AAAA,YAClB,OAAO,OAAO;AAAA,UAChB;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MACA,wBAAwB,CAAC,WACvB,SAAS,EAAE,MAAM,iBAAiB,WAAW,OAAO,UAAU,CAAC;AAAA,MACjE,SAAS,CAAC,UAAU,SAAS,EAAE,MAAM,cAAc,MAAM,CAAC;AAAA,IAC5D,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,KAAK,gBAAgB,OAAO,mBAAmB,OAAO,0BAA0B,CAAC;AAE3F,QAAM,oBAAoB,YAAY,MAAM;AAC1C,UAAM,OAAO;AACb,aAAS,EAAE,MAAM,kBAAkB,CAAC;AAAA,EACtC,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,kBAAkB,YAAY,YAAY;AAC9C,QAAI,CAAC,MAAO;AACZ,aAAS,EAAE,MAAM,YAAY,CAAC;AAC9B,UAAM,OACJ,mBAAmB,WACf,SACE;AAAA,MACE,MAAM;AAAA,MACN,cAAc,OAAO;AAAA,IACvB,IACA;AAAA,MACE,MAAM;AAAA,MACN,gBAAgB;AAAA,IAClB,IACF,EAAE,MAAM,OAAgB;AAC9B,UAAM,UAAU,OAAO;AAAA,MACrB,cACG,IAAI,CAAC,WAAW,CAAC,OAAO,KAAK,KAAK,GAAG,OAAO,MAAM,KAAK,CAAC,CAAU,EAClE,OAAO,CAAC,CAAC,MAAMA,MAAK,MAAM,QAAQA,MAAK;AAAA,IAC5C;AACA,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,IACF;AACA,UAAM,uBAA2D;AAAA,MAC/D,GAAG;AAAA,MACH,GAAG,YAAY;AAAA,IACjB;AACA,UAAM,cAAc,eAAe,KAAK,KAAK,KAAK,MAAM,cAAc,MAAM;AAC5E,UAAM,gBAAgB,iBAAiB,eAAe,SAAS;AAC/D,UAAM,OAAO,MAAM,MAAM;AAAA,MACvB,QAAQ,EAAE,QAAQ;AAAA,MAClB,SAAS;AAAA,QACP,aAAa;AAAA,QACb,WAAW;AAAA,QACX,MAAM;AAAA,QACN,WAAW,iBAAiB;AAAA,QAC5B,UAAU,MAAM,IAAI,KAAK;AAAA,QACzB;AAAA,QACA,uBACE,mBAAmB,YAAY,SAC3B,6BACA;AAAA,QACN,GAAI,OAAO,KAAK,oBAAoB,EAAE,SAAS,IAAI,EAAE,SAAS,qBAAqB,IAAI,CAAC;AAAA,QACxF,GAAI,OAAO,KAAK,YAAY,WAAW,EAAE,SAAS,IAC9C,EAAE,aAAa,YAAY,YAAY,IACvC,CAAC;AAAA,MACP;AAAA,MACA,gBAAgB;AAAA,IAClB,CAAC;AACD,QAAS,eAAU,IAAI,GAAG;AACxB,eAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO,qBAAqB,MAAM,sBAAsB;AAAA,MAC1D,CAAC;AACD;AAAA,IACF;AACA,UAAM,WAAW;AAAA,EACnB,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAID,QAAM,iBAAiB,CAAC,QAA0B;AAChD,QAAI,CAAC,IAAI,KAAK,EAAG,QAAO,CAAC;AACzB,UAAM,OAAiB,CAAC;AACxB,UAAM,QAAQ;AACd,QAAIC;AACJ,YAAQA,SAAQ,MAAM,KAAK,GAAG,OAAO,MAAM;AACzC,WAAK,KAAKA,OAAM,CAAC,KAAKA,OAAM,CAAC,CAAC;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,CAAC,QAAoD;AACzE,QAAI,CAAC,IAAI,KAAK,EAAG,QAAO;AACxB,UAAM,MAA8B,CAAC;AACrC,eAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC,YAAM,KAAK,KAAK,QAAQ,GAAG;AAC3B,UAAI,KAAK,GAAG;AACV,YAAI,KAAK,MAAM,GAAG,EAAE,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,KAAK,CAAC,EAAE,KAAK;AAAA,MAC1D;AAAA,IACF;AACA,WAAO,OAAO,KAAK,GAAG,EAAE,SAAS,IAAI,MAAM;AAAA,EAC7C;AAEA,QAAM,iBAAiB,YAAY,YAAY;AAC7C,UAAM,MAAM,aAAa,KAAK;AAC9B,QAAI,CAAC,IAAK;AACV,mBAAe,IAAI;AACnB,kBAAc,IAAI;AAClB,UAAM,cAAc,cAAc,KAAK,KAAK,KAAK;AACjD,UAAM,gBAAgB,iBAAiB,cAAc,SAAS;AAC9D,UAAM,OAAO,MAAM,MAAM;AAAA,MACvB,QAAQ,EAAE,QAAQ;AAAA,MAClB,SAAS;AAAA,QACP,aAAa;AAAA,QACb,WAAW;AAAA,QACX,MAAM;AAAA,QACN,WAAW,iBAAiB;AAAA,QAC5B,SAAS;AAAA,QACT,MAAM,eAAe,SAAS;AAAA,QAC9B,KAAK,cAAc,QAAQ;AAAA,MAC7B;AAAA,MACA,gBAAgB;AAAA,IAClB,CAAC;AACD,QAAS,eAAU,IAAI,GAAG;AACxB,oBAAc,qBAAqB,MAAM,sBAAsB,CAAC;AAChE,qBAAe,KAAK;AACpB;AAAA,IACF;AACA,UAAM,WAAW;AAAA,EACnB,GAAG,CAAC,cAAc,WAAW,UAAU,eAAe,OAAO,SAAS,KAAK,CAAC;AAI5E,SACE,qBAAC,SAAI,WAAU,8BACb;AAAA,yBAAC,SACC;AAAA,0BAAC,QAAG,WAAU,yCAAwC,4BAAc;AAAA,MACpE,oBAAC,OAAE,WAAU,0CAAyC,qEAEtD;AAAA,OACF;AAAA,IAGC,cACC,qBAAC,SAAI,WAAU,8DACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,SAAS,MAAM,aAAa,QAAQ;AAAA,UACpC,WAAW,uEACT,cAAc,WACV,4CACA,6CACN;AAAA,UACD;AAAA;AAAA,MAED;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,SAAS,MAAM,aAAa,OAAO;AAAA,UACnC,WAAW,uEACT,cAAc,UACV,4CACA,6CACN;AAAA,UACD;AAAA;AAAA,MAED;AAAA,OACF;AAAA,IAGD,cAAc,WACb,iCACE;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,KAAK,MAAM;AAAA,UACX,aAAa,CAAC,QAAQ,SAAS,EAAE,MAAM,WAAW,IAAI,CAAC;AAAA,UACvD,UAAU;AAAA,UACV,SAAS;AAAA,UACT,SAAS;AAAA,UACT,OAAO;AAAA,UACP,SAAS;AAAA;AAAA,MACX;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,aAAa;AAAA,UACb,UAAU;AAAA,UACV,iBAAiB;AAAA,UACjB,YAAY,eAAe;AAAA,UAC3B,aAAa;AAAA,UACb;AAAA,UACA,qBAAqB;AAAA,UACrB,QAAQ;AAAA,YACN,SAAS;AAAA,YACT,aAAa;AAAA,UACf;AAAA;AAAA,MACF;AAAA,MAGC,SACC,qBAAC,aAAQ,WAAU,eACjB;AAAA,6BAAC,SAAI,WAAU,2CACb;AAAA,8BAAC,cAAW,4BAAc;AAAA,UAC1B;AAAA,YAAC;AAAA;AAAA,cACC,MACE,MAAM,iBAAiB,MAAM,8BACzB,CAAC,EAAE,OAAO,UAAU,OAAO,QAAQ,CAAC,IACpC;AAAA,gBACE,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,gBAC/B,EAAE,OAAO,UAAU,OAAO,QAAQ;AAAA,cACpC;AAAA,cAEN,OAAO;AAAA,cACP,UAAU;AAAA;AAAA,UACZ;AAAA,WACF;AAAA,QAEC,mBAAmB,YAClB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,SAAS;AAAA,YACT,UAAU,CAAC,gBAAgB;AACzB,4CAA8B,WAAW;AACzC,uBAAS,EAAE,MAAM,cAAc,CAAC;AAAA,YAClC;AAAA,YACA,OAAM;AAAA,YACN,MAAK;AAAA,YAEL;AAAA,cAAC;AAAA;AAAA,gBACC,OAAM;AAAA,gBACN,MAAK;AAAA,gBAEJ;AAAA,mBAAC,UACA,MAAM,SAAS,aACd,MAAM,8BACL;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,SAAS;AAAA,sBACT,SAAQ;AAAA,sBACR,WAAU;AAAA,sBACX;AAAA;AAAA,kBAED,IAEA,oBAAC,SAAI,WAAU,uFAAsF,gOAIrG;AAAA,kBAGH,CAAC,UAAU,MAAM,SAAS,oBACzB,qBAAC,SAAI,WAAU,yFACb;AAAA,wCAAC,WAAQ,WAAU,YAAW;AAAA,oBAC9B,oBAAC,UAAK,WAAU,iCAAgC,uCAEhD;AAAA,qBACF;AAAA,kBAGD,CAAC,UAAU,MAAM,SAAS,mBACzB,qBAAC,SAAI,WAAU,gGACb;AAAA,wCAAC,WAAQ,WAAU,0BAAyB;AAAA,oBAC5C,oBAAC,UAAK,WAAU,4CAA2C,0CAE3D;AAAA,oBACA;AAAA,sBAAC;AAAA;AAAA,wBACC,MAAK;AAAA,wBACL,SAAQ;AAAA,wBACR,MAAK;AAAA,wBACL,SAAS;AAAA,wBACT,WAAU;AAAA,wBACX;AAAA;AAAA,oBAED;AAAA,qBACF;AAAA,kBAGD,UACC,qBAAC,SAAI,WAAU,sGACb;AAAA,wCAAC,SAAI,SAAQ,aAAY,MAAK,QAAO,WAAU,6BAC7C;AAAA,sBAAC;AAAA;AAAA,wBACC,GAAE;AAAA,wBACF,QAAO;AAAA,wBACP,aAAY;AAAA,wBACZ,eAAc;AAAA,wBACd,gBAAe;AAAA;AAAA,oBACjB,GACF;AAAA,oBACA,oBAAC,UAAK,WAAU,8DAA6D,2BAE7E;AAAA,qBACF;AAAA;AAAA;AAAA,YAEJ;AAAA;AAAA,QACF;AAAA,SAEJ;AAAA,MAID,SACC,qBAAC,aAAQ,WAAU,eACjB;AAAA,6BAAC,SACC;AAAA,8BAAC,SAAM,gCAAkB;AAAA,UACzB,oBAAC,OAAE,WAAU,0CAAyC,4GAGtD;AAAA,WACF;AAAA,QAEA,oBAAC,aACC,8BAAC,oBACE,wBAAc,WAAW,IACxB;AAAA,UAAC;AAAA;AAAA,YACC,SAAS,oBAAC,UAAK,wBAAU;AAAA,YACzB,SAAS,MACP,iBAAiB,CAAC,YAAY,CAAC,GAAG,SAAS,EAAE,MAAM,IAAI,OAAO,GAAG,CAAC,CAAC;AAAA;AAAA,QAEvE,IAEA,iCACG;AAAA,wBAAc,IAAI,CAAC,QAAQ,UAC1B,qBAAC,kBAA2B,WAAU,gCACpC;AAAA,iCAAC,SAAI,WAAU,qCACb;AAAA,kCAAC,SAAM,WAAU,8DAA6D,oBAE9E;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,SAAS,MACP;AAAA,oBAAiB,CAAC,YAChB,QAAQ,OAAO,CAAC,GAAG,gBAAgB,gBAAgB,KAAK;AAAA,kBAC1D;AAAA,kBAEH;AAAA;AAAA,cAED;AAAA,eACF;AAAA,YACA,qBAAC,SAAI,WAAU,0BACb;AAAA,mCAAC,SAAI,WAAU,aACb;AAAA,oCAAC,SAAM,WAAU,8DAA6D,kBAE9E;AAAA,gBACA;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO,OAAO;AAAA,oBACd,UAAU,CAAC,UACT;AAAA,sBAAiB,CAAC,YAChB,QAAQ;AAAA,wBAAI,CAAC,SAAS,gBACpB,gBAAgB,QACZ;AAAA,0BACE,GAAG;AAAA,0BACH,MAAO,MAAM,OAA4B;AAAA,wBAC3C,IACA;AAAA,sBACN;AAAA,oBACF;AAAA,oBAEF,aAAY;AAAA,oBACZ,WAAU;AAAA;AAAA,gBACZ;AAAA,iBACF;AAAA,cACA,qBAAC,SAAI,WAAU,aACb;AAAA,oCAAC,SAAM,WAAU,8DAA6D,mBAE9E;AAAA,gBACA;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO,OAAO;AAAA,oBACd,UAAU,CAAC,UACT;AAAA,sBAAiB,CAAC,YAChB,QAAQ;AAAA,wBAAI,CAAC,SAAS,gBACpB,gBAAgB,QACZ;AAAA,0BACE,GAAG;AAAA,0BACH,OAAQ,MAAM,OAA4B;AAAA,wBAC5C,IACA;AAAA,sBACN;AAAA,oBACF;AAAA,oBAEF,aAAY;AAAA,oBACZ,WAAU;AAAA;AAAA,gBACZ;AAAA,iBACF;AAAA,eACF;AAAA,eAhEmB,KAiErB,CACD;AAAA,UACD;AAAA,YAAC;AAAA;AAAA,cACC,SAAS,MACP,iBAAiB,CAAC,YAAY,CAAC,GAAG,SAAS,EAAE,MAAM,IAAI,OAAO,GAAG,CAAC,CAAC;AAAA;AAAA,UAEvE;AAAA,WACF,GAEJ,GACF;AAAA,SACF;AAAA,MAID,cACC,qBAAC,SAAI,WAAU,aACb;AAAA,4BAAC,SAAI,WAAU,sEACb,8BAAC,OAAE,WAAU,gCAAgC,sBAAW,GAC1D;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAM,SAAS,EAAE,MAAM,QAAQ,CAAC;AAAA,YACzC,WAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,SACF;AAAA,MAGF,qBAAC,gBACC;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,SAAS,MAAM;AACb,oBAAM,OAAO;AACb,oBAAM,SAAS;AAAA,YACjB;AAAA,YACA,UAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,SACE,SAAS,cACT,oBAAC,UAAO,MAAK,UAAS,SAAS,iBAAiB,UAAU,CAAC,QACxD,qBACC,iCACE;AAAA,8BAAC,WAAQ,WAAU,YAAW;AAAA,UAAE;AAAA,WAClC,IAEA,cAEJ;AAAA,SAEJ;AAAA,OACF,IAEA,iCAEE;AAAA,0BAAC,aACC,+BAAC,oBAAiB,WAAU,cAC1B;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,aAAY;AAAA,YAEZ;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,gBAAiB,EAAE,OAA4B,KAAK;AAAA,gBACrE,aAAY;AAAA,gBACZ,WAAU;AAAA;AAAA,YACZ;AAAA;AAAA,QACF;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,aAAY;AAAA,YAEZ;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,aAAc,EAAE,OAA4B,KAAK;AAAA,gBAClE,aAAY;AAAA,gBACZ,WAAU;AAAA;AAAA,YACZ;AAAA;AAAA,QACF;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,aAAY;AAAA,YAEZ;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,YAAa,EAAE,OAA+B,KAAK;AAAA,gBACpE,aAAa;AAAA,gBACb,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,WAAU;AAAA;AAAA,YACZ;AAAA;AAAA,QACF;AAAA,SACF,GACF;AAAA,MAEA,oBAAC,wBAAqB,UAAU,eAAe,iBAAgB,iBAAgB;AAAA,MAG9E,cACC,oBAAC,SAAI,WAAU,sEACb,8BAAC,OAAE,WAAU,gCAAgC,sBAAW,GAC1D;AAAA,MAGF,qBAAC,gBACC;AAAA,4BAAC,UAAO,MAAK,UAAS,SAAQ,SAAQ,SAAS,MAAM,UAAU,UAAU,aAAa,oBAEtF;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS;AAAA,YACT,UAAU,CAAC,aAAa,KAAK,KAAK;AAAA,YAEjC,wBACC,iCACE;AAAA,kCAAC,WAAQ,WAAU,YAAW;AAAA,cAAE;AAAA,eAClC,IAEA;AAAA;AAAA,QAEJ;AAAA,SACF;AAAA,OACF;AAAA,KAEJ;AAEJ;AAEA,SAAS,kBAAkB;AAAA,EACzB;AAAA,EACA;AACF,GAGG;AACD;AAAA;AAAA,IAEE;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,CAAC,UAAU;AAClB,gBAAM,gBAAgB;AACtB,kBAAQ;AAAA,QACV;AAAA,QACA,cAAW;AAAA,QACX,WAAU;AAAA,QAEV;AAAA,8BAAC,UAAK,WAAU,4BAA4B,mBAAQ;AAAA,UACpD,oBAAC,SAAI,eAAW,MAAC,SAAQ,aAAY,MAAK,QAAO,WAAU,mBACzD,8BAAC,UAAK,GAAE,oBAAmB,QAAO,gBAAe,aAAY,OAAM,eAAc,SAAQ,GAC3F;AAAA;AAAA;AAAA,IACF;AAAA;AAEJ;","names":["value","match"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/react/EditMcpSource.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { useAtomValue, useAtomSet } from \"@effect/atom-react\";\nimport * as AsyncResult from \"effect/unstable/reactivity/AsyncResult\";\nimport * as Exit from \"effect/Exit\";\nimport {\n mcpSourceAtom,\n mcpSourceBindingsAtom,\n setMcpSourceBinding,\n updateMcpSource,\n} from \"./atoms\";\nimport { connectionsAtom } from \"@executor-js/react/api/atoms\";\nimport { useScope, useScopeStack } from \"@executor-js/react/api/scope-context\";\nimport { connectionWriteKeys, sourceWriteKeys } from \"@executor-js/react/api/reactivity-keys\";\nimport { slugifyNamespace, useSourceIdentity } from \"@executor-js/react/plugins/source-identity\";\nimport { useCredentialTargetScope } from \"@executor-js/react/plugins/credential-target-scope\";\nimport { useSecretPickerSecrets } from \"@executor-js/react/plugins/use-secret-picker-secrets\";\nimport {\n HttpCredentialsEditor,\n serializeHttpCredentials,\n serializeScopedHttpCredentials,\n type HttpCredentialsState,\n} from \"@executor-js/react/plugins/http-credentials\";\nimport {\n effectiveCredentialBindingForScope,\n httpCredentialsFromConfiguredCredentialBindings,\n initialCredentialTargetScope,\n} from \"@executor-js/react/plugins/credential-bindings\";\nimport { SourceOAuthConnectionControl } from \"@executor-js/react/plugins/source-oauth-connection\";\nimport { Button } from \"@executor-js/react/components/button\";\nimport { Badge } from \"@executor-js/react/components/badge\";\nimport { ScopeId } from \"@executor-js/sdk/core\";\nimport { McpRemoteSourceFields } from \"./McpRemoteSourceFields\";\nimport {\n McpSourceBindingInput,\n type McpCredentialInput,\n type McpSourceBindingRef,\n} from \"../sdk/types\";\nimport type { McpStoredSourceSchemaType } from \"../sdk/stored-source\";\n\n// ---------------------------------------------------------------------------\n// Remote edit form\n// ---------------------------------------------------------------------------\n\nfunction RemoteEditForm(props: {\n sourceId: string;\n initial: McpStoredSourceSchemaType & { config: { transport: \"remote\" } };\n bindings: readonly McpSourceBindingRef[];\n onSave: () => void;\n}) {\n const displayScope = useScope();\n const scopeStack = useScopeStack();\n const sourceScope = ScopeId.make(props.initial.scope);\n const { credentialTargetScope, credentialScopeOptions } = useCredentialTargetScope({\n sourceScope,\n initialTargetScope: initialCredentialTargetScope(sourceScope, props.bindings),\n });\n const {\n credentialTargetScope: oauthCredentialTargetScope,\n setCredentialTargetScope: setOAuthCredentialTargetScope,\n } = useCredentialTargetScope({\n sourceScope,\n initialTargetScope: initialCredentialTargetScope(sourceScope, props.bindings),\n });\n const doUpdate = useAtomSet(updateMcpSource, { mode: \"promiseExit\" });\n const setBinding = useAtomSet(setMcpSourceBinding, { mode: \"promise\" });\n const secretList = useSecretPickerSecrets();\n const connectionsResult = useAtomValue(connectionsAtom(displayScope));\n\n const identity = useSourceIdentity({\n fallbackName: props.initial.name,\n fallbackNamespace: props.initial.namespace,\n });\n const [endpoint, setEndpoint] = useState(props.initial.config.endpoint);\n const [credentials, setCredentials] = useState<HttpCredentialsState>(() =>\n httpCredentialsFromConfiguredCredentialBindings({\n headers: props.initial.config.headers,\n queryParams: props.initial.config.queryParams,\n bindings: props.bindings,\n }),\n );\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [credentialsDirty, setCredentialsDirty] = useState(false);\n\n const identityDirty = identity.name.trim() !== props.initial.name.trim();\n const metadataDirty = identityDirty || endpoint.trim() !== props.initial.config.endpoint.trim();\n const dirty = metadataDirty || credentialsDirty;\n const oauth2 = props.initial.config.auth.kind === \"oauth2\" ? props.initial.config.auth : null;\n const connections = AsyncResult.isSuccess(connectionsResult) ? connectionsResult.value : [];\n const scopeRanks = new Map(scopeStack.map((scope, index) => [scope.id, index] as const));\n const connectionBinding = oauth2\n ? effectiveCredentialBindingForScope(\n props.bindings,\n oauth2.connectionSlot,\n oauthCredentialTargetScope,\n scopeRanks,\n )\n : null;\n const boundConnectionId =\n connectionBinding?.value.kind === \"connection\" ? connectionBinding.value.connectionId : null;\n const isConnected =\n boundConnectionId !== null &&\n connections.some((connection) => connection.id === boundConnectionId);\n const oauthRequestCredentials = serializeHttpCredentials(credentials);\n\n const handleCredentialsChange = (next: HttpCredentialsState) => {\n setCredentials(next);\n setCredentialsDirty(true);\n };\n\n const handleSave = async () => {\n setSaving(true);\n setError(null);\n const { headers, queryParams } = serializeScopedHttpCredentials(\n credentials,\n credentialTargetScope,\n );\n const payload: {\n sourceScope: ScopeId;\n name?: string;\n endpoint?: string;\n headers?: Record<string, McpCredentialInput>;\n queryParams?: Record<string, McpCredentialInput>;\n credentialTargetScope?: ScopeId;\n } = {\n sourceScope,\n name: metadataDirty ? identity.name.trim() || undefined : undefined,\n endpoint: metadataDirty ? endpoint.trim() || undefined : undefined,\n };\n if (credentialsDirty) {\n payload.headers = headers;\n payload.queryParams = queryParams as Record<string, McpCredentialInput>;\n payload.credentialTargetScope = credentialTargetScope;\n }\n const exit = await doUpdate({\n params: { scopeId: displayScope, namespace: props.sourceId },\n payload,\n reactivityKeys: sourceWriteKeys,\n });\n if (Exit.isFailure(exit)) {\n setError(\"Failed to update source\");\n setSaving(false);\n return;\n }\n setCredentialsDirty(false);\n setSaving(false);\n props.onSave();\n };\n\n return (\n <div className=\"space-y-6\">\n <div>\n <h1 className=\"text-xl font-semibold text-foreground\">Edit MCP Source</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n Update the endpoint and headers for this MCP connection.\n </p>\n </div>\n\n <div className=\"flex items-center gap-3 rounded-lg border border-border bg-card px-4 py-3\">\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-semibold text-card-foreground\">{props.sourceId}</p>\n </div>\n <Badge variant=\"secondary\" className=\"text-xs\">\n remote\n </Badge>\n </div>\n\n <McpRemoteSourceFields\n url={endpoint}\n onUrlChange={setEndpoint}\n identity={identity}\n preview={{\n name: props.initial.name,\n serverName: props.initial.name,\n connected: true,\n toolCount: null,\n }}\n namespaceReadOnly\n />\n\n <HttpCredentialsEditor\n credentials={credentials}\n onChange={handleCredentialsChange}\n existingSecrets={secretList}\n sourceName={identity.name}\n targetScope={credentialTargetScope}\n credentialScopeOptions={credentialScopeOptions}\n bindingScopeOptions={credentialScopeOptions}\n />\n\n {oauth2 && (\n <SourceOAuthConnectionControl\n popupName=\"mcp-oauth\"\n pluginId=\"mcp\"\n namespace={slugifyNamespace(props.initial.namespace) || \"mcp\"}\n fallbackNamespace=\"mcp\"\n endpoint={endpoint.trim()}\n tokenScope={oauthCredentialTargetScope}\n onTokenScopeChange={setOAuthCredentialTargetScope}\n credentialScopeOptions={credentialScopeOptions}\n connectionId={boundConnectionId}\n sourceLabel={`${identity.name.trim() || props.initial.namespace || \"MCP\"} OAuth`}\n headers={oauthRequestCredentials.headers}\n queryParams={oauthRequestCredentials.queryParams}\n isConnected={isConnected}\n onConnected={async (connectionId) => {\n await setBinding({\n params: { scopeId: oauthCredentialTargetScope },\n payload: McpSourceBindingInput.make({\n sourceId: props.sourceId,\n sourceScope,\n scope: oauthCredentialTargetScope,\n slot: oauth2.connectionSlot,\n value: { kind: \"connection\", connectionId },\n }),\n reactivityKeys: [...sourceWriteKeys, ...connectionWriteKeys],\n });\n }}\n reconnectingLabel=\"Reconnecting…\"\n signingInLabel=\"Signing in…\"\n />\n )}\n\n {error && (\n <div className=\"rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2\">\n <p className=\"text-sm text-destructive\">{error}</p>\n </div>\n )}\n\n <div className=\"flex items-center justify-between border-t border-border pt-4\">\n <Button variant=\"ghost\" onClick={props.onSave}>\n Cancel\n </Button>\n <Button onClick={handleSave} disabled={!dirty || saving}>\n {saving ? \"Saving…\" : \"Save changes\"}\n </Button>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Stdio read-only view\n// ---------------------------------------------------------------------------\n\nfunction StdioReadOnly(props: {\n sourceId: string;\n initial: McpStoredSourceSchemaType & { config: { transport: \"stdio\" } };\n onSave: () => void;\n}) {\n const { command, args } = props.initial.config;\n return (\n <div className=\"space-y-6\">\n <div>\n <h1 className=\"text-xl font-semibold text-foreground\">Edit MCP Source</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n Stdio MCP sources cannot be edited in the UI. Remove and recreate the source with the\n updated command.\n </p>\n </div>\n\n <div className=\"flex items-center gap-3 rounded-lg border border-border bg-card px-4 py-3\">\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-semibold text-card-foreground\">{props.sourceId}</p>\n <p className=\"mt-0.5 text-xs text-muted-foreground font-mono\">\n {command} {(args ?? []).join(\" \")}\n </p>\n </div>\n <Badge variant=\"secondary\" className=\"text-xs\">\n stdio\n </Badge>\n </div>\n\n <div className=\"flex items-center justify-end border-t border-border pt-4\">\n <Button onClick={props.onSave}>Done</Button>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\nexport default function EditMcpSource({\n sourceId,\n onSave,\n}: {\n readonly sourceId: string;\n readonly onSave: () => void;\n}) {\n const scopeId = useScope();\n const sourceResult = useAtomValue(mcpSourceAtom(scopeId, sourceId)) as AsyncResult.AsyncResult<\n McpStoredSourceSchemaType | null,\n unknown\n >;\n const source =\n AsyncResult.isSuccess(sourceResult) && sourceResult.value ? sourceResult.value : null;\n const sourceScope = source ? ScopeId.make(source.scope) : scopeId;\n const bindingsResult = useAtomValue(mcpSourceBindingsAtom(scopeId, sourceId, sourceScope));\n\n if (!AsyncResult.isSuccess(sourceResult) || !source || !AsyncResult.isSuccess(bindingsResult)) {\n return (\n <div className=\"space-y-6\">\n <div>\n <h1 className=\"text-xl font-semibold text-foreground\">Edit MCP Source</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">Loading configuration…</p>\n </div>\n </div>\n );\n }\n\n if (source.config.transport === \"stdio\") {\n return (\n <StdioReadOnly\n sourceId={sourceId}\n initial={source as McpStoredSourceSchemaType & { config: { transport: \"stdio\" } }}\n onSave={onSave}\n />\n );\n }\n\n return (\n <RemoteEditForm\n sourceId={sourceId}\n initial={source as McpStoredSourceSchemaType & { config: { transport: \"remote\" } }}\n bindings={bindingsResult.value}\n onSave={onSave}\n />\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,85 +0,0 @@
1
- import {
2
- mcpSourceAtom,
3
- mcpSourceBindingsAtom
4
- } from "./chunk-4ORPFRLI.js";
5
- import "./chunk-M6REVU6O.js";
6
-
7
- // src/react/McpSourceSummary.tsx
8
- import { useAtomValue } from "@effect/atom-react";
9
- import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
10
- import { connectionsAtom } from "@executor-js/react/api/atoms";
11
- import { useScope, useScopeStack, useUserScope } from "@executor-js/react/api/scope-context";
12
- import {
13
- SourceCredentialNotice,
14
- SourceCredentialStatusBadge,
15
- missingSourceCredentialLabels
16
- } from "@executor-js/react/plugins/source-credential-status";
17
- import { ScopeId } from "@executor-js/sdk/core";
18
- import { jsx } from "react/jsx-runtime";
19
- var sourceCredentialSlots = (source) => {
20
- if (source.config.transport !== "remote") return [];
21
- const slots = [];
22
- for (const [name, value] of Object.entries(source.config.headers ?? {})) {
23
- if (typeof value !== "string") slots.push({ kind: "secret", slot: value.slot, label: name });
24
- }
25
- for (const [name, value] of Object.entries(source.config.queryParams ?? {})) {
26
- if (typeof value !== "string") slots.push({ kind: "secret", slot: value.slot, label: name });
27
- }
28
- const auth = source.config.auth;
29
- if (auth.kind === "header") {
30
- slots.push({
31
- kind: "secret",
32
- slot: auth.secretSlot,
33
- label: auth.headerName
34
- });
35
- }
36
- if (auth.kind === "oauth2") {
37
- if (auth.clientIdSlot) {
38
- slots.push({ kind: "secret", slot: auth.clientIdSlot, label: "Client ID" });
39
- }
40
- if (auth.clientSecretSlot) {
41
- slots.push({ kind: "secret", slot: auth.clientSecretSlot, label: "Client Secret" });
42
- }
43
- slots.push({
44
- kind: "connection",
45
- slot: auth.connectionSlot,
46
- label: "OAuth sign-in"
47
- });
48
- }
49
- return slots;
50
- };
51
- function McpSourceSummary(props) {
52
- const displayScope = useScope();
53
- const userScope = useUserScope();
54
- const scopeStack = useScopeStack();
55
- const sourceResult = useAtomValue(mcpSourceAtom(displayScope, props.sourceId));
56
- const source = AsyncResult.isSuccess(sourceResult) && sourceResult.value ? sourceResult.value : null;
57
- const sourceScope = source ? ScopeId.make(source.scope) : displayScope;
58
- const bindingsResult = useAtomValue(
59
- mcpSourceBindingsAtom(displayScope, props.sourceId, sourceScope)
60
- );
61
- const connectionsResult = useAtomValue(connectionsAtom(displayScope));
62
- if (!source) return null;
63
- const slots = sourceCredentialSlots(source);
64
- if (slots.length === 0) return null;
65
- if (!AsyncResult.isSuccess(bindingsResult) || !AsyncResult.isSuccess(connectionsResult)) {
66
- return props.variant === "panel" ? null : /* @__PURE__ */ jsx(SourceCredentialStatusBadge, { missing: ["credentials"] });
67
- }
68
- const scopeRanks = new Map(scopeStack.map((scope, index) => [scope.id, index]));
69
- const liveConnectionIds = new Set(connectionsResult.value.map((connection) => connection.id));
70
- const missing = missingSourceCredentialLabels({
71
- slots,
72
- bindings: bindingsResult.value,
73
- targetScope: userScope,
74
- scopeRanks,
75
- liveConnectionIds
76
- });
77
- if (props.variant === "panel") {
78
- return /* @__PURE__ */ jsx(SourceCredentialNotice, { missing, onAction: props.onAction });
79
- }
80
- return /* @__PURE__ */ jsx(SourceCredentialStatusBadge, { missing });
81
- }
82
- export {
83
- McpSourceSummary as default
84
- };
85
- //# sourceMappingURL=McpSourceSummary-257JNETP.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/react/McpSourceSummary.tsx"],"sourcesContent":["import { useAtomValue } from \"@effect/atom-react\";\nimport * as AsyncResult from \"effect/unstable/reactivity/AsyncResult\";\n\nimport { connectionsAtom } from \"@executor-js/react/api/atoms\";\nimport { useScope, useScopeStack, useUserScope } from \"@executor-js/react/api/scope-context\";\nimport {\n SourceCredentialNotice,\n SourceCredentialStatusBadge,\n missingSourceCredentialLabels,\n type SourceCredentialSlot,\n} from \"@executor-js/react/plugins/source-credential-status\";\nimport { ScopeId } from \"@executor-js/sdk/core\";\n\nimport { mcpSourceAtom, mcpSourceBindingsAtom } from \"./atoms\";\nimport type { McpStoredSourceSchemaType } from \"../sdk/stored-source\";\n\nconst sourceCredentialSlots = (\n source: McpStoredSourceSchemaType,\n): readonly SourceCredentialSlot[] => {\n if (source.config.transport !== \"remote\") return [];\n const slots: SourceCredentialSlot[] = [];\n for (const [name, value] of Object.entries(source.config.headers ?? {})) {\n if (typeof value !== \"string\") slots.push({ kind: \"secret\", slot: value.slot, label: name });\n }\n for (const [name, value] of Object.entries(source.config.queryParams ?? {})) {\n if (typeof value !== \"string\") slots.push({ kind: \"secret\", slot: value.slot, label: name });\n }\n const auth = source.config.auth;\n if (auth.kind === \"header\") {\n slots.push({\n kind: \"secret\",\n slot: auth.secretSlot,\n label: auth.headerName,\n });\n }\n if (auth.kind === \"oauth2\") {\n if (auth.clientIdSlot) {\n slots.push({ kind: \"secret\", slot: auth.clientIdSlot, label: \"Client ID\" });\n }\n if (auth.clientSecretSlot) {\n slots.push({ kind: \"secret\", slot: auth.clientSecretSlot, label: \"Client Secret\" });\n }\n slots.push({\n kind: \"connection\",\n slot: auth.connectionSlot,\n label: \"OAuth sign-in\",\n });\n }\n return slots;\n};\n\nexport default function McpSourceSummary(props: {\n readonly sourceId: string;\n readonly variant?: \"badge\" | \"panel\";\n readonly onAction?: () => void;\n}) {\n const displayScope = useScope();\n const userScope = useUserScope();\n const scopeStack = useScopeStack();\n const sourceResult = useAtomValue(mcpSourceAtom(displayScope, props.sourceId));\n const source =\n AsyncResult.isSuccess(sourceResult) && sourceResult.value ? sourceResult.value : null;\n const sourceScope = source ? ScopeId.make(source.scope) : displayScope;\n const bindingsResult = useAtomValue(\n mcpSourceBindingsAtom(displayScope, props.sourceId, sourceScope),\n );\n const connectionsResult = useAtomValue(connectionsAtom(displayScope));\n\n if (!source) return null;\n const slots = sourceCredentialSlots(source as McpStoredSourceSchemaType);\n if (slots.length === 0) return null;\n if (!AsyncResult.isSuccess(bindingsResult) || !AsyncResult.isSuccess(connectionsResult)) {\n return props.variant === \"panel\" ? null : (\n <SourceCredentialStatusBadge missing={[\"credentials\"]} />\n );\n }\n\n const scopeRanks = new Map(scopeStack.map((scope, index) => [scope.id, index] as const));\n const liveConnectionIds = new Set(connectionsResult.value.map((connection) => connection.id));\n const missing = missingSourceCredentialLabels({\n slots,\n bindings: bindingsResult.value,\n targetScope: userScope,\n scopeRanks,\n liveConnectionIds,\n });\n\n if (props.variant === \"panel\") {\n return <SourceCredentialNotice missing={missing} onAction={props.onAction} />;\n }\n\n return <SourceCredentialStatusBadge missing={missing} />;\n}\n"],"mappings":";;;;;;;AAAA,SAAS,oBAAoB;AAC7B,YAAY,iBAAiB;AAE7B,SAAS,uBAAuB;AAChC,SAAS,UAAU,eAAe,oBAAoB;AACtD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,eAAe;AA8DlB;AAzDN,IAAM,wBAAwB,CAC5B,WACoC;AACpC,MAAI,OAAO,OAAO,cAAc,SAAU,QAAO,CAAC;AAClD,QAAM,QAAgC,CAAC;AACvC,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,OAAO,OAAO,WAAW,CAAC,CAAC,GAAG;AACvE,QAAI,OAAO,UAAU,SAAU,OAAM,KAAK,EAAE,MAAM,UAAU,MAAM,MAAM,MAAM,OAAO,KAAK,CAAC;AAAA,EAC7F;AACA,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,OAAO,OAAO,eAAe,CAAC,CAAC,GAAG;AAC3E,QAAI,OAAO,UAAU,SAAU,OAAM,KAAK,EAAE,MAAM,UAAU,MAAM,MAAM,MAAM,OAAO,KAAK,CAAC;AAAA,EAC7F;AACA,QAAM,OAAO,OAAO,OAAO;AAC3B,MAAI,KAAK,SAAS,UAAU;AAC1B,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,IACd,CAAC;AAAA,EACH;AACA,MAAI,KAAK,SAAS,UAAU;AAC1B,QAAI,KAAK,cAAc;AACrB,YAAM,KAAK,EAAE,MAAM,UAAU,MAAM,KAAK,cAAc,OAAO,YAAY,CAAC;AAAA,IAC5E;AACA,QAAI,KAAK,kBAAkB;AACzB,YAAM,KAAK,EAAE,MAAM,UAAU,MAAM,KAAK,kBAAkB,OAAO,gBAAgB,CAAC;AAAA,IACpF;AACA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,MACX,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEe,SAAR,iBAAkC,OAItC;AACD,QAAM,eAAe,SAAS;AAC9B,QAAM,YAAY,aAAa;AAC/B,QAAM,aAAa,cAAc;AACjC,QAAM,eAAe,aAAa,cAAc,cAAc,MAAM,QAAQ,CAAC;AAC7E,QAAM,SACQ,sBAAU,YAAY,KAAK,aAAa,QAAQ,aAAa,QAAQ;AACnF,QAAM,cAAc,SAAS,QAAQ,KAAK,OAAO,KAAK,IAAI;AAC1D,QAAM,iBAAiB;AAAA,IACrB,sBAAsB,cAAc,MAAM,UAAU,WAAW;AAAA,EACjE;AACA,QAAM,oBAAoB,aAAa,gBAAgB,YAAY,CAAC;AAEpE,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,QAAQ,sBAAsB,MAAmC;AACvE,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,CAAa,sBAAU,cAAc,KAAK,CAAa,sBAAU,iBAAiB,GAAG;AACvF,WAAO,MAAM,YAAY,UAAU,OACjC,oBAAC,+BAA4B,SAAS,CAAC,aAAa,GAAG;AAAA,EAE3D;AAEA,QAAM,aAAa,IAAI,IAAI,WAAW,IAAI,CAAC,OAAO,UAAU,CAAC,MAAM,IAAI,KAAK,CAAU,CAAC;AACvF,QAAM,oBAAoB,IAAI,IAAI,kBAAkB,MAAM,IAAI,CAAC,eAAe,WAAW,EAAE,CAAC;AAC5F,QAAM,UAAU,8BAA8B;AAAA,IAC5C;AAAA,IACA,UAAU,eAAe;AAAA,IACzB,aAAa;AAAA,IACb;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,MAAM,YAAY,SAAS;AAC7B,WAAO,oBAAC,0BAAuB,SAAkB,UAAU,MAAM,UAAU;AAAA,EAC7E;AAEA,SAAO,oBAAC,+BAA4B,SAAkB;AACxD;","names":[]}