@geminixiang/mikan 1.0.0-beta.7 → 1.0.0-beta.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1052 -0
- package/README.md +98 -38
- package/dist/adapters/commands/admin.d.ts.map +1 -0
- package/dist/{commands → adapters/commands}/admin.js +11 -8
- package/dist/adapters/commands/admin.js.map +1 -0
- package/dist/{commands → adapters/commands}/auto-reply.d.ts +0 -3
- package/dist/adapters/commands/auto-reply.d.ts.map +1 -0
- package/dist/adapters/commands/auto-reply.js +47 -0
- package/dist/adapters/commands/auto-reply.js.map +1 -0
- package/dist/adapters/commands/login.d.ts +6 -0
- package/dist/adapters/commands/login.d.ts.map +1 -0
- package/dist/adapters/commands/login.js +166 -0
- package/dist/adapters/commands/login.js.map +1 -0
- package/dist/adapters/commands/manifest.d.ts +37 -0
- package/dist/adapters/commands/manifest.d.ts.map +1 -0
- package/dist/adapters/commands/manifest.js +155 -0
- package/dist/adapters/commands/manifest.js.map +1 -0
- package/dist/adapters/commands/model.d.ts +15 -0
- package/dist/adapters/commands/model.d.ts.map +1 -0
- package/dist/adapters/commands/model.js +153 -0
- package/dist/adapters/commands/model.js.map +1 -0
- package/dist/adapters/commands/new.d.ts.map +1 -0
- package/dist/adapters/commands/new.js +41 -0
- package/dist/adapters/commands/new.js.map +1 -0
- package/dist/adapters/commands/registry.d.ts +5 -0
- package/dist/adapters/commands/registry.d.ts.map +1 -0
- package/dist/adapters/commands/registry.js +43 -0
- package/dist/adapters/commands/registry.js.map +1 -0
- package/dist/adapters/commands/sandbox.d.ts.map +1 -0
- package/dist/adapters/commands/sandbox.js +125 -0
- package/dist/adapters/commands/sandbox.js.map +1 -0
- package/dist/adapters/commands/session-view.d.ts.map +1 -0
- package/dist/{commands → adapters/commands}/session-view.js +23 -16
- package/dist/adapters/commands/session-view.js.map +1 -0
- package/dist/adapters/commands/types.d.ts +145 -0
- package/dist/adapters/commands/types.d.ts.map +1 -0
- package/dist/adapters/commands/types.js.map +1 -0
- package/dist/adapters/commands/utils.d.ts +14 -0
- package/dist/adapters/commands/utils.d.ts.map +1 -0
- package/dist/{commands → adapters/commands}/utils.js +18 -1
- package/dist/adapters/commands/utils.js.map +1 -0
- package/dist/adapters/discord/bot.d.ts +11 -8
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +223 -256
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/components.d.ts +28 -0
- package/dist/adapters/discord/components.d.ts.map +1 -0
- package/dist/adapters/discord/components.js +32 -0
- package/dist/adapters/discord/components.js.map +1 -0
- package/dist/adapters/discord/context.d.ts +2 -6
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +64 -218
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/discord/format.d.ts +3 -0
- package/dist/adapters/discord/format.d.ts.map +1 -0
- package/dist/adapters/discord/format.js +84 -0
- package/dist/adapters/discord/format.js.map +1 -0
- package/dist/adapters/discord/types.d.ts +8 -1
- package/dist/adapters/discord/types.d.ts.map +1 -1
- package/dist/adapters/discord/types.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +102 -0
- package/dist/adapters/github/bot.d.ts.map +1 -0
- package/dist/adapters/github/bot.js +720 -0
- package/dist/adapters/github/bot.js.map +1 -0
- package/dist/adapters/github/client.d.ts +122 -0
- package/dist/adapters/github/client.d.ts.map +1 -0
- package/dist/adapters/github/client.js +301 -0
- package/dist/adapters/github/client.js.map +1 -0
- package/dist/adapters/github/context.d.ts +5 -0
- package/dist/adapters/github/context.d.ts.map +1 -0
- package/dist/adapters/github/context.js +101 -0
- package/dist/adapters/github/context.js.map +1 -0
- package/dist/adapters/github/github-ops.d.ts +78 -0
- package/dist/adapters/github/github-ops.d.ts.map +1 -0
- package/dist/adapters/github/github-ops.js +337 -0
- package/dist/adapters/github/github-ops.js.map +1 -0
- package/dist/adapters/github/ids.d.ts +34 -0
- package/dist/adapters/github/ids.d.ts.map +1 -0
- package/dist/adapters/github/ids.js +57 -0
- package/dist/adapters/github/ids.js.map +1 -0
- package/dist/adapters/github/repo.d.ts +33 -0
- package/dist/adapters/github/repo.d.ts.map +1 -0
- package/dist/adapters/github/repo.js +141 -0
- package/dist/adapters/github/repo.js.map +1 -0
- package/dist/adapters/github/tool-pack.d.ts +14 -0
- package/dist/adapters/github/tool-pack.d.ts.map +1 -0
- package/dist/adapters/github/tool-pack.js +55 -0
- package/dist/adapters/github/tool-pack.js.map +1 -0
- package/dist/adapters/github/tools/checks.d.ts +18 -0
- package/dist/adapters/github/tools/checks.d.ts.map +1 -0
- package/dist/adapters/github/tools/checks.js +86 -0
- package/dist/adapters/github/tools/checks.js.map +1 -0
- package/dist/adapters/github/tools/issue.d.ts +21 -0
- package/dist/adapters/github/tools/issue.d.ts.map +1 -0
- package/dist/adapters/github/tools/issue.js +48 -0
- package/dist/adapters/github/tools/issue.js.map +1 -0
- package/dist/adapters/github/tools/pr.d.ts +22 -0
- package/dist/adapters/github/tools/pr.d.ts.map +1 -0
- package/dist/adapters/github/tools/pr.js +48 -0
- package/dist/adapters/github/tools/pr.js.map +1 -0
- package/dist/adapters/github/tools/read.d.ts +21 -0
- package/dist/adapters/github/tools/read.d.ts.map +1 -0
- package/dist/adapters/github/tools/read.js +141 -0
- package/dist/adapters/github/tools/read.js.map +1 -0
- package/dist/adapters/github/tools/review-reply.d.ts +17 -0
- package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
- package/dist/adapters/github/tools/review-reply.js +38 -0
- package/dist/adapters/github/tools/review-reply.js.map +1 -0
- package/dist/adapters/github/tools/sync.d.ts +17 -0
- package/dist/adapters/github/tools/sync.d.ts.map +1 -0
- package/dist/adapters/github/tools/sync.js +34 -0
- package/dist/adapters/github/tools/sync.js.map +1 -0
- package/dist/adapters/github/types.d.ts +345 -0
- package/dist/adapters/github/types.d.ts.map +1 -0
- package/dist/adapters/github/types.js.map +1 -0
- package/dist/adapters/github/webhook.d.ts +20 -0
- package/dist/adapters/github/webhook.d.ts.map +1 -0
- package/dist/adapters/github/webhook.js +78 -0
- package/dist/adapters/github/webhook.js.map +1 -0
- package/dist/adapters/index.d.ts +12 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +19 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/intake.d.ts +17 -6
- package/dist/adapters/intake.d.ts.map +1 -1
- package/dist/adapters/intake.js +96 -27
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/markdown-tables.d.ts +19 -0
- package/dist/adapters/markdown-tables.d.ts.map +1 -0
- package/dist/adapters/markdown-tables.js +152 -0
- package/dist/adapters/markdown-tables.js.map +1 -0
- package/dist/{platform-messages.d.ts → adapters/messages.d.ts} +3 -2
- package/dist/adapters/messages.d.ts.map +1 -0
- package/dist/{platform-messages.js → adapters/messages.js} +4 -1
- package/dist/adapters/messages.js.map +1 -0
- package/dist/adapters/progressive-renderer.d.ts +7 -0
- package/dist/adapters/progressive-renderer.d.ts.map +1 -0
- package/dist/adapters/progressive-renderer.js +443 -0
- package/dist/adapters/progressive-renderer.js.map +1 -0
- package/dist/adapters/shared.d.ts +37 -11
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +130 -24
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/assistant.d.ts +73 -0
- package/dist/adapters/slack/assistant.d.ts.map +1 -0
- package/dist/adapters/slack/assistant.js +205 -0
- package/dist/adapters/slack/assistant.js.map +1 -0
- package/dist/adapters/slack/auto-reply-context.d.ts +21 -0
- package/dist/adapters/slack/auto-reply-context.d.ts.map +1 -0
- package/dist/adapters/slack/auto-reply-context.js +28 -0
- package/dist/adapters/slack/auto-reply-context.js.map +1 -0
- package/dist/adapters/slack/blocks.d.ts +14 -0
- package/dist/adapters/slack/blocks.d.ts.map +1 -1
- package/dist/adapters/slack/blocks.js +104 -148
- package/dist/adapters/slack/blocks.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +154 -21
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +1037 -484
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/context.d.ts +2 -6
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +11 -17
- package/dist/adapters/slack/context.js.map +1 -1
- package/dist/adapters/slack/jev-context.d.ts +30 -0
- package/dist/adapters/slack/jev-context.d.ts.map +1 -0
- package/dist/adapters/slack/jev-context.js +67 -0
- package/dist/adapters/slack/jev-context.js.map +1 -0
- package/dist/adapters/slack/markdown.d.ts +3 -0
- package/dist/adapters/slack/markdown.d.ts.map +1 -0
- package/dist/adapters/slack/markdown.js +48 -0
- package/dist/adapters/slack/markdown.js.map +1 -0
- package/dist/adapters/slack/persona.d.ts +15 -0
- package/dist/adapters/slack/persona.d.ts.map +1 -0
- package/dist/adapters/slack/persona.js +22 -0
- package/dist/adapters/slack/persona.js.map +1 -0
- package/dist/adapters/slack/response-lifecycle.d.ts +1 -1
- package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
- package/dist/adapters/slack/response-lifecycle.js +261 -345
- package/dist/adapters/slack/response-lifecycle.js.map +1 -1
- package/dist/adapters/slack/session.d.ts.map +1 -1
- package/dist/adapters/slack/session.js +7 -11
- package/dist/adapters/slack/session.js.map +1 -1
- package/dist/adapters/slack/stream-limits.d.ts +35 -0
- package/dist/adapters/slack/stream-limits.d.ts.map +1 -0
- package/dist/adapters/slack/stream-limits.js +56 -0
- package/dist/adapters/slack/stream-limits.js.map +1 -0
- package/dist/adapters/slack/task-intent.d.ts +32 -0
- package/dist/adapters/slack/task-intent.d.ts.map +1 -0
- package/dist/adapters/slack/task-intent.js +72 -0
- package/dist/adapters/slack/task-intent.js.map +1 -0
- package/dist/adapters/slack/task-status.d.ts +7 -0
- package/dist/adapters/slack/task-status.d.ts.map +1 -0
- package/dist/adapters/slack/task-status.js +107 -0
- package/dist/adapters/slack/task-status.js.map +1 -0
- package/dist/adapters/slack/tool-pack.d.ts +11 -0
- package/dist/adapters/slack/tool-pack.d.ts.map +1 -0
- package/dist/adapters/slack/tool-pack.js +45 -0
- package/dist/adapters/slack/tool-pack.js.map +1 -0
- package/dist/adapters/slack/tools/blockkit.d.ts +14 -0
- package/dist/adapters/slack/tools/blockkit.d.ts.map +1 -0
- package/dist/adapters/slack/tools/blockkit.js +106 -0
- package/dist/adapters/slack/tools/blockkit.js.map +1 -0
- package/dist/adapters/slack/types.d.ts +73 -2
- package/dist/adapters/slack/types.d.ts.map +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/slack/update-diagnostics.d.ts +14 -0
- package/dist/adapters/slack/update-diagnostics.d.ts.map +1 -0
- package/dist/adapters/slack/update-diagnostics.js +134 -0
- package/dist/adapters/slack/update-diagnostics.js.map +1 -0
- package/dist/adapters/telegram/bot.d.ts +10 -9
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +133 -202
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts +2 -6
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js +53 -190
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/telegram/types.d.ts +1 -1
- package/dist/adapters/telegram/types.d.ts.map +1 -1
- package/dist/adapters/telegram/types.js.map +1 -1
- package/dist/adapters/types.d.ts +144 -13
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/adapters/web/admin/portal.d.ts +44 -0
- package/dist/adapters/web/admin/portal.d.ts.map +1 -0
- package/dist/adapters/web/admin/portal.js +3207 -0
- package/dist/adapters/web/admin/portal.js.map +1 -0
- package/dist/{web → adapters/web}/admin/provider-models.d.ts +1 -1
- package/dist/adapters/web/admin/provider-models.d.ts.map +1 -0
- package/dist/{web → adapters/web}/admin/provider-models.js +1 -1
- package/dist/adapters/web/admin/provider-models.js.map +1 -0
- package/dist/adapters/web/admin/types.d.ts +53 -0
- package/dist/adapters/web/admin/types.d.ts.map +1 -0
- package/dist/adapters/web/admin/types.js.map +1 -0
- package/dist/adapters/web/login/oauth.d.ts +5 -0
- package/dist/adapters/web/login/oauth.d.ts.map +1 -0
- package/dist/{web → adapters/web}/login/oauth.js +50 -85
- package/dist/adapters/web/login/oauth.js.map +1 -0
- package/dist/{web → adapters/web}/login/portal.d.ts +9 -3
- package/dist/adapters/web/login/portal.d.ts.map +1 -0
- package/dist/{web → adapters/web}/login/portal.js +161 -119
- package/dist/adapters/web/login/portal.js.map +1 -0
- package/dist/{web → adapters/web}/login/types.d.ts +1 -12
- package/dist/adapters/web/login/types.d.ts.map +1 -0
- package/dist/adapters/web/login/types.js.map +1 -0
- package/dist/adapters/web/portal-shell.d.ts +22 -0
- package/dist/adapters/web/portal-shell.d.ts.map +1 -0
- package/dist/{portal-shell.js → adapters/web/portal-shell.js} +78 -2
- package/dist/adapters/web/portal-shell.js.map +1 -0
- package/dist/{web → adapters/web}/server.d.ts +14 -8
- package/dist/adapters/web/server.d.ts.map +1 -0
- package/dist/{web → adapters/web}/server.js +14 -7
- package/dist/adapters/web/server.js.map +1 -0
- package/dist/adapters/web/session-view/portal.d.ts +20 -0
- package/dist/adapters/web/session-view/portal.d.ts.map +1 -0
- package/dist/{web → adapters/web}/session-view/portal.js +633 -162
- package/dist/adapters/web/session-view/portal.js.map +1 -0
- package/dist/{web → adapters/web}/session-view/types.d.ts +11 -6
- package/dist/adapters/web/session-view/types.d.ts.map +1 -0
- package/dist/adapters/web/session-view/types.js.map +1 -0
- package/dist/adapters/web/token-store.d.ts.map +1 -0
- package/dist/{web → adapters/web}/token-store.js +1 -1
- package/dist/adapters/web/token-store.js.map +1 -0
- package/dist/adapters/web/types.d.ts.map +1 -0
- package/dist/adapters/web/types.js.map +1 -0
- package/dist/cli/arg-grammar.d.ts +11 -0
- package/dist/cli/arg-grammar.d.ts.map +1 -0
- package/dist/cli/arg-grammar.js +50 -0
- package/dist/cli/arg-grammar.js.map +1 -0
- package/dist/cli/boot.d.ts +5 -0
- package/dist/cli/boot.d.ts.map +1 -0
- package/dist/cli/boot.js +90 -0
- package/dist/cli/boot.js.map +1 -0
- package/dist/cli/download.d.ts.map +1 -0
- package/dist/cli/download.js +88 -0
- package/dist/cli/download.js.map +1 -0
- package/dist/cli/office.d.ts +2 -0
- package/dist/cli/office.d.ts.map +1 -0
- package/dist/cli/office.js +181 -0
- package/dist/cli/office.js.map +1 -0
- package/dist/cli/onboard.d.ts +10 -0
- package/dist/cli/onboard.d.ts.map +1 -0
- package/dist/cli/onboard.js +225 -0
- package/dist/cli/onboard.js.map +1 -0
- package/dist/cli/process-lifecycle.d.ts +19 -0
- package/dist/cli/process-lifecycle.d.ts.map +1 -0
- package/dist/cli/process-lifecycle.js +67 -0
- package/dist/cli/process-lifecycle.js.map +1 -0
- package/dist/cli/sessions.d.ts +2 -0
- package/dist/cli/sessions.d.ts.map +1 -0
- package/dist/cli/sessions.js +88 -0
- package/dist/cli/sessions.js.map +1 -0
- package/dist/cli/types.d.ts +25 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/dream/index.d.ts +20 -0
- package/dist/dream/index.d.ts.map +1 -0
- package/dist/dream/index.js +264 -0
- package/dist/dream/index.js.map +1 -0
- package/dist/dream/types.d.ts +30 -0
- package/dist/dream/types.d.ts.map +1 -0
- package/dist/dream/types.js +2 -0
- package/dist/dream/types.js.map +1 -0
- package/dist/env-manifest.d.ts +38 -0
- package/dist/env-manifest.d.ts.map +1 -0
- package/dist/env-manifest.js +260 -0
- package/dist/env-manifest.js.map +1 -0
- package/dist/events/index.d.ts +172 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +340 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/scheduler.d.ts +34 -0
- package/dist/events/scheduler.d.ts.map +1 -0
- package/dist/events/scheduler.js +231 -0
- package/dist/events/scheduler.js.map +1 -0
- package/dist/file-guards.d.ts +26 -0
- package/dist/file-guards.d.ts.map +1 -0
- package/dist/file-guards.js +133 -0
- package/dist/file-guards.js.map +1 -0
- package/dist/harness/execution-env.d.ts +19 -0
- package/dist/harness/execution-env.d.ts.map +1 -0
- package/dist/harness/execution-env.js +262 -0
- package/dist/harness/execution-env.js.map +1 -0
- package/dist/harness/execution-resolver.d.ts +25 -0
- package/dist/harness/execution-resolver.d.ts.map +1 -0
- package/dist/harness/execution-resolver.js +156 -0
- package/dist/harness/execution-resolver.js.map +1 -0
- package/dist/harness/index.d.ts +18 -13
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +11 -11
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/jev.d.ts +86 -0
- package/dist/harness/jev.d.ts.map +1 -0
- package/dist/harness/jev.js +167 -0
- package/dist/harness/jev.js.map +1 -0
- package/dist/harness/mcp.d.ts +38 -0
- package/dist/harness/mcp.d.ts.map +1 -0
- package/dist/harness/mcp.js +304 -0
- package/dist/harness/mcp.js.map +1 -0
- package/dist/harness/models.d.ts +7 -4
- package/dist/harness/models.d.ts.map +1 -1
- package/dist/harness/models.js +54 -55
- package/dist/harness/models.js.map +1 -1
- package/dist/harness/open-connector.d.ts +25 -0
- package/dist/harness/open-connector.d.ts.map +1 -0
- package/dist/harness/open-connector.js +178 -0
- package/dist/harness/open-connector.js.map +1 -0
- package/dist/harness/presenter.d.ts +31 -0
- package/dist/harness/presenter.d.ts.map +1 -0
- package/dist/harness/presenter.js +859 -0
- package/dist/harness/presenter.js.map +1 -0
- package/dist/harness/prompt.d.ts +30 -0
- package/dist/harness/prompt.d.ts.map +1 -0
- package/dist/harness/prompt.js +420 -0
- package/dist/harness/prompt.js.map +1 -0
- package/dist/harness/runner.d.ts +2 -123
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +551 -416
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session.d.ts +122 -0
- package/dist/harness/session.d.ts.map +1 -0
- package/dist/harness/session.js +581 -0
- package/dist/harness/session.js.map +1 -0
- package/dist/harness/skills.d.ts +17 -28
- package/dist/harness/skills.d.ts.map +1 -1
- package/dist/harness/skills.js +104 -39
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/subagent-profiles.d.ts +8 -0
- package/dist/harness/subagent-profiles.d.ts.map +1 -0
- package/dist/harness/subagent-profiles.js +293 -0
- package/dist/harness/subagent-profiles.js.map +1 -0
- package/dist/harness/subagent.d.ts +64 -0
- package/dist/harness/subagent.d.ts.map +1 -0
- package/dist/harness/subagent.js +687 -0
- package/dist/harness/subagent.js.map +1 -0
- package/dist/harness/tools/attach.d.ts.map +1 -0
- package/dist/{adapters/slack → harness}/tools/attach.js +1 -1
- package/dist/harness/tools/attach.js.map +1 -0
- package/dist/{tools → harness/tools}/event.d.ts +4 -33
- package/dist/harness/tools/event.d.ts.map +1 -0
- package/dist/harness/tools/event.js +175 -0
- package/dist/harness/tools/event.js.map +1 -0
- package/dist/harness/tools/generate-image.d.ts +23 -0
- package/dist/harness/tools/generate-image.d.ts.map +1 -0
- package/dist/harness/tools/generate-image.js +65 -0
- package/dist/harness/tools/generate-image.js.map +1 -0
- package/dist/harness/tools/host-fn-tool.d.ts +21 -0
- package/dist/harness/tools/host-fn-tool.d.ts.map +1 -0
- package/dist/harness/tools/host-fn-tool.js +32 -0
- package/dist/harness/tools/host-fn-tool.js.map +1 -0
- package/dist/harness/tools/index.d.ts +41 -0
- package/dist/harness/tools/index.d.ts.map +1 -0
- package/dist/harness/tools/index.js +51 -0
- package/dist/harness/tools/index.js.map +1 -0
- package/dist/harness/tools/jev.d.ts +21 -0
- package/dist/harness/tools/jev.d.ts.map +1 -0
- package/dist/harness/tools/jev.js +109 -0
- package/dist/harness/tools/jev.js.map +1 -0
- package/dist/harness/tools/pi-tools.d.ts +18 -0
- package/dist/harness/tools/pi-tools.d.ts.map +1 -0
- package/dist/harness/tools/pi-tools.js +84 -0
- package/dist/harness/tools/pi-tools.js.map +1 -0
- package/dist/harness/tools/react.d.ts.map +1 -0
- package/dist/{tools → harness/tools}/react.js +6 -17
- package/dist/harness/tools/react.js.map +1 -0
- package/dist/{tools → harness/tools}/sandbox.d.ts +4 -4
- package/dist/harness/tools/sandbox.d.ts.map +1 -0
- package/dist/{tools → harness/tools}/sandbox.js +12 -8
- package/dist/harness/tools/sandbox.js.map +1 -0
- package/dist/harness/tools/subagent.d.ts +85 -0
- package/dist/harness/tools/subagent.d.ts.map +1 -0
- package/dist/harness/tools/subagent.js +677 -0
- package/dist/harness/tools/subagent.js.map +1 -0
- package/dist/harness/tools/task.d.ts +20 -0
- package/dist/harness/tools/task.d.ts.map +1 -0
- package/dist/harness/tools/task.js +79 -0
- package/dist/harness/tools/task.js.map +1 -0
- package/dist/harness/tools/types.d.ts +29 -0
- package/dist/harness/tools/types.d.ts.map +1 -0
- package/dist/harness/tools/types.js +2 -0
- package/dist/harness/tools/types.js.map +1 -0
- package/dist/harness/types.d.ts +384 -25
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +33 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -6
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +4 -1
- package/dist/log.js.map +1 -1
- package/dist/main.js +357 -198
- package/dist/main.js.map +1 -1
- package/dist/observability/index.d.ts +33 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +257 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/instrument.js +14 -6
- package/dist/observability/instrument.js.map +1 -1
- package/dist/observability/otel.d.ts +10 -0
- package/dist/observability/otel.d.ts.map +1 -0
- package/dist/observability/otel.js +183 -0
- package/dist/observability/otel.js.map +1 -0
- package/dist/observability/sentry.d.ts +40 -7
- package/dist/observability/sentry.d.ts.map +1 -1
- package/dist/observability/sentry.js +176 -32
- package/dist/observability/sentry.js.map +1 -1
- package/dist/observability/types.d.ts +24 -3
- package/dist/observability/types.d.ts.map +1 -1
- package/dist/observability/types.js.map +1 -1
- package/dist/office/index.d.ts +139 -0
- package/dist/office/index.d.ts.map +1 -0
- package/dist/office/index.js +1084 -0
- package/dist/office/index.js.map +1 -0
- package/dist/office/projection.d.ts +42 -0
- package/dist/office/projection.d.ts.map +1 -0
- package/dist/office/projection.js +182 -0
- package/dist/office/projection.js.map +1 -0
- package/dist/office/types.d.ts +116 -0
- package/dist/office/types.d.ts.map +1 -0
- package/dist/office/types.js +2 -0
- package/dist/office/types.js.map +1 -0
- package/dist/runtime/conversation-runtime.d.ts +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +423 -152
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts +76 -0
- package/dist/runtime/session-lifecycle.d.ts.map +1 -0
- package/dist/runtime/session-lifecycle.js +404 -0
- package/dist/runtime/session-lifecycle.js.map +1 -0
- package/dist/runtime/types.d.ts +63 -15
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.d.ts +4 -0
- package/dist/sandbox/cloudflare.d.ts.map +1 -1
- package/dist/sandbox/cloudflare.js +54 -52
- package/dist/sandbox/cloudflare.js.map +1 -1
- package/dist/sandbox/container.d.ts +3 -0
- package/dist/sandbox/container.d.ts.map +1 -1
- package/dist/sandbox/container.js +19 -7
- package/dist/sandbox/container.js.map +1 -1
- package/dist/sandbox/host.d.ts +3 -0
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +44 -35
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sandbox/identity.d.ts +42 -0
- package/dist/sandbox/identity.d.ts.map +1 -0
- package/dist/sandbox/identity.js +77 -0
- package/dist/sandbox/identity.js.map +1 -0
- package/dist/sandbox/index.d.ts +24 -6
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +77 -17
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/provisioner.d.ts +139 -0
- package/dist/sandbox/provisioner.d.ts.map +1 -0
- package/dist/{provisioner.js → sandbox/provisioner.js} +378 -24
- package/dist/sandbox/provisioner.js.map +1 -0
- package/dist/sandbox/types.d.ts +43 -9
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/sandbox/utils.d.ts +24 -0
- package/dist/sandbox/utils.d.ts.map +1 -1
- package/dist/sandbox/utils.js +92 -1
- package/dist/sandbox/utils.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts +23 -0
- package/dist/sessions/chat-history-sync.d.ts.map +1 -0
- package/dist/sessions/{agent-memory-file-manager.js → chat-history-sync.js} +239 -175
- package/dist/sessions/chat-history-sync.js.map +1 -0
- package/dist/sessions/history-line.d.ts +29 -0
- package/dist/sessions/history-line.d.ts.map +1 -0
- package/dist/sessions/history-line.js +45 -0
- package/dist/sessions/history-line.js.map +1 -0
- package/dist/sessions/migrate-common.d.ts +43 -0
- package/dist/sessions/migrate-common.d.ts.map +1 -0
- package/dist/sessions/migrate-common.js +99 -0
- package/dist/sessions/migrate-common.js.map +1 -0
- package/dist/sessions/migrate-pi-084.d.ts +8 -0
- package/dist/sessions/migrate-pi-084.d.ts.map +1 -0
- package/dist/sessions/migrate-pi-084.js +302 -0
- package/dist/sessions/migrate-pi-084.js.map +1 -0
- package/dist/sessions/migrate-v3.d.ts +15 -0
- package/dist/sessions/migrate-v3.d.ts.map +1 -0
- package/dist/sessions/migrate-v3.js +419 -0
- package/dist/sessions/migrate-v3.js.map +1 -0
- package/dist/sessions/session-key.d.ts +33 -0
- package/dist/sessions/session-key.d.ts.map +1 -0
- package/dist/sessions/session-key.js +115 -0
- package/dist/sessions/session-key.js.map +1 -0
- package/dist/sessions/session-store.d.ts +61 -0
- package/dist/sessions/session-store.d.ts.map +1 -0
- package/dist/sessions/session-store.js +684 -0
- package/dist/sessions/session-store.js.map +1 -0
- package/dist/sessions/store.d.ts +17 -10
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +182 -47
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +74 -8
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/settings/apply.d.ts +16 -0
- package/dist/settings/apply.d.ts.map +1 -0
- package/dist/settings/apply.js +60 -0
- package/dist/settings/apply.js.map +1 -0
- package/dist/settings/index.d.ts +126 -0
- package/dist/settings/index.d.ts.map +1 -0
- package/dist/settings/index.js +422 -0
- package/dist/settings/index.js.map +1 -0
- package/dist/settings/migrate.d.ts +21 -0
- package/dist/settings/migrate.d.ts.map +1 -0
- package/dist/settings/migrate.js +86 -0
- package/dist/settings/migrate.js.map +1 -0
- package/dist/types.d.ts +330 -141
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -2
- package/dist/types.js.map +1 -1
- package/dist/vault/index.d.ts +52 -2
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +218 -86
- package/dist/vault/index.js.map +1 -1
- package/dist/vault/types.d.ts +6 -2
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/vault/types.js.map +1 -1
- package/package.json +79 -40
- package/dist/adapter.d.ts +0 -2
- package/dist/adapter.d.ts.map +0 -1
- package/dist/adapter.js +0 -2
- package/dist/adapter.js.map +0 -1
- package/dist/adapters/slack/tools/attach.d.ts.map +0 -1
- package/dist/adapters/slack/tools/attach.js.map +0 -1
- package/dist/adapters/streaming.d.ts +0 -18
- package/dist/adapters/streaming.d.ts.map +0 -1
- package/dist/adapters/streaming.js +0 -44
- package/dist/adapters/streaming.js.map +0 -1
- package/dist/adapters/telegram/html.d.ts +0 -3
- package/dist/adapters/telegram/html.d.ts.map +0 -1
- package/dist/adapters/telegram/html.js +0 -98
- package/dist/adapters/telegram/html.js.map +0 -1
- package/dist/agent-events.d.ts +0 -5
- package/dist/agent-events.d.ts.map +0 -1
- package/dist/agent-events.js +0 -26
- package/dist/agent-events.js.map +0 -1
- package/dist/agent.d.ts +0 -39
- package/dist/agent.d.ts.map +0 -1
- package/dist/agent.js +0 -1291
- package/dist/agent.js.map +0 -1
- package/dist/cli/ext-git.d.ts +0 -22
- package/dist/cli/ext-git.d.ts.map +0 -1
- package/dist/cli/ext-git.js +0 -76
- package/dist/cli/ext-git.js.map +0 -1
- package/dist/cli/ext.d.ts +0 -2
- package/dist/cli/ext.d.ts.map +0 -1
- package/dist/cli/ext.js +0 -217
- package/dist/cli/ext.js.map +0 -1
- package/dist/commands/admin.d.ts.map +0 -1
- package/dist/commands/admin.js.map +0 -1
- package/dist/commands/auto-reply.d.ts.map +0 -1
- package/dist/commands/auto-reply.js +0 -76
- package/dist/commands/auto-reply.js.map +0 -1
- package/dist/commands/extensions.d.ts +0 -14
- package/dist/commands/extensions.d.ts.map +0 -1
- package/dist/commands/extensions.js +0 -55
- package/dist/commands/extensions.js.map +0 -1
- package/dist/commands/login.d.ts +0 -5
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js +0 -115
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/model.d.ts +0 -10
- package/dist/commands/model.d.ts.map +0 -1
- package/dist/commands/model.js +0 -102
- package/dist/commands/model.js.map +0 -1
- package/dist/commands/new.d.ts.map +0 -1
- package/dist/commands/new.js +0 -25
- package/dist/commands/new.js.map +0 -1
- package/dist/commands/parse.d.ts +0 -7
- package/dist/commands/parse.d.ts.map +0 -1
- package/dist/commands/parse.js +0 -14
- package/dist/commands/parse.js.map +0 -1
- package/dist/commands/registry.d.ts +0 -5
- package/dist/commands/registry.d.ts.map +0 -1
- package/dist/commands/registry.js +0 -31
- package/dist/commands/registry.js.map +0 -1
- package/dist/commands/sandbox.d.ts.map +0 -1
- package/dist/commands/sandbox.js +0 -78
- package/dist/commands/sandbox.js.map +0 -1
- package/dist/commands/session-view.d.ts.map +0 -1
- package/dist/commands/session-view.js.map +0 -1
- package/dist/commands/types.d.ts +0 -66
- package/dist/commands/types.d.ts.map +0 -1
- package/dist/commands/types.js.map +0 -1
- package/dist/commands/utils.d.ts +0 -11
- package/dist/commands/utils.d.ts.map +0 -1
- package/dist/commands/utils.js.map +0 -1
- package/dist/config.d.ts +0 -78
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -450
- package/dist/config.js.map +0 -1
- package/dist/download.d.ts.map +0 -1
- package/dist/download.js +0 -89
- package/dist/download.js.map +0 -1
- package/dist/events.d.ts +0 -43
- package/dist/events.d.ts.map +0 -1
- package/dist/events.js +0 -456
- package/dist/events.js.map +0 -1
- package/dist/execution-resolver.d.ts +0 -21
- package/dist/execution-resolver.d.ts.map +0 -1
- package/dist/execution-resolver.js +0 -170
- package/dist/execution-resolver.js.map +0 -1
- package/dist/harness/auth.d.ts +0 -16
- package/dist/harness/auth.d.ts.map +0 -1
- package/dist/harness/auth.js +0 -86
- package/dist/harness/auth.js.map +0 -1
- package/dist/harness/extensions/loader.d.ts +0 -86
- package/dist/harness/extensions/loader.d.ts.map +0 -1
- package/dist/harness/extensions/loader.js +0 -525
- package/dist/harness/extensions/loader.js.map +0 -1
- package/dist/harness/extensions/registry.d.ts +0 -23
- package/dist/harness/extensions/registry.d.ts.map +0 -1
- package/dist/harness/extensions/registry.js +0 -45
- package/dist/harness/extensions/registry.js.map +0 -1
- package/dist/harness/extensions/types.d.ts +0 -248
- package/dist/harness/extensions/types.d.ts.map +0 -1
- package/dist/harness/extensions/types.js.map +0 -1
- package/dist/harness/session-store.d.ts +0 -77
- package/dist/harness/session-store.d.ts.map +0 -1
- package/dist/harness/session-store.js +0 -248
- package/dist/harness/session-store.js.map +0 -1
- package/dist/harness/settings.d.ts +0 -47
- package/dist/harness/settings.d.ts.map +0 -1
- package/dist/harness/settings.js +0 -29
- package/dist/harness/settings.js.map +0 -1
- package/dist/model-registry.d.ts +0 -4
- package/dist/model-registry.d.ts.map +0 -1
- package/dist/model-registry.js +0 -7
- package/dist/model-registry.js.map +0 -1
- package/dist/platform-messages.d.ts.map +0 -1
- package/dist/platform-messages.js.map +0 -1
- package/dist/portal-shell.d.ts +0 -4
- package/dist/portal-shell.d.ts.map +0 -1
- package/dist/portal-shell.js.map +0 -1
- package/dist/provisioner.d.ts +0 -61
- package/dist/provisioner.d.ts.map +0 -1
- package/dist/provisioner.js.map +0 -1
- package/dist/runtime/agent-run-controller.d.ts +0 -31
- package/dist/runtime/agent-run-controller.d.ts.map +0 -1
- package/dist/runtime/agent-run-controller.js +0 -195
- package/dist/runtime/agent-run-controller.js.map +0 -1
- package/dist/sandbox/errors.d.ts +0 -6
- package/dist/sandbox/errors.d.ts.map +0 -1
- package/dist/sandbox/errors.js +0 -11
- package/dist/sandbox/errors.js.map +0 -1
- package/dist/sandbox/firecracker.d.ts +0 -15
- package/dist/sandbox/firecracker.d.ts.map +0 -1
- package/dist/sandbox/firecracker.js +0 -212
- package/dist/sandbox/firecracker.js.map +0 -1
- package/dist/sandbox/image.d.ts +0 -3
- package/dist/sandbox/image.d.ts.map +0 -1
- package/dist/sandbox/image.js +0 -27
- package/dist/sandbox/image.js.map +0 -1
- package/dist/sandbox/path-context.d.ts +0 -3
- package/dist/sandbox/path-context.d.ts.map +0 -1
- package/dist/sandbox/path-context.js +0 -20
- package/dist/sandbox/path-context.js.map +0 -1
- package/dist/sessions/agent-memory-file-manager.d.ts +0 -19
- package/dist/sessions/agent-memory-file-manager.d.ts.map +0 -1
- package/dist/sessions/agent-memory-file-manager.js.map +0 -1
- package/dist/sessions/metadata.d.ts +0 -3
- package/dist/sessions/metadata.d.ts.map +0 -1
- package/dist/sessions/metadata.js +0 -11
- package/dist/sessions/metadata.js.map +0 -1
- package/dist/sessions/policy.d.ts +0 -6
- package/dist/sessions/policy.d.ts.map +0 -1
- package/dist/sessions/policy.js +0 -23
- package/dist/sessions/policy.js.map +0 -1
- package/dist/store.d.ts +0 -46
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -177
- package/dist/store.js.map +0 -1
- package/dist/tools/bash.d.ts +0 -10
- package/dist/tools/bash.d.ts.map +0 -1
- package/dist/tools/bash.js +0 -80
- package/dist/tools/bash.js.map +0 -1
- package/dist/tools/edit.d.ts +0 -11
- package/dist/tools/edit.d.ts.map +0 -1
- package/dist/tools/edit.js +0 -131
- package/dist/tools/edit.js.map +0 -1
- package/dist/tools/event.d.ts.map +0 -1
- package/dist/tools/event.js +0 -252
- package/dist/tools/event.js.map +0 -1
- package/dist/tools/index.d.ts +0 -24
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -31
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/react.d.ts.map +0 -1
- package/dist/tools/react.js.map +0 -1
- package/dist/tools/read.d.ts +0 -11
- package/dist/tools/read.d.ts.map +0 -1
- package/dist/tools/read.js +0 -134
- package/dist/tools/read.js.map +0 -1
- package/dist/tools/sandbox.d.ts.map +0 -1
- package/dist/tools/sandbox.js.map +0 -1
- package/dist/tools/truncate.d.ts +0 -33
- package/dist/tools/truncate.d.ts.map +0 -1
- package/dist/tools/truncate.js +0 -184
- package/dist/tools/truncate.js.map +0 -1
- package/dist/tools/types.d.ts +0 -54
- package/dist/tools/types.d.ts.map +0 -1
- package/dist/tools/types.js.map +0 -1
- package/dist/tools/write.d.ts +0 -10
- package/dist/tools/write.d.ts.map +0 -1
- package/dist/tools/write.js +0 -29
- package/dist/tools/write.js.map +0 -1
- package/dist/trigger.d.ts +0 -22
- package/dist/trigger.d.ts.map +0 -1
- package/dist/trigger.js +0 -100
- package/dist/trigger.js.map +0 -1
- package/dist/utils/date.d.ts +0 -10
- package/dist/utils/date.d.ts.map +0 -1
- package/dist/utils/date.js +0 -23
- package/dist/utils/date.js.map +0 -1
- package/dist/utils/env.d.ts +0 -3
- package/dist/utils/env.d.ts.map +0 -1
- package/dist/utils/env.js +0 -12
- package/dist/utils/env.js.map +0 -1
- package/dist/utils/file-guards.d.ts +0 -9
- package/dist/utils/file-guards.d.ts.map +0 -1
- package/dist/utils/file-guards.js +0 -59
- package/dist/utils/file-guards.js.map +0 -1
- package/dist/utils/fs-atomic.d.ts +0 -10
- package/dist/utils/fs-atomic.d.ts.map +0 -1
- package/dist/utils/fs-atomic.js +0 -45
- package/dist/utils/fs-atomic.js.map +0 -1
- package/dist/utils/html.d.ts +0 -2
- package/dist/utils/html.d.ts.map +0 -1
- package/dist/utils/html.js +0 -4
- package/dist/utils/html.js.map +0 -1
- package/dist/utils/http-body.d.ts +0 -10
- package/dist/utils/http-body.d.ts.map +0 -1
- package/dist/utils/http-body.js +0 -34
- package/dist/utils/http-body.js.map +0 -1
- package/dist/vault/routing.d.ts +0 -3
- package/dist/vault/routing.d.ts.map +0 -1
- package/dist/vault/routing.js +0 -13
- package/dist/vault/routing.js.map +0 -1
- package/dist/web/admin/portal.d.ts +0 -5
- package/dist/web/admin/portal.d.ts.map +0 -1
- package/dist/web/admin/portal.js +0 -2572
- package/dist/web/admin/portal.js.map +0 -1
- package/dist/web/admin/provider-models.d.ts.map +0 -1
- package/dist/web/admin/provider-models.js.map +0 -1
- package/dist/web/admin/store.d.ts +0 -13
- package/dist/web/admin/store.d.ts.map +0 -1
- package/dist/web/admin/store.js +0 -14
- package/dist/web/admin/store.js.map +0 -1
- package/dist/web/admin/types.d.ts +0 -30
- package/dist/web/admin/types.d.ts.map +0 -1
- package/dist/web/admin/types.js.map +0 -1
- package/dist/web/agent-events/portal.d.ts +0 -3
- package/dist/web/agent-events/portal.d.ts.map +0 -1
- package/dist/web/agent-events/portal.js +0 -18
- package/dist/web/agent-events/portal.js.map +0 -1
- package/dist/web/login/oauth.d.ts +0 -6
- package/dist/web/login/oauth.d.ts.map +0 -1
- package/dist/web/login/oauth.js.map +0 -1
- package/dist/web/login/portal.d.ts.map +0 -1
- package/dist/web/login/portal.js.map +0 -1
- package/dist/web/login/store.d.ts +0 -8
- package/dist/web/login/store.d.ts.map +0 -1
- package/dist/web/login/store.js +0 -15
- package/dist/web/login/store.js.map +0 -1
- package/dist/web/login/types.d.ts.map +0 -1
- package/dist/web/login/types.js.map +0 -1
- package/dist/web/request.d.ts +0 -3
- package/dist/web/request.d.ts.map +0 -1
- package/dist/web/request.js +0 -13
- package/dist/web/request.js.map +0 -1
- package/dist/web/server.d.ts.map +0 -1
- package/dist/web/server.js.map +0 -1
- package/dist/web/session-view/command.d.ts +0 -4
- package/dist/web/session-view/command.d.ts.map +0 -1
- package/dist/web/session-view/command.js +0 -7
- package/dist/web/session-view/command.js.map +0 -1
- package/dist/web/session-view/portal.d.ts +0 -13
- package/dist/web/session-view/portal.d.ts.map +0 -1
- package/dist/web/session-view/portal.js.map +0 -1
- package/dist/web/session-view/service.d.ts +0 -6
- package/dist/web/session-view/service.d.ts.map +0 -1
- package/dist/web/session-view/service.js +0 -498
- package/dist/web/session-view/service.js.map +0 -1
- package/dist/web/session-view/store.d.ts +0 -8
- package/dist/web/session-view/store.d.ts.map +0 -1
- package/dist/web/session-view/store.js +0 -15
- package/dist/web/session-view/store.js.map +0 -1
- package/dist/web/session-view/types.d.ts.map +0 -1
- package/dist/web/session-view/types.js.map +0 -1
- package/dist/web/token-store.d.ts.map +0 -1
- package/dist/web/token-store.js.map +0 -1
- package/dist/web/types.d.ts.map +0 -1
- package/dist/web/types.js.map +0 -1
- /package/dist/{commands → adapters/commands}/admin.d.ts +0 -0
- /package/dist/{commands → adapters/commands}/new.d.ts +0 -0
- /package/dist/{commands → adapters/commands}/sandbox.d.ts +0 -0
- /package/dist/{commands → adapters/commands}/session-view.d.ts +0 -0
- /package/dist/{commands → adapters/commands}/types.js +0 -0
- /package/dist/{harness/extensions → adapters/github}/types.js +0 -0
- /package/dist/{tools → adapters/web/admin}/types.js +0 -0
- /package/dist/{web/admin → adapters/web/login}/types.js +0 -0
- /package/dist/{web/login → adapters/web/session-view}/types.js +0 -0
- /package/dist/{web → adapters/web}/token-store.d.ts +0 -0
- /package/dist/{web → adapters/web}/types.d.ts +0 -0
- /package/dist/{web/session-view → adapters/web}/types.js +0 -0
- /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
- /package/dist/{web → cli}/types.js +0 -0
- /package/dist/{adapters/slack → harness}/tools/attach.d.ts +0 -0
- /package/dist/{tools → harness/tools}/react.d.ts +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"portal.js","sourceRoot":"","sources":["../../../src/web/admin/portal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAE7E,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,IAAI,WAAW,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,MAAM,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEnE,OAAO,EACL,+BAA+B,EAC/B,kBAAkB,EAClB,2BAA2B,EAC3B,+BAA+B,EAC/B,0BAA0B,EAC1B,oBAAoB,GAErB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,+BAA+B,EAAE,MAAM,sBAAsB,CAAC;AAMjF,kFAAkF;AAElF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAoB,EACpB,GAAmB,EACnB,GAAQ,EACR,QAAuB;IAEvB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAErD,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACrD,MAAM,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;YACnE,GAAG,CAAC,GAAG,CACL,oBAAoB,CAClB,2FAA2F,CAC5F,CACF,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,0BAA0B;YAC1C,eAAe,EAAE,UAAU;SAC5B,CAAC,CAAC;QACH,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC3C,MAAM,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,kFAAkF;AAElF,KAAK,UAAU,eAAe,CAC5B,GAAoB,EACpB,GAAmB,EACnB,GAAQ,EACR,QAAuB;IAEvB,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACjF,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,eAAe,EAAE,CAAC;YACrC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,0BAA0B,EAAE,CAAC;YAChD,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,0BAA0B,EAAE,CAAC;YAChD,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,+BAA+B,EAAE,CAAC;YACrD,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,+BAA+B,EAAE,CAAC;YACrD,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAClD,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,4BAA4B,EAAE,CAAC;YAClD,mBAAmB,CAAC,GAAG,CAAC,CAAC;YACzB,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;YACzC,KAAK,eAAe,CAAC,GAAG,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,2BAA2B,EAAE,CAAC;YACjD,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,2BAA2B,EAAE,CAAC;YACjD,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;YACzC,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,wBAAwB,EAAE,CAAC;YAC9C,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;YACzC,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,wBAAwB,EAAE,CAAC;YAC9C,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,iCAAiC,EAAE,CAAC;YACvD,2BAA2B,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YACvD,OAAO;QACT,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;QACnD,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1C,IAAI,CAAC,IAAI;QAAE,OAAO;IAElB,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,MAAM,KAAK,GAAG,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,gCAAgC,EAAE,CAAC;QACtD,4BAA4B,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,kCAAkC,EAAE,CAAC;QACxD,8BAA8B,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC3D,OAAO;IACT,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,qCAAqC,EAAE,CAAC;QAC3D,gCAAgC,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,gCAAgC,EAAE,CAAC;QACtD,4BAA4B,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,uCAAuC,EAAE,CAAC;QAC7D,4BAA4B,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,qCAAqC,EAAE,CAAC;QAC3D,0BAA0B,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,wCAAwC,EAAE,CAAC;QAC9D,4BAA4B,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,2BAA2B,EAAE,CAAC;QACjD,sBAAsB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,6BAA6B,EAAE,CAAC;QACnD,wBAAwB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACpC,OAAO;IACT,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,2BAA2B,EAAE,CAAC;QACjD,sBAAsB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED,kFAAkF;AAElF,SAAS,qBAAqB,CAC5B,SAAiB,EACjB,KAAiB;IAEjB,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC;IAChE,IAAI,SAAS,KAAK,KAAK,CAAC,cAAc;QAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC;IAC7E,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;IACzE,CAAC;IACD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC;AACvC,CAAC;AAED,SAAS,yBAAyB,CAChC,IAA6B,EAC7B,KAAiB;IAEjB,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5F,OAAO,qBAAqB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,sBAAsB,CAAC,GAAmB,EAAE,QAAuB;IAC1E,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,QAAQ,CAAC,UAAU,CAAC;AAC7B,CAAC;AAED,kFAAkF;AAElF,SAAS,OAAO,CAAC,GAAmB,EAAE,KAAiB;IACrD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE;QAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,IAAI;QAChD,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,eAAe,EAAE,YAAY,EAAE,qBAAqB,CAAC,CAAC,CAAC;AAEvF,SAAS,oBAAoB,CAAC,UAAkB;IAC9C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7E,OAAO,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SACpD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SAC9F,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAC/B,kEAAkE;YAClE,+DAA+D;YAC/D,OAAO,KAAK,CAAC,IAAI,CACf,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,UAAU,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CACrF,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC;SACD,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,wBAAwB,CAAC,UAAkB,EAAE,cAAsB;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IAC7C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,KAAa,EAAQ,EAAE;QAClD,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO;QACtB,IAAI,OAAO,CAAC;QACZ,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBACvB,SAAS;YACX,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC7B,IAAI,KAAK,CAAC,OAAO,GAAG,MAAM;oBAAE,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;YACrD,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACd,OAAO,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACpC,CAAC;AAED,SAAS,wBAAwB,CAAC,QAAuB,EAAE,cAAsB;IAC/E,KAAK,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE,CAAC;QAC5E,MAAM,OAAO,GAAG,GAAG,EAAE,gBAAgB,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,cAAc,CAAC,CAAC;QACtF,IAAI,OAAO;YAAE,OAAO,GAAG,QAAQ,KAAK,OAAO,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;IACvE,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,SAAS,sBAAsB,CAAC,GAAmB,EAAE,QAAuB;IAC1E,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IAExB,MAAM,GAAG,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAE7C,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,QAAQ,CAAC,OAAO,EAAE,kBAAkB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CACtE,CAAC;IAEF,MAAM,aAAa,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,EAAE;QAC/C,MAAM,YAAY,GAAG,wBAAwB,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAC1C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,cAAc,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,cAAc,GAAG,CAAC,CACxE,CAAC;QACF,OAAO;YACL,cAAc;YACd,KAAK,EAAE,wBAAwB,CAAC,QAAQ,EAAE,cAAc,CAAC;YACzD,OAAO;YACP,cAAc,EAAE,YAAY;SAC7B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;AACvC,CAAC;AAgBD,SAAS,iBAAiB,CAAC,GAAmB,EAAE,QAAuB;IACrE,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IAExB,MAAM,IAAI,GAAG,oBAAoB,CAAC,UAAU,CAAC;SAC1C,OAAO,CAAC,CAAC,cAAc,EAAE,EAAE,CAC1B,4BAA4B,CAC1B,UAAU,EACV,cAAc,EACd,wBAAwB,CAAC,QAAQ,EAAE,cAAc,CAAC,CACnD,CACF;SACA,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SACrC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEhB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,4BAA4B,CACnC,UAAkB,EAClB,cAAsB,EACtB,KAAa;IAEb,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;IAChE,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;aACpD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;aAClE,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC;IAC/F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CACvB,WAAmB,EACnB,cAAsB,EACtB,KAAa;IAEb,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAEvB,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAC1B,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YACb,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW;gBAAE,OAAO,GAAG,CAAC;YAC/E,MAAM,OAAO,GAAG,KAAK,CAAC,OAA2C,CAAC;YAClE,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC;YAC3B,IAAI,CAAC,IAAI;gBAAE,OAAO,GAAG,CAAC;YACtB,GAAG,CAAC,KAAK,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtC,GAAG,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACxC,GAAG,CAAC,SAAS,IAAI,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9C,GAAG,CAAC,UAAU,IAAI,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAChD,GAAG,CAAC,IAAI,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC3C,OAAO,GAAG,CAAC;QACb,CAAC,EACD,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAC9D,CAAC;QACF,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC;QAC9E,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QAE1B,OAAO;YACL;gBACE,cAAc;gBACd,KAAK;gBACL,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC;gBAC/B,SAAS,EAAE,MAAM,CAAC,EAAE;gBACpB,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,MAAM,CAAC,SAAS;gBACxD,GAAG,KAAK;gBACR,KAAK;aACN;SACF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAYD,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC;AAYD,SAAS,WAAW,CAAC,CAAO;IAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjD,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;AACnC,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACvF,CAAC;AAED,mFAAmF;AACnF,SAAS,sBAAsB,CAAC,GAAmB,EAAE,GAAQ,EAAE,QAAuB;IACpF,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IAExB,MAAM,cAAc,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;IACpE,IAAI,CAAC,cAAc,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAClF,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAC;IAEhB,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;IACzB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC/C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC/B,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;IAE7C,MAAM,KAAK,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAClC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;IAChE,IAAI,CAAC;QACH,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACrE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAChE,2BAA2B,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,oDAAoD;IACtD,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACtC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC;QACrB,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC;QACvB,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,CAAC;QAC7B,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU,CAAC;QAC/B,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC;QACrB,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC;QACnB,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IAEpB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE;QAChB,cAAc;QACd,KAAK,EAAE,wBAAwB,CAAC,QAAQ,EAAE,cAAc,CAAC;QACzD,IAAI;QACJ,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,MAAM;QACf,MAAM,EAAE;YACN,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,2BAA2B,CAClC,WAAmB,EACnB,MAAY,EACZ,OAAiC,EACjC,KAA4B;IAE5B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;YAAE,OAAO;QAEjC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;YACzC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW;gBAAE,SAAS;YAC7E,MAAM,KAAK,GAAI,KAAK,CAAC,OAA4C,CAAC,KAAK,CAAC;YACxE,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS;gBAAE,SAAS;YAEzC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACvC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAAE,SAAS;YAC3C,IAAI,IAAI,GAAG,MAAM,EAAE,CAAC;gBAClB,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACtB,SAAS;YACX,CAAC;YAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9C,IAAI,CAAC,MAAM;gBAAE,SAAS;YAEtB,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACxC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC1C,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAChD,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAClD,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC;YACtB,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC;YACxB,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC;YAC9B,MAAM,CAAC,UAAU,IAAI,UAAU,CAAC;YAChC,MAAM,CAAC,KAAK,IAAI,KAAK,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;YACxD,MAAM,CAAC,IAAI,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,iCAAiC;IACnC,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAC7B,GAAmB,EACnB,GAAQ,EACR,QAAuB,EACvB,KAAiB;IAEjB,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IAExB,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACvE,MAAM,cAAc,GAAG,SAAS,IAAI,KAAK,CAAC,cAAc,CAAC;IACzD,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAClE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAG,kBAAkB,EAAE,CAAC;IAC1C,MAAM,kBAAkB,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC;IAC5D,MAAM,SAAS,GAAG,+BAA+B,CAAC,GAAG,CAAC,CAAC;IAEvD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE;QAChB,cAAc;QACd,QAAQ,EAAE,kBAAkB,CAAC,QAAQ;QACrC,KAAK,EAAE,kBAAkB,CAAC,KAAK;QAC/B,aAAa,EAAE,kBAAkB,CAAC,aAAa;QAC/C,cAAc,EAAE,YAAY,CAAC,QAAQ;QACrC,WAAW,EAAE,YAAY,CAAC,KAAK;QAC/B,mBAAmB,EAAE,YAAY,CAAC,aAAa;QAC/C,0BAA0B,EAAE,kBAAkB,CAAC,0BAA0B,IAAI,IAAI;QACjF,gCAAgC,EAAE,YAAY,CAAC,0BAA0B,IAAI,IAAI;QACjF,gBAAgB,EAAE,SAAS,CAAC,OAAO;QACnC,cAAc,EAAE,SAAS,CAAC,KAAK;QAC/B,KAAK,EAAE;YACL,SAAS,EACP,kBAAkB,CAAC,KAAK,EAAE,SAAS,IAAI,YAAY,CAAC,KAAK,EAAE,SAAS,IAAI,WAAW;YACrF,eAAe,EAAE,YAAY,CAAC,KAAK,EAAE,SAAS,IAAI,WAAW;SAC9D;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAmB;IAC9C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE;YAChB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,IAAI;YACvC,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;YAC3C,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,IAAI,IAAI;YACjD,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,IAAI,IAAI;YACrD,0BAA0B,EAAE,MAAM,CAAC,0BAA0B,IAAI,IAAI;YACrE,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,IAAI,IAAI;YACrD,KAAK,EAAE;gBACL,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS,IAAI,WAAW;aAClD;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAmB;IAChD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;QACtC,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,MAAM,+BAA+B,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;QAClF,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC7C,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE;YAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,IAAI,WAAW;SAChF,CAAC,CAAC,CAAC;QACJ,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE5F,SAAS,4BAA4B,CACnC,GAAmB,EACnB,IAA6B,EAC7B,QAAuB,EACvB,KAAiB;IAEjB,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,MAAM,aAAa,GACjB,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,IAAI,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC;QACrF,CAAC,CAAE,IAAI,CAAC,aAA8C;QACtD,CAAC,CAAC,SAAS,CAAC;IAEhB,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC1D,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IAEnD,IAAI,CAAC;QACH,0BAA0B,CAAC,GAAG,EAAE;YAC9B,QAAQ;YACR,KAAK;YACL,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5C,CAAC,CAAC;QACH,IAAI,eAAe,GAAmB,IAAI,CAAC;QAC3C,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,uBAAuB,CACxD,KAAK,CAAC,cAAc,EACpB,QAAQ,EACR,KAAK,CACN,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,SAAS,8BAA8B,CACrC,GAAmB,EACnB,IAA6B,EAC7B,QAAuB,EACvB,KAAiB;IAEjB,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;IAC3C,IAAI,cAAc,KAAK,SAAS,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;QAC9D,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,4CAA4C,EAAE,CAAC,CAAC;QAC3E,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IACnD,IAAI,CAAC;QACH,0BAA0B,CAAC,GAAG,EAAE,EAAE,0BAA0B,EAAE,cAAc,EAAE,CAAC,CAAC;QAChF,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,SAAS,4BAA4B,CACnC,GAAmB,EACnB,IAA6B,EAC7B,QAAuB,EACvB,KAAiB;IAEjB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IACjC,IAAI,SAAS,KAAK,WAAW,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QACxD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,2CAA2C,EAAE,CAAC,CAAC;QAC1E,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IACnD,IAAI,CAAC;QACH,0BAA0B,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,SAAS,gCAAgC,CACvC,GAAmB,EACnB,IAA6B,EAC7B,QAAuB,EACvB,KAAiB;IAEjB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IACzB,IACE,KAAK,KAAK,SAAS;QACnB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,EACzE,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,mCAAmC,EAAE,CAAC,CAAC;QAClE,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,+BAA+B,CAAC,GAAG,CAAC,CAAC;QACtD,+BAA+B,CAAC,GAAG,EAAE;YACnC,OAAO;YACP,KAAK,EAAE,KAAK,IAAI,QAAQ,CAAC,KAAK;SAC/B,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,SAAS,4BAA4B,CACnC,GAAmB,EACnB,IAA6B,EAC7B,QAAuB,EACvB,KAAiB;IAEjB,MAAM,KAAK,GAAG,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,wCAAwC,EAAE,CAAC,CAAC;QACvE,OAAO;IACT,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE;YAChB,KAAK,EAAE,0EAA0E;SAClF,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,0BAA0B,CAC5C,UAAU,EACV,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,cAAc,CACrB,CAAC;IACF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,6CAA6C,EAAE,CAAC,CAAC;QAC5E,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC,qBAAqB,CAAC,MAAM,CAChE,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,cAAc,EACpB,WAAW,EACX,KAAK,CAAC,gBAAgB,CACvB,CAAC;QACF,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,aAAa,kBAAkB,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC;QACvF,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CACjC,GAAmB,EACnB,IAA6B,EAC7B,QAAuB,EACvB,KAAiB;IAEjB,MAAM,KAAK,GAAG,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC;QAC3D,OAAO;IACT,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,IAAI,OAAe,CAAC;IACpB,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;QACvC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QACD,OAAO,GAAG,GAAG,CAAC;IAChB,CAAC;SAAM,CAAC;QACN,IAAI,CAAC;YACH,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;QAC/F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/E,OAAO;QACT,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACH,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CACzD,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,cAAc,EACpB,OAAO,EACP,EAAE,CACH,CAAC;QACF,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,aAAa,eAAe,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC;QACpF,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,GAAmB,EAAE,IAA6B;IAChF,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,MAAM,aAAa,GACjB,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,IAAI,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC;QACrF,CAAC,CAAE,IAAI,CAAC,aAA8C;QACtD,CAAC,CAAC,SAAS,CAAC;IAEhB,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC1D,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,oBAAoB,CAAC;YACnB,QAAQ;YACR,KAAK;YACL,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5C,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,GAAmB,EAAE,IAA6B;IAChF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IACjC,IAAI,SAAS,KAAK,WAAW,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QACxD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,2CAA2C,EAAE,CAAC,CAAC;QAC1E,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,oBAAoB,CAAC,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,SAAS,wBAAwB,CAAC,GAAmB,EAAE,IAA6B;IAClF,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAClF,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxF,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;IAC3C,MAAM,UAAU,GAAG,cAAc,KAAK,SAAS,IAAI,cAAc,KAAK,MAAM,CAAC;IAE7E,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,IAAI,IAAI;QAAE,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;IACpC,IAAI,MAAM;QAAE,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC;IAC1C,IAAI,SAAS;QAAE,MAAM,CAAC,gBAAgB,GAAG,SAAS,CAAC;IACnD,IAAI,WAAW;QAAE,MAAM,CAAC,kBAAkB,GAAG,WAAW,CAAC;IACzD,IAAI,UAAU;QAAE,MAAM,CAAC,0BAA0B,GAAG,cAAoC,CAAC;IAEzF,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,kFAAkF;AAElF,MAAM,wBAAwB,GAAG,CAAC,CAAC;AACnC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AACvC,MAAM,sBAAsB,GAAG,GAAG,GAAG,IAAI,CAAC;AAE1C,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,qBAAqB,CAAC,CAAC,CAAC;AAC3E,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AAEhD;;;GAGG;AACH,SAAS,sBAAsB,CAAC,GAAW;IACzC,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,4BAA4B,CACnC,GAAQ,EACR,KAAiB;IAEjB,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACxE,OAAO,qBAAqB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AACjD,CAAC;AAOD,SAAS,iBAAiB,CAAC,OAAe,EAAE,QAAgB;IAC1D,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IACjD,CAAC;IACD,IAAI,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC,EAAE,CAAC;QAC1E,IAAI,QAAQ,KAAK,EAAE;YAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IACtE,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,MAAM,KAAK,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC,EAAE,CAAC;QAChE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAC;IACxE,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC;AAYD,SAAS,SAAS,CAAC,QAAgB,EAAE,SAAiB;IACpD,IAAI,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,GAAW,EAAE,KAAa,EAAmB,EAAE;QACxE,IAAI,OAAO,CAAC,KAAK,IAAI,0BAA0B;YAAE,OAAO,IAAI,CAAC;QAC7D,IAAI,KAAK,CAAC;QACV,IAAI,CAAC;YACH,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;YACnB,OAAO;gBACL,IAAI;gBACJ,IAAI,EAAE,GAAG;gBACT,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;aACvB,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;QACnB,IAAI,KAAK,IAAI,wBAAwB,EAAE,CAAC;YACtC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAC3D,CAAC;QACD,IAAI,OAAO,CAAC;QACZ,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAC1C,CAAC;QACD,MAAM,QAAQ,GAAe,EAAE,CAAC;QAChC,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC5C,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE;gBAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzE,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC,EAAE,CAAC;YACH,MAAM,QAAQ,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YAClE,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAChD,IAAI,OAAO,CAAC,KAAK,IAAI,0BAA0B,EAAE,CAAC;gBAChD,SAAS,GAAG,IAAI,CAAC;gBACjB,MAAM;YACR,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YAC9D,IAAI,IAAI;gBAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC;QACD,OAAO;YACL,IAAI;YACJ,IAAI,EAAE,GAAG;YACT,IAAI,EAAE,KAAK;YACX,QAAQ;YACR,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB,CACzB,GAAmB,EACnB,GAAQ,EACR,QAAuB,EACvB,KAAiB;IAEjB,MAAM,KAAK,GAAG,4BAA4B,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACvD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IACvD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IACD,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACjE,IAAI,CAAC,sBAAsB,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1C,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IACD,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC3D,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE;QAChB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,IAAI,EAAE,YAAY,IAAI,GAAG;QACzB,IAAI;KACL,CAAC,CAAC;AACL,CAAC;AAED,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC,SAAS,YAAY,CAAC,GAAW;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAC7B,IAAI,IAAI,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3B,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC;QAC7C,IAAI,IAAI,GAAG,EAAE,IAAI,IAAI,GAAG,EAAE;YAAE,OAAO,KAAK,CAAC;IAC3C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,gBAAgB,CACvB,GAAmB,EACnB,YAAoB,EACpB,QAAiC,EACjC,eAAuB;IAEvB,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,GAAG,sBAAsB,EAAE,CAAC;QACxC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE;YAChB,KAAK,EAAE,2BAA2B;YAClC,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK,EAAE,sBAAsB;SAC9B,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/E,OAAO;IACT,CAAC;IACD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE;YAChB,GAAG,QAAQ;YACX,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE;QAChB,GAAG,QAAQ;QACX,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;KAC/B,CAAC,CAAC;AACL,CAAC;AAED,SAAS,kBAAkB,CACzB,GAAmB,EACnB,GAAQ,EACR,QAAuB,EACvB,KAAiB;IAEjB,MAAM,KAAK,GAAG,4BAA4B,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACvD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,MAAM,aAAa,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAClE,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IACD,IAAI,CAAC,sBAAsB,CAAC,aAAa,CAAC,EAAE,CAAC;QAC3C,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,iBAAiB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACvD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACzC,OAAO;IACT,CAAC;IACD,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAClF,CAAC;AAYD,SAAS,qBAAqB,CAAC,QAAgB;IAC7C,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACrC,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IACvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjC,MAAM,GAAG,GAA4C,EAAE,CAAC;IACxD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,GAAG,CAAC;YAAE,SAAS;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACtD,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,IACE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAC9C,CAAC;YACD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,GAAG,KAAK,MAAM;YAAE,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC;QACrC,IAAI,GAAG,KAAK,aAAa;YAAE,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC;IACrD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,iBAAiB,CAAC,SAAiB,EAAE,MAA4B;IACxE,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC;IACZ,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACjE,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACxD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,SAAS;QACnC,MAAM,IAAI,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC5C,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;YAC7B,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;YACnC,MAAM;YACN,IAAI,EAAE,OAAO;YACb,SAAS,EAAE,KAAK,CAAC,IAAI;SACtB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,eAAe,CACtB,GAAmB,EACnB,GAAQ,EACR,QAAuB,EACvB,KAAiB;IAEjB,MAAM,KAAK,GAAG,4BAA4B,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACvD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;IACvE,MAAM,YAAY,GAAG,iBAAiB,CACpC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,cAAc,EAAE,QAAQ,CAAC,EAChD,cAAc,CACf,CAAC;IACF,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE;QAChB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,GAAG,YAAY,CAAC;KACrC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CACrB,GAAmB,EACnB,GAAQ,EACR,QAAuB,EACvB,KAAiB;IAEjB,MAAM,KAAK,GAAG,4BAA4B,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACvD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IAExB,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7D,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACnE,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;QACrD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;QACrD,OAAO;IACT,CAAC;IACD,IACE,CAAC,SAAS;QACV,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;QACvB,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;QACxB,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EACxB,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACxD,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GACd,MAAM,KAAK,QAAQ;QACjB,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC;QAC5B,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IACxE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACzC,OAAO;IACT,CAAC;IAED,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,sBAAsB,CAAC,CAAC;AACtF,CAAC;AAED,kFAAkF;AAElF,MAAM,qBAAqB,GAAG,EAAE,GAAG,IAAI,CAAC;AAexC,SAAS,aAAa,CAAC,UAAkB;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,IAAI,OAAO,CAAC;IACZ,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SACrD,GAAG,CAAC,CAAC,CAAC,EAAuB,EAAE;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC;QACV,IAAI,CAAC;YACH,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,MAAM,GAAY,IAAI,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,uCAAuC;QACzC,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAE,MAAkC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,wEAAwE;QACxE,MAAM,cAAc,GAClB,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ;YACrC,CAAC,CAAC,IAAI,CAAC,cAAc;YACrB,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ;gBAClC,CAAC,CAAC,IAAI,CAAC,SAAS;gBAChB,CAAC,CAAC,IAAI,CAAC;QACb,OAAO;YACL,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;YACtD,QAAQ,EAAE,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;YAClE,cAAc;YACd,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;YACtD,EAAE,EAAE,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;YAChD,QAAQ,EAAE,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;YAClE,QAAQ,EAAE,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;SACnE,CAAC;IACJ,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;SAC5C,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,eAAe,CAAC,GAAmB,EAAE,QAAuB;IACnE,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,4EAA4E;AAC5E,SAAS,2BAA2B,CAClC,GAAmB,EACnB,GAAQ,EACR,QAAuB,EACvB,KAAiB;IAEjB,MAAM,KAAK,GAAG,4BAA4B,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACvD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,KAAK,CAAC,cAAc,CAAC,CAAC;IAClG,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,eAAe,CAAC,GAAmB,EAAE,GAAQ,EAAE,QAAuB;IAC7E,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACzD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9E,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClD,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,GAAG,qBAAqB,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IACD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/E,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED,sEAAsE;AACtE,SAAS,4BAA4B,CACnC,GAAmB,EACnB,IAA6B,EAC7B,QAAuB,EACvB,KAAiB;IAEjB,MAAM,KAAK,GAAG,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9E,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IACD,IAAI,MAAM,GAA4B,EAAE,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,MAAM,GAAG,CAA4B,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,mEAAmE;IACrE,CAAC;IACD,MAAM,WAAW,GACf,OAAO,MAAM,CAAC,cAAc,KAAK,QAAQ;QACvC,CAAC,CAAC,MAAM,CAAC,cAAc;QACvB,CAAC,CAAC,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;YACpC,CAAC,CAAC,MAAM,CAAC,SAAS;YAClB,CAAC,CAAC,IAAI,CAAC;IACb,IAAI,WAAW,KAAK,KAAK,CAAC,cAAc,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,6CAA6C,EAAE,CAAC,CAAC;QAC5E,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,kFAAkF;AAElF,SAAS,OAAO,CAAC,GAAmB,EAAE,MAAc,EAAE,IAAa;IACjE,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE;QACpB,cAAc,EAAE,iCAAiC;QACjD,eAAe,EAAE,UAAU;KAC5B,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,GAAoB,EACpB,GAAmB;IAEnB,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACpD,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAE/B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,GAAG,GAAG,UAAU,CAAC;AAEvB,kFAAkF;AAElF,SAAS,eAAe,CAAC,KAAiB;IACxC,MAAM,SAAS,GAAG,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,cAAc,CAAC;IACjE,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA+IJ,CAAC;IAEV,MAAM,MAAM,GAAG;yBACQ,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC;oCAChB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAszBrE,CAAC;IAEF,OAAO,iBAAiB,CAAC;QACvB,UAAU,EAAE,OAAO;QACnB,SAAS,EAAE,OAAO;QAClB,QAAQ,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE;QAC3D,oBAAoB,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,cAAc,EAAE;QACzD,IAAI;QACJ,WAAW,EAAE,eAAe;QAC5B,YAAY,EAAE,MAAM;KACrB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAe;IAC3C,OAAO,iBAAiB,CAAC;QACvB,UAAU,EAAE,OAAO;QACnB,SAAS,EAAE,OAAO;QAClB,IAAI,EAAE;2BACiB,YAAY;;6BAEV,GAAG,CAAC,OAAO,CAAC;eAC1B;KACZ,CAAC,CAAC;AACL,CAAC;AAED,kFAAkF;AAElF,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoSvB,CAAC","sourcesContent":["import { existsSync, readdirSync, readFileSync, rmSync, statSync } from \"fs\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport { basename, join, resolve as pathResolve, sep as pathSep } from \"path\";\nimport { MikanModels, SessionStore } from \"../../harness/index.js\";\n\nimport {\n loadConversationAutoReplyConfig,\n loadGlobalSettings,\n resolveConversationSettings,\n saveConversationAutoReplyConfig,\n updateConversationSettings,\n updateGlobalSettings,\n type AgentConfig,\n} from \"../../config.js\";\nimport { escapeHtml } from \"../../utils/html.js\";\nimport { readRawBody } from \"../../utils/http-body.js\";\nimport { renderPortalShell } from \"../../portal-shell.js\";\nimport { resolveExistingSessionFile } from \"../session-view/service.js\";\nimport { PRODUCT_NAME } from \"../../platform-messages.js\";\nimport { resolveActorVaultKey } from \"../../vault/routing.js\";\nimport { sharedVaultKey } from \"../../vault/index.js\";\nimport { modelKey, resolveAdminModelAccessStatuses } from \"./provider-models.js\";\nimport type { AdminToken } from \"./store.js\";\n\nexport type { AdminRuntimeBridge, AdminServices } from \"./types.js\";\nimport type { AdminServices } from \"./types.js\";\n\n// ── Handler ────────────────────────────────────────────────────────────────────\n\nexport async function handleAdminRequest(\n req: IncomingMessage,\n res: ServerResponse,\n url: URL,\n services: AdminServices,\n): Promise<boolean> {\n if (!url.pathname.startsWith(\"/admin\")) return false;\n\n if (req.method === \"GET\" && url.pathname === \"/admin\") {\n const provided = url.searchParams.get(\"token\") ?? \"\";\n const token = services.adminTokenStore.peek(provided);\n if (!token) {\n res.writeHead(403, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(\n renderAdminErrorPage(\n \"Admin link is missing, invalid, or expired. Send `/admin` to the bot to get a fresh link.\",\n ),\n );\n return true;\n }\n res.writeHead(200, {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n });\n res.end(renderAdminPage(token));\n return true;\n }\n\n if (url.pathname.startsWith(\"/admin/api/\")) {\n await routeApiRequest(req, res, url, services);\n return true;\n }\n\n return false;\n}\n\n// ── API routing ────────────────────────────────────────────────────────────────\n\nasync function routeApiRequest(\n req: IncomingMessage,\n res: ServerResponse,\n url: URL,\n services: AdminServices,\n): Promise<void> {\n if (req.method === \"GET\") {\n const token = services.adminTokenStore.peek(url.searchParams.get(\"token\") ?? \"\");\n if (!token) {\n jsonRes(res, 403, { error: \"Unauthorized\" });\n return;\n }\n if (url.pathname === \"/admin/api/me\") {\n serveMe(res, token);\n return;\n }\n if (url.pathname === \"/admin/api/conversations\") {\n serveConversationsList(res, services);\n return;\n }\n if (url.pathname === \"/admin/api/session-usage\") {\n serveSessionUsage(res, services);\n return;\n }\n if (url.pathname === \"/admin/api/conversation-usage\") {\n serveConversationUsage(res, url, services);\n return;\n }\n if (url.pathname === \"/admin/api/conversation-state\") {\n serveConversationState(res, url, services, token);\n return;\n }\n if (url.pathname === \"/admin/api/settings/global\") {\n serveGlobalSettings(res);\n return;\n }\n if (url.pathname === \"/admin/api/models\") {\n void serveModelsList(res);\n return;\n }\n if (url.pathname === \"/admin/api/workspace/tree\") {\n serveWorkspaceTree(res, url, services, token);\n return;\n }\n if (url.pathname === \"/admin/api/workspace/file\") {\n serveWorkspaceFile(res, url, services, token);\n return;\n }\n if (url.pathname === \"/admin/api/skills\") {\n serveSkillsList(res, url, services, token);\n return;\n }\n if (url.pathname === \"/admin/api/skills/file\") {\n serveSkillFile(res, url, services, token);\n return;\n }\n if (url.pathname === \"/admin/api/events\") {\n serveEventsList(res, services);\n return;\n }\n if (url.pathname === \"/admin/api/events/file\") {\n serveEventsFile(res, url, services);\n return;\n }\n if (url.pathname === \"/admin/api/conversations/events\") {\n serveConversationEventsList(res, url, services, token);\n return;\n }\n jsonRes(res, 404, { error: \"Not found\" });\n return;\n }\n\n if (req.method !== \"POST\") {\n jsonRes(res, 405, { error: \"Method not allowed\" });\n return;\n }\n\n const body = await readJsonBody(req, res);\n if (!body) return;\n\n const rawToken = typeof body.token === \"string\" ? body.token : \"\";\n const token = services.adminTokenStore.peek(rawToken);\n if (!token) {\n jsonRes(res, 403, { error: \"Unauthorized\" });\n return;\n }\n if (url.pathname === \"/admin/api/conversations/model\") {\n serveConversationModelUpdate(res, body, services, token);\n return;\n }\n if (url.pathname === \"/admin/api/conversations/sandbox\") {\n serveConversationSandboxUpdate(res, body, services, token);\n return;\n }\n if (url.pathname === \"/admin/api/conversations/auto-reply\") {\n serveConversationAutoReplyUpdate(res, body, services, token);\n return;\n }\n if (url.pathname === \"/admin/api/conversations/slack\") {\n serveConversationSlackUpdate(res, body, services, token);\n return;\n }\n if (url.pathname === \"/admin/api/conversations/session-link\") {\n serveConversationSessionLink(res, body, services, token);\n return;\n }\n if (url.pathname === \"/admin/api/conversations/login-link\") {\n serveConversationLoginLink(res, body, services, token);\n return;\n }\n if (url.pathname === \"/admin/api/conversations/events/delete\") {\n serveConversationEventDelete(res, body, services, token);\n return;\n }\n if (url.pathname === \"/admin/api/settings/model\") {\n serveGlobalModelUpdate(res, body);\n return;\n }\n if (url.pathname === \"/admin/api/settings/sandbox\") {\n serveGlobalSandboxUpdate(res, body);\n return;\n }\n if (url.pathname === \"/admin/api/settings/slack\") {\n serveGlobalSlackUpdate(res, body);\n return;\n }\n jsonRes(res, 404, { error: \"Not found\" });\n}\n\n// ── Scope helpers ──────────────────────────────────────────────────────────────\n\nfunction resolveConversationId(\n requested: string,\n token: AdminToken,\n): { conversationId: string; error?: string } {\n if (!requested) return { conversationId: token.conversationId };\n if (requested === token.conversationId) return { conversationId: requested };\n if (requested.includes(\"/\") || requested.includes(\"..\")) {\n return { conversationId: requested, error: \"Invalid conversationId.\" };\n }\n return { conversationId: requested };\n}\n\nfunction resolveTargetConversation(\n body: Record<string, unknown>,\n token: AdminToken,\n): { conversationId: string; error?: string } {\n const requested = typeof body.conversationId === \"string\" ? body.conversationId.trim() : \"\";\n return resolveConversationId(requested, token);\n}\n\nfunction requireAdminWorkingDir(res: ServerResponse, services: AdminServices): string | null {\n if (!services.workingDir) {\n jsonRes(res, 503, { error: \"Working directory not available\" });\n return null;\n }\n return services.workingDir;\n}\n\n// ── API handlers ───────────────────────────────────────────────────────────────\n\nfunction serveMe(res: ServerResponse, token: AdminToken): void {\n jsonRes(res, 200, {\n platform: token.platform,\n platformUserId: token.platformUserId,\n platformUserName: token.platformUserName ?? null,\n conversationId: token.conversationId,\n expiresAt: token.expiresAt,\n });\n}\n\nconst SETTINGS_FILES = new Set([\"settings.json\", \"auto-reply\", \"auto-reply.disabled\"]);\n\nfunction listConversationDirs(workingDir: string): string[] {\n if (!existsSync(workingDir)) return [];\n const skip = new Set([\"vaults\", \"skills\", \"events\", \"node_modules\", \".git\"]);\n return readdirSync(workingDir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() && !entry.name.startsWith(\".\") && !skip.has(entry.name))\n .map((entry) => entry.name)\n .filter((name) => {\n const dir = join(workingDir, name);\n try {\n const items = readdirSync(dir);\n // Conversation settings migrated to the state dir, so a sessions/\n // subdir is the primary marker for existing conversation dirs.\n return items.some(\n (item) => item === \"sessions\" || SETTINGS_FILES.has(item) || item.endsWith(\".jsonl\"),\n );\n } catch {\n return false;\n }\n })\n .toSorted((a, b) => a.localeCompare(b));\n}\n\nfunction conversationLastActivity(workingDir: string, conversationId: string): number | null {\n const dir = join(workingDir, conversationId);\n if (!existsSync(dir)) return null;\n let latest = 0;\n const visit = (path: string, depth: number): void => {\n if (depth > 3) return;\n let entries;\n try {\n entries = readdirSync(path, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const full = join(path, entry.name);\n if (entry.isDirectory()) {\n visit(full, depth + 1);\n continue;\n }\n try {\n const stats = statSync(full);\n if (stats.mtimeMs > latest) latest = stats.mtimeMs;\n } catch {\n // ignore\n }\n }\n };\n visit(dir, 0);\n return latest > 0 ? latest : null;\n}\n\nfunction conversationDisplayLabel(services: AdminServices, conversationId: string): string {\n for (const [platform, bot] of Object.entries(services.botsByPlatform ?? {})) {\n const channel = bot?.getMessagingInfo().channels.find((c) => c.id === conversationId);\n if (channel) return `${platform}:#${channel.name}:${conversationId}`;\n }\n return conversationId;\n}\n\nfunction serveConversationsList(res: ServerResponse, services: AdminServices): void {\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n\n const ids = listConversationDirs(workingDir);\n\n const runningKeys = new Set<string>(\n services.runtime?.getRunningSessions().map((s) => s.sessionKey) ?? [],\n );\n\n const conversations = ids.map((conversationId) => {\n const lastActivity = conversationLastActivity(workingDir, conversationId);\n const running = Array.from(runningKeys).some(\n (key) => key === conversationId || key.startsWith(`${conversationId}:`),\n );\n return {\n conversationId,\n label: conversationDisplayLabel(services, conversationId),\n running,\n lastActivityAt: lastActivity,\n };\n });\n\n jsonRes(res, 200, { conversations });\n}\n\ninterface SessionUsageRow {\n conversationId: string;\n label: string;\n fileName: string;\n sessionId: string;\n updatedAt: string;\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n total: number;\n cost: number;\n}\n\nfunction serveSessionUsage(res: ServerResponse, services: AdminServices): void {\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n\n const rows = listConversationDirs(workingDir)\n .flatMap((conversationId) =>\n listConversationSessionUsage(\n workingDir,\n conversationId,\n conversationDisplayLabel(services, conversationId),\n ),\n )\n .toSorted((a, b) => b.total - a.total)\n .slice(0, 20);\n\n jsonRes(res, 200, { sessions: rows });\n}\n\nfunction listConversationSessionUsage(\n workingDir: string,\n conversationId: string,\n label: string,\n): SessionUsageRow[] {\n const sessionDir = join(workingDir, conversationId, \"sessions\");\n try {\n return readdirSync(sessionDir, { withFileTypes: true })\n .filter((entry) => entry.isFile() && entry.name.endsWith(\".jsonl\"))\n .flatMap((entry) => readSessionUsage(join(sessionDir, entry.name), conversationId, label));\n } catch {\n return [];\n }\n}\n\nfunction readSessionUsage(\n sessionFile: string,\n conversationId: string,\n label: string,\n): SessionUsageRow[] {\n try {\n const manager = SessionStore.open(sessionFile);\n const header = manager.getHeader();\n if (!header) return [];\n\n const entries = manager.getEntries();\n const usage = entries.reduce(\n (sum, entry) => {\n if (entry.type !== \"message\" || entry.message.role !== \"assistant\") return sum;\n const message = entry.message as unknown as AssistantUsageMessage;\n const item = message.usage;\n if (!item) return sum;\n sum.input += numberOrZero(item.input);\n sum.output += numberOrZero(item.output);\n sum.cacheRead += numberOrZero(item.cacheRead);\n sum.cacheWrite += numberOrZero(item.cacheWrite);\n sum.cost += numberOrZero(item.cost?.total);\n return sum;\n },\n { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 },\n );\n const total = usage.input + usage.output + usage.cacheRead + usage.cacheWrite;\n if (total <= 0) return [];\n\n return [\n {\n conversationId,\n label,\n fileName: basename(sessionFile),\n sessionId: header.id,\n updatedAt: entries.at(-1)?.timestamp ?? header.timestamp,\n ...usage,\n total,\n },\n ];\n } catch {\n return [];\n }\n}\n\ninterface AssistantUsageMessage {\n usage?: {\n input?: unknown;\n output?: unknown;\n cacheRead?: unknown;\n cacheWrite?: unknown;\n cost?: { total?: unknown };\n };\n}\n\nfunction numberOrZero(value: unknown): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : 0;\n}\n\ninterface UsageBucket {\n date: string;\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n total: number;\n cost: number;\n}\n\nfunction localDayKey(d: Date): string {\n const year = d.getFullYear();\n const month = String(d.getMonth() + 1).padStart(2, \"0\");\n const day = String(d.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n}\n\nfunction emptyBucket(date: string): UsageBucket {\n return { date, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0, cost: 0 };\n}\n\n/** Per-conversation daily token usage over the last N days (N clamped to 1..7). */\nfunction serveConversationUsage(res: ServerResponse, url: URL, services: AdminServices): void {\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n\n const conversationId = url.searchParams.get(\"conversationId\") ?? \"\";\n if (!conversationId || !listConversationDirs(workingDir).includes(conversationId)) {\n jsonRes(res, 400, { error: \"Unknown conversationId\" });\n return;\n }\n\n const days = 14;\n\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n const buckets = new Map<string, UsageBucket>();\n const order: string[] = [];\n for (let i = days - 1; i >= 0; i--) {\n const d = new Date(today);\n d.setDate(today.getDate() - i);\n const key = localDayKey(d);\n order.push(key);\n buckets.set(key, emptyBucket(key));\n }\n const cutoff = new Date(today);\n cutoff.setDate(today.getDate() - (days - 1));\n\n const flags = { hasOlder: false };\n const sessionDir = join(workingDir, conversationId, \"sessions\");\n try {\n for (const entry of readdirSync(sessionDir, { withFileTypes: true })) {\n if (!entry.isFile() || !entry.name.endsWith(\".jsonl\")) continue;\n accumulateSessionUsageByDay(join(sessionDir, entry.name), cutoff, buckets, flags);\n }\n } catch {\n // No sessions directory yet — return empty buckets.\n }\n\n const series = order.map((key) => buckets.get(key) ?? emptyBucket(key));\n const totals = series.reduce((sum, b) => {\n sum.input += b.input;\n sum.output += b.output;\n sum.cacheRead += b.cacheRead;\n sum.cacheWrite += b.cacheWrite;\n sum.total += b.total;\n sum.cost += b.cost;\n return sum;\n }, emptyBucket(\"\"));\n\n jsonRes(res, 200, {\n conversationId,\n label: conversationDisplayLabel(services, conversationId),\n days,\n hasOlder: flags.hasOlder,\n buckets: series,\n totals: {\n input: totals.input,\n output: totals.output,\n cacheRead: totals.cacheRead,\n cacheWrite: totals.cacheWrite,\n total: totals.total,\n cost: totals.cost,\n },\n });\n}\n\nfunction accumulateSessionUsageByDay(\n sessionFile: string,\n cutoff: Date,\n buckets: Map<string, UsageBucket>,\n flags: { hasOlder: boolean },\n): void {\n try {\n const manager = SessionStore.open(sessionFile);\n if (!manager.getHeader()) return;\n\n for (const entry of manager.getEntries()) {\n if (entry.type !== \"message\" || entry.message.role !== \"assistant\") continue;\n const usage = (entry.message as unknown as AssistantUsageMessage).usage;\n if (!usage || !entry.timestamp) continue;\n\n const when = new Date(entry.timestamp);\n if (Number.isNaN(when.getTime())) continue;\n if (when < cutoff) {\n flags.hasOlder = true;\n continue;\n }\n\n const bucket = buckets.get(localDayKey(when));\n if (!bucket) continue;\n\n const input = numberOrZero(usage.input);\n const output = numberOrZero(usage.output);\n const cacheRead = numberOrZero(usage.cacheRead);\n const cacheWrite = numberOrZero(usage.cacheWrite);\n bucket.input += input;\n bucket.output += output;\n bucket.cacheRead += cacheRead;\n bucket.cacheWrite += cacheWrite;\n bucket.total += input + output + cacheRead + cacheWrite;\n bucket.cost += numberOrZero(usage.cost?.total);\n }\n } catch {\n // Skip unreadable session files.\n }\n}\n\nfunction serveConversationState(\n res: ServerResponse,\n url: URL,\n services: AdminServices,\n token: AdminToken,\n): void {\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n\n const requested = url.searchParams.get(\"conversationId\")?.trim() ?? \"\";\n const conversationId = requested || token.conversationId;\n if (conversationId.includes(\"/\") || conversationId.includes(\"..\")) {\n jsonRes(res, 400, { error: \"Invalid conversationId\" });\n return;\n }\n\n const dir = join(workingDir, conversationId);\n const globalConfig = loadGlobalSettings();\n const conversationConfig = resolveConversationSettings(dir);\n const autoReply = loadConversationAutoReplyConfig(dir);\n\n jsonRes(res, 200, {\n conversationId,\n provider: conversationConfig.provider,\n model: conversationConfig.model,\n thinkingLevel: conversationConfig.thinkingLevel,\n globalProvider: globalConfig.provider,\n globalModel: globalConfig.model,\n globalThinkingLevel: globalConfig.thinkingLevel,\n sandboxImageWorkspaceMount: conversationConfig.sandboxImageWorkspaceMount ?? null,\n globalSandboxImageWorkspaceMount: globalConfig.sandboxImageWorkspaceMount ?? null,\n autoReplyEnabled: autoReply.enabled,\n autoReplyRules: autoReply.rules,\n slack: {\n replyMode:\n conversationConfig.slack?.replyMode ?? globalConfig.slack?.replyMode ?? \"top-level\",\n globalReplyMode: globalConfig.slack?.replyMode ?? \"top-level\",\n },\n });\n}\n\nfunction serveGlobalSettings(res: ServerResponse): void {\n try {\n const config = loadGlobalSettings();\n jsonRes(res, 200, {\n provider: config.provider,\n model: config.model,\n thinkingLevel: config.thinkingLevel,\n sandboxCpus: config.sandboxCpus ?? null,\n sandboxMemory: config.sandboxMemory ?? null,\n sandboxBoostCpus: config.sandboxBoostCpus ?? null,\n sandboxBoostMemory: config.sandboxBoostMemory ?? null,\n sandboxImageWorkspaceMount: config.sandboxImageWorkspaceMount ?? null,\n defaultSharedVault: config.defaultSharedVault ?? null,\n slack: {\n replyMode: config.slack?.replyMode ?? \"top-level\",\n },\n });\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n}\n\nasync function serveModelsList(res: ServerResponse): Promise<void> {\n try {\n const registry = MikanModels.create();\n const availableModels = await registry.getAvailable();\n const statuses = await resolveAdminModelAccessStatuses(registry, availableModels);\n const models = availableModels.map((model) => ({\n provider: model.provider,\n id: model.id,\n name: model.name ?? model.id,\n reasoning: model.reasoning,\n input: model.input,\n contextWindow: model.contextWindow,\n maxTokens: model.maxTokens,\n status: statuses.get(modelKey(model.provider, model.id))?.status ?? \"available\",\n }));\n jsonRes(res, 200, { models });\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n}\n\nconst VALID_THINKING_LEVELS = new Set([\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"]);\n\nfunction serveConversationModelUpdate(\n res: ServerResponse,\n body: Record<string, unknown>,\n services: AdminServices,\n token: AdminToken,\n): void {\n const provider = typeof body.provider === \"string\" ? body.provider.trim() : \"\";\n const model = typeof body.model === \"string\" ? body.model.trim() : \"\";\n const thinkingLevel =\n typeof body.thinkingLevel === \"string\" && VALID_THINKING_LEVELS.has(body.thinkingLevel)\n ? (body.thinkingLevel as AgentConfig[\"thinkingLevel\"])\n : undefined;\n\n if (!provider || !model) {\n jsonRes(res, 400, { error: \"Missing provider or model\" });\n return;\n }\n const scope = resolveTargetConversation(body, token);\n if (scope.error) {\n jsonRes(res, 403, { error: scope.error });\n return;\n }\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n const dir = join(workingDir, scope.conversationId);\n\n try {\n updateConversationSettings(dir, {\n provider,\n model,\n ...(thinkingLevel ? { thinkingLevel } : {}),\n });\n let runtimeSwitched: boolean | null = null;\n if (services.runtime) {\n runtimeSwitched = services.runtime.switchConversationModel(\n scope.conversationId,\n provider,\n model,\n );\n }\n jsonRes(res, 200, { ok: true, runtimeSwitched });\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n}\n\nfunction serveConversationSandboxUpdate(\n res: ServerResponse,\n body: Record<string, unknown>,\n services: AdminServices,\n token: AdminToken,\n): void {\n const workspaceMount = body.workspaceMount;\n if (workspaceMount !== \"private\" && workspaceMount !== \"full\") {\n jsonRes(res, 400, { error: \"workspaceMount must be 'private' or 'full'\" });\n return;\n }\n const scope = resolveTargetConversation(body, token);\n if (scope.error) {\n jsonRes(res, 403, { error: scope.error });\n return;\n }\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n const dir = join(workingDir, scope.conversationId);\n try {\n updateConversationSettings(dir, { sandboxImageWorkspaceMount: workspaceMount });\n jsonRes(res, 200, { ok: true });\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n}\n\nfunction serveConversationSlackUpdate(\n res: ServerResponse,\n body: Record<string, unknown>,\n services: AdminServices,\n token: AdminToken,\n): void {\n const replyMode = body.replyMode;\n if (replyMode !== \"top-level\" && replyMode !== \"thread\") {\n jsonRes(res, 400, { error: \"replyMode must be 'top-level' or 'thread'\" });\n return;\n }\n const scope = resolveTargetConversation(body, token);\n if (scope.error) {\n jsonRes(res, 403, { error: scope.error });\n return;\n }\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n const dir = join(workingDir, scope.conversationId);\n try {\n updateConversationSettings(dir, { slack: { replyMode } });\n jsonRes(res, 200, { ok: true });\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n}\n\nfunction serveConversationAutoReplyUpdate(\n res: ServerResponse,\n body: Record<string, unknown>,\n services: AdminServices,\n token: AdminToken,\n): void {\n const enabled = body.enabled === true;\n const rules = body.rules;\n if (\n rules !== undefined &&\n (!Array.isArray(rules) || rules.some((rule) => typeof rule !== \"string\"))\n ) {\n jsonRes(res, 400, { error: \"rules must be an array of strings\" });\n return;\n }\n const scope = resolveTargetConversation(body, token);\n if (scope.error) {\n jsonRes(res, 403, { error: scope.error });\n return;\n }\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n const dir = join(workingDir, scope.conversationId);\n try {\n const existing = loadConversationAutoReplyConfig(dir);\n saveConversationAutoReplyConfig(dir, {\n enabled,\n rules: rules ?? existing.rules,\n });\n jsonRes(res, 200, { ok: true });\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n}\n\nfunction serveConversationSessionLink(\n res: ServerResponse,\n body: Record<string, unknown>,\n services: AdminServices,\n token: AdminToken,\n): void {\n const scope = resolveTargetConversation(body, token);\n if (scope.error) {\n jsonRes(res, 403, { error: scope.error });\n return;\n }\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n if (!services.sessionViewTokenStore) {\n jsonRes(res, 503, { error: \"Session view token store not available\" });\n return;\n }\n if (!services.portalBaseUrl) {\n jsonRes(res, 503, {\n error: \"Portal URL not configured. Set MIKAN_LINK_URL to enable link generation.\",\n });\n return;\n }\n\n const sessionFile = resolveExistingSessionFile(\n workingDir,\n scope.conversationId,\n scope.conversationId,\n );\n if (!sessionFile) {\n jsonRes(res, 404, { error: \"No session file found for this conversation\" });\n return;\n }\n\n try {\n const { token: viewToken } = services.sessionViewTokenStore.create(\n token.platform,\n token.platformUserId,\n scope.conversationId,\n scope.conversationId,\n sessionFile,\n token.platformUserName,\n );\n const url = `${services.portalBaseUrl}/session?token=${encodeURIComponent(viewToken)}`;\n jsonRes(res, 200, { ok: true, url });\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n}\n\nfunction serveConversationLoginLink(\n res: ServerResponse,\n body: Record<string, unknown>,\n services: AdminServices,\n token: AdminToken,\n): void {\n const scope = resolveTargetConversation(body, token);\n if (scope.error) {\n jsonRes(res, 403, { error: scope.error });\n return;\n }\n if (!services.portalBaseUrl) {\n jsonRes(res, 503, { error: \"Portal URL not configured.\" });\n return;\n }\n if (!services.sandbox) {\n jsonRes(res, 503, { error: \"Sandbox config not available.\" });\n return;\n }\n const sharedName = typeof body.sharedVault === \"string\" ? body.sharedVault.trim() : \"\";\n let vaultId: string;\n if (sharedName) {\n const key = sharedVaultKey(sharedName);\n if (!key) {\n jsonRes(res, 400, { error: \"Invalid shared vault name\" });\n return;\n }\n vaultId = key;\n } else {\n try {\n vaultId = resolveActorVaultKey(services.sandbox, token.platformUserId, scope.conversationId);\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n return;\n }\n }\n try {\n const { token: linkToken } = services.linkTokenStore.create(\n token.platform,\n token.platformUserId,\n scope.conversationId,\n vaultId,\n \"\",\n );\n const url = `${services.portalBaseUrl}/link?token=${encodeURIComponent(linkToken)}`;\n jsonRes(res, 200, { ok: true, url, vaultId });\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n}\n\nfunction serveGlobalModelUpdate(res: ServerResponse, body: Record<string, unknown>): void {\n const provider = typeof body.provider === \"string\" ? body.provider.trim() : \"\";\n const model = typeof body.model === \"string\" ? body.model.trim() : \"\";\n const thinkingLevel =\n typeof body.thinkingLevel === \"string\" && VALID_THINKING_LEVELS.has(body.thinkingLevel)\n ? (body.thinkingLevel as AgentConfig[\"thinkingLevel\"])\n : undefined;\n\n if (!provider || !model) {\n jsonRes(res, 400, { error: \"Missing provider or model\" });\n return;\n }\n\n try {\n updateGlobalSettings({\n provider,\n model,\n ...(thinkingLevel ? { thinkingLevel } : {}),\n });\n jsonRes(res, 200, { ok: true });\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n}\n\nfunction serveGlobalSlackUpdate(res: ServerResponse, body: Record<string, unknown>): void {\n const replyMode = body.replyMode;\n if (replyMode !== \"top-level\" && replyMode !== \"thread\") {\n jsonRes(res, 400, { error: \"replyMode must be 'top-level' or 'thread'\" });\n return;\n }\n\n try {\n updateGlobalSettings({ slack: { replyMode } });\n jsonRes(res, 200, { ok: true });\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n}\n\nfunction serveGlobalSandboxUpdate(res: ServerResponse, body: Record<string, unknown>): void {\n const cpus = typeof body.cpus === \"string\" ? body.cpus.trim() : \"\";\n const memory = typeof body.memory === \"string\" ? body.memory.trim() : \"\";\n const boostCpus = typeof body.boostCpus === \"string\" ? body.boostCpus.trim() : \"\";\n const boostMemory = typeof body.boostMemory === \"string\" ? body.boostMemory.trim() : \"\";\n const workspaceMount = body.workspaceMount;\n const validMount = workspaceMount === \"private\" || workspaceMount === \"full\";\n\n const update: Partial<AgentConfig> = {};\n if (cpus) update.sandboxCpus = cpus;\n if (memory) update.sandboxMemory = memory;\n if (boostCpus) update.sandboxBoostCpus = boostCpus;\n if (boostMemory) update.sandboxBoostMemory = boostMemory;\n if (validMount) update.sandboxImageWorkspaceMount = workspaceMount as \"private\" | \"full\";\n\n if (Object.keys(update).length === 0) {\n jsonRes(res, 400, { error: \"No valid sandbox fields provided\" });\n return;\n }\n\n try {\n updateGlobalSettings(update);\n jsonRes(res, 200, { ok: true });\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n}\n\n// ── Workspace ──────────────────────────────────────────────────────────────────\n\nconst WORKSPACE_TREE_MAX_DEPTH = 4;\nconst WORKSPACE_TREE_MAX_ENTRIES = 800;\nconst PREVIEW_FILE_MAX_BYTES = 256 * 1024;\n\nconst WORKSPACE_TOP_FILES = new Set([\"auto-reply\", \"auto-reply.disabled\"]);\nconst WORKSPACE_TOP_DIRS = new Set([\"scratch\"]);\n\n/**\n * Limit what the admin UI can browse under a conversation directory.\n * Allowed: top-level \"scratch/\" subtree, and the two auto-reply marker files.\n */\nfunction isWorkspacePathAllowed(rel: string): boolean {\n if (rel === \"\") return true;\n const segments = rel.split(\"/\").filter(Boolean);\n if (segments.length === 0) return true;\n const first = segments[0];\n if (segments.length === 1) {\n return WORKSPACE_TOP_DIRS.has(first) || WORKSPACE_TOP_FILES.has(first);\n }\n return WORKSPACE_TOP_DIRS.has(first);\n}\n\nfunction resolveConversationFromQuery(\n url: URL,\n token: AdminToken,\n): { conversationId: string; error?: string } {\n const requested = (url.searchParams.get(\"conversationId\") ?? \"\").trim();\n return resolveConversationId(requested, token);\n}\n\ninterface SafePathResult {\n absolute: string;\n error?: string;\n}\n\nfunction safeJoinUnderRoot(rootDir: string, relative: string): SafePathResult {\n if (relative.startsWith(\"/\") || relative.includes(\"\\0\")) {\n return { absolute: \"\", error: \"Invalid path\" };\n }\n if (relative.split(/[\\\\/]+/).some((part) => part === \"..\" || part === \"\")) {\n if (relative !== \"\") return { absolute: \"\", error: \"Invalid path\" };\n }\n const target = pathResolve(rootDir, relative);\n const rootAbs = pathResolve(rootDir);\n if (target !== rootAbs && !target.startsWith(rootAbs + pathSep)) {\n return { absolute: \"\", error: \"Path escapes conversation directory\" };\n }\n return { absolute: target };\n}\n\ninterface TreeNode {\n name: string;\n path: string;\n type: \"dir\" | \"file\";\n size?: number;\n mtimeMs?: number;\n children?: TreeNode[];\n truncated?: boolean;\n}\n\nfunction buildTree(startDir: string, relPrefix: string): TreeNode | null {\n let counter = { value: 0 };\n const walk = (dir: string, rel: string, depth: number): TreeNode | null => {\n if (counter.value >= WORKSPACE_TREE_MAX_ENTRIES) return null;\n let stats;\n try {\n stats = statSync(dir);\n } catch {\n return null;\n }\n const name = rel === \"\" ? \".\" : basename(rel);\n if (!stats.isDirectory()) {\n counter.value += 1;\n return {\n name,\n path: rel,\n type: \"file\",\n size: stats.size,\n mtimeMs: stats.mtimeMs,\n };\n }\n counter.value += 1;\n if (depth >= WORKSPACE_TREE_MAX_DEPTH) {\n return { name, path: rel, type: \"dir\", truncated: true };\n }\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return { name, path: rel, type: \"dir\" };\n }\n const children: TreeNode[] = [];\n let truncated = false;\n for (const entry of entries.toSorted((a, b) => {\n if (a.isDirectory() !== b.isDirectory()) return a.isDirectory() ? -1 : 1;\n return a.name.localeCompare(b.name);\n })) {\n const childRel = rel === \"\" ? entry.name : `${rel}/${entry.name}`;\n if (!isWorkspacePathAllowed(childRel)) continue;\n if (counter.value >= WORKSPACE_TREE_MAX_ENTRIES) {\n truncated = true;\n break;\n }\n const node = walk(join(dir, entry.name), childRel, depth + 1);\n if (node) children.push(node);\n }\n return {\n name,\n path: rel,\n type: \"dir\",\n children,\n ...(truncated ? { truncated: true } : {}),\n };\n };\n const node = walk(startDir, relPrefix, 0);\n return node;\n}\n\nfunction serveWorkspaceTree(\n res: ServerResponse,\n url: URL,\n services: AdminServices,\n token: AdminToken,\n): void {\n const scope = resolveConversationFromQuery(url, token);\n if (scope.error) {\n jsonRes(res, 403, { error: scope.error });\n return;\n }\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n const convDir = join(workingDir, scope.conversationId);\n if (!existsSync(convDir)) {\n jsonRes(res, 200, { conversationId: scope.conversationId, tree: null });\n return;\n }\n const requestedSub = (url.searchParams.get(\"path\") ?? \"\").trim();\n if (!isWorkspacePathAllowed(requestedSub)) {\n jsonRes(res, 403, { error: \"Workspace path is not exposed\" });\n return;\n }\n const startSafe = safeJoinUnderRoot(convDir, requestedSub);\n if (startSafe.error) {\n jsonRes(res, 400, { error: startSafe.error });\n return;\n }\n const tree = buildTree(startSafe.absolute, requestedSub);\n jsonRes(res, 200, {\n conversationId: scope.conversationId,\n root: requestedSub || \".\",\n tree,\n });\n}\n\nconst BINARY_PROBE_BYTES = 4096;\n\nfunction looksTextual(buf: Buffer): boolean {\n const limit = Math.min(buf.length, BINARY_PROBE_BYTES);\n for (let i = 0; i < limit; i++) {\n const byte = buf[i];\n if (byte === 0) return false;\n if (byte < 9) return false;\n if (byte === 11 || byte === 12) return false;\n if (byte > 13 && byte < 32) return false;\n }\n return true;\n}\n\nfunction servePreviewFile(\n res: ServerResponse,\n absolutePath: string,\n metadata: Record<string, unknown>,\n notFoundMessage: string,\n): void {\n let stats;\n try {\n stats = statSync(absolutePath);\n } catch {\n jsonRes(res, 404, { error: notFoundMessage });\n return;\n }\n if (!stats.isFile()) {\n jsonRes(res, 400, { error: \"Not a file\" });\n return;\n }\n if (stats.size > PREVIEW_FILE_MAX_BYTES) {\n jsonRes(res, 413, {\n error: \"File too large to preview\",\n size: stats.size,\n limit: PREVIEW_FILE_MAX_BYTES,\n });\n return;\n }\n let buf: Buffer;\n try {\n buf = readFileSync(absolutePath);\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n return;\n }\n if (!looksTextual(buf)) {\n jsonRes(res, 200, {\n ...metadata,\n size: stats.size,\n mtimeMs: stats.mtimeMs,\n binary: true,\n content: null,\n });\n return;\n }\n jsonRes(res, 200, {\n ...metadata,\n size: stats.size,\n mtimeMs: stats.mtimeMs,\n binary: false,\n content: buf.toString(\"utf-8\"),\n });\n}\n\nfunction serveWorkspaceFile(\n res: ServerResponse,\n url: URL,\n services: AdminServices,\n token: AdminToken,\n): void {\n const scope = resolveConversationFromQuery(url, token);\n if (scope.error) {\n jsonRes(res, 403, { error: scope.error });\n return;\n }\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n const requestedPath = (url.searchParams.get(\"path\") ?? \"\").trim();\n if (!requestedPath) {\n jsonRes(res, 400, { error: \"Missing path\" });\n return;\n }\n if (!isWorkspacePathAllowed(requestedPath)) {\n jsonRes(res, 403, { error: \"Workspace path is not exposed\" });\n return;\n }\n const convDir = join(workingDir, scope.conversationId);\n const safe = safeJoinUnderRoot(convDir, requestedPath);\n if (safe.error) {\n jsonRes(res, 400, { error: safe.error });\n return;\n }\n servePreviewFile(res, safe.absolute, { path: requestedPath }, \"File not found\");\n}\n\n// ── Skills ─────────────────────────────────────────────────────────────────────\n\ninterface SkillEntry {\n name: string;\n description: string;\n source: \"global\" | \"conversation\";\n path: string;\n directory: string;\n}\n\nfunction parseSkillFrontmatter(filePath: string): { name?: string; description?: string } {\n let text: string;\n try {\n text = readFileSync(filePath, \"utf-8\");\n } catch {\n return {};\n }\n if (!text.startsWith(\"---\")) return {};\n const end = text.indexOf(\"\\n---\", 3);\n if (end < 0) return {};\n const block = text.slice(3, end);\n const out: { name?: string; description?: string } = {};\n for (const line of block.split(\"\\n\")) {\n const colon = line.indexOf(\":\");\n if (colon < 0) continue;\n const key = line.slice(0, colon).trim().toLowerCase();\n let value = line.slice(colon + 1).trim();\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n if (key === \"name\") out.name = value;\n if (key === \"description\") out.description = value;\n }\n return out;\n}\n\nfunction readSkillsFromDir(skillsDir: string, source: SkillEntry[\"source\"]): SkillEntry[] {\n if (!existsSync(skillsDir)) return [];\n const out: SkillEntry[] = [];\n let entries;\n try {\n entries = readdirSync(skillsDir, { withFileTypes: true });\n } catch {\n return [];\n }\n for (const entry of entries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\")) continue;\n const skillMd = join(skillsDir, entry.name, \"SKILL.md\");\n if (!existsSync(skillMd)) continue;\n const meta = parseSkillFrontmatter(skillMd);\n out.push({\n name: meta.name ?? entry.name,\n description: meta.description ?? \"\",\n source,\n path: skillMd,\n directory: entry.name,\n });\n }\n return out.toSorted((a, b) => a.name.localeCompare(b.name));\n}\n\nfunction serveSkillsList(\n res: ServerResponse,\n url: URL,\n services: AdminServices,\n token: AdminToken,\n): void {\n const scope = resolveConversationFromQuery(url, token);\n if (scope.error) {\n jsonRes(res, 403, { error: scope.error });\n return;\n }\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n const global = readSkillsFromDir(join(workingDir, \"skills\"), \"global\");\n const conversation = readSkillsFromDir(\n join(workingDir, scope.conversationId, \"skills\"),\n \"conversation\",\n );\n jsonRes(res, 200, {\n conversationId: scope.conversationId,\n skills: [...global, ...conversation],\n });\n}\n\nfunction serveSkillFile(\n res: ServerResponse,\n url: URL,\n services: AdminServices,\n token: AdminToken,\n): void {\n const scope = resolveConversationFromQuery(url, token);\n if (scope.error) {\n jsonRes(res, 403, { error: scope.error });\n return;\n }\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n\n const source = (url.searchParams.get(\"source\") ?? \"\").trim();\n const directory = (url.searchParams.get(\"directory\") ?? \"\").trim();\n if (source !== \"global\" && source !== \"conversation\") {\n jsonRes(res, 400, { error: \"Invalid skill source\" });\n return;\n }\n if (\n !directory ||\n directory.includes(\"/\") ||\n directory.includes(\"\\\\\") ||\n directory.includes(\"..\")\n ) {\n jsonRes(res, 400, { error: \"Invalid skill directory\" });\n return;\n }\n\n const skillsRoot =\n source === \"global\"\n ? join(workingDir, \"skills\")\n : join(workingDir, scope.conversationId, \"skills\");\n const safe = safeJoinUnderRoot(skillsRoot, join(directory, \"SKILL.md\"));\n if (safe.error) {\n jsonRes(res, 400, { error: safe.error });\n return;\n }\n\n servePreviewFile(res, safe.absolute, { source, directory }, \"Skill file not found\");\n}\n\n// ── Events ─────────────────────────────────────────────────────────────────────\n\nconst EVENTS_FILE_MAX_BYTES = 64 * 1024;\n\ninterface EventSummary {\n name: string;\n size: number;\n mtimeMs: number;\n type: string | null;\n platform: string | null;\n conversationId: string | null;\n text: string | null;\n at: string | null;\n schedule: string | null;\n timezone: string | null;\n}\n\nfunction listAllEvents(workingDir: string): EventSummary[] {\n const dir = join(workingDir, \"events\");\n if (!existsSync(dir)) return [];\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return [];\n }\n return entries\n .filter((e) => e.isFile() && e.name.endsWith(\".json\"))\n .map((e): EventSummary | null => {\n const filePath = join(dir, e.name);\n let stats;\n try {\n stats = statSync(filePath);\n } catch {\n return null;\n }\n let parsed: unknown = null;\n try {\n parsed = JSON.parse(readFileSync(filePath, \"utf-8\"));\n } catch {\n // Keep entry; just omit parsed fields.\n }\n const meta = parsed && typeof parsed === \"object\" ? (parsed as Record<string, unknown>) : {};\n // events.ts accepts `channelId` as a legacy alias for `conversationId`.\n const conversationId =\n typeof meta.conversationId === \"string\"\n ? meta.conversationId\n : typeof meta.channelId === \"string\"\n ? meta.channelId\n : null;\n return {\n name: e.name,\n size: stats.size,\n mtimeMs: stats.mtimeMs,\n type: typeof meta.type === \"string\" ? meta.type : null,\n platform: typeof meta.platform === \"string\" ? meta.platform : null,\n conversationId,\n text: typeof meta.text === \"string\" ? meta.text : null,\n at: typeof meta.at === \"string\" ? meta.at : null,\n schedule: typeof meta.schedule === \"string\" ? meta.schedule : null,\n timezone: typeof meta.timezone === \"string\" ? meta.timezone : null,\n };\n })\n .filter((e): e is EventSummary => e !== null)\n .toSorted((a, b) => a.name.localeCompare(b.name));\n}\n\nfunction serveEventsList(res: ServerResponse, services: AdminServices): void {\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n jsonRes(res, 200, { events: listAllEvents(workingDir) });\n}\n\n/** Per-conversation listing — filter all events by conversationId match. */\nfunction serveConversationEventsList(\n res: ServerResponse,\n url: URL,\n services: AdminServices,\n token: AdminToken,\n): void {\n const scope = resolveConversationFromQuery(url, token);\n if (scope.error) {\n jsonRes(res, 403, { error: scope.error });\n return;\n }\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n const events = listAllEvents(workingDir).filter((e) => e.conversationId === scope.conversationId);\n jsonRes(res, 200, { conversationId: scope.conversationId, events });\n}\n\nfunction serveEventsFile(res: ServerResponse, url: URL, services: AdminServices): void {\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n const name = (url.searchParams.get(\"name\") ?? \"\").trim();\n if (!name || name.includes(\"/\") || name.includes(\"\\\\\") || name.includes(\"..\")) {\n jsonRes(res, 400, { error: \"Invalid name\" });\n return;\n }\n const filePath = join(workingDir, \"events\", name);\n let stats;\n try {\n stats = statSync(filePath);\n } catch {\n jsonRes(res, 404, { error: \"Not found\" });\n return;\n }\n if (!stats.isFile()) {\n jsonRes(res, 400, { error: \"Not a file\" });\n return;\n }\n if (stats.size > EVENTS_FILE_MAX_BYTES) {\n jsonRes(res, 413, { error: \"File too large\" });\n return;\n }\n let raw: string;\n try {\n raw = readFileSync(filePath, \"utf-8\");\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n return;\n }\n jsonRes(res, 200, { name, content: raw });\n}\n\n/** Delete a single event file scoped to the caller's conversation. */\nfunction serveConversationEventDelete(\n res: ServerResponse,\n body: Record<string, unknown>,\n services: AdminServices,\n token: AdminToken,\n): void {\n const scope = resolveTargetConversation(body, token);\n if (scope.error) {\n jsonRes(res, 403, { error: scope.error });\n return;\n }\n const name = typeof body.name === \"string\" ? body.name.trim() : \"\";\n if (!name || name.includes(\"/\") || name.includes(\"\\\\\") || name.includes(\"..\")) {\n jsonRes(res, 400, { error: \"Invalid name\" });\n return;\n }\n const workingDir = requireAdminWorkingDir(res, services);\n if (!workingDir) return;\n const filePath = join(workingDir, \"events\", name);\n let raw: string;\n try {\n raw = readFileSync(filePath, \"utf-8\");\n } catch {\n jsonRes(res, 404, { error: \"Event not found\" });\n return;\n }\n let parsed: Record<string, unknown> = {};\n try {\n const j = JSON.parse(raw);\n if (j && typeof j === \"object\") parsed = j as Record<string, unknown>;\n } catch {\n // Malformed events cannot be associated with a conversation below.\n }\n const eventConvId =\n typeof parsed.conversationId === \"string\"\n ? parsed.conversationId\n : typeof parsed.channelId === \"string\"\n ? parsed.channelId\n : null;\n if (eventConvId !== scope.conversationId) {\n jsonRes(res, 403, { error: \"Event does not belong to this conversation.\" });\n return;\n }\n try {\n rmSync(filePath, { force: true });\n jsonRes(res, 200, { ok: true });\n } catch (err) {\n jsonRes(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n}\n\n// ── Utilities ──────────────────────────────────────────────────────────────────\n\nfunction jsonRes(res: ServerResponse, status: number, body: unknown): void {\n res.writeHead(status, {\n \"Content-Type\": \"application/json; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n });\n res.end(JSON.stringify(body));\n}\n\nasync function readJsonBody(\n req: IncomingMessage,\n res: ServerResponse,\n): Promise<Record<string, unknown> | null> {\n const data = await readRawBody(req, res, 32 * 1024);\n if (data === null) return null;\n\n try {\n return JSON.parse(data) as Record<string, unknown>;\n } catch {\n jsonRes(res, 400, { error: \"Invalid JSON\" });\n return null;\n }\n}\n\nconst esc = escapeHtml;\n\n// ── HTML ───────────────────────────────────────────────────────────────────────\n\nfunction renderAdminPage(token: AdminToken): string {\n const userLabel = token.platformUserName ?? token.platformUserId;\n const body = `<nav class=\"tab-nav\" role=\"tablist\" aria-label=\"Admin sections\">\n <button class=\"tab-btn active\" role=\"tab\" aria-selected=\"true\" aria-controls=\"panel-conversation\" data-tab=\"conversation\">Conversation</button>\n <button class=\"tab-btn\" role=\"tab\" aria-selected=\"false\" aria-controls=\"panel-global\" data-tab=\"global\">Global</button>\n </nav>\n\n <div class=\"tab-panel active\" id=\"panel-conversation\">\n <section class=\"card sect\" id=\"sect-settings\" data-section=\"settings\">\n <header class=\"sect-head\">\n <div>\n <p class=\"eyebrow\">Settings</p>\n <h2 class=\"card-title\">模型 / Thinking / Auto-reply / Workspace mount</h2>\n </div>\n <button class=\"refresh-btn\" onclick=\"loadSettings()\">↻</button>\n </header>\n <div id=\"settings-content\"><div class=\"loading-msg\">Loading…</div></div>\n </section>\n\n <section class=\"card sect\" id=\"sect-workspace\" data-section=\"workspace\">\n <header class=\"sect-head\">\n <div>\n <p class=\"eyebrow\">Workspace</p>\n <h2 class=\"card-title\">檔案瀏覽 (只讀)</h2>\n </div>\n <button class=\"refresh-btn\" onclick=\"loadWorkspace()\">↻</button>\n </header>\n <div class=\"workspace-split\">\n <div id=\"workspace-tree\" class=\"workspace-tree\"><div class=\"loading-msg\">Loading…</div></div>\n <div id=\"workspace-preview\" class=\"workspace-preview\"><div class=\"placeholder-msg\">Click a file to preview</div></div>\n </div>\n </section>\n\n <section class=\"card sect\" id=\"sect-skills\" data-section=\"skills\">\n <header class=\"sect-head\">\n <div>\n <p class=\"eyebrow\">Skills</p>\n <h2 class=\"card-title\">可用的 skills</h2>\n </div>\n <button class=\"refresh-btn\" onclick=\"loadSkills()\">↻</button>\n </header>\n <div class=\"workspace-split\">\n <div id=\"skills-content\" class=\"workspace-tree\"><div class=\"loading-msg\">Loading…</div></div>\n <div id=\"skills-preview\" class=\"workspace-preview\"><div class=\"placeholder-msg\">Click a skill to preview SKILL.md</div></div>\n </div>\n </section>\n\n <section class=\"card sect\" id=\"sect-vault\" data-section=\"vault\">\n <header class=\"sect-head\">\n <div>\n <p class=\"eyebrow\">Vault</p>\n <h2 class=\"card-title\">該對話的憑證</h2>\n </div>\n <button class=\"primary-action-btn\" onclick=\"openLogin()\">Open login form</button>\n </header>\n <div id=\"vault-link-result\" class=\"link-result\" style=\"display:none\"></div>\n <iframe id=\"login-frame\" class=\"portal-frame\" title=\"Login\" style=\"display:none\"></iframe>\n </section>\n\n <section class=\"card sect\" id=\"sect-events\" data-section=\"events\">\n <header class=\"sect-head\">\n <div>\n <p class=\"eyebrow\">Events</p>\n <h2 class=\"card-title\">關聯此對話的 events</h2>\n </div>\n <button class=\"refresh-btn\" onclick=\"loadConversationEvents()\">↻</button>\n </header>\n <div id=\"events-content\"><div class=\"loading-msg\">Loading…</div></div>\n </section>\n\n <section class=\"card sect\" id=\"sect-session\" data-section=\"session\">\n <header class=\"sect-head\">\n <div>\n <p class=\"eyebrow\">Session View</p>\n <h2 class=\"card-title\">對話歷史檢視</h2>\n </div>\n <button class=\"primary-action-btn\" onclick=\"openSessionView()\">Open session view</button>\n </header>\n <div id=\"session-link-result\" class=\"link-result\" style=\"display:none\"></div>\n <iframe id=\"session-frame\" class=\"portal-frame\" title=\"Session View\" style=\"display:none\"></iframe>\n </section>\n </div>\n\n <div class=\"tab-panel\" id=\"panel-global\">\n <section class=\"card sect\">\n <header class=\"sect-head\">\n <div>\n <p class=\"eyebrow\">All Conversations</p>\n <h2 class=\"card-title\">所有對話</h2>\n </div>\n <button class=\"refresh-btn\" onclick=\"loadAllConversations()\">↻</button>\n </header>\n <div id=\"all-conv-content\"><div class=\"loading-msg\">Loading…</div></div>\n </section>\n\n <section class=\"card sect\">\n <header class=\"sect-head\">\n <div>\n <p class=\"eyebrow\">Token Usage</p>\n </div>\n <button class=\"refresh-btn\" onclick=\"loadTokenUsage()\">↻</button>\n </header>\n <h2 class=\"card-subtitle\" style=\"margin-bottom:10px\">Top 20 sessions</h3>\n <div id=\"session-usage-content\"><div class=\"loading-msg\">Loading…</div></div>\n <h2 class=\"card-subtitle\" style=\"margin:24px 0 10px\">Usage timeline</h3>\n <div class=\"timeline-controls\">\n <label>Conversation\n <select id=\"timeline-conv\" onchange=\"loadUsageTimeline()\"></select>\n </label>\n </div>\n <div id=\"usage-timeline-content\"><div class=\"loading-msg\">Loading…</div></div>\n </section>\n\n <section class=\"card sect\">\n <header class=\"sect-head\">\n <div>\n <p class=\"eyebrow\">Global Settings</p>\n <h2 class=\"card-title\">全域預設</h2>\n </div>\n <button class=\"refresh-btn\" onclick=\"loadGlobalSettings()\">↻</button>\n </header>\n <div id=\"global-settings-content\"><div class=\"loading-msg\">Loading…</div></div>\n </section>\n\n <section class=\"card sect\">\n <header class=\"sect-head\">\n <div>\n <p class=\"eyebrow\">Global Skills</p>\n <h2 class=\"card-title\">全域 skills</h2>\n </div>\n <button class=\"refresh-btn\" onclick=\"loadGlobalSkills()\">↻</button>\n </header>\n <div id=\"global-skills-content\"><div class=\"loading-msg\">Loading…</div></div>\n </section>\n\n <section class=\"card sect\">\n <header class=\"sect-head\">\n <div>\n <p class=\"eyebrow\">Global Events</p>\n <h2 class=\"card-title\">全域 events.json</h2>\n </div>\n <button class=\"refresh-btn\" onclick=\"loadEvents()\">↻</button>\n </header>\n <div id=\"global-events-content\"><div class=\"loading-msg\">Loading…</div></div>\n </section>\n </div>`;\n\n const script = `\n const adminToken = ${JSON.stringify(token.token)};\n const defaultConversationId = ${JSON.stringify(token.conversationId)};\n let activeConversationId = defaultConversationId;\n let availableModels = [];\n let modelsLoaded = false;\n\n // ── Helpers ──────────────────────────────────────────────────────────────────\n\n function escHtml(str) {\n return String(str).replace(/[&<>\"']/g, (c) => (\n {'&':'&','<':'<','>':'>','\"':'"',\"'\":'''}[c]\n ));\n }\n function escAttr(str) {\n return String(str).replace(/[\"'&<>]/g, (c) => (\n {'\"':'"',\"'\":''','&':'&','<':'<','>':'>'}[c]\n ));\n }\n async function copyToClipboard(text) {\n try { await navigator.clipboard.writeText(text); } catch { prompt('Copy this link:', text); }\n }\n async function apiGet(path) {\n const url = path + (path.includes('?') ? '&' : '?') + 'token=' + encodeURIComponent(adminToken);\n const r = await fetch(url);\n const data = await r.json();\n if (!r.ok) throw new Error(data.error || ('HTTP ' + r.status));\n return data;\n }\n async function apiPost(path, body) {\n const r = await fetch(path, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ token: adminToken, ...body }),\n });\n const data = await r.json();\n if (!r.ok) throw new Error(data.error || ('HTTP ' + r.status));\n return data;\n }\n async function loadModels() {\n try {\n const data = await apiGet('/admin/api/models');\n availableModels = Array.isArray(data.models) ? data.models : [];\n } catch (err) {\n availableModels = [];\n } finally {\n modelsLoaded = true;\n }\n }\n function modelRef(provider, model) {\n return provider && model ? provider + '/' + model : '';\n }\n function parseModelRef(value) {\n const slash = value.indexOf('/');\n if (slash <= 0 || slash === value.length - 1) return { provider: '', model: '' };\n return { provider: value.slice(0, slash), model: value.slice(slash + 1) };\n }\n function renderModelOptions(currentProvider, currentModel) {\n const current = modelRef(currentProvider, currentModel);\n const seen = new Set();\n const groups = {\n available: [],\n unverified: [],\n };\n if (current) {\n seen.add(current);\n groups.available.push('<option value=\"' + escAttr(current) + '\">' + escHtml(current + ' (current)') + '</option>');\n }\n for (const model of availableModels) {\n const ref = modelRef(model.provider, model.id);\n if (!ref || seen.has(ref)) continue;\n seen.add(ref);\n const details = [model.name && model.name !== model.id ? model.name : '', model.reasoning ? 'thinking' : '', Array.isArray(model.input) && model.input.includes('image') ? 'image' : '']\n .filter(Boolean)\n .join(' · ');\n const option = '<option value=\"' + escAttr(ref) + '\">' + escHtml(details ? ref + ' — ' + details : ref) + '</option>';\n if (model.status === 'unverified') groups.unverified.push(option);\n else groups.available.push(option);\n }\n const sections = [];\n if (groups.available.length > 0) sections.push('<optgroup label=\"Available\">' + groups.available.join('') + '</optgroup>');\n if (groups.unverified.length > 0) sections.push('<optgroup label=\"Configured but unverified\">' + groups.unverified.join('') + '</optgroup>');\n if (sections.length === 0) {\n return '<option value=\"\">No available models</option>';\n }\n return sections.join('');\n }\n\n // ── Tab switching ────────────────────────────────────────────────────────────\n\n const tabBtns = document.querySelectorAll('.tab-btn');\n const tabPanels = document.querySelectorAll('.tab-panel');\n\n function switchTab(tabId) {\n tabBtns.forEach((btn) => {\n const active = btn.dataset.tab === tabId;\n btn.classList.toggle('active', active);\n btn.setAttribute('aria-selected', active ? 'true' : 'false');\n });\n tabPanels.forEach((panel) => panel.classList.toggle('active', panel.id === 'panel-' + tabId));\n if (tabId === 'global') initGlobal();\n }\n tabBtns.forEach((btn) => btn.addEventListener('click', () => switchTab(btn.dataset.tab)));\n\n // ── Conversation switcher ───────────────────────────────────────────────────\n\n async function initConvSwitcher() {\n const sel = document.getElementById('conv-switcher');\n try {\n const data = await apiGet('/admin/api/conversations');\n sel.innerHTML = data.conversations.map((c) => {\n const label = (c.label || c.conversationId) + (c.running ? ' (running)' : '');\n const selected = c.conversationId === defaultConversationId ? ' selected' : '';\n return '<option value=\"' + escAttr(c.conversationId) + '\"' + selected + '>' + escHtml(label) + '</option>';\n }).join('');\n sel.addEventListener('change', () => setActiveConversation(sel.value));\n } catch (err) {\n // ignore; conversation selector stays empty\n }\n }\n\n function setActiveConversation(id) {\n activeConversationId = id;\n const sel = document.getElementById('conv-switcher');\n if (sel && sel.value !== id) sel.value = id;\n // Reset all conversation sections.\n loadSettings();\n loadWorkspace();\n loadSkills();\n loadConversationEvents();\n openLogin(true);\n openSessionView(true);\n }\n\n // ── Settings ─────────────────────────────────────────────────────────────────\n\n async function loadSettings() {\n const container = document.getElementById('settings-content');\n container.innerHTML = '<div class=\"loading-msg\">Loading…</div>';\n if (!modelsLoaded) await loadModels();\n try {\n const data = await apiGet('/admin/api/conversation-state?conversationId=' + encodeURIComponent(activeConversationId));\n container.innerHTML = renderSettings(data);\n } catch (err) {\n container.innerHTML = '<div class=\"err-msg\">' + escHtml(err.message) + '</div>';\n }\n }\n\n function renderSettings(data) {\n const thinking = ['off','minimal','low','medium','high','xhigh'];\n const thinkingOpts = thinking.map((t) =>\n '<option value=\"' + t + '\"' + (data.thinkingLevel === t ? ' selected' : '') + '>' + t + '</option>'\n ).join('');\n const mounts = ['private','full'];\n const mountOpts = mounts.map((m) =>\n '<option value=\"' + m + '\"' + (data.sandboxImageWorkspaceMount === m ? ' selected' : '') + '>' + m + '</option>'\n ).join('');\n const rulesText = (data.autoReplyRules || []).join('\\\\n');\n const replyModes = ['top-level','thread'];\n const replyModeOpts = replyModes.map((m) =>\n '<option value=\"' + m + '\"' + (((data.slack && data.slack.replyMode) || 'top-level') === m ? ' selected' : '') + '>' + m + '</option>'\n ).join('');\n const globalReplyMode = (data.slack && data.slack.globalReplyMode) || 'top-level';\n const globalModel = [data.globalProvider, data.globalModel].filter(Boolean).join('/');\n const globalModelLabel = globalModel + (data.globalThinkingLevel ? ':' + data.globalThinkingLevel : '');\n const globalMount = data.globalSandboxImageWorkspaceMount || 'private';\n return [\n '<div class=\"config-grid\">',\n '<div class=\"config-block\">',\n '<h3 class=\"card-subtitle\">Model</h3>',\n '<div class=\"config-row config-row-stack\"><label>Model</label><select id=\"m-model-ref\">' + renderModelOptions(data.provider, data.model) + '</select></div>',\n '<div class=\"config-row\"><label>Thinking</label><select id=\"m-thinking\">' + thinkingOpts + '</select></div>',\n '<p class=\"muted-note\">Global default: ' + escHtml(globalModelLabel) + '</p>',\n '<button class=\"primary-action-btn\" onclick=\"saveModel(this)\">Save model</button>',\n '<div id=\"model-save-result\" class=\"inline-result\" style=\"display:none\"></div>',\n '</div>',\n '<div class=\"config-block\">',\n '<h3 class=\"card-subtitle\">Auto-reply</h3>',\n '<div class=\"config-row\"><label>Enabled</label><label class=\"toggle\"><input type=\"checkbox\" id=\"a-enabled\"' + (data.autoReplyEnabled ? ' checked' : '') + '> on</label></div>',\n '<div class=\"config-row config-row-stack\"><label>Rules</label><textarea id=\"a-rules\" rows=\"5\" placeholder=\"一行一條規則\">' + escHtml(rulesText) + '</textarea></div>',\n '<button class=\"primary-action-btn\" onclick=\"saveAutoReply(this)\">Save auto-reply</button>',\n '<div id=\"auto-save-result\" class=\"inline-result\" style=\"display:none\"></div>',\n '</div>',\n '<div class=\"config-block\">',\n '<h3 class=\"card-subtitle\">Workspace mount</h3>',\n '<div class=\"config-row\"><label>Mode</label><select id=\"m-mount\">' + mountOpts + '</select></div>',\n '<p class=\"muted-note\">Global default: ' + escHtml(globalMount) + '</p>',\n '<button class=\"primary-action-btn\" onclick=\"saveMount(this)\">Save mount</button>',\n '<div id=\"mount-save-result\" class=\"inline-result\" style=\"display:none\"></div>',\n '</div>',\n '<div class=\"config-block\">',\n '<h3 class=\"card-subtitle\">Slack</h3>',\n '<div class=\"config-row\"><label>Reply mode</label><select id=\"m-slack-reply-mode\">' + replyModeOpts + '</select></div>',\n '<p class=\"muted-note\">Global default: ' + escHtml(globalReplyMode) + '</p>',\n '<button class=\"primary-action-btn\" onclick=\"saveSlack(this)\">Save Slack</button>',\n '<div id=\"slack-save-result\" class=\"inline-result\" style=\"display:none\"></div>',\n '</div>',\n '</div>',\n ].join('');\n }\n\n async function saveModel(btn) {\n const selectedModel = parseModelRef(document.getElementById('m-model-ref').value.trim());\n const provider = selectedModel.provider;\n const model = selectedModel.model;\n const thinkingLevel = document.getElementById('m-thinking').value;\n const result = document.getElementById('model-save-result');\n if (!provider || !model) {\n result.style.display = 'block'; result.className = 'inline-result err';\n result.textContent = 'Provider and model are required';\n return;\n }\n btn.disabled = true; btn.textContent = 'Saving…'; result.style.display = 'none';\n try {\n const data = await apiPost('/admin/api/conversations/model', {\n conversationId: activeConversationId, provider, model, thinkingLevel,\n });\n result.style.display = 'block'; result.className = 'inline-result ok';\n result.textContent = data.runtimeSwitched === false\n ? 'Saved — running session pinned; new model applies on next start.'\n : 'Saved ✓';\n } catch (err) {\n result.style.display = 'block'; result.className = 'inline-result err';\n result.textContent = err.message;\n } finally {\n btn.disabled = false; btn.textContent = 'Save model';\n }\n }\n\n async function saveAutoReply(btn) {\n const enabled = document.getElementById('a-enabled').checked;\n const rules = document.getElementById('a-rules').value.split('\\\\n').map((s) => s.trim()).filter(Boolean);\n const result = document.getElementById('auto-save-result');\n btn.disabled = true; btn.textContent = 'Saving…'; result.style.display = 'none';\n try {\n await apiPost('/admin/api/conversations/auto-reply', {\n conversationId: activeConversationId, enabled, rules,\n });\n result.style.display = 'block'; result.className = 'inline-result ok'; result.textContent = 'Saved ✓';\n } catch (err) {\n result.style.display = 'block'; result.className = 'inline-result err'; result.textContent = err.message;\n } finally {\n btn.disabled = false; btn.textContent = 'Save auto-reply';\n }\n }\n\n async function saveMount(btn) {\n const workspaceMount = document.getElementById('m-mount').value;\n const result = document.getElementById('mount-save-result');\n btn.disabled = true; btn.textContent = 'Saving…'; result.style.display = 'none';\n try {\n await apiPost('/admin/api/conversations/sandbox', {\n conversationId: activeConversationId, workspaceMount,\n });\n result.style.display = 'block'; result.className = 'inline-result ok'; result.textContent = 'Saved ✓';\n } catch (err) {\n result.style.display = 'block'; result.className = 'inline-result err'; result.textContent = err.message;\n } finally {\n btn.disabled = false; btn.textContent = 'Save mount';\n }\n }\n\n async function saveSlack(btn) {\n const replyMode = document.getElementById('m-slack-reply-mode').value;\n const result = document.getElementById('slack-save-result');\n btn.disabled = true; btn.textContent = 'Saving…'; result.style.display = 'none';\n try {\n await apiPost('/admin/api/conversations/slack', {\n conversationId: activeConversationId, replyMode,\n });\n result.style.display = 'block'; result.className = 'inline-result ok'; result.textContent = 'Saved ✓';\n } catch (err) {\n result.style.display = 'block'; result.className = 'inline-result err'; result.textContent = err.message;\n } finally {\n btn.disabled = false; btn.textContent = 'Save Slack';\n }\n }\n\n // ── Workspace ────────────────────────────────────────────────────────────────\n\n async function loadWorkspace() {\n const treeEl = document.getElementById('workspace-tree');\n const previewEl = document.getElementById('workspace-preview');\n treeEl.innerHTML = '<div class=\"loading-msg\">Loading…</div>';\n previewEl.innerHTML = '<div class=\"placeholder-msg\">Click a file to preview</div>';\n try {\n const data = await apiGet('/admin/api/workspace/tree?conversationId=' + encodeURIComponent(activeConversationId));\n if (!data.tree) {\n treeEl.innerHTML = '<div class=\"empty-state\">No files</div>';\n return;\n }\n treeEl.innerHTML = '<ul class=\"tree-root\">' + renderTreeChildren(data.tree) + '</ul>';\n } catch (err) {\n treeEl.innerHTML = '<div class=\"err-msg\">' + escHtml(err.message) + '</div>';\n }\n }\n\n function renderTreeChildren(node) {\n if (node.type === 'file') {\n return '<li><button class=\"tree-file\" onclick=\"previewFile(\\\\'' + escAttr(node.path) + '\\\\')\">' + escHtml(node.name) + '</button></li>';\n }\n if (!node.children || node.children.length === 0) {\n return '<li><span class=\"tree-dir empty\">' + escHtml(node.name || '.') + '/</span></li>';\n }\n const inner = node.children.map((c) =>\n c.type === 'file'\n ? '<li><button class=\"tree-file\" onclick=\"previewFile(\\\\'' + escAttr(c.path) + '\\\\')\">' + escHtml(c.name) + '</button></li>'\n : '<li><details open><summary class=\"tree-dir\">' + escHtml(c.name) + '/</summary><ul>' + renderTreeChildren(c) + '</ul></details></li>'\n ).join('');\n return inner;\n }\n\n function renderPreviewFileResult(previewEl, label, data) {\n if (data.binary) {\n previewEl.innerHTML = '<div class=\"preview-meta\">' + escHtml(label) + ' · ' + data.size + ' bytes · binary</div><div class=\"placeholder-msg\">Binary file — preview not available</div>';\n return;\n }\n previewEl.innerHTML =\n '<div class=\"preview-meta\">' + escHtml(label) + ' · ' + data.size + ' bytes</div>' +\n '<pre class=\"preview-body\">' + escHtml(data.content || '') + '</pre>';\n }\n\n async function previewFile(path) {\n const previewEl = document.getElementById('workspace-preview');\n previewEl.innerHTML = '<div class=\"loading-msg\">Loading ' + escHtml(path) + '…</div>';\n try {\n const data = await apiGet('/admin/api/workspace/file?conversationId=' + encodeURIComponent(activeConversationId) + '&path=' + encodeURIComponent(path));\n renderPreviewFileResult(previewEl, path, data);\n } catch (err) {\n previewEl.innerHTML = '<div class=\"err-msg\">' + escHtml(err.message) + '</div>';\n }\n }\n\n // ── Skills ───────────────────────────────────────────────────────────────────\n\n async function loadSkills() {\n const container = document.getElementById('skills-content');\n const previewEl = document.getElementById('skills-preview');\n container.innerHTML = '<div class=\"loading-msg\">Loading…</div>';\n if (previewEl) previewEl.innerHTML = '<div class=\"placeholder-msg\">Click a skill to preview SKILL.md</div>';\n try {\n const data = await apiGet('/admin/api/skills?conversationId=' + encodeURIComponent(activeConversationId));\n if (data.skills.length === 0) {\n container.innerHTML = '<div class=\"empty-state\">No skills available</div>';\n return;\n }\n container.innerHTML = '<div class=\"skills-list\">' +\n data.skills.map((s) =>\n '<button class=\"skill-row skill-row-btn\" data-skill-source=\"' + escAttr(s.source) + '\" data-skill-directory=\"' + escAttr(s.directory) + '\" data-skill-name=\"' + escAttr(s.name) + '\">' +\n '<div class=\"skill-name\">' + escHtml(s.name) + '<span class=\"skill-source skill-source-' + s.source + '\">' + s.source + '</span></div>' +\n (s.description ? '<div class=\"skill-desc\">' + escHtml(s.description) + '</div>' : '') +\n '</button>'\n ).join('') + '</div>';\n\n } catch (err) {\n container.innerHTML = '<div class=\"err-msg\">' + escHtml(err.message) + '</div>';\n }\n }\n\n async function previewSkill(source, directory, name) {\n const previewEl = document.getElementById('skills-preview');\n if (!source || !directory) {\n previewEl.innerHTML = '<div class=\"err-msg\">Missing skill source or directory</div>';\n return;\n }\n previewEl.innerHTML = '<div class=\"loading-msg\">Loading ' + escHtml(name || directory) + '…</div>';\n try {\n const data = await apiGet('/admin/api/skills/file?conversationId=' + encodeURIComponent(activeConversationId) + '&source=' + encodeURIComponent(source) + '&directory=' + encodeURIComponent(directory));\n renderPreviewFileResult(previewEl, source + '/' + directory + '/SKILL.md', data);\n } catch (err) {\n previewEl.innerHTML = '<div class=\"err-msg\">' + escHtml(err.message) + '</div>';\n }\n }\n\n document.getElementById('skills-content').addEventListener('click', (event) => {\n const btn = event.target.closest('[data-skill-source]');\n if (!btn) return;\n previewSkill(btn.dataset.skillSource, btn.dataset.skillDirectory, btn.dataset.skillName);\n });\n\n // ── Vault (Login link) ───────────────────────────────────────────────────────\n\n async function openLogin(silent) {\n const result = document.getElementById('vault-link-result');\n const frame = document.getElementById('login-frame');\n if (silent) { frame.removeAttribute('src'); frame.style.display = 'none'; result.style.display = 'none'; return; }\n result.style.display = 'block'; result.className = 'link-result loading'; result.textContent = 'Generating link…';\n try {\n const data = await apiPost('/admin/api/conversations/login-link', { conversationId: activeConversationId });\n result.className = 'link-result ok';\n result.innerHTML =\n '<span class=\"link-vault\">vault: <code>' + escHtml(data.vaultId) + '</code></span>' +\n '<a href=\"' + escAttr(data.url) + '\" target=\"_blank\" rel=\"noopener\">' + escHtml(data.url) + '</a>' +\n '<button class=\"copy-link-btn\" onclick=\"copyToClipboard(' + JSON.stringify(data.url) + ')\">Copy</button>';\n frame.src = data.url; frame.style.display = 'block';\n } catch (err) {\n result.className = 'link-result err'; result.textContent = err.message;\n frame.removeAttribute('src'); frame.style.display = 'none';\n }\n }\n\n // ── Session View ─────────────────────────────────────────────────────────────\n\n async function openSessionView(silent) {\n const result = document.getElementById('session-link-result');\n const frame = document.getElementById('session-frame');\n if (silent) { frame.removeAttribute('src'); frame.style.display = 'none'; result.style.display = 'none'; return; }\n result.style.display = 'block'; result.className = 'link-result loading'; result.textContent = 'Generating link…';\n try {\n const data = await apiPost('/admin/api/conversations/session-link', { conversationId: activeConversationId });\n result.className = 'link-result ok';\n result.innerHTML =\n '<a href=\"' + escAttr(data.url) + '\" target=\"_blank\" rel=\"noopener\">' + escHtml(data.url) + '</a>' +\n '<button class=\"copy-link-btn\" onclick=\"copyToClipboard(' + JSON.stringify(data.url) + ')\">Copy</button>';\n frame.src = data.url; frame.style.display = 'block';\n } catch (err) {\n result.className = 'link-result err'; result.textContent = err.message;\n frame.removeAttribute('src'); frame.style.display = 'none';\n }\n }\n\n // ── Events ───────────────────────────────────────────────────────────────────\n\n async function loadConversationEvents() {\n const container = document.getElementById('events-content');\n if (!container) return;\n container.innerHTML = '<div class=\"loading-msg\">Loading…</div>';\n try {\n const data = await apiGet('/admin/api/conversations/events?conversationId=' + encodeURIComponent(activeConversationId));\n if (data.events.length === 0) {\n container.innerHTML = '<div class=\"empty-state\">沒有關聯此對話的 event</div>';\n return;\n }\n container.innerHTML = '<div class=\"events-list\">' +\n data.events.map((e) => renderEventRow(e, true)).join('') + '</div>';\n } catch (err) {\n container.innerHTML = '<div class=\"err-msg\">' + escHtml(err.message) + '</div>';\n }\n }\n\n async function loadEvents() {\n const container = document.getElementById('global-events-content');\n if (!container) return;\n container.innerHTML = '<div class=\"loading-msg\">Loading…</div>';\n try {\n const data = await apiGet('/admin/api/events');\n if (data.events.length === 0) {\n container.innerHTML = '<div class=\"empty-state\">No events scheduled</div>';\n return;\n }\n container.innerHTML = '<div class=\"events-list\">' +\n data.events.map((e) => renderEventRow(e, false)).join('') + '</div>';\n } catch (err) {\n container.innerHTML = '<div class=\"err-msg\">' + escHtml(err.message) + '</div>';\n }\n }\n\n function renderEventRow(e, allowDelete) {\n const meta = [e.type, e.platform, e.conversationId, e.schedule || e.at]\n .filter(Boolean).map(escHtml).join(' · ');\n const preview = e.text ? '<div class=\"event-text\">' + escHtml(e.text.length > 240 ? e.text.slice(0, 237) + '…' : e.text) + '</div>' : '';\n const deleteBtn = allowDelete\n ? '<button class=\"event-delete-btn\" onclick=\"deleteEvent(\\\\'' + escAttr(e.name) + '\\\\', this)\">Delete</button>'\n : '';\n return '<div class=\"event-row\">' +\n '<div class=\"event-row-top\">' +\n '<div class=\"event-name\"><code>' + escHtml(e.name) + '</code></div>' +\n deleteBtn +\n '</div>' +\n '<div class=\"event-meta\">' + meta + '</div>' +\n preview +\n '</div>';\n }\n\n async function deleteEvent(name, btn) {\n if (!confirm('Delete event \"' + name + '\"?')) return;\n btn.disabled = true; btn.textContent = 'Deleting…';\n try {\n await apiPost('/admin/api/conversations/events/delete', {\n conversationId: activeConversationId, name,\n });\n await loadConversationEvents();\n } catch (err) {\n btn.disabled = false; btn.textContent = 'Delete';\n alert(err.message);\n }\n }\n\n // ── Global section ──────────────────────────────────────────────────────────\n\n let globalLoaded = false;\n function initGlobal() {\n if (globalLoaded) return;\n globalLoaded = true;\n loadAllConversations();\n loadTokenUsage();\n loadGlobalSettings();\n loadGlobalSkills();\n loadEvents();\n }\n\n async function loadAllConversations() {\n const container = document.getElementById('all-conv-content');\n container.innerHTML = '<div class=\"loading-msg\">Loading…</div>';\n try {\n const data = await apiGet('/admin/api/conversations');\n if (data.conversations.length === 0) {\n container.innerHTML = '<div class=\"empty-state\">No conversations found</div>';\n return;\n }\n container.innerHTML = '<div class=\"conv-list\">' + data.conversations.map((c) => {\n const last = c.lastActivityAt ? new Date(c.lastActivityAt).toLocaleString() : '—';\n return '<button class=\"conv-row-btn\" onclick=\"setActiveConversation(\\\\'' + escAttr(c.conversationId) + '\\\\'); switchTab(\\\\'conversation\\\\');\">' +\n '<span class=\"conv-id\">' + escHtml(c.label || c.conversationId) + '</span>' +\n (c.running ? '<span class=\"status-pill running\">running</span>' : '') +\n '<span class=\"conv-last\">' + escHtml(last) + '</span>' +\n '</button>';\n }).join('') + '</div>';\n } catch (err) {\n container.innerHTML = '<div class=\"err-msg\">' + escHtml(err.message) + '</div>';\n }\n }\n\n async function loadSessionUsage() {\n const container = document.getElementById('session-usage-content');\n container.innerHTML = '<div class=\"loading-msg\">Loading…</div>';\n try {\n const data = await apiGet('/admin/api/session-usage');\n if (data.sessions.length === 0) {\n container.innerHTML = '<div class=\"empty-state\">No token usage found</div>';\n return;\n }\n container.innerHTML = '<div class=\"usage-table-wrap\"><table class=\"usage-table\"><thead><tr><th>#</th><th>Channel</th><th>Session</th><th>Updated</th><th>Input</th><th>Output</th><th>Cache Read</th><th>Cache Write</th><th>Total</th><th>Cost</th></tr></thead><tbody>' +\n data.sessions.map((s, i) => '<tr>' +\n '<td>' + (i + 1) + '</td>' +\n '<td>' + escHtml(s.label || s.conversationId) + '</td>' +\n '<td><code>' + escHtml(s.fileName) + '</code></td>' +\n '<td>' + escHtml(new Date(s.updatedAt).toLocaleString()) + '</td>' +\n '<td>' + fmtNum(s.input) + '</td>' +\n '<td>' + fmtNum(s.output) + '</td>' +\n '<td>' + fmtNum(s.cacheRead) + '</td>' +\n '<td>' + fmtNum(s.cacheWrite) + '</td>' +\n '<td><strong>' + fmtNum(s.total) + '</strong></td>' +\n '<td>' + (s.cost > 0 ? '$' + Number(s.cost).toFixed(4) : '—') + '</td>' +\n '</tr>').join('') + '</tbody></table></div>';\n } catch (err) {\n container.innerHTML = '<div class=\"err-msg\">' + escHtml(err.message) + '</div>';\n }\n }\n\n function fmtNum(value) {\n return Number(value || 0).toLocaleString('en-US');\n }\n\n let timelineConvLoaded = false;\n let timelineData = null;\n let timelineFilter = null;\n async function ensureTimelineConvOptions() {\n if (timelineConvLoaded) return;\n const sel = document.getElementById('timeline-conv');\n const prev = sel.value;\n const data = await apiGet('/admin/api/conversations');\n if (!data.conversations.length) {\n sel.innerHTML = '<option value=\"\">No conversations</option>';\n timelineConvLoaded = true;\n return;\n }\n const want = prev || defaultConversationId;\n sel.innerHTML = data.conversations.map((c) =>\n '<option value=\"' + escAttr(c.conversationId) + '\"' +\n (c.conversationId === want ? ' selected' : '') + '>' +\n escHtml(c.label || c.conversationId) + '</option>'\n ).join('');\n timelineConvLoaded = true;\n }\n\n // Shared refresh for the merged Token Usage section: reloads the session\n // ranking and re-fetches the conversation list (so new sessions appear),\n // preserving the currently selected conversation.\n async function loadTokenUsage() {\n loadSessionUsage();\n timelineConvLoaded = false;\n await loadUsageTimeline();\n }\n\n async function loadUsageTimeline() {\n const container = document.getElementById('usage-timeline-content');\n try {\n await ensureTimelineConvOptions();\n const conv = document.getElementById('timeline-conv').value;\n if (!conv) {\n container.innerHTML = '<div class=\"empty-state\">No conversations found</div>';\n return;\n }\n container.innerHTML = '<div class=\"loading-msg\">Loading…</div>';\n const data = await apiGet('/admin/api/conversation-usage?conversationId=' +\n encodeURIComponent(conv));\n timelineData = data;\n container.innerHTML = renderUsageTimeline(data);\n } catch (err) {\n container.innerHTML = '<div class=\"err-msg\">' + escHtml(err.message) + '</div>';\n }\n }\n\n function tlCard(label, value) {\n return '<div class=\"tl-card\"><div class=\"tl-card-label\">' + label +\n '</div><div class=\"tl-card-value\">' + value + '</div></div>';\n }\n\n const TL_SERIES = [\n { key: 'cacheRead', seg: 'tl-cache-read', sw: 'sw-cache-read', label: 'Cache read' },\n { key: 'cacheWrite', seg: 'tl-cache-write', sw: 'sw-cache-write', label: 'Cache write' },\n { key: 'input', seg: 'tl-input', sw: 'sw-input', label: 'Input' },\n { key: 'output', seg: 'tl-output', sw: 'sw-output', label: 'Output' },\n ];\n\n // Click a legend item to show only that series; click it again for all.\n function toggleTimelineFilter(key) {\n timelineFilter = timelineFilter === key ? null : key;\n if (timelineData) {\n document.getElementById('usage-timeline-content').innerHTML = renderUsageTimeline(timelineData);\n }\n }\n\n function renderUsageTimeline(data) {\n const buckets = data.buckets || [];\n const totals = data.totals || { total: 0, cost: 0, cacheRead: 0 };\n const cacheHit = totals.total > 0 ? Math.round((totals.cacheRead / totals.total) * 100) : 0;\n const cards = '<div class=\"tl-cards\">' +\n tlCard('Total cost', totals.cost > 0 ? '$' + Number(totals.cost).toFixed(4) : '—') +\n tlCard('Total tokens', fmtNum(totals.total)) +\n tlCard('Cache hit', cacheHit + '%') +\n '</div>';\n\n if (totals.total === 0) {\n const emptyNote = data.hasOlder\n ? '<div class=\"tl-note\">No usage in the last 14 days · earlier activity exists</div>'\n : '<div class=\"empty-state\">No token usage in the last 14 days</div>';\n return cards + emptyNote;\n }\n\n const active = TL_SERIES.find((s) => s.key === timelineFilter) || null;\n const valueOf = (b) => active ? (b[active.key] || 0) : b.total;\n const max = Math.max(1, ...buckets.map(valueOf));\n const px = (v) => Math.round((v / max) * 180);\n\n const legend = '<div class=\"tl-legend\">' + TL_SERIES.map((s) => {\n const cls = 'tl-legend-item' +\n (active && active.key === s.key ? ' active' : (active ? ' dim' : ''));\n return '<span class=\"' + cls + '\" onclick=\"toggleTimelineFilter(\\\\'' + s.key + '\\\\')\">' +\n '<i class=\"sw ' + s.sw + '\"></i>' + s.label + '</span>';\n }).join('') + '</div>';\n\n const bars = buckets.map((b) => {\n const val = valueOf(b);\n const tip = active\n ? b.date + ' · ' + active.label + ': ' + fmtNum(b[active.key] || 0) + ' tokens'\n : b.date + ' · ' + fmtNum(b.total) + ' tokens' +\n (b.cost > 0 ? ' · $' + Number(b.cost).toFixed(4) : '');\n let inner;\n if (val <= 0) {\n inner = '<span class=\"tl-empty\"></span>';\n } else if (active) {\n inner = '<span class=\"tl-seg ' + active.seg + '\" style=\"height:' + px(val) + 'px\"></span>';\n } else {\n inner = '<span class=\"tl-seg tl-output\" style=\"height:' + px(b.output) + 'px\"></span>' +\n '<span class=\"tl-seg tl-input\" style=\"height:' + px(b.input) + 'px\"></span>' +\n '<span class=\"tl-seg tl-cache-write\" style=\"height:' + px(b.cacheWrite) + 'px\"></span>' +\n '<span class=\"tl-seg tl-cache-read\" style=\"height:' + px(b.cacheRead) + 'px\"></span>';\n }\n return '<div class=\"tl-bar\">' +\n '<span class=\"tl-tip\">' + escHtml(tip) + '</span>' +\n '<div class=\"tl-fill\">' + inner + '</div>' +\n '</div>';\n }).join('');\n\n const axis = buckets.length\n ? '<div class=\"tl-axis\"><span>' + escHtml(buckets[0].date.slice(5)) +\n '</span><span>' + escHtml(buckets[buckets.length - 1].date.slice(5)) + '</span></div>'\n : '';\n const note = data.hasOlder\n ? '<div class=\"tl-note\">Showing last 14 days · earlier activity not shown</div>'\n : '<div class=\"tl-note\">Showing last 14 days</div>';\n const peak = '<div class=\"tl-peak\" style=\"bottom:180px\"><span class=\"tl-peak-label\">' +\n fmtNum(max) + ' tokens</span></div>';\n return cards + legend + '<div class=\"tl-chart\">' + peak + bars + '</div>' + axis + note;\n }\n\n async function loadGlobalSettings() {\n const container = document.getElementById('global-settings-content');\n container.innerHTML = '<div class=\"loading-msg\">Loading…</div>';\n if (!modelsLoaded) await loadModels();\n try {\n const data = await apiGet('/admin/api/settings/global');\n container.innerHTML = renderGlobalSettings(data);\n } catch (err) {\n container.innerHTML = '<div class=\"err-msg\">' + escHtml(err.message) + '</div>';\n }\n }\n\n function renderGlobalSettings(data) {\n const thinking = ['off','minimal','low','medium','high','xhigh'];\n const thinkingOpts = thinking.map((t) =>\n '<option value=\"' + t + '\"' + (data.thinkingLevel === t ? ' selected' : '') + '>' + t + '</option>'\n ).join('');\n const mounts = ['private','full'];\n const mountOpts = mounts.map((m) =>\n '<option value=\"' + m + '\"' + (data.sandboxImageWorkspaceMount === m ? ' selected' : '') + '>' + m + '</option>'\n ).join('');\n const replyModes = ['top-level','thread'];\n const replyModeOpts = replyModes.map((m) =>\n '<option value=\"' + m + '\"' + (((data.slack && data.slack.replyMode) || 'top-level') === m ? ' selected' : '') + '>' + m + '</option>'\n ).join('');\n return [\n '<div class=\"config-grid\">',\n '<div class=\"config-block\">',\n '<h3 class=\"card-subtitle\">Default model</h3>',\n '<div class=\"config-row config-row-stack\"><label>Model</label><select id=\"g-model-ref\">' + renderModelOptions(data.provider, data.model) + '</select></div>',\n '<div class=\"config-row\"><label>Thinking</label><select id=\"g-thinking\">' + thinkingOpts + '</select></div>',\n '<button class=\"primary-action-btn\" onclick=\"saveGlobalModel(this)\">Save model</button>',\n '<div id=\"g-model-result\" class=\"inline-result\" style=\"display:none\"></div>',\n '</div>',\n '<div class=\"config-block\">',\n '<h3 class=\"card-subtitle\">Sandbox limits</h3>',\n '<div class=\"config-row\"><label>CPUs</label><input id=\"g-cpus\" placeholder=\"0.5\" value=\"' + escAttr(data.sandboxCpus || '') + '\"></div>',\n '<div class=\"config-row\"><label>Memory</label><input id=\"g-mem\" placeholder=\"1g\" value=\"' + escAttr(data.sandboxMemory || '') + '\"></div>',\n '<div class=\"config-row\"><label>Boost CPUs</label><input id=\"g-bcpus\" placeholder=\"2\" value=\"' + escAttr(data.sandboxBoostCpus || '') + '\"></div>',\n '<div class=\"config-row\"><label>Boost Mem</label><input id=\"g-bmem\" placeholder=\"4g\" value=\"' + escAttr(data.sandboxBoostMemory || '') + '\"></div>',\n '<div class=\"config-row\"><label>Mount</label><select id=\"g-mount\">' + mountOpts + '</select></div>',\n '<button class=\"primary-action-btn\" onclick=\"saveGlobalSandbox(this)\">Save sandbox</button>',\n '<div id=\"g-sandbox-result\" class=\"inline-result\" style=\"display:none\"></div>',\n '</div>',\n '<div class=\"config-block\">',\n '<h3 class=\"card-subtitle\">Slack</h3>',\n '<div class=\"config-row\"><label>Reply mode</label><select id=\"g-slack-reply-mode\">' + replyModeOpts + '</select></div>',\n '<button class=\"primary-action-btn\" onclick=\"saveGlobalSlack(this)\">Save Slack</button>',\n '<div id=\"g-slack-result\" class=\"inline-result\" style=\"display:none\"></div>',\n '</div>',\n '</div>',\n ].join('');\n }\n\n async function saveGlobalModel(btn) {\n const selectedModel = parseModelRef(document.getElementById('g-model-ref').value.trim());\n const provider = selectedModel.provider;\n const model = selectedModel.model;\n const thinkingLevel = document.getElementById('g-thinking').value;\n const result = document.getElementById('g-model-result');\n if (!provider || !model) {\n result.style.display = 'block'; result.className = 'inline-result err';\n result.textContent = 'Provider and model are required'; return;\n }\n btn.disabled = true; btn.textContent = 'Saving…'; result.style.display = 'none';\n try {\n await apiPost('/admin/api/settings/model', { provider, model, thinkingLevel });\n result.style.display = 'block'; result.className = 'inline-result ok'; result.textContent = 'Saved ✓';\n } catch (err) {\n result.style.display = 'block'; result.className = 'inline-result err'; result.textContent = err.message;\n } finally {\n btn.disabled = false; btn.textContent = 'Save model';\n }\n }\n\n async function saveGlobalSandbox(btn) {\n const cpus = document.getElementById('g-cpus').value.trim();\n const memory = document.getElementById('g-mem').value.trim();\n const boostCpus = document.getElementById('g-bcpus').value.trim();\n const boostMemory = document.getElementById('g-bmem').value.trim();\n const workspaceMount = document.getElementById('g-mount').value;\n const result = document.getElementById('g-sandbox-result');\n btn.disabled = true; btn.textContent = 'Saving…'; result.style.display = 'none';\n try {\n await apiPost('/admin/api/settings/sandbox', { cpus, memory, boostCpus, boostMemory, workspaceMount });\n result.style.display = 'block'; result.className = 'inline-result ok'; result.textContent = 'Saved ✓';\n } catch (err) {\n result.style.display = 'block'; result.className = 'inline-result err'; result.textContent = err.message;\n } finally {\n btn.disabled = false; btn.textContent = 'Save sandbox';\n }\n }\n\n async function saveGlobalSlack(btn) {\n const replyMode = document.getElementById('g-slack-reply-mode').value;\n const result = document.getElementById('g-slack-result');\n btn.disabled = true; btn.textContent = 'Saving…'; result.style.display = 'none';\n try {\n await apiPost('/admin/api/settings/slack', { replyMode });\n result.style.display = 'block'; result.className = 'inline-result ok'; result.textContent = 'Saved ✓';\n } catch (err) {\n result.style.display = 'block'; result.className = 'inline-result err'; result.textContent = err.message;\n } finally {\n btn.disabled = false; btn.textContent = 'Save Slack';\n }\n }\n\n async function loadGlobalSkills() {\n const container = document.getElementById('global-skills-content');\n container.innerHTML = '<div class=\"loading-msg\">Loading…</div>';\n try {\n // Reuse skills endpoint scoped to a conversation that doesn't have any of its own; the global half is what we want.\n const data = await apiGet('/admin/api/skills?conversationId=' + encodeURIComponent(activeConversationId));\n const globals = data.skills.filter((s) => s.source === 'global');\n if (globals.length === 0) {\n container.innerHTML = '<div class=\"empty-state\">No global skills</div>';\n return;\n }\n container.innerHTML = '<div class=\"skills-list\">' + globals.map((s) =>\n '<div class=\"skill-row\"><div class=\"skill-name\">' + escHtml(s.name) + '</div>' +\n (s.description ? '<div class=\"skill-desc\">' + escHtml(s.description) + '</div>' : '') + '</div>'\n ).join('') + '</div>';\n } catch (err) {\n container.innerHTML = '<div class=\"err-msg\">' + escHtml(err.message) + '</div>';\n }\n }\n\n // ── Init ─────────────────────────────────────────────────────────────────────\n\n initConvSwitcher();\n loadModels().finally(() => {\n loadSettings();\n loadWorkspace();\n loadSkills();\n loadConversationEvents();\n });\n `;\n\n return renderPortalShell({\n activeView: \"admin\",\n pageTitle: \"Admin\",\n identity: { primary: token.platform, secondary: userLabel },\n conversationSwitcher: { currentId: token.conversationId },\n body,\n extraStyles: adminViewStyles,\n inlineScript: script,\n });\n}\n\nfunction renderAdminErrorPage(message: string): string {\n return renderPortalShell({\n activeView: \"admin\",\n pageTitle: \"Admin\",\n body: `<section class=\"card\" style=\"text-align:center;padding:40px 32px\">\n <p class=\"eyebrow\">${PRODUCT_NAME} admin</p>\n <h1 class=\"page-title\" style=\"margin:12px 0 16px\">Access Denied</h1>\n <div class=\"err-msg\">${esc(message)}</div>\n </section>`,\n });\n}\n\n// ── Styles ─────────────────────────────────────────────────────────────────────\n\nconst adminViewStyles = `\n .tab-nav {\n display: flex; gap: 6px; padding: 6px;\n border: 1px solid var(--border); border-radius: 16px;\n background: rgba(255,255,255,0.72); backdrop-filter: blur(8px);\n overflow-x: auto; scrollbar-width: none;\n }\n .tab-nav::-webkit-scrollbar { display: none; }\n .tab-btn {\n flex: 1; min-width: 80px; padding: 10px 16px;\n border: none; border-radius: 10px; background: transparent;\n color: var(--muted);\n font: 500 0.88rem/1.2 'DM Sans', sans-serif;\n cursor: pointer; white-space: nowrap;\n transition: background 140ms, color 140ms;\n }\n .tab-btn:hover { background: rgba(0,0,0,0.04); color: var(--text); }\n .tab-btn.active { background: var(--text); color: #fafafa; font-weight: 600; }\n .tab-btn:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }\n\n .tab-panel { display: none; flex-direction: column; gap: 14px; }\n .tab-panel.active { display: flex; }\n\n .card-desc { color: var(--muted); font-size: 0.9rem; line-height: 1.55; margin-bottom: 12px; }\n\n .link-result {\n margin-top: 12px; padding: 10px 14px; border-radius: 10px;\n display: flex; gap: 10px; align-items: center; flex-wrap: wrap;\n font-size: 0.84rem;\n }\n .link-result.ok { background: var(--ok-bg); border: 1px solid var(--ok-border); }\n .link-result.err { background: var(--err-bg); border: 1px solid var(--err-border); color: var(--err-text); }\n .link-result.loading { background: rgba(0,0,0,0.025); border: 1px solid var(--border); color: var(--muted); }\n .link-result a {\n color: var(--ok-text);\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n font-size: 0.78rem; word-break: break-all; flex: 1; min-width: 0;\n }\n .link-vault { color: var(--muted); font-size: 0.78rem; flex-shrink: 0; }\n .copy-link-btn {\n padding: 5px 12px; border: 1px solid var(--ok-border); border-radius: 7px;\n background: rgba(255,255,255,0.7); color: var(--ok-text);\n font: 500 0.78rem/1.2 'DM Sans', sans-serif;\n cursor: pointer; flex-shrink: 0;\n }\n\n .portal-frame {\n width: 100%; min-height: 720px;\n border: 1px solid var(--border); border-radius: 14px; background: #fff;\n }\n\n .config-grid {\n display: grid; grid-template-columns: 1fr 1fr; gap: 18px;\n }\n .config-block { display: flex; flex-direction: column; gap: 10px; }\n .config-row { display: grid; grid-template-columns: 110px 1fr; gap: 10px; align-items: center; }\n .config-row.config-row-stack { grid-template-columns: 1fr; }\n .config-row label { font-size: 0.82rem; color: var(--muted); }\n .config-row input, .config-row select, .config-row textarea {\n padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px;\n font-family: inherit; font-size: 0.84rem; width: 100%;\n }\n .config-row textarea {\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n resize: vertical;\n }\n .toggle { display: inline-flex; align-items: center; gap: 8px; font-size: 0.84rem; }\n\n .inline-result {\n padding: 8px 12px; border-radius: 8px; font-size: 0.82rem; margin-top: 4px;\n }\n .inline-result.ok { background: var(--ok-bg); color: var(--ok-text); border: 1px solid var(--ok-border); }\n .inline-result.err { background: var(--err-bg); color: var(--err-text); border: 1px solid var(--err-border); }\n\n /* ── Sections (Conversation page stack) ─────────────────────────────── */\n\n .sect-head {\n display: flex; align-items: flex-start; justify-content: space-between;\n gap: 12px; margin-bottom: 14px; flex-wrap: wrap;\n }\n .sect-head .card-title { margin-bottom: 0; }\n .sect-disabled { opacity: 0.7; }\n\n .refresh-btn {\n flex-shrink: 0; padding: 6px 12px;\n border: 1px solid var(--border); border-radius: 10px;\n background: rgba(0,0,0,0.025); color: var(--muted);\n font: 500 0.84rem/1.2 'DM Sans', sans-serif; cursor: pointer;\n }\n .refresh-btn:hover { background: rgba(0,0,0,0.06); color: var(--text); }\n\n /* ── Workspace ──────────────────────────────────────────────────────── */\n\n .workspace-split {\n display: grid; grid-template-columns: 260px 1fr; gap: 14px;\n min-height: 360px;\n }\n .workspace-tree {\n border: 1px solid var(--border); border-radius: 12px; padding: 10px;\n background: rgba(0,0,0,0.02); overflow: auto; max-height: 480px;\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n font-size: 0.78rem;\n }\n .workspace-tree ul { list-style: none; padding-left: 12px; margin: 0; }\n .workspace-tree .tree-root { padding-left: 0; }\n .workspace-tree details { margin: 1px 0; }\n .workspace-tree summary { cursor: pointer; padding: 2px 4px; border-radius: 4px; }\n .workspace-tree summary:hover { background: rgba(0,0,0,0.05); }\n .tree-dir { color: var(--text); font-weight: 600; }\n .tree-dir.empty { color: var(--subtle); font-weight: 400; }\n .tree-file {\n display: block; width: 100%; text-align: left;\n background: transparent; border: none; cursor: pointer;\n padding: 2px 4px; border-radius: 4px;\n font-family: inherit; font-size: inherit; color: var(--muted);\n }\n .tree-file:hover { background: rgba(0,0,0,0.05); color: var(--text); }\n\n .workspace-preview {\n border: 1px solid var(--border); border-radius: 12px;\n background: #fff; padding: 12px; overflow: auto; max-height: 480px;\n }\n .preview-meta {\n font-size: 0.74rem; color: var(--subtle);\n margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px solid var(--border);\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n }\n .preview-body {\n margin: 0; white-space: pre-wrap; word-break: break-word;\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n font-size: 0.78rem; color: var(--text);\n }\n .placeholder-msg { color: var(--subtle); font-size: 0.86rem; padding: 24px 8px; text-align: center; }\n\n /* ── Skills ─────────────────────────────────────────────────────────── */\n\n .skills-list { display: flex; flex-direction: column; gap: 8px; }\n .skill-row {\n padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px;\n background: rgba(0,0,0,0.02);\n }\n .skill-row-btn {\n width: 100%; text-align: left; cursor: pointer; font-family: inherit;\n }\n .skill-row-btn:hover { background: rgba(0,0,0,0.05); }\n .skill-name {\n font-weight: 650; font-size: 0.9rem; color: var(--text);\n display: flex; align-items: center; gap: 8px; flex-wrap: wrap;\n }\n .skill-source {\n padding: 1px 8px; border-radius: 999px; font-size: 0.7rem;\n font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;\n }\n .skill-source-global { background: rgba(59,130,246,0.1); color: #1d4ed8; }\n .skill-source-conversation { background: rgba(217,119,6,0.1); color: var(--accent); }\n .skill-desc { color: var(--muted); font-size: 0.82rem; margin-top: 4px; line-height: 1.5; }\n\n /* ── Events ─────────────────────────────────────────────────────────── */\n\n .events-list { display: flex; flex-direction: column; gap: 8px; }\n .event-row {\n padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px;\n background: rgba(0,0,0,0.02);\n }\n .event-row-top {\n display: flex; align-items: center; justify-content: space-between;\n gap: 10px;\n }\n .event-name { min-width: 0; flex: 1; word-break: break-all; }\n .event-name code { font-size: 0.82rem; background: transparent; padding: 0; }\n .event-meta { font-size: 0.74rem; color: var(--muted); margin-top: 3px; }\n .event-text {\n font-size: 0.82rem; color: var(--text); margin-top: 6px;\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n white-space: pre-wrap; word-break: break-word;\n }\n .event-delete-btn {\n flex-shrink: 0; padding: 4px 10px;\n border-radius: 7px; border: 1px solid rgba(185, 28, 28, 0.18);\n background: rgba(0,0,0,0.03); color: var(--err-text);\n font: 500 0.76rem/1.2 'DM Sans', sans-serif; cursor: pointer;\n }\n .event-delete-btn:hover:not(:disabled) {\n background: var(--err-bg); border-color: rgba(185, 28, 28, 0.28);\n }\n .event-delete-btn:disabled { opacity: 0.5; cursor: wait; }\n\n /* ── All Conversations list ─────────────────────────────────────────── */\n\n .conv-list { display: flex; flex-direction: column; gap: 6px; }\n .conv-row-btn {\n display: flex; align-items: center; gap: 12px;\n padding: 10px 14px; border: 1px solid var(--border); border-radius: 10px;\n background: rgba(0,0,0,0.02); cursor: pointer; text-align: left;\n transition: background 120ms, border-color 120ms;\n }\n .conv-row-btn:hover { background: rgba(0,0,0,0.05); border-color: rgba(0,0,0,0.14); }\n .conv-id { flex: 1; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.84rem; }\n .conv-last { color: var(--subtle); font-size: 0.78rem; }\n\n .usage-table-wrap { overflow-x: auto; }\n .usage-table { width: 100%; border-collapse: collapse; font-size: 0.78rem; }\n .usage-table th, .usage-table td {\n padding: 8px 10px; border-bottom: 1px solid var(--border);\n text-align: left; white-space: nowrap;\n }\n .usage-table th {\n color: var(--subtle); font-size: 0.68rem;\n text-transform: uppercase; letter-spacing: 0.08em;\n }\n .usage-table code { font-size: 0.72rem; }\n\n .timeline-controls {\n display: flex; flex-wrap: wrap; gap: 18px; align-items: center; margin-bottom: 16px;\n }\n .timeline-controls label {\n display: flex; align-items: center; gap: 8px;\n font-size: 0.76rem; color: var(--muted);\n }\n .timeline-controls select {\n padding: 6px 10px; border: 1px solid var(--border); border-radius: 8px;\n background: #fff; color: var(--text); font-size: 0.8rem; max-width: 240px;\n }\n .tl-note { margin-top: 8px; font-size: 0.72rem; color: var(--subtle); }\n .tl-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 16px; }\n .tl-card { background: rgba(0,0,0,0.025); border-radius: 10px; padding: 10px 12px; }\n .tl-card-label { font-size: 0.73rem; color: var(--muted); margin-bottom: 4px; }\n .tl-card-value { font-size: 1.35rem; font-weight: 600; color: var(--text); }\n .tl-legend { display: flex; gap: 16px; font-size: 0.73rem; color: var(--muted); margin-bottom: 10px; }\n .tl-legend span { display: inline-flex; align-items: center; gap: 6px; }\n .tl-legend-item { cursor: pointer; transition: opacity 100ms; }\n .tl-legend-item:hover { text-decoration: underline; }\n .tl-legend-item.active { color: var(--text); font-weight: 600; text-decoration: underline; }\n .tl-legend-item.dim { opacity: 0.4; }\n .sw { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }\n .sw-cache-read { background: rgba(0,0,0,0.18); }\n .sw-cache-write { background: #3b6fb0; }\n .sw-input { background: var(--accent); }\n .sw-output { background: var(--ok-text); }\n .tl-chart {\n position: relative;\n display: flex; align-items: flex-end; gap: 6px;\n height: 216px; border-bottom: 1px solid var(--border);\n }\n .tl-peak {\n position: absolute; left: 0; right: 0; height: 0;\n border-top: 1px dashed var(--accent); pointer-events: none;\n }\n .tl-peak-label {\n position: absolute; left: 0; top: -15px;\n font-size: 0.7rem; color: var(--accent); white-space: nowrap;\n }\n .tl-bar {\n position: relative; flex: 1; min-width: 0; height: 180px;\n display: flex; flex-direction: column; justify-content: flex-end;\n border-radius: 6px 6px 0 0; transition: background 80ms ease;\n }\n .tl-bar:hover { background: rgba(0,0,0,0.06); }\n .tl-bar:hover .tl-seg { opacity: 0.55; }\n .tl-fill {\n display: flex; flex-direction: column; justify-content: flex-end;\n border-radius: 3px 3px 0 0; overflow: hidden;\n }\n .tl-tip {\n position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);\n margin-bottom: 6px; padding: 5px 9px; border-radius: 6px;\n background: var(--text); color: #fafafa; font-size: 0.7rem; line-height: 1.35;\n white-space: nowrap; opacity: 0; pointer-events: none; z-index: 5;\n }\n .tl-bar:hover .tl-tip { opacity: 1; }\n .tl-seg { display: block; width: 100%; }\n .tl-seg.tl-output { background: var(--ok-text); }\n .tl-seg.tl-input { background: var(--accent); }\n .tl-seg.tl-cache-write { background: #3b6fb0; }\n .tl-seg.tl-cache-read { background: rgba(0,0,0,0.18); }\n .tl-empty { display: block; width: 100%; height: 3px; background: var(--border); }\n .tl-axis { display: flex; justify-content: space-between; margin-top: 6px; font-size: 0.7rem; color: var(--subtle); }\n\n .status-pill {\n display: inline-flex; padding: 2px 9px; border-radius: 999px;\n font-size: 0.7rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;\n }\n .status-pill.running { background: var(--ok-bg); color: var(--ok-text); border: 1px solid var(--ok-border); }\n\n @media (max-width: 640px) {\n .tab-btn { padding: 9px 12px; font-size: 0.82rem; min-width: 60px; }\n .config-grid { grid-template-columns: 1fr; }\n .config-row { grid-template-columns: 1fr; gap: 4px; }\n .portal-frame { min-height: 520px; }\n .workspace-split { grid-template-columns: 1fr; }\n .workspace-tree, .workspace-preview { max-height: 260px; }\n }\n`;\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provider-models.d.ts","sourceRoot":"","sources":["../../../src/web/admin/provider-models.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,KAAK,gBAAgB,GAAG,WAAW,GAAG,YAAY,CAAC;AAEnD,UAAU,sBAAsB;IAC9B,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAYD,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAgB9C;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE7D"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provider-models.js","sourceRoot":"","sources":["../../../src/web/admin/provider-models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAUpC,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AACnC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAO9B,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAoC,CAAC;AAExE,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,QAAqB,EACrB,MAAoB;IAEpB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkC,CAAC;IACzD,MAAM,UAAU,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAEjD,MAAM,OAAO,CAAC,GAAG,CACf,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,cAAc,CAAC,EAAE,EAAE;QACjE,MAAM,gBAAgB,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACzE,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE;gBAC7C,MAAM,EAAE,aAAa,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY;aAC/E,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,QAAgB,EAAE,EAAU;IACnD,OAAO,GAAG,QAAQ,IAAI,EAAE,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAoB;IACjD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC/C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,QAAqB,EACrB,QAAgB;IAEhB,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,WAAW;QAAE,OAAO,IAAI,GAAG,EAAU,CAAC;IAEhF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC7D,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,GAAG,EAAU,CAAC;IAEtC,MAAM,QAAQ,GAAG,GAAG,QAAQ,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;IACrD,MAAM,MAAM,GAAG,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC;IAEpE,IAAI,CAAC;QACH,MAAM,QAAQ,GACZ,QAAQ,KAAK,QAAQ;YACnB,CAAC,CAAC,MAAM,mBAAmB,CAAC,MAAM,CAAC;YACnC,CAAC,CAAC,MAAM,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAC3C,mBAAmB,CAAC,GAAG,CAAC,QAAQ,EAAE;YAChC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY;YACpC,QAAQ;SACT,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,MAAc;IAC/C,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,kCAAkC,EAAE;QAC1E,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE;KAC/C,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACtF,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuC,CAAC;IAC3E,OAAO,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,MAAc;IAClD,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,qCAAqC,EAAE;QAC7E,OAAO,EAAE;YACP,mBAAmB,EAAE,YAAY;YACjC,WAAW,EAAE,MAAM;SACpB;KACF,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACzF,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuC,CAAC;IAC3E,OAAO,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,GAAW,EAAE,IAAiB;IAC5D,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,gBAAgB,CAAC,CAAC;IACvE,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CACpB,gBAAyC,EACzC,eAAuB;IAEvB,OAAO,gBAAgB;QACrB,CAAC,CAAC,gBAAgB,CAAC,IAAI,KAAK,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,eAAe,CAAC;QACtE,CAAC,CAAC,KAAK,CAAC;AACZ,CAAC;AAED,SAAS,UAAU,CAAC,MAAc;IAChC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AACvD,CAAC","sourcesContent":["import { createHash } from \"crypto\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport type { MikanModels } from \"../../harness/index.js\";\n\ntype AdminModelStatus = \"available\" | \"unverified\";\n\ninterface AdminModelAccessStatus {\n status: AdminModelStatus;\n}\n\nconst CACHE_TTL_MS = 5 * 60 * 1000;\nconst PROBE_TIMEOUT_MS = 3000;\n\ninterface ProviderModelsCacheEntry {\n expiresAt: number;\n modelIds: Set<string>;\n}\n\nconst providerModelsCache = new Map<string, ProviderModelsCacheEntry>();\n\nexport async function resolveAdminModelAccessStatuses(\n registry: MikanModels,\n models: Model<Api>[],\n): Promise<Map<string, AdminModelAccessStatus>> {\n const result = new Map<string, AdminModelAccessStatus>();\n const byProvider = groupModelsByProvider(models);\n\n await Promise.all(\n [...byProvider.entries()].map(async ([provider, providerModels]) => {\n const providerModelIds = await fetchProviderModelIds(registry, provider);\n for (const model of providerModels) {\n result.set(modelKey(model.provider, model.id), {\n status: modelIsListed(providerModelIds, model.id) ? \"available\" : \"unverified\",\n });\n }\n }),\n );\n\n return result;\n}\n\nexport function modelKey(provider: string, id: string): string {\n return `${provider}/${id}`;\n}\n\nfunction groupModelsByProvider(models: Model<Api>[]): Map<string, Model<Api>[]> {\n const groups = new Map<string, Model<Api>[]>();\n for (const model of models) {\n const group = groups.get(model.provider) ?? [];\n group.push(model);\n groups.set(model.provider, group);\n }\n return groups;\n}\n\nasync function fetchProviderModelIds(\n registry: MikanModels,\n provider: string,\n): Promise<Set<string> | undefined> {\n if (provider !== \"openai\" && provider !== \"anthropic\") return new Set<string>();\n\n const apiKey = await registry.getApiKeyForProvider(provider);\n if (!apiKey) return new Set<string>();\n\n const cacheKey = `${provider}:${hashApiKey(apiKey)}`;\n const cached = providerModelsCache.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) return cached.modelIds;\n\n try {\n const modelIds =\n provider === \"openai\"\n ? await fetchOpenAiModelIds(apiKey)\n : await fetchAnthropicModelIds(apiKey);\n providerModelsCache.set(cacheKey, {\n expiresAt: Date.now() + CACHE_TTL_MS,\n modelIds,\n });\n return modelIds;\n } catch {\n return undefined;\n }\n}\n\nasync function fetchOpenAiModelIds(apiKey: string): Promise<Set<string>> {\n const response = await fetchWithTimeout(\"https://api.openai.com/v1/models\", {\n headers: { Authorization: `Bearer ${apiKey}` },\n });\n if (!response.ok) throw new Error(`OpenAI models request failed: ${response.status}`);\n const body = (await response.json()) as { data?: Array<{ id?: unknown }> };\n return new Set((body.data ?? []).map((model) => model.id).filter(isString));\n}\n\nasync function fetchAnthropicModelIds(apiKey: string): Promise<Set<string>> {\n const response = await fetchWithTimeout(\"https://api.anthropic.com/v1/models\", {\n headers: {\n \"anthropic-version\": \"2023-06-01\",\n \"x-api-key\": apiKey,\n },\n });\n if (!response.ok) throw new Error(`Anthropic models request failed: ${response.status}`);\n const body = (await response.json()) as { data?: Array<{ id?: unknown }> };\n return new Set((body.data ?? []).map((model) => model.id).filter(isString));\n}\n\nasync function fetchWithTimeout(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), PROBE_TIMEOUT_MS);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction modelIsListed(\n providerModelIds: Set<string> | undefined,\n registryModelId: string,\n): boolean {\n return providerModelIds\n ? providerModelIds.size === 0 || providerModelIds.has(registryModelId)\n : false;\n}\n\nfunction hashApiKey(apiKey: string): string {\n return createHash(\"sha256\").update(apiKey).digest(\"hex\").slice(0, 16);\n}\n\nfunction isString(value: unknown): value is string {\n return typeof value === \"string\" && value.length > 0;\n}\n"]}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { PlatformName } from "../../adapter.js";
|
|
2
|
-
import { InMemoryTokenStore } from "../token-store.js";
|
|
3
|
-
export type { AdminToken } from "./types.js";
|
|
4
|
-
import type { AdminToken } from "./types.js";
|
|
5
|
-
export declare class InMemoryAdminTokenStore extends InMemoryTokenStore<AdminToken> {
|
|
6
|
-
create(args: {
|
|
7
|
-
platform: PlatformName;
|
|
8
|
-
platformUserId: string;
|
|
9
|
-
conversationId: string;
|
|
10
|
-
platformUserName?: string;
|
|
11
|
-
}): AdminToken;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/web/admin/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,qBAAa,uBAAwB,SAAQ,kBAAkB,CAAC,UAAU,CAAC;IACzE,MAAM,CAAC,IAAI,EAAE;QACX,QAAQ,EAAE,YAAY,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,GAAG,UAAU,CAUb;CACF"}
|
package/dist/web/admin/store.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { InMemoryTokenStore } from "../token-store.js";
|
|
2
|
-
const TTL_MS = 30 * 60 * 1000;
|
|
3
|
-
export class InMemoryAdminTokenStore extends InMemoryTokenStore {
|
|
4
|
-
create(args) {
|
|
5
|
-
this.deleteWhere((token) => token.platform === args.platform && token.platformUserId === args.platformUserId);
|
|
6
|
-
return this.createRecord(TTL_MS, {
|
|
7
|
-
platform: args.platform,
|
|
8
|
-
platformUserId: args.platformUserId,
|
|
9
|
-
...(args.platformUserName ? { platformUserName: args.platformUserName } : {}),
|
|
10
|
-
conversationId: args.conversationId,
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=store.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/web/admin/store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAIvD,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE9B,MAAM,OAAO,uBAAwB,SAAQ,kBAA8B;IACzE,MAAM,CAAC,IAKN;QACC,IAAI,CAAC,WAAW,CACd,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,cAAc,KAAK,IAAI,CAAC,cAAc,CAC5F,CAAC;QACF,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;YAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,cAAc,EAAE,IAAI,CAAC,cAAc;SACpC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import type { PlatformName } from \"../../adapter.js\";\nimport { InMemoryTokenStore } from \"../token-store.js\";\nexport type { AdminToken } from \"./types.js\";\nimport type { AdminToken } from \"./types.js\";\n\nconst TTL_MS = 30 * 60 * 1000;\n\nexport class InMemoryAdminTokenStore extends InMemoryTokenStore<AdminToken> {\n create(args: {\n platform: PlatformName;\n platformUserId: string;\n conversationId: string;\n platformUserName?: string;\n }): AdminToken {\n this.deleteWhere(\n (token) => token.platform === args.platform && token.platformUserId === args.platformUserId,\n );\n return this.createRecord(TTL_MS, {\n platform: args.platform,\n platformUserId: args.platformUserId,\n ...(args.platformUserName ? { platformUserName: args.platformUserName } : {}),\n conversationId: args.conversationId,\n });\n }\n}\n"]}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { MessagingBot, PlatformName, RunningSession } from "../../adapter.js";
|
|
2
|
-
import type { LinkTokenStoreLike } from "../../commands/types.js";
|
|
3
|
-
import type { SandboxConfig } from "../../sandbox/index.js";
|
|
4
|
-
import type { VaultManager } from "../../vault/index.js";
|
|
5
|
-
import type { InMemorySessionViewTokenStore } from "../session-view/store.js";
|
|
6
|
-
import type { TokenRecord } from "../types.js";
|
|
7
|
-
import type { InMemoryAdminTokenStore } from "./store.js";
|
|
8
|
-
export interface AdminRuntimeBridge {
|
|
9
|
-
getRunningSessions(): RunningSession[];
|
|
10
|
-
switchConversationModel(conversationId: string, provider: string, model: string): boolean;
|
|
11
|
-
}
|
|
12
|
-
export interface AdminServices {
|
|
13
|
-
vaultManager: VaultManager;
|
|
14
|
-
linkTokenStore: LinkTokenStoreLike;
|
|
15
|
-
sessionViewTokenStore?: InMemorySessionViewTokenStore;
|
|
16
|
-
adminTokenStore: InMemoryAdminTokenStore;
|
|
17
|
-
portalBaseUrl?: string;
|
|
18
|
-
workingDir?: string;
|
|
19
|
-
sandbox?: SandboxConfig;
|
|
20
|
-
runtime?: AdminRuntimeBridge;
|
|
21
|
-
botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;
|
|
22
|
-
}
|
|
23
|
-
export interface AdminToken extends TokenRecord {
|
|
24
|
-
platform: PlatformName;
|
|
25
|
-
platformUserId: string;
|
|
26
|
-
platformUserName?: string;
|
|
27
|
-
/** The conversation where /admin was invoked. Default scope for the 3 sub-pages. */
|
|
28
|
-
conversationId: string;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/web/admin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,IAAI,cAAc,EAAE,CAAC;IACvC,uBAAuB,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3F;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,kBAAkB,CAAC;IACnC,qBAAqB,CAAC,EAAE,6BAA6B,CAAC;IACtD,eAAe,EAAE,uBAAuB,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,EAAE,YAAY,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oFAAoF;IACpF,cAAc,EAAE,MAAM,CAAC;CACxB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/web/admin/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { MessagingBot, PlatformName, RunningSession } from \"../../adapter.js\";\nimport type { LinkTokenStoreLike } from \"../../commands/types.js\";\nimport type { SandboxConfig } from \"../../sandbox/index.js\";\nimport type { VaultManager } from \"../../vault/index.js\";\nimport type { InMemorySessionViewTokenStore } from \"../session-view/store.js\";\nimport type { TokenRecord } from \"../types.js\";\nimport type { InMemoryAdminTokenStore } from \"./store.js\";\n\nexport interface AdminRuntimeBridge {\n getRunningSessions(): RunningSession[];\n switchConversationModel(conversationId: string, provider: string, model: string): boolean;\n}\n\nexport interface AdminServices {\n vaultManager: VaultManager;\n linkTokenStore: LinkTokenStoreLike;\n sessionViewTokenStore?: InMemorySessionViewTokenStore;\n adminTokenStore: InMemoryAdminTokenStore;\n portalBaseUrl?: string;\n workingDir?: string;\n sandbox?: SandboxConfig;\n runtime?: AdminRuntimeBridge;\n botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;\n}\n\nexport interface AdminToken extends TokenRecord {\n platform: PlatformName;\n platformUserId: string;\n platformUserName?: string;\n /** The conversation where /admin was invoked. Default scope for the 3 sub-pages. */\n conversationId: string;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../../../src/web/agent-events/portal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAG5D,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,GAAG,GACP,OAAO,CAiBT"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { addAgentEventStreamClient } from "../../agent-events.js";
|
|
2
|
-
export function handleAgentEventsRequest(req, res, url) {
|
|
3
|
-
if (req.method !== "GET" || url.pathname !== "/api/agent-events/stream") {
|
|
4
|
-
return false;
|
|
5
|
-
}
|
|
6
|
-
const expectedToken = process.env.MIKAN_AGENT_EVENTS_TOKEN;
|
|
7
|
-
const auth = req.headers.authorization ?? "";
|
|
8
|
-
const queryToken = url.searchParams.get("token") ?? "";
|
|
9
|
-
if (expectedToken && auth !== `Bearer ${expectedToken}` && queryToken !== expectedToken) {
|
|
10
|
-
res.writeHead(401, { "Content-Type": "text/plain; charset=utf-8" });
|
|
11
|
-
res.end("unauthorized");
|
|
12
|
-
return true;
|
|
13
|
-
}
|
|
14
|
-
const cleanup = addAgentEventStreamClient(res);
|
|
15
|
-
req.on("close", cleanup);
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=portal.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"portal.js","sourceRoot":"","sources":["../../../src/web/agent-events/portal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAElE,MAAM,UAAU,wBAAwB,CACtC,GAAoB,EACpB,GAAmB,EACnB,GAAQ;IAER,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,0BAA0B,EAAE,CAAC;QACxE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;IAC3D,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;IAC7C,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACvD,IAAI,aAAa,IAAI,IAAI,KAAK,UAAU,aAAa,EAAE,IAAI,UAAU,KAAK,aAAa,EAAE,CAAC;QACxF,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE,CAAC,CAAC;QACpE,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,yBAAyB,CAAC,GAAG,CAAC,CAAC;IAC/C,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzB,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"http\";\nimport { addAgentEventStreamClient } from \"../../agent-events.js\";\n\nexport function handleAgentEventsRequest(\n req: IncomingMessage,\n res: ServerResponse,\n url: URL,\n): boolean {\n if (req.method !== \"GET\" || url.pathname !== \"/api/agent-events/stream\") {\n return false;\n }\n\n const expectedToken = process.env.MIKAN_AGENT_EVENTS_TOKEN;\n const auth = req.headers.authorization ?? \"\";\n const queryToken = url.searchParams.get(\"token\") ?? \"\";\n if (expectedToken && auth !== `Bearer ${expectedToken}` && queryToken !== expectedToken) {\n res.writeHead(401, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n res.end(\"unauthorized\");\n return true;\n }\n\n const cleanup = addAgentEventStreamClient(res);\n req.on(\"close\", cleanup);\n return true;\n}\n"]}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export type { LoginCredentialKind, OAuthService, ParsedLoginCommand } from "./types.js";
|
|
2
|
-
import type { OAuthService, ParsedLoginCommand } from "./types.js";
|
|
3
|
-
export declare function getOAuthServices(): OAuthService[];
|
|
4
|
-
export declare function resolveOAuthService(input: string): OAuthService | undefined;
|
|
5
|
-
export declare function parseLoginCommand(text: string): ParsedLoginCommand | null;
|
|
6
|
-
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../src/web/login/oauth.ts"],"names":[],"mappings":"AAKA,YAAY,EAAE,mBAAmB,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACxF,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAyOnE,wBAAgB,gBAAgB,IAAI,YAAY,EAAE,CA8BjD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAM3E;AAID,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CA+BzE"}
|