@shipit-ai/cli 1.165.0 → 1.166.1
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/LICENSE +2 -1
- package/README.md +6 -0
- package/apis/json-schema/AgentSession.yaml +1 -1
- package/apis/json-schema/AgentType.yaml +2 -0
- package/dist/eslint.config.mjs +2 -0
- package/dist/packages/core/src/application/ports/output/services/spec-initializer.interface.d.ts +1 -1
- package/dist/packages/core/src/application/ports/output/services/spec-initializer.interface.js +1 -1
- package/dist/packages/core/src/application/use-cases/agents/delete-agent-run.use-case.js +1 -1
- package/dist/packages/core/src/domain/generated/output.d.ts +3 -1
- package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
- package/dist/packages/core/src/domain/generated/output.js +2 -0
- package/dist/packages/core/src/infrastructure/di/modules/agents.module.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/modules/agents.module.js +6 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.js +33 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-validator.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-validator.service.js +2 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.d.ts +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.js +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/copilot-cli-executor.service.d.ts +34 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/copilot-cli-executor.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/copilot-cli-executor.service.js +149 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.js +2 -2
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/research.fixture.d.ts +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/research.fixture.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/research.fixture.js +2 -2
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/tasks.fixture.d.ts +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/tasks.fixture.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/tasks.fixture.js +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/rovo-dev-executor.service.d.ts +37 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/rovo-dev-executor.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/rovo-dev-executor.service.js +150 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +1 -1
- package/dist/packages/core/src/infrastructure/services/git/merge-strategy.service.js +1 -1
- package/dist/packages/core/src/infrastructure/services/interactive/feature-context.builder.js +1 -1
- package/dist/packages/core/src/infrastructure/services/notifications/notification-bus.js +1 -1
- package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.d.ts +1 -1
- package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.js +3 -3
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/copilot-cli.json +31 -0
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/rovo-dev.json +31 -0
- package/dist/src/presentation/web/app/actions/check-agent-auth.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/check-agent-auth.js +35 -0
- package/dist/src/presentation/web/app/actions/check-agent-tool.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/check-agent-tool.js +4 -0
- package/dist/src/presentation/web/app/actions/get-all-agent-models.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/get-all-agent-models.js +8 -2
- package/dist/src/presentation/web/components/assistant-ui/thread.js +2 -2
- package/dist/src/presentation/web/components/common/action-button/action-button.js +2 -2
- package/dist/src/presentation/web/components/common/action-button/action-button.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/action-button/action-button.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/add-repository-button/add-repository-button.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/add-repository-button/add-repository-button.js +3 -2
- package/dist/src/presentation/web/components/common/add-repository-button/add-repository-button.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/add-repository-button/add-repository-button.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/add-repository-button/add-repository-button.stories.js +1 -1
- package/dist/src/presentation/web/components/common/attachment-card/attachment-card.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/attachment-card/attachment-card.js +2 -2
- package/dist/src/presentation/web/components/common/attachment-card/attachment-card.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/attachment-card/attachment-card.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/attachment-card/attachment-card.stories.js +1 -1
- package/dist/src/presentation/web/components/common/attachment-chip/attachment-chip.js +2 -2
- package/dist/src/presentation/web/components/common/attachment-chip/attachment-chip.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/attachment-chip/attachment-chip.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/attachment-chip/attachment-chip.stories.js +1 -1
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/ci-status-badge/ci-status-badge.js +4 -4
- package/dist/src/presentation/web/components/common/ci-status-badge/ci-status-badge.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/ci-status-badge/ci-status-badge.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.js +3 -3
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.stories.js +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-drawer-client.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-drawer-client.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +3 -3
- package/dist/src/presentation/web/components/common/control-center-drawer/global-chat-drawer-client.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/global-chat-drawer-client.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/repository-drawer-client.js +5 -5
- package/dist/src/presentation/web/components/common/control-center-drawer/repository-drawer-client.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/repository-drawer-client.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.js +2 -2
- package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/delete-feature-dialog/delete-feature-dialog.stories.js +1 -1
- package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.js +2 -2
- package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.js +2 -2
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.js +1 -1
- package/dist/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/drawer-revision-input/drawer-revision-input.stories.js +1 -1
- package/dist/src/presentation/web/components/common/editor-type-icons.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/editor-type-icons.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/elapsed-time/elapsed-time.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/elapsed-time/elapsed-time.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/empty-state/empty-state.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/empty-state/empty-state.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/parent-feature-combobox.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/parent-feature-combobox.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/prompt-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/prompt-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/prompt-section.stories.js +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/repository-combobox.js +2 -2
- package/dist/src/presentation/web/components/common/feature-create-drawer/repository-combobox.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/repository-combobox.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.stories.js +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.js +7 -7
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/branch-sync-status.js +2 -2
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/branch-sync-status.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/branch-sync-status.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/branch-sync-status.stories.js +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.js +4 -6
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +2 -2
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.js +2 -2
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +4 -4
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.js +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.js +4 -4
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.js +3 -3
- package/dist/src/presentation/web/components/common/feature-node/feature-node.js +5 -11
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-status-badges/feature-status-badges.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-status-badges/feature-status-badges.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-status-config.js +2 -2
- package/dist/src/presentation/web/components/common/feature-status-group/feature-status-group.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-status-group/feature-status-group.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/floating-action-button/floating-action-button.js +2 -2
- package/dist/src/presentation/web/components/common/floating-action-button/floating-action-button.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/floating-action-button/floating-action-button.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/github-import-dialog/github-import-dialog.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/github-import-dialog/github-import-dialog.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/github-import-dialog/github-import-dialog.stories.js +1 -1
- package/dist/src/presentation/web/components/common/github-import-dialog/github-repo-browser.js +3 -3
- package/dist/src/presentation/web/components/common/github-import-dialog/github-repo-browser.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/github-import-dialog/github-repo-browser.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/github-import-dialog/github-repo-browser.stories.js +1 -1
- package/dist/src/presentation/web/components/common/github-import-dialog/github-url-input.js +2 -2
- package/dist/src/presentation/web/components/common/github-import-dialog/github-url-input.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/github-import-dialog/github-url-input.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/github-import-dialog/github-url-input.stories.js +1 -1
- package/dist/src/presentation/web/components/common/inline-attachments/inline-attachments.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/inline-attachments/inline-attachments.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/loading-skeleton/loading-skeleton.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/loading-skeleton/loading-skeleton.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/merge-review/diff-view.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/merge-review/diff-view.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/merge-review/merge-review.js +3 -5
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.js +1 -1
- package/dist/src/presentation/web/components/common/open-action-menu/open-action-menu.js +2 -2
- package/dist/src/presentation/web/components/common/open-action-menu/open-action-menu.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/open-action-menu/open-action-menu.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/open-action-menu/open-action-menu.stories.js +1 -1
- package/dist/src/presentation/web/components/common/page-header/page-header.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/page-header/page-header.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.js +1 -1
- package/dist/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/react-file-manager-dialog/react-file-manager-dialog.js +2 -2
- package/dist/src/presentation/web/components/common/react-file-manager-dialog/react-file-manager-dialog.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/react-file-manager-dialog/react-file-manager-dialog.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/react-file-manager-dialog/react-file-manager-dialog.stories.js +1 -1
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.js +2 -2
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/reject-feedback-dialog/reject-feedback-dialog.stories.js +1 -1
- package/dist/src/presentation/web/components/common/repo-group/repo-group.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/repo-group/repo-group.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-node.js +4 -7
- package/dist/src/presentation/web/components/common/repository-node/repository-node.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-node.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/server-log-viewer/server-log-viewer.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/server-log-viewer/server-log-viewer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/shipit-ai-logo/shipit-ai-logo.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/shipit-ai-logo/shipit-ai-logo.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/sound-toggle/sound-toggle.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/sound-toggle/sound-toggle.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/task-progress-view/task-progress-view.js +4 -4
- package/dist/src/presentation/web/components/common/task-progress-view/task-progress-view.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/task-progress-view/task-progress-view.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.js +1 -1
- package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/version-badge/version-badge.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/version-badge/version-badge.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/AgentStatusBadge.js +7 -7
- package/dist/src/presentation/web/components/features/chat/AgentStatusBadge.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/chat/AgentStatusBadge.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatComposer.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatComposer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatComposer.stories.js +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatInput.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatInput.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatMessageBubble.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatMessageBubble.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatMessageList.stories.d.ts +2 -2
- package/dist/src/presentation/web/components/features/chat/ChatMessageList.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatSheet.stories.d.ts +2 -2
- package/dist/src/presentation/web/components/features/chat/ChatSheet.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatTab.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatTab.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js +9 -13
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +3 -2
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.stories.d.ts +2 -2
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.js +3 -3
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.stories.js +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.stories.d.ts +2 -2
- package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.stories.js +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/dependency-edge.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/dependency-edge.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.js +1 -4
- package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.js +1 -1
- package/dist/src/presentation/web/components/features/settings/ModelPicker/ModelPicker.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/ModelPicker/ModelPicker.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/ModelPicker/ModelPicker.stories.js +1 -1
- package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/ci-settings-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/ci-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/database-settings-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/database-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/environment-settings-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/environment-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/fab-layout-settings-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/fab-layout-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/interactive-agent-settings-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/interactive-agent-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/language-settings-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/language-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/notification-settings-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/notification-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-section-utils.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-section-utils.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-section-utils.stories.js +1 -1
- package/dist/src/presentation/web/components/features/settings/stage-timeouts-settings-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/stage-timeouts-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/timeout-slider.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/timeout-slider.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/workflow-settings-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/workflow-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/skills/category-filter.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/skills/category-filter.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/skills/skill-card.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/skills/skill-card.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/skills/skill-card.stories.js +3 -3
- package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.stories.js +3 -3
- package/dist/src/presentation/web/components/features/skills/skill-list.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/skills/skill-list.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/skills/skill-list.stories.js +4 -4
- package/dist/src/presentation/web/components/features/skills/skills-page-client.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/skills/skills-page-client.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/skills/skills-page-client.stories.js +8 -8
- package/dist/src/presentation/web/components/features/tools/tool-card.js +3 -5
- package/dist/src/presentation/web/components/features/tools/tool-card.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/tools/tool-card.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/tools/tool-detail-drawer.js +3 -7
- package/dist/src/presentation/web/components/features/tools/tool-detail-drawer.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/tools/tool-detail-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/tools/tools-page-client.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/tools/tools-page-client.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/version/version-page-client.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/version/version-page-client.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/layouts/app-shell/app-shell.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/layouts/app-shell/app-shell.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/layouts/dashboard-layout/dashboard-layout.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/layouts/dashboard-layout/dashboard-layout.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/layouts/header/header.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/layouts/header/header.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/layouts/sidebar/sidebar.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/layouts/sidebar/sidebar.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/accordion.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/accordion.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/alert-dialog.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/alert-dialog.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/alert.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/alert.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/alert.stories.js +2 -2
- package/dist/src/presentation/web/components/ui/badge.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/badge.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/button.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/button.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/card.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/card.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/checkbox-group-item.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/checkbox-group-item.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/checkbox-group.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/checkbox-group.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/checkbox.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/checkbox.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/comet-spinner.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/comet-spinner.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/command.stories.d.ts +2 -2
- package/dist/src/presentation/web/components/ui/command.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/dialog.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/dialog.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/drawer.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/dropdown-menu.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/dropdown-menu.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/github-icon.d.ts +13 -0
- package/dist/src/presentation/web/components/ui/github-icon.d.ts.map +1 -0
- package/dist/src/presentation/web/components/ui/github-icon.js +15 -0
- package/dist/src/presentation/web/components/ui/github-icon.stories.d.ts +10 -0
- package/dist/src/presentation/web/components/ui/github-icon.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/ui/github-icon.stories.js +22 -0
- package/dist/src/presentation/web/components/ui/input.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/input.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/label.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/label.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/popover.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/popover.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/scroll-area.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/scroll-area.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/select.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/select.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/separator.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/separator.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/sheet.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/sheet.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/sidebar.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/sidebar.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/skeleton.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/skeleton.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/slider.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/slider.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/sonner.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/sonner.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/spinner.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/spinner.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/switch.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/switch.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/tabs.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/tabs.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/textarea.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/textarea.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/tooltip.stories.d.ts +2 -2
- package/dist/src/presentation/web/components/ui/tooltip.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-notifications.stories.d.ts +1 -1
- package/dist/src/presentation/web/hooks/use-notifications.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-sound-action.stories.d.ts +1 -1
- package/dist/src/presentation/web/hooks/use-sound-action.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-sound.stories.d.ts +1 -1
- package/dist/src/presentation/web/hooks/use-sound.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/lib/session-scanner.js +2 -2
- package/dist/src/presentation/web/lib/skills.js +2 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +24 -25
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +5 -5
- package/web/.next/fallback-build-manifest.json +3 -3
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +2 -2
- package/web/.next/required-server-files.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/chat/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/create/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +30 -30
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +37 -37
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/chat/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/chat/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/create/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +30 -30
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +37 -37
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error/page/build-manifest.json +2 -2
- package/web/.next/server/app/_global-error.html +1 -1
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/build-manifest.json +2 -2
- package/web/.next/server/app/_not-found/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/api/dialog/pick-files/route.js.nft.json +1 -1
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
- package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
- package/web/.next/server/app/api/sessions/route.js +2 -2
- package/web/.next/server/app/settings/page/build-manifest.json +2 -2
- package/web/.next/server/app/settings/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/settings/page/server-reference-manifest.json +11 -11
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/build-manifest.json +2 -2
- package/web/.next/server/app/skills/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/skills/page/server-reference-manifest.json +11 -11
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/build-manifest.json +2 -2
- package/web/.next/server/app/tools/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/build-manifest.json +2 -2
- package/web/.next/server/app/version/page/react-loadable-manifest.json +3 -3
- package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/0n.o_server_app_api_interactive_chat_[featureId]_stop_route_actions_09da~zt.js +1 -1
- package/web/.next/server/chunks/11es_next_dist_esm_build_templates_app-route_067cwst.js +1 -1
- package/web/.next/server/chunks/11es_next_dist_esm_build_templates_app-route_067cwst.js.map +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__07suer1._.js.map +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__0_.w-eb._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__0_.w-eb._.js.map +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__0tb~wwk._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__13ni_ow._.js +1 -1
- package/web/.next/server/chunks/ssr/{0lyk_lucide-react_dist_esm_icons_0shxsmr._.js → 08qz_lucide-react_dist_esm_icons_0_gqlce._.js} +2 -2
- package/web/.next/server/chunks/ssr/08qz_lucide-react_dist_esm_icons_0_gqlce._.js.map +1 -0
- package/web/.next/server/chunks/ssr/08qz_lucide-react_dist_esm_icons_0zwb4s4._.js +3 -0
- package/web/.next/server/chunks/ssr/08qz_lucide-react_dist_esm_icons_0zwb4s4._.js.map +1 -0
- package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_00~eq5i.js +1 -1
- package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_00~eq5i.js.map +1 -1
- package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_0979_c..js +1 -1
- package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_0979_c..js.map +1 -1
- package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_chat_page_actions_0dqll_1.js +1 -1
- package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_chat_page_actions_0dqll_1.js.map +1 -1
- package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js +1 -1
- package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js.map +1 -1
- package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js +3 -3
- package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js.map +1 -1
- package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js +1 -1
- package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js.map +1 -1
- package/web/.next/server/chunks/ssr/11es_next_dist_0e36~wi._.js +2 -2
- package/web/.next/server/chunks/ssr/11es_next_dist_client_components_058~c_t._.js +1 -1
- package/web/.next/server/chunks/ssr/11es_next_dist_esm_build_templates_app-page_0l-25e2.js +1 -1
- package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_global-chat-drawer-client_tsx_03s32.q._.js +1 -1
- package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js +1 -1
- package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__0uxn6-j._.js → [root-of-the-server]__045sv4b._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__0uxn6-j._.js.map → [root-of-the-server]__045sv4b._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0brje6_._.js +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__0np51e2._.js → [root-of-the-server]__0d_0_fp._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__0np51e2._.js.map → [root-of-the-server]__0d_0_fp._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__0~h382a._.js → [root-of-the-server]__0l4d7e.._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__0~h382a._.js.map → [root-of-the-server]__0l4d7e.._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__0_ag.8y._.js → [root-of-the-server]__0lslgap._.js} +3 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0lslgap._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0o3qggc._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0o3qggc._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__01~y8wi._.js → [root-of-the-server]__0r32z03._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__01~y8wi._.js.map → [root-of-the-server]__0r32z03._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0rv1gci._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__122xqm6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__12g8h3_._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__12g8h3_._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_0d-pkk0._.js → _0-09vq7._.js} +2 -2
- package/web/.next/server/chunks/ssr/_0-09vq7._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_0.rsra~._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_00k65h-._.js +3 -0
- package/web/.next/server/chunks/ssr/_00k65h-._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_01mq~sm._.js +2 -2
- package/web/.next/server/chunks/ssr/_01mq~sm._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_01sesw0._.js +3 -0
- package/web/.next/server/chunks/ssr/_01sesw0._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_04s_q5r._.js +1 -1
- package/web/.next/server/chunks/ssr/_04s_q5r._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_0xtds88._.js → _08i-c2n._.js} +2 -2
- package/web/.next/server/chunks/ssr/_08i-c2n._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_0a-ddx-._.js +3 -0
- package/web/.next/server/chunks/ssr/_0a-ddx-._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{_0jk5q_z._.js → _0e4npv~._.js} +2 -2
- package/web/.next/server/chunks/ssr/_0e4npv~._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_0gdghcr._.js +3 -0
- package/web/.next/server/chunks/ssr/_0gdghcr._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_0hwjfpu._.js +3 -0
- package/web/.next/server/chunks/ssr/_0hwjfpu._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_0hw~zvl._.js +3 -0
- package/web/.next/server/chunks/ssr/_0hw~zvl._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_0jpbsh_._.js +1 -1
- package/web/.next/server/chunks/ssr/_0jpbsh_._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_13bl-l1._.js → _0nvrqsj._.js} +2 -2
- package/web/.next/server/chunks/ssr/_0nvrqsj._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_0phryzt._.js +3 -0
- package/web/.next/server/chunks/ssr/_0phryzt._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_0vyfc4b._.js +3 -0
- package/web/.next/server/chunks/ssr/_0vyfc4b._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_0w-_hww._.js +1 -1
- package/web/.next/server/chunks/ssr/_0w-_hww._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_0j9vx-1._.js → _0y8u4.e._.js} +3 -3
- package/web/.next/server/chunks/ssr/_0y8u4.e._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_0~7lwu_._.js +3 -0
- package/web/.next/server/chunks/ssr/_0~7lwu_._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{_0rvaoj4._.js → _109n-y4._.js} +2 -2
- package/web/.next/server/chunks/ssr/_109n-y4._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{_09g41d0._.js → _12un22l._.js} +3 -3
- package/web/.next/server/chunks/ssr/_12un22l._.js.map +1 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_0l8_ov3._.js +3 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_0l8_ov3._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_0.e4~xc._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_0.e4~xc._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_00dvh.m._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_00dvh.m._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_05-w-~v._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_05-w-~v._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_06b6~lt._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_06b6~lt._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_08fy2mf._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_08fy2mf._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_0f~udu1._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_0f~udu1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_0qys821._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_0qys821._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_0q~dt0o._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_0q~dt0o._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_0y11iiz._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_0y11iiz._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_11jrkxt._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_11jrkxt._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_1199d3x.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_1199d3x.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app__not-found_page_actions_0m2jqxx.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app__not-found_page_actions_0m2jqxx.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_version_page_actions_0krkh_0.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_version_page_actions_0krkh_0.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_load-settings_ts_0b8f3pf._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_0aji.op._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_0aji.op._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_select_tsx_0b.-59k._.js +1 -1
- package/web/.next/server/middleware-build-manifest.js +5 -5
- package/web/.next/server/pages/500.html +1 -1
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +49 -49
- package/web/.next/static/chunks/0-lu0b1ewsb0_.js +1 -0
- package/web/.next/static/chunks/00dg6gti40.3i.js +1 -0
- package/web/.next/static/chunks/01~dudieyb7wl.js +5 -0
- package/web/.next/static/chunks/{0riti1bs-erm~.js → 02kpdawdtqcxm.js} +1 -1
- package/web/.next/static/chunks/{0~er~22zwvx0i.js → 09_oo_kc.j.df.js} +1 -1
- package/web/.next/static/chunks/09dqgshddfxff.js +1 -0
- package/web/.next/static/chunks/0_--5mgqukm__.js +1 -0
- package/web/.next/static/chunks/0_c5~n__lz4ks.js +1 -0
- package/web/.next/static/chunks/0awttldb-.7m..js +1 -0
- package/web/.next/static/chunks/0d-2jp.f._l2e.js +1 -0
- package/web/.next/static/chunks/0fg~vc93spa9c.js +1 -0
- package/web/.next/static/chunks/{0t_48qc0x7bhs.js → 0ist7260j__0m.js} +3 -3
- package/web/.next/static/chunks/0j_0i2qsrwh-c.js +1 -0
- package/web/.next/static/chunks/{07yqyvabetyrh.js → 0l.kymg3jmf7n.js} +2 -2
- package/web/.next/static/chunks/0m5~9kij3s~81.js +1 -0
- package/web/.next/static/chunks/0njrgvmyafrod.js +1 -0
- package/web/.next/static/chunks/0nk2r-18.7g6r.js +1 -0
- package/web/.next/static/chunks/0ntgq3d_.m5el.js +5 -0
- package/web/.next/static/chunks/{0wmckrtphfa12.js → 0odlgm-ixqorl.js} +1 -1
- package/web/.next/static/chunks/0q~uf2s33.48w.js +1 -0
- package/web/.next/static/chunks/0t.pzrmeoq6th.js +7 -0
- package/web/.next/static/chunks/0t8zwgaz.d1s5.js +1 -0
- package/web/.next/static/chunks/11bi612fz8agh.js +1 -0
- package/web/.next/static/chunks/{071_2_.sfp-im.js → 14g1l3~6i5251.js} +2 -2
- package/web/.next/static/chunks/164dnpi666fv_.js +5 -0
- package/web/.next/static/chunks/{turbopack-0ve8f54_veg.u.js → turbopack-0wsav6to5abtk.js} +1 -1
- package/web/package.json +5 -5
- package/web/.next/server/chunks/ssr/0lyk_lucide-react_dist_esm_icons_06zrfq4._.js +0 -3
- package/web/.next/server/chunks/ssr/0lyk_lucide-react_dist_esm_icons_06zrfq4._.js.map +0 -1
- package/web/.next/server/chunks/ssr/0lyk_lucide-react_dist_esm_icons_0shxsmr._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0_ag.8y._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__12qqi.~._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__12qqi.~._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0.gy.n8._.js +0 -3
- package/web/.next/server/chunks/ssr/_0.gy.n8._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0.k7wl.._.js +0 -3
- package/web/.next/server/chunks/ssr/_0.k7wl.._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_09g41d0._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0aa~oer._.js +0 -3
- package/web/.next/server/chunks/ssr/_0aa~oer._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0d-pkk0._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0ez.1o4._.js +0 -3
- package/web/.next/server/chunks/ssr/_0ez.1o4._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0j9vx-1._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0jk5q_z._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0n.xy38._.js +0 -3
- package/web/.next/server/chunks/ssr/_0n.xy38._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0rvaoj4._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0v.yfmg._.js +0 -3
- package/web/.next/server/chunks/ssr/_0v.yfmg._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0vl.03w._.js +0 -3
- package/web/.next/server/chunks/ssr/_0vl.03w._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0xtds88._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_11kuznh._.js +0 -3
- package/web/.next/server/chunks/ssr/_11kuznh._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_13bl-l1._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_13euo-f._.js +0 -3
- package/web/.next/server/chunks/ssr/_13euo-f._.js.map +0 -1
- package/web/.next/server/chunks/ssr/node_modules__pnpm_0xyo1be._.js +0 -3
- package/web/.next/server/chunks/ssr/node_modules__pnpm_0xyo1be._.js.map +0 -1
- package/web/.next/static/chunks/00racug7sobut.js +0 -1
- package/web/.next/static/chunks/06sdx5zm71_u5.js +0 -1
- package/web/.next/static/chunks/08iq.j3rbmhbm.js +0 -1
- package/web/.next/static/chunks/08iuksm8rvb09.js +0 -1
- package/web/.next/static/chunks/08se-_opmk~.7.js +0 -1
- package/web/.next/static/chunks/09b2usag59_bi.js +0 -5
- package/web/.next/static/chunks/0icjwdqytqa_8.js +0 -5
- package/web/.next/static/chunks/0qjoc4x5q-aeg.js +0 -1
- package/web/.next/static/chunks/0rhzqh.-6e6k7.js +0 -1
- package/web/.next/static/chunks/0s-e-ekdbgoqa.js +0 -1
- package/web/.next/static/chunks/0u5.s.lv2bae5.js +0 -1
- package/web/.next/static/chunks/0vgbvqu82ac1x.js +0 -1
- package/web/.next/static/chunks/0w~84g7r9307~.js +0 -1
- package/web/.next/static/chunks/0y1nwnouroh6k.js +0 -1
- package/web/.next/static/chunks/0zz.xgsd83.3n.js +0 -1
- package/web/.next/static/chunks/0~wymq55b2bn3.js +0 -1
- package/web/.next/static/chunks/10wo3waalauct.js +0 -5
- package/web/.next/static/chunks/15lcx-697j_3z.js +0 -7
- package/web/.next/static/chunks/176x256xw_viv.js +0 -1
- /package/web/.next/static/{xP_-L4TLYvd3i_sEmljLs → ZpPnD_b687G9xVr2nzrds}/_buildManifest.js +0 -0
- /package/web/.next/static/{xP_-L4TLYvd3i_sEmljLs → ZpPnD_b687G9xVr2nzrds}/_clientMiddlewareManifest.js +0 -0
- /package/web/.next/static/{xP_-L4TLYvd3i_sEmljLs → ZpPnD_b687G9xVr2nzrds}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../src/presentation/web/components/common/product-decisions-summary/product-decisions-summary.tsx","../../../../../../../src/presentation/web/hooks/use-branch-sync-status.ts","../../../../../../../src/presentation/web/app/actions/data%3A98db1d%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/app/actions/data%3Ad4fd8b%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/app/actions/data%3Acf020c%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/app/actions/data%3Aab0d76%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/common/open-action-menu/open-action-menu.tsx","../../../../../../../src/presentation/web/app/actions/data%3A47b417%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/app/actions/data%3A7c73c6%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx","../../../../../../../src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.tsx","../../../../../../../src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.tsx","../../../../../../../src/presentation/web/app/actions/data%3A4ff9d8%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/common/merge-review/diff-view.tsx","../../../../../../../src/presentation/web/components/common/merge-review/merge-review.tsx","../../../../../../../src/presentation/web/components/common/inline-attachments/inline-attachments.tsx","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/overview-tab.tsx","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.tsx","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.tsx","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/log-tab.tsx","../../../../../../../src/presentation/web/components/common/task-progress-view/task-progress-view.tsx","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/plan-tab.tsx","../../../../../../../src/presentation/web/hooks/use-feature-logs.ts","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.ts","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.tsx","../../../../../../../src/presentation/web/app/actions/data%3Ae4017b%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/common/feature-drawer/use-feature-actions.ts","../../../../../../../src/presentation/web/components/common/control-center-drawer/use-artifact-fetch.ts","../../../../../../../src/presentation/web/app/actions/data%3A4c23e4%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx","../../../../../../../src/presentation/web/components/common/control-center-drawer/use-drawer-sync.ts","../../../../../../../src/presentation/web/app/actions/data%3A418be1%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/common/ci-status-badge/ci-status-badge.tsx","../../../../../../../src/presentation/web/components/ui/comet-spinner.tsx","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/monitor-play.ts","../../../../../../../src/presentation/web/lib/format-duration.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/info.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/arrow-up-from-line.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/dollar-sign.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/scroll-text.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/arrow-right.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/arrow-down-to-line.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/server.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/list-todo.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/image-off.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/circle-dashed.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/git-merge.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/git-compare-arrows.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/coins.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/file-minus.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/file-check.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/file-code.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/layers.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/shield-check.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/file-diff.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/map.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/file-search.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/camera.ts","../../../../../../../node_modules/.pnpm/lucide-react%400.563.0_react%4019.2.4/node_modules/lucide-react/src/icons/send.ts","../../../../../../../src/presentation/web/components/common/control-center-drawer/drawer-view.ts","../../../../../../../src/presentation/web/lib/parse-log-line.ts"],"sourcesContent":["'use client';\n\nimport { ClipboardList } from 'lucide-react';\nimport { Badge } from '@/components/ui/badge';\nimport type {\n ProductDecisionsSummaryProps,\n ProductDecisionItem,\n} from './product-decisions-summary-config';\n\nfunction ProductDecisionCard({ item, index }: { item: ProductDecisionItem; index: number }) {\n return (\n <div className=\"border-border rounded-lg border\">\n <div className=\"space-y-2 px-4 py-3\">\n <div className=\"flex items-start gap-2.5\">\n <span className=\"bg-primary text-primary-foreground flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-xs font-bold\">\n {index + 1}\n </span>\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"text-foreground text-sm leading-tight font-semibold\">{item.question}</h3>\n <div className=\"mt-1 flex items-center gap-2\">\n <p className=\"text-muted-foreground min-w-0 truncate text-xs\">\n {item.selectedOption}\n </p>\n {item.wasRecommended ? (\n <Badge className=\"shrink-0 px-1.5 py-0 text-[10px] whitespace-nowrap\">\n AI Recommended\n </Badge>\n ) : null}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nexport function ProductDecisionsSummary({ data }: ProductDecisionsSummaryProps) {\n const { questions } = data;\n\n if (questions.length === 0) return null;\n\n return (\n <div className=\"space-y-4 p-4\">\n {/* Section heading */}\n <div className=\"flex items-center gap-2\">\n <ClipboardList className=\"text-primary h-4 w-4\" />\n <h3 className=\"text-foreground text-sm font-bold\">Product Decisions</h3>\n </div>\n\n {/* Decision cards */}\n {questions.map((item, i) => (\n <ProductDecisionCard key={item.question} item={item} index={i} />\n ))}\n </div>\n );\n}\n","'use client';\n\nimport { useState, useCallback, useEffect, useRef } from 'react';\nimport { getBranchSyncStatus } from '@/app/actions/get-branch-sync-status';\n\nexport interface BranchSyncData {\n ahead: number;\n behind: number;\n baseBranch: string;\n checkedAt: string;\n}\n\nexport interface UseBranchSyncStatusResult {\n data: BranchSyncData | null;\n loading: boolean;\n error: string | null;\n refresh: () => void;\n}\n\nconst CACHE_TTL_MS = 30_000;\n\n/** Module-level cache so data survives component remounts / drawer close-reopen. */\nconst cache = new Map<string, { data: BranchSyncData; timestamp: number }>();\n\nexport function useBranchSyncStatus(featureId: string | null): UseBranchSyncStatusResult {\n const [data, setData] = useState<BranchSyncData | null>(() => {\n if (!featureId) return null;\n const cached = cache.get(featureId);\n return cached ? cached.data : null;\n });\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const featureIdRef = useRef(featureId);\n featureIdRef.current = featureId;\n\n const fetchStatus = useCallback(async (id: string) => {\n setLoading(true);\n setError(null);\n try {\n const result = await getBranchSyncStatus(id);\n // Guard against stale responses if featureId changed during fetch\n if (featureIdRef.current !== id) return;\n if (result.success && result.data) {\n const syncData: BranchSyncData = result.data;\n cache.set(id, { data: syncData, timestamp: Date.now() });\n setData(syncData);\n } else {\n setError(result.error ?? 'Failed to check sync status');\n }\n } catch {\n if (featureIdRef.current !== id) return;\n setError('Failed to check sync status');\n } finally {\n if (featureIdRef.current === id) {\n setLoading(false);\n }\n }\n }, []);\n\n // Auto-fetch on mount if cache is stale\n useEffect(() => {\n if (!featureId) {\n setData(null);\n setError(null);\n return;\n }\n\n const cached = cache.get(featureId);\n if (cached) {\n setData(cached.data);\n if (Date.now() - cached.timestamp < CACHE_TTL_MS) return;\n }\n\n void fetchStatus(featureId);\n }, [featureId, fetchStatus]);\n\n const refresh = useCallback(() => {\n if (featureId) {\n void fetchStatus(featureId);\n }\n }, [featureId, fetchStatus]);\n\n return { data, loading, error, refresh };\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"70058ea4a019b792a33c4f373daa88a243bedc19ba\":{\"name\":\"rejectFeature\"}},\"src/presentation/web/app/actions/reject-feature.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"70058ea4a019b792a33c4f373daa88a243bedc19ba\",callServer,void 0,findSourceMapURL,\"rejectFeature\");export{$$RSC_SERVER_ACTION_0 as rejectFeature};","/* __next_internal_action_entry_do_not_use__ [{\"40a3b38d4d440be674e98741aebbbc27e952ffd55f\":{\"name\":\"getFeatureArtifact\"}},\"src/presentation/web/app/actions/get-feature-artifact.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"40a3b38d4d440be674e98741aebbbc27e952ffd55f\",callServer,void 0,findSourceMapURL,\"getFeatureArtifact\");export{$$RSC_SERVER_ACTION_0 as getFeatureArtifact};","/* __next_internal_action_entry_do_not_use__ [{\"400b6ed88289b9d28a47b78510ce9ed0f9da32d062\":{\"name\":\"getResearchArtifact\"}},\"src/presentation/web/app/actions/get-research-artifact.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"400b6ed88289b9d28a47b78510ce9ed0f9da32d062\",callServer,void 0,findSourceMapURL,\"getResearchArtifact\");export{$$RSC_SERVER_ACTION_0 as getResearchArtifact};","/* __next_internal_action_entry_do_not_use__ [{\"40737ca8dbb8b9aa0fd2b2091eaaf0e5090cb66839\":{\"name\":\"getMergeReviewData\"}},\"src/presentation/web/app/actions/get-merge-review-data.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"40737ca8dbb8b9aa0fd2b2091eaaf0e5090cb66839\",callServer,void 0,findSourceMapURL,\"getMergeReviewData\");export{$$RSC_SERVER_ACTION_0 as getMergeReviewData};","'use client';\n\nimport { useState } from 'react';\nimport {\n Code2,\n Terminal,\n FolderOpen,\n FileText,\n Copy,\n Check,\n Loader2,\n CircleAlert,\n} from 'lucide-react';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\nimport type { OpenActionMenuProps } from './config';\n\nconst COPY_FEEDBACK_DELAY = 2000;\n\nconst tbBtn =\n 'text-muted-foreground hover:bg-foreground/8 hover:text-foreground inline-flex size-8 items-center justify-center rounded-[3px] disabled:opacity-40';\n\nfunction TbIcon({\n loading,\n error,\n icon: Icon,\n}: {\n loading?: boolean;\n error?: string | null;\n icon: React.ComponentType<{ className?: string }>;\n}) {\n if (loading) return <Loader2 className=\"size-3.5 animate-spin\" />;\n if (error) return <CircleAlert className=\"text-destructive size-3.5\" />;\n return <Icon className=\"size-4\" />;\n}\n\nexport function OpenActionMenu({\n actions,\n repositoryPath,\n worktreePath,\n showSpecs,\n}: OpenActionMenuProps) {\n const [copied, setCopied] = useState(false);\n\n const handleCopyPath = () => {\n void navigator.clipboard.writeText(worktreePath ?? repositoryPath);\n setCopied(true);\n setTimeout(() => setCopied(false), COPY_FEEDBACK_DELAY);\n };\n\n return (\n <TooltipProvider delayDuration={300}>\n <div className=\"flex items-center\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className={tbBtn}\n onClick={actions.openInIde}\n disabled={actions.ideLoading}\n aria-label=\"Open in IDE\"\n >\n <TbIcon loading={actions.ideLoading} error={actions.ideError} icon={Code2} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n Open in IDE\n </TooltipContent>\n </Tooltip>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className={tbBtn}\n onClick={actions.openInShell}\n disabled={actions.shellLoading}\n aria-label=\"Open terminal\"\n >\n <TbIcon loading={actions.shellLoading} error={actions.shellError} icon={Terminal} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n Open terminal\n </TooltipContent>\n </Tooltip>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className={tbBtn}\n onClick={actions.openFolder}\n disabled={actions.folderLoading}\n aria-label=\"Open folder\"\n >\n <TbIcon\n loading={actions.folderLoading}\n error={actions.folderError}\n icon={FolderOpen}\n />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n Open folder\n </TooltipContent>\n </Tooltip>\n\n {showSpecs ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className={tbBtn}\n onClick={actions.openSpecsFolder}\n disabled={actions.specsLoading}\n aria-label=\"Open specs\"\n >\n <TbIcon loading={actions.specsLoading} error={actions.specsError} icon={FileText} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n Open specs\n </TooltipContent>\n </Tooltip>\n ) : null}\n\n <Tooltip>\n <TooltipTrigger asChild>\n <button type=\"button\" className={tbBtn} onClick={handleCopyPath} aria-label=\"Copy path\">\n {copied ? <Check className=\"size-3.5 text-green-500\" /> : <Copy className=\"size-4\" />}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n {copied ? 'Copied!' : 'Copy path'}\n </TooltipContent>\n </Tooltip>\n </div>\n </TooltipProvider>\n );\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"40d248dbf2987d763c031a25d60f2cad747b932bda\":{\"name\":\"getFeaturePhaseTimings\"}},\"src/presentation/web/app/actions/get-feature-phase-timings.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"40d248dbf2987d763c031a25d60f2cad747b932bda\",callServer,void 0,findSourceMapURL,\"getFeaturePhaseTimings\");export{$$RSC_SERVER_ACTION_0 as getFeaturePhaseTimings};","/* __next_internal_action_entry_do_not_use__ [{\"40f95c929d80189e73a32d01f46570c79b3350622f\":{\"name\":\"getFeaturePlan\"}},\"src/presentation/web/app/actions/get-feature-plan.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"40f95c929d80189e73a32d01f46570c79b3350622f\",callServer,void 0,findSourceMapURL,\"getFeaturePlan\");export{$$RSC_SERVER_ACTION_0 as getFeaturePlan};","'use client';\n\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { PaperclipIcon, Send, ChevronLeft, Check, AlertTriangle } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { Textarea } from '@/components/ui/textarea';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\nimport { useSoundAction } from '@/hooks/use-sound-action';\nimport { AttachmentChip } from '@/components/common/attachment-chip';\nimport { pickFiles } from '@/components/common/feature-create-drawer/pick-files';\nimport type { DrawerActionBarProps, RejectAttachment } from './drawer-action-bar-config';\n\nconst MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB\n\nconst ALLOWED_EXTENSIONS = new Set([\n '.png',\n '.jpg',\n '.jpeg',\n '.gif',\n '.webp',\n '.svg',\n '.bmp',\n '.ico',\n '.pdf',\n '.doc',\n '.docx',\n '.xls',\n '.xlsx',\n '.ppt',\n '.pptx',\n '.txt',\n '.md',\n '.csv',\n '.json',\n '.yaml',\n '.yml',\n '.xml',\n '.ts',\n '.tsx',\n '.js',\n '.jsx',\n '.py',\n '.rb',\n '.go',\n '.rs',\n '.java',\n '.c',\n '.cpp',\n '.h',\n '.hpp',\n '.cs',\n '.swift',\n '.kt',\n '.html',\n '.css',\n '.scss',\n '.less',\n '.sh',\n '.bash',\n '.zsh',\n '.fish',\n '.toml',\n '.ini',\n '.cfg',\n '.conf',\n '.env',\n '.zip',\n '.tar',\n '.gz',\n '.log',\n]);\n\nfunction getExtension(filename: string): string {\n const dot = filename.lastIndexOf('.');\n return dot >= 0 ? filename.slice(dot).toLowerCase() : '';\n}\n\nexport function DrawerActionBar({\n onReject,\n onApprove,\n approveLabel,\n approveVariant = 'default',\n revisionPlaceholder,\n isProcessing = false,\n isRejecting = false,\n children,\n chatInput: controlledChatInput,\n onChatInputChange,\n}: DrawerActionBarProps) {\n const { t } = useTranslation('web');\n const isWarning = approveVariant === 'warning';\n const ApproveIcon = isWarning ? AlertTriangle : Check;\n const accentBg = isWarning ? 'bg-orange-500/85' : 'bg-blue-500/85';\n const accentBorder = isWarning ? 'border-orange-400/60' : 'border-blue-400/60';\n const [internalChatInput, setInternalChatInput] = useState('');\n const chatInput = controlledChatInput ?? internalChatInput;\n const setChatInput = onChatInputChange ?? setInternalChatInput;\n const approveSound = useSoundAction('approve');\n const disabled = isProcessing || isRejecting;\n\n const [attachments, setAttachments] = useState<RejectAttachment[]>([]);\n const [isDragOver, setIsDragOver] = useState(false);\n const [uploadError, setUploadError] = useState<string | null>(null);\n const [hoverExpanded, setHoverExpanded] = useState(false);\n const [ctrlHeld, setCtrlHeld] = useState(false);\n const [shiftHeld, setShiftHeld] = useState(false);\n const hasText = chatInput.trim().length > 0;\n const approveExpanded = hasText ? hoverExpanded || (ctrlHeld && shiftHeld) : !hoverExpanded;\n const rejectHighlighted = hasText ? ctrlHeld && !shiftHeld : false;\n const dragCounterRef = useRef(0);\n const sessionIdRef = useRef(crypto.randomUUID());\n const formRef = useRef<HTMLFormElement>(null);\n\n // Track Ctrl/Meta + Shift keys for button state\n useEffect(() => {\n function onKeyDown(e: KeyboardEvent) {\n if (e.key === 'Control' || e.key === 'Meta') setCtrlHeld(true);\n if (e.key === 'Shift') setShiftHeld(true);\n }\n function onKeyUp(e: KeyboardEvent) {\n if (e.key === 'Control' || e.key === 'Meta') setCtrlHeld(false);\n if (e.key === 'Shift') setShiftHeld(false);\n }\n function onBlur() {\n setCtrlHeld(false);\n setShiftHeld(false);\n }\n window.addEventListener('keydown', onKeyDown);\n window.addEventListener('keyup', onKeyUp);\n window.addEventListener('blur', onBlur);\n return () => {\n window.removeEventListener('keydown', onKeyDown);\n window.removeEventListener('keyup', onKeyUp);\n window.removeEventListener('blur', onBlur);\n };\n }, []);\n\n const handleFiles = useCallback(async (fileList: File[]) => {\n setUploadError(null);\n\n for (const file of fileList) {\n if (file.size > MAX_FILE_SIZE) {\n setUploadError(`\"${file.name}\" exceeds 10 MB limit`);\n return;\n }\n const ext = getExtension(file.name);\n if (ext && !ALLOWED_EXTENSIONS.has(ext)) {\n setUploadError(`File type \"${ext}\" is not allowed`);\n return;\n }\n }\n\n for (const file of fileList) {\n const tempId = crypto.randomUUID();\n\n setAttachments((prev) => [\n ...prev,\n {\n id: tempId,\n name: file.name,\n size: file.size,\n mimeType: file.type || 'application/octet-stream',\n path: '',\n loading: true,\n },\n ]);\n\n try {\n const formData = new FormData();\n formData.append('file', file);\n formData.append('sessionId', sessionIdRef.current);\n\n const res = await fetch('/api/attachments/upload', {\n method: 'POST',\n body: formData,\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: 'Upload failed' }));\n setAttachments((prev) => prev.filter((a) => a.id !== tempId));\n setUploadError(body.error ?? 'Upload failed');\n return;\n }\n\n const uploaded = await res.json();\n setAttachments((prev) => {\n const isDupe = prev.some((a) => a.id !== tempId && a.path === uploaded.path);\n if (isDupe) return prev.filter((a) => a.id !== tempId);\n return prev.map((a) =>\n a.id === tempId ? { ...uploaded, id: tempId, loading: false } : a\n );\n });\n } catch {\n setAttachments((prev) => prev.filter((a) => a.id !== tempId));\n setUploadError('Upload failed');\n }\n }\n }, []);\n\n const handleDragEnter = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounterRef.current += 1;\n if (dragCounterRef.current === 1) setIsDragOver(true);\n }, []);\n\n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounterRef.current -= 1;\n if (dragCounterRef.current === 0) setIsDragOver(false);\n }, []);\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }, []);\n\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounterRef.current = 0;\n setIsDragOver(false);\n const files = Array.from(e.dataTransfer.files);\n if (files.length > 0) handleFiles(files);\n },\n [handleFiles]\n );\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent) => {\n const items = e.clipboardData?.items;\n if (!items) return;\n const files: File[] = [];\n for (const item of Array.from(items)) {\n if (item.kind === 'file') {\n const file = item.getAsFile();\n if (file) files.push(file);\n }\n }\n if (files.length > 0) {\n e.preventDefault();\n handleFiles(files);\n }\n },\n [handleFiles]\n );\n\n const handleAddFiles = useCallback(async () => {\n try {\n const files = await pickFiles();\n if (files) {\n setAttachments((prev) => {\n const existingPaths = new Set(prev.map((f) => f.path));\n const unique = files\n .filter((f) => !existingPaths.has(f.path))\n .map(\n (f): RejectAttachment => ({\n id: crypto.randomUUID(),\n name: f.name,\n size: f.size,\n mimeType: 'application/octet-stream',\n path: f.path,\n })\n );\n return unique.length > 0 ? [...prev, ...unique] : prev;\n });\n }\n } catch {\n // Native dialog failed — silently ignore\n }\n }, []);\n\n const handleRemoveFile = useCallback((id: string) => {\n setAttachments((prev) => prev.filter((f) => f.id !== id));\n }, []);\n\n const handleNotesChange = useCallback((id: string, notes: string) => {\n setAttachments((prev) => prev.map((f) => (f.id === id ? { ...f, notes } : f)));\n }, []);\n\n const clearForm = useCallback(() => {\n setChatInput('');\n setAttachments([]);\n setUploadError(null);\n }, [setChatInput]);\n\n function handleFormSubmit(e: { preventDefault: () => void }) {\n e.preventDefault();\n const text = chatInput.trim();\n\n if (approveExpanded) {\n // Approve mode\n approveSound.play();\n onApprove();\n clearForm();\n } else {\n // Reject mode — text required\n if (!text || !onReject) return;\n onReject(\n text,\n attachments.filter((a) => !a.loading)\n );\n clearForm();\n }\n }\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {\n e.preventDefault();\n // Ctrl+Shift+Enter = approve, Ctrl+Enter = reject\n formRef.current?.requestSubmit();\n }\n }, []);\n\n const modKey =\n typeof navigator !== 'undefined' && /Mac/i.test(navigator.userAgent) ? '⌘' : 'Ctrl';\n\n return (\n <div className=\"border-border shrink-0 border-t\">\n {children}\n {onReject ? (\n <TooltipProvider delayDuration={400}>\n <form ref={formRef} onSubmit={handleFormSubmit} className=\"p-3\">\n <div\n role=\"region\"\n aria-label={t('createDrawer.fileDropZone')}\n data-drag-over={isDragOver ? 'true' : 'false'}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n className={cn(\n 'rounded-md border-2 border-transparent transition-colors',\n isDragOver && 'border-primary/50 bg-primary/5'\n )}\n >\n <div className=\"border-input focus-within:ring-ring/50 focus-within:border-ring flex flex-col overflow-hidden rounded-md border shadow-xs transition-[color,box-shadow] focus-within:ring-[3px]\">\n <Textarea\n placeholder={revisionPlaceholder ?? 'Ask AI to revise...'}\n aria-label={revisionPlaceholder ?? 'Ask AI to revise...'}\n disabled={disabled}\n value={chatInput}\n onChange={(e) => setChatInput(e.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n rows={1}\n aria-invalid={!!uploadError}\n aria-describedby={uploadError ? 'drawer-action-upload-error' : undefined}\n className=\"max-h-[35dvh] min-h-9 flex-1 resize-none overflow-y-auto rounded-none border-0 py-2 shadow-none focus-visible:ring-0\"\n data-testid=\"drawer-chat-input\"\n />\n {attachments.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-1.5 px-3 py-2\">\n {attachments.map((file) => (\n <AttachmentChip\n key={file.id}\n name={file.name}\n size={file.size}\n mimeType={file.mimeType}\n path={file.path}\n onRemove={() => handleRemoveFile(file.id)}\n disabled={disabled}\n loading={file.loading}\n notes={file.notes}\n onNotesChange={(notes) => handleNotesChange(file.id, notes)}\n />\n ))}\n </div>\n )}\n {uploadError ? (\n <p\n id=\"drawer-action-upload-error\"\n className=\"text-destructive px-3 pb-2 text-xs\"\n role=\"alert\"\n >\n {uploadError}\n </p>\n ) : null}\n <div className=\"border-input flex items-center gap-2 border-t px-3 py-1.5\">\n <span className=\"text-muted-foreground flex-1 truncate text-[11px]\">\n <kbd className=\"bg-muted rounded px-1 py-0.5 font-mono text-[10px]\">\n {modKey}+Enter\n </kbd>{' '}\n {hasText ? 'reject' : 'approve'}\n </span>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={handleAddFiles}\n disabled={disabled}\n aria-label={t('chat.attachFiles')}\n className=\"text-muted-foreground hover:text-foreground cursor-pointer rounded p-1 transition-colors\"\n >\n <PaperclipIcon className=\"h-4 w-4\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\">{t('chat.attachFiles')}</TooltipContent>\n </Tooltip>\n\n {/* Single action button: Approve when empty, Reject when text present */}\n <div onMouseLeave={() => setHoverExpanded(false)}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"submit\"\n disabled={disabled}\n data-testid=\"drawer-action-submit\"\n className={cn(\n 'relative flex h-9 min-w-[12rem] cursor-pointer items-center overflow-hidden rounded-md border ps-4 pe-10 text-sm font-medium whitespace-nowrap transition-colors',\n 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n approveExpanded\n ? `${accentBorder} text-white`\n : rejectHighlighted\n ? 'border-primary bg-muted ring-primary/30 shadow-sm ring-1'\n : 'border-border bg-muted/50 hover:bg-muted shadow-sm'\n )}\n >\n {/* Accent fill — slides in from right */}\n <div\n className={cn(\n 'pointer-events-none absolute inset-0 transition-transform duration-300 ease-in-out',\n accentBg\n )}\n style={{\n transform: approveExpanded ? 'translateX(0)' : 'translateX(100%)',\n }}\n />\n {/* Reject content */}\n <span\n className={cn(\n 'absolute inset-0 z-10 flex items-center justify-center gap-2 pe-8 transition-opacity duration-300',\n approveExpanded ? 'opacity-0' : 'opacity-100'\n )}\n >\n <Send className=\"h-4 w-4 shrink-0\" />\n Reject\n </span>\n {/* Approve content — overlaid, centered */}\n <span\n className={cn(\n 'absolute inset-0 z-10 flex items-center justify-center gap-2 text-white transition-opacity duration-300',\n approveExpanded ? 'opacity-100' : 'opacity-0'\n )}\n >\n <ApproveIcon className=\"h-4 w-4 shrink-0\" />\n {approveLabel}\n </span>\n {/* Arrow indicator — hover trigger to toggle between modes */}\n <span\n className={cn(\n `border-input/60 absolute inset-y-0 right-0 z-20 flex w-8 cursor-pointer items-center justify-center rounded-e-[5px] border-s ${accentBg} transition-opacity duration-300`,\n !hasText && !hoverExpanded && 'pointer-events-none opacity-0'\n )}\n onMouseEnter={() => setHoverExpanded(true)}\n >\n <ChevronLeft className=\"h-4 w-4 text-white\" />\n </span>\n </button>\n </TooltipTrigger>\n {!isWarning ? (\n <TooltipContent side=\"top\">\n {approveExpanded\n ? approveLabel\n : t('drawerActionBar.sendRevisionFeedback')}\n </TooltipContent>\n ) : null}\n </Tooltip>\n </div>\n </div>\n </div>\n </div>\n </form>\n </TooltipProvider>\n ) : (\n <div className=\"flex items-center gap-2 px-4 pb-4\">\n <Button\n type=\"button\"\n className=\"flex-1\"\n disabled={disabled}\n onClick={() => {\n approveSound.play();\n onApprove();\n }}\n >\n {approveLabel}\n </Button>\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { useCallback, useMemo, useState } from 'react';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { Badge } from '@/components/ui/badge';\nimport { DrawerActionBar } from '@/components/common/drawer-action-bar';\nimport { useSoundAction } from '@/hooks/use-sound-action';\nimport type { PrdQuestionnaireProps } from './prd-questionnaire-config';\n\nexport function PrdQuestionnaire({\n data,\n selections,\n onSelect,\n onApprove,\n onReject,\n isProcessing = false,\n isRejecting = false,\n showHeader = false,\n chatInput,\n onChatInputChange,\n}: PrdQuestionnaireProps) {\n const { question, context, questions, finalAction } = data;\n const [currentStep, setCurrentStep] = useState(0);\n const selectSound = useSoundAction('select');\n const navigateSound = useSoundAction('navigate');\n\n const total = questions.length;\n const isFirstStep = currentStep === 0;\n const isLastStep = currentStep === total - 1;\n const currentQuestion = questions[currentStep];\n\n const answeredCount = useMemo(() => Object.keys(selections).length, [selections]);\n\n const handleSelect = useCallback(\n (questionId: string, optionId: string) => {\n selectSound.play();\n onSelect(questionId, optionId);\n // Auto-advance to the next step after selection (unless last step)\n if (!isLastStep) {\n setTimeout(() => setCurrentStep((s) => s + 1), 250);\n }\n },\n [onSelect, isLastStep, selectSound]\n );\n\n if (total === 0) return null;\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"flex-1 space-y-4 overflow-y-auto p-4\">\n {/* Header */}\n {showHeader ? (\n <div className=\"border-border flex items-start gap-3 border-b pb-3\">\n <div className=\"mt-1.5 h-2 w-2 shrink-0 rounded-full bg-amber-500\" />\n <div className=\"flex-1\">\n <h3 className=\"text-foreground mb-1.5 text-sm font-bold\">{question}</h3>\n <p className=\"text-muted-foreground text-xs leading-relaxed\">{context}</p>\n </div>\n </div>\n ) : null}\n\n {/* Question + step indicator */}\n <div className=\"space-y-3\">\n <div className=\"flex items-start gap-3\">\n <label className=\"text-foreground min-w-0 flex-1 text-sm font-semibold\">\n {currentStep + 1}. {currentQuestion.question}\n </label>\n <div className=\"mt-1.5 flex shrink-0 gap-1\">\n {questions.map((q, idx) => (\n <button\n key={q.id}\n type=\"button\"\n aria-label={`Go to question ${idx + 1}`}\n className={cn(\n 'h-1.5 rounded-full transition-all duration-200',\n idx === currentStep ? 'bg-primary w-4' : 'w-1.5',\n idx !== currentStep && selections[q.id] ? 'bg-primary/50' : '',\n idx !== currentStep && !selections[q.id] ? 'bg-muted-foreground/25' : ''\n )}\n onClick={() => {\n navigateSound.play();\n setCurrentStep(idx);\n }}\n />\n ))}\n </div>\n </div>\n <div className=\"space-y-2\">\n {currentQuestion.options.map((opt, optIdx) => {\n const selected = selections[currentQuestion.id] === opt.id;\n const letter = String.fromCharCode(65 + optIdx);\n return (\n <button\n key={opt.id}\n type=\"button\"\n className={cn(\n 'border-border w-full overflow-hidden rounded-md border px-3 py-3 text-start text-xs transition-all',\n 'hover:border-primary/70 hover:bg-primary/5 group',\n selected && 'border-primary bg-primary/5',\n opt.isNew && 'animate-option-highlight'\n )}\n disabled={isProcessing}\n onClick={() => handleSelect(currentQuestion.id, opt.id)}\n >\n <div className=\"flex items-start gap-2\">\n <span className=\"text-muted-foreground mt-0.5 font-mono text-xs\">\n {letter}.\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-foreground mb-0.5 text-xs font-semibold wrap-break-word\">\n {opt.label}\n </div>\n <div className=\"text-muted-foreground text-xs leading-snug\">\n {opt.rationale}\n </div>\n </div>\n {opt.recommended || opt.isNew ? (\n <div className=\"shrink-0 pt-0.5\">\n {opt.recommended ? (\n <Badge className=\"px-1.5 py-0 text-[10px] whitespace-nowrap\">\n AI Recommended\n </Badge>\n ) : (\n <Badge className=\"border-transparent bg-emerald-600 px-1.5 py-0 text-[10px] whitespace-nowrap text-white hover:bg-emerald-600/80\">\n New\n </Badge>\n )}\n </div>\n ) : null}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Step navigation */}\n <div className=\"flex items-center justify-between pt-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={isFirstStep || isProcessing}\n onClick={() => {\n navigateSound.play();\n setCurrentStep((s) => s - 1);\n }}\n >\n <ChevronLeft className=\"me-1 h-4 w-4\" />\n Previous\n </Button>\n\n {!isLastStep ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={isProcessing}\n onClick={() => {\n navigateSound.play();\n setCurrentStep((s) => s + 1);\n }}\n >\n {selections[currentQuestion.id] ? 'Next' : 'Skip'}\n <ChevronRight className=\"ms-1 h-4 w-4\" />\n </Button>\n ) : null}\n </div>\n </div>\n\n <DrawerActionBar\n onReject={onReject}\n onApprove={() => onApprove(finalAction.id)}\n approveLabel={finalAction.label}\n revisionPlaceholder=\"Ask AI to refine requirements...\"\n isProcessing={isProcessing}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={onChatInputChange}\n >\n <div\n className={cn(\n 'bg-muted h-1.5 overflow-hidden',\n (answeredCount > 0 && answeredCount < total) || isProcessing\n ? 'opacity-100'\n : 'opacity-0',\n 'transition-opacity duration-200'\n )}\n data-testid=\"progress-bar-container\"\n >\n {isProcessing ? (\n <div className=\"bg-primary animate-indeterminate-progress h-full w-1/3\" />\n ) : (\n <div\n className=\"bg-primary h-full transition-all duration-300\"\n style={{ width: `${total > 0 ? (answeredCount / total) * 100 : 0}%` }}\n data-testid=\"progress-bar\"\n />\n )}\n </div>\n </DrawerActionBar>\n </div>\n );\n}\n","'use client';\n\nimport { useState } from 'react';\nimport type { Components } from 'react-markdown';\nimport Markdown from 'react-markdown';\nimport { ChevronRight, GitCompareArrows, Layers } from 'lucide-react';\nimport { Badge } from '@/components/ui/badge';\nimport { DrawerActionBar } from '@/components/common/drawer-action-bar';\nimport { useSoundAction } from '@/hooks/use-sound-action';\nimport type {\n TechDecisionsReviewProps,\n TechDecisionsReviewData,\n TechDecision,\n} from './tech-decisions-review-config';\n\nconst markdownComponents: Components = {\n p: ({ children }) => (\n <p className=\"text-muted-foreground mb-2 text-xs leading-relaxed last:mb-0\">{children}</p>\n ),\n strong: ({ children }) => <strong className=\"text-foreground font-semibold\">{children}</strong>,\n em: ({ children }) => <em className=\"italic\">{children}</em>,\n code: ({ children, className }) =>\n className ? (\n <code className={`${className} text-[11px]`}>{children}</code>\n ) : (\n <code className=\"bg-muted text-foreground rounded-md px-1.5 py-0.5 font-mono text-[11px]\">\n {children}\n </code>\n ),\n pre: ({ children }) => (\n <pre className=\"bg-muted my-2 overflow-x-auto rounded-lg border p-3\">{children}</pre>\n ),\n ul: ({ children }) => (\n <ul className=\"text-muted-foreground mb-2 list-disc space-y-1 ps-4 text-xs\">{children}</ul>\n ),\n ol: ({ children }) => (\n <ol className=\"text-muted-foreground mb-2 list-decimal space-y-1 ps-4 text-xs\">{children}</ol>\n ),\n li: ({ children }) => <li className=\"leading-relaxed\">{children}</li>,\n a: ({ children, href }) => (\n <a\n href={href}\n className=\"text-primary underline underline-offset-2\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {children}\n </a>\n ),\n};\n\nfunction DecisionCard({ decision, index }: { decision: TechDecision; index: number }) {\n const [alternativesOpen, setAlternativesOpen] = useState(false);\n const expandSound = useSoundAction('expand');\n const collapseSound = useSoundAction('collapse');\n\n const handleToggleAlternatives = () => {\n // Play sound based on current state (before toggle)\n if (alternativesOpen) {\n collapseSound.play();\n } else {\n expandSound.play();\n }\n setAlternativesOpen((prev) => !prev);\n };\n\n return (\n <div className=\"border-border rounded-lg border\">\n {/* Header: number + title + chosen badge */}\n <div className=\"space-y-3 px-4 py-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-2.5\">\n <span className=\"bg-primary text-primary-foreground flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-xs font-bold\">\n {index + 1}\n </span>\n <div className=\"min-w-0\">\n <h3 className=\"text-foreground text-sm leading-tight font-semibold\">\n {decision.title}\n </h3>\n <p className=\"text-muted-foreground mt-0.5 text-xs\">{decision.chosen}</p>\n </div>\n </div>\n {'decisionName' in decision &&\n (decision as unknown as { decisionName?: string }).decisionName ? (\n <Badge variant=\"secondary\" className=\"bg-primary/10 text-primary shrink-0\">\n {(decision as unknown as { decisionName: string }).decisionName}\n </Badge>\n ) : null}\n </div>\n\n {/* Rationale */}\n {decision.rationale ? (\n <Markdown components={markdownComponents}>{decision.rationale}</Markdown>\n ) : null}\n </div>\n\n {/* Rejected alternatives (collapsed by default) */}\n {decision.rejected.length > 0 ? (\n <div className=\"border-border border-t\">\n <button\n type=\"button\"\n onClick={handleToggleAlternatives}\n className=\"text-muted-foreground hover:bg-muted/50 flex w-full items-center gap-1.5 px-4 py-3 text-xs font-medium transition-colors\"\n >\n <ChevronRight\n className={`h-3.5 w-3.5 transition-transform ${alternativesOpen ? 'rotate-90' : ''}`}\n />\n <Layers className=\"h-3.5 w-3.5\" />\n Other Options Considered ({decision.rejected.length})\n </button>\n {alternativesOpen ? (\n <div className=\"space-y-1.5 px-4 pb-3\">\n {decision.rejected.map((alt) => (\n <div key={alt} className=\"bg-primary/5 rounded-md px-3 py-2\">\n <span className=\"text-foreground text-xs\">{alt}</span>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\n/**\n * Renders the tech decisions content (header + decision cards) without the action bar.\n * Used by TechReviewTabs to compose with a shared DrawerActionBar.\n */\nexport function TechDecisionsContent({ data }: { data: TechDecisionsReviewData }) {\n const { summary, decisions } = data;\n\n if (decisions.length === 0) return null;\n\n return (\n <div className=\"space-y-4 p-4\">\n {/* Header */}\n <div className=\"flex items-start gap-3\">\n <div className=\"mt-1.5 h-2.5 w-2.5 shrink-0 rounded-full bg-blue-500\" />\n <div className=\"flex-1\">\n <h2 className=\"text-foreground text-sm font-bold\">\n Technical Implementation Plan Review\n </h2>\n {summary ? (\n <p className=\"text-muted-foreground mt-1 text-xs leading-relaxed\">{summary}</p>\n ) : null}\n </div>\n </div>\n\n {/* Section heading */}\n <div className=\"flex items-center gap-2 pt-1\">\n <GitCompareArrows className=\"text-primary h-4 w-4\" />\n <h3 className=\"text-foreground text-sm font-bold\">Technical Decisions</h3>\n </div>\n\n {/* Decision cards */}\n {decisions.map((decision, i) => (\n <DecisionCard key={decision.title} decision={decision} index={i} />\n ))}\n </div>\n );\n}\n\nexport function TechDecisionsReview({\n data,\n onApprove,\n onReject,\n isProcessing = false,\n isRejecting = false,\n}: TechDecisionsReviewProps) {\n if (data.decisions.length === 0) return null;\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"flex-1 overflow-y-auto\">\n <TechDecisionsContent data={data} />\n </div>\n\n <DrawerActionBar\n onReject={onReject}\n onApprove={onApprove}\n approveLabel=\"Approve Plan\"\n revisionPlaceholder=\"Ask AI to revise the plan...\"\n isProcessing={isProcessing}\n isRejecting={isRejecting}\n />\n </div>\n );\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"600238001c3e908fa4de18aa2ef024d6bec82cc7d4\":{\"name\":\"approveFeature\"}},\"src/presentation/web/app/actions/approve-feature.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"600238001c3e908fa4de18aa2ef024d6bec82cc7d4\",callServer,void 0,findSourceMapURL,\"approveFeature\");export{$$RSC_SERVER_ACTION_0 as approveFeature};","'use client';\n\nimport { useState } from 'react';\nimport { ChevronRight, FileText, FilePlus, FileMinus, FileEdit } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport type { MergeReviewFileDiff, MergeReviewDiffHunk } from './merge-review-config';\n\nconst STATUS_CONFIG = {\n added: { icon: FilePlus, label: 'A', className: 'text-green-600' },\n modified: { icon: FileEdit, label: 'M', className: 'text-amber-600' },\n deleted: { icon: FileMinus, label: 'D', className: 'text-red-600' },\n renamed: { icon: FileEdit, label: 'R', className: 'text-blue-600' },\n} as const;\n\nfunction FileStatusIcon({ status }: { status: MergeReviewFileDiff['status'] }) {\n const config = STATUS_CONFIG[status];\n const Icon = config.icon;\n return <Icon className={cn('h-3.5 w-3.5 shrink-0', config.className)} />;\n}\n\nfunction HunkView({ hunk }: { hunk: MergeReviewDiffHunk }) {\n return (\n <div className=\"border-border border-t first:border-t-0\">\n <div className=\"bg-muted/50 text-muted-foreground px-3 py-1 font-mono text-[10px]\">\n {hunk.header}\n </div>\n <div className=\"font-mono text-[11px] leading-[18px]\">\n {hunk.lines.map((line) => (\n <div\n key={`${line.type}-${line.oldNumber ?? ''}-${line.newNumber ?? ''}`}\n className={cn(\n 'flex',\n line.type === 'added' && 'bg-green-50 dark:bg-green-950/30',\n line.type === 'removed' && 'bg-red-50 dark:bg-red-950/30'\n )}\n >\n <span className=\"text-muted-foreground w-10 shrink-0 px-1 text-end text-[10px] select-none\">\n {line.oldNumber ?? ''}\n </span>\n <span className=\"text-muted-foreground w-10 shrink-0 px-1 text-end text-[10px] select-none\">\n {line.newNumber ?? ''}\n </span>\n <span\n className={cn(\n 'w-4 shrink-0 text-center select-none',\n line.type === 'added' && 'text-green-700 dark:text-green-400',\n line.type === 'removed' && 'text-red-700 dark:text-red-400'\n )}\n >\n {line.type === 'added' ? '+' : line.type === 'removed' ? '-' : ' '}\n </span>\n <span className=\"min-w-0 flex-1 pe-2 break-all whitespace-pre-wrap\">\n {line.content}\n </span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nfunction FileDiffItem({ file }: { file: MergeReviewFileDiff }) {\n const [isOpen, setIsOpen] = useState(false);\n\n const fileName = file.path.split('/').pop() ?? file.path;\n const dirPath = file.path.includes('/') ? file.path.slice(0, file.path.lastIndexOf('/')) : '';\n\n return (\n <div className=\"border-border border-b last:border-b-0\">\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n className=\"hover:bg-muted/50 flex w-full items-center gap-2 px-3 py-2 text-start\"\n >\n <ChevronRight\n className={cn(\n 'text-muted-foreground h-3 w-3 shrink-0 transition-transform duration-150',\n isOpen && 'rotate-90'\n )}\n />\n <FileStatusIcon status={file.status} />\n <span className=\"text-foreground min-w-0 flex-1 truncate text-xs\">\n {dirPath ? (\n <>\n <span className=\"text-muted-foreground\">{dirPath}/</span>\n {fileName}\n </>\n ) : (\n fileName\n )}\n </span>\n {file.oldPath ? (\n <span className=\"text-muted-foreground truncate text-[10px]\">\n ← {file.oldPath.split('/').pop()}\n </span>\n ) : null}\n <span className=\"shrink-0 text-[10px]\">\n {file.additions > 0 ? <span className=\"text-green-600\">+{file.additions}</span> : null}\n {file.additions > 0 && file.deletions > 0 ? ' ' : null}\n {file.deletions > 0 ? <span className=\"text-red-600\">-{file.deletions}</span> : null}\n </span>\n </button>\n {isOpen && file.hunks.length > 0 ? (\n <div className=\"border-border overflow-x-auto border-t\">\n {file.hunks.map((hunk) => (\n <HunkView key={hunk.header} hunk={hunk} />\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport interface DiffViewProps {\n fileDiffs: MergeReviewFileDiff[];\n}\n\nexport function DiffView({ fileDiffs }: DiffViewProps) {\n if (fileDiffs.length === 0) return null;\n\n return (\n <div className=\"border-border rounded-lg border\">\n <div className=\"px-4 py-3\">\n <div className=\"mb-2 flex items-center gap-2\">\n <FileText className=\"text-muted-foreground h-4 w-4\" />\n <span className=\"text-foreground text-xs font-semibold\">Changed Files</span>\n <span className=\"text-muted-foreground text-[10px]\">({fileDiffs.length})</span>\n </div>\n </div>\n <div className=\"border-border border-t\">\n {fileDiffs.map((file) => (\n <FileDiffItem key={`${file.status}-${file.path}`} file={file} />\n ))}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useState } from 'react';\nimport {\n ExternalLink,\n AlertTriangle,\n FileDiff,\n GitCommitHorizontal,\n GitBranch,\n ArrowRight,\n Camera,\n FileText,\n MonitorPlay,\n Terminal,\n Download,\n ChevronDown,\n ChevronRight,\n} from 'lucide-react';\nimport { Badge } from '@/components/ui/badge';\nimport { CiStatusBadge } from '@/components/common/ci-status-badge';\nimport { DrawerActionBar } from '@/components/common/drawer-action-bar';\nimport { DiffView } from './diff-view';\nimport type { MergeReviewProps, MergeReviewEvidence } from './merge-review-config';\n\nconst EVIDENCE_ICONS: Record<MergeReviewEvidence['type'], typeof Camera> = {\n Screenshot: Camera,\n Video: MonitorPlay,\n TestOutput: FileText,\n TerminalRecording: Terminal,\n};\n\nconst IMAGE_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.bmp']);\nconst VIDEO_EXTENSIONS = new Set(['.mp4', '.webm', '.mov']);\n\nfunction getExtension(path: string): string {\n const dot = path.lastIndexOf('.');\n return dot >= 0 ? path.slice(dot).toLowerCase() : '';\n}\n\n/** Build the API URL for serving an evidence file (paths are pre-normalized to absolute). */\nfunction buildEvidenceUrl(absolutePath: string): string {\n return `/api/evidence?path=${encodeURIComponent(absolutePath)}`;\n}\n\nfunction EvidenceItem({ evidence }: { evidence: MergeReviewEvidence }) {\n const [expanded, setExpanded] = useState(true);\n const Icon = EVIDENCE_ICONS[evidence.type] ?? Camera;\n const ext = getExtension(evidence.relativePath);\n const url = buildEvidenceUrl(evidence.relativePath);\n const isImage = evidence.type === 'Screenshot' || IMAGE_EXTENSIONS.has(ext);\n const isVideo = evidence.type === 'Video' || VIDEO_EXTENSIONS.has(ext);\n const isText = evidence.type === 'TestOutput' || evidence.type === 'TerminalRecording';\n\n return (\n <li className=\"border-border rounded-md border\">\n <button\n type=\"button\"\n onClick={() => setExpanded(!expanded)}\n className=\"flex w-full cursor-pointer items-center gap-2.5 px-3 py-2.5 text-start\"\n >\n {expanded ? (\n <ChevronDown className=\"text-muted-foreground h-3 w-3 shrink-0\" />\n ) : (\n <ChevronRight className=\"text-muted-foreground h-3 w-3 shrink-0\" />\n )}\n <Icon className=\"text-muted-foreground h-3.5 w-3.5 shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <span className=\"text-foreground text-xs font-medium\">{evidence.description}</span>\n {evidence.taskRef ? (\n <span className=\"text-muted-foreground ms-1.5 text-[10px]\">({evidence.taskRef})</span>\n ) : null}\n </div>\n {url ? (\n <a\n href={url}\n download\n onClick={(e) => e.stopPropagation()}\n className=\"text-muted-foreground hover:text-foreground shrink-0 rounded p-1 transition-colors\"\n aria-label=\"Download\"\n >\n <Download className=\"h-3 w-3\" />\n </a>\n ) : null}\n </button>\n {expanded && url ? (\n <div className=\"border-border border-t px-3 py-2.5\">\n {isImage ? (\n /* eslint-disable-next-line @next/next/no-img-element */\n <img\n src={url}\n alt={evidence.description}\n className=\"max-h-80 w-full rounded-md border object-contain\"\n loading=\"lazy\"\n />\n ) : isVideo ? (\n <video\n src={url}\n controls\n className=\"max-h-80 w-full rounded-md border\"\n preload=\"metadata\"\n >\n <track kind=\"captions\" />\n </video>\n ) : isText ? (\n <EvidenceTextPreview url={url} />\n ) : (\n <p className=\"text-muted-foreground truncate font-mono text-[10px]\">\n {evidence.relativePath}\n </p>\n )}\n </div>\n ) : null}\n {expanded && !url ? (\n <div className=\"border-border border-t px-3 py-2.5\">\n <p className=\"text-muted-foreground truncate font-mono text-[10px]\">\n {evidence.relativePath}\n </p>\n </div>\n ) : null}\n </li>\n );\n}\n\nfunction EvidenceTextPreview({ url }: { url: string }) {\n const [content, setContent] = useState<string | null>(null);\n const [loaded, setLoaded] = useState(false);\n\n if (!loaded) {\n fetch(url)\n .then((r) => (r.ok ? r.text() : Promise.reject(new Error('Failed'))))\n .then((text) => {\n // Limit to first 100 lines for preview\n const lines = text.split('\\n');\n setContent(lines.length > 100 ? `${lines.slice(0, 100).join('\\n')}\\n...` : text);\n })\n .catch(() => setContent(null))\n .finally(() => setLoaded(true));\n\n return <div className=\"bg-muted/50 h-16 animate-pulse rounded-md\" />;\n }\n\n if (!content) {\n return <p className=\"text-muted-foreground text-[10px]\">Unable to load preview</p>;\n }\n\n return (\n <pre className=\"bg-muted/50 max-h-60 overflow-auto rounded-md p-3 font-mono text-[11px] leading-relaxed\">\n {content}\n </pre>\n );\n}\n\nfunction EvidenceList({ evidence }: { evidence: MergeReviewEvidence[] }) {\n return (\n <div className=\"border-border rounded-lg border\">\n <div className=\"px-4 py-3\">\n <div className=\"mb-3 flex items-center gap-2\">\n <Camera className=\"text-muted-foreground h-4 w-4\" />\n <span className=\"text-foreground text-xs font-semibold\">Evidence</span>\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {evidence.length}\n </Badge>\n </div>\n <ul className=\"space-y-2\">\n {evidence.map((e) => (\n <EvidenceItem key={`${e.type}-${e.relativePath}`} evidence={e} />\n ))}\n </ul>\n </div>\n </div>\n );\n}\n\nexport function MergeReview({\n data,\n readOnly = false,\n onApprove,\n onReject,\n isProcessing = false,\n isRejecting = false,\n chatInput,\n onChatInputChange,\n}: MergeReviewProps) {\n const { pr, diffSummary, fileDiffs, branch, warning, evidence, hideCiStatus } = data;\n const hasConflicts = pr?.mergeable === false;\n\n const handleApproveOrResolve =\n hasConflicts && onReject ? () => onReject('Resolve merge conflicts', []) : onApprove;\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"flex-1 space-y-4 overflow-y-auto p-4\">\n {/* Header */}\n <div className=\"flex items-start gap-3\">\n <div className=\"mt-1.5 h-2.5 w-2.5 shrink-0 rounded-full bg-emerald-500\" />\n <div className=\"flex-1\">\n <h2 className=\"text-foreground text-sm font-bold\">\n {readOnly ? 'Merge History' : 'Merge Review'}\n </h2>\n <p className=\"text-muted-foreground mt-1 text-xs leading-relaxed\">\n {readOnly\n ? 'This feature was merged. Review the pull request details and evidence below.'\n : pr\n ? 'Review the pull request details and approve to merge.'\n : 'Review the changes and approve to merge.'}\n </p>\n </div>\n </div>\n\n {/* Branch merge direction (GitHub-like) */}\n {branch ? (\n <div className=\"border-border rounded-lg border\">\n <div className=\"flex items-center gap-2 px-4 py-3\">\n <GitBranch className=\"text-muted-foreground h-4 w-4 shrink-0\" />\n <Badge variant=\"secondary\" className=\"font-mono text-[11px]\">\n {branch.source}\n </Badge>\n <ArrowRight className=\"text-muted-foreground h-3.5 w-3.5 shrink-0\" />\n <Badge variant=\"outline\" className=\"font-mono text-[11px]\">\n {branch.target}\n </Badge>\n </div>\n </div>\n ) : null}\n\n {/* PR metadata card */}\n {pr ? (\n <div className=\"border-border rounded-lg border\">\n <div className=\"space-y-3 px-4 py-3\">\n {/* PR number + link */}\n <div className=\"flex items-center justify-between\">\n <a\n href={pr.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary flex items-center gap-1.5 text-sm font-semibold underline underline-offset-2\"\n >\n PR #{pr.number}\n <ExternalLink className=\"h-3.5 w-3.5\" />\n </a>\n <Badge variant=\"outline\" className=\"text-xs\">\n {pr.status}\n </Badge>\n </div>\n\n {/* Merge status */}\n {pr.mergeable === false ? (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-muted-foreground text-xs font-medium\">Merge Status</span>\n <Badge className=\"border-transparent bg-orange-50 text-orange-700 hover:bg-orange-50\">\n <AlertTriangle className=\"me-1 h-3.5 w-3.5\" />\n Conflicts\n </Badge>\n </div>\n ) : null}\n\n {/* CI status */}\n {pr.ciStatus && hideCiStatus !== true ? (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-muted-foreground text-xs font-medium\">CI Status</span>\n <CiStatusBadge status={pr.ciStatus} />\n </div>\n ) : null}\n\n {/* Commit hash */}\n {pr.commitHash ? (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-muted-foreground text-xs font-medium\">Commit</span>\n <div className=\"flex items-center gap-1.5\">\n <GitCommitHorizontal className=\"text-muted-foreground h-3.5 w-3.5\" />\n <code className=\"bg-muted text-foreground rounded-md px-1.5 py-0.5 font-mono text-[11px]\">\n {pr.commitHash.slice(0, 7)}\n </code>\n </div>\n </div>\n ) : null}\n </div>\n </div>\n ) : null}\n\n {/* Diff summary */}\n {diffSummary ? (\n <div className=\"border-border rounded-lg border\">\n <div className=\"px-4 py-3\">\n <div className=\"mb-3 flex items-center gap-2\">\n <FileDiff className=\"text-muted-foreground h-4 w-4\" />\n <span className=\"text-foreground text-xs font-semibold\">Changes</span>\n </div>\n <div className=\"grid grid-cols-4 gap-3\">\n <div className=\"text-center\">\n <div className=\"text-foreground text-sm font-bold\">\n {diffSummary.filesChanged}\n </div>\n <div className=\"text-muted-foreground text-[10px]\">files</div>\n </div>\n <div className=\"text-center\">\n <div className=\"text-sm font-bold text-green-600\">+{diffSummary.additions}</div>\n <div className=\"text-muted-foreground text-[10px]\">additions</div>\n </div>\n <div className=\"text-center\">\n <div className=\"text-sm font-bold text-red-600\">-{diffSummary.deletions}</div>\n <div className=\"text-muted-foreground text-[10px]\">deletions</div>\n </div>\n <div className=\"text-center\">\n <div className=\"text-foreground text-sm font-bold\">{diffSummary.commitCount}</div>\n <div className=\"text-muted-foreground text-[10px]\">commits</div>\n </div>\n </div>\n </div>\n </div>\n ) : warning ? (\n <div className=\"border-border rounded-lg border\">\n <div className=\"flex items-center gap-2 px-4 py-3\">\n <AlertTriangle className=\"text-muted-foreground h-4 w-4 shrink-0\" />\n <span className=\"text-muted-foreground text-xs\">{warning}</span>\n </div>\n </div>\n ) : null}\n\n {/* Evidence */}\n {evidence && evidence.length > 0 ? <EvidenceList evidence={evidence} /> : null}\n\n {/* File diffs */}\n {fileDiffs && fileDiffs.length > 0 ? <DiffView fileDiffs={fileDiffs} /> : null}\n </div>\n\n {!readOnly && (\n <DrawerActionBar\n onReject={onReject}\n onApprove={handleApproveOrResolve}\n approveLabel={hasConflicts ? 'Resolve Conflicts' : 'Approve Merge'}\n approveVariant={hasConflicts ? 'warning' : 'default'}\n revisionPlaceholder=\"Ask AI to revise before merging...\"\n isProcessing={isProcessing}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={onChatInputChange}\n />\n )}\n </div>\n );\n}\n","/* eslint-disable @next/next/no-img-element -- Local file preview requires raw <img>, not next/image */\n'use client';\n\nimport { useState } from 'react';\nimport { Dialog, DialogTrigger, DialogContent, DialogTitle } from '@/components/ui/dialog';\nimport { VisuallyHidden } from 'radix-ui';\nimport { DownloadIcon, ImageOff } from 'lucide-react';\n\nconst IMAGE_EXTS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico', '.bmp']);\n\nfunction isImagePath(path: string): boolean {\n const dot = path.lastIndexOf('.');\n return dot >= 0 && IMAGE_EXTS.has(path.slice(dot).toLowerCase());\n}\n\nfunction previewUrl(path: string): string {\n const ext = path.lastIndexOf('.') >= 0 ? path.slice(path.lastIndexOf('.')) : '';\n const mimeGuess = isImagePath(path) ? `image/${ext.slice(1).replace('jpg', 'jpeg')}` : '';\n const params = new URLSearchParams({ path, ...(mimeGuess && { mimeType: mimeGuess }) });\n return `/api/attachments/preview?${params.toString()}`;\n}\n\nfunction getFilename(path: string): string {\n return path.split('/').pop() ?? path;\n}\n\n/** Regex matching `@/absolute/path` attachment references in text. */\nconst ATTACHMENT_REF_RE = /(?:^|\\s)@(\\/[^\\s]+)/g;\n\nexport interface InlineAttachmentsProps {\n /** Text that may contain `@/path/to/file` attachment references. */\n text: string;\n /** Additional attachment paths to render (e.g. from rejection feedback). */\n attachmentPaths?: string[];\n}\n\ninterface TextSegment {\n type: 'text';\n value: string;\n}\n\ninterface AttachmentSegment {\n type: 'attachment';\n path: string;\n}\n\ntype Segment = TextSegment | AttachmentSegment;\n\n/** Parse text into segments of plain text and attachment references. */\nexport function parseAttachmentRefs(text: string): Segment[] {\n const segments: Segment[] = [];\n let lastIndex = 0;\n\n for (const match of text.matchAll(ATTACHMENT_REF_RE)) {\n const fullMatchStart = match.index;\n // The path capture starts after the optional leading whitespace\n const leadingWs = match[0].length - match[0].trimStart().length;\n const refStart = fullMatchStart + leadingWs;\n\n // Add text before this reference (including leading whitespace)\n if (refStart > lastIndex) {\n segments.push({ type: 'text', value: text.slice(lastIndex, refStart) });\n }\n\n segments.push({ type: 'attachment', path: match[1] });\n lastIndex = fullMatchStart + match[0].length;\n }\n\n if (lastIndex < text.length) {\n segments.push({ type: 'text', value: text.slice(lastIndex) });\n }\n\n return segments;\n}\n\nexport function InlineAttachments({ text, attachmentPaths }: InlineAttachmentsProps) {\n const segments = parseAttachmentRefs(text);\n const hasInlineAttachments = segments.some((s) => s.type === 'attachment');\n const extraPaths = attachmentPaths?.filter(Boolean) ?? [];\n\n if (!hasInlineAttachments && extraPaths.length === 0) {\n return <span className=\"text-sm leading-relaxed\">{text}</span>;\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {segments.map((segment) => {\n if (segment.type === 'text') {\n const trimmed = segment.value.trim();\n if (!trimmed) return null;\n return (\n <span key={`text-${trimmed.slice(0, 40)}`} className=\"text-sm leading-relaxed\">\n {trimmed}\n </span>\n );\n }\n return <AttachmentPreview key={`att-${segment.path}`} path={segment.path} />;\n })}\n {extraPaths.map((path) => (\n <AttachmentPreview key={`extra-${path}`} path={path} />\n ))}\n </div>\n );\n}\n\nfunction AttachmentPreview({ path }: { path: string }) {\n const filename = getFilename(path);\n const [loadError, setLoadError] = useState(false);\n\n if (isImagePath(path)) {\n if (loadError) {\n return (\n <div\n data-testid=\"inline-attachment-image-error\"\n className=\"text-muted-foreground flex items-center gap-2 rounded-md border px-3 py-2 text-sm\"\n >\n <ImageOff className=\"h-4 w-4 shrink-0\" />\n <span className=\"truncate\">{filename}</span>\n </div>\n );\n }\n\n return (\n <Dialog>\n <DialogTrigger asChild>\n <img\n src={previewUrl(path)}\n alt={filename}\n data-testid=\"inline-attachment-image\"\n onError={() => setLoadError(true)}\n className=\"max-h-48 max-w-full cursor-pointer rounded-md border object-contain transition-opacity hover:opacity-80\"\n />\n </DialogTrigger>\n <DialogContent className=\"max-w-3xl gap-0 overflow-hidden border-0 p-0 [&>button:last-child]:!cursor-pointer [&>button:last-child]:!rounded-full [&>button:last-child]:!bg-black/70 [&>button:last-child]:!p-1.5 [&>button:last-child]:!text-white [&>button:last-child]:!opacity-100 [&>button:last-child]:!shadow-lg [&>button:last-child]:!backdrop-blur-md [&>button:last-child]:hover:!bg-black/90\">\n <VisuallyHidden.Root>\n <DialogTitle>Preview: {filename}</DialogTitle>\n </VisuallyHidden.Root>\n <div className=\"relative bg-black/90\">\n <img\n src={previewUrl(path)}\n alt={filename}\n className=\"h-auto max-h-[70vh] w-full object-contain\"\n />\n </div>\n <div className=\"bg-background flex items-center gap-3 px-4 py-3\">\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"truncate text-sm font-medium\">{filename}</span>\n </div>\n <a\n href={previewUrl(path)}\n download={filename}\n className=\"text-muted-foreground hover:text-foreground shrink-0 cursor-pointer rounded p-1.5 transition-colors\"\n aria-label={`Download ${filename}`}\n >\n <DownloadIcon className=\"h-4 w-4\" />\n </a>\n </div>\n </DialogContent>\n </Dialog>\n );\n }\n\n return (\n <a\n href={previewUrl(path)}\n download={filename}\n data-testid=\"inline-attachment-file\"\n className=\"text-primary text-sm underline underline-offset-2\"\n >\n {filename}\n </a>\n );\n}\n","'use client';\n\nimport { useState, useEffect, useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n AlertTriangle,\n Check,\n CheckCircle2,\n Clock,\n ExternalLink,\n FileSearch,\n GitBranch,\n GitCommitHorizontal,\n GitMerge,\n Info,\n RefreshCw,\n Settings,\n ShieldCheck,\n X,\n Zap,\n} from 'lucide-react';\nimport { InlineAttachments } from '@/components/common/inline-attachments';\nimport { PrStatus } from '@shipit-ai/core/domain/generated/output';\nimport { cn } from '@/lib/utils';\nimport { CiStatusBadge } from '@/components/common/ci-status-badge';\nimport { CometSpinner } from '@/components/ui/comet-spinner';\nimport { ActionButton } from '@/components/common/action-button';\nimport { featureNodeStateConfig } from '@/components/common/feature-node';\nimport type { FeatureNodeData } from '@/components/common/feature-node';\nimport {\n getAgentTypeIcon,\n agentTypeLabels,\n} from '@/components/common/feature-node/agent-type-icons';\nimport { getModelMeta } from '@/lib/model-metadata';\nimport { formatDuration } from '@/lib/format-duration';\nimport type { BranchSyncData } from '@/hooks/use-branch-sync-status';\n\n// ── Primitives ──────────────────────────────────────────────────────\n\nfunction Section({\n icon: Icon,\n title,\n children,\n}: {\n icon: React.ComponentType<{ className?: string }>;\n title: string;\n children: React.ReactNode;\n}) {\n return (\n <div className=\"px-3 pt-4 pb-1\">\n <div className=\"text-foreground mb-2 flex items-center gap-1.5 text-sm font-semibold tracking-wider uppercase\">\n <Icon className=\"size-4 opacity-50\" />\n {title}\n </div>\n {children}\n </div>\n );\n}\n\nfunction Card({ children, className }: { children: React.ReactNode; className?: string }) {\n return (\n <div className={cn('bg-muted/60 rounded-md border border-transparent p-3', className)}>\n {children}\n </div>\n );\n}\n\nfunction KV({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"text-foreground/40 text-[11px] font-medium tracking-wider uppercase\">\n {label}\n </span>\n <span className=\"text-sm leading-snug\">{children}</span>\n </div>\n );\n}\n\nfunction Flag({ on, label }: { on: boolean; label: string }) {\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs font-medium',\n on\n ? 'bg-emerald-500/10 text-emerald-600 dark:text-emerald-400'\n : 'bg-foreground/[0.04] text-foreground/25'\n )}\n >\n {on ? <Check className=\"size-3\" /> : <X className=\"size-3\" />}\n {label}\n </span>\n );\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction formatRelativeTime(timestamp: string | number): string {\n const now = Date.now();\n const time = typeof timestamp === 'string' ? new Date(timestamp).getTime() : timestamp;\n const diffMs = now - time;\n const diffMin = Math.floor(diffMs / 60000);\n const diffHr = Math.floor(diffMin / 60);\n const diffDay = Math.floor(diffHr / 24);\n if (diffDay > 30)\n return new Date(time).toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n if (diffDay > 0) return `${diffDay}d ago`;\n if (diffHr > 0) return `${diffHr}h ago`;\n if (diffMin > 0) return `${diffMin}m ago`;\n return 'just now';\n}\n\nfunction useElapsedTime(startedAt?: number): string | null {\n const [elapsed, setElapsed] = useState<string | null>(null);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n useEffect(() => {\n if (!startedAt) {\n setElapsed(null);\n return;\n }\n setElapsed(formatDuration(Math.max(0, Date.now() - startedAt)));\n intervalRef.current = setInterval(() => {\n setElapsed(formatDuration(Math.max(0, Date.now() - startedAt)));\n }, 1000);\n return () => {\n if (intervalRef.current) clearInterval(intervalRef.current);\n };\n }, [startedAt]);\n return elapsed;\n}\n\nconst prColor: Record<PrStatus, string> = {\n [PrStatus.Open]: 'text-blue-600 dark:text-blue-400',\n [PrStatus.Merged]: 'text-purple-600 dark:text-purple-400',\n [PrStatus.Closed]: 'text-red-600 dark:text-red-400',\n};\n\n// ── Main ────────────────────────────────────────────────────────────\n\nexport interface OverviewTabProps {\n data: FeatureNodeData;\n syncStatus?: BranchSyncData | null;\n syncLoading?: boolean;\n syncError?: string | null;\n onRefreshSync?: () => void;\n onRebaseOnMain?: () => void;\n rebaseLoading?: boolean;\n rebaseError?: string | null;\n}\n\nexport function OverviewTab({\n data,\n syncStatus,\n syncLoading,\n syncError,\n onRefreshSync,\n onRebaseOnMain,\n rebaseLoading,\n rebaseError,\n}: OverviewTabProps) {\n const isCompleted = data.lifecycle === 'maintain';\n const isRunning = data.state === 'running' || data.state === 'action-required';\n const elapsedTime = useElapsedTime(isRunning ? data.startedAt : undefined);\n const config = featureNodeStateConfig[data.state];\n const showSummary =\n Boolean(data.summary) && !(data.userQuery && data.summary?.trim() === data.userQuery.trim());\n\n return (\n <div data-testid=\"feature-drawer-status\" className=\"pb-4\">\n {/* ── Progress ── */}\n\n {!isCompleted && data.progress > 0 ? (\n <div data-testid=\"feature-drawer-progress\" className=\"px-3 pb-2\">\n <div className=\"bg-foreground/[0.06] h-1.5 w-full overflow-hidden rounded-full\">\n <div\n className={cn('h-full rounded-full transition-all', config.progressClass)}\n style={{ width: `${data.progress}%` }}\n />\n </div>\n </div>\n ) : null}\n\n {/* ── Description (above stats) ── */}\n {data.oneLiner || data.userQuery || showSummary ? (\n <Section icon={Info} title=\"Description\">\n <Card className=\"flex flex-col gap-2\">\n {data.oneLiner ? <KV label=\"One-Liner\">{data.oneLiner}</KV> : null}\n {data.userQuery ? (\n <KV label=\"Query\">\n <InlineAttachments text={data.userQuery} />\n </KV>\n ) : null}\n {showSummary ? (\n <KV label=\"Summary\">\n <span className=\"leading-snug\">{data.summary}</span>\n </KV>\n ) : null}\n </Card>\n </Section>\n ) : null}\n\n {/* ── PR (right after description) ── */}\n {data.pr ? (\n <Section icon={GitCommitHorizontal} title=\"Pull Request\">\n <Card>\n <div className=\"flex items-center gap-2\">\n <a\n href={data.pr.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary inline-flex items-center gap-1 text-sm font-semibold hover:underline\"\n >\n #{data.pr.number} <ExternalLink className=\"size-3\" />\n </a>\n <span className={cn('text-xs font-semibold', prColor[data.pr.status])}>\n {data.pr.status}\n </span>\n {data.pr.mergeable === false ? (\n <span className=\"inline-flex items-center gap-1 text-xs font-medium text-orange-600 dark:text-orange-400\">\n <AlertTriangle className=\"size-3 shrink-0\" /> Conflicts\n </span>\n ) : null}\n {data.pr.ciStatus && data.hideCiStatus !== true ? (\n <CiStatusBadge status={data.pr.ciStatus} />\n ) : null}\n {data.pr.commitHash ? (\n <code className=\"text-foreground/40 ml-auto font-mono text-[11px]\">\n {data.pr.commitHash.slice(0, 7)}\n </code>\n ) : null}\n </div>\n </Card>\n </Section>\n ) : null}\n\n {/* ── Quick stats grid ── */}\n <div className=\"grid grid-cols-2 gap-2 px-3 pb-1\">\n {data.branch ? (\n <Card>\n <KV label=\"Branch\">\n <span className=\"inline-flex items-center gap-1\">\n <GitBranch className=\"text-foreground/30 size-3 shrink-0\" />\n <code className=\"font-mono text-[11px]\">{data.branch}</code>\n </span>\n {data.baseBranch ? (\n <span className=\"text-foreground/30 block text-[10px]\">from {data.baseBranch}</span>\n ) : null}\n </KV>\n </Card>\n ) : null}\n {data.agentType || data.modelId ? (\n <Card>\n <KV label=\"Agent\">\n <span className=\"inline-flex items-center gap-1.5\">\n {data.agentType\n ? (() => {\n const I = getAgentTypeIcon(data.agentType);\n return <I className=\"size-3.5 shrink-0 opacity-50\" />;\n })()\n : null}\n {data.agentType ? (\n <span>\n {agentTypeLabels[data.agentType as keyof typeof agentTypeLabels] ??\n data.agentType}\n </span>\n ) : null}\n {data.agentType && data.modelId ? (\n <span className=\"text-foreground/20\">/</span>\n ) : null}\n {data.modelId ? (\n <span className=\"text-foreground/50 text-[12px]\">\n {getModelMeta(data.modelId).displayName || data.modelId}\n </span>\n ) : null}\n </span>\n </KV>\n </Card>\n ) : null}\n {data.createdAt ? (\n <Card>\n <KV label=\"Created\">\n <span className=\"inline-flex items-center gap-1\">\n <Clock className=\"text-foreground/30 size-3 shrink-0\" />\n {formatRelativeTime(data.createdAt)}\n </span>\n </KV>\n </Card>\n ) : null}\n {data.fastMode ? (\n <Card>\n <KV label=\"Mode\">\n <span className=\"inline-flex items-center gap-1 text-amber-600 dark:text-amber-400\">\n <Zap className=\"size-3.5\" /> Fast\n </span>\n </KV>\n </Card>\n ) : null}\n {data.runtime || elapsedTime ? (\n <Card>\n <KV label={data.runtime ? 'Runtime' : 'Elapsed'}>\n <span className=\"inline-flex items-center gap-1\">\n <Clock className=\"text-foreground/30 size-3 shrink-0\" />\n {data.runtime ?? elapsedTime}\n </span>\n </KV>\n </Card>\n ) : null}\n </div>\n\n {/* ── Errors ── */}\n {data.blockedBy || data.errorMessage ? (\n <Section icon={AlertTriangle} title=\"Issues\">\n <Card className=\"border-destructive/20 bg-destructive/5\">\n {data.blockedBy ? <KV label=\"Blocked By\">{data.blockedBy}</KV> : null}\n {data.errorMessage ? (\n <KV label=\"Error\">\n <span className=\"text-destructive\">{data.errorMessage}</span>\n </KV>\n ) : null}\n </Card>\n </Section>\n ) : null}\n\n {/* ── Sync ── */}\n {onRebaseOnMain && data.branch && onRefreshSync ? (\n <Section icon={RefreshCw} title=\"Branch Sync\">\n <SyncCard\n syncStatus={syncStatus ?? null}\n syncLoading={syncLoading ?? false}\n syncError={syncError ?? null}\n onRefreshSync={onRefreshSync}\n onRebaseOnMain={onRebaseOnMain}\n rebaseLoading={rebaseLoading ?? false}\n rebaseError={rebaseError ?? null}\n />\n </Section>\n ) : null}\n\n {/* ── Settings ── */}\n <SettingsBlock data={data} />\n </div>\n );\n}\n\n// ── Sync card ───────────────────────────────────────────────────────\n\nfunction SyncCard({\n syncStatus,\n syncLoading,\n syncError,\n onRefreshSync,\n onRebaseOnMain,\n rebaseLoading,\n rebaseError,\n}: {\n syncStatus: BranchSyncData | null;\n syncLoading: boolean;\n syncError: string | null;\n onRefreshSync: () => void;\n onRebaseOnMain: () => void;\n rebaseLoading: boolean;\n rebaseError: string | null;\n}) {\n const { t } = useTranslation('web');\n const isBehind = syncStatus != null && syncStatus.behind > 0;\n const isUpToDate = syncStatus?.behind === 0;\n const base = syncStatus?.baseBranch ?? 'main';\n\n return (\n <Card>\n <div data-testid=\"branch-sync-status\" className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-1.5 text-[13px]\">\n {syncLoading && !syncStatus ? (\n <>\n <CometSpinner size=\"sm\" />\n <span className=\"text-foreground/40\">Checking...</span>\n </>\n ) : syncError ? (\n <>\n <AlertTriangle className=\"size-3.5 text-red-500\" />\n <span className=\"text-destructive text-xs\">{syncError}</span>\n </>\n ) : rebaseLoading ? (\n <>\n <CometSpinner size=\"sm\" />\n <span>\n Rebasing on <code className=\"font-mono text-[11px]\">{base}</code>...\n </span>\n </>\n ) : isBehind ? (\n <>\n <AlertTriangle className=\"size-3.5 text-orange-500\" />\n <span>\n {syncStatus.behind} behind <code className=\"font-mono text-[11px]\">{base}</code>\n {syncStatus.ahead > 0 ? (\n <span className=\"text-foreground/30 ml-1 text-[11px]\">\n · {syncStatus.ahead} ahead\n </span>\n ) : null}\n </span>\n </>\n ) : isUpToDate ? (\n <>\n <CheckCircle2 className=\"size-3.5 text-green-500\" />\n <span>\n Up to date · <code className=\"font-mono text-[11px]\">{base}</code>\n {syncStatus.ahead > 0 ? (\n <span className=\"text-foreground/30 ml-1 text-[11px]\">\n · {syncStatus.ahead} ahead\n </span>\n ) : null}\n </span>\n </>\n ) : null}\n </div>\n {(syncStatus || syncError) && !rebaseLoading ? (\n <button\n onClick={onRefreshSync}\n disabled={syncLoading}\n className=\"text-foreground/30 hover:text-foreground/60 hover:bg-foreground/5 inline-flex size-6 items-center justify-center rounded-sm disabled:opacity-50\"\n aria-label={t('branchSyncStatus.refreshSyncStatus')}\n >\n <RefreshCw className={cn('size-3', syncLoading && 'animate-spin')} />\n </button>\n ) : null}\n </div>\n {isBehind && !rebaseLoading ? (\n <div className=\"pt-2\">\n <ActionButton\n label={t('branchSyncStatus.rebaseOnMain')}\n onClick={onRebaseOnMain}\n loading={false}\n error={!!rebaseError}\n icon={GitMerge}\n variant=\"outline\"\n size=\"sm\"\n />\n </div>\n ) : null}\n {rebaseError ? <p className=\"text-destructive pt-1 text-[11px]\">{rebaseError}</p> : null}\n </Card>\n );\n}\n\n// ── Settings ────────────────────────────────────────────────────────\n\nfunction SettingsBlock({ data }: { data: FeatureNodeData }) {\n const has =\n data.approvalGates != null ||\n data.push != null ||\n data.openPr != null ||\n data.ciWatchEnabled != null ||\n data.enableEvidence != null ||\n data.forkAndPr != null ||\n data.commitSpecs != null;\n if (!has) return null;\n\n return (\n <Section icon={Settings} title=\"Settings\">\n <div className=\"grid grid-cols-3 gap-2\">\n {data.approvalGates ? (\n <Card>\n <div className=\"text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase\">\n <ShieldCheck className=\"size-3\" /> Approve\n </div>\n <div className=\"flex flex-col gap-0.5\">\n <Flag on={data.approvalGates.allowPrd} label=\"PRD\" />\n <Flag on={data.approvalGates.allowPlan} label=\"Plan\" />\n <Flag on={data.approvalGates.allowMerge} label=\"Merge\" />\n </div>\n </Card>\n ) : null}\n {data.enableEvidence != null ? (\n <Card>\n <div className=\"text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase\">\n <FileSearch className=\"size-3\" /> Evidence\n </div>\n <div className=\"flex flex-col gap-0.5\">\n <Flag on={data.enableEvidence} label=\"Collect\" />\n {data.commitEvidence != null ? (\n <Flag on={data.commitEvidence} label=\"Add to PR\" />\n ) : null}\n </div>\n </Card>\n ) : null}\n {data.push != null ||\n data.openPr != null ||\n data.ciWatchEnabled != null ||\n data.commitSpecs != null ||\n data.forkAndPr != null ? (\n <Card>\n <div className=\"text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase\">\n <GitBranch className=\"size-3\" /> Git\n </div>\n <div className=\"flex flex-col gap-0.5\">\n {data.push != null ? <Flag on={data.push} label=\"Push\" /> : null}\n {data.openPr != null ? <Flag on={data.openPr} label=\"PR\" /> : null}\n {data.ciWatchEnabled != null ? <Flag on={data.ciWatchEnabled} label=\"Watch\" /> : null}\n {data.commitSpecs != null ? <Flag on={data.commitSpecs} label=\"Specs\" /> : null}\n {data.forkAndPr != null ? <Flag on={data.forkAndPr} label=\"Fork\" /> : null}\n </div>\n </Card>\n ) : null}\n </div>\n </Section>\n );\n}\n","'use client';\n\nimport { useState, useEffect, useRef, useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n Loader2,\n AlertCircle,\n Clock,\n Zap,\n DollarSign,\n Play,\n RotateCcw,\n CheckCircle2,\n XCircle,\n Square,\n Ban,\n MessageSquare,\n Timer,\n ArrowDownToLine,\n ArrowUpFromLine,\n Copy,\n Check,\n} from 'lucide-react';\nimport type {\n PhaseTimingData,\n RejectionFeedbackData,\n} from '@/app/actions/get-feature-phase-timings';\nimport { InlineAttachments } from '@/components/common/inline-attachments';\nimport { formatDuration } from '@/lib/format-duration';\n\n/**\n * Computes the effective duration for a phase timing entry.\n * For completed phases, uses the server-provided durationMs.\n * For in-progress phases (has startedAt but no completedAt), computes\n * elapsed time client-side so the UI shows a live-updating timer.\n */\nfunction getEffectiveDuration(timing: PhaseTimingData, now: number): number {\n if (timing.durationMs != null && timing.durationMs > 0) return timing.durationMs;\n if (!timing.completedAt && timing.startedAt) {\n const started = new Date(timing.startedAt).getTime();\n if (!Number.isNaN(started)) return Math.max(0, now - started);\n }\n return 0;\n}\n\n/** Returns true if any non-lifecycle phase is still in progress. */\nfunction hasRunningPhase(timings: PhaseTimingData[]): boolean {\n return timings.some((t) => !t.phase.startsWith('run:') && !t.completedAt && t.startedAt);\n}\n\n/** Hook that ticks every second while there are running phases. */\nfunction useTickingNow(timings: PhaseTimingData[] | null): number {\n const [now, setNow] = useState(Date.now);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n useEffect(() => {\n const running = timings ? hasRunningPhase(timings) : false;\n if (running) {\n // Tick every second\n intervalRef.current = setInterval(() => setNow(Date.now()), 1000);\n }\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [timings]);\n\n return now;\n}\n\n/** Format a token count with K/M suffix for readability. */\nfunction formatTokens(count: number): string {\n if (count >= 1_000_000) return `${(count / 1_000_000).toFixed(1)}M`;\n if (count >= 1_000) return `${(count / 1_000).toFixed(1)}K`;\n return String(count);\n}\n\n/** Format a timestamp to a short local time string (e.g. \"10:05:30 AM\"). */\nfunction formatTimestamp(value: string | Date | unknown): string {\n const d = value instanceof Date ? value : new Date(String(value));\n if (Number.isNaN(d.getTime())) return '';\n return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n}\n\n/** Format a USD cost with appropriate precision. */\nfunction formatCost(usd: number): string {\n if (usd >= 1) return `$${usd.toFixed(2)}`;\n if (usd >= 0.01) return `$${usd.toFixed(3)}`;\n return `$${usd.toFixed(4)}`;\n}\n\nexport interface ActivityTabProps {\n timings: PhaseTimingData[] | null;\n loading: boolean;\n error: string | null;\n rejectionFeedback?: RejectionFeedbackData[];\n}\n\nconst NODE_TO_PHASE: Record<string, string> = {\n analyze: 'Analyzing',\n requirements: 'Requirements',\n research: 'Researching',\n plan: 'Planning',\n implement: 'Implementing',\n rebase: 'Rebasing',\n 'fast-implement': 'Fast Implement',\n evidence: 'Evidence',\n validate: 'Validating',\n repair: 'Repairing',\n merge: 'Merging',\n};\n\nconst LIFECYCLE_EVENTS: Record<\n string,\n { label: string; colorClass: string; bgClass: string; icon: typeof Play }\n> = {\n 'run:started': {\n label: 'started',\n colorClass: 'text-blue-600',\n bgClass: 'bg-blue-50 dark:bg-blue-950/30',\n icon: Play,\n },\n 'run:resumed': {\n label: 'resumed',\n colorClass: 'text-blue-600',\n bgClass: 'bg-blue-50 dark:bg-blue-950/30',\n icon: RotateCcw,\n },\n 'run:completed': {\n label: 'completed',\n colorClass: 'text-emerald-600',\n bgClass: 'bg-emerald-50 dark:bg-emerald-950/30',\n icon: CheckCircle2,\n },\n 'run:failed': {\n label: 'failed',\n colorClass: 'text-red-600',\n bgClass: 'bg-red-50 dark:bg-red-950/30',\n icon: XCircle,\n },\n 'run:stopped': {\n label: 'stopped',\n colorClass: 'text-amber-600',\n bgClass: 'bg-amber-50 dark:bg-amber-950/30',\n icon: Square,\n },\n 'run:crashed': {\n label: 'crashed',\n colorClass: 'text-red-600',\n bgClass: 'bg-red-50 dark:bg-red-950/30',\n icon: XCircle,\n },\n 'run:rejected': {\n label: 'rejected',\n colorClass: 'text-orange-600',\n bgClass: 'bg-orange-50 dark:bg-orange-950/30',\n icon: Ban,\n },\n};\n\nfunction isLifecycleEvent(phase: string): boolean {\n return phase.startsWith('run:');\n}\n\n/* ---------------------------------------------------------------------------\n * Lifecycle-aware view model\n * ------------------------------------------------------------------------- */\n\n/**\n * A single iteration in the lifecycle timeline.\n *\n * An iteration represents one cycle of work:\n * started/resumed → phase work → rejected/completed/failed\n *\n * Each rejected iteration has associated rejection feedback.\n */\nexport interface TimelineIteration {\n /** 1-based iteration number */\n number: number;\n /** The timing events in this iteration */\n timings: PhaseTimingData[];\n /** If this iteration ended with rejection, the feedback message */\n rejectionMessage?: string;\n /** If this iteration ended with rejection, any attachments */\n rejectionAttachments?: string[];\n}\n\n/**\n * Build a lifecycle-aware timeline from flat timing events and rejection feedback.\n *\n * Splits the timing stream at run:rejected boundaries to produce iterations.\n * Each rejection feedback entry is matched to its iteration by index.\n *\n * When there are more feedback entries than run:rejected events in the timings,\n * synthetic run:rejected + run:resumed events are appended to ensure every\n * feedback entry is represented.\n */\nexport function buildLifecycleTimeline(\n timings: PhaseTimingData[],\n feedback?: RejectionFeedbackData[]\n): TimelineIteration[] {\n if (!timings.length) return [];\n\n // Count existing run:rejected events\n const existingRejectionCount = timings.filter((t) => t.phase === 'run:rejected').length;\n const feedbackCount = feedback?.length ?? 0;\n\n // Augment timings with synthetic rejection/resumed cycles for unmatched feedback\n let augmented = timings;\n if (feedbackCount > existingRejectionCount) {\n augmented = [...timings];\n\n // Use last timing's agentRunId as template\n const templateRunId = timings[timings.length - 1].agentRunId;\n\n for (let i = existingRejectionCount; i < feedbackCount; i++) {\n const fb = feedback![i];\n // Add run:resumed before work (except for the first synthetic, which continues from existing)\n if (i > existingRejectionCount) {\n augmented.push({\n agentRunId: templateRunId,\n phase: 'run:resumed',\n startedAt: fb.timestamp ?? `synthetic-resumed-${i}`,\n });\n }\n // Add run:rejected\n augmented.push({\n agentRunId: templateRunId,\n phase: 'run:rejected',\n startedAt: fb.timestamp ?? `synthetic-${i}`,\n });\n }\n }\n\n // Split into iterations at run:rejected boundaries\n const iterations: TimelineIteration[] = [];\n let currentEvents: PhaseTimingData[] = [];\n let rejectionIndex = 0;\n\n for (const t of augmented) {\n currentEvents.push(t);\n\n if (t.phase === 'run:rejected') {\n const fb = feedback?.[rejectionIndex];\n iterations.push({\n number: iterations.length + 1,\n timings: currentEvents,\n rejectionMessage: fb?.message,\n rejectionAttachments: fb?.attachments,\n });\n currentEvents = [];\n rejectionIndex++;\n }\n }\n\n // Remaining events after last rejection (or all events if no rejections)\n if (currentEvents.length > 0) {\n iterations.push({\n number: iterations.length + 1,\n timings: currentEvents,\n });\n }\n\n return iterations;\n}\n\n/** Determine the outcome status of an iteration */\nfunction getIterationOutcome(\n iteration: TimelineIteration\n): { label: string; colorClass: string; dotClass: string } | null {\n const lastLifecycle = [...iteration.timings].reverse().find((t) => isLifecycleEvent(t.phase));\n if (!lastLifecycle) return null;\n\n switch (lastLifecycle.phase) {\n case 'run:rejected':\n return { label: 'Rejected', colorClass: 'text-orange-600', dotClass: 'bg-orange-500' };\n case 'run:completed':\n return { label: 'Completed', colorClass: 'text-emerald-600', dotClass: 'bg-emerald-500' };\n case 'run:failed':\n return { label: 'Failed', colorClass: 'text-red-600', dotClass: 'bg-red-500' };\n case 'run:crashed':\n return { label: 'Crashed', colorClass: 'text-red-600', dotClass: 'bg-red-500' };\n case 'run:stopped':\n return { label: 'Stopped', colorClass: 'text-amber-600', dotClass: 'bg-amber-500' };\n default:\n return null;\n }\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport function ActivityTab({ timings, loading, error, rejectionFeedback }: ActivityTabProps) {\n const { t } = useTranslation('web');\n const now = useTickingNow(timings);\n\n if (loading) {\n return (\n <div data-testid=\"activity-tab-loading\" className=\"flex items-center justify-center p-8\">\n <Loader2 className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"flex items-center gap-2 p-4 text-base text-red-600\">\n <AlertCircle className=\"h-4 w-4 shrink-0\" />\n <span>{error}</span>\n </div>\n );\n }\n\n if (!timings || timings.length === 0) {\n return (\n <div className=\"flex flex-col items-center justify-center gap-2 p-8\">\n <Clock className=\"text-muted-foreground h-8 w-8\" />\n <p className=\"text-muted-foreground text-base\">{t('activityTab.noActivityRecorded')}</p>\n </div>\n );\n }\n\n const nodeTimings = timings.filter((t) => !isLifecycleEvent(t.phase));\n const maxDurationMs = Math.max(\n ...nodeTimings.map((t) => getEffectiveDuration(t, now)),\n ...nodeTimings.map((t) => t.approvalWaitMs ?? 0),\n 0\n );\n\n const iterations = buildLifecycleTimeline(timings, rejectionFeedback);\n const hasMultipleIterations = iterations.length > 1;\n\n const totalExecMs = nodeTimings.reduce((sum, t) => sum + getEffectiveDuration(t, now), 0);\n const totalWaitMs = nodeTimings.reduce((sum, t) => sum + (t.approvalWaitMs ?? 0), 0);\n const totalInputTokens = nodeTimings.reduce((sum, t) => sum + (t.inputTokens ?? 0), 0);\n const totalOutputTokens = nodeTimings.reduce((sum, t) => sum + (t.outputTokens ?? 0), 0);\n const totalCostUsd = nodeTimings.reduce((sum, t) => sum + (t.costUsd ?? 0), 0);\n\n return (\n <div className=\"flex flex-col gap-3 p-4\">\n <div data-testid=\"activity-timings\" className=\"flex flex-col gap-3\">\n {iterations.map((iteration) => (\n <IterationGroup\n key={iteration.number}\n iteration={iteration}\n showHeader={hasMultipleIterations}\n maxDurationMs={maxDurationMs}\n now={now}\n />\n ))}\n </div>\n {totalExecMs > 0 ? (\n <SummaryTotals\n totalExecMs={totalExecMs}\n totalWaitMs={totalWaitMs}\n totalInputTokens={totalInputTokens}\n totalOutputTokens={totalOutputTokens}\n totalCostUsd={totalCostUsd}\n />\n ) : null}\n </div>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Iteration group — one cycle of work\n * ------------------------------------------------------------------------- */\n\nfunction IterationGroup({\n iteration,\n showHeader,\n maxDurationMs,\n now,\n}: {\n iteration: TimelineIteration;\n showHeader: boolean;\n maxDurationMs: number;\n now: number;\n}) {\n const outcome = getIterationOutcome(iteration);\n\n return (\n <div\n data-testid={`iteration-${iteration.number}`}\n className=\"border-border/50 bg-card/50 flex flex-col overflow-hidden rounded-lg border\"\n >\n {/* Iteration header */}\n {showHeader ? (\n <div className=\"bg-muted/30 border-border/50 flex items-center justify-between border-b px-3 py-1.5\">\n <span className=\"text-muted-foreground text-sm font-semibold tracking-wide\">\n Iteration {iteration.number}\n </span>\n {outcome ? (\n <span className={`flex items-center gap-1 text-xs font-medium ${outcome.colorClass}`}>\n <span className={`inline-block h-1.5 w-1.5 rounded-full ${outcome.dotClass}`} />\n {outcome.label}\n </span>\n ) : null}\n </div>\n ) : null}\n\n {/* Timeline content */}\n <div className=\"relative flex flex-col\">\n {/* Vertical timeline line — centered on 20px dots with px-3 (12px) left padding: 12 + 10 - 0.5 = 21.5px */}\n <div className=\"bg-border/60 absolute top-4 bottom-4 left-[21.5px] w-px\" />\n\n {iteration.timings.map((t, idx) => {\n if (isLifecycleEvent(t.phase)) {\n const isRejection = t.phase === 'run:rejected';\n const isFailure =\n t.phase === 'run:failed' || t.phase === 'run:crashed' || t.phase === 'run:stopped';\n // For failures, find the last phase with an error message in this iteration\n let message: string | undefined;\n if (isRejection) {\n message = iteration.rejectionMessage;\n } else if (isFailure) {\n const lastErrorPhase = [...iteration.timings]\n .reverse()\n .find((p) => !isLifecycleEvent(p.phase) && p.errorMessage);\n message = lastErrorPhase?.errorMessage ?? t.errorMessage;\n }\n return (\n <LifecycleEventRow\n key={`${t.agentRunId}-${t.phase}-${t.startedAt}`}\n timing={t}\n message={message}\n attachments={isRejection ? iteration.rejectionAttachments : undefined}\n isFirst={idx === 0}\n isLast={idx === iteration.timings.length - 1}\n />\n );\n }\n return (\n <NodeTimingRow\n key={`${t.agentRunId}-${t.phase}-${t.startedAt}`}\n timing={t}\n maxDurationMs={maxDurationMs}\n now={now}\n />\n );\n })}\n </div>\n </div>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Row components\n * ------------------------------------------------------------------------- */\n\nfunction LifecycleEventRow({\n timing,\n message,\n attachments,\n isFirst,\n isLast,\n}: {\n timing: PhaseTimingData;\n message?: string;\n attachments?: string[];\n isFirst?: boolean;\n isLast?: boolean;\n}) {\n const event = LIFECYCLE_EVENTS[timing.phase];\n if (!event) return null;\n\n const hasAttachments = attachments && attachments.length > 0;\n const Icon = event.icon;\n\n return (\n <div\n className={`relative flex flex-col gap-1 px-3 ${isFirst ? 'pt-2' : 'pt-1'} ${isLast ? 'pb-2' : 'pb-1'}`}\n >\n <div className=\"flex items-center gap-2\">\n {/* Timeline dot */}\n <div\n className={`relative z-10 flex h-5 w-5 shrink-0 items-center justify-center rounded-full ${event.bgClass}`}\n >\n <Icon className={`h-3 w-3 ${event.colorClass}`} />\n </div>\n\n {/* Label */}\n <span className={`text-sm font-medium ${event.colorClass}`}>{event.label}</span>\n\n {/* Timestamp */}\n {timing.startedAt &&\n !(typeof timing.startedAt === 'string' && timing.startedAt.startsWith('synthetic')) ? (\n <span className=\"text-muted-foreground/60 ml-auto text-xs tabular-nums\">\n {formatTimestamp(String(timing.startedAt))}\n </span>\n ) : null}\n </div>\n\n {/* Feedback / error message */}\n {message\n ? (() => {\n const isError =\n timing.phase === 'run:failed' ||\n timing.phase === 'run:crashed' ||\n timing.phase === 'run:stopped';\n return (\n <div\n className={`ml-[26px] flex items-start gap-1.5 rounded-md px-2 py-1.5 ${\n isError\n ? 'bg-red-50/50 dark:bg-red-950/20'\n : 'bg-orange-50/50 dark:bg-orange-950/20'\n }`}\n >\n {isError ? (\n <AlertCircle className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-red-400\" />\n ) : (\n <MessageSquare className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-orange-400\" />\n )}\n <span\n data-testid={isError ? 'error-message-text' : 'rejection-feedback-text'}\n className=\"text-muted-foreground text-xs leading-relaxed italic\"\n >\n — {message}\n </span>\n </div>\n );\n })()\n : null}\n {hasAttachments ? (\n <div data-testid=\"rejection-feedback-attachments\" className=\"ml-[26px]\">\n <InlineAttachments text=\"\" attachmentPaths={attachments} />\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction NodeTimingRow({\n timing,\n maxDurationMs,\n now,\n}: {\n timing: PhaseTimingData;\n maxDurationMs: number;\n now: number;\n}) {\n const { t } = useTranslation('web');\n const base = timing.phase.includes(':') ? timing.phase.split(':')[0] : timing.phase;\n const suffix = timing.phase.includes(':') ? timing.phase.split(':')[1] : null;\n const isSubPhase = suffix !== null;\n const isImplPhase = suffix?.startsWith('phase-') ?? false;\n const baseName = NODE_TO_PHASE[base] ?? base;\n const label = isImplPhase\n ? `Phase ${suffix!.replace('phase-', '')}`\n : suffix !== null\n ? `${baseName} #${suffix}`\n : baseName;\n\n const durationMs = getEffectiveDuration(timing, now);\n const isRunning = !timing.completedAt && !!timing.startedAt;\n // Running phases get a minimum 15% bar so they're always visually prominent\n const minPercent = isRunning ? 15 : 2;\n const barPercent =\n maxDurationMs > 0 ? Math.max(minPercent, (durationMs / maxDurationMs) * 100) : minPercent;\n const barColorClass = timing.completedAt\n ? isImplPhase\n ? 'bg-emerald-400'\n : isSubPhase\n ? 'bg-amber-500'\n : 'bg-emerald-500'\n : 'bg-blue-500';\n const totalTokens =\n timing.inputTokens != null || timing.outputTokens != null\n ? (timing.inputTokens ?? 0) + (timing.outputTokens ?? 0)\n : null;\n\n const [copied, setCopied] = useState(false);\n const handleCopyPrompt = useCallback(() => {\n if (!timing.prompt) return;\n navigator.clipboard.writeText(timing.prompt).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n });\n }, [timing.prompt]);\n\n return (\n <div\n className={`group/phase relative flex flex-col gap-0.5 px-3 py-1.5 ${isSubPhase ? 'ms-4' : ''}`}\n >\n <div data-testid={`timing-bar-${timing.phase}`} className=\"flex items-center gap-2\">\n {/* Timeline dot */}\n <div className=\"relative z-10 flex h-5 w-5 shrink-0 items-center justify-center\">\n <div\n className={`rounded-full ${isRunning ? 'h-3 w-3 animate-pulse' : 'h-2.5 w-2.5'} ${\n isRunning\n ? 'bg-blue-500'\n : timing.completedAt\n ? 'bg-emerald-500'\n : 'bg-muted-foreground/30'\n }`}\n />\n </div>\n\n {/* Phase label — fixed width so all bars align in a single column */}\n <span\n className={`w-28 shrink-0 truncate text-sm font-medium ${\n isSubPhase ? 'text-muted-foreground' : 'text-foreground/80'\n }`}\n >\n {label}\n </span>\n\n {/* Copy prompt button — appears on hover */}\n {timing.prompt ? (\n <button\n type=\"button\"\n onClick={handleCopyPrompt}\n className=\"text-muted-foreground/50 hover:text-foreground/70 -ms-1 shrink-0 opacity-0 transition-opacity group-hover/phase:opacity-100\"\n title={t('activityTab.copyPromptToClipboard')}\n >\n {copied ? (\n <Check className=\"h-3.5 w-3.5 text-emerald-500\" />\n ) : (\n <Copy className=\"h-3.5 w-3.5\" />\n )}\n </button>\n ) : null}\n\n {/* Progress bar */}\n <div\n className={`bg-muted relative min-w-0 flex-1 overflow-hidden rounded-full ${isSubPhase ? 'h-1.5' : 'h-2'}`}\n >\n {isRunning ? (\n <div\n className=\"absolute inset-0 rounded-full bg-blue-500/30\"\n style={{\n backgroundImage:\n 'linear-gradient(90deg, transparent 0%, rgb(59 130 246) 50%, transparent 100%)',\n backgroundSize: '200% 100%',\n animation: 'shimmer 1.5s ease-in-out infinite',\n }}\n />\n ) : (\n <div\n className={`h-full rounded-full transition-all duration-300 ${barColorClass}`}\n style={{ width: `${Math.min(barPercent, 100)}%` }}\n />\n )}\n </div>\n\n {/* Duration */}\n <span className=\"text-muted-foreground w-14 shrink-0 text-end text-sm font-medium tabular-nums\">\n {formatDuration(durationMs)}\n </span>\n </div>\n\n {/* Metrics row (timestamp + tokens + cost) */}\n <div className=\"ml-[28px] flex items-center gap-3 text-xs\">\n {timing.startedAt ? (\n <span className=\"text-muted-foreground/60 tabular-nums\">\n {formatTimestamp(timing.startedAt)}\n </span>\n ) : null}\n {totalTokens != null && totalTokens > 0 ? (\n <span className=\"text-muted-foreground/70 inline-flex items-center gap-0.5\">\n <Zap className=\"h-3 w-3 opacity-50\" />\n {formatTokens(totalTokens)}\n </span>\n ) : null}\n {timing.costUsd != null && timing.costUsd > 0 ? (\n <span className=\"text-muted-foreground/70 inline-flex items-center gap-0.5\">\n <DollarSign className=\"h-3 w-3 opacity-50\" />\n {formatCost(timing.costUsd)}\n </span>\n ) : null}\n </div>\n\n {/* Approval wait sub-row */}\n {timing.approvalWaitMs != null && timing.approvalWaitMs > 0 ? (\n <ApprovalWaitRow timing={timing} maxDurationMs={maxDurationMs} />\n ) : null}\n </div>\n );\n}\n\nfunction ApprovalWaitRow({\n timing,\n maxDurationMs,\n}: {\n timing: PhaseTimingData;\n maxDurationMs: number;\n}) {\n const waitMs = timing.approvalWaitMs ?? 0;\n const barPercent = maxDurationMs > 0 ? Math.max(2, (waitMs / maxDurationMs) * 100) : 2;\n\n return (\n <div\n data-testid={`approval-wait-${timing.phase}`}\n className=\"ml-[26px] flex items-center gap-2 rounded-md bg-amber-50/50 px-1.5 py-1 dark:bg-amber-950/20\"\n >\n <Timer className=\"h-3.5 w-3.5 shrink-0 text-amber-500\" />\n <span className=\"text-muted-foreground w-16 shrink-0 text-xs\">approval</span>\n <div className=\"bg-muted h-1.5 min-w-0 flex-1 overflow-hidden rounded-full\">\n <div\n className=\"h-full rounded-full bg-amber-500\"\n style={{ width: `${Math.min(barPercent, 100)}%` }}\n />\n </div>\n <span className=\"text-muted-foreground w-14 shrink-0 text-end text-xs tabular-nums\">\n {formatDuration(waitMs)}\n </span>\n </div>\n );\n}\n\nfunction SummaryTotals({\n totalExecMs,\n totalWaitMs,\n totalInputTokens,\n totalOutputTokens,\n totalCostUsd,\n}: {\n totalExecMs: number;\n totalWaitMs: number;\n totalInputTokens: number;\n totalOutputTokens: number;\n totalCostUsd: number;\n}) {\n const { t } = useTranslation('web');\n const totalTokens = totalInputTokens + totalOutputTokens;\n return (\n <div\n data-testid=\"activity-summary\"\n className=\"border-border bg-card/30 flex flex-col gap-2 rounded-lg border p-3\"\n >\n <div className=\"text-muted-foreground mb-1 text-xs font-semibold tracking-wider uppercase\">\n Summary\n </div>\n <div className=\"grid grid-cols-2 gap-x-4 gap-y-3\">\n <SummaryCell\n icon={Clock}\n label={t('activityTab.execution')}\n value={formatDuration(totalExecMs)}\n />\n <SummaryCell\n icon={Timer}\n label={t('activityTab.wait')}\n value={totalWaitMs > 0 ? formatDuration(totalWaitMs) : 'n/a'}\n />\n <SummaryCell\n icon={Clock}\n label=\"Wall-clock\"\n value={\n totalWaitMs > 0\n ? formatDuration(totalExecMs + totalWaitMs)\n : formatDuration(totalExecMs)\n }\n />\n <SummaryCell\n icon={DollarSign}\n label={t('activityTab.cost')}\n value={totalCostUsd > 0 ? formatCost(totalCostUsd) : 'n/a'}\n />\n <div className=\"col-span-2 flex flex-col gap-0.5\">\n <span className=\"text-muted-foreground flex items-center gap-1 text-xs\">\n <Zap className=\"h-3 w-3 opacity-40\" />\n Tokens\n </span>\n {totalTokens > 0 ? (\n <span className=\"flex items-center gap-2.5 text-sm tabular-nums\">\n <span>{formatTokens(totalTokens)}</span>\n <span\n className=\"text-muted-foreground flex items-center gap-3 text-xs\"\n title=\"Input tokens / Output tokens\"\n >\n <span className=\"flex items-center gap-0.5\">\n <ArrowDownToLine className=\"h-3 w-3 text-blue-500 opacity-60\" />\n {formatTokens(totalInputTokens)}\n </span>\n <span className=\"flex items-center gap-0.5\">\n <ArrowUpFromLine className=\"h-3 w-3 text-emerald-500 opacity-60\" />\n {formatTokens(totalOutputTokens)}\n </span>\n </span>\n </span>\n ) : (\n <span className=\"text-muted-foreground/40 text-sm italic tabular-nums\">n/a</span>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nfunction SummaryCell({\n icon: Icon,\n label,\n value,\n className = '',\n}: {\n icon: typeof Clock;\n label: string;\n value: string;\n className?: string;\n}) {\n const isNA = value === 'n/a';\n return (\n <div className={`flex flex-col gap-0.5 ${className}`}>\n <span className=\"text-muted-foreground flex items-center gap-1 text-xs\">\n <Icon className=\"h-3 w-3 opacity-40\" />\n {label}\n </span>\n <span className={`text-sm tabular-nums ${isNA ? 'text-muted-foreground/40 italic' : ''}`}>\n {value}\n </span>\n </div>\n );\n}\n","'use client';\n\nimport { useMemo } from 'react';\nimport {\n FileText,\n Terminal,\n MessageSquare,\n CheckCircle2,\n Coins,\n Server,\n FileCode,\n Play,\n ArrowRight,\n AlertCircle,\n} from 'lucide-react';\nimport {\n parseLogContent,\n parseToolCall,\n parseResultMessage,\n parseTokensMessage,\n type ParsedLogLine,\n} from '@/lib/parse-log-line';\n\n/* ---------------------------------------------------------------------------\n * Public API\n * ------------------------------------------------------------------------- */\n\nexport interface EventLogViewerProps {\n content: string;\n}\n\nexport function EventLogViewer({ content }: EventLogViewerProps) {\n const lines = useMemo(() => parseLogContent(content), [content]);\n\n if (lines.length === 0) return null;\n\n return (\n <div className=\"flex flex-col\">\n {lines.map((line, i) => (\n // eslint-disable-next-line react/no-array-index-key -- append-only list, raw content not unique\n <LogLineRow key={i} line={line} />\n ))}\n </div>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Line router\n * ------------------------------------------------------------------------- */\n\nfunction LogLineRow({ line }: { line: ParsedLogLine }) {\n switch (line.tag) {\n case 'tool':\n return <ToolCallRow line={line} />;\n case 'tool-result':\n return <ToolResultRow line={line} />;\n case 'text':\n case 'delta':\n return <TextRow line={line} />;\n case 'result':\n return <ResultRow line={line} />;\n case 'tokens':\n case 'turn':\n return <TokensRow line={line} />;\n case 'cmd':\n return <CommandRow line={line} />;\n case 'file':\n return <FileChangeRow line={line} />;\n case 'thread':\n case 'event':\n return <InfoRow line={line} />;\n case 'error':\n return <ErrorRow line={line} />;\n case 'worker':\n return <WorkerRow line={line} />;\n case 'info':\n return <InfoRow line={line} />;\n case 'raw':\n default:\n return <RawRow line={line} />;\n }\n}\n\n/* ---------------------------------------------------------------------------\n * Shared helpers\n * ------------------------------------------------------------------------- */\n\nfunction Timestamp({ value }: { value: string | null }) {\n if (!value) return null;\n // Show only MM:SS — compact, hours rarely change in a session\n const full = value.replace(/^.*T/, '').replace('Z', '');\n const parts = full.split(':');\n const compact = parts.length >= 3 ? `${parts[1]}:${parts[2].split('.')[0]}` : full;\n return (\n <span className=\"text-muted-foreground/60 w-11 shrink-0 font-mono text-[10px]\">{compact}</span>\n );\n}\n\nfunction PhaseBadge({ phase }: { phase: string | null }) {\n if (!phase) return <span className=\"w-20 shrink-0\" />;\n return (\n <span\n className=\"bg-muted text-muted-foreground w-20 shrink-0 truncate rounded px-1.5 py-0.5 font-mono text-[10px] font-medium\"\n title={phase}\n >\n {phase}\n </span>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Event-specific rows\n * ------------------------------------------------------------------------- */\n\nfunction ToolCallRow({ line }: { line: ParsedLogLine }) {\n const { toolName, args } = parseToolCall(line.message);\n\n // Try to extract a key detail from args for common tools\n const detail = getToolDetail(toolName, args);\n\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 border-b border-transparent px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <ToolIcon toolName={toolName} />\n <span className=\"text-xs font-semibold text-violet-600 dark:text-violet-400\">\n {toolName}\n </span>\n {detail ? (\n <span className=\"text-muted-foreground min-w-0 font-mono text-xs break-all\">\n {detail}\n </span>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction ToolIcon({ toolName }: { toolName: string }) {\n const lower = toolName.toLowerCase();\n if (lower === 'bash') return <Terminal className=\"mt-0.5 h-3 w-3 shrink-0 text-violet-500\" />;\n if (lower === 'read' || lower === 'glob' || lower === 'grep')\n return <FileText className=\"mt-0.5 h-3 w-3 shrink-0 text-violet-500\" />;\n if (lower === 'write' || lower === 'edit')\n return <FileCode className=\"mt-0.5 h-3 w-3 shrink-0 text-violet-500\" />;\n return <Terminal className=\"mt-0.5 h-3 w-3 shrink-0 text-violet-500\" />;\n}\n\nfunction getToolDetail(toolName: string, args: string): string | null {\n try {\n const parsed = JSON.parse(args);\n if (toolName === 'Read' && parsed.file_path) return parsed.file_path;\n if (toolName === 'Write' && parsed.file_path) return parsed.file_path;\n if (toolName === 'Edit' && parsed.file_path) return parsed.file_path;\n if (toolName === 'Glob' && parsed.pattern) return parsed.pattern;\n if (toolName === 'Grep' && parsed.pattern) return parsed.pattern;\n if (toolName === 'Bash' && parsed.command) {\n return parsed.command as string;\n }\n if (toolName === 'Task' && parsed.description) return parsed.description;\n } catch {\n // Not JSON — show truncated raw args\n if (args.length > 0) return args;\n }\n return null;\n}\n\nfunction TextRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <MessageSquare className=\"mt-0.5 h-3 w-3 shrink-0 text-blue-500\" />\n <span className=\"text-foreground/80 min-w-0 text-xs leading-relaxed\">{line.message}</span>\n </div>\n </div>\n );\n}\n\nfunction ResultRow({ line }: { line: ParsedLogLine }) {\n const { chars } = parseResultMessage(line.message);\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <CheckCircle2 className=\"mt-0.5 h-3 w-3 shrink-0 text-emerald-500\" />\n <span className=\"text-xs font-medium text-emerald-600 dark:text-emerald-400\">\n Result: {chars.toLocaleString()} chars\n </span>\n </div>\n </div>\n );\n}\n\nfunction TokensRow({ line }: { line: ParsedLogLine }) {\n const { inputTokens, outputTokens } = parseTokensMessage(line.message);\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <Coins className=\"mt-0.5 h-3 w-3 shrink-0 text-amber-500\" />\n <span className=\"text-muted-foreground text-xs\">\n <span className=\"text-amber-600 dark:text-amber-400\">{inputTokens.toLocaleString()}</span>\n {' in / '}\n <span className=\"text-amber-600 dark:text-amber-400\">\n {outputTokens.toLocaleString()}\n </span>\n {' out'}\n </span>\n </div>\n </div>\n );\n}\n\nfunction WorkerRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 bg-zinc-50 px-3 py-1.5 transition-colors dark:bg-zinc-900/50\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <Server className=\"mt-0.5 h-3 w-3 shrink-0 text-zinc-500\" />\n <span className=\"text-muted-foreground text-xs font-medium break-all\">{line.message}</span>\n </div>\n </div>\n );\n}\n\nfunction ToolResultRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <ArrowRight className=\"mt-0.5 h-3 w-3 shrink-0 text-violet-400\" />\n <span className=\"text-muted-foreground min-w-0 font-mono text-[11px] break-all\">\n {line.message}\n </span>\n </div>\n </div>\n );\n}\n\nfunction CommandRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <Play className=\"mt-0.5 h-3 w-3 shrink-0 text-cyan-500\" />\n <span className=\"min-w-0 font-mono text-xs break-all text-cyan-700 dark:text-cyan-400\">\n {line.message}\n </span>\n </div>\n </div>\n );\n}\n\nfunction FileChangeRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <FileCode className=\"mt-0.5 h-3 w-3 shrink-0 text-orange-500\" />\n <span className=\"min-w-0 text-xs break-all text-orange-700 dark:text-orange-400\">\n {line.message}\n </span>\n </div>\n </div>\n );\n}\n\nfunction ErrorRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 bg-red-50 px-3 py-1.5 transition-colors dark:bg-red-950/30\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <AlertCircle className=\"mt-0.5 h-3 w-3 shrink-0 text-red-500\" />\n <span className=\"min-w-0 text-xs font-medium break-all text-red-700 dark:text-red-400\">\n {line.message}\n </span>\n </div>\n </div>\n );\n}\n\nfunction InfoRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <span className=\"text-muted-foreground min-w-0 text-xs break-all\">{line.message}</span>\n </div>\n );\n}\n\nfunction RawRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"px-3 py-0.5\">\n <span className=\"text-muted-foreground/70 font-mono text-[11px] break-all whitespace-pre-wrap\">\n {line.raw}\n </span>\n </div>\n );\n}\n","'use client';\n\nimport { useRef, useEffect, useState, useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { AlertCircle, Terminal, ArrowDown, Code, FileText } from 'lucide-react';\nimport { EventLogViewer } from './event-log-viewer';\n\nexport interface LogTabProps {\n content: string;\n isConnected: boolean;\n error: string | null;\n}\n\ntype ViewMode = 'structured' | 'raw';\n\nexport function LogTab({ content, isConnected, error }: LogTabProps) {\n const { t } = useTranslation('web');\n const containerRef = useRef<HTMLDivElement>(null);\n const [autoScroll, setAutoScroll] = useState(true);\n const [viewMode, setViewMode] = useState<ViewMode>('structured');\n\n const handleScroll = useCallback(() => {\n const el = containerRef.current;\n if (!el) return;\n const isAtBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 40;\n setAutoScroll(isAtBottom);\n }, []);\n\n const jumpToBottom = useCallback(() => {\n const el = containerRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n setAutoScroll(true);\n }, []);\n\n // Auto-scroll when new content arrives (only if auto-scroll is active)\n useEffect(() => {\n if (autoScroll && containerRef.current) {\n containerRef.current.scrollTop = containerRef.current.scrollHeight;\n }\n }, [content, autoScroll]);\n\n if (error) {\n return (\n <div className=\"flex items-center gap-2 p-4 text-sm text-red-600\">\n <AlertCircle className=\"h-4 w-4 shrink-0\" />\n <span>{error}</span>\n </div>\n );\n }\n\n if (!content) {\n return (\n <div className=\"flex flex-col items-center justify-center gap-2 p-8\">\n <Terminal className=\"text-muted-foreground h-8 w-8\" />\n <p className=\"text-muted-foreground text-sm\">{t('logTab.noLogOutput')}</p>\n {isConnected ? (\n <p className=\"text-muted-foreground text-xs\">Waiting for log data...</p>\n ) : null}\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full flex-col\" data-testid=\"log-tab\">\n {/* Status bar */}\n <div className=\"flex items-center gap-2 border-b px-3 py-1.5\">\n <span\n className={`h-2 w-2 rounded-full ${isConnected ? 'bg-emerald-500' : 'bg-zinc-400'}`}\n />\n <span className=\"text-muted-foreground text-xs\">\n {isConnected ? 'Live' : 'Disconnected'}\n </span>\n\n {/* View mode toggle */}\n <div className=\"ml-auto flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => setViewMode('structured')}\n className={`rounded p-1 transition-colors ${\n viewMode === 'structured'\n ? 'bg-muted text-foreground'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n title={t('logTab.structuredView')}\n >\n <FileText className=\"h-3.5 w-3.5\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setViewMode('raw')}\n className={`rounded p-1 transition-colors ${\n viewMode === 'raw'\n ? 'bg-muted text-foreground'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n title={t('logTab.rawView')}\n >\n <Code className=\"h-3.5 w-3.5\" />\n </button>\n\n {!autoScroll ? (\n <button\n type=\"button\"\n onClick={jumpToBottom}\n className=\"text-muted-foreground hover:text-foreground ms-1 flex items-center gap-1 text-xs\"\n >\n <ArrowDown className=\"h-3 w-3\" />\n Jump to bottom\n </button>\n ) : null}\n </div>\n </div>\n\n {/* Log content */}\n <div\n ref={containerRef}\n onScroll={handleScroll}\n className={`flex-1 overflow-y-auto ${\n viewMode === 'raw'\n ? 'bg-zinc-950 p-3 font-mono text-xs leading-relaxed break-all whitespace-pre-wrap text-zinc-300'\n : 'bg-background'\n }`}\n >\n {viewMode === 'structured' ? <EventLogViewer content={content} /> : content}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useState, useCallback, useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n Loader2,\n Circle,\n Check,\n Eye,\n ChevronRight,\n CheckCircle2,\n CircleDashed,\n} from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport type { PlanTaskData, ActionItemData } from '@/app/actions/get-feature-plan';\n\nexport interface TaskProgressViewProps {\n tasks: PlanTaskData[];\n}\n\nconst taskStateConfig: Record<\n string,\n {\n icon: typeof Circle;\n colorClass: string;\n borderClass: string;\n spinning?: boolean;\n label: string;\n }\n> = {\n Todo: {\n icon: Circle,\n colorClass: 'text-muted-foreground',\n borderClass: 'border-border',\n label: 'Todo',\n },\n 'Work in Progress': {\n icon: Loader2,\n colorClass: 'text-blue-600',\n borderClass: 'border-blue-200',\n spinning: true,\n label: 'In Progress',\n },\n Done: {\n icon: Check,\n colorClass: 'text-emerald-600',\n borderClass: 'border-emerald-200',\n label: 'Done',\n },\n Review: {\n icon: Eye,\n colorClass: 'text-amber-600',\n borderClass: 'border-amber-200',\n label: 'Review',\n },\n};\n\nconst defaultTaskConfig = {\n icon: Circle,\n colorClass: 'text-muted-foreground',\n borderClass: 'border-border',\n label: 'Unknown',\n};\n\nexport function TaskProgressView({ tasks }: TaskProgressViewProps) {\n const { t } = useTranslation('web');\n if (tasks.length === 0) {\n return (\n <div className=\"flex flex-col items-center justify-center gap-2 py-4\">\n <p className=\"text-muted-foreground text-sm\">{t('taskProgress.noTasksDefined')}</p>\n </div>\n );\n }\n\n return (\n <div data-testid=\"task-progress-view\" className=\"flex flex-col gap-3\">\n <ProgressSummary tasks={tasks} />\n <div data-testid=\"task-progress-list\" className=\"flex flex-col gap-2\">\n {tasks.map((task, index) => (\n <TaskCard key={task.title || `task-${index}`} task={task} index={index} />\n ))}\n </div>\n </div>\n );\n}\n\n// ── Progress Summary ─────────────────────────────────────────────────\n\nfunction ProgressSummary({ tasks }: { tasks: PlanTaskData[] }) {\n const { t } = useTranslation('web');\n const counts = useMemo(() => {\n const done = tasks.filter((t) => t.state === 'Done').length;\n const wip = tasks.filter((t) => t.state === 'Work in Progress').length;\n const review = tasks.filter((t) => t.state === 'Review').length;\n const todo = tasks.filter(\n (t) => t.state !== 'Done' && t.state !== 'Work in Progress' && t.state !== 'Review'\n ).length;\n const total = tasks.length;\n const percent = total > 0 ? Math.round((done / total) * 100) : 0;\n return { done, wip, review, todo, total, percent };\n }, [tasks]);\n\n return (\n <div data-testid=\"task-progress-summary\" className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-muted-foreground text-xs font-medium\">Task Progress</span>\n <span className=\"text-muted-foreground text-xs\">\n {counts.done} of {counts.total} done\n </span>\n </div>\n <div className=\"bg-muted h-2 w-full overflow-hidden rounded-full\">\n <div\n data-testid=\"task-progress-bar\"\n className=\"h-full rounded-full bg-emerald-500 transition-all\"\n style={{ width: `${counts.percent}%` }}\n />\n </div>\n <div className=\"flex flex-wrap gap-3\">\n {counts.done > 0 ? (\n <StatChip\n icon={Check}\n label={t('taskProgress.done')}\n count={counts.done}\n className=\"text-emerald-600\"\n />\n ) : null}\n {counts.wip > 0 ? (\n <StatChip\n icon={Loader2}\n label={t('taskProgress.inProgress')}\n count={counts.wip}\n className=\"text-blue-600\"\n />\n ) : null}\n {counts.review > 0 ? (\n <StatChip\n icon={Eye}\n label={t('taskProgress.review')}\n count={counts.review}\n className=\"text-amber-600\"\n />\n ) : null}\n {counts.todo > 0 ? (\n <StatChip\n icon={Circle}\n label={t('taskProgress.todo')}\n count={counts.todo}\n className=\"text-muted-foreground\"\n />\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction StatChip({\n icon: Icon,\n label,\n count,\n className,\n}: {\n icon: typeof Circle;\n label: string;\n count: number;\n className?: string;\n}) {\n return (\n <span className={cn('flex items-center gap-1 text-xs', className)}>\n <Icon className=\"h-3 w-3\" />\n {count} {label}\n </span>\n );\n}\n\n// ── Task Card ────────────────────────────────────────────────────────\n\nfunction TaskCard({ task, index }: { task: PlanTaskData; index: number }) {\n const [expanded, setExpanded] = useState(false);\n const config = taskStateConfig[task.state] ?? defaultTaskConfig;\n const Icon = config.icon;\n const hasDetails = task.actionItems.length > 0;\n\n const handleToggle = useCallback(() => {\n if (hasDetails) {\n setExpanded((prev) => !prev);\n }\n }, [hasDetails]);\n\n return (\n <div data-testid={`task-card-${index}`} className={cn('rounded-lg border', config.borderClass)}>\n <button\n type=\"button\"\n onClick={handleToggle}\n disabled={!hasDetails}\n className={cn(\n 'flex w-full items-start gap-2 px-3 py-2.5 text-start',\n hasDetails && 'hover:bg-muted/50 cursor-pointer transition-colors'\n )}\n >\n <Icon\n className={cn(\n 'mt-0.5 h-4 w-4 shrink-0',\n config.colorClass,\n config.spinning && 'animate-spin'\n )}\n />\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <span className={cn('text-sm font-medium', config.colorClass)}>{task.title}</span>\n {task.description ? (\n <span className=\"text-muted-foreground text-xs\">{task.description}</span>\n ) : null}\n </div>\n {hasDetails ? (\n <ChevronRight\n className={cn(\n 'text-muted-foreground mt-0.5 h-4 w-4 shrink-0 transition-transform',\n expanded && 'rotate-90'\n )}\n />\n ) : null}\n </button>\n\n {expanded && hasDetails ? (\n <div className=\"border-t px-3 py-2.5\">\n <div className=\"flex flex-col gap-2\">\n {task.actionItems.map((item, aiIndex) => (\n <ActionItemRow key={item.name || `ai-${aiIndex}`} item={item} />\n ))}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\n// ── Action Item Row ──────────────────────────────────────────────────\n\nfunction ActionItemRow({ item }: { item: ActionItemData }) {\n const totalCriteria = item.acceptanceCriteria.length;\n const verifiedCriteria = item.acceptanceCriteria.filter((ac) => ac.verified).length;\n const allVerified = totalCriteria > 0 && verifiedCriteria === totalCriteria;\n\n return (\n <div data-testid=\"action-item\" className=\"flex flex-col gap-1.5\">\n <div className=\"flex items-start gap-2\">\n {allVerified ? (\n <CheckCircle2 className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-emerald-600\" />\n ) : (\n <CircleDashed className=\"text-muted-foreground mt-0.5 h-3.5 w-3.5 shrink-0\" />\n )}\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n <span className=\"text-xs font-medium\">{item.name}</span>\n {item.description ? (\n <span className=\"text-muted-foreground text-[11px]\">{item.description}</span>\n ) : null}\n </div>\n {totalCriteria > 0 ? (\n <span className=\"text-muted-foreground ml-auto shrink-0 text-[11px]\">\n {verifiedCriteria}/{totalCriteria}\n </span>\n ) : null}\n </div>\n {totalCriteria > 0 ? (\n <div className=\"ms-5.5 flex flex-col gap-1\">\n {item.acceptanceCriteria.map((ac, acIndex) => (\n <AcceptanceCriterionRow key={ac.description || `ac-${acIndex}`} criterion={ac} />\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n\n// ── Acceptance Criterion Row ─────────────────────────────────────────\n\nfunction AcceptanceCriterionRow({\n criterion,\n}: {\n criterion: { description: string; verified: boolean };\n}) {\n return (\n <div data-testid=\"acceptance-criterion\" className=\"flex items-start gap-1.5\">\n {criterion.verified ? (\n <Check className=\"mt-0.5 h-3 w-3 shrink-0 text-emerald-600\" />\n ) : (\n <Circle className=\"text-muted-foreground mt-0.5 h-3 w-3 shrink-0\" />\n )}\n <span\n className={cn(\n 'text-[11px]',\n criterion.verified ? 'text-muted-foreground line-through' : 'text-foreground'\n )}\n >\n {criterion.description}\n </span>\n </div>\n );\n}\n","'use client';\n\nimport { Loader2 } from 'lucide-react';\nimport { AlertCircle, ListTodo } from 'lucide-react';\nimport { Badge } from '@/components/ui/badge';\nimport { TaskProgressView } from '@/components/common/task-progress-view';\nimport type { PlanData } from '@/app/actions/get-feature-plan';\n\nexport interface PlanTabProps {\n plan: PlanData | null;\n loading: boolean;\n error: string | null;\n}\n\nconst planStateBadgeStyles: Record<string, string> = {\n Requirements: 'border-transparent bg-blue-50 text-blue-700 hover:bg-blue-50',\n ClarificationRequired: 'border-transparent bg-amber-50 text-amber-700 hover:bg-amber-50',\n Ready: 'border-transparent bg-green-50 text-green-700 hover:bg-green-50',\n};\n\nexport function PlanTab({ plan, loading, error }: PlanTabProps) {\n if (loading) {\n return (\n <div data-testid=\"plan-tab-loading\" className=\"flex items-center justify-center p-8\">\n <Loader2 className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"flex items-center gap-2 p-4 text-sm text-red-600\">\n <AlertCircle className=\"h-4 w-4 shrink-0\" />\n <span>{error}</span>\n </div>\n );\n }\n\n if (!plan) {\n return (\n <div className=\"flex flex-col items-center justify-center gap-2 p-8\">\n <ListTodo className=\"text-muted-foreground h-8 w-8\" />\n <p className=\"text-muted-foreground text-sm\">No plan created yet</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-4 p-4\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-xs font-medium\">Plan State</span>\n <Badge\n className={\n planStateBadgeStyles[plan.state] ?? 'border-transparent bg-gray-50 text-gray-700'\n }\n >\n {plan.state}\n </Badge>\n </div>\n {plan.overview ? (\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-muted-foreground text-xs font-medium\">Overview</span>\n <p className=\"text-sm leading-relaxed\">{plan.overview}</p>\n </div>\n ) : null}\n <TaskProgressView tasks={plan.tasks} />\n </div>\n );\n}\n","'use client';\n\nimport { useState, useEffect, useRef, useCallback } from 'react';\n\nexport interface UseFeatureLogsResult {\n content: string;\n isConnected: boolean;\n error: string | null;\n}\n\nexport function useFeatureLogs(featureId: string | null | undefined): UseFeatureLogsResult {\n const [content, setContent] = useState('');\n const [isConnected, setIsConnected] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const eventSourceRef = useRef<EventSource | null>(null);\n\n const cleanup = useCallback(() => {\n if (eventSourceRef.current) {\n eventSourceRef.current.close();\n eventSourceRef.current = null;\n }\n setIsConnected(false);\n }, []);\n\n useEffect(() => {\n if (!featureId) {\n setContent('');\n setIsConnected(false);\n setError(null);\n return;\n }\n\n // Reset state for new featureId\n setContent('');\n setError(null);\n\n // Connect EventSource for live updates\n const es = new EventSource(`/api/feature-logs?featureId=${featureId}`);\n eventSourceRef.current = es;\n\n es.onopen = () => {\n setIsConnected(true);\n };\n\n es.addEventListener('initial', (event: MessageEvent) => {\n const data: { content: string } = JSON.parse(event.data);\n setContent(data.content);\n });\n\n es.addEventListener('log', (event: MessageEvent) => {\n const data: { content: string } = JSON.parse(event.data);\n setContent((prev) => prev + data.content);\n });\n\n es.addEventListener('error', (event: MessageEvent) => {\n try {\n const data: { error: string } = JSON.parse(event.data);\n setError(data.error);\n } catch {\n setError(event.data ? String(event.data) : 'Log stream unavailable');\n }\n });\n\n es.onerror = () => {\n setIsConnected(false);\n };\n\n return () => {\n es.close();\n eventSourceRef.current = null;\n };\n }, [featureId, cleanup]);\n\n return { content, isConnected, error };\n}\n","'use client';\n\nimport { useState, useRef, useCallback, useEffect } from 'react';\n\n/** State for a single tab's data, loading, and error. */\nexport interface TabState<T = unknown> {\n data: T | null;\n loading: boolean;\n error: string | null;\n}\n\n/** A function that fetches data for a tab given a feature ID. */\nexport type TabFetcher<T = unknown> = (featureId: string) => Promise<T>;\n\n/** Map of tab keys to their fetcher functions. */\nexport type TabFetchers<K extends string> = Record<K, TabFetcher>;\n\n/** Return type of the useTabDataFetch hook. */\nexport interface UseTabDataFetchResult<K extends string> {\n /** Per-tab state (data, loading, error). */\n tabs: Record<K, TabState>;\n /** Fetch data for a tab. Uses cache if already fetched. */\n fetchTab: (tab: K) => Promise<void>;\n /** Force re-fetch for a tab, bypassing cache. */\n refreshTab: (tab: K) => Promise<void>;\n}\n\nfunction createInitialTabState(): TabState {\n return { data: null, loading: false, error: null };\n}\n\n/**\n * Custom hook for lazy-loading tab data with per-tab caching.\n *\n * - Fetches data only when a tab is explicitly activated via fetchTab().\n * - Caches results so revisiting a loaded tab is instant.\n * - Clears all cached data when featureId changes.\n * - Supports force re-fetch via refreshTab() for SSE-driven updates.\n * - Uses ref-based callbacks to avoid stale closures (matches useArtifactFetch pattern).\n */\nexport function useTabDataFetch<K extends string>(\n featureId: string,\n fetchers: TabFetchers<K>\n): UseTabDataFetchResult<K> {\n const tabKeys = Object.keys(fetchers) as K[];\n\n const [tabStates, setTabStates] = useState<Record<K, TabState>>(() => {\n const initial = {} as Record<K, TabState>;\n for (const key of tabKeys) {\n initial[key] = createInitialTabState();\n }\n return initial;\n });\n\n // Ref-based fetchers to avoid stale closures in callbacks.\n const fetchersRef = useRef(fetchers);\n fetchersRef.current = fetchers;\n\n // Ref-based featureId to use current value in callbacks.\n const featureIdRef = useRef(featureId);\n featureIdRef.current = featureId;\n\n // Track mounted state to prevent state updates after unmount.\n const mountedRef = useRef(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n // Clear all cached data when featureId changes.\n const prevFeatureIdRef = useRef(featureId);\n useEffect(() => {\n if (prevFeatureIdRef.current !== featureId) {\n prevFeatureIdRef.current = featureId;\n setTabStates((prev) => {\n const cleared = {} as Record<K, TabState>;\n for (const key of Object.keys(prev) as K[]) {\n cleared[key] = createInitialTabState();\n }\n return cleared;\n });\n }\n }, [featureId]);\n\n const doFetch = useCallback(async (tab: K) => {\n const fetcher = fetchersRef.current[tab];\n const currentFeatureId = featureIdRef.current;\n\n if (!fetcher) return;\n\n // Only show loading spinner when there's no existing data.\n // On refresh (data already present), keep showing stale data while fetching\n // to avoid flickering the entire tab on every poll cycle.\n if (mountedRef.current) {\n setTabStates((prev) => {\n const hasData = prev[tab]?.data !== null;\n if (hasData) return prev; // Keep stale data visible — no loading flash\n return { ...prev, [tab]: { ...prev[tab], loading: true, error: null } };\n });\n }\n\n try {\n const data = await fetcher(currentFeatureId);\n if (mountedRef.current) {\n setTabStates((prev) => ({\n ...prev,\n [tab]: { data, loading: false, error: null },\n }));\n }\n } catch (error: unknown) {\n if (mountedRef.current) {\n setTabStates((prev) => {\n const message = error instanceof Error ? error.message : 'Failed to fetch tab data';\n // On refresh failure, keep existing data instead of clearing it\n const existingData = prev[tab]?.data ?? null;\n return {\n ...prev,\n [tab]: { data: existingData, loading: false, error: existingData ? null : message },\n };\n });\n }\n }\n }, []);\n\n const fetchTab = useCallback(\n async (tab: K) => {\n // Check if data is already cached (non-null data means already fetched)\n const current = tabStates[tab];\n if (current && current.data !== null) return;\n // Also skip if currently loading\n if (current && current.loading) return;\n await doFetch(tab);\n },\n [tabStates, doFetch]\n );\n\n const refreshTab = useCallback(\n async (tab: K) => {\n await doFetch(tab);\n },\n [doFetch]\n );\n\n return {\n tabs: tabStates,\n fetchTab,\n refreshTab,\n };\n}\n","'use client';\n\nimport { useState, useEffect, useCallback, useRef, useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { usePathname } from 'next/navigation';\nimport {\n Loader2,\n AlertCircle,\n LayoutDashboard,\n Activity,\n ScrollText,\n Map,\n FileCheck,\n Cpu,\n Package,\n GitMerge,\n MessageSquare,\n Play,\n Square,\n RotateCcw,\n Zap,\n Layers,\n} from 'lucide-react';\nimport type { NotificationEvent } from '@shipit-ai/core/domain/generated/output';\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\nimport { getFeaturePhaseTimings } from '@/app/actions/get-feature-phase-timings';\nimport type {\n PhaseTimingData,\n RejectionFeedbackData,\n} from '@/app/actions/get-feature-phase-timings';\nimport { getFeaturePlan } from '@/app/actions/get-feature-plan';\nimport type { PlanData } from '@/app/actions/get-feature-plan';\nimport type { FeatureNodeData } from '@/components/common/feature-node';\nimport { cn } from '@/lib/utils';\nimport { featureNodeStateConfig } from '@/components/common/feature-node';\nimport { CometSpinner } from '@/components/ui/comet-spinner';\nimport type { PrdQuestionnaireData } from '@/components/common/prd-questionnaire';\nimport type { TechDecisionsReviewData } from '@/components/common/tech-decisions-review';\nimport type { ProductDecisionsSummaryData } from '@/components/common/product-decisions-summary';\nimport type { MergeReviewData } from '@/components/common/merge-review';\nimport { PrdQuestionnaire } from '@/components/common/prd-questionnaire';\nimport { TechDecisionsContent } from '@/components/common/tech-decisions-review';\nimport { ProductDecisionsSummary } from '@/components/common/product-decisions-summary';\nimport { MergeReview } from '@/components/common/merge-review';\nimport { DrawerActionBar } from '@/components/common/drawer-action-bar';\nimport type { RejectAttachment } from '@/components/common/drawer-action-bar';\nimport { OverviewTab } from './overview-tab';\nimport { ActivityTab } from './activity-tab';\nimport { LogTab } from './log-tab';\nimport { PlanTab } from './plan-tab';\nimport { ChatTab } from '@/components/features/chat/ChatTab';\nimport { useFeatureLogs } from '@/hooks/use-feature-logs';\nimport { useTabDataFetch } from './use-tab-data-fetch';\nimport type { TabFetchers } from './use-tab-data-fetch';\nimport type { FeatureTabKey } from '@/components/common/control-center-drawer/drawer-view';\nimport type { BranchSyncData } from '@/hooks/use-branch-sync-status';\n\n/** Lazy-loaded tab keys (tabs that fetch data on activation). */\ntype LazyTabKey = 'activity' | 'plan';\n\n/** Tab definition for rendering the tab list dynamically. */\ninterface TabDef {\n key: FeatureTabKey;\n label: string;\n icon: React.ComponentType<{ className?: string }>;\n}\n\n/** All possible tabs in display order. */\nconst ALL_TABS: TabDef[] = [\n { key: 'overview', label: 'Overview', icon: LayoutDashboard },\n { key: 'activity', label: 'Activity', icon: Activity },\n { key: 'log', label: 'Log', icon: ScrollText },\n { key: 'plan', label: 'Plan', icon: Map },\n { key: 'prd-review', label: 'PRD Review', icon: FileCheck },\n { key: 'tech-decisions', label: 'Tech Decisions', icon: Cpu },\n { key: 'product-decisions', label: 'Product', icon: Package },\n { key: 'merge-review', label: 'Merge Review', icon: GitMerge },\n { key: 'chat', label: 'Chat', icon: MessageSquare },\n];\n\n/** Compute which tabs are visible based on feature lifecycle + state. */\nfunction computeVisibleTabs(\n node: FeatureNodeData,\n interactiveAgentEnabled = true\n): FeatureTabKey[] {\n const tabs: FeatureTabKey[] = ['overview', 'activity'];\n\n if (node.hasAgentRun) {\n tabs.push('log');\n }\n\n if (node.hasPlan) {\n tabs.push('plan');\n }\n if (node.lifecycle === 'requirements' && node.state === 'action-required') {\n tabs.push('prd-review');\n }\n if (node.lifecycle === 'implementation' && node.state === 'action-required') {\n tabs.push('tech-decisions', 'product-decisions');\n }\n if (node.lifecycle === 'review' && (node.state === 'action-required' || node.state === 'error')) {\n tabs.push('merge-review');\n }\n if (node.lifecycle === 'maintain' && node.pr) {\n tabs.push('merge-review');\n }\n\n // Chat tab is visible for ALL lifecycle phases when interactive agent is enabled\n if (interactiveAgentEnabled) {\n tabs.push('chat');\n }\n\n return tabs;\n}\n\nexport interface FeatureDrawerTabsProps {\n /** Feature name rendered in the inline header. */\n featureName?: string;\n /** Additional header content (repo info, actions) rendered below the title row. */\n headerContent?: React.ReactNode;\n featureNode: FeatureNodeData;\n featureId: string;\n /** Action handlers for the status chip in the title row. */\n onRetry?: (featureId: string) => void;\n onStop?: (featureId: string) => void;\n onStart?: (featureId: string) => void;\n initialTab?: FeatureTabKey;\n /** Tab key from URL path segment (e.g. /feature/[id]/activity → 'activity'). */\n urlTab?: FeatureTabKey;\n /** SSE events from the agent events provider, used to trigger tab data refresh. */\n sseEvents?: readonly NotificationEvent[];\n\n // PRD review\n prdData?: PrdQuestionnaireData | null;\n prdSelections?: Record<string, string>;\n onPrdSelect?: (questionId: string, optionId: string) => void;\n onPrdApprove?: (actionId: string) => void;\n onPrdReject?: (feedback: string, attachments: RejectAttachment[]) => void;\n isPrdLoading?: boolean;\n\n // Tech decisions\n techData?: TechDecisionsReviewData | null;\n onTechApprove?: () => void;\n onTechReject?: (feedback: string, attachments: RejectAttachment[]) => void;\n isTechLoading?: boolean;\n\n // Product decisions\n productData?: ProductDecisionsSummaryData | null;\n\n // Merge review\n mergeData?: MergeReviewData | null;\n onMergeApprove?: () => void;\n onMergeReject?: (feedback: string, attachments: RejectAttachment[]) => void;\n isMergeLoading?: boolean;\n\n // Branch sync\n syncStatus?: BranchSyncData | null;\n syncLoading?: boolean;\n syncError?: string | null;\n onRefreshSync?: () => void;\n\n // Rebase\n onRebaseOnMain?: () => void;\n rebaseLoading?: boolean;\n rebaseError?: string | null;\n\n // Shared\n isRejecting?: boolean;\n chatInput?: string;\n onChatInputChange?: (value: string) => void;\n\n // Interactive agent\n /** When false, the Chat tab is hidden from the tab bar (FR-17). Defaults to true. */\n interactiveAgentEnabled?: boolean;\n}\n\ninterface ActivityData {\n timings: PhaseTimingData[];\n rejectionFeedback: RejectionFeedbackData[];\n}\n\nasync function fetchActivity(featureId: string): Promise<ActivityData> {\n const result = await getFeaturePhaseTimings(featureId);\n if ('error' in result) throw new Error(result.error);\n return { timings: result.timings, rejectionFeedback: result.rejectionFeedback };\n}\n\nasync function fetchPlan(featureId: string): Promise<PlanData | undefined> {\n const result = await getFeaturePlan(featureId);\n if ('error' in result) throw new Error(result.error);\n return result.plan;\n}\n\nconst TAB_FETCHERS: TabFetchers<LazyTabKey> = {\n activity: fetchActivity,\n plan: fetchPlan,\n};\n\nexport function FeatureDrawerTabs({\n featureName,\n headerContent,\n featureNode,\n featureId,\n initialTab,\n urlTab,\n prdData,\n prdSelections,\n onPrdSelect,\n onPrdApprove,\n onPrdReject,\n isPrdLoading,\n techData,\n onTechApprove,\n onTechReject,\n isTechLoading,\n productData,\n mergeData,\n onMergeApprove,\n onMergeReject,\n isMergeLoading,\n syncStatus,\n syncLoading,\n syncError,\n onRefreshSync,\n onRebaseOnMain,\n rebaseLoading,\n rebaseError,\n isRejecting,\n chatInput,\n onChatInputChange,\n sseEvents,\n interactiveAgentEnabled = true,\n onRetry,\n onStop,\n onStart,\n}: FeatureDrawerTabsProps) {\n const pathname = usePathname();\n\n const visibleTabs = useMemo(\n () => computeVisibleTabs(featureNode, interactiveAgentEnabled),\n [featureNode, interactiveAgentEnabled]\n );\n const visibleTabDefs = useMemo(\n () =>\n ALL_TABS.filter((t) => visibleTabs.includes(t.key)).map((t) =>\n t.key === 'merge-review' && featureNode.lifecycle === 'maintain'\n ? { ...t, label: 'Merge History' }\n : t\n ),\n [visibleTabs, featureNode.lifecycle]\n );\n\n // Derive the base path (without tab segment) from the current pathname.\n // e.g. /feature/abc123/activity → /feature/abc123\n const basePath = useMemo(() => {\n const match = pathname.match(/^(\\/feature\\/[^/]+)/);\n return match ? match[1] : pathname;\n }, [pathname]);\n\n // Resolve the effective initial tab: URL path tab > initialTab prop > 'overview'\n const effectiveInitial = useMemo(() => {\n if (urlTab && visibleTabs.includes(urlTab)) return urlTab;\n if (initialTab && visibleTabs.includes(initialTab)) return initialTab;\n return 'overview';\n // Only compute on mount — subsequent changes are handled by effects below\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n const [activeTab, setActiveTab] = useState<FeatureTabKey>(effectiveInitial);\n\n // Only subscribe to log SSE when the log tab is active to avoid\n // opening an EventSource connection on every drawer open.\n const featureLogs = useFeatureLogs(activeTab === 'log' ? featureId : null);\n\n const { tabs, fetchTab, refreshTab } = useTabDataFetch<LazyTabKey>(featureId, TAB_FETCHERS);\n\n // Sync URL when active tab changes via user interaction.\n // Use window.history.pushState instead of router.push to avoid triggering a\n // server component re-render (which would remount the drawer).\n const isUserInteraction = useRef(false);\n useEffect(() => {\n if (!isUserInteraction.current) return;\n isUserInteraction.current = false;\n\n // Build the target URL from the base path + tab segment\n const targetUrl = activeTab === 'overview' ? basePath : `${basePath}/${activeTab}`;\n // Only update URL if it actually changed\n if (targetUrl !== pathname) {\n window.history.pushState(null, '', targetUrl);\n }\n }, [activeTab, basePath, pathname]);\n\n // Sync active tab from URL when pathname changes (e.g. browser back/forward).\n // Skip on initial mount — the effectiveInitial handles that via urlTab prop.\n const prevPathnameRef = useRef(pathname);\n useEffect(() => {\n if (prevPathnameRef.current === pathname) return; // Skip initial mount\n prevPathnameRef.current = pathname;\n if (isUserInteraction.current) return; // Skip — this is our own navigation\n const segments = pathname.split('/');\n // pathname is /feature/[id] or /feature/[id]/[tab]\n const pathTab = segments.length >= 4 ? (segments[3] as FeatureTabKey) : undefined;\n const resolved = pathTab && visibleTabs.includes(pathTab) ? pathTab : 'overview';\n if (resolved !== activeTab) {\n setActiveTab(resolved as FeatureTabKey);\n if (resolved === 'activity' || resolved === 'plan') {\n fetchTab(resolved as LazyTabKey);\n }\n }\n }, [pathname]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // On mount, sync the URL to reflect the effective initial tab when it was\n // derived from feature state (initialTab) rather than from the URL (urlTab).\n // Use replaceState so we don't add a duplicate history entry.\n const initialSyncDone = useRef(false);\n useEffect(() => {\n if (initialSyncDone.current) return;\n initialSyncDone.current = true;\n // Only sync if the effective tab came from initialTab (not from URL)\n if (!urlTab && effectiveInitial !== 'overview') {\n const targetUrl = `${basePath}/${effectiveInitial}`;\n if (targetUrl !== pathname) {\n window.history.replaceState(null, '', targetUrl);\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Trigger lazy fetch for URL-driven initial tab\n const initialFetchDone = useRef(false);\n useEffect(() => {\n if (initialFetchDone.current) return;\n initialFetchDone.current = true;\n if (activeTab === 'activity' || activeTab === 'plan') {\n fetchTab(activeTab);\n }\n }, [activeTab, fetchTab]);\n\n // Reset tab when featureId changes\n const prevFeatureIdRef = useRef(featureId);\n useEffect(() => {\n if (prevFeatureIdRef.current !== featureId) {\n prevFeatureIdRef.current = featureId;\n setActiveTab('overview');\n }\n }, [featureId]);\n\n // When initialTab changes (e.g. SSE updates lifecycle), switch to it if visible\n // and sync the URL with replaceState so the address bar reflects the new tab.\n // Also trigger lazy fetch for the new tab so data is ready immediately.\n const prevInitialTabRef = useRef(initialTab);\n useEffect(() => {\n if (\n prevInitialTabRef.current !== initialTab &&\n initialTab &&\n visibleTabs.includes(initialTab)\n ) {\n prevInitialTabRef.current = initialTab;\n setActiveTab(initialTab);\n // Trigger lazy fetch for the new tab if it's a lazy-loaded tab\n if (initialTab === 'activity' || initialTab === 'plan') {\n fetchTab(initialTab as LazyTabKey);\n }\n // Sync URL to match the new tab\n const targetUrl = initialTab === 'overview' ? basePath : `${basePath}/${initialTab}`;\n if (targetUrl !== window.location.pathname) {\n window.history.replaceState(null, '', targetUrl);\n }\n }\n }, [initialTab, visibleTabs, basePath, fetchTab]);\n\n // If the active tab becomes invisible (lifecycle changed), fall back to overview\n // and sync the URL accordingly.\n useEffect(() => {\n if (!visibleTabs.includes(activeTab)) {\n setActiveTab('overview');\n if (window.location.pathname !== basePath) {\n window.history.replaceState(null, '', basePath);\n }\n }\n }, [visibleTabs, activeTab, basePath]);\n\n // SSE refresh: re-fetch lazy tab data when relevant SSE events arrive\n // for this feature (e.g. PhaseCompleted, AgentStarted, AgentCompleted).\n // Always refresh 'activity' data (even if not the active tab) so switching\n // to the activity tab shows up-to-date timings without a loading flash.\n const activeTabRef = useRef(activeTab);\n activeTabRef.current = activeTab;\n const sseProcessedRef = useRef(0);\n\n useEffect(() => {\n if (!sseEvents || sseEvents.length === 0) return;\n // Clamp cursor if events were pruned\n if (sseProcessedRef.current > sseEvents.length) {\n sseProcessedRef.current = 0;\n }\n if (sseEvents.length <= sseProcessedRef.current) return;\n\n const newEvents = sseEvents.slice(sseProcessedRef.current);\n sseProcessedRef.current = sseEvents.length;\n\n const hasRelevantEvent = newEvents.some((e) => e.featureId === featureId);\n if (!hasRelevantEvent) return;\n\n // Always refresh activity data so it stays current for when the user switches tabs\n refreshTab('activity' as LazyTabKey);\n\n const current = activeTabRef.current;\n if (current === 'plan') {\n refreshTab(current);\n }\n }, [sseEvents, featureId, refreshTab]);\n\n // Poll activity data while the feature is actively running.\n // SSE events only fire on state transitions (phase completed, lifecycle changed),\n // so during a long-running phase there are no events and the data goes stale.\n // Poll every 5s when the feature is in a working state to keep data fresh.\n const isFeatureActive = featureNode.state === 'running' || featureNode.state === 'creating';\n useEffect(() => {\n if (!isFeatureActive) return;\n const interval = setInterval(() => {\n refreshTab('activity' as LazyTabKey);\n }, 5000);\n return () => clearInterval(interval);\n }, [isFeatureActive, refreshTab]);\n\n const handleTabChange = useCallback(\n (value: string) => {\n const tab = value as FeatureTabKey;\n isUserInteraction.current = true;\n setActiveTab(tab);\n if (tab === 'activity' || tab === 'plan') {\n fetchTab(tab);\n }\n },\n [fetchTab]\n );\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <Tabs\n value={activeTab}\n onValueChange={handleTabChange}\n className=\"flex min-h-0 flex-1 flex-col\"\n >\n {/* VS Code-style tab bar — first row */}\n <TabsList className=\"bg-muted/50 h-auto w-full shrink-0 justify-start gap-0 rounded-none border-b p-0\">\n {visibleTabDefs.map((tab) => {\n const Icon = tab.icon;\n return (\n <TabsTrigger\n key={tab.key}\n value={tab.key}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:border-t-primary [&:not([data-state=active])]:border-r-border relative h-auto rounded-none border-t-2 border-r border-t-transparent border-r-transparent bg-transparent px-3.5 py-2.5 text-[13px] font-normal shadow-none transition-none last:border-r-transparent data-[state=active]:shadow-none\"\n >\n <Icon className=\"mr-1.5 size-4\" />\n {tab.label}\n </TabsTrigger>\n );\n })}\n </TabsList>\n {/* Persistent header — contrasting background */}\n <div className=\"bg-muted/40 shrink-0 border-b\">\n {/* Feature / repo + status chip */}\n {featureName ? (\n <div\n className=\"flex h-12 items-stretch gap-2 pr-0 pl-4\"\n data-testid=\"feature-drawer-header\"\n >\n {/* Fast/SDLC icon */}\n <div className=\"flex items-center\">\n {featureNode.fastMode ? (\n <Zap className=\"size-4 shrink-0 text-amber-500\" />\n ) : (\n <Layers className=\"text-muted-foreground/50 size-4 shrink-0\" />\n )}\n </div>\n {/* Feature name */}\n <h2 className=\"text-foreground flex min-w-0 items-center truncate text-base font-semibold tracking-tight\">\n {featureName}\n </h2>\n {/* / repo */}\n {featureNode.repositoryName ? (\n <span className=\"animate-in fade-in flex shrink-0 items-center gap-1.5 self-center duration-200\">\n <span className=\"text-muted-foreground/30 text-sm\">/</span>\n {featureNode.remoteUrl ? (\n <a\n href={featureNode.remoteUrl as string}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-muted-foreground hover:text-foreground text-sm\"\n >\n {featureNode.repositoryName}\n </a>\n ) : (\n <span className=\"text-muted-foreground text-sm\">\n {featureNode.repositoryName}\n </span>\n )}\n </span>\n ) : (\n <span className=\"flex items-center gap-1.5 self-center\">\n <span className=\"text-muted-foreground/30 text-sm\">/</span>\n <span className=\"bg-muted h-4 w-16 animate-pulse rounded\" />\n </span>\n )}\n\n {/* Status chip + action button */}\n <TooltipProvider delayDuration={300}>\n <Tooltip>\n <TooltipTrigger asChild>\n <div className=\"ml-auto flex shrink-0 cursor-default items-center self-stretch text-xs font-medium\">\n <div\n className={cn(\n 'flex items-center gap-1.5 self-stretch px-3',\n featureNodeStateConfig[featureNode.state].labelClass\n )}\n >\n {featureNode.state === 'running' ? (\n <CometSpinner size=\"sm\" className=\"shrink-0\" />\n ) : (\n (() => {\n const I = featureNodeStateConfig[featureNode.state].icon;\n return <I className=\"size-3.5 shrink-0\" />;\n })()\n )}\n {featureNodeStateConfig[featureNode.state].label}\n </div>\n {/* Inline action button */}\n {featureNode.state === 'pending' && onStart ? (\n <button\n type=\"button\"\n onClick={() => onStart(featureNode.featureId)}\n className=\"text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-green-500/10 hover:text-green-600 dark:hover:text-green-400\"\n data-testid=\"feature-drawer-start-button\"\n >\n <Play className=\"size-3.5\" /> Start\n </button>\n ) : featureNode.state === 'error' && onRetry ? (\n <button\n type=\"button\"\n onClick={() => onRetry(featureNode.featureId)}\n className=\"text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-red-500/10 hover:text-red-500 dark:hover:text-red-400\"\n data-testid=\"feature-drawer-retry-button\"\n >\n <RotateCcw className=\"size-3.5\" /> Retry\n </button>\n ) : featureNode.state === 'running' && onStop ? (\n <button\n type=\"button\"\n onClick={() => onStop(featureNode.featureId)}\n className=\"text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-red-500/10 hover:text-red-500 dark:hover:text-red-400\"\n data-testid=\"feature-drawer-stop-button\"\n >\n <Square className=\"size-3.5\" /> Stop\n </button>\n ) : null}\n </div>\n </TooltipTrigger>\n {featureNode.errorMessage ? (\n <TooltipContent\n side=\"bottom\"\n align=\"end\"\n sideOffset={4}\n className=\"z-[100] max-w-xs cursor-pointer text-xs leading-relaxed select-text\"\n onClick={() => {\n void navigator.clipboard.writeText(featureNode.errorMessage!);\n }}\n >\n {featureNode.errorMessage}\n <span className=\"text-muted-foreground ml-1 text-[10px] italic\">\n (click to copy)\n </span>\n </TooltipContent>\n ) : null}\n </Tooltip>\n </TooltipProvider>\n </div>\n ) : null}\n {/* IDE toolbar */}\n {headerContent}\n </div>\n\n <TabsContent value=\"overview\" className=\"mt-0 flex-1 overflow-y-auto\">\n <OverviewTab\n data={featureNode}\n syncStatus={syncStatus}\n syncLoading={syncLoading}\n syncError={syncError}\n onRefreshSync={onRefreshSync}\n onRebaseOnMain={onRebaseOnMain}\n rebaseLoading={rebaseLoading}\n rebaseError={rebaseError}\n />\n </TabsContent>\n\n <TabsContent value=\"activity\" className=\"mt-0 flex-1 overflow-y-auto\">\n <ActivityTab\n timings={(tabs.activity.data as ActivityData | null)?.timings ?? null}\n loading={tabs.activity.loading}\n error={tabs.activity.error}\n rejectionFeedback={(tabs.activity.data as ActivityData | null)?.rejectionFeedback}\n />\n </TabsContent>\n\n <TabsContent value=\"log\" className=\"mt-0 flex-1 overflow-hidden\">\n <LogTab\n content={featureLogs.content}\n isConnected={featureLogs.isConnected}\n error={featureLogs.error}\n />\n </TabsContent>\n\n <TabsContent value=\"plan\" className=\"mt-0 flex-1 overflow-y-auto\">\n <PlanTab\n plan={tabs.plan.data as PlanData | null}\n loading={tabs.plan.loading}\n error={tabs.plan.error}\n />\n </TabsContent>\n\n {/* PRD Review tab */}\n {visibleTabs.includes('prd-review') ? (\n <TabsContent value=\"prd-review\" className=\"mt-0 flex min-h-0 flex-1 flex-col\">\n {prdData ? (\n <PrdQuestionnaire\n data={prdData}\n selections={prdSelections ?? {}}\n onSelect={onPrdSelect ?? (() => undefined)}\n onApprove={onPrdApprove ?? (() => undefined)}\n onReject={onPrdReject}\n isProcessing={isPrdLoading}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={onChatInputChange}\n />\n ) : (\n <div className=\"flex items-center justify-center p-8\">\n <Loader2 className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n </div>\n )}\n </TabsContent>\n ) : null}\n\n {/* Tech Decisions tab */}\n {visibleTabs.includes('tech-decisions') ? (\n <TabsContent value=\"tech-decisions\" className=\"mt-0 flex min-h-0 flex-1 flex-col\">\n {techData ? (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"flex-1 overflow-y-auto\">\n <TechDecisionsContent data={techData} />\n </div>\n <DrawerActionBarForTech\n onApprove={onTechApprove ?? (() => undefined)}\n onReject={onTechReject}\n isProcessing={isTechLoading}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={onChatInputChange}\n />\n </div>\n ) : (\n <div className=\"flex items-center justify-center p-8\">\n <Loader2 className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n </div>\n )}\n </TabsContent>\n ) : null}\n\n {/* Product Decisions tab */}\n {visibleTabs.includes('product-decisions') ? (\n <TabsContent value=\"product-decisions\" className=\"mt-0 flex-1 overflow-y-auto\">\n {productData === null ? (\n <div className=\"flex items-center justify-center p-8\">\n <Loader2 className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n </div>\n ) : productData ? (\n <ProductDecisionsSummary data={productData} />\n ) : (\n <p className=\"text-muted-foreground p-4 text-center text-sm\">\n No product decisions available.\n </p>\n )}\n </TabsContent>\n ) : null}\n\n {/* Merge Review tab */}\n {visibleTabs.includes('merge-review') ? (\n <TabsContent value=\"merge-review\" className=\"mt-0 flex min-h-0 flex-1 flex-col\">\n {mergeData ? (\n <MergeReview\n data={mergeData}\n readOnly={featureNode.lifecycle === 'maintain'}\n onApprove={onMergeApprove ?? (() => undefined)}\n onReject={onMergeReject}\n isProcessing={isMergeLoading}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={onChatInputChange}\n />\n ) : (\n <div className=\"flex items-center justify-center p-8\">\n {isMergeLoading ? (\n <Loader2 className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n ) : (\n <div className=\"text-muted-foreground flex flex-col items-center gap-2 text-sm\">\n <AlertCircle className=\"h-6 w-6\" />\n <span>Merge review data unavailable</span>\n </div>\n )}\n </div>\n )}\n </TabsContent>\n ) : null}\n\n {/* Chat tab — always visible when interactive agent is enabled (FR-1, FR-17) */}\n {visibleTabs.includes('chat') ? (\n <TabsContent value=\"chat\" className=\"mt-0 flex min-h-0 flex-1 flex-col overflow-hidden\">\n <ChatTab featureId={featureId} worktreePath={featureNode.worktreePath} />\n </TabsContent>\n ) : null}\n </Tabs>\n </div>\n );\n}\n\n// ── Private helper ──────────────────────────────────────────────────────\n\nfunction DrawerActionBarForTech({\n onApprove,\n onReject,\n isProcessing,\n isRejecting,\n chatInput,\n onChatInputChange,\n}: {\n onApprove: () => void;\n onReject?: (feedback: string, attachments: RejectAttachment[]) => void;\n isProcessing?: boolean;\n isRejecting?: boolean;\n chatInput?: string;\n onChatInputChange?: (value: string) => void;\n}) {\n const { t } = useTranslation('web');\n return (\n <DrawerActionBar\n onReject={onReject}\n onApprove={onApprove}\n approveLabel={t('featureDrawer.approvePlan')}\n revisionPlaceholder=\"Ask AI to revise the plan...\"\n isProcessing={isProcessing}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={onChatInputChange}\n />\n );\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"40e1f25087a7ea01b451899611d66d390ec6bbcedc\":{\"name\":\"rebaseFeature\"}},\"src/presentation/web/app/actions/rebase-feature.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"40e1f25087a7ea01b451899611d66d390ec6bbcedc\",callServer,void 0,findSourceMapURL,\"rebaseFeature\");export{$$RSC_SERVER_ACTION_0 as rebaseFeature};","'use client';\n\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport { openIde } from '@/app/actions/open-ide';\nimport { openShell } from '@/app/actions/open-shell';\nimport { openFolder } from '@/app/actions/open-folder';\nimport { rebaseFeature } from '@/app/actions/rebase-feature';\n\nexport interface FeatureActionsInput {\n featureId: string;\n repositoryPath: string;\n branch: string;\n worktreePath?: string;\n specPath?: string;\n}\n\nexport interface FeatureActionsState {\n openInIde: () => Promise<void>;\n openInShell: () => Promise<void>;\n openFolder: () => Promise<void>;\n openSpecsFolder: () => Promise<void>;\n rebaseOnMain: () => Promise<void>;\n ideLoading: boolean;\n shellLoading: boolean;\n folderLoading: boolean;\n specsLoading: boolean;\n rebaseLoading: boolean;\n ideError: string | null;\n shellError: string | null;\n folderError: string | null;\n specsError: string | null;\n rebaseError: string | null;\n}\n\nconst ERROR_CLEAR_DELAY = 5000;\n\nexport function useFeatureActions(input: FeatureActionsInput | null): FeatureActionsState {\n const [ideLoading, setIdeLoading] = useState(false);\n const [shellLoading, setShellLoading] = useState(false);\n const [folderLoading, setFolderLoading] = useState(false);\n const [specsLoading, setSpecsLoading] = useState(false);\n const [rebaseLoading, setRebaseLoading] = useState(false);\n const [ideError, setIdeError] = useState<string | null>(null);\n const [shellError, setShellError] = useState<string | null>(null);\n const [folderError, setFolderError] = useState<string | null>(null);\n const [specsError, setSpecsError] = useState<string | null>(null);\n const [rebaseError, setRebaseError] = useState<string | null>(null);\n\n const ideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const shellTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const folderTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const specsTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const rebaseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Clear timers on unmount — read .current inside cleanup so we get the\n // actual timer value at teardown time, not the always-null value at mount.\n useEffect(() => {\n const refs = [ideTimerRef, shellTimerRef, folderTimerRef, specsTimerRef, rebaseTimerRef];\n return () => {\n for (const ref of refs) {\n if (ref.current) clearTimeout(ref.current);\n }\n };\n }, []);\n\n const performAction = useCallback(\n async (\n action: (input: { repositoryPath: string; branch?: string }) => Promise<{\n success: boolean;\n error?: string;\n }>,\n setLoading: (v: boolean) => void,\n setError: (v: string | null) => void,\n timerRef: React.RefObject<ReturnType<typeof setTimeout> | null>,\n isLoading: boolean\n ) => {\n if (!input || isLoading) return;\n\n // Clear any existing timer\n if (timerRef.current) clearTimeout(timerRef.current);\n\n setLoading(true);\n setError(null);\n\n try {\n const result = await action({\n repositoryPath: input.repositoryPath,\n branch: input.branch,\n });\n\n if (!result.success) {\n const errorMessage = result.error ?? 'An unexpected error occurred';\n setError(errorMessage);\n timerRef.current = setTimeout(() => setError(null), ERROR_CLEAR_DELAY);\n }\n } catch (err: unknown) {\n const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';\n setError(errorMessage);\n timerRef.current = setTimeout(() => setError(null), ERROR_CLEAR_DELAY);\n } finally {\n setLoading(false);\n }\n },\n [input]\n );\n\n const handleOpenIde = useCallback(\n () => performAction(openIde, setIdeLoading, setIdeError, ideTimerRef, ideLoading),\n [performAction, ideLoading]\n );\n\n const handleOpenShell = useCallback(\n () => performAction(openShell, setShellLoading, setShellError, shellTimerRef, shellLoading),\n [performAction, shellLoading]\n );\n\n const handleOpenFolder = useCallback(async () => {\n if (!input || folderLoading) return;\n\n if (folderTimerRef.current) clearTimeout(folderTimerRef.current);\n\n setFolderLoading(true);\n setFolderError(null);\n\n try {\n const folderPath = input.worktreePath ?? input.repositoryPath;\n const result = await openFolder(folderPath);\n\n if (!result.success) {\n const errorMessage = result.error ?? 'An unexpected error occurred';\n setFolderError(errorMessage);\n folderTimerRef.current = setTimeout(() => setFolderError(null), ERROR_CLEAR_DELAY);\n }\n } catch (err: unknown) {\n const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';\n setFolderError(errorMessage);\n folderTimerRef.current = setTimeout(() => setFolderError(null), ERROR_CLEAR_DELAY);\n } finally {\n setFolderLoading(false);\n }\n }, [input, folderLoading]);\n\n const handleOpenSpecsFolder = useCallback(async () => {\n if (!input?.specPath || specsLoading) return;\n\n if (specsTimerRef.current) clearTimeout(specsTimerRef.current);\n\n setSpecsLoading(true);\n setSpecsError(null);\n\n try {\n const result = await openFolder(input.specPath);\n\n if (!result.success) {\n const errorMessage = result.error ?? 'An unexpected error occurred';\n setSpecsError(errorMessage);\n specsTimerRef.current = setTimeout(() => setSpecsError(null), ERROR_CLEAR_DELAY);\n }\n } catch (err: unknown) {\n const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';\n setSpecsError(errorMessage);\n specsTimerRef.current = setTimeout(() => setSpecsError(null), ERROR_CLEAR_DELAY);\n } finally {\n setSpecsLoading(false);\n }\n }, [input, specsLoading]);\n\n const handleRebaseOnMain = useCallback(async () => {\n if (!input?.featureId || rebaseLoading) return;\n\n if (rebaseTimerRef.current) clearTimeout(rebaseTimerRef.current);\n\n setRebaseLoading(true);\n setRebaseError(null);\n\n try {\n const result = await rebaseFeature(input.featureId);\n\n if (!result.success) {\n const errorMessage = result.error ?? 'An unexpected error occurred';\n setRebaseError(errorMessage);\n rebaseTimerRef.current = setTimeout(() => setRebaseError(null), ERROR_CLEAR_DELAY);\n }\n } catch (err: unknown) {\n const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';\n setRebaseError(errorMessage);\n rebaseTimerRef.current = setTimeout(() => setRebaseError(null), ERROR_CLEAR_DELAY);\n } finally {\n setRebaseLoading(false);\n }\n }, [input, rebaseLoading]);\n\n return {\n openInIde: handleOpenIde,\n openInShell: handleOpenShell,\n openFolder: handleOpenFolder,\n openSpecsFolder: handleOpenSpecsFolder,\n rebaseOnMain: handleRebaseOnMain,\n ideLoading,\n shellLoading,\n folderLoading,\n specsLoading,\n rebaseLoading,\n ideError,\n shellError,\n folderError,\n specsError,\n rebaseError,\n };\n}\n","'use client';\n\nimport { useState, useEffect, useRef } from 'react';\nimport { toast } from 'sonner';\n\n/**\n * Generic hook for fetching drawer artifact data when a feature ID changes.\n * Handles loading state, cancellation on unmount/re-fetch, and error toasting.\n *\n * @param featureId - The feature ID to fetch for, or null to reset.\n * @param fetcher - Async function that fetches the artifact data.\n * @param onSuccess - Called with the fetch result when successful and not cancelled.\n * @param onReset - Called immediately when featureId changes (before fetching).\n * @param errorMessage - Optional toast message shown on fetch failure.\n * @param refreshKey - Optional key that forces a re-fetch when it changes (even if featureId is the same).\n * @returns Whether the fetch is currently in progress.\n */\nexport function useArtifactFetch<TResult>(\n featureId: string | null,\n fetcher: (id: string) => Promise<TResult>,\n onSuccess: (result: TResult) => void,\n onReset: () => void,\n errorMessage?: string,\n refreshKey?: number\n): boolean {\n const [isLoading, setIsLoading] = useState(false);\n\n // Use refs to avoid stale callbacks in the effect without triggering re-runs.\n const onSuccessRef = useRef(onSuccess);\n const onResetRef = useRef(onReset);\n onSuccessRef.current = onSuccess;\n onResetRef.current = onReset;\n\n useEffect(() => {\n onResetRef.current();\n if (!featureId) return;\n\n let cancelled = false;\n setIsLoading(true);\n\n fetcher(featureId)\n .then((result) => {\n if (!cancelled) onSuccessRef.current(result);\n })\n .catch(() => {\n if (!cancelled && errorMessage) toast.error(errorMessage);\n })\n .finally(() => {\n if (!cancelled) setIsLoading(false);\n });\n\n return () => {\n cancelled = true;\n };\n }, [featureId, fetcher, errorMessage, refreshKey]);\n\n return isLoading;\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"40d3dcb1ea4ccb484109d5d26154b3603cd0e7539f\":{\"name\":\"getFeatureDrawerData\"}},\"src/presentation/web/app/actions/get-feature-drawer-data.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"40d3dcb1ea4ccb484109d5d26154b3603cd0e7539f\",callServer,void 0,findSourceMapURL,\"getFeatureDrawerData\");export{$$RSC_SERVER_ACTION_0 as getFeatureDrawerData};","'use client';\n\nimport { useState, useCallback, useEffect, useRef } from 'react';\nimport { cn } from '@/lib/utils';\nimport { useTranslation } from 'react-i18next';\nimport { useRouter, usePathname } from 'next/navigation';\nimport { toast } from 'sonner';\nimport { Loader2, Trash2, Play, Square, Copy, Check, Archive, ArchiveRestore } from 'lucide-react';\nimport type {\n PrdApprovalPayload,\n QuestionSelectionChange,\n} from '@shipit-ai/core/domain/generated/output';\nimport { approveFeature } from '@/app/actions/approve-feature';\nimport { resumeFeature } from '@/app/actions/resume-feature';\nimport { startFeature } from '@/app/actions/start-feature';\nimport { stopFeature } from '@/app/actions/stop-feature';\nimport { rejectFeature } from '@/app/actions/reject-feature';\nimport type { RejectAttachment } from '@/components/common/drawer-action-bar';\nimport { getFeatureArtifact } from '@/app/actions/get-feature-artifact';\nimport { getResearchArtifact } from '@/app/actions/get-research-artifact';\nimport { getMergeReviewData } from '@/app/actions/get-merge-review-data';\nimport { useFeatureFlags } from '@/hooks/feature-flags-context';\nimport { useSoundAction } from '@/hooks/use-sound-action';\nimport { useGuardedDrawerClose } from '@/hooks/drawer-close-guard';\nimport { useDeployAction } from '@/hooks/use-deploy-action';\nimport { useAgentEventsContext } from '@/hooks/agent-events-provider';\nimport { BaseDrawer } from '@/components/common/base-drawer';\nimport { DeploymentStatusBadge } from '@/components/common/deployment-status-badge';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\nimport { DeleteFeatureDialog } from '@/components/common/delete-feature-dialog';\nimport { OpenActionMenu } from '@/components/common/open-action-menu';\nimport { FeatureDrawerTabs } from '@/components/common/feature-drawer-tabs';\nimport { useFeatureActions } from '@/components/common/feature-drawer/use-feature-actions';\nimport type { PrdQuestionnaireData } from '@/components/common/prd-questionnaire';\nimport type { TechDecisionsReviewData } from '@/components/common/tech-decisions-review';\nimport type { ProductDecisionsSummaryData } from '@/components/common/product-decisions-summary';\nimport type { MergeReviewData } from '@/components/common/merge-review';\nimport { resolveSseEventUpdates } from '@/components/common/feature-node/derive-feature-state';\nimport { deriveInitialTab } from './drawer-view';\nimport type { DrawerView, FeatureTabKey } from './drawer-view';\nimport { useArtifactFetch } from './use-artifact-fetch';\nimport { useDrawerSync } from './use-drawer-sync';\nimport { useBranchSyncStatus } from '@/hooks/use-branch-sync-status';\n\nexport interface FeatureDrawerClientProps {\n view: DrawerView;\n /** Tab key extracted from the URL path segment (e.g. /feature/[id]/activity → 'activity'). */\n urlTab?: FeatureTabKey;\n /** When false, the Chat tab is hidden from the tab bar (FR-17). Defaults to true. */\n interactiveAgentEnabled?: boolean;\n}\n\nexport function FeatureDrawerClient({\n view: initialView,\n urlTab,\n interactiveAgentEnabled = true,\n}: FeatureDrawerClientProps) {\n const featureFlags = useFeatureFlags();\n const { t } = useTranslation('web');\n const router = useRouter();\n const rejectSound = useSoundAction('reject');\n\n // Track the view locally so SSE events can update the drawer type in real-time\n const [view, setView] = useState(initialView);\n\n // Sync when server re-renders with new props (e.g. after navigation).\n // When reopening the SAME feature, merge server data into the existing view\n // to preserve enriched fields (repositoryName, baseBranch, oneLiner, remoteUrl)\n // that useDrawerSync added but the minimal server component doesn't provide.\n useEffect(() => {\n setView((prev) => {\n if (\n prev.type === 'feature' &&\n initialView.type === 'feature' &&\n prev.node.featureId === initialView.node.featureId\n ) {\n return {\n ...initialView,\n node: { ...prev.node, ...initialView.node },\n };\n }\n return initialView;\n });\n }, [initialView]);\n\n const featureNode = view.type === 'feature' ? view.node : null;\n\n // SSE: update drawer view when feature state changes\n const { events } = useAgentEventsContext();\n const processedCountRef = useRef(0);\n\n useEffect(() => {\n // Clamp cursor if events were pruned\n if (processedCountRef.current > events.length) {\n processedCountRef.current = 0;\n }\n if (!featureNode || events.length <= processedCountRef.current) return;\n\n const newEvents = events.slice(processedCountRef.current);\n processedCountRef.current = events.length;\n\n for (const update of resolveSseEventUpdates(newEvents)) {\n if (update.featureId !== featureNode.featureId) continue;\n\n // Skip SSE updates for features in 'deleting' state — prevents stale\n // events from overwriting the delete animation or triggering artifact\n // fetches (which would fail with \"not found\" for soft-deleted features).\n if (featureNode.state === 'deleting') continue;\n\n if (update.state !== undefined || update.lifecycle !== undefined) {\n // Update the node data AND re-derive the initial tab so the drawer\n // switches immediately (e.g. prd-review → overview when agent resumes).\n setView((prev) => {\n if (prev.type !== 'feature') return prev;\n const updatedNode = {\n ...prev.node,\n ...(update.state !== undefined && { state: update.state }),\n ...(update.lifecycle !== undefined && { lifecycle: update.lifecycle }),\n };\n return { ...prev, node: updatedNode, initialTab: deriveInitialTab(updatedNode) };\n });\n }\n }\n }, [events, featureNode]);\n\n // Derive open state from the URL. Next.js parallel routes preserve slot\n // content during soft navigation, so this component is NOT unmounted when\n // navigating to `/`. Instead, we watch the pathname and let Vaul handle\n // the close animation when the path no longer matches a feature route.\n const pathname = usePathname();\n const isOpen = pathname.startsWith('/feature/');\n\n // Targeted data sync: fetches fresh FeatureNodeData on drawer open and\n // periodically while open. Replaces router.refresh() to avoid full-page\n // re-renders that cause visible flashing and can reset form state.\n useDrawerSync(isOpen, featureNode?.featureId ?? null, setView);\n\n const onClose = useCallback(() => {\n router.push('/');\n }, [router]);\n\n // ── Chat input state (shared across all review views) ────────────────\n const [chatInput, setChatInput] = useState('');\n\n // ── PRD state ──────────────────────────────────────────────────────────\n const [prdData, setPrdData] = useState<PrdQuestionnaireData | null>(null);\n const [prdSelections, setPrdSelections] = useState<Record<string, string>>({});\n const [prdDefaultSelections, setPrdDefaultSelections] = useState<Record<string, string>>({});\n\n // ── Tech state ─────────────────────────────────────────────────────────\n const [techData, setTechData] = useState<TechDecisionsReviewData | null>(null);\n\n // ── Product decisions state (for tech review Product tab) ─────────────\n const [techProductData, setTechProductData] = useState<\n ProductDecisionsSummaryData | null | undefined\n >(undefined);\n\n // ── Merge state ────────────────────────────────────────────────────────\n const [mergeData, setMergeData] = useState<MergeReviewData | null>(null);\n\n // ── Delete state ───────────────────────────────────────────────────────\n const [isDeleting, setIsDeleting] = useState(false);\n const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);\n\n // ── Archive state ─────────────────────────────────────────────────────\n const [isArchiving, setIsArchiving] = useState(false);\n\n // Reset archive loading spinner when the feature state or feature ID\n // changes (e.g. state flips to 'archived' / 'done' after the server\n // action, or the user navigates to a different feature drawer).\n const archiveResetKey = `${featureNode?.featureId}:${featureNode?.state}`;\n const prevArchiveResetKeyRef = useRef(archiveResetKey);\n useEffect(() => {\n if (archiveResetKey !== prevArchiveResetKeyRef.current) {\n prevArchiveResetKeyRef.current = archiveResetKey;\n setIsArchiving(false);\n }\n }, [archiveResetKey]);\n\n // ── Shared reject state ────────────────────────────────────────────────\n const [isRejecting, setIsRejecting] = useState(false);\n const isRejectingRef = useRef(false);\n\n // Reset chat input whenever the initialTab changes (lifecycle transition)\n const initialTab = view.type === 'feature' ? view.initialTab : undefined;\n useEffect(() => {\n setChatInput('');\n }, [initialTab]);\n\n // ── Artifact refresh key ─────────────────────────────────────────────\n // Increments whenever state or lifecycle changes (via SSE or background sync),\n // forcing useArtifactFetch to re-fetch even when the featureId stays the same.\n // This fixes race conditions where the first fetch fires too early (e.g. merge\n // data requested before the PR is created) and subsequent state updates don't\n // trigger a re-fetch because the featureId dep hasn't changed.\n const artifactRefreshKeyRef = useRef(0);\n const prevStateRef = useRef(featureNode?.state);\n const prevLifecycleRef = useRef(featureNode?.lifecycle);\n if (\n featureNode?.state !== prevStateRef.current ||\n featureNode?.lifecycle !== prevLifecycleRef.current\n ) {\n prevStateRef.current = featureNode?.state;\n prevLifecycleRef.current = featureNode?.lifecycle;\n artifactRefreshKeyRef.current += 1;\n }\n const artifactRefreshKey = artifactRefreshKeyRef.current;\n\n // ── Data fetching ─────────────────────────────────────────────────────\n\n const prdFeatureId =\n featureNode?.lifecycle === 'requirements' && featureNode?.state === 'action-required'\n ? featureNode.featureId\n : null;\n const isLoadingPrd = useArtifactFetch(\n prdFeatureId,\n getFeatureArtifact,\n (result) => {\n if (result.error) {\n toast.error(result.error);\n return;\n }\n if (result.questionnaire) {\n setPrdData(result.questionnaire);\n const defaults: Record<string, string> = {};\n for (const q of result.questionnaire.questions) {\n const recommended = q.options.find((o) => o.recommended);\n if (recommended) defaults[q.id] = recommended.id;\n }\n setPrdSelections(defaults);\n setPrdDefaultSelections(defaults);\n }\n },\n () => {\n setPrdSelections({});\n setPrdDefaultSelections({});\n setPrdData(null);\n },\n 'Failed to load questionnaire',\n artifactRefreshKey\n );\n\n const techFeatureId =\n featureNode?.lifecycle === 'implementation' && featureNode?.state === 'action-required'\n ? featureNode.featureId\n : null;\n const isLoadingTech = useArtifactFetch(\n techFeatureId,\n getResearchArtifact,\n (result) => {\n if (result.error) {\n toast.error(result.error);\n return;\n }\n if (result.techDecisions) setTechData(result.techDecisions);\n },\n () => setTechData(null),\n 'Failed to load tech decisions',\n artifactRefreshKey\n );\n\n const isLoadingTechProduct = useArtifactFetch(\n techFeatureId,\n getFeatureArtifact,\n (result) => {\n if (result.productDecisions) setTechProductData(result.productDecisions);\n },\n () => setTechProductData(undefined),\n undefined,\n artifactRefreshKey\n );\n\n const mergeFeatureId =\n (featureNode?.lifecycle === 'review' &&\n (featureNode?.state === 'action-required' || featureNode?.state === 'error')) ||\n (featureNode?.lifecycle === 'maintain' && featureNode?.pr)\n ? featureNode.featureId\n : null;\n const isLoadingMerge = useArtifactFetch(\n mergeFeatureId,\n getMergeReviewData,\n (result) => {\n if ('error' in result) {\n toast.error(result.error);\n return;\n }\n setMergeData(result);\n },\n () => setMergeData(null),\n 'Failed to load merge review data',\n artifactRefreshKey\n );\n\n // ── Close guard ──────────────────────────────────────────────────────\n const isChatDirty = chatInput.trim().length > 0;\n const isPrdDirty =\n featureNode?.lifecycle === 'requirements' &&\n featureNode?.state === 'action-required' &&\n Object.keys(prdDefaultSelections).some((k) => prdDefaultSelections[k] !== prdSelections[k]);\n const isDirty = isChatDirty || isPrdDirty;\n\n const onReset = useCallback(() => {\n setChatInput('');\n setPrdSelections({ ...prdDefaultSelections });\n }, [prdDefaultSelections]);\n\n const { attemptClose } = useGuardedDrawerClose({ open: isOpen, isDirty, onClose, onReset });\n\n // ── Approve / reject handlers ─────────────────────────────────────────\n\n const handleReject = useCallback(\n async (\n feedback: string,\n label: string,\n attachments: RejectAttachment[] = [],\n onDone?: () => void\n ) => {\n if (!featureNode?.featureId) return;\n isRejectingRef.current = true;\n setIsRejecting(true);\n try {\n const attachmentPaths = attachments.map((a) => a.path).filter(Boolean);\n const notedAttachments = attachments.filter((a) => a.notes?.trim());\n const feedbackWithNotes =\n notedAttachments.length > 0\n ? `${feedback}\\n\\nImage notes:\\n${notedAttachments.map((a) => `- @${a.path}: ${a.notes!.trim()}`).join('\\n')}`\n : feedback;\n const result = await rejectFeature(\n featureNode.featureId,\n feedbackWithNotes,\n attachmentPaths\n );\n if (!result.rejected) {\n toast.error(result.error ?? `Failed to reject ${label.toLowerCase()}`);\n return;\n }\n rejectSound.play();\n setChatInput('');\n toast.success(`${label} rejected — agent re-iterating (iteration ${result.iteration})`);\n if (result.iterationWarning) {\n toast.warning(\n `Iteration ${result.iteration} — consider approving or adjusting feedback to avoid excessive iterations`\n );\n }\n // Optimistically update canvas node before SSE arrives (~500ms delay)\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-approved', {\n detail: { featureId: featureNode.featureId },\n })\n );\n onClose();\n onDone?.();\n } finally {\n isRejectingRef.current = false;\n setIsRejecting(false);\n }\n },\n [featureNode, onClose, rejectSound]\n );\n\n const handlePrdReject = useCallback(\n (feedback: string, attachments: RejectAttachment[]) =>\n handleReject(feedback, 'Requirements', attachments, () => setPrdSelections({})),\n [handleReject]\n );\n const handleTechReject = useCallback(\n (feedback: string, attachments: RejectAttachment[]) =>\n handleReject(feedback, 'Plan', attachments),\n [handleReject]\n );\n const handleMergeReject = useCallback(\n (feedback: string, attachments: RejectAttachment[]) =>\n handleReject(feedback, 'Merge', attachments),\n [handleReject]\n );\n\n const handleSimpleApprove = useCallback(\n async (label: string) => {\n if (!featureNode?.featureId) return;\n const result = await approveFeature(featureNode.featureId);\n if (!result.approved) {\n toast.error(result.error ?? `Failed to approve ${label.toLowerCase()}`);\n return;\n }\n setChatInput('');\n toast.success(`${label} approved — agent resuming`);\n // Optimistically update canvas node before SSE arrives (~500ms delay)\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-approved', {\n detail: { featureId: featureNode.featureId },\n })\n );\n onClose();\n },\n [featureNode, onClose]\n );\n\n const handlePrdApprove = useCallback(\n async (_actionId: string) => {\n if (view.type !== 'feature' || !featureNode) return;\n let payload: PrdApprovalPayload | undefined;\n if (prdData) {\n const changedSelections: QuestionSelectionChange[] = [];\n for (const [questionId, optionId] of Object.entries(prdSelections)) {\n const question = prdData.questions.find((q) => q.id === questionId);\n const option = question?.options.find((o) => o.id === optionId);\n if (question && option) {\n changedSelections.push({ questionId: question.question, selectedOption: option.label });\n }\n }\n payload = { approved: true, changedSelections };\n }\n const result = await approveFeature(featureNode.featureId, payload);\n if (!result.approved) {\n toast.error(result.error ?? 'Failed to approve requirements');\n return;\n }\n setChatInput('');\n toast.success('Requirements approved — agent resuming');\n // Optimistically update canvas node before SSE arrives (~500ms delay)\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-approved', {\n detail: { featureId: featureNode.featureId },\n })\n );\n setPrdSelections({});\n onClose();\n },\n [view, featureNode, prdData, prdSelections, onClose]\n );\n\n const handleTechApprove = useCallback(() => handleSimpleApprove('Plan'), [handleSimpleApprove]);\n const handleMergeApprove = useCallback(() => handleSimpleApprove('Merge'), [handleSimpleApprove]);\n\n const handleDelete = useCallback(\n async (featureId: string, cleanup?: boolean, cascadeDelete?: boolean, closePr?: boolean) => {\n setIsDeleting(true);\n // Close the delete dialog and drawer before the server action so the\n // user sees immediate feedback. We dispatch a DOM event so the canvas\n // control center can run its own optimistic delete flow (deleting state,\n // mutation guard, node removal) in parallel.\n setDeleteDialogOpen(false);\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-delete-requested', {\n detail: { featureId, cleanup, cascadeDelete, closePr },\n })\n );\n router.push('/');\n },\n [router]\n );\n\n const handleArchive = useCallback(\n (featureId: string) => {\n setIsArchiving(true);\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-archive-requested', {\n detail: { featureId },\n })\n );\n router.push('/');\n },\n [router]\n );\n\n const handleUnarchive = useCallback(\n (featureId: string) => {\n setIsArchiving(true);\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-unarchive-requested', {\n detail: { featureId },\n })\n );\n router.push('/');\n },\n [router]\n );\n\n const handleRetry = useCallback(async (featureId: string) => {\n const result = await resumeFeature(featureId);\n if (result.error) {\n toast.error(result.error);\n return;\n }\n toast.success('Feature resumed — agent restarting');\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-approved', {\n detail: { featureId },\n })\n );\n setView((prev) => {\n if (prev.type !== 'feature') return prev;\n return { ...prev, node: { ...prev.node, state: 'running' } };\n });\n }, []);\n\n const handleStop = useCallback(async (featureId: string) => {\n const result = await stopFeature(featureId);\n if (!result.stopped) {\n toast.error(result.error ?? 'Failed to stop');\n return;\n }\n toast.success('Agent stopped');\n setView((prev) => {\n if (prev.type !== 'feature') return prev;\n return { ...prev, node: { ...prev.node, state: 'error' } };\n });\n }, []);\n\n const handleStart = useCallback(async (featureId: string) => {\n const result = await startFeature(featureId);\n if (result.error) {\n toast.error(result.error);\n return;\n }\n toast.success('Feature started');\n // Optimistically update the drawer view\n setView((prev) => {\n if (prev.type !== 'feature') return prev;\n return { ...prev, node: { ...prev.node, state: 'running' } };\n });\n }, []);\n\n // ── Hooks (always called unconditionally per Rules of Hooks) ──────────\n\n const featureActionsInput =\n featureNode?.repositoryPath && featureNode?.branch\n ? {\n featureId: featureNode.featureId,\n repositoryPath: featureNode.repositoryPath,\n branch: featureNode.branch,\n worktreePath: featureNode.worktreePath,\n specPath: featureNode.specPath,\n }\n : null;\n const featureActions = useFeatureActions(featureActionsInput);\n\n // Branch sync status — only when the feature flag is on, the feature has a branch,\n // and the repository has a remote (no remote = no sync needed)\n const syncFeatureId =\n featureFlags.gitRebaseSync && featureNode?.branch && featureNode?.remoteUrl\n ? featureNode.featureId\n : null;\n const {\n data: syncData,\n loading: syncLoading,\n error: syncError,\n refresh: refreshSync,\n } = useBranchSyncStatus(syncFeatureId);\n\n // Auto-refresh sync status after a successful rebase\n const prevRebaseLoadingRef = useRef(featureActions.rebaseLoading);\n useEffect(() => {\n if (\n prevRebaseLoadingRef.current &&\n !featureActions.rebaseLoading &&\n !featureActions.rebaseError\n ) {\n refreshSync();\n }\n prevRebaseLoadingRef.current = featureActions.rebaseLoading;\n }, [featureActions.rebaseLoading, featureActions.rebaseError, refreshSync]);\n\n const featureDeployTarget =\n featureNode?.repositoryPath && featureNode.branch\n ? {\n targetId: featureNode.featureId,\n targetType: 'feature' as const,\n repositoryPath: featureNode.repositoryPath,\n branch: featureNode.branch,\n }\n : null;\n\n const deployAction = useDeployAction(featureDeployTarget);\n const isFeatureDeployActive =\n deployAction.status === 'Booting' || deployAction.status === 'Ready';\n\n // ── Short ID copy ───────────────────────────────────────────────────\n const COPY_FEEDBACK_DELAY = 2000;\n const [idCopied, setIdCopied] = useState(false);\n const handleCopyId = useCallback(() => {\n if (!featureNode?.featureId) return;\n void navigator.clipboard.writeText(featureNode.featureId);\n setIdCopied(true);\n setTimeout(() => setIdCopied(false), COPY_FEEDBACK_DELAY);\n }, [featureNode?.featureId]);\n\n // ── Header ────────────────────────────────────────────────────────────\n\n let headerContent: React.ReactNode = undefined;\n\n if (featureNode) {\n const shortId = featureNode.featureId.slice(0, 8);\n {\n /* Reusable toolbar icon button classes */\n }\n const tbBtn =\n 'text-muted-foreground hover:bg-foreground/8 hover:text-foreground inline-flex size-8 items-center justify-center rounded-[3px] disabled:opacity-40';\n const tbSep = 'bg-border/60 mx-1.5 h-5 w-px shrink-0';\n\n headerContent = (\n <div data-testid=\"feature-drawer-toolbar\">\n <div className=\"flex h-10 items-center px-2\" data-testid=\"feature-drawer-actions\">\n {/* ── Left: Open + Run/Stop ── */}\n {featureActionsInput && featureNode?.state !== 'done' ? (\n <OpenActionMenu\n actions={featureActions}\n repositoryPath={featureActionsInput.repositoryPath}\n worktreePath={featureActionsInput.worktreePath}\n showSpecs={!!featureActionsInput.specPath}\n />\n ) : null}\n {featureActionsInput &&\n featureNode?.state !== 'done' &&\n featureFlags.envDeploy &&\n featureDeployTarget ? (\n <>\n <div className={tbSep} />\n <TooltipProvider delayDuration={300}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled={deployAction.deployLoading || deployAction.stopLoading}\n onClick={isFeatureDeployActive ? deployAction.stop : deployAction.deploy}\n className={cn(\n 'inline-flex size-7 items-center justify-center rounded-[3px] disabled:opacity-40',\n isFeatureDeployActive\n ? 'text-red-500 hover:bg-red-500/10 hover:text-red-400'\n : 'text-green-600 hover:bg-green-500/10 dark:text-green-500'\n )}\n aria-label={\n isFeatureDeployActive\n ? t('featureDrawer.stopDevServer')\n : t('featureDrawer.startDevServer')\n }\n >\n {deployAction.deployLoading || deployAction.stopLoading ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : isFeatureDeployActive ? (\n <Square className=\"size-4\" />\n ) : (\n <Play className=\"size-4\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n {isFeatureDeployActive\n ? t('featureDrawer.stopDevServer')\n : t('featureDrawer.startDevServer')}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n {isFeatureDeployActive ? (\n <DeploymentStatusBadge\n status={deployAction.status}\n url={deployAction.url}\n targetId={featureDeployTarget?.targetId}\n />\n ) : null}\n </>\n ) : null}\n\n {/* ── Spacer ── */}\n <div className=\"flex-1\" />\n\n {/* ── Right: ID · archive · delete ── */}\n <div className=\"flex items-center\">\n <code className=\"text-muted-foreground/70 font-mono text-[10px] tracking-wide select-none\">\n {shortId}\n </code>\n <TooltipProvider delayDuration={300}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={handleCopyId}\n className={tbBtn}\n aria-label={t('featureDrawer.copyFeatureId')}\n data-testid=\"feature-drawer-copy-id\"\n >\n {idCopied ? (\n <Check className=\"size-4 text-green-500\" />\n ) : (\n <Copy className=\"size-4\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n {t('featureDrawer.copyFeatureId')}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n {featureNode.featureId ? (\n <>\n <div className={tbSep} />\n <TooltipProvider delayDuration={300}>\n {featureNode.state === 'archived' ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled={isArchiving}\n className={tbBtn}\n aria-label={t('featureDrawer.unarchiveFeature')}\n data-testid=\"feature-drawer-unarchive\"\n onClick={() => handleUnarchive(featureNode.featureId)}\n >\n {isArchiving ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <ArchiveRestore className=\"size-3\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n {t('featureDrawer.unarchiveFeature')}\n </TooltipContent>\n </Tooltip>\n ) : featureNode.state !== 'deleting' ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled={isArchiving}\n className={tbBtn}\n aria-label={t('featureDrawer.archiveFeature')}\n data-testid=\"feature-drawer-archive\"\n onClick={() => handleArchive(featureNode.featureId)}\n >\n {isArchiving ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <Archive className=\"size-3\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n {t('featureDrawer.archiveFeature')}\n </TooltipContent>\n </Tooltip>\n ) : null}\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled={isDeleting}\n className={cn(tbBtn, 'hover:bg-destructive/10 hover:text-destructive')}\n aria-label={t('featureDrawer.deleteFeature')}\n data-testid=\"feature-drawer-delete\"\n onClick={() => setDeleteDialogOpen(true)}\n >\n {isDeleting ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <Trash2 className=\"size-3\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n {t('featureDrawer.deleteFeature')}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <DeleteFeatureDialog\n open={deleteDialogOpen}\n onOpenChange={setDeleteDialogOpen}\n onConfirm={(cleanup, cascadeDelete, closePr) =>\n handleDelete(featureNode.featureId, cleanup, cascadeDelete, closePr)\n }\n isDeleting={isDeleting}\n featureName={featureNode.name}\n featureId={featureNode.featureId}\n hasChildren={featureNode.hasChildren}\n hasOpenPr={!!featureNode.pr && featureNode.pr.status === 'Open'}\n />\n </>\n ) : null}\n </div>\n </div>\n </div>\n );\n }\n\n // ── Body ──────────────────────────────────────────────────────────────\n\n let body: React.ReactNode = null;\n\n if (view.type === 'feature' && featureNode) {\n const enrichedNode = {\n ...featureNode,\n ...(featureNode.state === 'error' && { onRetry: handleRetry }),\n ...(featureNode.state === 'pending' && { onStart: handleStart }),\n };\n body = (\n <FeatureDrawerTabs\n featureName={featureNode.name}\n headerContent={headerContent}\n featureNode={enrichedNode}\n featureId={featureNode.featureId}\n initialTab={view.initialTab}\n urlTab={urlTab}\n sseEvents={events}\n prdData={prdData}\n prdSelections={prdSelections}\n onPrdSelect={(qId, oId) => setPrdSelections((prev) => ({ ...prev, [qId]: oId }))}\n onPrdApprove={handlePrdApprove}\n onPrdReject={handlePrdReject}\n isPrdLoading={isLoadingPrd}\n techData={techData}\n onTechApprove={handleTechApprove}\n onTechReject={handleTechReject}\n isTechLoading={isLoadingTech}\n productData={isLoadingTechProduct ? null : techProductData}\n mergeData={mergeData}\n onMergeApprove={handleMergeApprove}\n onMergeReject={handleMergeReject}\n isMergeLoading={isLoadingMerge}\n syncStatus={syncFeatureId ? syncData : undefined}\n syncLoading={syncLoading}\n syncError={syncError}\n onRefreshSync={syncFeatureId ? refreshSync : undefined}\n onRebaseOnMain={syncFeatureId ? featureActions.rebaseOnMain : undefined}\n rebaseLoading={featureActions.rebaseLoading}\n rebaseError={featureActions.rebaseError}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={setChatInput}\n interactiveAgentEnabled={interactiveAgentEnabled}\n onRetry={handleRetry}\n onStop={handleStop}\n onStart={handleStart}\n />\n );\n }\n\n return (\n <BaseDrawer\n open={isOpen}\n onClose={attemptClose}\n size=\"lg\"\n modal={false}\n data-testid={view.type === 'feature' ? 'feature-drawer' : 'repository-drawer'}\n >\n {body}\n </BaseDrawer>\n );\n}\n","'use client';\n\nimport { useEffect, useRef, useCallback } from 'react';\nimport { getFeatureDrawerData } from '@/app/actions/get-feature-drawer-data';\nimport type { FeatureNodeData } from '@/components/common/feature-node';\nimport { deriveInitialTab } from './drawer-view';\nimport type { DrawerView } from './drawer-view';\n\n/** How often (ms) to run a background sync while the drawer is open. */\nconst BACKGROUND_SYNC_INTERVAL_MS = 15_000;\n\n/**\n * Targeted drawer data synchronization — replaces router.refresh() for\n * keeping the feature drawer in sync with the server.\n *\n * - On drawer open: fetches fresh FeatureNodeData via server action\n * - Background sync: every 15s while open, merges fresh data into view\n * - SSE-driven state/lifecycle updates are handled separately (not here)\n * - Never affects form state (chatInput, prdSelections, attachments)\n */\nexport function useDrawerSync(\n isOpen: boolean,\n featureId: string | null,\n setView: React.Dispatch<React.SetStateAction<DrawerView>>\n): void {\n const wasOpenRef = useRef(isOpen);\n const isFetchingRef = useRef(false);\n // Incremented on every open transition — stale fetches from a previous\n // open/close cycle are discarded so they can't overwrite fresh data.\n const generationRef = useRef(0);\n\n const syncFromServer = useCallback(async () => {\n if (!featureId || isFetchingRef.current) return;\n isFetchingRef.current = true;\n const gen = generationRef.current;\n try {\n const data = await getFeatureDrawerData(featureId);\n if (!data) return;\n // Discard result if the drawer was closed and reopened while fetching\n if (gen !== generationRef.current) return;\n setView((prev) => mergeFeatureData(prev, data));\n } catch {\n // Silent — background sync failure is non-critical\n } finally {\n isFetchingRef.current = false;\n }\n }, [featureId, setView]);\n\n // Fetch full data when drawer opens (either on mount or closed→open transition).\n // The server component only provides minimal data (feature + agent run);\n // expensive fields (repo name, remote URL, CI status, etc.) are loaded here.\n const hasFetchedOnMountRef = useRef(false);\n useEffect(() => {\n if (isOpen && (!wasOpenRef.current || !hasFetchedOnMountRef.current)) {\n hasFetchedOnMountRef.current = true;\n // New open transition — bump generation to invalidate any in-flight fetch\n // from a previous cycle and reset the fetching guard.\n generationRef.current += 1;\n isFetchingRef.current = false;\n void syncFromServer();\n }\n wasOpenRef.current = isOpen;\n }, [isOpen, syncFromServer]);\n\n // Background sync: throttled interval while drawer is open\n useEffect(() => {\n if (!isOpen || !featureId) return;\n\n const timer = setInterval(() => {\n void syncFromServer();\n }, BACKGROUND_SYNC_INTERVAL_MS);\n\n return () => clearInterval(timer);\n }, [isOpen, featureId, syncFromServer]);\n}\n\n/**\n * Merges fresh server data into the current drawer view.\n * Preserves the view type and only updates the feature node data,\n * keeping all client-side state (form inputs, selections) untouched.\n */\nfunction mergeFeatureData(prev: DrawerView, freshData: FeatureNodeData): DrawerView {\n if (prev.type !== 'feature') return prev;\n\n const merged: FeatureNodeData = { ...prev.node, ...freshData };\n\n // Only re-derive initialTab when state or lifecycle actually changed.\n // Re-deriving on every background sync would reset the chat input\n // (which clears on initialTab change) even when nothing meaningful changed.\n const tabChanged = merged.state !== prev.node.state || merged.lifecycle !== prev.node.lifecycle;\n\n return {\n ...prev,\n node: merged,\n initialTab: tabChanged ? deriveInitialTab(merged) : prev.initialTab,\n };\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"40207f736f2afbb86579362cbd909ff38bc4f7e337\":{\"name\":\"getBranchSyncStatus\"}},\"src/presentation/web/app/actions/get-branch-sync-status.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"40207f736f2afbb86579362cbd909ff38bc4f7e337\",callServer,void 0,findSourceMapURL,\"getBranchSyncStatus\");export{$$RSC_SERVER_ACTION_0 as getBranchSyncStatus};","import { CheckCircle2, Loader2, XCircle } from 'lucide-react';\nimport { CiStatus } from '@shipit-ai/core/domain/generated/output';\nimport { Badge } from '@/components/ui/badge';\n\nexport function CiStatusBadge({ status }: { status: CiStatus }) {\n switch (status) {\n case CiStatus.Success:\n return (\n <Badge className=\"border-transparent bg-green-50 text-green-700 hover:bg-green-50\">\n <CheckCircle2 className=\"me-1 h-3.5 w-3.5\" />\n Passing\n </Badge>\n );\n case CiStatus.Pending:\n return (\n <Badge className=\"border-transparent bg-yellow-50 text-yellow-700 hover:bg-yellow-50\">\n <Loader2 className=\"me-1 h-3.5 w-3.5 animate-spin\" />\n Pending\n </Badge>\n );\n case CiStatus.Failure:\n return (\n <Badge className=\"border-transparent bg-red-50 text-red-700 hover:bg-red-50\">\n <XCircle className=\"me-1 h-3.5 w-3.5\" />\n Failing\n </Badge>\n );\n }\n}\n","import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\nconst cometSpinnerVariants = cva('inline-block shrink-0', {\n variants: {\n size: {\n sm: 'size-5',\n md: 'size-8',\n lg: 'size-12',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nexport interface CometSpinnerProps\n extends React.SVGAttributes<SVGSVGElement>, VariantProps<typeof cometSpinnerVariants> {\n /** Duration in seconds for the outer rotation. */\n duration?: number;\n}\n\nconst PARTICLES = [\n { r: 9, spline: '0.12 0 0.04 1', opacity: 1 },\n { r: 8.2, spline: '0.16 0 0.08 1', opacity: 0.95 },\n { r: 7.4, spline: '0.20 0 0.12 1', opacity: 0.9 },\n { r: 6.6, spline: '0.25 0 0.16 1', opacity: 0.84 },\n { r: 5.8, spline: '0.30 0 0.20 1', opacity: 0.76 },\n { r: 5, spline: '0.36 0 0.25 1', opacity: 0.67 },\n { r: 4.2, spline: '0.42 0 0.31 1', opacity: 0.56 },\n { r: 3.4, spline: '0.48 0 0.37 1', opacity: 0.44 },\n { r: 2.6, spline: '0.55 0 0.44 1', opacity: 0.32 },\n { r: 1.8, spline: '0.62 0 0.52 1', opacity: 0.2 },\n { r: 1, spline: '0.70 0 0.60 1', opacity: 0.1 },\n];\n\nfunction CometSpinner({ className, size = 'md', duration = 5, ...props }: CometSpinnerProps) {\n return (\n <svg\n data-slot=\"comet-spinner\"\n role=\"status\"\n aria-label=\"Loading\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 100 100\"\n className={cn(cometSpinnerVariants({ size }), className)}\n {...props}\n >\n <defs>\n <filter\n id=\"comet-gooey\"\n x=\"-100%\"\n y=\"-100%\"\n width=\"300%\"\n height=\"300%\"\n colorInterpolationFilters=\"sRGB\"\n >\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"2.5\" />\n <feColorMatrix\n mode=\"matrix\"\n values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 50 -30\"\n result=\"goo\"\n />\n </filter>\n </defs>\n\n <g filter=\"url(#comet-gooey)\">\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 50 50\"\n to=\"360 50 50\"\n dur={`${duration}s`}\n repeatCount=\"indefinite\"\n />\n\n {PARTICLES.map((p) => (\n <g key={p.r}>\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n calcMode=\"spline\"\n values=\"0 50 50;360 50 50\"\n keyTimes=\"0;1\"\n keySplines={p.spline}\n dur=\"1s\"\n repeatCount=\"indefinite\"\n />\n <circle cx=\"50\" cy=\"18\" r={p.r} fill=\"currentColor\" opacity={p.opacity} />\n </g>\n ))}\n\n <circle cx=\"50\" cy=\"50\" r=\"4\" fill=\"currentColor\" opacity=\"0.15\">\n <animate attributeName=\"r\" values=\"3;5;3\" dur=\"2s\" repeatCount=\"indefinite\" />\n <animate\n attributeName=\"opacity\"\n values=\"0.1;0.25;0.1\"\n dur=\"2s\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </g>\n </svg>\n );\n}\n\nexport { CometSpinner, cometSpinnerVariants };\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M15.033 9.44a.647.647 0 0 1 0 1.12l-4.065 2.352a.645.645 0 0 1-.968-.56V7.648a.645.645 0 0 1 .967-.56z',\n key: 'vbtd3f',\n },\n ],\n ['path', { d: 'M12 17v4', key: '1riwvh' }],\n ['path', { d: 'M8 21h8', key: '1ev6f3' }],\n ['rect', { x: '2', y: '3', width: '20', height: '14', rx: '2', key: 'x3v2xh' }],\n];\n\n/**\n * @component @name MonitorPlay\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/monitor-play\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst MonitorPlay = createLucideIcon('monitor-play', __iconNode);\n\nexport default MonitorPlay;\n","/**\n * Formats a duration in milliseconds to a human-friendly string.\n *\n * - 0ms → \"0s\"\n * - <1s → \"<1s\"\n * - <60s → \"Xs\"\n * - <1h → \"Xm Ys\"\n * - ≥1h → \"Xh Ym\" (seconds omitted)\n */\nexport function formatDuration(ms: number): string {\n if (ms === 0) return '0s';\n\n const totalSeconds = Math.floor(ms / 1000);\n if (totalSeconds === 0) return '<1s';\n\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n if (hours > 0) {\n return `${hours}h ${minutes}m`;\n }\n\n if (minutes > 0) {\n return `${minutes}m ${seconds}s`;\n }\n\n return `${seconds}s`;\n}\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['circle', { cx: '12', cy: '12', r: '10', key: '1mglay' }],\n ['path', { d: 'M12 16v-4', key: '1dtifu' }],\n ['path', { d: 'M12 8h.01', key: 'e9boi3' }],\n];\n\n/**\n * @component @name Info\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/info\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Info = createLucideIcon('info', __iconNode);\n\nexport default Info;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'm18 9-6-6-6 6', key: 'kcunyi' }],\n ['path', { d: 'M12 3v14', key: '7cf3v8' }],\n ['path', { d: 'M5 21h14', key: '11awu3' }],\n];\n\n/**\n * @component @name ArrowUpFromLine\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/arrow-up-from-line\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ArrowUpFromLine = createLucideIcon('arrow-up-from-line', __iconNode);\n\nexport default ArrowUpFromLine;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['line', { x1: '12', x2: '12', y1: '2', y2: '22', key: '7eqyqh' }],\n ['path', { d: 'M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6', key: '1b0p4s' }],\n];\n\n/**\n * @component @name DollarSign\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/dollar-sign\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst DollarSign = createLucideIcon('dollar-sign', __iconNode);\n\nexport default DollarSign;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M15 12h-5', key: 'r7krc0' }],\n ['path', { d: 'M15 8h-5', key: '1khuty' }],\n ['path', { d: 'M19 17V5a2 2 0 0 0-2-2H4', key: 'zz82l3' }],\n [\n 'path',\n {\n d: 'M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3',\n key: '1ph1d7',\n },\n ],\n];\n\n/**\n * @component @name ScrollText\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/scroll-text\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ScrollText = createLucideIcon('scroll-text', __iconNode);\n\nexport default ScrollText;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M5 12h14', key: '1ays0h' }],\n ['path', { d: 'm12 5 7 7-7 7', key: 'xquz4c' }],\n];\n\n/**\n * @component @name ArrowRight\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/arrow-right\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ArrowRight = createLucideIcon('arrow-right', __iconNode);\n\nexport default ArrowRight;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M12 17V3', key: '1cwfxf' }],\n ['path', { d: 'm6 11 6 6 6-6', key: '12ii2o' }],\n ['path', { d: 'M19 21H5', key: '150jfl' }],\n];\n\n/**\n * @component @name ArrowDownToLine\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/arrow-down-to-line\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ArrowDownToLine = createLucideIcon('arrow-down-to-line', __iconNode);\n\nexport default ArrowDownToLine;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['rect', { width: '20', height: '8', x: '2', y: '2', rx: '2', ry: '2', key: 'ngkwjq' }],\n ['rect', { width: '20', height: '8', x: '2', y: '14', rx: '2', ry: '2', key: 'iecqi9' }],\n ['line', { x1: '6', x2: '6.01', y1: '6', y2: '6', key: '16zg32' }],\n ['line', { x1: '6', x2: '6.01', y1: '18', y2: '18', key: 'nzw8ys' }],\n];\n\n/**\n * @component @name Server\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/server\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Server = createLucideIcon('server', __iconNode);\n\nexport default Server;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M13 5h8', key: 'a7qcls' }],\n ['path', { d: 'M13 12h8', key: 'h98zly' }],\n ['path', { d: 'M13 19h8', key: 'c3s6r1' }],\n ['path', { d: 'm3 17 2 2 4-4', key: '1jhpwq' }],\n ['rect', { x: '3', y: '4', width: '6', height: '6', rx: '1', key: 'cif1o7' }],\n];\n\n/**\n * @component @name ListTodo\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/list-todo\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ListTodo = createLucideIcon('list-todo', __iconNode);\n\nexport default ListTodo;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['line', { x1: '2', x2: '22', y1: '2', y2: '22', key: 'a6p6uj' }],\n ['path', { d: 'M10.41 10.41a2 2 0 1 1-2.83-2.83', key: '1bzlo9' }],\n ['line', { x1: '13.5', x2: '6', y1: '13.5', y2: '21', key: '1q0aeu' }],\n ['line', { x1: '18', x2: '21', y1: '12', y2: '15', key: '5mozeu' }],\n [\n 'path',\n {\n d: 'M3.59 3.59A1.99 1.99 0 0 0 3 5v14a2 2 0 0 0 2 2h14c.55 0 1.052-.22 1.41-.59',\n key: 'mmje98',\n },\n ],\n ['path', { d: 'M21 15V5a2 2 0 0 0-2-2H9', key: '43el77' }],\n];\n\n/**\n * @component @name ImageOff\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/image-off\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ImageOff = createLucideIcon('image-off', __iconNode);\n\nexport default ImageOff;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M10.1 2.182a10 10 0 0 1 3.8 0', key: '5ilxe3' }],\n ['path', { d: 'M13.9 21.818a10 10 0 0 1-3.8 0', key: '11zvb9' }],\n ['path', { d: 'M17.609 3.721a10 10 0 0 1 2.69 2.7', key: '1iw5b2' }],\n ['path', { d: 'M2.182 13.9a10 10 0 0 1 0-3.8', key: 'c0bmvh' }],\n ['path', { d: 'M20.279 17.609a10 10 0 0 1-2.7 2.69', key: '1ruxm7' }],\n ['path', { d: 'M21.818 10.1a10 10 0 0 1 0 3.8', key: 'qkgqxc' }],\n ['path', { d: 'M3.721 6.391a10 10 0 0 1 2.7-2.69', key: '1mcia2' }],\n ['path', { d: 'M6.391 20.279a10 10 0 0 1-2.69-2.7', key: '1fvljs' }],\n];\n\n/**\n * @component @name CircleDashed\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/circle-dashed\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst CircleDashed = createLucideIcon('circle-dashed', __iconNode);\n\nexport default CircleDashed;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['circle', { cx: '18', cy: '18', r: '3', key: '1xkwt0' }],\n ['circle', { cx: '6', cy: '6', r: '3', key: '1lh9wr' }],\n ['path', { d: 'M6 21V9a9 9 0 0 0 9 9', key: '7kw0sc' }],\n];\n\n/**\n * @component @name GitMerge\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/git-merge\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst GitMerge = createLucideIcon('git-merge', __iconNode);\n\nexport default GitMerge;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['circle', { cx: '5', cy: '6', r: '3', key: '1qnov2' }],\n ['path', { d: 'M12 6h5a2 2 0 0 1 2 2v7', key: '1yj91y' }],\n ['path', { d: 'm15 9-3-3 3-3', key: '1lwv8l' }],\n ['circle', { cx: '19', cy: '18', r: '3', key: '1qljk2' }],\n ['path', { d: 'M12 18H7a2 2 0 0 1-2-2V9', key: '16sdep' }],\n ['path', { d: 'm9 15 3 3-3 3', key: '1m3kbl' }],\n];\n\n/**\n * @component @name GitCompareArrows\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/git-compare-arrows\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst GitCompareArrows = createLucideIcon('git-compare-arrows', __iconNode);\n\nexport default GitCompareArrows;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['circle', { cx: '8', cy: '8', r: '6', key: '3yglwk' }],\n ['path', { d: 'M18.09 10.37A6 6 0 1 1 10.34 18', key: 't5s6rm' }],\n ['path', { d: 'M7 6h1v4', key: '1obek4' }],\n ['path', { d: 'm16.71 13.88.7.71-2.82 2.82', key: '1rbuyh' }],\n];\n\n/**\n * @component @name Coins\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/coins\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Coins = createLucideIcon('coins', __iconNode);\n\nexport default Coins;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z',\n key: '1oefj6',\n },\n ],\n ['path', { d: 'M14 2v5a1 1 0 0 0 1 1h5', key: 'wfsgrz' }],\n ['path', { d: 'M9 15h6', key: 'cctwl0' }],\n];\n\n/**\n * @component @name FileMinus\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/file-minus\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst FileMinus = createLucideIcon('file-minus', __iconNode);\n\nexport default FileMinus;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z',\n key: '1oefj6',\n },\n ],\n ['path', { d: 'M14 2v5a1 1 0 0 0 1 1h5', key: 'wfsgrz' }],\n ['path', { d: 'm9 15 2 2 4-4', key: '1grp1n' }],\n];\n\n/**\n * @component @name FileCheck\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/file-check\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst FileCheck = createLucideIcon('file-check', __iconNode);\n\nexport default FileCheck;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z',\n key: '1oefj6',\n },\n ],\n ['path', { d: 'M14 2v5a1 1 0 0 0 1 1h5', key: 'wfsgrz' }],\n ['path', { d: 'M10 12.5 8 15l2 2.5', key: '1tg20x' }],\n ['path', { d: 'm14 12.5 2 2.5-2 2.5', key: 'yinavb' }],\n];\n\n/**\n * @component @name FileCode\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/file-code\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst FileCode = createLucideIcon('file-code', __iconNode);\n\nexport default FileCode;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z',\n key: 'zw3jo',\n },\n ],\n [\n 'path',\n {\n d: 'M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12',\n key: '1wduqc',\n },\n ],\n [\n 'path',\n {\n d: 'M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17',\n key: 'kqbvx6',\n },\n ],\n];\n\n/**\n * @component @name Layers\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/layers\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Layers = createLucideIcon('layers', __iconNode);\n\nexport default Layers;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z',\n key: 'oel41y',\n },\n ],\n ['path', { d: 'm9 12 2 2 4-4', key: 'dzmm74' }],\n];\n\n/**\n * @component @name ShieldCheck\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/shield-check\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ShieldCheck = createLucideIcon('shield-check', __iconNode);\n\nexport default ShieldCheck;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z',\n key: '1oefj6',\n },\n ],\n ['path', { d: 'M9 10h6', key: '9gxzsh' }],\n ['path', { d: 'M12 13V7', key: 'h0r20n' }],\n ['path', { d: 'M9 17h6', key: 'r8uit2' }],\n];\n\n/**\n * @component @name FileDiff\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/file-diff\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst FileDiff = createLucideIcon('file-diff', __iconNode);\n\nexport default FileDiff;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z',\n key: '169xi5',\n },\n ],\n ['path', { d: 'M15 5.764v15', key: '1pn4in' }],\n ['path', { d: 'M9 3.236v15', key: '1uimfh' }],\n];\n\n/**\n * @component @name Map\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/map\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Map = createLucideIcon('map', __iconNode);\n\nexport default Map;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z',\n key: '1oefj6',\n },\n ],\n ['path', { d: 'M14 2v5a1 1 0 0 0 1 1h5', key: 'wfsgrz' }],\n ['circle', { cx: '11.5', cy: '14.5', r: '2.5', key: '1bq0ko' }],\n ['path', { d: 'M13.3 16.3 15 18', key: '2quom7' }],\n];\n\n/**\n * @component @name FileSearch\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/file-search\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst FileSearch = createLucideIcon('file-search', __iconNode);\n\nexport default FileSearch;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z',\n key: '18u6gg',\n },\n ],\n ['circle', { cx: '12', cy: '13', r: '3', key: '1vg3eu' }],\n];\n\n/**\n * @component @name Camera\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/camera\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Camera = createLucideIcon('camera', __iconNode);\n\nexport default Camera;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z',\n key: '1ffxy3',\n },\n ],\n ['path', { d: 'm21.854 2.147-10.94 10.939', key: '12cjpa' }],\n];\n\n/**\n * @component @name Send\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/send\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Send = createLucideIcon('send', __iconNode);\n\nexport default Send;\n","import type { FeatureNodeData } from '@/components/common/feature-node';\nimport type { RepositoryNodeData } from '@/components/common/repository-node';\nimport type { ParentFeatureOption } from '@/components/common/feature-create-drawer/feature-create-drawer';\nimport type { WorkflowDefaults } from '@/app/actions/get-workflow-defaults';\n\n/** Tab key matching FeatureDrawerTabs */\nexport type FeatureTabKey =\n | 'overview'\n | 'activity'\n | 'log'\n | 'plan'\n | 'prd-review'\n | 'tech-decisions'\n | 'product-decisions'\n | 'merge-review'\n | 'chat';\n\n/** All valid tab key values — used for URL param validation. */\nexport const VALID_TAB_KEYS: ReadonlySet<string> = new Set<FeatureTabKey>([\n 'overview',\n 'activity',\n 'log',\n 'plan',\n 'prd-review',\n 'tech-decisions',\n 'product-decisions',\n 'merge-review',\n 'chat',\n]);\n\n/** Type-guard: returns the value as FeatureTabKey if valid, otherwise undefined. */\nexport function parseTabKey(value: string | null | undefined): FeatureTabKey | undefined {\n if (value && VALID_TAB_KEYS.has(value)) return value as FeatureTabKey;\n return undefined;\n}\n\n/**\n * Discriminated union representing every possible drawer state in the control center.\n * Only one view can be active at a time.\n */\nexport type DrawerView =\n /** All feature views — tabs handle the lifecycle-specific content */\n | { type: 'feature'; node: FeatureNodeData; initialTab: FeatureTabKey }\n /** Feature creation form */\n | {\n type: 'feature-create';\n repositoryPath: string;\n initialParentId?: string;\n features: ParentFeatureOption[];\n workflowDefaults?: WorkflowDefaults;\n }\n /** Repository node actions */\n | { type: 'repository'; data: RepositoryNodeData };\n\n/** Derives the initial tab from node lifecycle + state. */\nexport function deriveInitialTab(node: FeatureNodeData): FeatureTabKey {\n if (node.lifecycle === 'requirements' && node.state === 'action-required') return 'prd-review';\n if (node.lifecycle === 'implementation' && node.state === 'action-required')\n return 'tech-decisions';\n if (node.lifecycle === 'review' && (node.state === 'action-required' || node.state === 'error'))\n return 'merge-review';\n return 'overview';\n}\n\n/**\n * Derives the active DrawerView from control-center state.\n * Priority: feature-create > selected-node > repository\n */\nexport function computeDrawerView({\n selectedNode,\n isCreateDrawerOpen,\n pendingRepositoryPath,\n pendingParentFeatureId,\n selectedRepoNode,\n features,\n workflowDefaults,\n}: {\n selectedNode: FeatureNodeData | null;\n isCreateDrawerOpen: boolean;\n pendingRepositoryPath: string;\n pendingParentFeatureId: string | undefined;\n selectedRepoNode: RepositoryNodeData | null;\n features: ParentFeatureOption[];\n workflowDefaults: WorkflowDefaults | undefined;\n}): DrawerView | null {\n if (isCreateDrawerOpen) {\n return {\n type: 'feature-create',\n repositoryPath: pendingRepositoryPath,\n initialParentId: pendingParentFeatureId,\n features,\n workflowDefaults,\n };\n }\n\n if (selectedNode) {\n return { type: 'feature', node: selectedNode, initialTab: deriveInitialTab(selectedNode) };\n }\n\n if (selectedRepoNode) {\n return { type: 'repository', data: selectedRepoNode };\n }\n\n return null;\n}\n","/**\n * Parses structured log lines from the feature agent worker process.\n *\n * Log format: [timestamp] [phase] [agent|model] [tag] message\n * Worker format: [timestamp] [agent|model] [WORKER] message\n * Fallback: raw string lines\n */\n\nexport type LogEventTag =\n | 'tool'\n | 'tool-result'\n | 'text'\n | 'delta'\n | 'result'\n | 'tokens'\n | 'cmd'\n | 'file'\n | 'turn'\n | 'thread'\n | 'error'\n | 'event'\n | 'raw'\n | 'worker'\n | 'info';\n\nexport interface ParsedLogLine {\n /** ISO timestamp */\n timestamp: string | null;\n /** Phase name (e.g. \"requirements\", \"implement\") */\n phase: string | null;\n /** Agent type (e.g. \"claude-code\") */\n agent: string | null;\n /** Model name (e.g. \"claude-haiku-4-5\") */\n model: string | null;\n /** Event tag */\n tag: LogEventTag;\n /** The message content after tags */\n message: string;\n /** Original raw line */\n raw: string;\n}\n\n/**\n * Regex to match structured log lines.\n * Captures: timestamp, optional phase, optional agent|model, rest of message\n *\n * Examples:\n * [2026-03-08T10:00:01.123Z] [requirements] [claude-code|claude-haiku-4-5] [tool] Read {\"path\":\"f.ts\"}\n * [2026-03-08T10:00:01.123Z] [claude-code|claude-haiku-4-5] [WORKER] Starting worker\n * [2026-03-08T10:00:01.123Z] [requirements] [claude-code|claude-haiku-4-5] Starting...\n */\nconst LOG_LINE_REGEX =\n /^\\[(\\d{4}-\\d{2}-\\d{2}T[\\d:.]+Z?)\\]\\s+(?:\\[([^\\]]+)\\]\\s+)?(?:\\[([^\\]|]+)(?:\\|([^\\]]+))?\\]\\s+)?(.*)$/;\n\nconst TAG_REGEX =\n /^\\[(tool-result|tool|text|delta|result|tokens|cmd|file|turn|thread|error|event|raw|WORKER)\\]\\s*(.*)/;\n\nexport function parseLogLine(raw: string): ParsedLogLine {\n const match = raw.match(LOG_LINE_REGEX);\n\n if (!match) {\n return {\n timestamp: null,\n phase: null,\n agent: null,\n model: null,\n tag: 'raw',\n message: raw,\n raw,\n };\n }\n\n const [, timestamp, group1, group2, group3, rest] = match;\n\n // Determine phase, agent, model from the captured groups.\n // The log format can be:\n // [ts] [phase] [agent|model] message → group1=phase, group2=agent, group3=model\n // [ts] [agent|model] [WORKER] message → group1=\"agent|model\", group2=WORKER\n // [ts] [phase] [agent] message → group1=phase, group2=agent\n // [ts] [phase] message → group1=phase only\n let phase: string | null = null;\n let agent: string | null = null;\n let model: string | null = null;\n let message = rest ?? '';\n\n if (group2 != null && group1 != null) {\n // Two bracket groups captured\n if (group1.includes('|')) {\n // group1 is [agent|model], group2 is next tag (e.g. WORKER)\n const [agentPart, modelPart] = group1.split('|');\n agent = agentPart;\n model = modelPart ?? null;\n // group2 becomes part of the message to be parsed as a tag\n message = `[${group2}] ${rest ?? ''}`;\n } else {\n // group1 is [phase], group2|group3 is [agent|model]\n phase = group1;\n agent = group2;\n model = group3 ?? null;\n }\n } else if (group1 != null) {\n // Only one bracket group\n if (group1.includes('|')) {\n const [agentPart, modelPart] = group1.split('|');\n agent = agentPart;\n model = modelPart ?? null;\n } else {\n phase = group1;\n }\n }\n\n // Parse tag from message\n const tagMatch = message.match(TAG_REGEX);\n let tag: LogEventTag = 'info';\n\n if (tagMatch) {\n tag = tagMatch[1].toLowerCase() as LogEventTag;\n message = tagMatch[2];\n }\n\n return {\n timestamp: timestamp ?? null,\n phase,\n agent,\n model,\n tag,\n message: message.trim(),\n raw,\n };\n}\n\n/** Tool call info extracted from [tool] messages */\nexport interface ToolCallInfo {\n toolName: string;\n args: string;\n}\n\n/** Parse a [tool] message into tool name and args */\nexport function parseToolCall(message: string): ToolCallInfo {\n const spaceIdx = message.indexOf(' ');\n if (spaceIdx === -1) {\n return { toolName: message, args: '' };\n }\n return {\n toolName: message.slice(0, spaceIdx),\n args: message.slice(spaceIdx + 1),\n };\n}\n\n/** Result info extracted from [result] messages */\nexport interface ResultInfo {\n chars: number;\n sessionId: string | null;\n}\n\n/** Parse a [result] message */\nexport function parseResultMessage(message: string): ResultInfo {\n const charsMatch = message.match(/^(\\d+)\\s+chars/);\n const sessionMatch = message.match(/session=(\\S+)/);\n return {\n chars: charsMatch ? parseInt(charsMatch[1], 10) : 0,\n sessionId: sessionMatch ? sessionMatch[1] : null,\n };\n}\n\n/** Token info extracted from [tokens] messages */\nexport interface TokenInfo {\n inputTokens: number;\n outputTokens: number;\n}\n\n/** Parse a [tokens] message */\nexport function parseTokensMessage(message: string): TokenInfo {\n const match = message.match(/^(\\d+)\\s+in\\s*\\/\\s*(\\d+)\\s+out/);\n if (!match) return { inputTokens: 0, outputTokens: 0 };\n return {\n inputTokens: parseInt(match[1], 10),\n outputTokens: parseInt(match[2], 10),\n };\n}\n\n/** Parse all lines from raw content string */\nexport function parseLogContent(content: string): ParsedLogLine[] {\n if (!content) return [];\n return content\n .split('\\n')\n .filter((line) => line.trim().length > 0)\n .map(parseLogLine);\n}\n"],"names":["$$RSC_SERVER_ACTION_0"],"mappings":"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","ignoreList":[34,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58]}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/presentation/web/app/actions/data%3A9820cc%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/hooks/use-branch-sync-status.ts","../../../../../../../src/presentation/web/app/actions/data%3A9ab119%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx","../../../../../../../src/presentation/web/app/actions/data%3Ac3913d%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/app/actions/data%3A8a51a3%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/app/actions/data%3A5c676e%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/common/open-action-menu/open-action-menu.tsx","../../../../../../../src/presentation/web/app/actions/data%3Afc29ec%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/app/actions/data%3A23223a%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx","../../../../../../../src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.tsx","../../../../../../../src/presentation/web/components/common/product-decisions-summary/product-decisions-summary.tsx","../../../../../../../src/presentation/web/components/common/ci-status-badge/ci-status-badge.tsx","../../../../../../../src/presentation/web/components/common/merge-review/diff-view.tsx","../../../../../../../src/presentation/web/components/common/merge-review/merge-review.tsx","../../../../../../../src/presentation/web/components/common/inline-attachments/inline-attachments.tsx","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/overview-tab.tsx","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.tsx","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.tsx","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/log-tab.tsx","../../../../../../../src/presentation/web/components/common/task-progress-view/task-progress-view.tsx","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/plan-tab.tsx","../../../../../../../src/presentation/web/hooks/use-feature-logs.ts","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.ts","../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.tsx","../../../../../../../src/presentation/web/app/actions/data%3Ae3f080%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/common/feature-drawer/use-feature-actions.ts","../../../../../../../src/presentation/web/components/common/control-center-drawer/use-artifact-fetch.ts","../../../../../../../src/presentation/web/app/actions/data%3A979ba3%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/common/control-center-drawer/use-drawer-sync.ts","../../../../../../../src/presentation/web/app/actions/data%3A0e3394%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.tsx","../../../../../../../src/presentation/web/components/ui/comet-spinner.tsx","../../../../../../../src/presentation/web/lib/format-duration.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/circle-dashed.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/dollar-sign.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/coins.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/server.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/git-merge.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/info.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/image-off.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/git-compare-arrows.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/list-todo.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/arrow-down-to-line.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/arrow-up-from-line.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/scroll-text.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/send.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/file-code.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/file-search.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/file-check.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/file-minus.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/camera.ts","../../../../../../../src/presentation/web/components/common/control-center-drawer/drawer-view.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/file-diff.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/map.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/monitor-play.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/layers.ts","../../../../../../../src/presentation/web/lib/parse-log-line.ts"],"sourcesContent":["/* __next_internal_action_entry_do_not_use__ [{\"608d79ca48d89182041331c418d6f70ce1fe6dfffe\":{\"name\":\"approveFeature\"}},\"src/presentation/web/app/actions/approve-feature.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"608d79ca48d89182041331c418d6f70ce1fe6dfffe\",callServer,void 0,findSourceMapURL,\"approveFeature\");export{$$RSC_SERVER_ACTION_0 as approveFeature};","'use client';\n\nimport { useState, useCallback, useEffect, useRef } from 'react';\nimport { getBranchSyncStatus } from '@/app/actions/get-branch-sync-status';\n\nexport interface BranchSyncData {\n ahead: number;\n behind: number;\n baseBranch: string;\n checkedAt: string;\n}\n\nexport interface UseBranchSyncStatusResult {\n data: BranchSyncData | null;\n loading: boolean;\n error: string | null;\n refresh: () => void;\n}\n\nconst CACHE_TTL_MS = 30_000;\n\n/** Module-level cache so data survives component remounts / drawer close-reopen. */\nconst cache = new Map<string, { data: BranchSyncData; timestamp: number }>();\n\nexport function useBranchSyncStatus(featureId: string | null): UseBranchSyncStatusResult {\n const [data, setData] = useState<BranchSyncData | null>(() => {\n if (!featureId) return null;\n const cached = cache.get(featureId);\n return cached ? cached.data : null;\n });\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const featureIdRef = useRef(featureId);\n featureIdRef.current = featureId;\n\n const fetchStatus = useCallback(async (id: string) => {\n setLoading(true);\n setError(null);\n try {\n const result = await getBranchSyncStatus(id);\n // Guard against stale responses if featureId changed during fetch\n if (featureIdRef.current !== id) return;\n if (result.success && result.data) {\n const syncData: BranchSyncData = result.data;\n cache.set(id, { data: syncData, timestamp: Date.now() });\n setData(syncData);\n } else {\n setError(result.error ?? 'Failed to check sync status');\n }\n } catch {\n if (featureIdRef.current !== id) return;\n setError('Failed to check sync status');\n } finally {\n if (featureIdRef.current === id) {\n setLoading(false);\n }\n }\n }, []);\n\n // Auto-fetch on mount if cache is stale\n useEffect(() => {\n if (!featureId) {\n setData(null);\n setError(null);\n return;\n }\n\n const cached = cache.get(featureId);\n if (cached) {\n setData(cached.data);\n if (Date.now() - cached.timestamp < CACHE_TTL_MS) return;\n }\n\n void fetchStatus(featureId);\n }, [featureId, fetchStatus]);\n\n const refresh = useCallback(() => {\n if (featureId) {\n void fetchStatus(featureId);\n }\n }, [featureId, fetchStatus]);\n\n return { data, loading, error, refresh };\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"70b7b369ab4b5566d533f71eb299cfcc9230fa91a1\":{\"name\":\"rejectFeature\"}},\"src/presentation/web/app/actions/reject-feature.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"70b7b369ab4b5566d533f71eb299cfcc9230fa91a1\",callServer,void 0,findSourceMapURL,\"rejectFeature\");export{$$RSC_SERVER_ACTION_0 as rejectFeature};","'use client';\n\nimport { useState, useCallback, useEffect, useRef } from 'react';\nimport { cn } from '@/lib/utils';\nimport { useTranslation } from 'react-i18next';\nimport { useRouter, usePathname } from 'next/navigation';\nimport { toast } from 'sonner';\nimport {\n LoaderCircle,\n Trash2,\n Play,\n Square,\n Copy,\n Check,\n Archive,\n ArchiveRestore,\n} from 'lucide-react';\nimport type {\n PrdApprovalPayload,\n QuestionSelectionChange,\n} from '@shipit-ai/core/domain/generated/output';\nimport { approveFeature } from '@/app/actions/approve-feature';\nimport { resumeFeature } from '@/app/actions/resume-feature';\nimport { startFeature } from '@/app/actions/start-feature';\nimport { stopFeature } from '@/app/actions/stop-feature';\nimport { rejectFeature } from '@/app/actions/reject-feature';\nimport type { RejectAttachment } from '@/components/common/drawer-action-bar';\nimport { getFeatureArtifact } from '@/app/actions/get-feature-artifact';\nimport { getResearchArtifact } from '@/app/actions/get-research-artifact';\nimport { getMergeReviewData } from '@/app/actions/get-merge-review-data';\nimport { useFeatureFlags } from '@/hooks/feature-flags-context';\nimport { useSoundAction } from '@/hooks/use-sound-action';\nimport { useGuardedDrawerClose } from '@/hooks/drawer-close-guard';\nimport { useDeployAction } from '@/hooks/use-deploy-action';\nimport { useAgentEventsContext } from '@/hooks/agent-events-provider';\nimport { BaseDrawer } from '@/components/common/base-drawer';\nimport { DeploymentStatusBadge } from '@/components/common/deployment-status-badge';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\nimport { DeleteFeatureDialog } from '@/components/common/delete-feature-dialog';\nimport { OpenActionMenu } from '@/components/common/open-action-menu';\nimport { FeatureDrawerTabs } from '@/components/common/feature-drawer-tabs';\nimport { useFeatureActions } from '@/components/common/feature-drawer/use-feature-actions';\nimport type { PrdQuestionnaireData } from '@/components/common/prd-questionnaire';\nimport type { TechDecisionsReviewData } from '@/components/common/tech-decisions-review';\nimport type { ProductDecisionsSummaryData } from '@/components/common/product-decisions-summary';\nimport type { MergeReviewData } from '@/components/common/merge-review';\nimport { resolveSseEventUpdates } from '@/components/common/feature-node/derive-feature-state';\nimport { deriveInitialTab } from './drawer-view';\nimport type { DrawerView, FeatureTabKey } from './drawer-view';\nimport { useArtifactFetch } from './use-artifact-fetch';\nimport { useDrawerSync } from './use-drawer-sync';\nimport { useBranchSyncStatus } from '@/hooks/use-branch-sync-status';\n\nexport interface FeatureDrawerClientProps {\n view: DrawerView;\n /** Tab key extracted from the URL path segment (e.g. /feature/[id]/activity → 'activity'). */\n urlTab?: FeatureTabKey;\n /** When false, the Chat tab is hidden from the tab bar (FR-17). Defaults to true. */\n interactiveAgentEnabled?: boolean;\n}\n\nexport function FeatureDrawerClient({\n view: initialView,\n urlTab,\n interactiveAgentEnabled = true,\n}: FeatureDrawerClientProps) {\n const featureFlags = useFeatureFlags();\n const { t } = useTranslation('web');\n const router = useRouter();\n const rejectSound = useSoundAction('reject');\n\n // Track the view locally so SSE events can update the drawer type in real-time\n const [view, setView] = useState(initialView);\n\n // Sync when server re-renders with new props (e.g. after navigation).\n // When reopening the SAME feature, merge server data into the existing view\n // to preserve enriched fields (repositoryName, baseBranch, oneLiner, remoteUrl)\n // that useDrawerSync added but the minimal server component doesn't provide.\n useEffect(() => {\n setView((prev) => {\n if (\n prev.type === 'feature' &&\n initialView.type === 'feature' &&\n prev.node.featureId === initialView.node.featureId\n ) {\n return {\n ...initialView,\n node: { ...prev.node, ...initialView.node },\n };\n }\n return initialView;\n });\n }, [initialView]);\n\n const featureNode = view.type === 'feature' ? view.node : null;\n\n // SSE: update drawer view when feature state changes\n const { events } = useAgentEventsContext();\n const processedCountRef = useRef(0);\n\n useEffect(() => {\n // Clamp cursor if events were pruned\n if (processedCountRef.current > events.length) {\n processedCountRef.current = 0;\n }\n if (!featureNode || events.length <= processedCountRef.current) return;\n\n const newEvents = events.slice(processedCountRef.current);\n processedCountRef.current = events.length;\n\n for (const update of resolveSseEventUpdates(newEvents)) {\n if (update.featureId !== featureNode.featureId) continue;\n\n // Skip SSE updates for features in 'deleting' state — prevents stale\n // events from overwriting the delete animation or triggering artifact\n // fetches (which would fail with \"not found\" for soft-deleted features).\n if (featureNode.state === 'deleting') continue;\n\n if (update.state !== undefined || update.lifecycle !== undefined) {\n // Update the node data AND re-derive the initial tab so the drawer\n // switches immediately (e.g. prd-review → overview when agent resumes).\n setView((prev) => {\n if (prev.type !== 'feature') return prev;\n const updatedNode = {\n ...prev.node,\n ...(update.state !== undefined && { state: update.state }),\n ...(update.lifecycle !== undefined && { lifecycle: update.lifecycle }),\n };\n return { ...prev, node: updatedNode, initialTab: deriveInitialTab(updatedNode) };\n });\n }\n }\n }, [events, featureNode]);\n\n // Derive open state from the URL. Next.js parallel routes preserve slot\n // content during soft navigation, so this component is NOT unmounted when\n // navigating to `/`. Instead, we watch the pathname and let Vaul handle\n // the close animation when the path no longer matches a feature route.\n const pathname = usePathname();\n const isOpen = pathname.startsWith('/feature/');\n\n // Targeted data sync: fetches fresh FeatureNodeData on drawer open and\n // periodically while open. Replaces router.refresh() to avoid full-page\n // re-renders that cause visible flashing and can reset form state.\n useDrawerSync(isOpen, featureNode?.featureId ?? null, setView);\n\n const onClose = useCallback(() => {\n router.push('/');\n }, [router]);\n\n // ── Chat input state (shared across all review views) ────────────────\n const [chatInput, setChatInput] = useState('');\n\n // ── PRD state ──────────────────────────────────────────────────────────\n const [prdData, setPrdData] = useState<PrdQuestionnaireData | null>(null);\n const [prdSelections, setPrdSelections] = useState<Record<string, string>>({});\n const [prdDefaultSelections, setPrdDefaultSelections] = useState<Record<string, string>>({});\n\n // ── Tech state ─────────────────────────────────────────────────────────\n const [techData, setTechData] = useState<TechDecisionsReviewData | null>(null);\n\n // ── Product decisions state (for tech review Product tab) ─────────────\n const [techProductData, setTechProductData] = useState<\n ProductDecisionsSummaryData | null | undefined\n >(undefined);\n\n // ── Merge state ────────────────────────────────────────────────────────\n const [mergeData, setMergeData] = useState<MergeReviewData | null>(null);\n\n // ── Delete state ───────────────────────────────────────────────────────\n const [isDeleting, setIsDeleting] = useState(false);\n const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);\n\n // ── Archive state ─────────────────────────────────────────────────────\n const [isArchiving, setIsArchiving] = useState(false);\n\n // Reset archive loading spinner when the feature state or feature ID\n // changes (e.g. state flips to 'archived' / 'done' after the server\n // action, or the user navigates to a different feature drawer).\n const archiveResetKey = `${featureNode?.featureId}:${featureNode?.state}`;\n const prevArchiveResetKeyRef = useRef(archiveResetKey);\n useEffect(() => {\n if (archiveResetKey !== prevArchiveResetKeyRef.current) {\n prevArchiveResetKeyRef.current = archiveResetKey;\n setIsArchiving(false);\n }\n }, [archiveResetKey]);\n\n // ── Shared reject state ────────────────────────────────────────────────\n const [isRejecting, setIsRejecting] = useState(false);\n const isRejectingRef = useRef(false);\n\n // Reset chat input whenever the initialTab changes (lifecycle transition)\n const initialTab = view.type === 'feature' ? view.initialTab : undefined;\n useEffect(() => {\n setChatInput('');\n }, [initialTab]);\n\n // ── Artifact refresh key ─────────────────────────────────────────────\n // Increments whenever state or lifecycle changes (via SSE or background sync),\n // forcing useArtifactFetch to re-fetch even when the featureId stays the same.\n // This fixes race conditions where the first fetch fires too early (e.g. merge\n // data requested before the PR is created) and subsequent state updates don't\n // trigger a re-fetch because the featureId dep hasn't changed.\n const artifactRefreshKeyRef = useRef(0);\n const prevStateRef = useRef(featureNode?.state);\n const prevLifecycleRef = useRef(featureNode?.lifecycle);\n if (\n featureNode?.state !== prevStateRef.current ||\n featureNode?.lifecycle !== prevLifecycleRef.current\n ) {\n prevStateRef.current = featureNode?.state;\n prevLifecycleRef.current = featureNode?.lifecycle;\n artifactRefreshKeyRef.current += 1;\n }\n const artifactRefreshKey = artifactRefreshKeyRef.current;\n\n // ── Data fetching ─────────────────────────────────────────────────────\n\n const prdFeatureId =\n featureNode?.lifecycle === 'requirements' && featureNode?.state === 'action-required'\n ? featureNode.featureId\n : null;\n const isLoadingPrd = useArtifactFetch(\n prdFeatureId,\n getFeatureArtifact,\n (result) => {\n if (result.error) {\n toast.error(result.error);\n return;\n }\n if (result.questionnaire) {\n setPrdData(result.questionnaire);\n const defaults: Record<string, string> = {};\n for (const q of result.questionnaire.questions) {\n const recommended = q.options.find((o) => o.recommended);\n if (recommended) defaults[q.id] = recommended.id;\n }\n setPrdSelections(defaults);\n setPrdDefaultSelections(defaults);\n }\n },\n () => {\n setPrdSelections({});\n setPrdDefaultSelections({});\n setPrdData(null);\n },\n 'Failed to load questionnaire',\n artifactRefreshKey\n );\n\n const techFeatureId =\n featureNode?.lifecycle === 'implementation' && featureNode?.state === 'action-required'\n ? featureNode.featureId\n : null;\n const isLoadingTech = useArtifactFetch(\n techFeatureId,\n getResearchArtifact,\n (result) => {\n if (result.error) {\n toast.error(result.error);\n return;\n }\n if (result.techDecisions) setTechData(result.techDecisions);\n },\n () => setTechData(null),\n 'Failed to load tech decisions',\n artifactRefreshKey\n );\n\n const isLoadingTechProduct = useArtifactFetch(\n techFeatureId,\n getFeatureArtifact,\n (result) => {\n if (result.productDecisions) setTechProductData(result.productDecisions);\n },\n () => setTechProductData(undefined),\n undefined,\n artifactRefreshKey\n );\n\n const mergeFeatureId =\n (featureNode?.lifecycle === 'review' &&\n (featureNode?.state === 'action-required' || featureNode?.state === 'error')) ||\n (featureNode?.lifecycle === 'maintain' && featureNode?.pr)\n ? featureNode.featureId\n : null;\n const isLoadingMerge = useArtifactFetch(\n mergeFeatureId,\n getMergeReviewData,\n (result) => {\n if ('error' in result) {\n toast.error(result.error);\n return;\n }\n setMergeData(result);\n },\n () => setMergeData(null),\n 'Failed to load merge review data',\n artifactRefreshKey\n );\n\n // ── Close guard ──────────────────────────────────────────────────────\n const isChatDirty = chatInput.trim().length > 0;\n const isPrdDirty =\n featureNode?.lifecycle === 'requirements' &&\n featureNode?.state === 'action-required' &&\n Object.keys(prdDefaultSelections).some((k) => prdDefaultSelections[k] !== prdSelections[k]);\n const isDirty = isChatDirty || isPrdDirty;\n\n const onReset = useCallback(() => {\n setChatInput('');\n setPrdSelections({ ...prdDefaultSelections });\n }, [prdDefaultSelections]);\n\n const { attemptClose } = useGuardedDrawerClose({ open: isOpen, isDirty, onClose, onReset });\n\n // ── Approve / reject handlers ─────────────────────────────────────────\n\n const handleReject = useCallback(\n async (\n feedback: string,\n label: string,\n attachments: RejectAttachment[] = [],\n onDone?: () => void\n ) => {\n if (!featureNode?.featureId) return;\n isRejectingRef.current = true;\n setIsRejecting(true);\n try {\n const attachmentPaths = attachments.map((a) => a.path).filter(Boolean);\n const notedAttachments = attachments.filter((a) => a.notes?.trim());\n const feedbackWithNotes =\n notedAttachments.length > 0\n ? `${feedback}\\n\\nImage notes:\\n${notedAttachments.map((a) => `- @${a.path}: ${a.notes!.trim()}`).join('\\n')}`\n : feedback;\n const result = await rejectFeature(\n featureNode.featureId,\n feedbackWithNotes,\n attachmentPaths\n );\n if (!result.rejected) {\n toast.error(result.error ?? `Failed to reject ${label.toLowerCase()}`);\n return;\n }\n rejectSound.play();\n setChatInput('');\n toast.success(`${label} rejected — agent re-iterating (iteration ${result.iteration})`);\n if (result.iterationWarning) {\n toast.warning(\n `Iteration ${result.iteration} — consider approving or adjusting feedback to avoid excessive iterations`\n );\n }\n // Optimistically update canvas node before SSE arrives (~500ms delay)\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-approved', {\n detail: { featureId: featureNode.featureId },\n })\n );\n onClose();\n onDone?.();\n } finally {\n isRejectingRef.current = false;\n setIsRejecting(false);\n }\n },\n [featureNode, onClose, rejectSound]\n );\n\n const handlePrdReject = useCallback(\n (feedback: string, attachments: RejectAttachment[]) =>\n handleReject(feedback, 'Requirements', attachments, () => setPrdSelections({})),\n [handleReject]\n );\n const handleTechReject = useCallback(\n (feedback: string, attachments: RejectAttachment[]) =>\n handleReject(feedback, 'Plan', attachments),\n [handleReject]\n );\n const handleMergeReject = useCallback(\n (feedback: string, attachments: RejectAttachment[]) =>\n handleReject(feedback, 'Merge', attachments),\n [handleReject]\n );\n\n const handleSimpleApprove = useCallback(\n async (label: string) => {\n if (!featureNode?.featureId) return;\n const result = await approveFeature(featureNode.featureId);\n if (!result.approved) {\n toast.error(result.error ?? `Failed to approve ${label.toLowerCase()}`);\n return;\n }\n setChatInput('');\n toast.success(`${label} approved — agent resuming`);\n // Optimistically update canvas node before SSE arrives (~500ms delay)\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-approved', {\n detail: { featureId: featureNode.featureId },\n })\n );\n onClose();\n },\n [featureNode, onClose]\n );\n\n const handlePrdApprove = useCallback(\n async (_actionId: string) => {\n if (view.type !== 'feature' || !featureNode) return;\n let payload: PrdApprovalPayload | undefined;\n if (prdData) {\n const changedSelections: QuestionSelectionChange[] = [];\n for (const [questionId, optionId] of Object.entries(prdSelections)) {\n const question = prdData.questions.find((q) => q.id === questionId);\n const option = question?.options.find((o) => o.id === optionId);\n if (question && option) {\n changedSelections.push({ questionId: question.question, selectedOption: option.label });\n }\n }\n payload = { approved: true, changedSelections };\n }\n const result = await approveFeature(featureNode.featureId, payload);\n if (!result.approved) {\n toast.error(result.error ?? 'Failed to approve requirements');\n return;\n }\n setChatInput('');\n toast.success('Requirements approved — agent resuming');\n // Optimistically update canvas node before SSE arrives (~500ms delay)\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-approved', {\n detail: { featureId: featureNode.featureId },\n })\n );\n setPrdSelections({});\n onClose();\n },\n [view, featureNode, prdData, prdSelections, onClose]\n );\n\n const handleTechApprove = useCallback(() => handleSimpleApprove('Plan'), [handleSimpleApprove]);\n const handleMergeApprove = useCallback(() => handleSimpleApprove('Merge'), [handleSimpleApprove]);\n\n const handleDelete = useCallback(\n async (featureId: string, cleanup?: boolean, cascadeDelete?: boolean, closePr?: boolean) => {\n setIsDeleting(true);\n // Close the delete dialog and drawer before the server action so the\n // user sees immediate feedback. We dispatch a DOM event so the canvas\n // control center can run its own optimistic delete flow (deleting state,\n // mutation guard, node removal) in parallel.\n setDeleteDialogOpen(false);\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-delete-requested', {\n detail: { featureId, cleanup, cascadeDelete, closePr },\n })\n );\n router.push('/');\n },\n [router]\n );\n\n const handleArchive = useCallback(\n (featureId: string) => {\n setIsArchiving(true);\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-archive-requested', {\n detail: { featureId },\n })\n );\n router.push('/');\n },\n [router]\n );\n\n const handleUnarchive = useCallback(\n (featureId: string) => {\n setIsArchiving(true);\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-unarchive-requested', {\n detail: { featureId },\n })\n );\n router.push('/');\n },\n [router]\n );\n\n const handleRetry = useCallback(async (featureId: string) => {\n const result = await resumeFeature(featureId);\n if (result.error) {\n toast.error(result.error);\n return;\n }\n toast.success('Feature resumed — agent restarting');\n window.dispatchEvent(\n new CustomEvent('shipit-ai:feature-approved', {\n detail: { featureId },\n })\n );\n setView((prev) => {\n if (prev.type !== 'feature') return prev;\n return { ...prev, node: { ...prev.node, state: 'running' } };\n });\n }, []);\n\n const handleStop = useCallback(async (featureId: string) => {\n const result = await stopFeature(featureId);\n if (!result.stopped) {\n toast.error(result.error ?? 'Failed to stop');\n return;\n }\n toast.success('Agent stopped');\n setView((prev) => {\n if (prev.type !== 'feature') return prev;\n return { ...prev, node: { ...prev.node, state: 'error' } };\n });\n }, []);\n\n const handleStart = useCallback(async (featureId: string) => {\n const result = await startFeature(featureId);\n if (result.error) {\n toast.error(result.error);\n return;\n }\n toast.success('Feature started');\n // Optimistically update the drawer view\n setView((prev) => {\n if (prev.type !== 'feature') return prev;\n return { ...prev, node: { ...prev.node, state: 'running' } };\n });\n }, []);\n\n // ── Hooks (always called unconditionally per Rules of Hooks) ──────────\n\n const featureActionsInput =\n featureNode?.repositoryPath && featureNode?.branch\n ? {\n featureId: featureNode.featureId,\n repositoryPath: featureNode.repositoryPath,\n branch: featureNode.branch,\n worktreePath: featureNode.worktreePath,\n specPath: featureNode.specPath,\n }\n : null;\n const featureActions = useFeatureActions(featureActionsInput);\n\n // Branch sync status — only when the feature flag is on, the feature has a branch,\n // and the repository has a remote (no remote = no sync needed)\n const syncFeatureId =\n featureFlags.gitRebaseSync && featureNode?.branch && featureNode?.remoteUrl\n ? featureNode.featureId\n : null;\n const {\n data: syncData,\n loading: syncLoading,\n error: syncError,\n refresh: refreshSync,\n } = useBranchSyncStatus(syncFeatureId);\n\n // Auto-refresh sync status after a successful rebase\n const prevRebaseLoadingRef = useRef(featureActions.rebaseLoading);\n useEffect(() => {\n if (\n prevRebaseLoadingRef.current &&\n !featureActions.rebaseLoading &&\n !featureActions.rebaseError\n ) {\n refreshSync();\n }\n prevRebaseLoadingRef.current = featureActions.rebaseLoading;\n }, [featureActions.rebaseLoading, featureActions.rebaseError, refreshSync]);\n\n const featureDeployTarget =\n featureNode?.repositoryPath && featureNode.branch\n ? {\n targetId: featureNode.featureId,\n targetType: 'feature' as const,\n repositoryPath: featureNode.repositoryPath,\n branch: featureNode.branch,\n }\n : null;\n\n const deployAction = useDeployAction(featureDeployTarget);\n const isFeatureDeployActive =\n deployAction.status === 'Booting' || deployAction.status === 'Ready';\n\n // ── Short ID copy ───────────────────────────────────────────────────\n const COPY_FEEDBACK_DELAY = 2000;\n const [idCopied, setIdCopied] = useState(false);\n const handleCopyId = useCallback(() => {\n if (!featureNode?.featureId) return;\n void navigator.clipboard.writeText(featureNode.featureId);\n setIdCopied(true);\n setTimeout(() => setIdCopied(false), COPY_FEEDBACK_DELAY);\n }, [featureNode?.featureId]);\n\n // ── Header ────────────────────────────────────────────────────────────\n\n let headerContent: React.ReactNode = undefined;\n\n if (featureNode) {\n const shortId = featureNode.featureId.slice(0, 8);\n {\n /* Reusable toolbar icon button classes */\n }\n const tbBtn =\n 'text-muted-foreground hover:bg-foreground/8 hover:text-foreground inline-flex size-8 items-center justify-center rounded-[3px] disabled:opacity-40';\n const tbSep = 'bg-border/60 mx-1.5 h-5 w-px shrink-0';\n\n headerContent = (\n <div data-testid=\"feature-drawer-toolbar\">\n <div className=\"flex h-10 items-center px-2\" data-testid=\"feature-drawer-actions\">\n {/* ── Left: Open + Run/Stop ── */}\n {featureActionsInput && featureNode?.state !== 'done' ? (\n <OpenActionMenu\n actions={featureActions}\n repositoryPath={featureActionsInput.repositoryPath}\n worktreePath={featureActionsInput.worktreePath}\n showSpecs={!!featureActionsInput.specPath}\n />\n ) : null}\n {featureActionsInput &&\n featureNode?.state !== 'done' &&\n featureFlags.envDeploy &&\n featureDeployTarget ? (\n <>\n <div className={tbSep} />\n <TooltipProvider delayDuration={300}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled={deployAction.deployLoading || deployAction.stopLoading}\n onClick={isFeatureDeployActive ? deployAction.stop : deployAction.deploy}\n className={cn(\n 'inline-flex size-7 items-center justify-center rounded-[3px] disabled:opacity-40',\n isFeatureDeployActive\n ? 'text-red-500 hover:bg-red-500/10 hover:text-red-400'\n : 'text-green-600 hover:bg-green-500/10 dark:text-green-500'\n )}\n aria-label={\n isFeatureDeployActive\n ? t('featureDrawer.stopDevServer')\n : t('featureDrawer.startDevServer')\n }\n >\n {deployAction.deployLoading || deployAction.stopLoading ? (\n <LoaderCircle className=\"size-4 animate-spin\" />\n ) : isFeatureDeployActive ? (\n <Square className=\"size-4\" />\n ) : (\n <Play className=\"size-4\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n {isFeatureDeployActive\n ? t('featureDrawer.stopDevServer')\n : t('featureDrawer.startDevServer')}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n {isFeatureDeployActive ? (\n <DeploymentStatusBadge\n status={deployAction.status}\n url={deployAction.url}\n targetId={featureDeployTarget?.targetId}\n />\n ) : null}\n </>\n ) : null}\n\n {/* ── Spacer ── */}\n <div className=\"flex-1\" />\n\n {/* ── Right: ID · archive · delete ── */}\n <div className=\"flex items-center\">\n <code className=\"text-muted-foreground/70 font-mono text-[10px] tracking-wide select-none\">\n {shortId}\n </code>\n <TooltipProvider delayDuration={300}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={handleCopyId}\n className={tbBtn}\n aria-label={t('featureDrawer.copyFeatureId')}\n data-testid=\"feature-drawer-copy-id\"\n >\n {idCopied ? (\n <Check className=\"size-4 text-green-500\" />\n ) : (\n <Copy className=\"size-4\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n {t('featureDrawer.copyFeatureId')}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n {featureNode.featureId ? (\n <>\n <div className={tbSep} />\n <TooltipProvider delayDuration={300}>\n {featureNode.state === 'archived' ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled={isArchiving}\n className={tbBtn}\n aria-label={t('featureDrawer.unarchiveFeature')}\n data-testid=\"feature-drawer-unarchive\"\n onClick={() => handleUnarchive(featureNode.featureId)}\n >\n {isArchiving ? (\n <LoaderCircle className=\"size-4 animate-spin\" />\n ) : (\n <ArchiveRestore className=\"size-3\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n {t('featureDrawer.unarchiveFeature')}\n </TooltipContent>\n </Tooltip>\n ) : featureNode.state !== 'deleting' ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled={isArchiving}\n className={tbBtn}\n aria-label={t('featureDrawer.archiveFeature')}\n data-testid=\"feature-drawer-archive\"\n onClick={() => handleArchive(featureNode.featureId)}\n >\n {isArchiving ? (\n <LoaderCircle className=\"size-4 animate-spin\" />\n ) : (\n <Archive className=\"size-3\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n {t('featureDrawer.archiveFeature')}\n </TooltipContent>\n </Tooltip>\n ) : null}\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled={isDeleting}\n className={cn(tbBtn, 'hover:bg-destructive/10 hover:text-destructive')}\n aria-label={t('featureDrawer.deleteFeature')}\n data-testid=\"feature-drawer-delete\"\n onClick={() => setDeleteDialogOpen(true)}\n >\n {isDeleting ? (\n <LoaderCircle className=\"size-4 animate-spin\" />\n ) : (\n <Trash2 className=\"size-3\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n {t('featureDrawer.deleteFeature')}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n <DeleteFeatureDialog\n open={deleteDialogOpen}\n onOpenChange={setDeleteDialogOpen}\n onConfirm={(cleanup, cascadeDelete, closePr) =>\n handleDelete(featureNode.featureId, cleanup, cascadeDelete, closePr)\n }\n isDeleting={isDeleting}\n featureName={featureNode.name}\n featureId={featureNode.featureId}\n hasChildren={featureNode.hasChildren}\n hasOpenPr={!!featureNode.pr && featureNode.pr.status === 'Open'}\n />\n </>\n ) : null}\n </div>\n </div>\n </div>\n );\n }\n\n // ── Body ──────────────────────────────────────────────────────────────\n\n let body: React.ReactNode = null;\n\n if (view.type === 'feature' && featureNode) {\n const enrichedNode = {\n ...featureNode,\n ...(featureNode.state === 'error' && { onRetry: handleRetry }),\n ...(featureNode.state === 'pending' && { onStart: handleStart }),\n };\n body = (\n <FeatureDrawerTabs\n featureName={featureNode.name}\n headerContent={headerContent}\n featureNode={enrichedNode}\n featureId={featureNode.featureId}\n initialTab={view.initialTab}\n urlTab={urlTab}\n sseEvents={events}\n prdData={prdData}\n prdSelections={prdSelections}\n onPrdSelect={(qId, oId) => setPrdSelections((prev) => ({ ...prev, [qId]: oId }))}\n onPrdApprove={handlePrdApprove}\n onPrdReject={handlePrdReject}\n isPrdLoading={isLoadingPrd}\n techData={techData}\n onTechApprove={handleTechApprove}\n onTechReject={handleTechReject}\n isTechLoading={isLoadingTech}\n productData={isLoadingTechProduct ? null : techProductData}\n mergeData={mergeData}\n onMergeApprove={handleMergeApprove}\n onMergeReject={handleMergeReject}\n isMergeLoading={isLoadingMerge}\n syncStatus={syncFeatureId ? syncData : undefined}\n syncLoading={syncLoading}\n syncError={syncError}\n onRefreshSync={syncFeatureId ? refreshSync : undefined}\n onRebaseOnMain={syncFeatureId ? featureActions.rebaseOnMain : undefined}\n rebaseLoading={featureActions.rebaseLoading}\n rebaseError={featureActions.rebaseError}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={setChatInput}\n interactiveAgentEnabled={interactiveAgentEnabled}\n onRetry={handleRetry}\n onStop={handleStop}\n onStart={handleStart}\n />\n );\n }\n\n return (\n <BaseDrawer\n open={isOpen}\n onClose={attemptClose}\n size=\"lg\"\n modal={false}\n data-testid={view.type === 'feature' ? 'feature-drawer' : 'repository-drawer'}\n >\n {body}\n </BaseDrawer>\n );\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"404541317062abd248dc6d01362962176bd21859e5\":{\"name\":\"getFeatureArtifact\"}},\"src/presentation/web/app/actions/get-feature-artifact.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"404541317062abd248dc6d01362962176bd21859e5\",callServer,void 0,findSourceMapURL,\"getFeatureArtifact\");export{$$RSC_SERVER_ACTION_0 as getFeatureArtifact};","/* __next_internal_action_entry_do_not_use__ [{\"4001823af7df460ee722f6533550e931dd1246ee6e\":{\"name\":\"getResearchArtifact\"}},\"src/presentation/web/app/actions/get-research-artifact.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"4001823af7df460ee722f6533550e931dd1246ee6e\",callServer,void 0,findSourceMapURL,\"getResearchArtifact\");export{$$RSC_SERVER_ACTION_0 as getResearchArtifact};","/* __next_internal_action_entry_do_not_use__ [{\"404d6c839ca95dce9f8da9958e90801549e26b3f69\":{\"name\":\"getMergeReviewData\"}},\"src/presentation/web/app/actions/get-merge-review-data.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"404d6c839ca95dce9f8da9958e90801549e26b3f69\",callServer,void 0,findSourceMapURL,\"getMergeReviewData\");export{$$RSC_SERVER_ACTION_0 as getMergeReviewData};","'use client';\n\nimport { useState } from 'react';\nimport {\n Code2,\n Terminal,\n FolderOpen,\n FileText,\n Copy,\n Check,\n LoaderCircle,\n CircleAlert,\n} from 'lucide-react';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\nimport type { OpenActionMenuProps } from './config';\n\nconst COPY_FEEDBACK_DELAY = 2000;\n\nconst tbBtn =\n 'text-muted-foreground hover:bg-foreground/8 hover:text-foreground inline-flex size-8 items-center justify-center rounded-[3px] disabled:opacity-40';\n\nfunction TbIcon({\n loading,\n error,\n icon: Icon,\n}: {\n loading?: boolean;\n error?: string | null;\n icon: React.ComponentType<{ className?: string }>;\n}) {\n if (loading) return <LoaderCircle className=\"size-3.5 animate-spin\" />;\n if (error) return <CircleAlert className=\"text-destructive size-3.5\" />;\n return <Icon className=\"size-4\" />;\n}\n\nexport function OpenActionMenu({\n actions,\n repositoryPath,\n worktreePath,\n showSpecs,\n}: OpenActionMenuProps) {\n const [copied, setCopied] = useState(false);\n\n const handleCopyPath = () => {\n void navigator.clipboard.writeText(worktreePath ?? repositoryPath);\n setCopied(true);\n setTimeout(() => setCopied(false), COPY_FEEDBACK_DELAY);\n };\n\n return (\n <TooltipProvider delayDuration={300}>\n <div className=\"flex items-center\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className={tbBtn}\n onClick={actions.openInIde}\n disabled={actions.ideLoading}\n aria-label=\"Open in IDE\"\n >\n <TbIcon loading={actions.ideLoading} error={actions.ideError} icon={Code2} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n Open in IDE\n </TooltipContent>\n </Tooltip>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className={tbBtn}\n onClick={actions.openInShell}\n disabled={actions.shellLoading}\n aria-label=\"Open terminal\"\n >\n <TbIcon loading={actions.shellLoading} error={actions.shellError} icon={Terminal} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n Open terminal\n </TooltipContent>\n </Tooltip>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className={tbBtn}\n onClick={actions.openFolder}\n disabled={actions.folderLoading}\n aria-label=\"Open folder\"\n >\n <TbIcon\n loading={actions.folderLoading}\n error={actions.folderError}\n icon={FolderOpen}\n />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n Open folder\n </TooltipContent>\n </Tooltip>\n\n {showSpecs ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n className={tbBtn}\n onClick={actions.openSpecsFolder}\n disabled={actions.specsLoading}\n aria-label=\"Open specs\"\n >\n <TbIcon loading={actions.specsLoading} error={actions.specsError} icon={FileText} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n Open specs\n </TooltipContent>\n </Tooltip>\n ) : null}\n\n <Tooltip>\n <TooltipTrigger asChild>\n <button type=\"button\" className={tbBtn} onClick={handleCopyPath} aria-label=\"Copy path\">\n {copied ? <Check className=\"size-3.5 text-green-500\" /> : <Copy className=\"size-4\" />}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"text-xs\">\n {copied ? 'Copied!' : 'Copy path'}\n </TooltipContent>\n </Tooltip>\n </div>\n </TooltipProvider>\n );\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"4080593bcaa215bcf803216987a55d49c5f44ddfe1\":{\"name\":\"getFeaturePhaseTimings\"}},\"src/presentation/web/app/actions/get-feature-phase-timings.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"4080593bcaa215bcf803216987a55d49c5f44ddfe1\",callServer,void 0,findSourceMapURL,\"getFeaturePhaseTimings\");export{$$RSC_SERVER_ACTION_0 as getFeaturePhaseTimings};","/* __next_internal_action_entry_do_not_use__ [{\"40ebd85d1a75c122fe0baf6b6aec39b989aa1ad5a3\":{\"name\":\"getFeaturePlan\"}},\"src/presentation/web/app/actions/get-feature-plan.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"40ebd85d1a75c122fe0baf6b6aec39b989aa1ad5a3\",callServer,void 0,findSourceMapURL,\"getFeaturePlan\");export{$$RSC_SERVER_ACTION_0 as getFeaturePlan};","'use client';\n\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { PaperclipIcon, Send, ChevronLeft, Check, TriangleAlert } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { Textarea } from '@/components/ui/textarea';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\nimport { useSoundAction } from '@/hooks/use-sound-action';\nimport { AttachmentChip } from '@/components/common/attachment-chip';\nimport { pickFiles } from '@/components/common/feature-create-drawer/pick-files';\nimport type { DrawerActionBarProps, RejectAttachment } from './drawer-action-bar-config';\n\nconst MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB\n\nconst ALLOWED_EXTENSIONS = new Set([\n '.png',\n '.jpg',\n '.jpeg',\n '.gif',\n '.webp',\n '.svg',\n '.bmp',\n '.ico',\n '.pdf',\n '.doc',\n '.docx',\n '.xls',\n '.xlsx',\n '.ppt',\n '.pptx',\n '.txt',\n '.md',\n '.csv',\n '.json',\n '.yaml',\n '.yml',\n '.xml',\n '.ts',\n '.tsx',\n '.js',\n '.jsx',\n '.py',\n '.rb',\n '.go',\n '.rs',\n '.java',\n '.c',\n '.cpp',\n '.h',\n '.hpp',\n '.cs',\n '.swift',\n '.kt',\n '.html',\n '.css',\n '.scss',\n '.less',\n '.sh',\n '.bash',\n '.zsh',\n '.fish',\n '.toml',\n '.ini',\n '.cfg',\n '.conf',\n '.env',\n '.zip',\n '.tar',\n '.gz',\n '.log',\n]);\n\nfunction getExtension(filename: string): string {\n const dot = filename.lastIndexOf('.');\n return dot >= 0 ? filename.slice(dot).toLowerCase() : '';\n}\n\nexport function DrawerActionBar({\n onReject,\n onApprove,\n approveLabel,\n approveVariant = 'default',\n revisionPlaceholder,\n isProcessing = false,\n isRejecting = false,\n children,\n chatInput: controlledChatInput,\n onChatInputChange,\n}: DrawerActionBarProps) {\n const { t } = useTranslation('web');\n const isWarning = approveVariant === 'warning';\n const ApproveIcon = isWarning ? TriangleAlert : Check;\n const accentBg = isWarning ? 'bg-orange-500/85' : 'bg-blue-500/85';\n const accentBorder = isWarning ? 'border-orange-400/60' : 'border-blue-400/60';\n const [internalChatInput, setInternalChatInput] = useState('');\n const chatInput = controlledChatInput ?? internalChatInput;\n const setChatInput = onChatInputChange ?? setInternalChatInput;\n const approveSound = useSoundAction('approve');\n const disabled = isProcessing || isRejecting;\n\n const [attachments, setAttachments] = useState<RejectAttachment[]>([]);\n const [isDragOver, setIsDragOver] = useState(false);\n const [uploadError, setUploadError] = useState<string | null>(null);\n const [hoverExpanded, setHoverExpanded] = useState(false);\n const [ctrlHeld, setCtrlHeld] = useState(false);\n const [shiftHeld, setShiftHeld] = useState(false);\n const hasText = chatInput.trim().length > 0;\n const approveExpanded = hasText ? hoverExpanded || (ctrlHeld && shiftHeld) : !hoverExpanded;\n const rejectHighlighted = hasText ? ctrlHeld && !shiftHeld : false;\n const dragCounterRef = useRef(0);\n const sessionIdRef = useRef(crypto.randomUUID());\n const formRef = useRef<HTMLFormElement>(null);\n\n // Track Ctrl/Meta + Shift keys for button state\n useEffect(() => {\n function onKeyDown(e: KeyboardEvent) {\n if (e.key === 'Control' || e.key === 'Meta') setCtrlHeld(true);\n if (e.key === 'Shift') setShiftHeld(true);\n }\n function onKeyUp(e: KeyboardEvent) {\n if (e.key === 'Control' || e.key === 'Meta') setCtrlHeld(false);\n if (e.key === 'Shift') setShiftHeld(false);\n }\n function onBlur() {\n setCtrlHeld(false);\n setShiftHeld(false);\n }\n window.addEventListener('keydown', onKeyDown);\n window.addEventListener('keyup', onKeyUp);\n window.addEventListener('blur', onBlur);\n return () => {\n window.removeEventListener('keydown', onKeyDown);\n window.removeEventListener('keyup', onKeyUp);\n window.removeEventListener('blur', onBlur);\n };\n }, []);\n\n const handleFiles = useCallback(async (fileList: File[]) => {\n setUploadError(null);\n\n for (const file of fileList) {\n if (file.size > MAX_FILE_SIZE) {\n setUploadError(`\"${file.name}\" exceeds 10 MB limit`);\n return;\n }\n const ext = getExtension(file.name);\n if (ext && !ALLOWED_EXTENSIONS.has(ext)) {\n setUploadError(`File type \"${ext}\" is not allowed`);\n return;\n }\n }\n\n for (const file of fileList) {\n const tempId = crypto.randomUUID();\n\n setAttachments((prev) => [\n ...prev,\n {\n id: tempId,\n name: file.name,\n size: file.size,\n mimeType: file.type || 'application/octet-stream',\n path: '',\n loading: true,\n },\n ]);\n\n try {\n const formData = new FormData();\n formData.append('file', file);\n formData.append('sessionId', sessionIdRef.current);\n\n const res = await fetch('/api/attachments/upload', {\n method: 'POST',\n body: formData,\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: 'Upload failed' }));\n setAttachments((prev) => prev.filter((a) => a.id !== tempId));\n setUploadError(body.error ?? 'Upload failed');\n return;\n }\n\n const uploaded = await res.json();\n setAttachments((prev) => {\n const isDupe = prev.some((a) => a.id !== tempId && a.path === uploaded.path);\n if (isDupe) return prev.filter((a) => a.id !== tempId);\n return prev.map((a) =>\n a.id === tempId ? { ...uploaded, id: tempId, loading: false } : a\n );\n });\n } catch {\n setAttachments((prev) => prev.filter((a) => a.id !== tempId));\n setUploadError('Upload failed');\n }\n }\n }, []);\n\n const handleDragEnter = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounterRef.current += 1;\n if (dragCounterRef.current === 1) setIsDragOver(true);\n }, []);\n\n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounterRef.current -= 1;\n if (dragCounterRef.current === 0) setIsDragOver(false);\n }, []);\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }, []);\n\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dragCounterRef.current = 0;\n setIsDragOver(false);\n const files = Array.from(e.dataTransfer.files);\n if (files.length > 0) handleFiles(files);\n },\n [handleFiles]\n );\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent) => {\n const items = e.clipboardData?.items;\n if (!items) return;\n const files: File[] = [];\n for (const item of Array.from(items)) {\n if (item.kind === 'file') {\n const file = item.getAsFile();\n if (file) files.push(file);\n }\n }\n if (files.length > 0) {\n e.preventDefault();\n handleFiles(files);\n }\n },\n [handleFiles]\n );\n\n const handleAddFiles = useCallback(async () => {\n try {\n const files = await pickFiles();\n if (files) {\n setAttachments((prev) => {\n const existingPaths = new Set(prev.map((f) => f.path));\n const unique = files\n .filter((f) => !existingPaths.has(f.path))\n .map(\n (f): RejectAttachment => ({\n id: crypto.randomUUID(),\n name: f.name,\n size: f.size,\n mimeType: 'application/octet-stream',\n path: f.path,\n })\n );\n return unique.length > 0 ? [...prev, ...unique] : prev;\n });\n }\n } catch {\n // Native dialog failed — silently ignore\n }\n }, []);\n\n const handleRemoveFile = useCallback((id: string) => {\n setAttachments((prev) => prev.filter((f) => f.id !== id));\n }, []);\n\n const handleNotesChange = useCallback((id: string, notes: string) => {\n setAttachments((prev) => prev.map((f) => (f.id === id ? { ...f, notes } : f)));\n }, []);\n\n const clearForm = useCallback(() => {\n setChatInput('');\n setAttachments([]);\n setUploadError(null);\n }, [setChatInput]);\n\n function handleFormSubmit(e: { preventDefault: () => void }) {\n e.preventDefault();\n const text = chatInput.trim();\n\n if (approveExpanded) {\n // Approve mode\n approveSound.play();\n onApprove();\n clearForm();\n } else {\n // Reject mode — text required\n if (!text || !onReject) return;\n onReject(\n text,\n attachments.filter((a) => !a.loading)\n );\n clearForm();\n }\n }\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {\n e.preventDefault();\n // Ctrl+Shift+Enter = approve, Ctrl+Enter = reject\n formRef.current?.requestSubmit();\n }\n }, []);\n\n const modKey =\n typeof navigator !== 'undefined' && /Mac/i.test(navigator.userAgent) ? '⌘' : 'Ctrl';\n\n return (\n <div className=\"border-border shrink-0 border-t\">\n {children}\n {onReject ? (\n <TooltipProvider delayDuration={400}>\n <form ref={formRef} onSubmit={handleFormSubmit} className=\"p-3\">\n <div\n role=\"region\"\n aria-label={t('createDrawer.fileDropZone')}\n data-drag-over={isDragOver ? 'true' : 'false'}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n className={cn(\n 'rounded-md border-2 border-transparent transition-colors',\n isDragOver && 'border-primary/50 bg-primary/5'\n )}\n >\n <div className=\"border-input focus-within:ring-ring/50 focus-within:border-ring flex flex-col overflow-hidden rounded-md border shadow-xs transition-[color,box-shadow] focus-within:ring-[3px]\">\n <Textarea\n placeholder={revisionPlaceholder ?? 'Ask AI to revise...'}\n aria-label={revisionPlaceholder ?? 'Ask AI to revise...'}\n disabled={disabled}\n value={chatInput}\n onChange={(e) => setChatInput(e.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n rows={1}\n aria-invalid={!!uploadError}\n aria-describedby={uploadError ? 'drawer-action-upload-error' : undefined}\n className=\"max-h-[35dvh] min-h-9 flex-1 resize-none overflow-y-auto rounded-none border-0 py-2 shadow-none focus-visible:ring-0\"\n data-testid=\"drawer-chat-input\"\n />\n {attachments.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-1.5 px-3 py-2\">\n {attachments.map((file) => (\n <AttachmentChip\n key={file.id}\n name={file.name}\n size={file.size}\n mimeType={file.mimeType}\n path={file.path}\n onRemove={() => handleRemoveFile(file.id)}\n disabled={disabled}\n loading={file.loading}\n notes={file.notes}\n onNotesChange={(notes) => handleNotesChange(file.id, notes)}\n />\n ))}\n </div>\n )}\n {uploadError ? (\n <p\n id=\"drawer-action-upload-error\"\n className=\"text-destructive px-3 pb-2 text-xs\"\n role=\"alert\"\n >\n {uploadError}\n </p>\n ) : null}\n <div className=\"border-input flex items-center gap-2 border-t px-3 py-1.5\">\n <span className=\"text-muted-foreground flex-1 truncate text-[11px]\">\n <kbd className=\"bg-muted rounded px-1 py-0.5 font-mono text-[10px]\">\n {modKey}+Enter\n </kbd>{' '}\n {hasText ? 'reject' : 'approve'}\n </span>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={handleAddFiles}\n disabled={disabled}\n aria-label={t('chat.attachFiles')}\n className=\"text-muted-foreground hover:text-foreground cursor-pointer rounded p-1 transition-colors\"\n >\n <PaperclipIcon className=\"h-4 w-4\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\">{t('chat.attachFiles')}</TooltipContent>\n </Tooltip>\n\n {/* Single action button: Approve when empty, Reject when text present */}\n <div onMouseLeave={() => setHoverExpanded(false)}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"submit\"\n disabled={disabled}\n data-testid=\"drawer-action-submit\"\n className={cn(\n 'relative flex h-9 min-w-[12rem] cursor-pointer items-center overflow-hidden rounded-md border ps-4 pe-10 text-sm font-medium whitespace-nowrap transition-colors',\n 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n approveExpanded\n ? `${accentBorder} text-white`\n : rejectHighlighted\n ? 'border-primary bg-muted ring-primary/30 shadow-sm ring-1'\n : 'border-border bg-muted/50 hover:bg-muted shadow-sm'\n )}\n >\n {/* Accent fill — slides in from right */}\n <div\n className={cn(\n 'pointer-events-none absolute inset-0 transition-transform duration-300 ease-in-out',\n accentBg\n )}\n style={{\n transform: approveExpanded ? 'translateX(0)' : 'translateX(100%)',\n }}\n />\n {/* Reject content */}\n <span\n className={cn(\n 'absolute inset-0 z-10 flex items-center justify-center gap-2 pe-8 transition-opacity duration-300',\n approveExpanded ? 'opacity-0' : 'opacity-100'\n )}\n >\n <Send className=\"h-4 w-4 shrink-0\" />\n Reject\n </span>\n {/* Approve content — overlaid, centered */}\n <span\n className={cn(\n 'absolute inset-0 z-10 flex items-center justify-center gap-2 text-white transition-opacity duration-300',\n approveExpanded ? 'opacity-100' : 'opacity-0'\n )}\n >\n <ApproveIcon className=\"h-4 w-4 shrink-0\" />\n {approveLabel}\n </span>\n {/* Arrow indicator — hover trigger to toggle between modes */}\n <span\n className={cn(\n `border-input/60 absolute inset-y-0 right-0 z-20 flex w-8 cursor-pointer items-center justify-center rounded-e-[5px] border-s ${accentBg} transition-opacity duration-300`,\n !hasText && !hoverExpanded && 'pointer-events-none opacity-0'\n )}\n onMouseEnter={() => setHoverExpanded(true)}\n >\n <ChevronLeft className=\"h-4 w-4 text-white\" />\n </span>\n </button>\n </TooltipTrigger>\n {!isWarning ? (\n <TooltipContent side=\"top\">\n {approveExpanded\n ? approveLabel\n : t('drawerActionBar.sendRevisionFeedback')}\n </TooltipContent>\n ) : null}\n </Tooltip>\n </div>\n </div>\n </div>\n </div>\n </form>\n </TooltipProvider>\n ) : (\n <div className=\"flex items-center gap-2 px-4 pb-4\">\n <Button\n type=\"button\"\n className=\"flex-1\"\n disabled={disabled}\n onClick={() => {\n approveSound.play();\n onApprove();\n }}\n >\n {approveLabel}\n </Button>\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport { useState } from 'react';\nimport type { Components } from 'react-markdown';\nimport Markdown from 'react-markdown';\nimport { ChevronRight, GitCompareArrows, Layers } from 'lucide-react';\nimport { Badge } from '@/components/ui/badge';\nimport { DrawerActionBar } from '@/components/common/drawer-action-bar';\nimport { useSoundAction } from '@/hooks/use-sound-action';\nimport type {\n TechDecisionsReviewProps,\n TechDecisionsReviewData,\n TechDecision,\n} from './tech-decisions-review-config';\n\nconst markdownComponents: Components = {\n p: ({ children }) => (\n <p className=\"text-muted-foreground mb-2 text-xs leading-relaxed last:mb-0\">{children}</p>\n ),\n strong: ({ children }) => <strong className=\"text-foreground font-semibold\">{children}</strong>,\n em: ({ children }) => <em className=\"italic\">{children}</em>,\n code: ({ children, className }) =>\n className ? (\n <code className={`${className} text-[11px]`}>{children}</code>\n ) : (\n <code className=\"bg-muted text-foreground rounded-md px-1.5 py-0.5 font-mono text-[11px]\">\n {children}\n </code>\n ),\n pre: ({ children }) => (\n <pre className=\"bg-muted my-2 overflow-x-auto rounded-lg border p-3\">{children}</pre>\n ),\n ul: ({ children }) => (\n <ul className=\"text-muted-foreground mb-2 list-disc space-y-1 ps-4 text-xs\">{children}</ul>\n ),\n ol: ({ children }) => (\n <ol className=\"text-muted-foreground mb-2 list-decimal space-y-1 ps-4 text-xs\">{children}</ol>\n ),\n li: ({ children }) => <li className=\"leading-relaxed\">{children}</li>,\n a: ({ children, href }) => (\n <a\n href={href}\n className=\"text-primary underline underline-offset-2\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {children}\n </a>\n ),\n};\n\nfunction DecisionCard({ decision, index }: { decision: TechDecision; index: number }) {\n const [alternativesOpen, setAlternativesOpen] = useState(false);\n const expandSound = useSoundAction('expand');\n const collapseSound = useSoundAction('collapse');\n\n const handleToggleAlternatives = () => {\n // Play sound based on current state (before toggle)\n if (alternativesOpen) {\n collapseSound.play();\n } else {\n expandSound.play();\n }\n setAlternativesOpen((prev) => !prev);\n };\n\n return (\n <div className=\"border-border rounded-lg border\">\n {/* Header: number + title + chosen badge */}\n <div className=\"space-y-3 px-4 py-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-2.5\">\n <span className=\"bg-primary text-primary-foreground flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-xs font-bold\">\n {index + 1}\n </span>\n <div className=\"min-w-0\">\n <h3 className=\"text-foreground text-sm leading-tight font-semibold\">\n {decision.title}\n </h3>\n <p className=\"text-muted-foreground mt-0.5 text-xs\">{decision.chosen}</p>\n </div>\n </div>\n {'decisionName' in decision &&\n (decision as unknown as { decisionName?: string }).decisionName ? (\n <Badge variant=\"secondary\" className=\"bg-primary/10 text-primary shrink-0\">\n {(decision as unknown as { decisionName: string }).decisionName}\n </Badge>\n ) : null}\n </div>\n\n {/* Rationale */}\n {decision.rationale ? (\n <Markdown components={markdownComponents}>{decision.rationale}</Markdown>\n ) : null}\n </div>\n\n {/* Rejected alternatives (collapsed by default) */}\n {decision.rejected.length > 0 ? (\n <div className=\"border-border border-t\">\n <button\n type=\"button\"\n onClick={handleToggleAlternatives}\n className=\"text-muted-foreground hover:bg-muted/50 flex w-full items-center gap-1.5 px-4 py-3 text-xs font-medium transition-colors\"\n >\n <ChevronRight\n className={`h-3.5 w-3.5 transition-transform ${alternativesOpen ? 'rotate-90' : ''}`}\n />\n <Layers className=\"h-3.5 w-3.5\" />\n Other Options Considered ({decision.rejected.length})\n </button>\n {alternativesOpen ? (\n <div className=\"space-y-1.5 px-4 pb-3\">\n {decision.rejected.map((alt) => (\n <div key={alt} className=\"bg-primary/5 rounded-md px-3 py-2\">\n <span className=\"text-foreground text-xs\">{alt}</span>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\n/**\n * Renders the tech decisions content (header + decision cards) without the action bar.\n * Used by TechReviewTabs to compose with a shared DrawerActionBar.\n */\nexport function TechDecisionsContent({ data }: { data: TechDecisionsReviewData }) {\n const { summary, decisions } = data;\n\n if (decisions.length === 0) return null;\n\n return (\n <div className=\"space-y-4 p-4\">\n {/* Header */}\n <div className=\"flex items-start gap-3\">\n <div className=\"mt-1.5 h-2.5 w-2.5 shrink-0 rounded-full bg-blue-500\" />\n <div className=\"flex-1\">\n <h2 className=\"text-foreground text-sm font-bold\">\n Technical Implementation Plan Review\n </h2>\n {summary ? (\n <p className=\"text-muted-foreground mt-1 text-xs leading-relaxed\">{summary}</p>\n ) : null}\n </div>\n </div>\n\n {/* Section heading */}\n <div className=\"flex items-center gap-2 pt-1\">\n <GitCompareArrows className=\"text-primary h-4 w-4\" />\n <h3 className=\"text-foreground text-sm font-bold\">Technical Decisions</h3>\n </div>\n\n {/* Decision cards */}\n {decisions.map((decision, i) => (\n <DecisionCard key={decision.title} decision={decision} index={i} />\n ))}\n </div>\n );\n}\n\nexport function TechDecisionsReview({\n data,\n onApprove,\n onReject,\n isProcessing = false,\n isRejecting = false,\n}: TechDecisionsReviewProps) {\n if (data.decisions.length === 0) return null;\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"flex-1 overflow-y-auto\">\n <TechDecisionsContent data={data} />\n </div>\n\n <DrawerActionBar\n onReject={onReject}\n onApprove={onApprove}\n approveLabel=\"Approve Plan\"\n revisionPlaceholder=\"Ask AI to revise the plan...\"\n isProcessing={isProcessing}\n isRejecting={isRejecting}\n />\n </div>\n );\n}\n","'use client';\n\nimport { ClipboardList } from 'lucide-react';\nimport { Badge } from '@/components/ui/badge';\nimport type {\n ProductDecisionsSummaryProps,\n ProductDecisionItem,\n} from './product-decisions-summary-config';\n\nfunction ProductDecisionCard({ item, index }: { item: ProductDecisionItem; index: number }) {\n return (\n <div className=\"border-border rounded-lg border\">\n <div className=\"space-y-2 px-4 py-3\">\n <div className=\"flex items-start gap-2.5\">\n <span className=\"bg-primary text-primary-foreground flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-xs font-bold\">\n {index + 1}\n </span>\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"text-foreground text-sm leading-tight font-semibold\">{item.question}</h3>\n <div className=\"mt-1 flex items-center gap-2\">\n <p className=\"text-muted-foreground min-w-0 truncate text-xs\">\n {item.selectedOption}\n </p>\n {item.wasRecommended ? (\n <Badge className=\"shrink-0 px-1.5 py-0 text-[10px] whitespace-nowrap\">\n AI Recommended\n </Badge>\n ) : null}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nexport function ProductDecisionsSummary({ data }: ProductDecisionsSummaryProps) {\n const { questions } = data;\n\n if (questions.length === 0) return null;\n\n return (\n <div className=\"space-y-4 p-4\">\n {/* Section heading */}\n <div className=\"flex items-center gap-2\">\n <ClipboardList className=\"text-primary h-4 w-4\" />\n <h3 className=\"text-foreground text-sm font-bold\">Product Decisions</h3>\n </div>\n\n {/* Decision cards */}\n {questions.map((item, i) => (\n <ProductDecisionCard key={item.question} item={item} index={i} />\n ))}\n </div>\n );\n}\n","import { CircleCheck, LoaderCircle, CircleX } from 'lucide-react';\nimport { CiStatus } from '@shipit-ai/core/domain/generated/output';\nimport { Badge } from '@/components/ui/badge';\n\nexport function CiStatusBadge({ status }: { status: CiStatus }) {\n switch (status) {\n case CiStatus.Success:\n return (\n <Badge className=\"border-transparent bg-green-50 text-green-700 hover:bg-green-50\">\n <CircleCheck className=\"me-1 h-3.5 w-3.5\" />\n Passing\n </Badge>\n );\n case CiStatus.Pending:\n return (\n <Badge className=\"border-transparent bg-yellow-50 text-yellow-700 hover:bg-yellow-50\">\n <LoaderCircle className=\"me-1 h-3.5 w-3.5 animate-spin\" />\n Pending\n </Badge>\n );\n case CiStatus.Failure:\n return (\n <Badge className=\"border-transparent bg-red-50 text-red-700 hover:bg-red-50\">\n <CircleX className=\"me-1 h-3.5 w-3.5\" />\n Failing\n </Badge>\n );\n }\n}\n","'use client';\n\nimport { useState } from 'react';\nimport { ChevronRight, FileText, FilePlus, FileMinus, FileEdit } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport type { MergeReviewFileDiff, MergeReviewDiffHunk } from './merge-review-config';\n\nconst STATUS_CONFIG = {\n added: { icon: FilePlus, label: 'A', className: 'text-green-600' },\n modified: { icon: FileEdit, label: 'M', className: 'text-amber-600' },\n deleted: { icon: FileMinus, label: 'D', className: 'text-red-600' },\n renamed: { icon: FileEdit, label: 'R', className: 'text-blue-600' },\n} as const;\n\nfunction FileStatusIcon({ status }: { status: MergeReviewFileDiff['status'] }) {\n const config = STATUS_CONFIG[status];\n const Icon = config.icon;\n return <Icon className={cn('h-3.5 w-3.5 shrink-0', config.className)} />;\n}\n\nfunction HunkView({ hunk }: { hunk: MergeReviewDiffHunk }) {\n return (\n <div className=\"border-border border-t first:border-t-0\">\n <div className=\"bg-muted/50 text-muted-foreground px-3 py-1 font-mono text-[10px]\">\n {hunk.header}\n </div>\n <div className=\"font-mono text-[11px] leading-[18px]\">\n {hunk.lines.map((line) => (\n <div\n key={`${line.type}-${line.oldNumber ?? ''}-${line.newNumber ?? ''}`}\n className={cn(\n 'flex',\n line.type === 'added' && 'bg-green-50 dark:bg-green-950/30',\n line.type === 'removed' && 'bg-red-50 dark:bg-red-950/30'\n )}\n >\n <span className=\"text-muted-foreground w-10 shrink-0 px-1 text-end text-[10px] select-none\">\n {line.oldNumber ?? ''}\n </span>\n <span className=\"text-muted-foreground w-10 shrink-0 px-1 text-end text-[10px] select-none\">\n {line.newNumber ?? ''}\n </span>\n <span\n className={cn(\n 'w-4 shrink-0 text-center select-none',\n line.type === 'added' && 'text-green-700 dark:text-green-400',\n line.type === 'removed' && 'text-red-700 dark:text-red-400'\n )}\n >\n {line.type === 'added' ? '+' : line.type === 'removed' ? '-' : ' '}\n </span>\n <span className=\"min-w-0 flex-1 pe-2 break-all whitespace-pre-wrap\">\n {line.content}\n </span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nfunction FileDiffItem({ file }: { file: MergeReviewFileDiff }) {\n const [isOpen, setIsOpen] = useState(false);\n\n const fileName = file.path.split('/').pop() ?? file.path;\n const dirPath = file.path.includes('/') ? file.path.slice(0, file.path.lastIndexOf('/')) : '';\n\n return (\n <div className=\"border-border border-b last:border-b-0\">\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n className=\"hover:bg-muted/50 flex w-full items-center gap-2 px-3 py-2 text-start\"\n >\n <ChevronRight\n className={cn(\n 'text-muted-foreground h-3 w-3 shrink-0 transition-transform duration-150',\n isOpen && 'rotate-90'\n )}\n />\n <FileStatusIcon status={file.status} />\n <span className=\"text-foreground min-w-0 flex-1 truncate text-xs\">\n {dirPath ? (\n <>\n <span className=\"text-muted-foreground\">{dirPath}/</span>\n {fileName}\n </>\n ) : (\n fileName\n )}\n </span>\n {file.oldPath ? (\n <span className=\"text-muted-foreground truncate text-[10px]\">\n ← {file.oldPath.split('/').pop()}\n </span>\n ) : null}\n <span className=\"shrink-0 text-[10px]\">\n {file.additions > 0 ? <span className=\"text-green-600\">+{file.additions}</span> : null}\n {file.additions > 0 && file.deletions > 0 ? ' ' : null}\n {file.deletions > 0 ? <span className=\"text-red-600\">-{file.deletions}</span> : null}\n </span>\n </button>\n {isOpen && file.hunks.length > 0 ? (\n <div className=\"border-border overflow-x-auto border-t\">\n {file.hunks.map((hunk) => (\n <HunkView key={hunk.header} hunk={hunk} />\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport interface DiffViewProps {\n fileDiffs: MergeReviewFileDiff[];\n}\n\nexport function DiffView({ fileDiffs }: DiffViewProps) {\n if (fileDiffs.length === 0) return null;\n\n return (\n <div className=\"border-border rounded-lg border\">\n <div className=\"px-4 py-3\">\n <div className=\"mb-2 flex items-center gap-2\">\n <FileText className=\"text-muted-foreground h-4 w-4\" />\n <span className=\"text-foreground text-xs font-semibold\">Changed Files</span>\n <span className=\"text-muted-foreground text-[10px]\">({fileDiffs.length})</span>\n </div>\n </div>\n <div className=\"border-border border-t\">\n {fileDiffs.map((file) => (\n <FileDiffItem key={`${file.status}-${file.path}`} file={file} />\n ))}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useState } from 'react';\nimport {\n ExternalLink,\n TriangleAlert,\n FileDiff,\n GitCommitHorizontal,\n GitBranch,\n ArrowRight,\n Camera,\n FileText,\n MonitorPlay,\n Terminal,\n Download,\n ChevronDown,\n ChevronRight,\n} from 'lucide-react';\nimport { Badge } from '@/components/ui/badge';\nimport { CiStatusBadge } from '@/components/common/ci-status-badge';\nimport { DrawerActionBar } from '@/components/common/drawer-action-bar';\nimport { DiffView } from './diff-view';\nimport type { MergeReviewProps, MergeReviewEvidence } from './merge-review-config';\n\nconst EVIDENCE_ICONS: Record<MergeReviewEvidence['type'], typeof Camera> = {\n Screenshot: Camera,\n Video: MonitorPlay,\n TestOutput: FileText,\n TerminalRecording: Terminal,\n};\n\nconst IMAGE_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.bmp']);\nconst VIDEO_EXTENSIONS = new Set(['.mp4', '.webm', '.mov']);\n\nfunction getExtension(path: string): string {\n const dot = path.lastIndexOf('.');\n return dot >= 0 ? path.slice(dot).toLowerCase() : '';\n}\n\n/** Build the API URL for serving an evidence file (paths are pre-normalized to absolute). */\nfunction buildEvidenceUrl(absolutePath: string): string {\n return `/api/evidence?path=${encodeURIComponent(absolutePath)}`;\n}\n\nfunction EvidenceItem({ evidence }: { evidence: MergeReviewEvidence }) {\n const [expanded, setExpanded] = useState(true);\n const Icon = EVIDENCE_ICONS[evidence.type] ?? Camera;\n const ext = getExtension(evidence.relativePath);\n const url = buildEvidenceUrl(evidence.relativePath);\n const isImage = evidence.type === 'Screenshot' || IMAGE_EXTENSIONS.has(ext);\n const isVideo = evidence.type === 'Video' || VIDEO_EXTENSIONS.has(ext);\n const isText = evidence.type === 'TestOutput' || evidence.type === 'TerminalRecording';\n\n return (\n <li className=\"border-border rounded-md border\">\n <button\n type=\"button\"\n onClick={() => setExpanded(!expanded)}\n className=\"flex w-full cursor-pointer items-center gap-2.5 px-3 py-2.5 text-start\"\n >\n {expanded ? (\n <ChevronDown className=\"text-muted-foreground h-3 w-3 shrink-0\" />\n ) : (\n <ChevronRight className=\"text-muted-foreground h-3 w-3 shrink-0\" />\n )}\n <Icon className=\"text-muted-foreground h-3.5 w-3.5 shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <span className=\"text-foreground text-xs font-medium\">{evidence.description}</span>\n {evidence.taskRef ? (\n <span className=\"text-muted-foreground ms-1.5 text-[10px]\">({evidence.taskRef})</span>\n ) : null}\n </div>\n {url ? (\n <a\n href={url}\n download\n onClick={(e) => e.stopPropagation()}\n className=\"text-muted-foreground hover:text-foreground shrink-0 rounded p-1 transition-colors\"\n aria-label=\"Download\"\n >\n <Download className=\"h-3 w-3\" />\n </a>\n ) : null}\n </button>\n {expanded && url ? (\n <div className=\"border-border border-t px-3 py-2.5\">\n {isImage ? (\n /* eslint-disable-next-line @next/next/no-img-element */\n <img\n src={url}\n alt={evidence.description}\n className=\"max-h-80 w-full rounded-md border object-contain\"\n loading=\"lazy\"\n />\n ) : isVideo ? (\n <video\n src={url}\n controls\n className=\"max-h-80 w-full rounded-md border\"\n preload=\"metadata\"\n >\n <track kind=\"captions\" />\n </video>\n ) : isText ? (\n <EvidenceTextPreview url={url} />\n ) : (\n <p className=\"text-muted-foreground truncate font-mono text-[10px]\">\n {evidence.relativePath}\n </p>\n )}\n </div>\n ) : null}\n {expanded && !url ? (\n <div className=\"border-border border-t px-3 py-2.5\">\n <p className=\"text-muted-foreground truncate font-mono text-[10px]\">\n {evidence.relativePath}\n </p>\n </div>\n ) : null}\n </li>\n );\n}\n\nfunction EvidenceTextPreview({ url }: { url: string }) {\n const [content, setContent] = useState<string | null>(null);\n const [loaded, setLoaded] = useState(false);\n\n if (!loaded) {\n fetch(url)\n .then((r) => (r.ok ? r.text() : Promise.reject(new Error('Failed'))))\n .then((text) => {\n // Limit to first 100 lines for preview\n const lines = text.split('\\n');\n setContent(lines.length > 100 ? `${lines.slice(0, 100).join('\\n')}\\n...` : text);\n })\n .catch(() => setContent(null))\n .finally(() => setLoaded(true));\n\n return <div className=\"bg-muted/50 h-16 animate-pulse rounded-md\" />;\n }\n\n if (!content) {\n return <p className=\"text-muted-foreground text-[10px]\">Unable to load preview</p>;\n }\n\n return (\n <pre className=\"bg-muted/50 max-h-60 overflow-auto rounded-md p-3 font-mono text-[11px] leading-relaxed\">\n {content}\n </pre>\n );\n}\n\nfunction EvidenceList({ evidence }: { evidence: MergeReviewEvidence[] }) {\n return (\n <div className=\"border-border rounded-lg border\">\n <div className=\"px-4 py-3\">\n <div className=\"mb-3 flex items-center gap-2\">\n <Camera className=\"text-muted-foreground h-4 w-4\" />\n <span className=\"text-foreground text-xs font-semibold\">Evidence</span>\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {evidence.length}\n </Badge>\n </div>\n <ul className=\"space-y-2\">\n {evidence.map((e) => (\n <EvidenceItem key={`${e.type}-${e.relativePath}`} evidence={e} />\n ))}\n </ul>\n </div>\n </div>\n );\n}\n\nexport function MergeReview({\n data,\n readOnly = false,\n onApprove,\n onReject,\n isProcessing = false,\n isRejecting = false,\n chatInput,\n onChatInputChange,\n}: MergeReviewProps) {\n const { pr, diffSummary, fileDiffs, branch, warning, evidence, hideCiStatus } = data;\n const hasConflicts = pr?.mergeable === false;\n\n const handleApproveOrResolve =\n hasConflicts && onReject ? () => onReject('Resolve merge conflicts', []) : onApprove;\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"flex-1 space-y-4 overflow-y-auto p-4\">\n {/* Header */}\n <div className=\"flex items-start gap-3\">\n <div className=\"mt-1.5 h-2.5 w-2.5 shrink-0 rounded-full bg-emerald-500\" />\n <div className=\"flex-1\">\n <h2 className=\"text-foreground text-sm font-bold\">\n {readOnly ? 'Merge History' : 'Merge Review'}\n </h2>\n <p className=\"text-muted-foreground mt-1 text-xs leading-relaxed\">\n {readOnly\n ? 'This feature was merged. Review the pull request details and evidence below.'\n : pr\n ? 'Review the pull request details and approve to merge.'\n : 'Review the changes and approve to merge.'}\n </p>\n </div>\n </div>\n\n {/* Branch merge direction (GitHub-like) */}\n {branch ? (\n <div className=\"border-border rounded-lg border\">\n <div className=\"flex items-center gap-2 px-4 py-3\">\n <GitBranch className=\"text-muted-foreground h-4 w-4 shrink-0\" />\n <Badge variant=\"secondary\" className=\"font-mono text-[11px]\">\n {branch.source}\n </Badge>\n <ArrowRight className=\"text-muted-foreground h-3.5 w-3.5 shrink-0\" />\n <Badge variant=\"outline\" className=\"font-mono text-[11px]\">\n {branch.target}\n </Badge>\n </div>\n </div>\n ) : null}\n\n {/* PR metadata card */}\n {pr ? (\n <div className=\"border-border rounded-lg border\">\n <div className=\"space-y-3 px-4 py-3\">\n {/* PR number + link */}\n <div className=\"flex items-center justify-between\">\n <a\n href={pr.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary flex items-center gap-1.5 text-sm font-semibold underline underline-offset-2\"\n >\n PR #{pr.number}\n <ExternalLink className=\"h-3.5 w-3.5\" />\n </a>\n <Badge variant=\"outline\" className=\"text-xs\">\n {pr.status}\n </Badge>\n </div>\n\n {/* Merge status */}\n {pr.mergeable === false ? (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-muted-foreground text-xs font-medium\">Merge Status</span>\n <Badge className=\"border-transparent bg-orange-50 text-orange-700 hover:bg-orange-50\">\n <TriangleAlert className=\"me-1 h-3.5 w-3.5\" />\n Conflicts\n </Badge>\n </div>\n ) : null}\n\n {/* CI status */}\n {pr.ciStatus && hideCiStatus !== true ? (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-muted-foreground text-xs font-medium\">CI Status</span>\n <CiStatusBadge status={pr.ciStatus} />\n </div>\n ) : null}\n\n {/* Commit hash */}\n {pr.commitHash ? (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-muted-foreground text-xs font-medium\">Commit</span>\n <div className=\"flex items-center gap-1.5\">\n <GitCommitHorizontal className=\"text-muted-foreground h-3.5 w-3.5\" />\n <code className=\"bg-muted text-foreground rounded-md px-1.5 py-0.5 font-mono text-[11px]\">\n {pr.commitHash.slice(0, 7)}\n </code>\n </div>\n </div>\n ) : null}\n </div>\n </div>\n ) : null}\n\n {/* Diff summary */}\n {diffSummary ? (\n <div className=\"border-border rounded-lg border\">\n <div className=\"px-4 py-3\">\n <div className=\"mb-3 flex items-center gap-2\">\n <FileDiff className=\"text-muted-foreground h-4 w-4\" />\n <span className=\"text-foreground text-xs font-semibold\">Changes</span>\n </div>\n <div className=\"grid grid-cols-4 gap-3\">\n <div className=\"text-center\">\n <div className=\"text-foreground text-sm font-bold\">\n {diffSummary.filesChanged}\n </div>\n <div className=\"text-muted-foreground text-[10px]\">files</div>\n </div>\n <div className=\"text-center\">\n <div className=\"text-sm font-bold text-green-600\">+{diffSummary.additions}</div>\n <div className=\"text-muted-foreground text-[10px]\">additions</div>\n </div>\n <div className=\"text-center\">\n <div className=\"text-sm font-bold text-red-600\">-{diffSummary.deletions}</div>\n <div className=\"text-muted-foreground text-[10px]\">deletions</div>\n </div>\n <div className=\"text-center\">\n <div className=\"text-foreground text-sm font-bold\">{diffSummary.commitCount}</div>\n <div className=\"text-muted-foreground text-[10px]\">commits</div>\n </div>\n </div>\n </div>\n </div>\n ) : warning ? (\n <div className=\"border-border rounded-lg border\">\n <div className=\"flex items-center gap-2 px-4 py-3\">\n <TriangleAlert className=\"text-muted-foreground h-4 w-4 shrink-0\" />\n <span className=\"text-muted-foreground text-xs\">{warning}</span>\n </div>\n </div>\n ) : null}\n\n {/* Evidence */}\n {evidence && evidence.length > 0 ? <EvidenceList evidence={evidence} /> : null}\n\n {/* File diffs */}\n {fileDiffs && fileDiffs.length > 0 ? <DiffView fileDiffs={fileDiffs} /> : null}\n </div>\n\n {!readOnly && (\n <DrawerActionBar\n onReject={onReject}\n onApprove={handleApproveOrResolve}\n approveLabel={hasConflicts ? 'Resolve Conflicts' : 'Approve Merge'}\n approveVariant={hasConflicts ? 'warning' : 'default'}\n revisionPlaceholder=\"Ask AI to revise before merging...\"\n isProcessing={isProcessing}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={onChatInputChange}\n />\n )}\n </div>\n );\n}\n","/* eslint-disable @next/next/no-img-element -- Local file preview requires raw <img>, not next/image */\n'use client';\n\nimport { useState } from 'react';\nimport { Dialog, DialogTrigger, DialogContent, DialogTitle } from '@/components/ui/dialog';\nimport { VisuallyHidden } from 'radix-ui';\nimport { DownloadIcon, ImageOff } from 'lucide-react';\n\nconst IMAGE_EXTS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico', '.bmp']);\n\nfunction isImagePath(path: string): boolean {\n const dot = path.lastIndexOf('.');\n return dot >= 0 && IMAGE_EXTS.has(path.slice(dot).toLowerCase());\n}\n\nfunction previewUrl(path: string): string {\n const ext = path.lastIndexOf('.') >= 0 ? path.slice(path.lastIndexOf('.')) : '';\n const mimeGuess = isImagePath(path) ? `image/${ext.slice(1).replace('jpg', 'jpeg')}` : '';\n const params = new URLSearchParams({ path, ...(mimeGuess && { mimeType: mimeGuess }) });\n return `/api/attachments/preview?${params.toString()}`;\n}\n\nfunction getFilename(path: string): string {\n return path.split('/').pop() ?? path;\n}\n\n/** Regex matching `@/absolute/path` attachment references in text. */\nconst ATTACHMENT_REF_RE = /(?:^|\\s)@(\\/[^\\s]+)/g;\n\nexport interface InlineAttachmentsProps {\n /** Text that may contain `@/path/to/file` attachment references. */\n text: string;\n /** Additional attachment paths to render (e.g. from rejection feedback). */\n attachmentPaths?: string[];\n}\n\ninterface TextSegment {\n type: 'text';\n value: string;\n}\n\ninterface AttachmentSegment {\n type: 'attachment';\n path: string;\n}\n\ntype Segment = TextSegment | AttachmentSegment;\n\n/** Parse text into segments of plain text and attachment references. */\nexport function parseAttachmentRefs(text: string): Segment[] {\n const segments: Segment[] = [];\n let lastIndex = 0;\n\n for (const match of text.matchAll(ATTACHMENT_REF_RE)) {\n const fullMatchStart = match.index;\n // The path capture starts after the optional leading whitespace\n const leadingWs = match[0].length - match[0].trimStart().length;\n const refStart = fullMatchStart + leadingWs;\n\n // Add text before this reference (including leading whitespace)\n if (refStart > lastIndex) {\n segments.push({ type: 'text', value: text.slice(lastIndex, refStart) });\n }\n\n segments.push({ type: 'attachment', path: match[1] });\n lastIndex = fullMatchStart + match[0].length;\n }\n\n if (lastIndex < text.length) {\n segments.push({ type: 'text', value: text.slice(lastIndex) });\n }\n\n return segments;\n}\n\nexport function InlineAttachments({ text, attachmentPaths }: InlineAttachmentsProps) {\n const segments = parseAttachmentRefs(text);\n const hasInlineAttachments = segments.some((s) => s.type === 'attachment');\n const extraPaths = attachmentPaths?.filter(Boolean) ?? [];\n\n if (!hasInlineAttachments && extraPaths.length === 0) {\n return <span className=\"text-sm leading-relaxed\">{text}</span>;\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {segments.map((segment) => {\n if (segment.type === 'text') {\n const trimmed = segment.value.trim();\n if (!trimmed) return null;\n return (\n <span key={`text-${trimmed.slice(0, 40)}`} className=\"text-sm leading-relaxed\">\n {trimmed}\n </span>\n );\n }\n return <AttachmentPreview key={`att-${segment.path}`} path={segment.path} />;\n })}\n {extraPaths.map((path) => (\n <AttachmentPreview key={`extra-${path}`} path={path} />\n ))}\n </div>\n );\n}\n\nfunction AttachmentPreview({ path }: { path: string }) {\n const filename = getFilename(path);\n const [loadError, setLoadError] = useState(false);\n\n if (isImagePath(path)) {\n if (loadError) {\n return (\n <div\n data-testid=\"inline-attachment-image-error\"\n className=\"text-muted-foreground flex items-center gap-2 rounded-md border px-3 py-2 text-sm\"\n >\n <ImageOff className=\"h-4 w-4 shrink-0\" />\n <span className=\"truncate\">{filename}</span>\n </div>\n );\n }\n\n return (\n <Dialog>\n <DialogTrigger asChild>\n <img\n src={previewUrl(path)}\n alt={filename}\n data-testid=\"inline-attachment-image\"\n onError={() => setLoadError(true)}\n className=\"max-h-48 max-w-full cursor-pointer rounded-md border object-contain transition-opacity hover:opacity-80\"\n />\n </DialogTrigger>\n <DialogContent className=\"max-w-3xl gap-0 overflow-hidden border-0 p-0 [&>button:last-child]:!cursor-pointer [&>button:last-child]:!rounded-full [&>button:last-child]:!bg-black/70 [&>button:last-child]:!p-1.5 [&>button:last-child]:!text-white [&>button:last-child]:!opacity-100 [&>button:last-child]:!shadow-lg [&>button:last-child]:!backdrop-blur-md [&>button:last-child]:hover:!bg-black/90\">\n <VisuallyHidden.Root>\n <DialogTitle>Preview: {filename}</DialogTitle>\n </VisuallyHidden.Root>\n <div className=\"relative bg-black/90\">\n <img\n src={previewUrl(path)}\n alt={filename}\n className=\"h-auto max-h-[70vh] w-full object-contain\"\n />\n </div>\n <div className=\"bg-background flex items-center gap-3 px-4 py-3\">\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"truncate text-sm font-medium\">{filename}</span>\n </div>\n <a\n href={previewUrl(path)}\n download={filename}\n className=\"text-muted-foreground hover:text-foreground shrink-0 cursor-pointer rounded p-1.5 transition-colors\"\n aria-label={`Download ${filename}`}\n >\n <DownloadIcon className=\"h-4 w-4\" />\n </a>\n </div>\n </DialogContent>\n </Dialog>\n );\n }\n\n return (\n <a\n href={previewUrl(path)}\n download={filename}\n data-testid=\"inline-attachment-file\"\n className=\"text-primary text-sm underline underline-offset-2\"\n >\n {filename}\n </a>\n );\n}\n","'use client';\n\nimport { useState, useEffect, useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n TriangleAlert,\n Check,\n CircleCheck,\n Clock,\n ExternalLink,\n FileSearch,\n GitBranch,\n GitCommitHorizontal,\n GitMerge,\n Info,\n RefreshCw,\n Settings,\n ShieldCheck,\n X,\n Zap,\n} from 'lucide-react';\nimport { InlineAttachments } from '@/components/common/inline-attachments';\nimport { PrStatus } from '@shipit-ai/core/domain/generated/output';\nimport { cn } from '@/lib/utils';\nimport { CiStatusBadge } from '@/components/common/ci-status-badge';\nimport { CometSpinner } from '@/components/ui/comet-spinner';\nimport { ActionButton } from '@/components/common/action-button';\nimport { featureNodeStateConfig } from '@/components/common/feature-node';\nimport type { FeatureNodeData } from '@/components/common/feature-node';\nimport {\n getAgentTypeIcon,\n agentTypeLabels,\n} from '@/components/common/feature-node/agent-type-icons';\nimport { getModelMeta } from '@/lib/model-metadata';\nimport { formatDuration } from '@/lib/format-duration';\nimport type { BranchSyncData } from '@/hooks/use-branch-sync-status';\n\n// ── Primitives ──────────────────────────────────────────────────────\n\nfunction Section({\n icon: Icon,\n title,\n children,\n}: {\n icon: React.ComponentType<{ className?: string }>;\n title: string;\n children: React.ReactNode;\n}) {\n return (\n <div className=\"px-3 pt-4 pb-1\">\n <div className=\"text-foreground mb-2 flex items-center gap-1.5 text-sm font-semibold tracking-wider uppercase\">\n <Icon className=\"size-4 opacity-50\" />\n {title}\n </div>\n {children}\n </div>\n );\n}\n\nfunction Card({ children, className }: { children: React.ReactNode; className?: string }) {\n return (\n <div className={cn('bg-muted/60 rounded-md border border-transparent p-3', className)}>\n {children}\n </div>\n );\n}\n\nfunction KV({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"text-foreground/40 text-[11px] font-medium tracking-wider uppercase\">\n {label}\n </span>\n <span className=\"text-sm leading-snug\">{children}</span>\n </div>\n );\n}\n\nfunction Flag({ on, label }: { on: boolean; label: string }) {\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs font-medium',\n on\n ? 'bg-emerald-500/10 text-emerald-600 dark:text-emerald-400'\n : 'bg-foreground/[0.04] text-foreground/25'\n )}\n >\n {on ? <Check className=\"size-3\" /> : <X className=\"size-3\" />}\n {label}\n </span>\n );\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction formatRelativeTime(timestamp: string | number): string {\n const now = Date.now();\n const time = typeof timestamp === 'string' ? new Date(timestamp).getTime() : timestamp;\n const diffMs = now - time;\n const diffMin = Math.floor(diffMs / 60000);\n const diffHr = Math.floor(diffMin / 60);\n const diffDay = Math.floor(diffHr / 24);\n if (diffDay > 30)\n return new Date(time).toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n if (diffDay > 0) return `${diffDay}d ago`;\n if (diffHr > 0) return `${diffHr}h ago`;\n if (diffMin > 0) return `${diffMin}m ago`;\n return 'just now';\n}\n\nfunction useElapsedTime(startedAt?: number): string | null {\n const [elapsed, setElapsed] = useState<string | null>(null);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n useEffect(() => {\n if (!startedAt) {\n setElapsed(null);\n return;\n }\n setElapsed(formatDuration(Math.max(0, Date.now() - startedAt)));\n intervalRef.current = setInterval(() => {\n setElapsed(formatDuration(Math.max(0, Date.now() - startedAt)));\n }, 1000);\n return () => {\n if (intervalRef.current) clearInterval(intervalRef.current);\n };\n }, [startedAt]);\n return elapsed;\n}\n\nconst prColor: Record<PrStatus, string> = {\n [PrStatus.Open]: 'text-blue-600 dark:text-blue-400',\n [PrStatus.Merged]: 'text-purple-600 dark:text-purple-400',\n [PrStatus.Closed]: 'text-red-600 dark:text-red-400',\n};\n\n// ── Main ────────────────────────────────────────────────────────────\n\nexport interface OverviewTabProps {\n data: FeatureNodeData;\n syncStatus?: BranchSyncData | null;\n syncLoading?: boolean;\n syncError?: string | null;\n onRefreshSync?: () => void;\n onRebaseOnMain?: () => void;\n rebaseLoading?: boolean;\n rebaseError?: string | null;\n}\n\nexport function OverviewTab({\n data,\n syncStatus,\n syncLoading,\n syncError,\n onRefreshSync,\n onRebaseOnMain,\n rebaseLoading,\n rebaseError,\n}: OverviewTabProps) {\n const isCompleted = data.lifecycle === 'maintain';\n const isRunning = data.state === 'running' || data.state === 'action-required';\n const elapsedTime = useElapsedTime(isRunning ? data.startedAt : undefined);\n const config = featureNodeStateConfig[data.state];\n const showSummary =\n Boolean(data.summary) && !(data.userQuery && data.summary?.trim() === data.userQuery.trim());\n\n return (\n <div data-testid=\"feature-drawer-status\" className=\"pb-4\">\n {/* ── Progress ── */}\n\n {!isCompleted && data.progress > 0 ? (\n <div data-testid=\"feature-drawer-progress\" className=\"px-3 pb-2\">\n <div className=\"bg-foreground/[0.06] h-1.5 w-full overflow-hidden rounded-full\">\n <div\n className={cn('h-full rounded-full transition-all', config.progressClass)}\n style={{ width: `${data.progress}%` }}\n />\n </div>\n </div>\n ) : null}\n\n {/* ── Description (above stats) ── */}\n {data.oneLiner || data.userQuery || showSummary ? (\n <Section icon={Info} title=\"Description\">\n <Card className=\"flex flex-col gap-2\">\n {data.oneLiner ? <KV label=\"One-Liner\">{data.oneLiner}</KV> : null}\n {data.userQuery ? (\n <KV label=\"Query\">\n <InlineAttachments text={data.userQuery} />\n </KV>\n ) : null}\n {showSummary ? (\n <KV label=\"Summary\">\n <span className=\"leading-snug\">{data.summary}</span>\n </KV>\n ) : null}\n </Card>\n </Section>\n ) : null}\n\n {/* ── PR (right after description) ── */}\n {data.pr ? (\n <Section icon={GitCommitHorizontal} title=\"Pull Request\">\n <Card>\n <div className=\"flex items-center gap-2\">\n <a\n href={data.pr.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary inline-flex items-center gap-1 text-sm font-semibold hover:underline\"\n >\n #{data.pr.number} <ExternalLink className=\"size-3\" />\n </a>\n <span className={cn('text-xs font-semibold', prColor[data.pr.status])}>\n {data.pr.status}\n </span>\n {data.pr.mergeable === false ? (\n <span className=\"inline-flex items-center gap-1 text-xs font-medium text-orange-600 dark:text-orange-400\">\n <TriangleAlert className=\"size-3 shrink-0\" /> Conflicts\n </span>\n ) : null}\n {data.pr.ciStatus && data.hideCiStatus !== true ? (\n <CiStatusBadge status={data.pr.ciStatus} />\n ) : null}\n {data.pr.commitHash ? (\n <code className=\"text-foreground/40 ml-auto font-mono text-[11px]\">\n {data.pr.commitHash.slice(0, 7)}\n </code>\n ) : null}\n </div>\n </Card>\n </Section>\n ) : null}\n\n {/* ── Quick stats grid ── */}\n <div className=\"grid grid-cols-2 gap-2 px-3 pb-1\">\n {data.branch ? (\n <Card>\n <KV label=\"Branch\">\n <span className=\"inline-flex items-center gap-1\">\n <GitBranch className=\"text-foreground/30 size-3 shrink-0\" />\n <code className=\"font-mono text-[11px]\">{data.branch}</code>\n </span>\n {data.baseBranch ? (\n <span className=\"text-foreground/30 block text-[10px]\">from {data.baseBranch}</span>\n ) : null}\n </KV>\n </Card>\n ) : null}\n {data.agentType || data.modelId ? (\n <Card>\n <KV label=\"Agent\">\n <span className=\"inline-flex items-center gap-1.5\">\n {data.agentType\n ? (() => {\n const I = getAgentTypeIcon(data.agentType);\n return <I className=\"size-3.5 shrink-0 opacity-50\" />;\n })()\n : null}\n {data.agentType ? (\n <span>\n {agentTypeLabels[data.agentType as keyof typeof agentTypeLabels] ??\n data.agentType}\n </span>\n ) : null}\n {data.agentType && data.modelId ? (\n <span className=\"text-foreground/20\">/</span>\n ) : null}\n {data.modelId ? (\n <span className=\"text-foreground/50 text-[12px]\">\n {getModelMeta(data.modelId).displayName || data.modelId}\n </span>\n ) : null}\n </span>\n </KV>\n </Card>\n ) : null}\n {data.createdAt ? (\n <Card>\n <KV label=\"Created\">\n <span className=\"inline-flex items-center gap-1\">\n <Clock className=\"text-foreground/30 size-3 shrink-0\" />\n {formatRelativeTime(data.createdAt)}\n </span>\n </KV>\n </Card>\n ) : null}\n {data.fastMode ? (\n <Card>\n <KV label=\"Mode\">\n <span className=\"inline-flex items-center gap-1 text-amber-600 dark:text-amber-400\">\n <Zap className=\"size-3.5\" /> Fast\n </span>\n </KV>\n </Card>\n ) : null}\n {data.runtime || elapsedTime ? (\n <Card>\n <KV label={data.runtime ? 'Runtime' : 'Elapsed'}>\n <span className=\"inline-flex items-center gap-1\">\n <Clock className=\"text-foreground/30 size-3 shrink-0\" />\n {data.runtime ?? elapsedTime}\n </span>\n </KV>\n </Card>\n ) : null}\n </div>\n\n {/* ── Errors ── */}\n {data.blockedBy || data.errorMessage ? (\n <Section icon={TriangleAlert} title=\"Issues\">\n <Card className=\"border-destructive/20 bg-destructive/5\">\n {data.blockedBy ? <KV label=\"Blocked By\">{data.blockedBy}</KV> : null}\n {data.errorMessage ? (\n <KV label=\"Error\">\n <span className=\"text-destructive\">{data.errorMessage}</span>\n </KV>\n ) : null}\n </Card>\n </Section>\n ) : null}\n\n {/* ── Sync ── */}\n {onRebaseOnMain && data.branch && onRefreshSync ? (\n <Section icon={RefreshCw} title=\"Branch Sync\">\n <SyncCard\n syncStatus={syncStatus ?? null}\n syncLoading={syncLoading ?? false}\n syncError={syncError ?? null}\n onRefreshSync={onRefreshSync}\n onRebaseOnMain={onRebaseOnMain}\n rebaseLoading={rebaseLoading ?? false}\n rebaseError={rebaseError ?? null}\n />\n </Section>\n ) : null}\n\n {/* ── Settings ── */}\n <SettingsBlock data={data} />\n </div>\n );\n}\n\n// ── Sync card ───────────────────────────────────────────────────────\n\nfunction SyncCard({\n syncStatus,\n syncLoading,\n syncError,\n onRefreshSync,\n onRebaseOnMain,\n rebaseLoading,\n rebaseError,\n}: {\n syncStatus: BranchSyncData | null;\n syncLoading: boolean;\n syncError: string | null;\n onRefreshSync: () => void;\n onRebaseOnMain: () => void;\n rebaseLoading: boolean;\n rebaseError: string | null;\n}) {\n const { t } = useTranslation('web');\n const isBehind = syncStatus != null && syncStatus.behind > 0;\n const isUpToDate = syncStatus?.behind === 0;\n const base = syncStatus?.baseBranch ?? 'main';\n\n return (\n <Card>\n <div data-testid=\"branch-sync-status\" className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-1.5 text-[13px]\">\n {syncLoading && !syncStatus ? (\n <>\n <CometSpinner size=\"sm\" />\n <span className=\"text-foreground/40\">Checking...</span>\n </>\n ) : syncError ? (\n <>\n <TriangleAlert className=\"size-3.5 text-red-500\" />\n <span className=\"text-destructive text-xs\">{syncError}</span>\n </>\n ) : rebaseLoading ? (\n <>\n <CometSpinner size=\"sm\" />\n <span>\n Rebasing on <code className=\"font-mono text-[11px]\">{base}</code>...\n </span>\n </>\n ) : isBehind ? (\n <>\n <TriangleAlert className=\"size-3.5 text-orange-500\" />\n <span>\n {syncStatus.behind} behind <code className=\"font-mono text-[11px]\">{base}</code>\n {syncStatus.ahead > 0 ? (\n <span className=\"text-foreground/30 ml-1 text-[11px]\">\n · {syncStatus.ahead} ahead\n </span>\n ) : null}\n </span>\n </>\n ) : isUpToDate ? (\n <>\n <CircleCheck className=\"size-3.5 text-green-500\" />\n <span>\n Up to date · <code className=\"font-mono text-[11px]\">{base}</code>\n {syncStatus.ahead > 0 ? (\n <span className=\"text-foreground/30 ml-1 text-[11px]\">\n · {syncStatus.ahead} ahead\n </span>\n ) : null}\n </span>\n </>\n ) : null}\n </div>\n {(syncStatus || syncError) && !rebaseLoading ? (\n <button\n onClick={onRefreshSync}\n disabled={syncLoading}\n className=\"text-foreground/30 hover:text-foreground/60 hover:bg-foreground/5 inline-flex size-6 items-center justify-center rounded-sm disabled:opacity-50\"\n aria-label={t('branchSyncStatus.refreshSyncStatus')}\n >\n <RefreshCw className={cn('size-3', syncLoading && 'animate-spin')} />\n </button>\n ) : null}\n </div>\n {isBehind && !rebaseLoading ? (\n <div className=\"pt-2\">\n <ActionButton\n label={t('branchSyncStatus.rebaseOnMain')}\n onClick={onRebaseOnMain}\n loading={false}\n error={!!rebaseError}\n icon={GitMerge}\n variant=\"outline\"\n size=\"sm\"\n />\n </div>\n ) : null}\n {rebaseError ? <p className=\"text-destructive pt-1 text-[11px]\">{rebaseError}</p> : null}\n </Card>\n );\n}\n\n// ── Settings ────────────────────────────────────────────────────────\n\nfunction SettingsBlock({ data }: { data: FeatureNodeData }) {\n const has =\n data.approvalGates != null ||\n data.push != null ||\n data.openPr != null ||\n data.ciWatchEnabled != null ||\n data.enableEvidence != null ||\n data.forkAndPr != null ||\n data.commitSpecs != null;\n if (!has) return null;\n\n return (\n <Section icon={Settings} title=\"Settings\">\n <div className=\"grid grid-cols-3 gap-2\">\n {data.approvalGates ? (\n <Card>\n <div className=\"text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase\">\n <ShieldCheck className=\"size-3\" /> Approve\n </div>\n <div className=\"flex flex-col gap-0.5\">\n <Flag on={data.approvalGates.allowPrd} label=\"PRD\" />\n <Flag on={data.approvalGates.allowPlan} label=\"Plan\" />\n <Flag on={data.approvalGates.allowMerge} label=\"Merge\" />\n </div>\n </Card>\n ) : null}\n {data.enableEvidence != null ? (\n <Card>\n <div className=\"text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase\">\n <FileSearch className=\"size-3\" /> Evidence\n </div>\n <div className=\"flex flex-col gap-0.5\">\n <Flag on={data.enableEvidence} label=\"Collect\" />\n {data.commitEvidence != null ? (\n <Flag on={data.commitEvidence} label=\"Add to PR\" />\n ) : null}\n </div>\n </Card>\n ) : null}\n {data.push != null ||\n data.openPr != null ||\n data.ciWatchEnabled != null ||\n data.commitSpecs != null ||\n data.forkAndPr != null ? (\n <Card>\n <div className=\"text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase\">\n <GitBranch className=\"size-3\" /> Git\n </div>\n <div className=\"flex flex-col gap-0.5\">\n {data.push != null ? <Flag on={data.push} label=\"Push\" /> : null}\n {data.openPr != null ? <Flag on={data.openPr} label=\"PR\" /> : null}\n {data.ciWatchEnabled != null ? <Flag on={data.ciWatchEnabled} label=\"Watch\" /> : null}\n {data.commitSpecs != null ? <Flag on={data.commitSpecs} label=\"Specs\" /> : null}\n {data.forkAndPr != null ? <Flag on={data.forkAndPr} label=\"Fork\" /> : null}\n </div>\n </Card>\n ) : null}\n </div>\n </Section>\n );\n}\n","'use client';\n\nimport { useState, useEffect, useRef, useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n LoaderCircle,\n CircleAlert,\n Clock,\n Zap,\n DollarSign,\n Play,\n RotateCcw,\n CircleCheck,\n CircleX,\n Square,\n Ban,\n MessageSquare,\n Timer,\n ArrowDownToLine,\n ArrowUpFromLine,\n Copy,\n Check,\n} from 'lucide-react';\nimport type {\n PhaseTimingData,\n RejectionFeedbackData,\n} from '@/app/actions/get-feature-phase-timings';\nimport { InlineAttachments } from '@/components/common/inline-attachments';\nimport { formatDuration } from '@/lib/format-duration';\n\n/**\n * Computes the effective duration for a phase timing entry.\n * For completed phases, uses the server-provided durationMs.\n * For in-progress phases (has startedAt but no completedAt), computes\n * elapsed time client-side so the UI shows a live-updating timer.\n */\nfunction getEffectiveDuration(timing: PhaseTimingData, now: number): number {\n if (timing.durationMs != null && timing.durationMs > 0) return timing.durationMs;\n if (!timing.completedAt && timing.startedAt) {\n const started = new Date(timing.startedAt).getTime();\n if (!Number.isNaN(started)) return Math.max(0, now - started);\n }\n return 0;\n}\n\n/** Returns true if any non-lifecycle phase is still in progress. */\nfunction hasRunningPhase(timings: PhaseTimingData[]): boolean {\n return timings.some((t) => !t.phase.startsWith('run:') && !t.completedAt && t.startedAt);\n}\n\n/** Hook that ticks every second while there are running phases. */\nfunction useTickingNow(timings: PhaseTimingData[] | null): number {\n const [now, setNow] = useState(Date.now);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n useEffect(() => {\n const running = timings ? hasRunningPhase(timings) : false;\n if (running) {\n // Tick every second\n intervalRef.current = setInterval(() => setNow(Date.now()), 1000);\n }\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [timings]);\n\n return now;\n}\n\n/** Format a token count with K/M suffix for readability. */\nfunction formatTokens(count: number): string {\n if (count >= 1_000_000) return `${(count / 1_000_000).toFixed(1)}M`;\n if (count >= 1_000) return `${(count / 1_000).toFixed(1)}K`;\n return String(count);\n}\n\n/** Format a timestamp to a short local time string (e.g. \"10:05:30 AM\"). */\nfunction formatTimestamp(value: string | Date | unknown): string {\n const d = value instanceof Date ? value : new Date(String(value));\n if (Number.isNaN(d.getTime())) return '';\n return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n}\n\n/** Format a USD cost with appropriate precision. */\nfunction formatCost(usd: number): string {\n if (usd >= 1) return `$${usd.toFixed(2)}`;\n if (usd >= 0.01) return `$${usd.toFixed(3)}`;\n return `$${usd.toFixed(4)}`;\n}\n\nexport interface ActivityTabProps {\n timings: PhaseTimingData[] | null;\n loading: boolean;\n error: string | null;\n rejectionFeedback?: RejectionFeedbackData[];\n}\n\nconst NODE_TO_PHASE: Record<string, string> = {\n analyze: 'Analyzing',\n requirements: 'Requirements',\n research: 'Researching',\n plan: 'Planning',\n implement: 'Implementing',\n rebase: 'Rebasing',\n 'fast-implement': 'Fast Implement',\n evidence: 'Evidence',\n validate: 'Validating',\n repair: 'Repairing',\n merge: 'Merging',\n};\n\nconst LIFECYCLE_EVENTS: Record<\n string,\n { label: string; colorClass: string; bgClass: string; icon: typeof Play }\n> = {\n 'run:started': {\n label: 'started',\n colorClass: 'text-blue-600',\n bgClass: 'bg-blue-50 dark:bg-blue-950/30',\n icon: Play,\n },\n 'run:resumed': {\n label: 'resumed',\n colorClass: 'text-blue-600',\n bgClass: 'bg-blue-50 dark:bg-blue-950/30',\n icon: RotateCcw,\n },\n 'run:completed': {\n label: 'completed',\n colorClass: 'text-emerald-600',\n bgClass: 'bg-emerald-50 dark:bg-emerald-950/30',\n icon: CircleCheck,\n },\n 'run:failed': {\n label: 'failed',\n colorClass: 'text-red-600',\n bgClass: 'bg-red-50 dark:bg-red-950/30',\n icon: CircleX,\n },\n 'run:stopped': {\n label: 'stopped',\n colorClass: 'text-amber-600',\n bgClass: 'bg-amber-50 dark:bg-amber-950/30',\n icon: Square,\n },\n 'run:crashed': {\n label: 'crashed',\n colorClass: 'text-red-600',\n bgClass: 'bg-red-50 dark:bg-red-950/30',\n icon: CircleX,\n },\n 'run:rejected': {\n label: 'rejected',\n colorClass: 'text-orange-600',\n bgClass: 'bg-orange-50 dark:bg-orange-950/30',\n icon: Ban,\n },\n};\n\nfunction isLifecycleEvent(phase: string): boolean {\n return phase.startsWith('run:');\n}\n\n/* ---------------------------------------------------------------------------\n * Lifecycle-aware view model\n * ------------------------------------------------------------------------- */\n\n/**\n * A single iteration in the lifecycle timeline.\n *\n * An iteration represents one cycle of work:\n * started/resumed → phase work → rejected/completed/failed\n *\n * Each rejected iteration has associated rejection feedback.\n */\nexport interface TimelineIteration {\n /** 1-based iteration number */\n number: number;\n /** The timing events in this iteration */\n timings: PhaseTimingData[];\n /** If this iteration ended with rejection, the feedback message */\n rejectionMessage?: string;\n /** If this iteration ended with rejection, any attachments */\n rejectionAttachments?: string[];\n}\n\n/**\n * Build a lifecycle-aware timeline from flat timing events and rejection feedback.\n *\n * Splits the timing stream at run:rejected boundaries to produce iterations.\n * Each rejection feedback entry is matched to its iteration by index.\n *\n * When there are more feedback entries than run:rejected events in the timings,\n * synthetic run:rejected + run:resumed events are appended to ensure every\n * feedback entry is represented.\n */\nexport function buildLifecycleTimeline(\n timings: PhaseTimingData[],\n feedback?: RejectionFeedbackData[]\n): TimelineIteration[] {\n if (!timings.length) return [];\n\n // Count existing run:rejected events\n const existingRejectionCount = timings.filter((t) => t.phase === 'run:rejected').length;\n const feedbackCount = feedback?.length ?? 0;\n\n // Augment timings with synthetic rejection/resumed cycles for unmatched feedback\n let augmented = timings;\n if (feedbackCount > existingRejectionCount) {\n augmented = [...timings];\n\n // Use last timing's agentRunId as template\n const templateRunId = timings[timings.length - 1].agentRunId;\n\n for (let i = existingRejectionCount; i < feedbackCount; i++) {\n const fb = feedback![i];\n // Add run:resumed before work (except for the first synthetic, which continues from existing)\n if (i > existingRejectionCount) {\n augmented.push({\n agentRunId: templateRunId,\n phase: 'run:resumed',\n startedAt: fb.timestamp ?? `synthetic-resumed-${i}`,\n });\n }\n // Add run:rejected\n augmented.push({\n agentRunId: templateRunId,\n phase: 'run:rejected',\n startedAt: fb.timestamp ?? `synthetic-${i}`,\n });\n }\n }\n\n // Split into iterations at run:rejected boundaries\n const iterations: TimelineIteration[] = [];\n let currentEvents: PhaseTimingData[] = [];\n let rejectionIndex = 0;\n\n for (const t of augmented) {\n currentEvents.push(t);\n\n if (t.phase === 'run:rejected') {\n const fb = feedback?.[rejectionIndex];\n iterations.push({\n number: iterations.length + 1,\n timings: currentEvents,\n rejectionMessage: fb?.message,\n rejectionAttachments: fb?.attachments,\n });\n currentEvents = [];\n rejectionIndex++;\n }\n }\n\n // Remaining events after last rejection (or all events if no rejections)\n if (currentEvents.length > 0) {\n iterations.push({\n number: iterations.length + 1,\n timings: currentEvents,\n });\n }\n\n return iterations;\n}\n\n/** Determine the outcome status of an iteration */\nfunction getIterationOutcome(\n iteration: TimelineIteration\n): { label: string; colorClass: string; dotClass: string } | null {\n const lastLifecycle = [...iteration.timings].reverse().find((t) => isLifecycleEvent(t.phase));\n if (!lastLifecycle) return null;\n\n switch (lastLifecycle.phase) {\n case 'run:rejected':\n return { label: 'Rejected', colorClass: 'text-orange-600', dotClass: 'bg-orange-500' };\n case 'run:completed':\n return { label: 'Completed', colorClass: 'text-emerald-600', dotClass: 'bg-emerald-500' };\n case 'run:failed':\n return { label: 'Failed', colorClass: 'text-red-600', dotClass: 'bg-red-500' };\n case 'run:crashed':\n return { label: 'Crashed', colorClass: 'text-red-600', dotClass: 'bg-red-500' };\n case 'run:stopped':\n return { label: 'Stopped', colorClass: 'text-amber-600', dotClass: 'bg-amber-500' };\n default:\n return null;\n }\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport function ActivityTab({ timings, loading, error, rejectionFeedback }: ActivityTabProps) {\n const { t } = useTranslation('web');\n const now = useTickingNow(timings);\n\n if (loading) {\n return (\n <div data-testid=\"activity-tab-loading\" className=\"flex items-center justify-center p-8\">\n <LoaderCircle className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"flex items-center gap-2 p-4 text-base text-red-600\">\n <CircleAlert className=\"h-4 w-4 shrink-0\" />\n <span>{error}</span>\n </div>\n );\n }\n\n if (!timings || timings.length === 0) {\n return (\n <div className=\"flex flex-col items-center justify-center gap-2 p-8\">\n <Clock className=\"text-muted-foreground h-8 w-8\" />\n <p className=\"text-muted-foreground text-base\">{t('activityTab.noActivityRecorded')}</p>\n </div>\n );\n }\n\n const nodeTimings = timings.filter((t) => !isLifecycleEvent(t.phase));\n const maxDurationMs = Math.max(\n ...nodeTimings.map((t) => getEffectiveDuration(t, now)),\n ...nodeTimings.map((t) => t.approvalWaitMs ?? 0),\n 0\n );\n\n const iterations = buildLifecycleTimeline(timings, rejectionFeedback);\n const hasMultipleIterations = iterations.length > 1;\n\n const totalExecMs = nodeTimings.reduce((sum, t) => sum + getEffectiveDuration(t, now), 0);\n const totalWaitMs = nodeTimings.reduce((sum, t) => sum + (t.approvalWaitMs ?? 0), 0);\n const totalInputTokens = nodeTimings.reduce((sum, t) => sum + (t.inputTokens ?? 0), 0);\n const totalOutputTokens = nodeTimings.reduce((sum, t) => sum + (t.outputTokens ?? 0), 0);\n const totalCostUsd = nodeTimings.reduce((sum, t) => sum + (t.costUsd ?? 0), 0);\n\n return (\n <div className=\"flex flex-col gap-3 p-4\">\n <div data-testid=\"activity-timings\" className=\"flex flex-col gap-3\">\n {iterations.map((iteration) => (\n <IterationGroup\n key={iteration.number}\n iteration={iteration}\n showHeader={hasMultipleIterations}\n maxDurationMs={maxDurationMs}\n now={now}\n />\n ))}\n </div>\n {totalExecMs > 0 ? (\n <SummaryTotals\n totalExecMs={totalExecMs}\n totalWaitMs={totalWaitMs}\n totalInputTokens={totalInputTokens}\n totalOutputTokens={totalOutputTokens}\n totalCostUsd={totalCostUsd}\n />\n ) : null}\n </div>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Iteration group — one cycle of work\n * ------------------------------------------------------------------------- */\n\nfunction IterationGroup({\n iteration,\n showHeader,\n maxDurationMs,\n now,\n}: {\n iteration: TimelineIteration;\n showHeader: boolean;\n maxDurationMs: number;\n now: number;\n}) {\n const outcome = getIterationOutcome(iteration);\n\n return (\n <div\n data-testid={`iteration-${iteration.number}`}\n className=\"border-border/50 bg-card/50 flex flex-col overflow-hidden rounded-lg border\"\n >\n {/* Iteration header */}\n {showHeader ? (\n <div className=\"bg-muted/30 border-border/50 flex items-center justify-between border-b px-3 py-1.5\">\n <span className=\"text-muted-foreground text-sm font-semibold tracking-wide\">\n Iteration {iteration.number}\n </span>\n {outcome ? (\n <span className={`flex items-center gap-1 text-xs font-medium ${outcome.colorClass}`}>\n <span className={`inline-block h-1.5 w-1.5 rounded-full ${outcome.dotClass}`} />\n {outcome.label}\n </span>\n ) : null}\n </div>\n ) : null}\n\n {/* Timeline content */}\n <div className=\"relative flex flex-col\">\n {/* Vertical timeline line — centered on 20px dots with px-3 (12px) left padding: 12 + 10 - 0.5 = 21.5px */}\n <div className=\"bg-border/60 absolute top-4 bottom-4 left-[21.5px] w-px\" />\n\n {iteration.timings.map((t, idx) => {\n if (isLifecycleEvent(t.phase)) {\n const isRejection = t.phase === 'run:rejected';\n const isFailure =\n t.phase === 'run:failed' || t.phase === 'run:crashed' || t.phase === 'run:stopped';\n // For failures, find the last phase with an error message in this iteration\n let message: string | undefined;\n if (isRejection) {\n message = iteration.rejectionMessage;\n } else if (isFailure) {\n const lastErrorPhase = [...iteration.timings]\n .reverse()\n .find((p) => !isLifecycleEvent(p.phase) && p.errorMessage);\n message = lastErrorPhase?.errorMessage ?? t.errorMessage;\n }\n return (\n <LifecycleEventRow\n key={`${t.agentRunId}-${t.phase}-${t.startedAt}`}\n timing={t}\n message={message}\n attachments={isRejection ? iteration.rejectionAttachments : undefined}\n isFirst={idx === 0}\n isLast={idx === iteration.timings.length - 1}\n />\n );\n }\n return (\n <NodeTimingRow\n key={`${t.agentRunId}-${t.phase}-${t.startedAt}`}\n timing={t}\n maxDurationMs={maxDurationMs}\n now={now}\n />\n );\n })}\n </div>\n </div>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Row components\n * ------------------------------------------------------------------------- */\n\nfunction LifecycleEventRow({\n timing,\n message,\n attachments,\n isFirst,\n isLast,\n}: {\n timing: PhaseTimingData;\n message?: string;\n attachments?: string[];\n isFirst?: boolean;\n isLast?: boolean;\n}) {\n const event = LIFECYCLE_EVENTS[timing.phase];\n if (!event) return null;\n\n const hasAttachments = attachments && attachments.length > 0;\n const Icon = event.icon;\n\n return (\n <div\n className={`relative flex flex-col gap-1 px-3 ${isFirst ? 'pt-2' : 'pt-1'} ${isLast ? 'pb-2' : 'pb-1'}`}\n >\n <div className=\"flex items-center gap-2\">\n {/* Timeline dot */}\n <div\n className={`relative z-10 flex h-5 w-5 shrink-0 items-center justify-center rounded-full ${event.bgClass}`}\n >\n <Icon className={`h-3 w-3 ${event.colorClass}`} />\n </div>\n\n {/* Label */}\n <span className={`text-sm font-medium ${event.colorClass}`}>{event.label}</span>\n\n {/* Timestamp */}\n {timing.startedAt &&\n !(typeof timing.startedAt === 'string' && timing.startedAt.startsWith('synthetic')) ? (\n <span className=\"text-muted-foreground/60 ml-auto text-xs tabular-nums\">\n {formatTimestamp(String(timing.startedAt))}\n </span>\n ) : null}\n </div>\n\n {/* Feedback / error message */}\n {message\n ? (() => {\n const isError =\n timing.phase === 'run:failed' ||\n timing.phase === 'run:crashed' ||\n timing.phase === 'run:stopped';\n return (\n <div\n className={`ml-[26px] flex items-start gap-1.5 rounded-md px-2 py-1.5 ${\n isError\n ? 'bg-red-50/50 dark:bg-red-950/20'\n : 'bg-orange-50/50 dark:bg-orange-950/20'\n }`}\n >\n {isError ? (\n <CircleAlert className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-red-400\" />\n ) : (\n <MessageSquare className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-orange-400\" />\n )}\n <span\n data-testid={isError ? 'error-message-text' : 'rejection-feedback-text'}\n className=\"text-muted-foreground text-xs leading-relaxed italic\"\n >\n — {message}\n </span>\n </div>\n );\n })()\n : null}\n {hasAttachments ? (\n <div data-testid=\"rejection-feedback-attachments\" className=\"ml-[26px]\">\n <InlineAttachments text=\"\" attachmentPaths={attachments} />\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction NodeTimingRow({\n timing,\n maxDurationMs,\n now,\n}: {\n timing: PhaseTimingData;\n maxDurationMs: number;\n now: number;\n}) {\n const { t } = useTranslation('web');\n const base = timing.phase.includes(':') ? timing.phase.split(':')[0] : timing.phase;\n const suffix = timing.phase.includes(':') ? timing.phase.split(':')[1] : null;\n const isSubPhase = suffix !== null;\n const isImplPhase = suffix?.startsWith('phase-') ?? false;\n const baseName = NODE_TO_PHASE[base] ?? base;\n const label = isImplPhase\n ? `Phase ${suffix!.replace('phase-', '')}`\n : suffix !== null\n ? `${baseName} #${suffix}`\n : baseName;\n\n const durationMs = getEffectiveDuration(timing, now);\n const isRunning = !timing.completedAt && !!timing.startedAt;\n // Running phases get a minimum 15% bar so they're always visually prominent\n const minPercent = isRunning ? 15 : 2;\n const barPercent =\n maxDurationMs > 0 ? Math.max(minPercent, (durationMs / maxDurationMs) * 100) : minPercent;\n const barColorClass = timing.completedAt\n ? isImplPhase\n ? 'bg-emerald-400'\n : isSubPhase\n ? 'bg-amber-500'\n : 'bg-emerald-500'\n : 'bg-blue-500';\n const totalTokens =\n timing.inputTokens != null || timing.outputTokens != null\n ? (timing.inputTokens ?? 0) + (timing.outputTokens ?? 0)\n : null;\n\n const [copied, setCopied] = useState(false);\n const handleCopyPrompt = useCallback(() => {\n if (!timing.prompt) return;\n navigator.clipboard.writeText(timing.prompt).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n });\n }, [timing.prompt]);\n\n return (\n <div\n className={`group/phase relative flex flex-col gap-0.5 px-3 py-1.5 ${isSubPhase ? 'ms-4' : ''}`}\n >\n <div data-testid={`timing-bar-${timing.phase}`} className=\"flex items-center gap-2\">\n {/* Timeline dot */}\n <div className=\"relative z-10 flex h-5 w-5 shrink-0 items-center justify-center\">\n <div\n className={`rounded-full ${isRunning ? 'h-3 w-3 animate-pulse' : 'h-2.5 w-2.5'} ${\n isRunning\n ? 'bg-blue-500'\n : timing.completedAt\n ? 'bg-emerald-500'\n : 'bg-muted-foreground/30'\n }`}\n />\n </div>\n\n {/* Phase label — fixed width so all bars align in a single column */}\n <span\n className={`w-28 shrink-0 truncate text-sm font-medium ${\n isSubPhase ? 'text-muted-foreground' : 'text-foreground/80'\n }`}\n >\n {label}\n </span>\n\n {/* Copy prompt button — appears on hover */}\n {timing.prompt ? (\n <button\n type=\"button\"\n onClick={handleCopyPrompt}\n className=\"text-muted-foreground/50 hover:text-foreground/70 -ms-1 shrink-0 opacity-0 transition-opacity group-hover/phase:opacity-100\"\n title={t('activityTab.copyPromptToClipboard')}\n >\n {copied ? (\n <Check className=\"h-3.5 w-3.5 text-emerald-500\" />\n ) : (\n <Copy className=\"h-3.5 w-3.5\" />\n )}\n </button>\n ) : null}\n\n {/* Progress bar */}\n <div\n className={`bg-muted relative min-w-0 flex-1 overflow-hidden rounded-full ${isSubPhase ? 'h-1.5' : 'h-2'}`}\n >\n {isRunning ? (\n <div\n className=\"absolute inset-0 rounded-full bg-blue-500/30\"\n style={{\n backgroundImage:\n 'linear-gradient(90deg, transparent 0%, rgb(59 130 246) 50%, transparent 100%)',\n backgroundSize: '200% 100%',\n animation: 'shimmer 1.5s ease-in-out infinite',\n }}\n />\n ) : (\n <div\n className={`h-full rounded-full transition-all duration-300 ${barColorClass}`}\n style={{ width: `${Math.min(barPercent, 100)}%` }}\n />\n )}\n </div>\n\n {/* Duration */}\n <span className=\"text-muted-foreground w-14 shrink-0 text-end text-sm font-medium tabular-nums\">\n {formatDuration(durationMs)}\n </span>\n </div>\n\n {/* Metrics row (timestamp + tokens + cost) */}\n <div className=\"ml-[28px] flex items-center gap-3 text-xs\">\n {timing.startedAt ? (\n <span className=\"text-muted-foreground/60 tabular-nums\">\n {formatTimestamp(timing.startedAt)}\n </span>\n ) : null}\n {totalTokens != null && totalTokens > 0 ? (\n <span className=\"text-muted-foreground/70 inline-flex items-center gap-0.5\">\n <Zap className=\"h-3 w-3 opacity-50\" />\n {formatTokens(totalTokens)}\n </span>\n ) : null}\n {timing.costUsd != null && timing.costUsd > 0 ? (\n <span className=\"text-muted-foreground/70 inline-flex items-center gap-0.5\">\n <DollarSign className=\"h-3 w-3 opacity-50\" />\n {formatCost(timing.costUsd)}\n </span>\n ) : null}\n </div>\n\n {/* Approval wait sub-row */}\n {timing.approvalWaitMs != null && timing.approvalWaitMs > 0 ? (\n <ApprovalWaitRow timing={timing} maxDurationMs={maxDurationMs} />\n ) : null}\n </div>\n );\n}\n\nfunction ApprovalWaitRow({\n timing,\n maxDurationMs,\n}: {\n timing: PhaseTimingData;\n maxDurationMs: number;\n}) {\n const waitMs = timing.approvalWaitMs ?? 0;\n const barPercent = maxDurationMs > 0 ? Math.max(2, (waitMs / maxDurationMs) * 100) : 2;\n\n return (\n <div\n data-testid={`approval-wait-${timing.phase}`}\n className=\"ml-[26px] flex items-center gap-2 rounded-md bg-amber-50/50 px-1.5 py-1 dark:bg-amber-950/20\"\n >\n <Timer className=\"h-3.5 w-3.5 shrink-0 text-amber-500\" />\n <span className=\"text-muted-foreground w-16 shrink-0 text-xs\">approval</span>\n <div className=\"bg-muted h-1.5 min-w-0 flex-1 overflow-hidden rounded-full\">\n <div\n className=\"h-full rounded-full bg-amber-500\"\n style={{ width: `${Math.min(barPercent, 100)}%` }}\n />\n </div>\n <span className=\"text-muted-foreground w-14 shrink-0 text-end text-xs tabular-nums\">\n {formatDuration(waitMs)}\n </span>\n </div>\n );\n}\n\nfunction SummaryTotals({\n totalExecMs,\n totalWaitMs,\n totalInputTokens,\n totalOutputTokens,\n totalCostUsd,\n}: {\n totalExecMs: number;\n totalWaitMs: number;\n totalInputTokens: number;\n totalOutputTokens: number;\n totalCostUsd: number;\n}) {\n const { t } = useTranslation('web');\n const totalTokens = totalInputTokens + totalOutputTokens;\n return (\n <div\n data-testid=\"activity-summary\"\n className=\"border-border bg-card/30 flex flex-col gap-2 rounded-lg border p-3\"\n >\n <div className=\"text-muted-foreground mb-1 text-xs font-semibold tracking-wider uppercase\">\n Summary\n </div>\n <div className=\"grid grid-cols-2 gap-x-4 gap-y-3\">\n <SummaryCell\n icon={Clock}\n label={t('activityTab.execution')}\n value={formatDuration(totalExecMs)}\n />\n <SummaryCell\n icon={Timer}\n label={t('activityTab.wait')}\n value={totalWaitMs > 0 ? formatDuration(totalWaitMs) : 'n/a'}\n />\n <SummaryCell\n icon={Clock}\n label=\"Wall-clock\"\n value={\n totalWaitMs > 0\n ? formatDuration(totalExecMs + totalWaitMs)\n : formatDuration(totalExecMs)\n }\n />\n <SummaryCell\n icon={DollarSign}\n label={t('activityTab.cost')}\n value={totalCostUsd > 0 ? formatCost(totalCostUsd) : 'n/a'}\n />\n <div className=\"col-span-2 flex flex-col gap-0.5\">\n <span className=\"text-muted-foreground flex items-center gap-1 text-xs\">\n <Zap className=\"h-3 w-3 opacity-40\" />\n Tokens\n </span>\n {totalTokens > 0 ? (\n <span className=\"flex items-center gap-2.5 text-sm tabular-nums\">\n <span>{formatTokens(totalTokens)}</span>\n <span\n className=\"text-muted-foreground flex items-center gap-3 text-xs\"\n title=\"Input tokens / Output tokens\"\n >\n <span className=\"flex items-center gap-0.5\">\n <ArrowDownToLine className=\"h-3 w-3 text-blue-500 opacity-60\" />\n {formatTokens(totalInputTokens)}\n </span>\n <span className=\"flex items-center gap-0.5\">\n <ArrowUpFromLine className=\"h-3 w-3 text-emerald-500 opacity-60\" />\n {formatTokens(totalOutputTokens)}\n </span>\n </span>\n </span>\n ) : (\n <span className=\"text-muted-foreground/40 text-sm italic tabular-nums\">n/a</span>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nfunction SummaryCell({\n icon: Icon,\n label,\n value,\n className = '',\n}: {\n icon: typeof Clock;\n label: string;\n value: string;\n className?: string;\n}) {\n const isNA = value === 'n/a';\n return (\n <div className={`flex flex-col gap-0.5 ${className}`}>\n <span className=\"text-muted-foreground flex items-center gap-1 text-xs\">\n <Icon className=\"h-3 w-3 opacity-40\" />\n {label}\n </span>\n <span className={`text-sm tabular-nums ${isNA ? 'text-muted-foreground/40 italic' : ''}`}>\n {value}\n </span>\n </div>\n );\n}\n","'use client';\n\nimport { useMemo } from 'react';\nimport {\n FileText,\n Terminal,\n MessageSquare,\n CircleCheck,\n Coins,\n Server,\n FileCode,\n Play,\n ArrowRight,\n CircleAlert,\n} from 'lucide-react';\nimport {\n parseLogContent,\n parseToolCall,\n parseResultMessage,\n parseTokensMessage,\n type ParsedLogLine,\n} from '@/lib/parse-log-line';\n\n/* ---------------------------------------------------------------------------\n * Public API\n * ------------------------------------------------------------------------- */\n\nexport interface EventLogViewerProps {\n content: string;\n}\n\nexport function EventLogViewer({ content }: EventLogViewerProps) {\n const lines = useMemo(() => parseLogContent(content), [content]);\n\n if (lines.length === 0) return null;\n\n return (\n <div className=\"flex flex-col\">\n {lines.map((line, i) => (\n // eslint-disable-next-line react/no-array-index-key -- append-only list, raw content not unique\n <LogLineRow key={i} line={line} />\n ))}\n </div>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Line router\n * ------------------------------------------------------------------------- */\n\nfunction LogLineRow({ line }: { line: ParsedLogLine }) {\n switch (line.tag) {\n case 'tool':\n return <ToolCallRow line={line} />;\n case 'tool-result':\n return <ToolResultRow line={line} />;\n case 'text':\n case 'delta':\n return <TextRow line={line} />;\n case 'result':\n return <ResultRow line={line} />;\n case 'tokens':\n case 'turn':\n return <TokensRow line={line} />;\n case 'cmd':\n return <CommandRow line={line} />;\n case 'file':\n return <FileChangeRow line={line} />;\n case 'thread':\n case 'event':\n return <InfoRow line={line} />;\n case 'error':\n return <ErrorRow line={line} />;\n case 'worker':\n return <WorkerRow line={line} />;\n case 'info':\n return <InfoRow line={line} />;\n case 'raw':\n default:\n return <RawRow line={line} />;\n }\n}\n\n/* ---------------------------------------------------------------------------\n * Shared helpers\n * ------------------------------------------------------------------------- */\n\nfunction Timestamp({ value }: { value: string | null }) {\n if (!value) return null;\n // Show only MM:SS — compact, hours rarely change in a session\n const full = value.replace(/^.*T/, '').replace('Z', '');\n const parts = full.split(':');\n const compact = parts.length >= 3 ? `${parts[1]}:${parts[2].split('.')[0]}` : full;\n return (\n <span className=\"text-muted-foreground/60 w-11 shrink-0 font-mono text-[10px]\">{compact}</span>\n );\n}\n\nfunction PhaseBadge({ phase }: { phase: string | null }) {\n if (!phase) return <span className=\"w-20 shrink-0\" />;\n return (\n <span\n className=\"bg-muted text-muted-foreground w-20 shrink-0 truncate rounded px-1.5 py-0.5 font-mono text-[10px] font-medium\"\n title={phase}\n >\n {phase}\n </span>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Event-specific rows\n * ------------------------------------------------------------------------- */\n\nfunction ToolCallRow({ line }: { line: ParsedLogLine }) {\n const { toolName, args } = parseToolCall(line.message);\n\n // Try to extract a key detail from args for common tools\n const detail = getToolDetail(toolName, args);\n\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 border-b border-transparent px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <ToolIcon toolName={toolName} />\n <span className=\"text-xs font-semibold text-violet-600 dark:text-violet-400\">\n {toolName}\n </span>\n {detail ? (\n <span className=\"text-muted-foreground min-w-0 font-mono text-xs break-all\">\n {detail}\n </span>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction ToolIcon({ toolName }: { toolName: string }) {\n const lower = toolName.toLowerCase();\n if (lower === 'bash') return <Terminal className=\"mt-0.5 h-3 w-3 shrink-0 text-violet-500\" />;\n if (lower === 'read' || lower === 'glob' || lower === 'grep')\n return <FileText className=\"mt-0.5 h-3 w-3 shrink-0 text-violet-500\" />;\n if (lower === 'write' || lower === 'edit')\n return <FileCode className=\"mt-0.5 h-3 w-3 shrink-0 text-violet-500\" />;\n return <Terminal className=\"mt-0.5 h-3 w-3 shrink-0 text-violet-500\" />;\n}\n\nfunction getToolDetail(toolName: string, args: string): string | null {\n try {\n const parsed = JSON.parse(args);\n if (toolName === 'Read' && parsed.file_path) return parsed.file_path;\n if (toolName === 'Write' && parsed.file_path) return parsed.file_path;\n if (toolName === 'Edit' && parsed.file_path) return parsed.file_path;\n if (toolName === 'Glob' && parsed.pattern) return parsed.pattern;\n if (toolName === 'Grep' && parsed.pattern) return parsed.pattern;\n if (toolName === 'Bash' && parsed.command) {\n return parsed.command as string;\n }\n if (toolName === 'Task' && parsed.description) return parsed.description;\n } catch {\n // Not JSON — show truncated raw args\n if (args.length > 0) return args;\n }\n return null;\n}\n\nfunction TextRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <MessageSquare className=\"mt-0.5 h-3 w-3 shrink-0 text-blue-500\" />\n <span className=\"text-foreground/80 min-w-0 text-xs leading-relaxed\">{line.message}</span>\n </div>\n </div>\n );\n}\n\nfunction ResultRow({ line }: { line: ParsedLogLine }) {\n const { chars } = parseResultMessage(line.message);\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <CircleCheck className=\"mt-0.5 h-3 w-3 shrink-0 text-emerald-500\" />\n <span className=\"text-xs font-medium text-emerald-600 dark:text-emerald-400\">\n Result: {chars.toLocaleString()} chars\n </span>\n </div>\n </div>\n );\n}\n\nfunction TokensRow({ line }: { line: ParsedLogLine }) {\n const { inputTokens, outputTokens } = parseTokensMessage(line.message);\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <Coins className=\"mt-0.5 h-3 w-3 shrink-0 text-amber-500\" />\n <span className=\"text-muted-foreground text-xs\">\n <span className=\"text-amber-600 dark:text-amber-400\">{inputTokens.toLocaleString()}</span>\n {' in / '}\n <span className=\"text-amber-600 dark:text-amber-400\">\n {outputTokens.toLocaleString()}\n </span>\n {' out'}\n </span>\n </div>\n </div>\n );\n}\n\nfunction WorkerRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 bg-zinc-50 px-3 py-1.5 transition-colors dark:bg-zinc-900/50\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <Server className=\"mt-0.5 h-3 w-3 shrink-0 text-zinc-500\" />\n <span className=\"text-muted-foreground text-xs font-medium break-all\">{line.message}</span>\n </div>\n </div>\n );\n}\n\nfunction ToolResultRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <ArrowRight className=\"mt-0.5 h-3 w-3 shrink-0 text-violet-400\" />\n <span className=\"text-muted-foreground min-w-0 font-mono text-[11px] break-all\">\n {line.message}\n </span>\n </div>\n </div>\n );\n}\n\nfunction CommandRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <Play className=\"mt-0.5 h-3 w-3 shrink-0 text-cyan-500\" />\n <span className=\"min-w-0 font-mono text-xs break-all text-cyan-700 dark:text-cyan-400\">\n {line.message}\n </span>\n </div>\n </div>\n );\n}\n\nfunction FileChangeRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <FileCode className=\"mt-0.5 h-3 w-3 shrink-0 text-orange-500\" />\n <span className=\"min-w-0 text-xs break-all text-orange-700 dark:text-orange-400\">\n {line.message}\n </span>\n </div>\n </div>\n );\n}\n\nfunction ErrorRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 bg-red-50 px-3 py-1.5 transition-colors dark:bg-red-950/30\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <div className=\"flex min-w-0 flex-1 items-start gap-1.5\">\n <CircleAlert className=\"mt-0.5 h-3 w-3 shrink-0 text-red-500\" />\n <span className=\"min-w-0 text-xs font-medium break-all text-red-700 dark:text-red-400\">\n {line.message}\n </span>\n </div>\n </div>\n );\n}\n\nfunction InfoRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors\">\n <Timestamp value={line.timestamp} />\n <PhaseBadge phase={line.phase} />\n <span className=\"text-muted-foreground min-w-0 text-xs break-all\">{line.message}</span>\n </div>\n );\n}\n\nfunction RawRow({ line }: { line: ParsedLogLine }) {\n return (\n <div className=\"px-3 py-0.5\">\n <span className=\"text-muted-foreground/70 font-mono text-[11px] break-all whitespace-pre-wrap\">\n {line.raw}\n </span>\n </div>\n );\n}\n","'use client';\n\nimport { useRef, useEffect, useState, useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { CircleAlert, Terminal, ArrowDown, Code, FileText } from 'lucide-react';\nimport { EventLogViewer } from './event-log-viewer';\n\nexport interface LogTabProps {\n content: string;\n isConnected: boolean;\n error: string | null;\n}\n\ntype ViewMode = 'structured' | 'raw';\n\nexport function LogTab({ content, isConnected, error }: LogTabProps) {\n const { t } = useTranslation('web');\n const containerRef = useRef<HTMLDivElement>(null);\n const [autoScroll, setAutoScroll] = useState(true);\n const [viewMode, setViewMode] = useState<ViewMode>('structured');\n\n const handleScroll = useCallback(() => {\n const el = containerRef.current;\n if (!el) return;\n const isAtBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 40;\n setAutoScroll(isAtBottom);\n }, []);\n\n const jumpToBottom = useCallback(() => {\n const el = containerRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n setAutoScroll(true);\n }, []);\n\n // Auto-scroll when new content arrives (only if auto-scroll is active)\n useEffect(() => {\n if (autoScroll && containerRef.current) {\n containerRef.current.scrollTop = containerRef.current.scrollHeight;\n }\n }, [content, autoScroll]);\n\n if (error) {\n return (\n <div className=\"flex items-center gap-2 p-4 text-sm text-red-600\">\n <CircleAlert className=\"h-4 w-4 shrink-0\" />\n <span>{error}</span>\n </div>\n );\n }\n\n if (!content) {\n return (\n <div className=\"flex flex-col items-center justify-center gap-2 p-8\">\n <Terminal className=\"text-muted-foreground h-8 w-8\" />\n <p className=\"text-muted-foreground text-sm\">{t('logTab.noLogOutput')}</p>\n {isConnected ? (\n <p className=\"text-muted-foreground text-xs\">Waiting for log data...</p>\n ) : null}\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full flex-col\" data-testid=\"log-tab\">\n {/* Status bar */}\n <div className=\"flex items-center gap-2 border-b px-3 py-1.5\">\n <span\n className={`h-2 w-2 rounded-full ${isConnected ? 'bg-emerald-500' : 'bg-zinc-400'}`}\n />\n <span className=\"text-muted-foreground text-xs\">\n {isConnected ? 'Live' : 'Disconnected'}\n </span>\n\n {/* View mode toggle */}\n <div className=\"ml-auto flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => setViewMode('structured')}\n className={`rounded p-1 transition-colors ${\n viewMode === 'structured'\n ? 'bg-muted text-foreground'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n title={t('logTab.structuredView')}\n >\n <FileText className=\"h-3.5 w-3.5\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setViewMode('raw')}\n className={`rounded p-1 transition-colors ${\n viewMode === 'raw'\n ? 'bg-muted text-foreground'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n title={t('logTab.rawView')}\n >\n <Code className=\"h-3.5 w-3.5\" />\n </button>\n\n {!autoScroll ? (\n <button\n type=\"button\"\n onClick={jumpToBottom}\n className=\"text-muted-foreground hover:text-foreground ms-1 flex items-center gap-1 text-xs\"\n >\n <ArrowDown className=\"h-3 w-3\" />\n Jump to bottom\n </button>\n ) : null}\n </div>\n </div>\n\n {/* Log content */}\n <div\n ref={containerRef}\n onScroll={handleScroll}\n className={`flex-1 overflow-y-auto ${\n viewMode === 'raw'\n ? 'bg-zinc-950 p-3 font-mono text-xs leading-relaxed break-all whitespace-pre-wrap text-zinc-300'\n : 'bg-background'\n }`}\n >\n {viewMode === 'structured' ? <EventLogViewer content={content} /> : content}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useState, useCallback, useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n LoaderCircle,\n Circle,\n Check,\n Eye,\n ChevronRight,\n CircleCheck,\n CircleDashed,\n} from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport type { PlanTaskData, ActionItemData } from '@/app/actions/get-feature-plan';\n\nexport interface TaskProgressViewProps {\n tasks: PlanTaskData[];\n}\n\nconst taskStateConfig: Record<\n string,\n {\n icon: typeof Circle;\n colorClass: string;\n borderClass: string;\n spinning?: boolean;\n label: string;\n }\n> = {\n Todo: {\n icon: Circle,\n colorClass: 'text-muted-foreground',\n borderClass: 'border-border',\n label: 'Todo',\n },\n 'Work in Progress': {\n icon: LoaderCircle,\n colorClass: 'text-blue-600',\n borderClass: 'border-blue-200',\n spinning: true,\n label: 'In Progress',\n },\n Done: {\n icon: Check,\n colorClass: 'text-emerald-600',\n borderClass: 'border-emerald-200',\n label: 'Done',\n },\n Review: {\n icon: Eye,\n colorClass: 'text-amber-600',\n borderClass: 'border-amber-200',\n label: 'Review',\n },\n};\n\nconst defaultTaskConfig = {\n icon: Circle,\n colorClass: 'text-muted-foreground',\n borderClass: 'border-border',\n label: 'Unknown',\n};\n\nexport function TaskProgressView({ tasks }: TaskProgressViewProps) {\n const { t } = useTranslation('web');\n if (tasks.length === 0) {\n return (\n <div className=\"flex flex-col items-center justify-center gap-2 py-4\">\n <p className=\"text-muted-foreground text-sm\">{t('taskProgress.noTasksDefined')}</p>\n </div>\n );\n }\n\n return (\n <div data-testid=\"task-progress-view\" className=\"flex flex-col gap-3\">\n <ProgressSummary tasks={tasks} />\n <div data-testid=\"task-progress-list\" className=\"flex flex-col gap-2\">\n {tasks.map((task, index) => (\n <TaskCard key={task.title || `task-${index}`} task={task} index={index} />\n ))}\n </div>\n </div>\n );\n}\n\n// ── Progress Summary ─────────────────────────────────────────────────\n\nfunction ProgressSummary({ tasks }: { tasks: PlanTaskData[] }) {\n const { t } = useTranslation('web');\n const counts = useMemo(() => {\n const done = tasks.filter((t) => t.state === 'Done').length;\n const wip = tasks.filter((t) => t.state === 'Work in Progress').length;\n const review = tasks.filter((t) => t.state === 'Review').length;\n const todo = tasks.filter(\n (t) => t.state !== 'Done' && t.state !== 'Work in Progress' && t.state !== 'Review'\n ).length;\n const total = tasks.length;\n const percent = total > 0 ? Math.round((done / total) * 100) : 0;\n return { done, wip, review, todo, total, percent };\n }, [tasks]);\n\n return (\n <div data-testid=\"task-progress-summary\" className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-muted-foreground text-xs font-medium\">Task Progress</span>\n <span className=\"text-muted-foreground text-xs\">\n {counts.done} of {counts.total} done\n </span>\n </div>\n <div className=\"bg-muted h-2 w-full overflow-hidden rounded-full\">\n <div\n data-testid=\"task-progress-bar\"\n className=\"h-full rounded-full bg-emerald-500 transition-all\"\n style={{ width: `${counts.percent}%` }}\n />\n </div>\n <div className=\"flex flex-wrap gap-3\">\n {counts.done > 0 ? (\n <StatChip\n icon={Check}\n label={t('taskProgress.done')}\n count={counts.done}\n className=\"text-emerald-600\"\n />\n ) : null}\n {counts.wip > 0 ? (\n <StatChip\n icon={LoaderCircle}\n label={t('taskProgress.inProgress')}\n count={counts.wip}\n className=\"text-blue-600\"\n />\n ) : null}\n {counts.review > 0 ? (\n <StatChip\n icon={Eye}\n label={t('taskProgress.review')}\n count={counts.review}\n className=\"text-amber-600\"\n />\n ) : null}\n {counts.todo > 0 ? (\n <StatChip\n icon={Circle}\n label={t('taskProgress.todo')}\n count={counts.todo}\n className=\"text-muted-foreground\"\n />\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction StatChip({\n icon: Icon,\n label,\n count,\n className,\n}: {\n icon: typeof Circle;\n label: string;\n count: number;\n className?: string;\n}) {\n return (\n <span className={cn('flex items-center gap-1 text-xs', className)}>\n <Icon className=\"h-3 w-3\" />\n {count} {label}\n </span>\n );\n}\n\n// ── Task Card ────────────────────────────────────────────────────────\n\nfunction TaskCard({ task, index }: { task: PlanTaskData; index: number }) {\n const [expanded, setExpanded] = useState(false);\n const config = taskStateConfig[task.state] ?? defaultTaskConfig;\n const Icon = config.icon;\n const hasDetails = task.actionItems.length > 0;\n\n const handleToggle = useCallback(() => {\n if (hasDetails) {\n setExpanded((prev) => !prev);\n }\n }, [hasDetails]);\n\n return (\n <div data-testid={`task-card-${index}`} className={cn('rounded-lg border', config.borderClass)}>\n <button\n type=\"button\"\n onClick={handleToggle}\n disabled={!hasDetails}\n className={cn(\n 'flex w-full items-start gap-2 px-3 py-2.5 text-start',\n hasDetails && 'hover:bg-muted/50 cursor-pointer transition-colors'\n )}\n >\n <Icon\n className={cn(\n 'mt-0.5 h-4 w-4 shrink-0',\n config.colorClass,\n config.spinning && 'animate-spin'\n )}\n />\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <span className={cn('text-sm font-medium', config.colorClass)}>{task.title}</span>\n {task.description ? (\n <span className=\"text-muted-foreground text-xs\">{task.description}</span>\n ) : null}\n </div>\n {hasDetails ? (\n <ChevronRight\n className={cn(\n 'text-muted-foreground mt-0.5 h-4 w-4 shrink-0 transition-transform',\n expanded && 'rotate-90'\n )}\n />\n ) : null}\n </button>\n\n {expanded && hasDetails ? (\n <div className=\"border-t px-3 py-2.5\">\n <div className=\"flex flex-col gap-2\">\n {task.actionItems.map((item, aiIndex) => (\n <ActionItemRow key={item.name || `ai-${aiIndex}`} item={item} />\n ))}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\n// ── Action Item Row ──────────────────────────────────────────────────\n\nfunction ActionItemRow({ item }: { item: ActionItemData }) {\n const totalCriteria = item.acceptanceCriteria.length;\n const verifiedCriteria = item.acceptanceCriteria.filter((ac) => ac.verified).length;\n const allVerified = totalCriteria > 0 && verifiedCriteria === totalCriteria;\n\n return (\n <div data-testid=\"action-item\" className=\"flex flex-col gap-1.5\">\n <div className=\"flex items-start gap-2\">\n {allVerified ? (\n <CircleCheck className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-emerald-600\" />\n ) : (\n <CircleDashed className=\"text-muted-foreground mt-0.5 h-3.5 w-3.5 shrink-0\" />\n )}\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n <span className=\"text-xs font-medium\">{item.name}</span>\n {item.description ? (\n <span className=\"text-muted-foreground text-[11px]\">{item.description}</span>\n ) : null}\n </div>\n {totalCriteria > 0 ? (\n <span className=\"text-muted-foreground ml-auto shrink-0 text-[11px]\">\n {verifiedCriteria}/{totalCriteria}\n </span>\n ) : null}\n </div>\n {totalCriteria > 0 ? (\n <div className=\"ms-5.5 flex flex-col gap-1\">\n {item.acceptanceCriteria.map((ac, acIndex) => (\n <AcceptanceCriterionRow key={ac.description || `ac-${acIndex}`} criterion={ac} />\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n\n// ── Acceptance Criterion Row ─────────────────────────────────────────\n\nfunction AcceptanceCriterionRow({\n criterion,\n}: {\n criterion: { description: string; verified: boolean };\n}) {\n return (\n <div data-testid=\"acceptance-criterion\" className=\"flex items-start gap-1.5\">\n {criterion.verified ? (\n <Check className=\"mt-0.5 h-3 w-3 shrink-0 text-emerald-600\" />\n ) : (\n <Circle className=\"text-muted-foreground mt-0.5 h-3 w-3 shrink-0\" />\n )}\n <span\n className={cn(\n 'text-[11px]',\n criterion.verified ? 'text-muted-foreground line-through' : 'text-foreground'\n )}\n >\n {criterion.description}\n </span>\n </div>\n );\n}\n","'use client';\n\nimport { LoaderCircle } from 'lucide-react';\nimport { CircleAlert, ListTodo } from 'lucide-react';\nimport { Badge } from '@/components/ui/badge';\nimport { TaskProgressView } from '@/components/common/task-progress-view';\nimport type { PlanData } from '@/app/actions/get-feature-plan';\n\nexport interface PlanTabProps {\n plan: PlanData | null;\n loading: boolean;\n error: string | null;\n}\n\nconst planStateBadgeStyles: Record<string, string> = {\n Requirements: 'border-transparent bg-blue-50 text-blue-700 hover:bg-blue-50',\n ClarificationRequired: 'border-transparent bg-amber-50 text-amber-700 hover:bg-amber-50',\n Ready: 'border-transparent bg-green-50 text-green-700 hover:bg-green-50',\n};\n\nexport function PlanTab({ plan, loading, error }: PlanTabProps) {\n if (loading) {\n return (\n <div data-testid=\"plan-tab-loading\" className=\"flex items-center justify-center p-8\">\n <LoaderCircle className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"flex items-center gap-2 p-4 text-sm text-red-600\">\n <CircleAlert className=\"h-4 w-4 shrink-0\" />\n <span>{error}</span>\n </div>\n );\n }\n\n if (!plan) {\n return (\n <div className=\"flex flex-col items-center justify-center gap-2 p-8\">\n <ListTodo className=\"text-muted-foreground h-8 w-8\" />\n <p className=\"text-muted-foreground text-sm\">No plan created yet</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-4 p-4\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-xs font-medium\">Plan State</span>\n <Badge\n className={\n planStateBadgeStyles[plan.state] ?? 'border-transparent bg-gray-50 text-gray-700'\n }\n >\n {plan.state}\n </Badge>\n </div>\n {plan.overview ? (\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-muted-foreground text-xs font-medium\">Overview</span>\n <p className=\"text-sm leading-relaxed\">{plan.overview}</p>\n </div>\n ) : null}\n <TaskProgressView tasks={plan.tasks} />\n </div>\n );\n}\n","'use client';\n\nimport { useState, useEffect, useRef, useCallback } from 'react';\n\nexport interface UseFeatureLogsResult {\n content: string;\n isConnected: boolean;\n error: string | null;\n}\n\nexport function useFeatureLogs(featureId: string | null | undefined): UseFeatureLogsResult {\n const [content, setContent] = useState('');\n const [isConnected, setIsConnected] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const eventSourceRef = useRef<EventSource | null>(null);\n\n const cleanup = useCallback(() => {\n if (eventSourceRef.current) {\n eventSourceRef.current.close();\n eventSourceRef.current = null;\n }\n setIsConnected(false);\n }, []);\n\n useEffect(() => {\n if (!featureId) {\n setContent('');\n setIsConnected(false);\n setError(null);\n return;\n }\n\n // Reset state for new featureId\n setContent('');\n setError(null);\n\n // Connect EventSource for live updates\n const es = new EventSource(`/api/feature-logs?featureId=${featureId}`);\n eventSourceRef.current = es;\n\n es.onopen = () => {\n setIsConnected(true);\n };\n\n es.addEventListener('initial', (event: MessageEvent) => {\n const data: { content: string } = JSON.parse(event.data);\n setContent(data.content);\n });\n\n es.addEventListener('log', (event: MessageEvent) => {\n const data: { content: string } = JSON.parse(event.data);\n setContent((prev) => prev + data.content);\n });\n\n es.addEventListener('error', (event: MessageEvent) => {\n try {\n const data: { error: string } = JSON.parse(event.data);\n setError(data.error);\n } catch {\n setError(event.data ? String(event.data) : 'Log stream unavailable');\n }\n });\n\n es.onerror = () => {\n setIsConnected(false);\n };\n\n return () => {\n es.close();\n eventSourceRef.current = null;\n };\n }, [featureId, cleanup]);\n\n return { content, isConnected, error };\n}\n","'use client';\n\nimport { useState, useRef, useCallback, useEffect } from 'react';\n\n/** State for a single tab's data, loading, and error. */\nexport interface TabState<T = unknown> {\n data: T | null;\n loading: boolean;\n error: string | null;\n}\n\n/** A function that fetches data for a tab given a feature ID. */\nexport type TabFetcher<T = unknown> = (featureId: string) => Promise<T>;\n\n/** Map of tab keys to their fetcher functions. */\nexport type TabFetchers<K extends string> = Record<K, TabFetcher>;\n\n/** Return type of the useTabDataFetch hook. */\nexport interface UseTabDataFetchResult<K extends string> {\n /** Per-tab state (data, loading, error). */\n tabs: Record<K, TabState>;\n /** Fetch data for a tab. Uses cache if already fetched. */\n fetchTab: (tab: K) => Promise<void>;\n /** Force re-fetch for a tab, bypassing cache. */\n refreshTab: (tab: K) => Promise<void>;\n}\n\nfunction createInitialTabState(): TabState {\n return { data: null, loading: false, error: null };\n}\n\n/**\n * Custom hook for lazy-loading tab data with per-tab caching.\n *\n * - Fetches data only when a tab is explicitly activated via fetchTab().\n * - Caches results so revisiting a loaded tab is instant.\n * - Clears all cached data when featureId changes.\n * - Supports force re-fetch via refreshTab() for SSE-driven updates.\n * - Uses ref-based callbacks to avoid stale closures (matches useArtifactFetch pattern).\n */\nexport function useTabDataFetch<K extends string>(\n featureId: string,\n fetchers: TabFetchers<K>\n): UseTabDataFetchResult<K> {\n const tabKeys = Object.keys(fetchers) as K[];\n\n const [tabStates, setTabStates] = useState<Record<K, TabState>>(() => {\n const initial = {} as Record<K, TabState>;\n for (const key of tabKeys) {\n initial[key] = createInitialTabState();\n }\n return initial;\n });\n\n // Ref-based fetchers to avoid stale closures in callbacks.\n const fetchersRef = useRef(fetchers);\n fetchersRef.current = fetchers;\n\n // Ref-based featureId to use current value in callbacks.\n const featureIdRef = useRef(featureId);\n featureIdRef.current = featureId;\n\n // Track mounted state to prevent state updates after unmount.\n const mountedRef = useRef(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n // Clear all cached data when featureId changes.\n const prevFeatureIdRef = useRef(featureId);\n useEffect(() => {\n if (prevFeatureIdRef.current !== featureId) {\n prevFeatureIdRef.current = featureId;\n setTabStates((prev) => {\n const cleared = {} as Record<K, TabState>;\n for (const key of Object.keys(prev) as K[]) {\n cleared[key] = createInitialTabState();\n }\n return cleared;\n });\n }\n }, [featureId]);\n\n const doFetch = useCallback(async (tab: K) => {\n const fetcher = fetchersRef.current[tab];\n const currentFeatureId = featureIdRef.current;\n\n if (!fetcher) return;\n\n // Only show loading spinner when there's no existing data.\n // On refresh (data already present), keep showing stale data while fetching\n // to avoid flickering the entire tab on every poll cycle.\n if (mountedRef.current) {\n setTabStates((prev) => {\n const hasData = prev[tab]?.data !== null;\n if (hasData) return prev; // Keep stale data visible — no loading flash\n return { ...prev, [tab]: { ...prev[tab], loading: true, error: null } };\n });\n }\n\n try {\n const data = await fetcher(currentFeatureId);\n if (mountedRef.current) {\n setTabStates((prev) => ({\n ...prev,\n [tab]: { data, loading: false, error: null },\n }));\n }\n } catch (error: unknown) {\n if (mountedRef.current) {\n setTabStates((prev) => {\n const message = error instanceof Error ? error.message : 'Failed to fetch tab data';\n // On refresh failure, keep existing data instead of clearing it\n const existingData = prev[tab]?.data ?? null;\n return {\n ...prev,\n [tab]: { data: existingData, loading: false, error: existingData ? null : message },\n };\n });\n }\n }\n }, []);\n\n const fetchTab = useCallback(\n async (tab: K) => {\n // Check if data is already cached (non-null data means already fetched)\n const current = tabStates[tab];\n if (current && current.data !== null) return;\n // Also skip if currently loading\n if (current && current.loading) return;\n await doFetch(tab);\n },\n [tabStates, doFetch]\n );\n\n const refreshTab = useCallback(\n async (tab: K) => {\n await doFetch(tab);\n },\n [doFetch]\n );\n\n return {\n tabs: tabStates,\n fetchTab,\n refreshTab,\n };\n}\n","'use client';\n\nimport { useState, useEffect, useCallback, useRef, useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { usePathname } from 'next/navigation';\nimport {\n LoaderCircle,\n CircleAlert,\n LayoutDashboard,\n Activity,\n ScrollText,\n Map,\n FileCheck,\n Cpu,\n Package,\n GitMerge,\n MessageSquare,\n Play,\n Square,\n RotateCcw,\n Zap,\n Layers,\n} from 'lucide-react';\nimport type { NotificationEvent } from '@shipit-ai/core/domain/generated/output';\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\nimport { getFeaturePhaseTimings } from '@/app/actions/get-feature-phase-timings';\nimport type {\n PhaseTimingData,\n RejectionFeedbackData,\n} from '@/app/actions/get-feature-phase-timings';\nimport { getFeaturePlan } from '@/app/actions/get-feature-plan';\nimport type { PlanData } from '@/app/actions/get-feature-plan';\nimport type { FeatureNodeData } from '@/components/common/feature-node';\nimport { cn } from '@/lib/utils';\nimport { featureNodeStateConfig } from '@/components/common/feature-node';\nimport { CometSpinner } from '@/components/ui/comet-spinner';\nimport type { PrdQuestionnaireData } from '@/components/common/prd-questionnaire';\nimport type { TechDecisionsReviewData } from '@/components/common/tech-decisions-review';\nimport type { ProductDecisionsSummaryData } from '@/components/common/product-decisions-summary';\nimport type { MergeReviewData } from '@/components/common/merge-review';\nimport { PrdQuestionnaire } from '@/components/common/prd-questionnaire';\nimport { TechDecisionsContent } from '@/components/common/tech-decisions-review';\nimport { ProductDecisionsSummary } from '@/components/common/product-decisions-summary';\nimport { MergeReview } from '@/components/common/merge-review';\nimport { DrawerActionBar } from '@/components/common/drawer-action-bar';\nimport type { RejectAttachment } from '@/components/common/drawer-action-bar';\nimport { OverviewTab } from './overview-tab';\nimport { ActivityTab } from './activity-tab';\nimport { LogTab } from './log-tab';\nimport { PlanTab } from './plan-tab';\nimport { ChatTab } from '@/components/features/chat/ChatTab';\nimport { useFeatureLogs } from '@/hooks/use-feature-logs';\nimport { useTabDataFetch } from './use-tab-data-fetch';\nimport type { TabFetchers } from './use-tab-data-fetch';\nimport type { FeatureTabKey } from '@/components/common/control-center-drawer/drawer-view';\nimport type { BranchSyncData } from '@/hooks/use-branch-sync-status';\n\n/** Lazy-loaded tab keys (tabs that fetch data on activation). */\ntype LazyTabKey = 'activity' | 'plan';\n\n/** Tab definition for rendering the tab list dynamically. */\ninterface TabDef {\n key: FeatureTabKey;\n label: string;\n icon: React.ComponentType<{ className?: string }>;\n}\n\n/** All possible tabs in display order. */\nconst ALL_TABS: TabDef[] = [\n { key: 'overview', label: 'Overview', icon: LayoutDashboard },\n { key: 'activity', label: 'Activity', icon: Activity },\n { key: 'log', label: 'Log', icon: ScrollText },\n { key: 'plan', label: 'Plan', icon: Map },\n { key: 'prd-review', label: 'PRD Review', icon: FileCheck },\n { key: 'tech-decisions', label: 'Tech Decisions', icon: Cpu },\n { key: 'product-decisions', label: 'Product', icon: Package },\n { key: 'merge-review', label: 'Merge Review', icon: GitMerge },\n { key: 'chat', label: 'Chat', icon: MessageSquare },\n];\n\n/** Compute which tabs are visible based on feature lifecycle + state. */\nfunction computeVisibleTabs(\n node: FeatureNodeData,\n interactiveAgentEnabled = true\n): FeatureTabKey[] {\n const tabs: FeatureTabKey[] = ['overview', 'activity'];\n\n if (node.hasAgentRun) {\n tabs.push('log');\n }\n\n if (node.hasPlan) {\n tabs.push('plan');\n }\n if (node.lifecycle === 'requirements' && node.state === 'action-required') {\n tabs.push('prd-review');\n }\n if (node.lifecycle === 'implementation' && node.state === 'action-required') {\n tabs.push('tech-decisions', 'product-decisions');\n }\n if (node.lifecycle === 'review' && (node.state === 'action-required' || node.state === 'error')) {\n tabs.push('merge-review');\n }\n if (node.lifecycle === 'maintain' && node.pr) {\n tabs.push('merge-review');\n }\n\n // Chat tab is visible for ALL lifecycle phases when interactive agent is enabled\n if (interactiveAgentEnabled) {\n tabs.push('chat');\n }\n\n return tabs;\n}\n\nexport interface FeatureDrawerTabsProps {\n /** Feature name rendered in the inline header. */\n featureName?: string;\n /** Additional header content (repo info, actions) rendered below the title row. */\n headerContent?: React.ReactNode;\n featureNode: FeatureNodeData;\n featureId: string;\n /** Action handlers for the status chip in the title row. */\n onRetry?: (featureId: string) => void;\n onStop?: (featureId: string) => void;\n onStart?: (featureId: string) => void;\n initialTab?: FeatureTabKey;\n /** Tab key from URL path segment (e.g. /feature/[id]/activity → 'activity'). */\n urlTab?: FeatureTabKey;\n /** SSE events from the agent events provider, used to trigger tab data refresh. */\n sseEvents?: readonly NotificationEvent[];\n\n // PRD review\n prdData?: PrdQuestionnaireData | null;\n prdSelections?: Record<string, string>;\n onPrdSelect?: (questionId: string, optionId: string) => void;\n onPrdApprove?: (actionId: string) => void;\n onPrdReject?: (feedback: string, attachments: RejectAttachment[]) => void;\n isPrdLoading?: boolean;\n\n // Tech decisions\n techData?: TechDecisionsReviewData | null;\n onTechApprove?: () => void;\n onTechReject?: (feedback: string, attachments: RejectAttachment[]) => void;\n isTechLoading?: boolean;\n\n // Product decisions\n productData?: ProductDecisionsSummaryData | null;\n\n // Merge review\n mergeData?: MergeReviewData | null;\n onMergeApprove?: () => void;\n onMergeReject?: (feedback: string, attachments: RejectAttachment[]) => void;\n isMergeLoading?: boolean;\n\n // Branch sync\n syncStatus?: BranchSyncData | null;\n syncLoading?: boolean;\n syncError?: string | null;\n onRefreshSync?: () => void;\n\n // Rebase\n onRebaseOnMain?: () => void;\n rebaseLoading?: boolean;\n rebaseError?: string | null;\n\n // Shared\n isRejecting?: boolean;\n chatInput?: string;\n onChatInputChange?: (value: string) => void;\n\n // Interactive agent\n /** When false, the Chat tab is hidden from the tab bar (FR-17). Defaults to true. */\n interactiveAgentEnabled?: boolean;\n}\n\ninterface ActivityData {\n timings: PhaseTimingData[];\n rejectionFeedback: RejectionFeedbackData[];\n}\n\nasync function fetchActivity(featureId: string): Promise<ActivityData> {\n const result = await getFeaturePhaseTimings(featureId);\n if ('error' in result) throw new Error(result.error);\n return { timings: result.timings, rejectionFeedback: result.rejectionFeedback };\n}\n\nasync function fetchPlan(featureId: string): Promise<PlanData | undefined> {\n const result = await getFeaturePlan(featureId);\n if ('error' in result) throw new Error(result.error);\n return result.plan;\n}\n\nconst TAB_FETCHERS: TabFetchers<LazyTabKey> = {\n activity: fetchActivity,\n plan: fetchPlan,\n};\n\nexport function FeatureDrawerTabs({\n featureName,\n headerContent,\n featureNode,\n featureId,\n initialTab,\n urlTab,\n prdData,\n prdSelections,\n onPrdSelect,\n onPrdApprove,\n onPrdReject,\n isPrdLoading,\n techData,\n onTechApprove,\n onTechReject,\n isTechLoading,\n productData,\n mergeData,\n onMergeApprove,\n onMergeReject,\n isMergeLoading,\n syncStatus,\n syncLoading,\n syncError,\n onRefreshSync,\n onRebaseOnMain,\n rebaseLoading,\n rebaseError,\n isRejecting,\n chatInput,\n onChatInputChange,\n sseEvents,\n interactiveAgentEnabled = true,\n onRetry,\n onStop,\n onStart,\n}: FeatureDrawerTabsProps) {\n const pathname = usePathname();\n\n const visibleTabs = useMemo(\n () => computeVisibleTabs(featureNode, interactiveAgentEnabled),\n [featureNode, interactiveAgentEnabled]\n );\n const visibleTabDefs = useMemo(\n () =>\n ALL_TABS.filter((t) => visibleTabs.includes(t.key)).map((t) =>\n t.key === 'merge-review' && featureNode.lifecycle === 'maintain'\n ? { ...t, label: 'Merge History' }\n : t\n ),\n [visibleTabs, featureNode.lifecycle]\n );\n\n // Derive the base path (without tab segment) from the current pathname.\n // e.g. /feature/abc123/activity → /feature/abc123\n const basePath = useMemo(() => {\n const match = pathname.match(/^(\\/feature\\/[^/]+)/);\n return match ? match[1] : pathname;\n }, [pathname]);\n\n // Resolve the effective initial tab: URL path tab > initialTab prop > 'overview'\n const effectiveInitial = useMemo(() => {\n if (urlTab && visibleTabs.includes(urlTab)) return urlTab;\n if (initialTab && visibleTabs.includes(initialTab)) return initialTab;\n return 'overview';\n // Only compute on mount — subsequent changes are handled by effects below\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n const [activeTab, setActiveTab] = useState<FeatureTabKey>(effectiveInitial);\n\n // Only subscribe to log SSE when the log tab is active to avoid\n // opening an EventSource connection on every drawer open.\n const featureLogs = useFeatureLogs(activeTab === 'log' ? featureId : null);\n\n const { tabs, fetchTab, refreshTab } = useTabDataFetch<LazyTabKey>(featureId, TAB_FETCHERS);\n\n // Sync URL when active tab changes via user interaction.\n // Use window.history.pushState instead of router.push to avoid triggering a\n // server component re-render (which would remount the drawer).\n const isUserInteraction = useRef(false);\n useEffect(() => {\n if (!isUserInteraction.current) return;\n isUserInteraction.current = false;\n\n // Build the target URL from the base path + tab segment\n const targetUrl = activeTab === 'overview' ? basePath : `${basePath}/${activeTab}`;\n // Only update URL if it actually changed\n if (targetUrl !== pathname) {\n window.history.pushState(null, '', targetUrl);\n }\n }, [activeTab, basePath, pathname]);\n\n // Sync active tab from URL when pathname changes (e.g. browser back/forward).\n // Skip on initial mount — the effectiveInitial handles that via urlTab prop.\n const prevPathnameRef = useRef(pathname);\n useEffect(() => {\n if (prevPathnameRef.current === pathname) return; // Skip initial mount\n prevPathnameRef.current = pathname;\n if (isUserInteraction.current) return; // Skip — this is our own navigation\n const segments = pathname.split('/');\n // pathname is /feature/[id] or /feature/[id]/[tab]\n const pathTab = segments.length >= 4 ? (segments[3] as FeatureTabKey) : undefined;\n const resolved = pathTab && visibleTabs.includes(pathTab) ? pathTab : 'overview';\n if (resolved !== activeTab) {\n setActiveTab(resolved as FeatureTabKey);\n if (resolved === 'activity' || resolved === 'plan') {\n fetchTab(resolved as LazyTabKey);\n }\n }\n }, [pathname]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // On mount, sync the URL to reflect the effective initial tab when it was\n // derived from feature state (initialTab) rather than from the URL (urlTab).\n // Use replaceState so we don't add a duplicate history entry.\n const initialSyncDone = useRef(false);\n useEffect(() => {\n if (initialSyncDone.current) return;\n initialSyncDone.current = true;\n // Only sync if the effective tab came from initialTab (not from URL)\n if (!urlTab && effectiveInitial !== 'overview') {\n const targetUrl = `${basePath}/${effectiveInitial}`;\n if (targetUrl !== pathname) {\n window.history.replaceState(null, '', targetUrl);\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Trigger lazy fetch for URL-driven initial tab\n const initialFetchDone = useRef(false);\n useEffect(() => {\n if (initialFetchDone.current) return;\n initialFetchDone.current = true;\n if (activeTab === 'activity' || activeTab === 'plan') {\n fetchTab(activeTab);\n }\n }, [activeTab, fetchTab]);\n\n // Reset tab when featureId changes\n const prevFeatureIdRef = useRef(featureId);\n useEffect(() => {\n if (prevFeatureIdRef.current !== featureId) {\n prevFeatureIdRef.current = featureId;\n setActiveTab('overview');\n }\n }, [featureId]);\n\n // When initialTab changes (e.g. SSE updates lifecycle), switch to it if visible\n // and sync the URL with replaceState so the address bar reflects the new tab.\n // Also trigger lazy fetch for the new tab so data is ready immediately.\n const prevInitialTabRef = useRef(initialTab);\n useEffect(() => {\n if (\n prevInitialTabRef.current !== initialTab &&\n initialTab &&\n visibleTabs.includes(initialTab)\n ) {\n prevInitialTabRef.current = initialTab;\n setActiveTab(initialTab);\n // Trigger lazy fetch for the new tab if it's a lazy-loaded tab\n if (initialTab === 'activity' || initialTab === 'plan') {\n fetchTab(initialTab as LazyTabKey);\n }\n // Sync URL to match the new tab\n const targetUrl = initialTab === 'overview' ? basePath : `${basePath}/${initialTab}`;\n if (targetUrl !== window.location.pathname) {\n window.history.replaceState(null, '', targetUrl);\n }\n }\n }, [initialTab, visibleTabs, basePath, fetchTab]);\n\n // If the active tab becomes invisible (lifecycle changed), fall back to overview\n // and sync the URL accordingly.\n useEffect(() => {\n if (!visibleTabs.includes(activeTab)) {\n setActiveTab('overview');\n if (window.location.pathname !== basePath) {\n window.history.replaceState(null, '', basePath);\n }\n }\n }, [visibleTabs, activeTab, basePath]);\n\n // SSE refresh: re-fetch lazy tab data when relevant SSE events arrive\n // for this feature (e.g. PhaseCompleted, AgentStarted, AgentCompleted).\n // Always refresh 'activity' data (even if not the active tab) so switching\n // to the activity tab shows up-to-date timings without a loading flash.\n const activeTabRef = useRef(activeTab);\n activeTabRef.current = activeTab;\n const sseProcessedRef = useRef(0);\n\n useEffect(() => {\n if (!sseEvents || sseEvents.length === 0) return;\n // Clamp cursor if events were pruned\n if (sseProcessedRef.current > sseEvents.length) {\n sseProcessedRef.current = 0;\n }\n if (sseEvents.length <= sseProcessedRef.current) return;\n\n const newEvents = sseEvents.slice(sseProcessedRef.current);\n sseProcessedRef.current = sseEvents.length;\n\n const hasRelevantEvent = newEvents.some((e) => e.featureId === featureId);\n if (!hasRelevantEvent) return;\n\n // Always refresh activity data so it stays current for when the user switches tabs\n refreshTab('activity' as LazyTabKey);\n\n const current = activeTabRef.current;\n if (current === 'plan') {\n refreshTab(current);\n }\n }, [sseEvents, featureId, refreshTab]);\n\n // Poll activity data while the feature is actively running.\n // SSE events only fire on state transitions (phase completed, lifecycle changed),\n // so during a long-running phase there are no events and the data goes stale.\n // Poll every 5s when the feature is in a working state to keep data fresh.\n const isFeatureActive = featureNode.state === 'running' || featureNode.state === 'creating';\n useEffect(() => {\n if (!isFeatureActive) return;\n const interval = setInterval(() => {\n refreshTab('activity' as LazyTabKey);\n }, 5000);\n return () => clearInterval(interval);\n }, [isFeatureActive, refreshTab]);\n\n const handleTabChange = useCallback(\n (value: string) => {\n const tab = value as FeatureTabKey;\n isUserInteraction.current = true;\n setActiveTab(tab);\n if (tab === 'activity' || tab === 'plan') {\n fetchTab(tab);\n }\n },\n [fetchTab]\n );\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <Tabs\n value={activeTab}\n onValueChange={handleTabChange}\n className=\"flex min-h-0 flex-1 flex-col\"\n >\n {/* VS Code-style tab bar — first row */}\n <TabsList className=\"bg-muted/50 h-auto w-full shrink-0 justify-start gap-0 rounded-none border-b p-0\">\n {visibleTabDefs.map((tab) => {\n const Icon = tab.icon;\n return (\n <TabsTrigger\n key={tab.key}\n value={tab.key}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:border-t-primary [&:not([data-state=active])]:border-r-border relative h-auto rounded-none border-t-2 border-r border-t-transparent border-r-transparent bg-transparent px-3.5 py-2.5 text-[13px] font-normal shadow-none transition-none last:border-r-transparent data-[state=active]:shadow-none\"\n >\n <Icon className=\"mr-1.5 size-4\" />\n {tab.label}\n </TabsTrigger>\n );\n })}\n </TabsList>\n {/* Persistent header — contrasting background */}\n <div className=\"bg-muted/40 shrink-0 border-b\">\n {/* Feature / repo + status chip */}\n {featureName ? (\n <div\n className=\"flex h-12 items-stretch gap-2 pr-0 pl-4\"\n data-testid=\"feature-drawer-header\"\n >\n {/* Fast/SDLC icon */}\n <div className=\"flex items-center\">\n {featureNode.fastMode ? (\n <Zap className=\"size-4 shrink-0 text-amber-500\" />\n ) : (\n <Layers className=\"text-muted-foreground/50 size-4 shrink-0\" />\n )}\n </div>\n {/* Feature name */}\n <h2 className=\"text-foreground flex min-w-0 items-center truncate text-base font-semibold tracking-tight\">\n {featureName}\n </h2>\n {/* / repo */}\n {featureNode.repositoryName ? (\n <span className=\"animate-in fade-in flex shrink-0 items-center gap-1.5 self-center duration-200\">\n <span className=\"text-muted-foreground/30 text-sm\">/</span>\n {featureNode.remoteUrl ? (\n <a\n href={featureNode.remoteUrl as string}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-muted-foreground hover:text-foreground text-sm\"\n >\n {featureNode.repositoryName}\n </a>\n ) : (\n <span className=\"text-muted-foreground text-sm\">\n {featureNode.repositoryName}\n </span>\n )}\n </span>\n ) : (\n <span className=\"flex items-center gap-1.5 self-center\">\n <span className=\"text-muted-foreground/30 text-sm\">/</span>\n <span className=\"bg-muted h-4 w-16 animate-pulse rounded\" />\n </span>\n )}\n\n {/* Status chip + action button */}\n <TooltipProvider delayDuration={300}>\n <Tooltip>\n <TooltipTrigger asChild>\n <div className=\"ml-auto flex shrink-0 cursor-default items-center self-stretch text-xs font-medium\">\n <div\n className={cn(\n 'flex items-center gap-1.5 self-stretch px-3',\n featureNodeStateConfig[featureNode.state].labelClass\n )}\n >\n {featureNode.state === 'running' ? (\n <CometSpinner size=\"sm\" className=\"shrink-0\" />\n ) : (\n (() => {\n const I = featureNodeStateConfig[featureNode.state].icon;\n return <I className=\"size-3.5 shrink-0\" />;\n })()\n )}\n {featureNodeStateConfig[featureNode.state].label}\n </div>\n {/* Inline action button */}\n {featureNode.state === 'pending' && onStart ? (\n <button\n type=\"button\"\n onClick={() => onStart(featureNode.featureId)}\n className=\"text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-green-500/10 hover:text-green-600 dark:hover:text-green-400\"\n data-testid=\"feature-drawer-start-button\"\n >\n <Play className=\"size-3.5\" /> Start\n </button>\n ) : featureNode.state === 'error' && onRetry ? (\n <button\n type=\"button\"\n onClick={() => onRetry(featureNode.featureId)}\n className=\"text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-red-500/10 hover:text-red-500 dark:hover:text-red-400\"\n data-testid=\"feature-drawer-retry-button\"\n >\n <RotateCcw className=\"size-3.5\" /> Retry\n </button>\n ) : featureNode.state === 'running' && onStop ? (\n <button\n type=\"button\"\n onClick={() => onStop(featureNode.featureId)}\n className=\"text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-red-500/10 hover:text-red-500 dark:hover:text-red-400\"\n data-testid=\"feature-drawer-stop-button\"\n >\n <Square className=\"size-3.5\" /> Stop\n </button>\n ) : null}\n </div>\n </TooltipTrigger>\n {featureNode.errorMessage ? (\n <TooltipContent\n side=\"bottom\"\n align=\"end\"\n sideOffset={4}\n className=\"z-[100] max-w-xs cursor-pointer text-xs leading-relaxed select-text\"\n onClick={() => {\n void navigator.clipboard.writeText(featureNode.errorMessage!);\n }}\n >\n {featureNode.errorMessage}\n <span className=\"text-muted-foreground ml-1 text-[10px] italic\">\n (click to copy)\n </span>\n </TooltipContent>\n ) : null}\n </Tooltip>\n </TooltipProvider>\n </div>\n ) : null}\n {/* IDE toolbar */}\n {headerContent}\n </div>\n\n <TabsContent value=\"overview\" className=\"mt-0 flex-1 overflow-y-auto\">\n <OverviewTab\n data={featureNode}\n syncStatus={syncStatus}\n syncLoading={syncLoading}\n syncError={syncError}\n onRefreshSync={onRefreshSync}\n onRebaseOnMain={onRebaseOnMain}\n rebaseLoading={rebaseLoading}\n rebaseError={rebaseError}\n />\n </TabsContent>\n\n <TabsContent value=\"activity\" className=\"mt-0 flex-1 overflow-y-auto\">\n <ActivityTab\n timings={(tabs.activity.data as ActivityData | null)?.timings ?? null}\n loading={tabs.activity.loading}\n error={tabs.activity.error}\n rejectionFeedback={(tabs.activity.data as ActivityData | null)?.rejectionFeedback}\n />\n </TabsContent>\n\n <TabsContent value=\"log\" className=\"mt-0 flex-1 overflow-hidden\">\n <LogTab\n content={featureLogs.content}\n isConnected={featureLogs.isConnected}\n error={featureLogs.error}\n />\n </TabsContent>\n\n <TabsContent value=\"plan\" className=\"mt-0 flex-1 overflow-y-auto\">\n <PlanTab\n plan={tabs.plan.data as PlanData | null}\n loading={tabs.plan.loading}\n error={tabs.plan.error}\n />\n </TabsContent>\n\n {/* PRD Review tab */}\n {visibleTabs.includes('prd-review') ? (\n <TabsContent value=\"prd-review\" className=\"mt-0 flex min-h-0 flex-1 flex-col\">\n {prdData ? (\n <PrdQuestionnaire\n data={prdData}\n selections={prdSelections ?? {}}\n onSelect={onPrdSelect ?? (() => undefined)}\n onApprove={onPrdApprove ?? (() => undefined)}\n onReject={onPrdReject}\n isProcessing={isPrdLoading}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={onChatInputChange}\n />\n ) : (\n <div className=\"flex items-center justify-center p-8\">\n <LoaderCircle className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n </div>\n )}\n </TabsContent>\n ) : null}\n\n {/* Tech Decisions tab */}\n {visibleTabs.includes('tech-decisions') ? (\n <TabsContent value=\"tech-decisions\" className=\"mt-0 flex min-h-0 flex-1 flex-col\">\n {techData ? (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"flex-1 overflow-y-auto\">\n <TechDecisionsContent data={techData} />\n </div>\n <DrawerActionBarForTech\n onApprove={onTechApprove ?? (() => undefined)}\n onReject={onTechReject}\n isProcessing={isTechLoading}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={onChatInputChange}\n />\n </div>\n ) : (\n <div className=\"flex items-center justify-center p-8\">\n <LoaderCircle className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n </div>\n )}\n </TabsContent>\n ) : null}\n\n {/* Product Decisions tab */}\n {visibleTabs.includes('product-decisions') ? (\n <TabsContent value=\"product-decisions\" className=\"mt-0 flex-1 overflow-y-auto\">\n {productData === null ? (\n <div className=\"flex items-center justify-center p-8\">\n <LoaderCircle className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n </div>\n ) : productData ? (\n <ProductDecisionsSummary data={productData} />\n ) : (\n <p className=\"text-muted-foreground p-4 text-center text-sm\">\n No product decisions available.\n </p>\n )}\n </TabsContent>\n ) : null}\n\n {/* Merge Review tab */}\n {visibleTabs.includes('merge-review') ? (\n <TabsContent value=\"merge-review\" className=\"mt-0 flex min-h-0 flex-1 flex-col\">\n {mergeData ? (\n <MergeReview\n data={mergeData}\n readOnly={featureNode.lifecycle === 'maintain'}\n onApprove={onMergeApprove ?? (() => undefined)}\n onReject={onMergeReject}\n isProcessing={isMergeLoading}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={onChatInputChange}\n />\n ) : (\n <div className=\"flex items-center justify-center p-8\">\n {isMergeLoading ? (\n <LoaderCircle className=\"text-muted-foreground h-6 w-6 animate-spin\" />\n ) : (\n <div className=\"text-muted-foreground flex flex-col items-center gap-2 text-sm\">\n <CircleAlert className=\"h-6 w-6\" />\n <span>Merge review data unavailable</span>\n </div>\n )}\n </div>\n )}\n </TabsContent>\n ) : null}\n\n {/* Chat tab — always visible when interactive agent is enabled (FR-1, FR-17) */}\n {visibleTabs.includes('chat') ? (\n <TabsContent value=\"chat\" className=\"mt-0 flex min-h-0 flex-1 flex-col overflow-hidden\">\n <ChatTab featureId={featureId} worktreePath={featureNode.worktreePath} />\n </TabsContent>\n ) : null}\n </Tabs>\n </div>\n );\n}\n\n// ── Private helper ──────────────────────────────────────────────────────\n\nfunction DrawerActionBarForTech({\n onApprove,\n onReject,\n isProcessing,\n isRejecting,\n chatInput,\n onChatInputChange,\n}: {\n onApprove: () => void;\n onReject?: (feedback: string, attachments: RejectAttachment[]) => void;\n isProcessing?: boolean;\n isRejecting?: boolean;\n chatInput?: string;\n onChatInputChange?: (value: string) => void;\n}) {\n const { t } = useTranslation('web');\n return (\n <DrawerActionBar\n onReject={onReject}\n onApprove={onApprove}\n approveLabel={t('featureDrawer.approvePlan')}\n revisionPlaceholder=\"Ask AI to revise the plan...\"\n isProcessing={isProcessing}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={onChatInputChange}\n />\n );\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"4087ffdfb839efc5a1432be35b5b3f4396542c568d\":{\"name\":\"rebaseFeature\"}},\"src/presentation/web/app/actions/rebase-feature.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"4087ffdfb839efc5a1432be35b5b3f4396542c568d\",callServer,void 0,findSourceMapURL,\"rebaseFeature\");export{$$RSC_SERVER_ACTION_0 as rebaseFeature};","'use client';\n\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport { openIde } from '@/app/actions/open-ide';\nimport { openShell } from '@/app/actions/open-shell';\nimport { openFolder } from '@/app/actions/open-folder';\nimport { rebaseFeature } from '@/app/actions/rebase-feature';\n\nexport interface FeatureActionsInput {\n featureId: string;\n repositoryPath: string;\n branch: string;\n worktreePath?: string;\n specPath?: string;\n}\n\nexport interface FeatureActionsState {\n openInIde: () => Promise<void>;\n openInShell: () => Promise<void>;\n openFolder: () => Promise<void>;\n openSpecsFolder: () => Promise<void>;\n rebaseOnMain: () => Promise<void>;\n ideLoading: boolean;\n shellLoading: boolean;\n folderLoading: boolean;\n specsLoading: boolean;\n rebaseLoading: boolean;\n ideError: string | null;\n shellError: string | null;\n folderError: string | null;\n specsError: string | null;\n rebaseError: string | null;\n}\n\nconst ERROR_CLEAR_DELAY = 5000;\n\nexport function useFeatureActions(input: FeatureActionsInput | null): FeatureActionsState {\n const [ideLoading, setIdeLoading] = useState(false);\n const [shellLoading, setShellLoading] = useState(false);\n const [folderLoading, setFolderLoading] = useState(false);\n const [specsLoading, setSpecsLoading] = useState(false);\n const [rebaseLoading, setRebaseLoading] = useState(false);\n const [ideError, setIdeError] = useState<string | null>(null);\n const [shellError, setShellError] = useState<string | null>(null);\n const [folderError, setFolderError] = useState<string | null>(null);\n const [specsError, setSpecsError] = useState<string | null>(null);\n const [rebaseError, setRebaseError] = useState<string | null>(null);\n\n const ideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const shellTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const folderTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const specsTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const rebaseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Clear timers on unmount — read .current inside cleanup so we get the\n // actual timer value at teardown time, not the always-null value at mount.\n useEffect(() => {\n const refs = [ideTimerRef, shellTimerRef, folderTimerRef, specsTimerRef, rebaseTimerRef];\n return () => {\n for (const ref of refs) {\n if (ref.current) clearTimeout(ref.current);\n }\n };\n }, []);\n\n const performAction = useCallback(\n async (\n action: (input: { repositoryPath: string; branch?: string }) => Promise<{\n success: boolean;\n error?: string;\n }>,\n setLoading: (v: boolean) => void,\n setError: (v: string | null) => void,\n timerRef: React.RefObject<ReturnType<typeof setTimeout> | null>,\n isLoading: boolean\n ) => {\n if (!input || isLoading) return;\n\n // Clear any existing timer\n if (timerRef.current) clearTimeout(timerRef.current);\n\n setLoading(true);\n setError(null);\n\n try {\n const result = await action({\n repositoryPath: input.repositoryPath,\n branch: input.branch,\n });\n\n if (!result.success) {\n const errorMessage = result.error ?? 'An unexpected error occurred';\n setError(errorMessage);\n timerRef.current = setTimeout(() => setError(null), ERROR_CLEAR_DELAY);\n }\n } catch (err: unknown) {\n const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';\n setError(errorMessage);\n timerRef.current = setTimeout(() => setError(null), ERROR_CLEAR_DELAY);\n } finally {\n setLoading(false);\n }\n },\n [input]\n );\n\n const handleOpenIde = useCallback(\n () => performAction(openIde, setIdeLoading, setIdeError, ideTimerRef, ideLoading),\n [performAction, ideLoading]\n );\n\n const handleOpenShell = useCallback(\n () => performAction(openShell, setShellLoading, setShellError, shellTimerRef, shellLoading),\n [performAction, shellLoading]\n );\n\n const handleOpenFolder = useCallback(async () => {\n if (!input || folderLoading) return;\n\n if (folderTimerRef.current) clearTimeout(folderTimerRef.current);\n\n setFolderLoading(true);\n setFolderError(null);\n\n try {\n const folderPath = input.worktreePath ?? input.repositoryPath;\n const result = await openFolder(folderPath);\n\n if (!result.success) {\n const errorMessage = result.error ?? 'An unexpected error occurred';\n setFolderError(errorMessage);\n folderTimerRef.current = setTimeout(() => setFolderError(null), ERROR_CLEAR_DELAY);\n }\n } catch (err: unknown) {\n const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';\n setFolderError(errorMessage);\n folderTimerRef.current = setTimeout(() => setFolderError(null), ERROR_CLEAR_DELAY);\n } finally {\n setFolderLoading(false);\n }\n }, [input, folderLoading]);\n\n const handleOpenSpecsFolder = useCallback(async () => {\n if (!input?.specPath || specsLoading) return;\n\n if (specsTimerRef.current) clearTimeout(specsTimerRef.current);\n\n setSpecsLoading(true);\n setSpecsError(null);\n\n try {\n const result = await openFolder(input.specPath);\n\n if (!result.success) {\n const errorMessage = result.error ?? 'An unexpected error occurred';\n setSpecsError(errorMessage);\n specsTimerRef.current = setTimeout(() => setSpecsError(null), ERROR_CLEAR_DELAY);\n }\n } catch (err: unknown) {\n const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';\n setSpecsError(errorMessage);\n specsTimerRef.current = setTimeout(() => setSpecsError(null), ERROR_CLEAR_DELAY);\n } finally {\n setSpecsLoading(false);\n }\n }, [input, specsLoading]);\n\n const handleRebaseOnMain = useCallback(async () => {\n if (!input?.featureId || rebaseLoading) return;\n\n if (rebaseTimerRef.current) clearTimeout(rebaseTimerRef.current);\n\n setRebaseLoading(true);\n setRebaseError(null);\n\n try {\n const result = await rebaseFeature(input.featureId);\n\n if (!result.success) {\n const errorMessage = result.error ?? 'An unexpected error occurred';\n setRebaseError(errorMessage);\n rebaseTimerRef.current = setTimeout(() => setRebaseError(null), ERROR_CLEAR_DELAY);\n }\n } catch (err: unknown) {\n const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';\n setRebaseError(errorMessage);\n rebaseTimerRef.current = setTimeout(() => setRebaseError(null), ERROR_CLEAR_DELAY);\n } finally {\n setRebaseLoading(false);\n }\n }, [input, rebaseLoading]);\n\n return {\n openInIde: handleOpenIde,\n openInShell: handleOpenShell,\n openFolder: handleOpenFolder,\n openSpecsFolder: handleOpenSpecsFolder,\n rebaseOnMain: handleRebaseOnMain,\n ideLoading,\n shellLoading,\n folderLoading,\n specsLoading,\n rebaseLoading,\n ideError,\n shellError,\n folderError,\n specsError,\n rebaseError,\n };\n}\n","'use client';\n\nimport { useState, useEffect, useRef } from 'react';\nimport { toast } from 'sonner';\n\n/**\n * Generic hook for fetching drawer artifact data when a feature ID changes.\n * Handles loading state, cancellation on unmount/re-fetch, and error toasting.\n *\n * @param featureId - The feature ID to fetch for, or null to reset.\n * @param fetcher - Async function that fetches the artifact data.\n * @param onSuccess - Called with the fetch result when successful and not cancelled.\n * @param onReset - Called immediately when featureId changes (before fetching).\n * @param errorMessage - Optional toast message shown on fetch failure.\n * @param refreshKey - Optional key that forces a re-fetch when it changes (even if featureId is the same).\n * @returns Whether the fetch is currently in progress.\n */\nexport function useArtifactFetch<TResult>(\n featureId: string | null,\n fetcher: (id: string) => Promise<TResult>,\n onSuccess: (result: TResult) => void,\n onReset: () => void,\n errorMessage?: string,\n refreshKey?: number\n): boolean {\n const [isLoading, setIsLoading] = useState(false);\n\n // Use refs to avoid stale callbacks in the effect without triggering re-runs.\n const onSuccessRef = useRef(onSuccess);\n const onResetRef = useRef(onReset);\n onSuccessRef.current = onSuccess;\n onResetRef.current = onReset;\n\n useEffect(() => {\n onResetRef.current();\n if (!featureId) return;\n\n let cancelled = false;\n setIsLoading(true);\n\n fetcher(featureId)\n .then((result) => {\n if (!cancelled) onSuccessRef.current(result);\n })\n .catch(() => {\n if (!cancelled && errorMessage) toast.error(errorMessage);\n })\n .finally(() => {\n if (!cancelled) setIsLoading(false);\n });\n\n return () => {\n cancelled = true;\n };\n }, [featureId, fetcher, errorMessage, refreshKey]);\n\n return isLoading;\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"40fc3e2a976f8fe5df98685b8e831e7514bfc01fcb\":{\"name\":\"getFeatureDrawerData\"}},\"src/presentation/web/app/actions/get-feature-drawer-data.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"40fc3e2a976f8fe5df98685b8e831e7514bfc01fcb\",callServer,void 0,findSourceMapURL,\"getFeatureDrawerData\");export{$$RSC_SERVER_ACTION_0 as getFeatureDrawerData};","'use client';\n\nimport { useEffect, useRef, useCallback } from 'react';\nimport { getFeatureDrawerData } from '@/app/actions/get-feature-drawer-data';\nimport type { FeatureNodeData } from '@/components/common/feature-node';\nimport { deriveInitialTab } from './drawer-view';\nimport type { DrawerView } from './drawer-view';\n\n/** How often (ms) to run a background sync while the drawer is open. */\nconst BACKGROUND_SYNC_INTERVAL_MS = 15_000;\n\n/**\n * Targeted drawer data synchronization — replaces router.refresh() for\n * keeping the feature drawer in sync with the server.\n *\n * - On drawer open: fetches fresh FeatureNodeData via server action\n * - Background sync: every 15s while open, merges fresh data into view\n * - SSE-driven state/lifecycle updates are handled separately (not here)\n * - Never affects form state (chatInput, prdSelections, attachments)\n */\nexport function useDrawerSync(\n isOpen: boolean,\n featureId: string | null,\n setView: React.Dispatch<React.SetStateAction<DrawerView>>\n): void {\n const wasOpenRef = useRef(isOpen);\n const isFetchingRef = useRef(false);\n // Incremented on every open transition — stale fetches from a previous\n // open/close cycle are discarded so they can't overwrite fresh data.\n const generationRef = useRef(0);\n\n const syncFromServer = useCallback(async () => {\n if (!featureId || isFetchingRef.current) return;\n isFetchingRef.current = true;\n const gen = generationRef.current;\n try {\n const data = await getFeatureDrawerData(featureId);\n if (!data) return;\n // Discard result if the drawer was closed and reopened while fetching\n if (gen !== generationRef.current) return;\n setView((prev) => mergeFeatureData(prev, data));\n } catch {\n // Silent — background sync failure is non-critical\n } finally {\n isFetchingRef.current = false;\n }\n }, [featureId, setView]);\n\n // Fetch full data when drawer opens (either on mount or closed→open transition).\n // The server component only provides minimal data (feature + agent run);\n // expensive fields (repo name, remote URL, CI status, etc.) are loaded here.\n const hasFetchedOnMountRef = useRef(false);\n useEffect(() => {\n if (isOpen && (!wasOpenRef.current || !hasFetchedOnMountRef.current)) {\n hasFetchedOnMountRef.current = true;\n // New open transition — bump generation to invalidate any in-flight fetch\n // from a previous cycle and reset the fetching guard.\n generationRef.current += 1;\n isFetchingRef.current = false;\n void syncFromServer();\n }\n wasOpenRef.current = isOpen;\n }, [isOpen, syncFromServer]);\n\n // Background sync: throttled interval while drawer is open\n useEffect(() => {\n if (!isOpen || !featureId) return;\n\n const timer = setInterval(() => {\n void syncFromServer();\n }, BACKGROUND_SYNC_INTERVAL_MS);\n\n return () => clearInterval(timer);\n }, [isOpen, featureId, syncFromServer]);\n}\n\n/**\n * Merges fresh server data into the current drawer view.\n * Preserves the view type and only updates the feature node data,\n * keeping all client-side state (form inputs, selections) untouched.\n */\nfunction mergeFeatureData(prev: DrawerView, freshData: FeatureNodeData): DrawerView {\n if (prev.type !== 'feature') return prev;\n\n const merged: FeatureNodeData = { ...prev.node, ...freshData };\n\n // Only re-derive initialTab when state or lifecycle actually changed.\n // Re-deriving on every background sync would reset the chat input\n // (which clears on initialTab change) even when nothing meaningful changed.\n const tabChanged = merged.state !== prev.node.state || merged.lifecycle !== prev.node.lifecycle;\n\n return {\n ...prev,\n node: merged,\n initialTab: tabChanged ? deriveInitialTab(merged) : prev.initialTab,\n };\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"4048c112b210f515d861c0702ac4e90c4d6a2dcf54\":{\"name\":\"getBranchSyncStatus\"}},\"src/presentation/web/app/actions/get-branch-sync-status.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"4048c112b210f515d861c0702ac4e90c4d6a2dcf54\",callServer,void 0,findSourceMapURL,\"getBranchSyncStatus\");export{$$RSC_SERVER_ACTION_0 as getBranchSyncStatus};","'use client';\n\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { useCallback, useMemo, useState } from 'react';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { Badge } from '@/components/ui/badge';\nimport { DrawerActionBar } from '@/components/common/drawer-action-bar';\nimport { useSoundAction } from '@/hooks/use-sound-action';\nimport type { PrdQuestionnaireProps } from './prd-questionnaire-config';\n\nexport function PrdQuestionnaire({\n data,\n selections,\n onSelect,\n onApprove,\n onReject,\n isProcessing = false,\n isRejecting = false,\n showHeader = false,\n chatInput,\n onChatInputChange,\n}: PrdQuestionnaireProps) {\n const { question, context, questions, finalAction } = data;\n const [currentStep, setCurrentStep] = useState(0);\n const selectSound = useSoundAction('select');\n const navigateSound = useSoundAction('navigate');\n\n const total = questions.length;\n const isFirstStep = currentStep === 0;\n const isLastStep = currentStep === total - 1;\n const currentQuestion = questions[currentStep];\n\n const answeredCount = useMemo(() => Object.keys(selections).length, [selections]);\n\n const handleSelect = useCallback(\n (questionId: string, optionId: string) => {\n selectSound.play();\n onSelect(questionId, optionId);\n // Auto-advance to the next step after selection (unless last step)\n if (!isLastStep) {\n setTimeout(() => setCurrentStep((s) => s + 1), 250);\n }\n },\n [onSelect, isLastStep, selectSound]\n );\n\n if (total === 0) return null;\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"flex-1 space-y-4 overflow-y-auto p-4\">\n {/* Header */}\n {showHeader ? (\n <div className=\"border-border flex items-start gap-3 border-b pb-3\">\n <div className=\"mt-1.5 h-2 w-2 shrink-0 rounded-full bg-amber-500\" />\n <div className=\"flex-1\">\n <h3 className=\"text-foreground mb-1.5 text-sm font-bold\">{question}</h3>\n <p className=\"text-muted-foreground text-xs leading-relaxed\">{context}</p>\n </div>\n </div>\n ) : null}\n\n {/* Question + step indicator */}\n <div className=\"space-y-3\">\n <div className=\"flex items-start gap-3\">\n <label className=\"text-foreground min-w-0 flex-1 text-sm font-semibold\">\n {currentStep + 1}. {currentQuestion.question}\n </label>\n <div className=\"mt-1.5 flex shrink-0 gap-1\">\n {questions.map((q, idx) => (\n <button\n key={q.id}\n type=\"button\"\n aria-label={`Go to question ${idx + 1}`}\n className={cn(\n 'h-1.5 rounded-full transition-all duration-200',\n idx === currentStep ? 'bg-primary w-4' : 'w-1.5',\n idx !== currentStep && selections[q.id] ? 'bg-primary/50' : '',\n idx !== currentStep && !selections[q.id] ? 'bg-muted-foreground/25' : ''\n )}\n onClick={() => {\n navigateSound.play();\n setCurrentStep(idx);\n }}\n />\n ))}\n </div>\n </div>\n <div className=\"space-y-2\">\n {currentQuestion.options.map((opt, optIdx) => {\n const selected = selections[currentQuestion.id] === opt.id;\n const letter = String.fromCharCode(65 + optIdx);\n return (\n <button\n key={opt.id}\n type=\"button\"\n className={cn(\n 'border-border w-full overflow-hidden rounded-md border px-3 py-3 text-start text-xs transition-all',\n 'hover:border-primary/70 hover:bg-primary/5 group',\n selected && 'border-primary bg-primary/5',\n opt.isNew && 'animate-option-highlight'\n )}\n disabled={isProcessing}\n onClick={() => handleSelect(currentQuestion.id, opt.id)}\n >\n <div className=\"flex items-start gap-2\">\n <span className=\"text-muted-foreground mt-0.5 font-mono text-xs\">\n {letter}.\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-foreground mb-0.5 text-xs font-semibold wrap-break-word\">\n {opt.label}\n </div>\n <div className=\"text-muted-foreground text-xs leading-snug\">\n {opt.rationale}\n </div>\n </div>\n {opt.recommended || opt.isNew ? (\n <div className=\"shrink-0 pt-0.5\">\n {opt.recommended ? (\n <Badge className=\"px-1.5 py-0 text-[10px] whitespace-nowrap\">\n AI Recommended\n </Badge>\n ) : (\n <Badge className=\"border-transparent bg-emerald-600 px-1.5 py-0 text-[10px] whitespace-nowrap text-white hover:bg-emerald-600/80\">\n New\n </Badge>\n )}\n </div>\n ) : null}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Step navigation */}\n <div className=\"flex items-center justify-between pt-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={isFirstStep || isProcessing}\n onClick={() => {\n navigateSound.play();\n setCurrentStep((s) => s - 1);\n }}\n >\n <ChevronLeft className=\"me-1 h-4 w-4\" />\n Previous\n </Button>\n\n {!isLastStep ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={isProcessing}\n onClick={() => {\n navigateSound.play();\n setCurrentStep((s) => s + 1);\n }}\n >\n {selections[currentQuestion.id] ? 'Next' : 'Skip'}\n <ChevronRight className=\"ms-1 h-4 w-4\" />\n </Button>\n ) : null}\n </div>\n </div>\n\n <DrawerActionBar\n onReject={onReject}\n onApprove={() => onApprove(finalAction.id)}\n approveLabel={finalAction.label}\n revisionPlaceholder=\"Ask AI to refine requirements...\"\n isProcessing={isProcessing}\n isRejecting={isRejecting}\n chatInput={chatInput}\n onChatInputChange={onChatInputChange}\n >\n <div\n className={cn(\n 'bg-muted h-1.5 overflow-hidden',\n (answeredCount > 0 && answeredCount < total) || isProcessing\n ? 'opacity-100'\n : 'opacity-0',\n 'transition-opacity duration-200'\n )}\n data-testid=\"progress-bar-container\"\n >\n {isProcessing ? (\n <div className=\"bg-primary animate-indeterminate-progress h-full w-1/3\" />\n ) : (\n <div\n className=\"bg-primary h-full transition-all duration-300\"\n style={{ width: `${total > 0 ? (answeredCount / total) * 100 : 0}%` }}\n data-testid=\"progress-bar\"\n />\n )}\n </div>\n </DrawerActionBar>\n </div>\n );\n}\n","import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\nconst cometSpinnerVariants = cva('inline-block shrink-0', {\n variants: {\n size: {\n sm: 'size-5',\n md: 'size-8',\n lg: 'size-12',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nexport interface CometSpinnerProps\n extends React.SVGAttributes<SVGSVGElement>, VariantProps<typeof cometSpinnerVariants> {\n /** Duration in seconds for the outer rotation. */\n duration?: number;\n}\n\nconst PARTICLES = [\n { r: 9, spline: '0.12 0 0.04 1', opacity: 1 },\n { r: 8.2, spline: '0.16 0 0.08 1', opacity: 0.95 },\n { r: 7.4, spline: '0.20 0 0.12 1', opacity: 0.9 },\n { r: 6.6, spline: '0.25 0 0.16 1', opacity: 0.84 },\n { r: 5.8, spline: '0.30 0 0.20 1', opacity: 0.76 },\n { r: 5, spline: '0.36 0 0.25 1', opacity: 0.67 },\n { r: 4.2, spline: '0.42 0 0.31 1', opacity: 0.56 },\n { r: 3.4, spline: '0.48 0 0.37 1', opacity: 0.44 },\n { r: 2.6, spline: '0.55 0 0.44 1', opacity: 0.32 },\n { r: 1.8, spline: '0.62 0 0.52 1', opacity: 0.2 },\n { r: 1, spline: '0.70 0 0.60 1', opacity: 0.1 },\n];\n\nfunction CometSpinner({ className, size = 'md', duration = 5, ...props }: CometSpinnerProps) {\n return (\n <svg\n data-slot=\"comet-spinner\"\n role=\"status\"\n aria-label=\"Loading\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 100 100\"\n className={cn(cometSpinnerVariants({ size }), className)}\n {...props}\n >\n <defs>\n <filter\n id=\"comet-gooey\"\n x=\"-100%\"\n y=\"-100%\"\n width=\"300%\"\n height=\"300%\"\n colorInterpolationFilters=\"sRGB\"\n >\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"2.5\" />\n <feColorMatrix\n mode=\"matrix\"\n values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 50 -30\"\n result=\"goo\"\n />\n </filter>\n </defs>\n\n <g filter=\"url(#comet-gooey)\">\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 50 50\"\n to=\"360 50 50\"\n dur={`${duration}s`}\n repeatCount=\"indefinite\"\n />\n\n {PARTICLES.map((p) => (\n <g key={p.r}>\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n calcMode=\"spline\"\n values=\"0 50 50;360 50 50\"\n keyTimes=\"0;1\"\n keySplines={p.spline}\n dur=\"1s\"\n repeatCount=\"indefinite\"\n />\n <circle cx=\"50\" cy=\"18\" r={p.r} fill=\"currentColor\" opacity={p.opacity} />\n </g>\n ))}\n\n <circle cx=\"50\" cy=\"50\" r=\"4\" fill=\"currentColor\" opacity=\"0.15\">\n <animate attributeName=\"r\" values=\"3;5;3\" dur=\"2s\" repeatCount=\"indefinite\" />\n <animate\n attributeName=\"opacity\"\n values=\"0.1;0.25;0.1\"\n dur=\"2s\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </g>\n </svg>\n );\n}\n\nexport { CometSpinner, cometSpinnerVariants };\n","/**\n * Formats a duration in milliseconds to a human-friendly string.\n *\n * - 0ms → \"0s\"\n * - <1s → \"<1s\"\n * - <60s → \"Xs\"\n * - <1h → \"Xm Ys\"\n * - ≥1h → \"Xh Ym\" (seconds omitted)\n */\nexport function formatDuration(ms: number): string {\n if (ms === 0) return '0s';\n\n const totalSeconds = Math.floor(ms / 1000);\n if (totalSeconds === 0) return '<1s';\n\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n if (hours > 0) {\n return `${hours}h ${minutes}m`;\n }\n\n if (minutes > 0) {\n return `${minutes}m ${seconds}s`;\n }\n\n return `${seconds}s`;\n}\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M10.1 2.182a10 10 0 0 1 3.8 0', key: '5ilxe3' }],\n ['path', { d: 'M13.9 21.818a10 10 0 0 1-3.8 0', key: '11zvb9' }],\n ['path', { d: 'M17.609 3.721a10 10 0 0 1 2.69 2.7', key: '1iw5b2' }],\n ['path', { d: 'M2.182 13.9a10 10 0 0 1 0-3.8', key: 'c0bmvh' }],\n ['path', { d: 'M20.279 17.609a10 10 0 0 1-2.7 2.69', key: '1ruxm7' }],\n ['path', { d: 'M21.818 10.1a10 10 0 0 1 0 3.8', key: 'qkgqxc' }],\n ['path', { d: 'M3.721 6.391a10 10 0 0 1 2.7-2.69', key: '1mcia2' }],\n ['path', { d: 'M6.391 20.279a10 10 0 0 1-2.69-2.7', key: '1fvljs' }],\n];\n\n/**\n * @component @name CircleDashed\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/circle-dashed\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst CircleDashed = createLucideIcon('circle-dashed', __iconNode);\n\nexport default CircleDashed;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['line', { x1: '12', x2: '12', y1: '2', y2: '22', key: '7eqyqh' }],\n ['path', { d: 'M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6', key: '1b0p4s' }],\n];\n\n/**\n * @component @name DollarSign\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/dollar-sign\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst DollarSign = createLucideIcon('dollar-sign', __iconNode);\n\nexport default DollarSign;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M13.744 17.736a6 6 0 1 1-7.48-7.48', key: 'bq4yh3' }],\n ['path', { d: 'M15 6h1v4', key: '11y1tn' }],\n ['path', { d: 'm6.134 14.768.866-.5 2 3.464', key: '17snzx' }],\n ['circle', { cx: '16', cy: '8', r: '6', key: '14bfc9' }],\n];\n\n/**\n * @component @name Coins\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/coins\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Coins = createLucideIcon('coins', __iconNode);\n\nexport default Coins;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['rect', { width: '20', height: '8', x: '2', y: '2', rx: '2', ry: '2', key: 'ngkwjq' }],\n ['rect', { width: '20', height: '8', x: '2', y: '14', rx: '2', ry: '2', key: 'iecqi9' }],\n ['line', { x1: '6', x2: '6.01', y1: '6', y2: '6', key: '16zg32' }],\n ['line', { x1: '6', x2: '6.01', y1: '18', y2: '18', key: 'nzw8ys' }],\n];\n\n/**\n * @component @name Server\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/server\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Server = createLucideIcon('server', __iconNode);\n\nexport default Server;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['circle', { cx: '18', cy: '18', r: '3', key: '1xkwt0' }],\n ['circle', { cx: '6', cy: '6', r: '3', key: '1lh9wr' }],\n ['path', { d: 'M6 21V9a9 9 0 0 0 9 9', key: '7kw0sc' }],\n];\n\n/**\n * @component @name GitMerge\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/git-merge\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst GitMerge = createLucideIcon('git-merge', __iconNode);\n\nexport default GitMerge;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['circle', { cx: '12', cy: '12', r: '10', key: '1mglay' }],\n ['path', { d: 'M12 16v-4', key: '1dtifu' }],\n ['path', { d: 'M12 8h.01', key: 'e9boi3' }],\n];\n\n/**\n * @component @name Info\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/info\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Info = createLucideIcon('info', __iconNode);\n\nexport default Info;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['line', { x1: '2', x2: '22', y1: '2', y2: '22', key: 'a6p6uj' }],\n ['path', { d: 'M10.41 10.41a2 2 0 1 1-2.83-2.83', key: '1bzlo9' }],\n ['line', { x1: '13.5', x2: '6', y1: '13.5', y2: '21', key: '1q0aeu' }],\n ['line', { x1: '18', x2: '21', y1: '12', y2: '15', key: '5mozeu' }],\n [\n 'path',\n {\n d: 'M3.59 3.59A1.99 1.99 0 0 0 3 5v14a2 2 0 0 0 2 2h14c.55 0 1.052-.22 1.41-.59',\n key: 'mmje98',\n },\n ],\n ['path', { d: 'M21 15V5a2 2 0 0 0-2-2H9', key: '43el77' }],\n];\n\n/**\n * @component @name ImageOff\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/image-off\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ImageOff = createLucideIcon('image-off', __iconNode);\n\nexport default ImageOff;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['circle', { cx: '5', cy: '6', r: '3', key: '1qnov2' }],\n ['path', { d: 'M12 6h5a2 2 0 0 1 2 2v7', key: '1yj91y' }],\n ['path', { d: 'm15 9-3-3 3-3', key: '1lwv8l' }],\n ['circle', { cx: '19', cy: '18', r: '3', key: '1qljk2' }],\n ['path', { d: 'M12 18H7a2 2 0 0 1-2-2V9', key: '16sdep' }],\n ['path', { d: 'm9 15 3 3-3 3', key: '1m3kbl' }],\n];\n\n/**\n * @component @name GitCompareArrows\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/git-compare-arrows\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst GitCompareArrows = createLucideIcon('git-compare-arrows', __iconNode);\n\nexport default GitCompareArrows;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M13 5h8', key: 'a7qcls' }],\n ['path', { d: 'M13 12h8', key: 'h98zly' }],\n ['path', { d: 'M13 19h8', key: 'c3s6r1' }],\n ['path', { d: 'm3 17 2 2 4-4', key: '1jhpwq' }],\n ['rect', { x: '3', y: '4', width: '6', height: '6', rx: '1', key: 'cif1o7' }],\n];\n\n/**\n * @component @name ListTodo\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/list-todo\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ListTodo = createLucideIcon('list-todo', __iconNode);\n\nexport default ListTodo;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M12 17V3', key: '1cwfxf' }],\n ['path', { d: 'm6 11 6 6 6-6', key: '12ii2o' }],\n ['path', { d: 'M19 21H5', key: '150jfl' }],\n];\n\n/**\n * @component @name ArrowDownToLine\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/arrow-down-to-line\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ArrowDownToLine = createLucideIcon('arrow-down-to-line', __iconNode);\n\nexport default ArrowDownToLine;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'm18 9-6-6-6 6', key: 'kcunyi' }],\n ['path', { d: 'M12 3v14', key: '7cf3v8' }],\n ['path', { d: 'M5 21h14', key: '11awu3' }],\n];\n\n/**\n * @component @name ArrowUpFromLine\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/arrow-up-from-line\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ArrowUpFromLine = createLucideIcon('arrow-up-from-line', __iconNode);\n\nexport default ArrowUpFromLine;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M15 12h-5', key: 'r7krc0' }],\n ['path', { d: 'M15 8h-5', key: '1khuty' }],\n ['path', { d: 'M19 17V5a2 2 0 0 0-2-2H4', key: 'zz82l3' }],\n [\n 'path',\n {\n d: 'M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3',\n key: '1ph1d7',\n },\n ],\n];\n\n/**\n * @component @name ScrollText\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/scroll-text\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ScrollText = createLucideIcon('scroll-text', __iconNode);\n\nexport default ScrollText;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z',\n key: '1ffxy3',\n },\n ],\n ['path', { d: 'm21.854 2.147-10.94 10.939', key: '12cjpa' }],\n];\n\n/**\n * @component @name Send\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/send\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Send = createLucideIcon('send', __iconNode);\n\nexport default Send;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z',\n key: '1oefj6',\n },\n ],\n ['path', { d: 'M14 2v5a1 1 0 0 0 1 1h5', key: 'wfsgrz' }],\n ['path', { d: 'M10 12.5 8 15l2 2.5', key: '1tg20x' }],\n ['path', { d: 'm14 12.5 2 2.5-2 2.5', key: 'yinavb' }],\n];\n\n/**\n * @component @name FileCode\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/file-code\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst FileCode = createLucideIcon('file-code', __iconNode);\n\nexport default FileCode;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z',\n key: '1oefj6',\n },\n ],\n ['path', { d: 'M14 2v5a1 1 0 0 0 1 1h5', key: 'wfsgrz' }],\n ['circle', { cx: '11.5', cy: '14.5', r: '2.5', key: '1bq0ko' }],\n ['path', { d: 'M13.3 16.3 15 18', key: '2quom7' }],\n];\n\n/**\n * @component @name FileSearch\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/file-search\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst FileSearch = createLucideIcon('file-search', __iconNode);\n\nexport default FileSearch;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z',\n key: '1oefj6',\n },\n ],\n ['path', { d: 'M14 2v5a1 1 0 0 0 1 1h5', key: 'wfsgrz' }],\n ['path', { d: 'm9 15 2 2 4-4', key: '1grp1n' }],\n];\n\n/**\n * @component @name FileCheck\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/file-check\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst FileCheck = createLucideIcon('file-check', __iconNode);\n\nexport default FileCheck;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z',\n key: '1oefj6',\n },\n ],\n ['path', { d: 'M14 2v5a1 1 0 0 0 1 1h5', key: 'wfsgrz' }],\n ['path', { d: 'M9 15h6', key: 'cctwl0' }],\n];\n\n/**\n * @component @name FileMinus\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/file-minus\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst FileMinus = createLucideIcon('file-minus', __iconNode);\n\nexport default FileMinus;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z',\n key: '18u6gg',\n },\n ],\n ['circle', { cx: '12', cy: '13', r: '3', key: '1vg3eu' }],\n];\n\n/**\n * @component @name Camera\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/camera\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Camera = createLucideIcon('camera', __iconNode);\n\nexport default Camera;\n","import type { FeatureNodeData } from '@/components/common/feature-node';\nimport type { RepositoryNodeData } from '@/components/common/repository-node';\nimport type { ParentFeatureOption } from '@/components/common/feature-create-drawer/feature-create-drawer';\nimport type { WorkflowDefaults } from '@/app/actions/get-workflow-defaults';\n\n/** Tab key matching FeatureDrawerTabs */\nexport type FeatureTabKey =\n | 'overview'\n | 'activity'\n | 'log'\n | 'plan'\n | 'prd-review'\n | 'tech-decisions'\n | 'product-decisions'\n | 'merge-review'\n | 'chat';\n\n/** All valid tab key values — used for URL param validation. */\nexport const VALID_TAB_KEYS: ReadonlySet<string> = new Set<FeatureTabKey>([\n 'overview',\n 'activity',\n 'log',\n 'plan',\n 'prd-review',\n 'tech-decisions',\n 'product-decisions',\n 'merge-review',\n 'chat',\n]);\n\n/** Type-guard: returns the value as FeatureTabKey if valid, otherwise undefined. */\nexport function parseTabKey(value: string | null | undefined): FeatureTabKey | undefined {\n if (value && VALID_TAB_KEYS.has(value)) return value as FeatureTabKey;\n return undefined;\n}\n\n/**\n * Discriminated union representing every possible drawer state in the control center.\n * Only one view can be active at a time.\n */\nexport type DrawerView =\n /** All feature views — tabs handle the lifecycle-specific content */\n | { type: 'feature'; node: FeatureNodeData; initialTab: FeatureTabKey }\n /** Feature creation form */\n | {\n type: 'feature-create';\n repositoryPath: string;\n initialParentId?: string;\n features: ParentFeatureOption[];\n workflowDefaults?: WorkflowDefaults;\n }\n /** Repository node actions */\n | { type: 'repository'; data: RepositoryNodeData };\n\n/** Derives the initial tab from node lifecycle + state. */\nexport function deriveInitialTab(node: FeatureNodeData): FeatureTabKey {\n if (node.lifecycle === 'requirements' && node.state === 'action-required') return 'prd-review';\n if (node.lifecycle === 'implementation' && node.state === 'action-required')\n return 'tech-decisions';\n if (node.lifecycle === 'review' && (node.state === 'action-required' || node.state === 'error'))\n return 'merge-review';\n return 'overview';\n}\n\n/**\n * Derives the active DrawerView from control-center state.\n * Priority: feature-create > selected-node > repository\n */\nexport function computeDrawerView({\n selectedNode,\n isCreateDrawerOpen,\n pendingRepositoryPath,\n pendingParentFeatureId,\n selectedRepoNode,\n features,\n workflowDefaults,\n}: {\n selectedNode: FeatureNodeData | null;\n isCreateDrawerOpen: boolean;\n pendingRepositoryPath: string;\n pendingParentFeatureId: string | undefined;\n selectedRepoNode: RepositoryNodeData | null;\n features: ParentFeatureOption[];\n workflowDefaults: WorkflowDefaults | undefined;\n}): DrawerView | null {\n if (isCreateDrawerOpen) {\n return {\n type: 'feature-create',\n repositoryPath: pendingRepositoryPath,\n initialParentId: pendingParentFeatureId,\n features,\n workflowDefaults,\n };\n }\n\n if (selectedNode) {\n return { type: 'feature', node: selectedNode, initialTab: deriveInitialTab(selectedNode) };\n }\n\n if (selectedRepoNode) {\n return { type: 'repository', data: selectedRepoNode };\n }\n\n return null;\n}\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z',\n key: '1oefj6',\n },\n ],\n ['path', { d: 'M9 10h6', key: '9gxzsh' }],\n ['path', { d: 'M12 13V7', key: 'h0r20n' }],\n ['path', { d: 'M9 17h6', key: 'r8uit2' }],\n];\n\n/**\n * @component @name FileDiff\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/file-diff\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst FileDiff = createLucideIcon('file-diff', __iconNode);\n\nexport default FileDiff;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z',\n key: '169xi5',\n },\n ],\n ['path', { d: 'M15 5.764v15', key: '1pn4in' }],\n ['path', { d: 'M9 3.236v15', key: '1uimfh' }],\n];\n\n/**\n * @component @name Map\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/map\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Map = createLucideIcon('map', __iconNode);\n\nexport default Map;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M15.033 9.44a.647.647 0 0 1 0 1.12l-4.065 2.352a.645.645 0 0 1-.968-.56V7.648a.645.645 0 0 1 .967-.56z',\n key: 'vbtd3f',\n },\n ],\n ['path', { d: 'M12 17v4', key: '1riwvh' }],\n ['path', { d: 'M8 21h8', key: '1ev6f3' }],\n ['rect', { x: '2', y: '3', width: '20', height: '14', rx: '2', key: 'x3v2xh' }],\n];\n\n/**\n * @component @name MonitorPlay\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/monitor-play\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst MonitorPlay = createLucideIcon('monitor-play', __iconNode);\n\nexport default MonitorPlay;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z',\n key: 'zw3jo',\n },\n ],\n [\n 'path',\n {\n d: 'M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12',\n key: '1wduqc',\n },\n ],\n [\n 'path',\n {\n d: 'M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17',\n key: 'kqbvx6',\n },\n ],\n];\n\n/**\n * @component @name Layers\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/layers\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Layers = createLucideIcon('layers', __iconNode);\n\nexport default Layers;\n","/**\n * Parses structured log lines from the feature agent worker process.\n *\n * Log format: [timestamp] [phase] [agent|model] [tag] message\n * Worker format: [timestamp] [agent|model] [WORKER] message\n * Fallback: raw string lines\n */\n\nexport type LogEventTag =\n | 'tool'\n | 'tool-result'\n | 'text'\n | 'delta'\n | 'result'\n | 'tokens'\n | 'cmd'\n | 'file'\n | 'turn'\n | 'thread'\n | 'error'\n | 'event'\n | 'raw'\n | 'worker'\n | 'info';\n\nexport interface ParsedLogLine {\n /** ISO timestamp */\n timestamp: string | null;\n /** Phase name (e.g. \"requirements\", \"implement\") */\n phase: string | null;\n /** Agent type (e.g. \"claude-code\") */\n agent: string | null;\n /** Model name (e.g. \"claude-haiku-4-5\") */\n model: string | null;\n /** Event tag */\n tag: LogEventTag;\n /** The message content after tags */\n message: string;\n /** Original raw line */\n raw: string;\n}\n\n/**\n * Regex to match structured log lines.\n * Captures: timestamp, optional phase, optional agent|model, rest of message\n *\n * Examples:\n * [2026-03-08T10:00:01.123Z] [requirements] [claude-code|claude-haiku-4-5] [tool] Read {\"path\":\"f.ts\"}\n * [2026-03-08T10:00:01.123Z] [claude-code|claude-haiku-4-5] [WORKER] Starting worker\n * [2026-03-08T10:00:01.123Z] [requirements] [claude-code|claude-haiku-4-5] Starting...\n */\nconst LOG_LINE_REGEX =\n /^\\[(\\d{4}-\\d{2}-\\d{2}T[\\d:.]+Z?)\\]\\s+(?:\\[([^\\]]+)\\]\\s+)?(?:\\[([^\\]|]+)(?:\\|([^\\]]+))?\\]\\s+)?(.*)$/;\n\nconst TAG_REGEX =\n /^\\[(tool-result|tool|text|delta|result|tokens|cmd|file|turn|thread|error|event|raw|WORKER)\\]\\s*(.*)/;\n\nexport function parseLogLine(raw: string): ParsedLogLine {\n const match = raw.match(LOG_LINE_REGEX);\n\n if (!match) {\n return {\n timestamp: null,\n phase: null,\n agent: null,\n model: null,\n tag: 'raw',\n message: raw,\n raw,\n };\n }\n\n const [, timestamp, group1, group2, group3, rest] = match;\n\n // Determine phase, agent, model from the captured groups.\n // The log format can be:\n // [ts] [phase] [agent|model] message → group1=phase, group2=agent, group3=model\n // [ts] [agent|model] [WORKER] message → group1=\"agent|model\", group2=WORKER\n // [ts] [phase] [agent] message → group1=phase, group2=agent\n // [ts] [phase] message → group1=phase only\n let phase: string | null = null;\n let agent: string | null = null;\n let model: string | null = null;\n let message = rest ?? '';\n\n if (group2 != null && group1 != null) {\n // Two bracket groups captured\n if (group1.includes('|')) {\n // group1 is [agent|model], group2 is next tag (e.g. WORKER)\n const [agentPart, modelPart] = group1.split('|');\n agent = agentPart;\n model = modelPart ?? null;\n // group2 becomes part of the message to be parsed as a tag\n message = `[${group2}] ${rest ?? ''}`;\n } else {\n // group1 is [phase], group2|group3 is [agent|model]\n phase = group1;\n agent = group2;\n model = group3 ?? null;\n }\n } else if (group1 != null) {\n // Only one bracket group\n if (group1.includes('|')) {\n const [agentPart, modelPart] = group1.split('|');\n agent = agentPart;\n model = modelPart ?? null;\n } else {\n phase = group1;\n }\n }\n\n // Parse tag from message\n const tagMatch = message.match(TAG_REGEX);\n let tag: LogEventTag = 'info';\n\n if (tagMatch) {\n tag = tagMatch[1].toLowerCase() as LogEventTag;\n message = tagMatch[2];\n }\n\n return {\n timestamp: timestamp ?? null,\n phase,\n agent,\n model,\n tag,\n message: message.trim(),\n raw,\n };\n}\n\n/** Tool call info extracted from [tool] messages */\nexport interface ToolCallInfo {\n toolName: string;\n args: string;\n}\n\n/** Parse a [tool] message into tool name and args */\nexport function parseToolCall(message: string): ToolCallInfo {\n const spaceIdx = message.indexOf(' ');\n if (spaceIdx === -1) {\n return { toolName: message, args: '' };\n }\n return {\n toolName: message.slice(0, spaceIdx),\n args: message.slice(spaceIdx + 1),\n };\n}\n\n/** Result info extracted from [result] messages */\nexport interface ResultInfo {\n chars: number;\n sessionId: string | null;\n}\n\n/** Parse a [result] message */\nexport function parseResultMessage(message: string): ResultInfo {\n const charsMatch = message.match(/^(\\d+)\\s+chars/);\n const sessionMatch = message.match(/session=(\\S+)/);\n return {\n chars: charsMatch ? parseInt(charsMatch[1], 10) : 0,\n sessionId: sessionMatch ? sessionMatch[1] : null,\n };\n}\n\n/** Token info extracted from [tokens] messages */\nexport interface TokenInfo {\n inputTokens: number;\n outputTokens: number;\n}\n\n/** Parse a [tokens] message */\nexport function parseTokensMessage(message: string): TokenInfo {\n const match = message.match(/^(\\d+)\\s+in\\s*\\/\\s*(\\d+)\\s+out/);\n if (!match) return { inputTokens: 0, outputTokens: 0 };\n return {\n inputTokens: parseInt(match[1], 10),\n outputTokens: parseInt(match[2], 10),\n };\n}\n\n/** Parse all lines from raw content string */\nexport function parseLogContent(content: string): ParsedLogLine[] {\n if (!content) return [];\n return content\n .split('\\n')\n .filter((line) => line.trim().length > 0)\n .map(parseLogLine);\n}\n"],"names":["$$RSC_SERVER_ACTION_0"],"mappings":"wDGEA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OAAA,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,MAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,OHPmN,EAAA,EAAA,CAAA,CAAA,MAAsG,IAAMA,EAAmC,CAAA,EAAA,EAAA,iBAAb,IAAa,AAAqB,EAAC,KAAxB,wCAAqE,EAAA,UAAU,CAAC,KAAK,EAAE,EAAA,gBAAgB,CAAC,kBGsBxc,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,MDxBuT,IAAM,EAAmC,CAAA,EAAA,EAAA,kBAAb,GAAa,AAAqB,EAAC,MAAxB,uCAAqE,EAAA,UAAU,CAAC,KAAK,EAAE,EAAA,gBAAgB,CAAC,iBEA9H,EAAmC,CAAA,EAAA,EAAA,kBAAb,GAAa,AAAqB,EAAC,MAAxB,uCAAqE,EAAA,UAAU,CAAC,KAAK,EAAE,EAAA,gBAAgB,CAAC,sBCAvI,EAAmC,CAAA,EAAA,EAAA,kBAAb,GAAa,AAAqB,EAAC,MAAxB,uCAAqE,EAAA,UAAU,CAAC,KAAK,EAAE,EAAA,gBAAgB,CAAC,uBCA1I,EAAmC,CAAA,EAAA,EAAA,kBAAb,GAAa,AAAqB,EAAC,MAAxB,uCAAqE,EAAA,UAAU,CAAC,KAAK,EAAE,EAAA,gBAAgB,CAAC,sBH8Bld,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OAAA,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OAAA,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OAAA,IAAA,EAAA,EAAA,CAAA,CAAA,OInCA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,MAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,OAeA,IAAM,EACJ,qJAEF,SAAS,EAAO,SACd,CAAO,OACP,CAAK,CACL,KAAM,CAAI,CAKX,SACC,AAAI,EAAgB,CAAA,EAAA,EAAA,EAAP,CAAO,EAAC,EAAA,YAAY,CAAA,CAAC,UAAU,0BACxC,EAAc,CAAA,EAAA,EAAP,AAAO,GAAA,EAAC,EAAA,WAAW,CAAA,CAAC,UAAU,8BAClC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAK,UAAU,UACzB,CAEO,SAAS,EAAe,SAC7B,CAAO,gBACP,CAAc,cACd,CAAY,WACZ,CAAS,CACW,EACpB,GAAM,CAAC,EAAQ,EAAU,CAAG,CAAA,EAAA,EAAA,QAAQ,AAAR,GAAS,GAQrC,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,eAAe,CAAA,CAAC,cAAe,aAC9B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8BACb,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,UAAW,EACX,QAAS,EAAQ,SAAS,CAC1B,SAAU,EAAQ,UAAU,CAC5B,aAAW,uBAEX,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAO,QAAS,EAAQ,UAAU,CAAE,MAAO,EAAQ,QAAQ,CAAE,KAAM,EAAA,KAAK,OAG7E,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,KAAK,SAAS,UAAU,mBAAU,mBAKpD,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,UAAW,EACX,QAAS,EAAQ,WAAW,CAC5B,SAAU,EAAQ,YAAY,CAC9B,aAAW,yBAEX,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAO,QAAS,EAAQ,YAAY,CAAE,MAAO,EAAQ,UAAU,CAAE,KAAM,EAAA,QAAQ,OAGpF,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,KAAK,SAAS,UAAU,mBAAU,qBAKpD,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,UAAW,EACX,QAAS,EAAQ,UAAU,CAC3B,SAAU,EAAQ,aAAa,CAC/B,aAAW,uBAEX,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,QAAS,EAAQ,aAAa,CAC9B,MAAO,EAAQ,WAAW,CAC1B,KAAM,EAAA,UAAU,OAItB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,KAAK,SAAS,UAAU,mBAAU,mBAKnD,EACC,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,UAAW,EACX,QAAS,EAAQ,eAAe,CAChC,SAAU,EAAQ,YAAY,CAC9B,aAAW,sBAEX,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAO,QAAS,EAAQ,YAAY,CAAE,MAAO,EAAQ,UAAU,CAAE,KAAM,EAAA,QAAQ,OAGpF,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,KAAK,SAAS,UAAU,mBAAU,kBAIlD,KAEJ,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CAAO,KAAK,SAAS,UAAW,EAAO,QArF3B,CAqFoC,IApFpD,UAAU,SAAS,CAAC,SAAS,CAAC,GAAgB,GACnD,GAAU,GACV,WAAW,IAAM,GAAU,GA9BH,IA+B1B,CADqC,CAkFsC,aAAW,qBACzE,EAAS,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,KAAK,CAAA,CAAC,UAAU,4BAA+B,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,IAAI,CAAA,CAAC,UAAU,eAG9E,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,KAAK,SAAS,UAAU,mBACrC,EAAS,UAAY,qBAMlC,CkBtIA,IAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,kMqBKS,gISgBG,CAAA,EAAA,EAAA,OAAA,EAAA,uVAdwB,sR9BPpC,IAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,mGcAe,GAAA,oFdAf,IAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,MAAA,EAAA,EAAA,CAAA,CAAA,OgCiCA,CAAA,GAAM,EAAA,CAAA,EAAS,EAAA,OAAA,EAAiB,uPArB9B,sGAME,CAEJ,EhCDA,IAAA,GAAA,EAAA,CAAA,CAAA,OjBxB2U,IAAM,GAAmC,CAAA,EAAA,EAAA,iBAAb,IAAa,AAAqB,EAAC,KAAxB,wCAAqE,EAAA,UAAU,CAAC,KAAK,EAAE,EAAA,gBAAgB,CAAC,0BCA1J,GAAmC,CAAA,EAAA,EAAA,iBAAb,IAAkC,AAArB,EAAsB,KAAxB,wCAAqE,EAAA,UAAU,CAAC,KAAK,EAAE,EAAA,gBAAgB,CAAC,kBgBmCzc,EAAA,CAAA,CAAA,OAAA,IAAA,GAAA,EAAA,CAAA,CAAA,OQ9BA,IAAM,GAAuB,CAAA,EAJ7B,AAI6B,EAJ7B,CAAA,CAAA,OAI6B,GAAA,AAAG,EAAC,wBAAyB,CACxD,SAAU,CACR,KAAM,CACJ,GAAI,SACJ,GAAI,SACJ,GAAI,SACN,CACF,EACA,gBAAiB,CACfA,KAAM,IACR,CACF,GAQM,GAAY,CAChB,CAAE,EAAG,EAAG,OAAQ,gBAAiB,QAAS,CAAE,EAC5C,CAAE,EAAG,IAAK,OAAQ,gBAAiB,QAAS,GAAK,EACjD,CAAE,EAAG,IAAK,OAAQ,gBAAiB,QAAS,EAAI,EAChD,CAAE,EAAG,IAAK,OAAQ,gBAAiB,QAAS,GAAK,EACjD,CAAE,EAAG,IAAK,OAAQ,gBAAiB,QAAS,GAAK,EACjD,CAAE,EAAG,EAAG,OAAQ,gBAAiB,QAAS,GAAK,EAC/C,CAAE,EAAG,IAAK,OAAQ,gBAAiB,QAAS,GAAK,EACjD,CAAE,EAAG,IAAK,OAAQ,gBAAiB,QAAS,GAAK,EACjD,CAAE,EAAG,IAAK,OAAQ,gBAAiB,QAAS,GAAK,EACjD,CAAE,EAAG,IAAK,OAAQ,gBAAiB,QAAS,EAAI,EAChD,CAAE,EAAG,EAAG,OAAQ,gBAAiB,QAAS,EAAI,EAC/C,CAED,SAAS,GAAa,WAAE,CAAS,MAAE,EAAO,IAAI,UAAE,EAAW,CAAC,CAAE,GAAG,EAA0B,EACzF,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CACC,YAAU,gBACV,KAAK,SACL,aAAW,UACX,MAAM,6BACN,QAAQ,cACR,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EAAC,GAAqB,MAAE,CAAK,GAAI,GAC7C,GAAG,CAAK,WAET,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,UACC,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CACC,GAAG,cACH,EAAE,QACF,EAAE,QACF,MAAM,OACN,OAAO,OACP,0BAA0B,iBAE1B,CAAA,EAAA,EAAA,GAAA,EAAC,iBAAA,CAAe,GAAG,gBAAgB,aAAa,QAChD,CAAA,EAAA,EAAA,GAAA,EAAC,gBAAA,CACC,KAAK,SACL,OAAO,gDACP,OAAO,aAKb,CAAA,EAAA,EAAA,IAAA,EAAC,IAAA,CAAE,OAAO,8BACR,CAAA,EAAA,EAAA,GAAA,EAAC,mBAAA,CACC,cAAc,YACd,KAAK,SACL,KAAK,UACL,GAAG,YACH,IAAK,CAAA,EAAG,EAAS,CAAC,CAAC,CACnB,YAAY,eAGb,GAAU,GAAG,CAAC,AAAC,GACd,CAAA,EAAA,EAAA,IAAA,EAAC,IAAA,WACC,CAAA,EAAA,EAAA,GAAA,EAAC,mBAAA,CACC,cAAc,YACd,KAAK,SACL,SAAS,SACT,OAAO,oBACP,SAAS,MACT,WAAY,EAAE,MAAM,CACpB,IAAI,KACJ,YAAY,eAEd,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CAAO,GAAG,KAAK,GAAG,KAAK,EAAG,EAAE,CAAC,CAAE,KAAK,eAAe,QAAS,EAAE,OAAO,KAXhE,EAAE,CAAC,GAeb,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CAAO,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,KAAK,eAAe,QAAQ,iBACxD,CAAA,EAAA,EAAA,GAAA,EAAC,UAAA,CAAQ,cAAc,IAAI,OAAO,QAAQ,IAAI,KAAK,YAAY,eAC/D,CAAA,EAAA,EAAA,GAAA,EAAC,UAAA,CACC,cAAc,UACd,OAAO,eACP,IAAI,KACJ,YAAY,uBAMxB,CDvGA,IAAA,GAAA,EAAA,CAAA,CAAA,OAAA,GAAA,EAAA,CAAA,CAAA,OAGA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,OtBFA,GAAA,EAAA,CAAA,CAAA,yPAAA,IAAA,GAAA,EAAA,CAAA,CAAA,OAGA,GAAA,EAAA,CAAA,CAAA,OAGA,EAAA,CAAA,CAAA,KAAA,IAAA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,OAKA,IAAM,GAAqB,IAAI,IAAI,CACjC,OACA,OACA,QACA,OACA,QACA,OACA,OACA,OACA,OACA,OACA,QACA,OACA,QACA,OACA,QACA,OACA,MACA,OACA,QACA,QACA,OACA,OACA,MACA,OACA,MACA,OACA,MACA,MACA,MACA,MACA,QACA,KACA,OACA,KACA,OACA,MACA,SACA,MACA,QACA,OACA,QACA,QACA,MACA,QACA,OACA,QACA,QACA,OACA,OACA,QACA,OACA,OACA,OACA,MACA,OACD,EAOM,SAAS,GAAgB,UAC9B,CAAQ,WACR,CAAS,cACT,CAAY,gBACZ,EAAiB,SAAS,qBAC1B,CAAmB,CACnB,gBAAe,CAAK,CACpB,eAAc,CAAK,UACnB,CAAQ,CACR,UAAW,CAAmB,mBAC9B,CAAiB,CACI,EACrB,GAAM,GAAE,CAAC,CAAE,CAAG,CAAA,EAAA,EAAA,cAAc,AAAd,EAAe,OACvB,EAA+B,YAAnB,EACZ,EAAc,EAAY,GAAA,aAAa,CAAG,EAAA,KAAK,CAC/C,EAAW,EAAY,mBAAqB,iBAE5C,CAAC,EAAmB,EAAqB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,IACrD,EAAY,GAAuB,EACnC,EAAe,GAAqB,EACpC,EAAe,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,WAC9B,EAAW,GAAgB,EAE3B,CAAC,EAAa,EAAe,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAqB,EAAE,EAC/D,CAAC,EAAY,EAAc,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACvC,CAAC,EAAa,EAAe,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MACxD,CAAC,EAAe,EAAiB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GAC7C,CAAC,EAAU,EAAY,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACnC,CAAC,EAAW,EAAa,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACrC,EAAU,EAAU,IAAI,GAAG,MAAM,CAAG,EACpC,EAAkB,EAAU,GAAkB,GAAY,EAAa,CAAC,EAExE,EAAiB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,GACxB,EAAe,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,OAAO,UAAU,IACvC,EAAU,CAAA,EAAA,EAAA,MAAA,AAAM,EAAkB,MAGxC,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,SAAS,EAAU,CAAgB,EAC7B,CAAU,cAAR,GAAG,EAA4B,SAAV,EAAE,GAAG,AAAK,GAAQ,GAAY,GACrD,AAAU,YAAR,GAAG,EAAc,GAAa,EACtC,CACA,SAAS,EAAQ,CAAgB,GACjB,YAAV,EAAE,GAAG,EAA4B,SAAV,EAAE,GAAG,AAAK,GAAQ,EAAY,IAC3C,UAAV,EAAE,GAAG,EAAc,EAAa,GACtC,CACA,SAAS,IACP,GAAY,GACZ,GAAa,EACf,CAIA,OAHA,OAAO,gBAAgB,CAAC,UAAW,GACnC,OAAO,gBAAgB,CAAC,QAAS,GACjC,OAAO,gBAAgB,CAAC,OAAQ,GACzB,KACL,OAAO,mBAAmB,CAAC,UAAW,GACtC,OAAO,mBAAmB,CAAC,QAAS,GACpC,OAAO,mBAAmB,CAAC,OAAQ,EACrC,CACF,EAAG,EAAE,EAEL,IAAM,EAAc,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,MAAO,IAGrC,IAAK,IAAM,KAFX,EAAe,MAEI,GAAU,CAC3B,GAAI,EAAK,IAAI,CAjIG,EAiIA,GAjIK,IAiIU,GAjIH,MAAM,GAkIhC,EAAe,CAAC,CAAC,CAlIuB,CAkIrB,EAAK,IAAI,CAAC,qBAAqB,CAAC,EAGrD,IAAM,EAAM,AAzElB,SAAsB,AAAb,CAA6B,EACpC,IAAM,EAAM,EAAS,WAAW,CAAC,KACjC,OAAO,GAAO,EAAI,EAAS,KAAK,CAAC,GAAK,WAAW,GAAK,EACxD,EAsE+B,EAAK,IAAI,EAClC,GAAI,GAAO,CAAC,GAAmB,GAAG,CAAC,GAAM,YACvC,EAAe,CAAC,WAAW,EAAE,EAAI,gBAAgB,CAAC,CAGtD,CAEA,IAAK,IAAM,KAAQ,EAAU,CAC3B,IAAM,EAAS,OAAO,UAAU,GAEhC,EAAe,AAAC,GAAS,IACpB,EACH,CACE,GAAI,EACJ,KAAM,EAAK,IAAI,CACf,KAAM,EAAK,IAAI,CACf,SAAU,EAAK,IAAI,EAAI,2BACvB,KAAM,GACN,SAAS,CACX,EACD,EAED,GAAI,CACF,IAAM,EAAW,IAAI,SACrB,EAAS,MAAM,CAAC,OAAQ,GACxB,EAAS,MAAM,CAAC,YAAa,EAAa,OAAO,EAEjD,IAAM,EAAM,MAAM,MAAM,0BAA2B,CACjD,OAAQ,OACR,KAAM,CACR,GAEA,GAAI,CAAC,EAAI,EAAE,CAAE,CACX,IAAM,EAAO,MAAM,EAAI,IAAI,GAAG,KAAK,CAAC,IAAM,CAAC,CAAE,MAAO,gBAAgB,CAAC,EACrE,EAAe,AAAC,GAAS,EAAK,MAAM,CAAC,AAAC,GAAM,EAAE,EAAE,GAAK,IACrD,EAAe,EAAK,KAAK,EAAI,iBAC7B,MACF,CAEA,IAAM,EAAW,MAAM,EAAI,IAAI,GAC/B,EAAgB,AAAD,GAEb,AADe,EAAK,EAChB,EADoB,CAAE,AAAD,GAAO,EAAE,AACtB,EADwB,GAAK,GAAU,EAAE,IAAI,GAAK,EAAS,IAAI,EACxD,EAAK,MAAM,CAAE,AAAD,GAAO,EAAE,EAAE,GAAK,GACxC,EAAK,GAAG,CAAE,AAAD,GACd,EAAE,EAAE,GAAK,EAAS,CAAE,GAAG,CAAQ,CAAE,GAAI,EAAQ,SAAS,CAAM,EAAI,GAGtE,CAAE,KAAM,CACN,EAAe,AAAC,GAAS,EAAK,MAAM,CAAC,AAAC,GAAM,EAAE,EAAE,GAAK,IACrD,EAAe,gBACjB,CACF,CACF,EAAG,EAAE,EAEC,EAAkB,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,AAAC,IACnC,EAAE,cAAc,GAChB,EAAE,eAAe,GACjB,EAAe,OAAO,EAAI,EACK,IAA3B,EAAe,OAAO,EAAQ,GAAc,EAClD,EAAG,EAAE,EAEC,EAAkB,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,AAAC,IACnC,EAAE,cAAc,GAChB,EAAE,eAAe,GACjB,EAAe,OAAO,EAAI,EACK,IAA3B,EAAe,OAAO,EAAQ,GAAc,EAClD,EAAG,EAAE,EAEC,EAAiB,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,AAAC,IAClC,EAAE,cAAc,GAChB,EAAE,eAAe,EACnB,EAAG,EAAE,EAEC,EAAa,CAAA,EAAA,EAAA,WAAA,AAAW,EAC5B,AAAC,IACC,EAAE,cAAc,GAChB,EAAE,eAAe,GACjB,EAAe,OAAO,CAAG,EACzB,GAAc,GACd,IAAM,EAAQ,MAAM,IAAI,CAAC,EAAE,YAAY,CAAC,KAAK,EACzC,EAAM,MAAM,CAAG,GAAG,EAAY,EACpC,EACA,CAAC,EAAY,EAGT,EAAc,CAAA,EAAA,EAAA,WAAA,AAAW,EAC7B,AAAC,IACC,IAAM,EAAQ,EAAE,aAAa,EAAE,MAC/B,GAAI,CAAC,EAAO,OACZ,IAAM,EAAgB,EAAE,CACxB,IAAK,IAAM,KAAQ,MAAM,IAAI,CAAC,GAC5B,GAAkB,CADkB,QAChC,EAAK,IAAI,CAAa,CACxB,IAAM,EAAO,EAAK,SAAS,GACvB,GAAM,EAAM,IAAI,CAAC,EACvB,CAEE,EAAM,MAAM,CAAG,GAAG,CACpB,EAAE,cAAc,GAChB,EAAY,GAEhB,EACA,CAAC,EAAY,EAGT,EAAiB,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,UACjC,GAAI,CACF,IAAM,EAAQ,MAAM,CAAA,EAAA,GAAA,SAAA,AAAS,IACzB,GACF,EAAe,AAAC,EADP,EAEP,IAAM,EAAgB,IAAI,IAAI,EAAK,GAAG,CAAE,AAAD,GAAO,EAAE,IAAI,GAC9C,EAAS,EACZ,MAAM,CAAC,AAAC,GAAM,CAAC,EAAc,GAAG,CAAC,EAAE,IAAI,GACvC,GAAG,CACF,AAAC,IAAwB,AAAC,CACxB,GAAI,OAAO,UAAU,GACrB,KAAM,EAAE,IAAI,CACZ,KAAM,EAAE,IAAI,CACZ,SAAU,2BACV,KAAM,EAAE,IAAI,CACd,CAAC,EAEL,OAAO,EAAO,MAAM,CAAG,EAAI,IAAI,KAAS,EAAO,CAAG,CACpD,EAEJ,CAAE,KAAM,CAER,CACF,EAAG,EAAE,EAEC,EAAmB,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,AAAC,IACpC,EAAe,AAAC,GAAS,EAAK,MAAM,CAAC,AAAC,GAAM,EAAE,EAAE,GAAK,GACvD,EAAG,EAAE,EAEC,EAAoB,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,CAAC,EAAY,KACjD,EAAe,AAAC,GAAS,EAAK,GAAG,CAAC,AAAC,GAAO,EAAE,EAAE,GAAK,EAAK,CAAE,GAAG,CAAC,OAAE,CAAM,EAAI,GAC5E,EAAG,EAAE,EAEC,EAAY,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,KAC5B,EAAa,IACb,EAAe,EAAE,EACjB,EAAe,KACjB,EAAG,CAAC,EAAa,EAsBX,GAAgB,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,AAAC,KAC5B,EAAE,OAAO,EAAI,EAAE,OAAA,AAAO,GAAe,SAAS,CAAnB,EAAE,GAAG,GACnC,EAAE,cAAc,GAEhB,EAAQ,OAAO,EAAE,gBAErB,EAAG,EAAE,EAEC,GACiB,IAArB,OAAO,WAA6B,OAAO,IAAI,CAAC,UAAU,SAAS,EAAI,IAAM,OAE/E,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,4CACZ,EACA,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,eAAe,CAAA,CAAC,cAAe,aAC9B,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,IAAK,EAAS,SApC5B,CAoCsC,QApC7B,AAAiB,CAAiC,EACzD,EAAE,cAAc,GAChB,IAAM,EAAO,EAAU,IAAI,GAE3B,GAAI,EAEF,EAAa,IAAI,GACjB,IACA,EAJmB,MAKd,CAEL,GAAI,CAAC,GAAQ,CAAC,EAAU,OACxB,EACE,EACA,EAAY,MAAM,CAAC,AAAC,GAAM,CAAC,EAAE,OAAO,GAEtC,GACF,CACF,EAkBwD,UAAU,eACxD,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,KAAK,SACL,aAAY,EAAE,6BACd,iBAAgB,EAAa,OAAS,QACtC,YAAa,EACb,YAAa,EACb,WAAY,EACZ,OAAQ,EACR,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,2DACA,GAAc,2CAGhB,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,4LACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,QAAQ,CAAA,CACP,YAAa,GAAuB,sBACpC,aAAY,GAAuB,sBACnC,SAAU,EACV,MAAO,EACP,SAAU,AAAC,GAAM,EAAa,EAAE,MAAM,CAAC,KAAK,EAC5C,UAAW,GACX,QAAS,EACT,KAAM,EACN,eAAc,CAAC,CAAC,EAChB,mBAAkB,EAAc,kCAA+B,EAC/D,UAAU,uHACV,cAAY,sBAEb,EAAY,MAAM,CAAG,GACpB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,yDACZ,EAAY,GAAG,CAAC,AAAC,GAChB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,cAAc,CAAA,CAEb,KAAM,EAAK,IAAI,CACf,KAAM,EAAK,IAAI,CACf,SAAU,EAAK,QAAQ,CACvB,KAAM,EAAK,IAAI,CACf,SAAU,IAAM,EAAiB,EAAK,EAAE,EACxC,SAAU,EACV,QAAS,EAAK,OAAO,CACrB,MAAO,EAAK,KAAK,CACjB,cAAe,AAAC,GAAU,EAAkB,EAAK,EAAE,CAAE,IAThD,EAAK,EAAE,KAcnB,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CACC,GAAG,6BACH,UAAU,qCACV,KAAK,iBAEJ,IAED,KACJ,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,sEACb,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,8DACd,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,+DACZ,GAAO,YACH,IACN,EAAU,SAAW,aAExB,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,EACT,SAAU,EACV,aAAY,EAAE,oBACd,UAAU,oGAEV,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,aAAa,CAAA,CAAC,UAAU,gBAG7B,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,KAAK,eAAO,EAAE,yBAIhC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,aAAc,IAAM,GAAiB,YACxC,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CACC,KAAK,SACL,SAAU,EACV,cAAY,uBACZ,UAAW,CAAA,EAAA,EAAA,EAAE,AAAF,EACT,mKACA,+EACA,EACI,CAAA,EAAG,AAjUZ,EAAY,uBAAyB,qBAiUZ,WAAW,CAAC,CAC5B,AAnTJ,GAAU,GAAY,CAAC,EAoTjB,UApT6B,iDAqT7B,gEAIR,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,qFACA,GAEF,MAAO,CACL,UAAW,EAAkB,gBAAkB,kBACjD,IAGF,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,oGACA,EAAkB,YAAc,yBAGlC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAK,UAAU,qBAAqB,YAIvC,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,0GACA,EAAkB,cAAgB,uBAGpC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAY,UAAU,qBACtB,KAGH,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,CAAC,6HAA6H,EAAE,EAAS,gCAAgC,CAAC,CAC1K,CAAC,GAAW,CAAC,GAAiB,iCAEhC,aAAc,IAAM,GAAiB,YAErC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,UAAU,8BAI3B,AAAD,EAMG,KALF,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,KAAK,eAClB,EACG,EACA,EAAE,2DAWxB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,6CACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,MAAM,CAAA,CACL,KAAK,SACL,UAAU,SACV,SAAU,EACV,QAAS,KACP,EAAa,IAAI,GACjB,GACF,WAEC,QAMb,CsBpeO,SAAS,GAAiB,MAC/B,CAAI,YACJ,CAAU,UACV,CAAQ,WACR,CAAS,UACT,CAAQ,cACR,GAAe,CAAK,aACpB,EAAc,EAAK,YACnB,GAAa,CAAK,WAClB,CAAS,mBACT,CAAiB,CACK,EACtB,GAAM,UAAE,CAAQ,SAAE,CAAO,WAAE,CAAS,aAAE,CAAW,CAAE,CAAG,EAChD,CAAC,EAAa,EAAe,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,GACzC,EAAc,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,UAC7B,EAAgB,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,YAE/B,EAAQ,EAAU,MAAM,CAExB,EAAa,IAAgB,EAAQ,EACrC,EAAkB,CAAS,CAAC,EAAY,CAExC,EAAgB,CAAA,EAAA,EAAA,OAAA,AAAO,EAAC,IAAM,OAAO,IAAI,CAAC,GAAY,MAAM,CAAE,CAAC,EAAW,EAE1E,EAAe,CAAA,EAAA,EAAA,WAAA,AAAW,EAC9B,CAAC,EAAoB,KACnB,EAAY,IAAI,GAChB,EAAS,EAAY,GAEjB,AAAC,GACH,SADe,EACJ,IAAM,EAAe,AAAC,GAAM,EAAI,GAAI,IAEnD,EACA,CAAC,EAAU,EAAY,EAAY,SAGrC,AAAc,GAAG,CAAb,EAAoB,KAGtB,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,yCACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,iDAEZ,EACC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,+DACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,sDACf,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mBACb,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,oDAA4C,IAC1D,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yDAAiD,UAGhE,KAGJ,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,sBACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mCACb,CAAA,EAAA,EAAA,IAAA,EAAC,QAAA,CAAM,UAAU,iEACd,EAAc,EAAE,KAAG,EAAgB,QAAQ,IAE9C,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,sCACZ,EAAU,GAAG,CAAC,CAAC,EAAG,IACjB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CAEC,KAAK,SACL,aAAY,CAAC,eAAe,EAAE,EAAM,EAAA,CAAG,CACvC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,iDACA,IAAQ,EAAc,iBAAmB,QACzC,IAAQ,GAAe,CAAU,CAAC,EAAE,EAAE,CAAC,CAAG,gBAAkB,GAC5D,IAAQ,GAAgB,CAAU,CAAC,EAAE,EAAE,CAAC,CAA8B,GAA3B,CAApB,yBAEzB,QAAS,KACP,EAAc,IAAI,GAClB,EAAe,EACjB,GAZK,EAAE,EAAE,QAiBjB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,qBACZ,EAAgB,OAAO,CAAC,GAAG,CAAC,CAAC,EAAK,KACjC,IAAM,EAAW,CAAU,CAAC,EAAgB,EAAE,CAAC,GAAK,EAAI,EAAE,CACpD,EAAS,OAAO,YAAY,CAAC,GAAK,GACxC,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CAEC,KAAK,SACL,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,qGACA,mDACA,GAAY,8BACZ,EAAI,KAAK,EAAI,4BAEf,SAAU,EACV,QAAS,IAAM,EAAa,EAAgB,EAAE,CAAE,EAAI,EAAE,WAEtD,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mCACb,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,2DACb,EAAO,OAEV,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,2BACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,wEACZ,EAAI,KAAK,GAEZ,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,sDACZ,EAAI,SAAS,MAGjB,EAAI,WAAW,EAAI,EAAI,KAAK,CAC3B,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,2BACZ,EAAI,WAAW,CACd,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,UAAU,qDAA4C,mBAI7D,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,UAAU,0HAAiH,UAKpI,SAnCD,EAAI,EAAE,CAuCjB,QAKJ,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mDACb,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,MAAM,CAAA,CACL,KAAK,SACL,QAAQ,QACR,KAAK,KACL,SAAU,AAnHgB,IAAhB,GAmHe,EACzB,QAAS,KACP,EAAc,IAAI,GAClB,EAAe,AAAC,GAAM,EAAI,EAC5B,YAEA,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,UAAU,iBAAiB,cAIxC,AAAD,EAcG,KAbF,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,MAAM,CAAA,CACL,KAAK,SACL,QAAQ,QACR,KAAK,KACL,SAAU,EACV,QAAS,KACP,EAAc,IAAI,GAClB,EAAe,AAAC,GAAM,EAAI,EAC5B,YAEC,CAAU,CAAC,EAAgB,EAAE,CAAC,CAAG,OAAS,OAC3C,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CAAC,UAAU,0BAMhC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,SAAU,EACV,UAAW,IAAM,EAAU,EAAY,EAAE,EACzC,aAAc,EAAY,KAAK,CAC/B,oBAAoB,mCACpB,aAAc,EACd,YAAa,EACb,UAAW,EACX,kBAAmB,WAEnB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,iCACC,EAAgB,GAAK,EAAgB,GAAU,EAC5C,cACA,YACJ,mCAEF,cAAY,kCAEX,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,2DAEf,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,UAAU,gDACV,MAAO,CAAE,MAAO,CAAA,EAAG,EAAQ,EAAK,EAAgB,EAAS,IAAM,EAAE,CAAC,CAAC,AAAC,EACpE,cAAY,uBAO1B,CrBzMA,IAAA,GAAA,EAAA,CAAA,CAAA,yM+BGe,GAAA,+FAEJ,CJYL,AIZK,APAA,AEYL,mC1BNA,GAAiC,CACrC,EAAG,CAAC,UAAE,CAAQ,CAAE,GACd,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,wEAAgE,IAE/E,OAAQ,CAAC,UAAE,CAAQ,CAAE,GAAK,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CAAO,UAAU,yCAAiC,IAC7E,GAAI,CAAC,CAAE,UAAQ,CAAE,GAAK,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,kBAAU,IAC9C,KAAM,CAAC,UAAE,CAAQ,WAAE,CAAS,CAAE,GAC5B,EACE,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAW,CAAA,EAAG,EAAU,YAAY,CAAC,UAAG,IAE9C,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,mFACb,IAGP,IAAK,CAAC,UAAE,CAAQ,CAAE,GAChB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,+DAAuD,IAExE,GAAI,CAAC,UAAE,CAAQ,CAAE,GACf,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,uEAA+D,IAE/E,GAAI,CAAC,UAAE,CAAQ,CAAE,GACf,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,0EAAkE,IAElF,GAAI,CAAC,UAAE,CAAQ,CAAE,GAAK,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,2BAAmB,IACvD,EAAG,CAAC,UAAE,CAAQ,CAAE,MAAI,CAAE,GACpB,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CACC,KAAM,EACN,UAAU,4CACV,OAAO,SACP,IAAI,+BAEH,GAGP,EAEA,SAAS,GAAa,UAAE,CAAQ,CAAE,OAAK,CAA6C,EAClF,GAAM,CAAC,EAAkB,EAAoB,CAAG,CAAA,EAAA,EAAA,QAAQ,AAAR,GAAS,GACnD,EAAc,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,UAC7B,EAAgB,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,YAYrC,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,4CAEb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,gCACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mDACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,qCACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,+HACb,EAAQ,IAEX,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oBACb,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,+DACX,EAAS,KAAK,GAEjB,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,gDAAwC,EAAS,MAAM,SAGvE,iBAAkB,GAClB,EAAkD,YAAY,CAC7D,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,QAAQ,YAAY,UAAU,+CACjC,EAAiD,YAAY,GAE/D,QAIL,EAAS,SAAS,CACjB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,OAAQ,CAAA,CAAC,WAAY,YAAqB,EAAS,SAAS,GAC3D,QAIL,EAAS,QAAQ,CAAC,MAAM,CAAG,EAC1B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mCACb,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CACC,KAAK,SACL,QA7CuB,CA6Cd,IA3Cb,EACF,EAAc,IAAI,GAElB,EAAY,IAAI,CAHI,EAKtB,EAAoB,AAAC,GAAS,CAAC,EACjC,EAsCU,UAAU,qIAEV,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CACX,UAAW,CAAC,iCAAiC,EAAE,EAAmB,YAAc,GAAA,CAAI,GAEtF,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAO,UAAU,gBAAgB,6BACP,EAAS,QAAQ,CAAC,MAAM,CAAC,OAErD,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,iCACZ,EAAS,QAAQ,CAAC,GAAG,CAAC,AAAC,GACtB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAc,UAAU,6CACvB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,mCAA2B,KADnC,MAKZ,QAEJ,OAGV,CAMO,SAAS,GAAqB,MAAE,CAAI,CAAqC,EAC9E,GAAM,SAAE,CAAO,WAAE,CAAS,CAAE,CAAG,SAE/B,AAAyB,GAAG,CAAxB,EAAU,MAAM,CAAe,KAGjC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,0BAEb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mCACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,yDACf,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mBACb,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,6CAAoC,yCAGjD,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,8DAAsD,IACjE,WAKR,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,yCACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAiB,UAAU,yBAC5B,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,6CAAoC,2BAInD,EAAU,GAAG,CAAC,CAAC,EAAU,IACxB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAkC,SAAU,EAAU,MAAO,GAA3C,EAAS,KAAK,KAIzC,CC/JA,IAAA,GAAA,EAAA,CAAA,CAAA,OAOA,SAAS,GAAoB,MAAE,CAAI,CAAE,OAAK,CAAgD,EACxFA,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,2CACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,+BACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,qCACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,+HACb,EAAQ,IAEX,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,2BACb,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,+DAAuD,EAAK,QAAQ,GAClF,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,yCACb,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,0DACV,EAAK,cAAc,GAErB,EAAK,cAAc,CAClB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,UAAU,8DAAqD,mBAGpE,iBAOlB,CAEO,SAAS,GAAwB,MAAE,CAAI,CAAgC,EAC5E,GAAM,WAAE,CAAS,CAAE,CAAG,SAEtB,AAAyB,GAAG,CAAxB,EAAU,MAAM,CAAe,KAGjC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,0BAEb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oCACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,aAAa,CAAA,CAAC,UAAU,yBACzB,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,6CAAoC,yBAInD,EAAU,GAAG,CAAC,CAAC,EAAM,IACpB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAwC,KAAM,EAAM,MAAO,GAAlC,EAAK,QAAQ,KAI/C,CGpDA,IAAA,GAAA,EAAA,CAAA,CAAA,0OuCS4B,IAAA,iDvCT5B,IAAA,GAAA,EAAA,CAAA,CAAA,OAAA,GAAA,EAAA,CAAA,CAAA,ybyCwBqD,CAAA,AFAN,AbZE,AQYE,AHAA,AEAJ,CFAI,AEAJ,ACAI,AOAE,AFAN,AbZE,CaYF,AbZE,AQYE,AOAE,ARAN,AFAI,CUAE,AFAI,ANAA,AFAN,AGAA,+POdmB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAU,GzCVhF,IAAA,GAAA,EAAA,CAAA,CAAA,OAAA,GAAA,EAAA,CAAA,CAAA,OFHA,GAAA,EAAA,CAAA,CAAA,OAAA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,OAGO,SAAS,GAAc,QAAE,CAAM,CAAwB,EAC5D,OAAQ,GACN,KAAK,GAAA,QAAQ,CAAC,OAAO,CACnB,MACEA,CAAAA,EAAAA,EAAAA,IAAAA,EAAC,GAAA,KAAK,CAAA,CAAC,UAAU,4EACf,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,UAAU,qBAAqB,YAIlD,MAAK,GAAA,QAAQ,CAAC,OAAO,CACnB,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,KAAK,CAAA,CAAC,UAAU,+EACf,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,YAAY,CAAA,CAAC,UAAU,kCAAkC,YAIhE,MAAK,GAAA,QAAQ,CAAC,OAAO,CACnB,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,KAAK,CAAA,CAAC,UAAU,sEACf,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,OAAO,CAAA,CAAC,UAAU,qBAAqB,YAIhD,CACF,CCzBA,IAAA,GAAA,EAAA,CAAA,CAAA,0CqCuBiD,CMZxC,ANYwC,ADAA,CCAA,AMZxC,APYwC,CCAA,ADAA,AOZxC,CAAA,ANYwC,ADAA,COZxC,ANYwC,ADAA,CAAA,ACAA,AMZxC,CAAA,APYwC,ACAA,8NrCvBjD,IAAA,GAAA,EAAA,CAAA,CAAA,OAIA,IAAM,GAAgB,CACpB,MAAO,CAAE,KAAM,GAAA,QAAQ,CAAE,MAAO,IAAK,UAAW,gBAAiB,EACjE,SAAU,CAAE,KAAM,GAAA,QAAQ,CAAE,MAAO,IAAK,UAAW,gBAAiB,EACpE,QAAS,CAAE,KAAM,GAAW,MAAO,IAAK,UAAW,cAAe,EAClE,QAAS,CAAE,KAAM,GAAA,QAAQ,CAAE,MAAO,IAAK,UAAW,eAAgB,CACpE,EAEA,SAAS,GAAe,QAAE,CAAM,CAA6C,EAC3E,IAAM,EAAS,EAAa,CAAC,EAAO,CAC9B,EAAO,EAAO,IAAI,CACxB,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAK,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EAAC,uBAAwB,EAAO,SAAS,GACrE,CAEA,SAAS,GAAS,MAAE,CAAI,CAAiC,EACvD,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oDACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,6EACZ,EAAK,MAAM,GAEd,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,gDACZ,EAAK,KAAK,CAAC,GAAG,CAAC,AAAC,GACf,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAEC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,OACc,UAAd,EAAK,IAAI,EAAgB,mCACzB,AAAc,cAAT,IAAI,EAAkB,0CAG7B,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,qFACb,EAAK,SAAS,EAAI,KAErB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,qFACb,EAAK,SAAS,EAAI,KAErB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,uCACc,UAAd,EAAK,IAAI,EAAgB,qCACX,YAAd,EAAK,IAAI,EAAkB,2CAGd,UAAd,EAAK,IAAI,CAAe,IAAoB,YAAd,EAAK,IAAI,CAAiB,IAAM,MAEjE,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,6DACb,EAAK,OAAO,KAvBV,CAAA,EAAG,EAAK,IAAI,CAAC,CAAC,EAAE,EAAK,SAAS,EAAI,GAAG,CAAC,EAAE,EAAK,SAAS,EAAI,GAAA,CAAI,OA8B/E,CAEA,SAAS,GAAa,MAAE,CAAI,CAAiC,EAC3D,GAAM,CAAC,EAAQ,EAAU,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GAE/B,EAAW,EAAK,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAM,EAAK,IAAI,CAClD,EAAU,EAAK,IAAI,CAAC,QAAQ,CAAC,KAAO,EAAK,IAAI,CAAC,KAAK,CAAC,EAAG,EAAK,IAAI,CAAC,WAAW,CAAC,MAAQ,GAE3F,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mDACb,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM,EAAU,CAAC,GAC1B,UAAU,kFAEV,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CACX,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,2EACA,GAAU,eAGd,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAe,OAAQ,EAAK,MAAM,GACnC,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,2DACb,EACC,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,kCAAyB,EAAQ,OAChD,KAGH,IAGH,EAAK,OAAO,CACX,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,uDAA6C,KACnD,EAAK,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,MAEnC,KACJ,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,iCACb,EAAK,SAAS,CAAG,EAAI,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,2BAAiB,IAAE,EAAK,SAAS,IAAW,KACjF,EAAK,SAAS,CAAG,GAAK,EAAK,SAAS,CAAG,EAAI,IAAM,KACjD,EAAK,SAAS,CAAG,EAAI,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,yBAAe,IAAE,EAAK,SAAS,IAAW,WAGnF,GAAU,EAAK,KAAK,CAAC,MAAM,CAAG,EAC7B,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,kDACZ,EAAK,KAAK,CAAC,GAAG,CAAC,AAAC,GACf,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAA2B,KAAM,GAAnB,EAAK,MAAM,KAG5B,OAGV,CAMO,SAAS,GAAS,WAAE,CAAS,CAAiB,SACnD,AAAyB,GAAG,CAAxB,EAAU,MAAM,CAAe,KAGjC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,4CACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,qBACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,yCACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,QAAQ,CAAA,CAAC,UAAU,kCACpB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,iDAAwC,kBACxD,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,8CAAoC,IAAE,EAAU,MAAM,CAAC,YAG3E,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,kCACZ,EAAU,GAAG,CAAC,AAAC,GACd,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAiD,KAAM,GAArC,CAAA,EAAG,EAAK,MAAM,CAAC,CAAC,EAAE,EAAK,IAAI,CAAA,CAAE,OAK1D,CChHA,IAAM,GAAqE,CACzE,WAAY,GACZ,MAAO,GACP,WAAY,EAAA,QAAQ,CACpB,kBAAmB,EAAA,QAAQ,AAC7B,EAEM,GAAmB,IAAI,IAAI,CAAC,OAAQ,OAAQ,QAAS,OAAQ,QAAS,OAAQ,OAAO,EACrF,GAAmB,IAAI,IAAI,CAAC,OAAQ,QAAS,OAAO,EAY1D,SAAS,GAAa,UAAE,CAAQ,CAAqC,UACnE,MAAM,CAAC,EAAU,EAAY,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACnC,EAAO,EAAc,CAAC,EAAS,IAAI,CAAC,EAAI,GACxC,EAXC,CADD,EAAM,CADQ,AAaR,EAAa,EAbO,AAaE,YAAY,EAZ7B,WAAW,CAAC,OACf,EAAI,EAAK,KAAK,CAAC,GAAK,WAAW,GAAK,GAY5C,GARkB,EAQK,CAAjB,CAA0B,QARM,IAQM,CAP3C,CAAC,mBAAmB,EAAE,mBAAmB,GAAA,CAAe,EAQzD,EAA4B,eAAlB,EAAS,IAAI,EAAqB,GAAiB,GAAG,CAAC,GACjE,EAA4B,UAAlB,EAAS,IAAI,EAAgB,GAAiB,GAAG,CAAC,GAC5D,EAA2B,eAAlB,EAAS,IAAI,EAAqB,AAAkB,wBAAT,IAAI,CAE9D,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,KAAA,CAAG,UAAU,4CACZ,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM,EAAY,CAAC,GAC5B,UAAU,mFAET,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,UAAU,2CAEvB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CAAC,UAAU,2CAE1B,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAK,UAAU,+CAChB,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,2BACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,+CAAuC,EAAS,WAAW,GAC1E,EAAS,OAAO,CACf,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,qDAA2C,IAAE,EAAS,OAAO,CAAC,OAC5E,QAGJ,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CACC,KAAM,EACN,QAAQ,CAAA,CAAA,EACR,QAAU,AAAD,GAAO,EAAE,eAAe,GACjC,UAAU,qFACV,aAAW,oBAEX,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,QAAQ,CAAA,CAAC,UAAU,gBAEpB,CAEL,GAAY,EACX,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,8CACZ,EAEC,CAAA,EAAA,EAAA,GAAA,AADA,AACA,EAAC,MAAA,CACC,IAAK,EACL,IAAK,EAAS,WAAW,CACzB,UAAU,WAJ0C,wCAKpD,QAAQ,SAER,EACF,CAAA,EAAA,EAAA,GAAA,EAAC,QAAA,CACC,IAAK,EACL,QAAQ,CAAA,CAAA,EACR,UAAU,oCACV,QAAQ,oBAER,CAAA,EAAA,EAAA,GAAA,EAAC,QAAA,CAAM,KAAK,eAEZ,EACF,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAoB,IAAK,IAE1B,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,gEACV,EAAS,YAAY,KAI1B,KAOA,OAGV,CAEA,SAAS,GAAoB,KAAE,CAAG,CAAmB,EACnD,GAAM,CAAC,EAAS,EAAW,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MAChD,CAAC,EAAQ,EAAU,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,WAErC,AAAK,EAcA,EAdD,AAmBF,CAAA,EAAA,CAnBW,CAmBX,EALY,CAKZ,EAAC,MAAA,CAAI,UAAU,mGACZ,IALI,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,6CAAoC,4BAdxD,MAAM,GACH,IAAI,CAAC,AAAC,GAAO,EAAE,EAAE,CAAG,EAAE,IAAI,GAAK,QAAQ,MAAM,CAAC,AAAI,MAAM,YACxD,IAAI,CAAC,AAAC,IAEL,IAAM,EAAQ,EAAK,KAAK,CAAC,MACzB,EAAW,EAAM,MAAM,CAAG,IAAM,CAAA,EAAG,EAAM,KAAK,CAAC,EAAG,KAAK,IAAI,CAAC,MAAM;AAAA,GAAK,CAAC,CAAG,EAC7E,GACC,KAAK,CAAC,IAAM,EAAW,OACvB,OAAO,CAAC,IAAM,GAAU,IAEpB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,8CAY1B,CAEA,SAAS,GAAa,UAAE,CAAQ,CAAuC,EACrE,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,2CACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,sBACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,yCACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAO,UAAU,kCAClB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,iDAAwC,aACxD,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,QAAQ,YAAY,UAAU,uBAClC,EAAS,MAAM,MAGpB,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,qBACX,EAAS,GAAG,CAAC,AAAC,GACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAiD,SAAU,GAAzC,CAAA,EAAG,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,YAAY,CAAA,CAAE,SAM5D,CAEO,SAAS,GAAY,MAC1B,CAAI,UACJ,GAAW,CAAK,WAChB,CAAS,UACT,CAAQ,cACR,GAAe,CAAK,aACpB,GAAc,CAAK,WACnB,CAAS,mBACT,CAAiB,CACA,EACjB,GAAM,CAAE,IAAE,CAAE,aAAW,WAAE,CAAS,QAAE,CAAM,CAAE,SAAO,UAAE,CAAQ,cAAE,CAAY,CAAE,CAAG,EAC1E,EAAe,GAAI,aAAc,EAEjC,EACJ,GAAgB,EAAW,IAAM,EAAS,0BAA2B,EAAE,EAAI,EAE7E,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,yCACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,iDAEb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mCACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,4DACf,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mBACb,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,6CACX,EAAW,gBAAkB,iBAEhC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,8DACV,EACG,+EACA,EACE,wDACA,mDAMX,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,2CACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8CACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,SAAS,CAAA,CAAC,UAAU,2CACrB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,QAAQ,YAAY,UAAU,iCAClC,EAAO,MAAM,GAEhB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,UAAU,+CACtB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,QAAQ,UAAU,UAAU,iCAChC,EAAO,MAAM,QAIlB,KAGH,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,2CACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,gCAEb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8CACb,CAAA,EAAA,EAAA,IAAA,EAAC,IAAA,CACC,KAAM,EAAG,GAAG,CACZ,OAAO,SACP,IAAI,sBACJ,UAAU,sGACX,OACM,EAAG,MAAM,CACd,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CAAC,UAAU,mBAE1B,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,QAAQ,UAAU,UAAU,mBAChC,EAAG,MAAM,OAKI,IAAjB,EAAG,SAAS,CACX,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8CACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,qDAA4C,iBAC5D,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,KAAK,CAAA,CAAC,UAAU,+EACf,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,aAAa,CAAA,CAAC,UAAU,qBAAqB,kBAIhD,KAGH,EAAG,QAAQ,EAAI,CAAiB,MAC/B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8CACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,qDAA4C,cAC5D,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAc,OAAQ,EAAG,QAAQ,MAElC,KAGH,EAAG,UAAU,CACZ,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8CACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,qDAA4C,WAC5D,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,sCACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,mBAAmB,CAAA,CAAC,UAAU,sCAC/B,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,mFACb,EAAG,UAAU,CAAC,KAAK,CAAC,EAAG,WAI5B,UAGN,KAGH,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,2CACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,sBACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,yCACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAS,UAAU,kCACpB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,iDAAwC,eAE1D,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mCACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,wBACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,6CACZ,EAAY,YAAY,GAE3B,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,6CAAoC,aAErD,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,wBACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,6CAAmC,IAAE,EAAY,SAAS,IACzE,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,6CAAoC,iBAErD,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,wBACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,2CAAiC,IAAE,EAAY,SAAS,IACvE,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,6CAAoC,iBAErD,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,wBACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,6CAAqC,EAAY,WAAW,GAC3E,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,6CAAoC,uBAKzD,EACF,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,2CACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8CACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,aAAa,CAAA,CAAC,UAAU,2CACzB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,yCAAiC,SAGnD,KAGH,GAAY,EAAS,MAAM,CAAG,EAAI,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAa,SAAU,IAAe,KAGzE,GAAa,EAAU,MAAM,CAAG,EAAI,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAS,UAAW,IAAgB,QAG3E,CAAC,GACA,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,SAAU,EACV,UAAW,EACX,aAAc,EAAe,oBAAsB,gBACnD,eAAgB,EAAe,UAAY,UAC3C,oBAAoB,qCACpB,aAAc,EACd,YAAa,EACb,UAAW,EACX,kBAAmB,MAK7B,CEjVA,IAAA,GAAA,EAAA,CAAA,CAAA,WgCuBM,CRZH,EAAA,CAAA,EAAA,EAAA,OAAA,EAAA,yNQHY,GAAA,yBAAkC,CDAL,GCAU,QAAA,EAAU,2LTN9B,avBFlC,IAAA,GAAA,EAAA,CAAA,CAAA,OAAA,GAAA,EAAA,CAAA,CAAA,sRAAA,IAAA,GAAA,EAAA,CAAA,CAAA,ODAA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,OyBuBA,CgBbI,AhBaJ,GAAA,GAAA,CAAA,EAAiB,EAAA,OAAA,EAAA,aAA8B,6KAvBwB,sNAUvE,EzBRM,GAAa,IAAI,IAAI,CAAC,OAAQ,OAAQ,QAAS,OAAQ,OAAQ,QAAS,OAAQ,OAAO,EAE7F,SAAS,GAAY,CAAY,EAC/B,IAAM,EAAM,EAAK,WAAW,CAAC,KAC7B,OAAO,GAAO,GAAK,GAAW,GAAG,CAAC,EAAK,KAAK,CAAC,GAAK,WAAW,GAC/D,CAEA,SAAS,GAAW,CAAY,EAC9B,IAAM,EAAM,EAAK,WAAW,CAAC,MAAQ,EAAI,EAAK,KAAK,CAAC,EAAK,WAAW,CAAC,MAAQ,GACvE,EAAY,GAAY,GAAQ,CAAC,MAAM,EAAE,EAAI,KAAK,CAAC,GAAG,OAAO,CAAC,MAAO,QAAA,CAAS,CAAG,GACjF,EAAS,IAAI,gBAAgB,CAAE,OAAM,GAAI,GAAa,CAAE,SAAU,CAAU,CAAC,AAAE,GACrF,MAAO,CAAC,yBAAyB,EAAE,EAAO,QAAQ,GAAA,CAAI,AACxD,CAOA,IAAM,GAAoB,uBAgDnB,SAAS,GAAkB,MAAE,CAAI,iBAAE,CAAe,CAA0B,EACjF,IAAM,EA3BD,AA2BY,SA3BiB,AAApB,CAAgC,EAC9C,IAAM,EAAsB,EAAE,CAC1B,EAAY,EAEhB,IAAK,IAAM,KAAS,EAAK,QAAQ,CAAC,IAAoB,CACpD,IAAM,EAAiB,EAAM,KAAK,CAG5B,EAAW,GADC,CAAK,CAAC,EAAE,CAAC,MAAM,CAAG,CAAK,CACP,AADQ,EAAE,CAAC,SAAS,GAAG,MAAA,AAAM,EAI3D,EAAW,GACb,EAAS,IAAI,CAAC,CAAE,AADQ,KACF,OAAQ,MAAO,EAAK,KAAK,CAAC,EAAW,EAAU,GAGvE,EAAS,IAAI,CAAC,CAAE,KAAM,aAAc,KAAM,CAAK,CAAC,EAAE,AAAC,GACnD,EAAY,EAAiB,CAAK,CAAC,EAAE,CAAC,MAAM,AAC9C,CAMA,OAJI,EAAY,EAAK,MAAM,EAAE,AAC3B,EAAS,IAAI,CAAC,CAAE,KAAM,OAAQ,MAAO,EAAK,KAAK,CAAC,EAAW,GAGtD,CACT,EAGuC,GAC/B,EAAuB,EAAS,IAAI,CAAE,AAAD,GAAO,AAAW,iBAAT,IAAI,EAClD,EAAa,GAAiB,OAAO,UAAY,EAAE,QAEzD,AAAI,AAAC,GAA8C,GAAG,CAAzB,EAAW,MAAM,CAK5C,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,gCACZ,EAAS,GAAG,CAAC,AAAC,IACb,GAAqB,SAAjB,EAAQ,IAAI,CAAa,CAC3B,IAAM,EAAU,EAAQ,KAAK,CAAC,IAAI,UAC7B,AAAL,EAEE,CAAA,CAFE,CAEF,EAAA,EAFY,CAEZ,EAAC,OAAA,CAA0C,UAAU,mCAClD,GADQ,CAAC,KAAK,EAAE,EAAQ,KAAK,CAAC,EAAG,IAAA,CAAK,EAFtB,IAMvB,CACA,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAA8C,KAAM,EAAQ,IAAI,EAAzC,CAAC,IAAI,EAAE,EAAQ,IAAI,CAAA,CAAE,CACtD,GACC,EAAW,GAAG,CAAC,AAAC,GACf,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAwC,KAAM,GAAvB,CAAC,MAAM,EAAE,EAAA,CAAM,MAlBpC,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,mCAA2B,GAsBtD,CAEA,SAAS,GAAkB,MAAE,CAAI,CAAoB,EACnD,IAAM,EAnFC,EAAK,KAAK,CAAC,CAmFD,IAnFM,GAAG,IAmFG,EACvB,AApF0B,CAoFzB,EAAW,EAAa,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,UAE3C,AAAI,GAAY,GACd,AAAI,EAEA,CAAA,CAHiB,CAGjB,EAAA,IAAA,AAFW,EAEV,MAAA,CACC,cAAY,gCACZ,UAAU,8FAEV,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAS,UAAU,qBACpB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,oBAAY,OAMhC,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,MAAM,CAAA,WACL,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,aAAa,CAAA,CAAC,OAAO,CAAA,CAAA,WACpB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,IAAK,GAAW,GAChB,IAAK,EACL,cAAY,0BACZ,QAAS,IAAM,EAAa,IAC5B,UAAU,8GAGd,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,aAAa,CAAA,CAAC,UAAU,0XACvB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,cAAc,CAAC,IAAI,CAAA,UAClB,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,WAAW,CAAA,WAAC,YAAU,OAEzB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,gCACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,IAAK,GAAW,GAChB,IAAK,EACL,UAAU,gDAGd,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,4DACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,wCACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,wCAAgC,MAElD,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CACC,KAAM,GAAW,GACjB,SAAU,EACV,UAAU,sGACV,aAAY,CAAC,SAAS,EAAE,EAAA,CAAU,UAElC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CAAC,UAAU,uBASlC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CACC,KAAM,GAAW,GACjB,SAAU,EACV,cAAY,yBACZ,UAAU,6DAET,GAGP,CClJA,EAAA,CAAA,CAAA,OAAA,IAAA,GAAA,EAAA,CAAA,CAAA,MAGA,GAAA,EAAA,CAAA,CAAA,OAIA,GAAA,EAAA,CAAA,CAAA,OiBxBO,SAAS,GAAe,CAAU,EACvC,GAAW,IAAP,EAAU,MAAO,KAErB,IAAM,EAAe,KAAK,KAAK,CAAC,EAAK,KACrC,GAAqB,IAAjB,EAAoB,MAAO,MAE/B,IAAM,EAAQ,KAAK,KAAK,CAAC,EAAe,MAClC,EAAU,KAAK,KAAK,CAAE,EAAe,KAAQ,IAC7C,EAAU,EAAe,UAE/B,AAAI,EAAQ,EACH,CAAA,AADM,EACH,EAAM,EAAE,EAAE,EAAQ,CAAC,CAAC,CAG5B,EAAU,EACL,CADQ,AACR,EAAG,EAAQ,EAAE,EAAE,EAAQ,CAAC,CAAC,CAG3B,CAAA,EAAG,EAAQ,CAAC,CAAC,AACtB,CjBWA,SAAS,GAAQ,CACf,KAAM,CAAI,OACV,CAAK,UACL,CAAQ,CAKT,EACC,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,2BACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,0GACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAK,UAAU,sBACf,KAEF,IAGP,CAEA,SAAS,GAAK,UAAE,CAAQ,CAAE,WAAS,CAAqD,EACtF,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EAAC,uDAAwD,YACxE,GAGP,CAEA,SAAS,GAAG,OAAE,CAAK,UAAE,CAAQ,CAAgD,EAC3E,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,kCACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,+EACb,IAEH,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,gCAAwB,MAG9C,CAEA,SAAS,GAAK,IAAE,CAAE,CAAE,OAAK,CAAkC,EACzD,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,yEACA,EACI,2DACA,qDAGL,EAAK,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,KAAK,CAAA,CAAC,UAAU,WAAc,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAC,CAAA,CAAC,UAAU,WACjD,IAGP,CA0CA,IAAM,GAAoC,CACxC,CAAC,GAAA,QAAQ,CAAC,IAAI,CAAC,CAAE,mCACjB,CAAC,GAAA,QAAQ,CAAC,MAAM,CAAC,CAAE,uCACnB,CAAC,GAAA,QAAQ,CAAC,MAAM,CAAC,CAAE,gCACrB,EAeO,SAAS,GAAY,MAC1B,CAAI,YACJ,CAAU,aACV,CAAW,WACX,CAAS,eACT,CAAa,gBACb,CAAc,eACd,CAAa,aACb,CAAW,CACM,QACjB,IAgG0B,MA/JpB,EACA,EACA,EA6DA,EAAiC,aAAnB,EAAK,SAAS,CAE5B,EAlDR,AAkDsB,SAlDb,AAAe,CAAkB,EACxC,GAAM,CAAC,EAAS,EAAW,CAAG,CAAA,EAAA,EAAA,QAAQ,AAAR,EAAwB,MAChD,EAAc,CAAA,EAAA,EAAA,MAAM,AAAN,EAA8C,MAclE,MAbA,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,IACR,AAAK,GAIL,CAJI,CAIO,GAAe,GAJV,EAIe,GAAG,CAAC,EAAG,KAAK,GAAG,GAAK,KACnD,EAAY,OAAO,CAAG,YAAY,KAChC,EAAW,GAAe,KAAK,GAAG,CAAC,EAAG,KAAK,GAAG,GAAK,IACrD,EAAG,KACI,KACD,EAAY,OAAO,EAAE,cAAc,EAAY,OAAO,CAC5D,QATE,EAAW,MAUZ,CAAC,EAAU,EACP,CACT,EAgCmC,AACE,YADjB,EAAK,KAAK,EAAiC,oBAAf,EAAK,KAAK,CACT,EAAK,SAAS,MAAG,GAC1D,EAAS,GAAA,sBAAsB,CAAC,EAAK,KAAK,CAAC,CAC3C,GACJ,CAAQ,EAAK,OAAO,EAAK,CAAC,CAAC,EAAK,SAAS,EAAI,EAAK,OAAO,EAAE,SAAW,EAAK,SAAS,CAAC,IAAI,EAAA,CAAE,CAE7F,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,cAAY,wBAAwB,UAAU,iBAGhD,CAAC,GAAe,EAAK,QAAQ,CAAG,EAC/B,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,cAAY,0BAA0B,UAAU,qBACnD,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,0EACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EAAC,qCAAsC,EAAO,aAAa,EACxE,MAAO,CAAE,MAAO,CAAA,EAAG,EAAK,QAAQ,CAAC,CAAC,CAAC,AAAC,QAIxC,KAGH,EAAK,QAAQ,EAAI,EAAK,SAAS,EAAI,EAClC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAQ,KAAM,GAAM,MAAM,uBACzB,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,CAAK,UAAU,gCACb,EAAK,QAAQ,CAAG,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAG,MAAM,qBAAa,EAAK,QAAQ,GAAS,KAC7D,EAAK,SAAS,CACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAG,MAAM,iBACR,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAkB,KAAM,EAAK,SAAS,KAEvC,KACH,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAG,MAAM,mBACR,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,wBAAgB,EAAK,OAAO,KAE5C,UAGN,KAGH,EAAK,EAAE,CACN,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAQ,KAAM,GAAA,mBAAmB,CAAE,MAAM,wBACxC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,UACC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oCACb,CAAA,EAAA,EAAA,IAAA,EAAC,IAAA,CACC,KAAM,EAAK,EAAE,CAAC,GAAG,CACjB,OAAO,SACP,IAAI,sBACJ,UAAU,8FACX,IACG,EAAK,EAAE,CAAC,MAAM,CAAC,IAAC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CAAC,UAAU,cAE5C,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EAAC,wBAAyB,EAAO,CAAC,EAAK,EAAE,CAAC,MAAM,CAAC,WACjE,EAAK,EAAE,CAAC,MAAM,IAEM,IAAtB,EAAK,EAAE,CAAC,SAAS,CAChB,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,oGACd,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,aAAa,CAAA,CAAC,UAAU,oBAAoB,gBAE7C,KACH,EAAK,EAAE,CAAC,QAAQ,GAA0B,IAAtB,EAAK,YAAY,CACpC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAc,OAAQ,EAAK,EAAE,CAAC,QAAQ,GACrC,KACH,EAAK,EAAE,CAAC,UAAU,CACjB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,4DACb,EAAK,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAG,KAE7B,YAIR,KAGJ,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,6CACZ,EAAK,MAAM,CACV,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,UACC,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,CAAG,MAAM,mBACR,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,2CACd,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,SAAS,CAAA,CAAC,UAAU,uCACrB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,iCAAyB,EAAK,MAAM,MAErD,EAAK,UAAU,CACd,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,iDAAuC,QAAM,EAAK,UAAU,IAC1E,UAGN,KACH,EAAK,SAAS,EAAI,EAAK,OAAO,CAC7B,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,UACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAG,MAAM,iBACR,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,6CACb,EAAK,SAAS,GACX,CAAC,AACW,CAAA,EAAA,GAAA,gBAAA,AAAgB,EAAC,EAAK,SAAS,EAClC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAE,UAAU,kCAEtB,KACH,EAAK,SAAS,CACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,UACE,GAAA,eAAe,CAAC,EAAK,SAAS,CAAiC,EAC9D,EAAK,SAAS,GAEhB,KACH,EAAK,SAAS,EAAI,EAAK,OAAO,CAC7B,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,8BAAqB,MACnC,KACH,EAAK,OAAO,CACX,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,0CACb,CAAA,EAAA,GAAA,YAAA,AAAY,EAAC,EAAK,OAAO,EAAE,WAAW,EAAI,EAAK,OAAO,GAEvD,YAIR,KACH,EAAK,SAAS,CACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,UACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAG,MAAM,mBACR,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,2CACd,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,UAAU,wCA7LL,EA8LQ,EAAK,KA9La,IA8LJ,CA7L1C,EAAM,KAAK,GAAG,GAMhB,AAAJ,GADgB,KAAK,KAAK,CAAC,GADZ,KAAK,KAAK,CAAC,GADV,KAAK,KAAK,CAAC,CADZ,GADT,EAAO,AAAqB,CACb,gBADD,EAAyB,IAAI,KAAK,GAAW,OAAO,GAAK,EACxD,EACe,MACA,KACA,KACtB,GACL,CAAP,GAAW,KAAK,GAAM,kBAAkB,MAAC,EAAW,CAClD,KAAM,UACN,MAAO,QACP,IAAK,SACP,GACE,EAAU,EAAU,CAAP,AAAO,EAAG,EAAQ,KAAK,CAAC,CACrC,EAAS,EAAU,CAAP,AAAO,EAAG,EAAO,KAAK,CAAC,CACnC,EAAU,EAAU,CAAP,AAAO,EAAG,EAAQ,KAAK,CAAC,CAClC,mBAkLG,KACH,EAAK,QAAQ,CACZ,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,UACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAG,MAAM,gBACR,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,8EACd,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,GAAG,CAAA,CAAC,UAAU,aAAa,eAIhC,KACH,EAAK,OAAO,EAAI,EACf,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,UACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAG,MAAO,EAAK,OAAO,CAAG,UAAY,mBACpC,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,2CACd,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,UAAU,uCAChB,EAAK,OAAO,EAAI,SAIrB,QAIL,EAAK,SAAS,EAAI,EAAK,YAAY,CAClC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAQ,KAAM,GAAA,aAAa,CAAE,MAAM,kBAClC,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,CAAK,UAAU,mDACb,EAAK,SAAS,CAAG,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAG,MAAM,sBAAc,EAAK,SAAS,GAAS,KAChE,EAAK,YAAY,CAChB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAG,MAAM,iBACR,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,4BAAoB,EAAK,YAAY,KAErD,UAGN,KAGH,GAAkB,EAAK,MAAM,EAAI,EAChC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAQ,KAAM,GAAA,SAAS,CAAE,MAAM,uBAC9B,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,WAAY,GAAc,KAC1B,YAAa,GAAe,GAC5B,UAAW,GAAa,KACxB,cAAe,EACf,eAAgB,EAChB,cAAe,IAAiB,EAChC,YAAa,GAAe,SAG9B,KAGJ,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAc,KAAM,MAG3B,CAIA,SAAS,GAAS,YAChB,CAAU,aACV,CAAW,WACX,CAAS,eACT,CAAa,gBACb,CAAc,eACd,CAAa,aACb,CAAW,CASZ,EACC,GAAM,GAAE,CAAC,CAAE,CAAG,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,OACvB,EAAyB,MAAd,GAAsB,EAAW,MAAM,CAAG,EACrD,EAAa,GAAY,SAAW,EACpC,EAAO,GAAY,YAAc,OAEvC,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,WACC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,cAAY,qBAAqB,UAAU,8CAC9C,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,iDACZ,GAAe,CAAC,EACf,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAa,KAAK,OACnB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,8BAAqB,mBAErC,EACF,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,aAAa,CAAA,CAAC,UAAU,0BACzB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,oCAA4B,OAE5C,EACF,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAa,KAAK,OACnB,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,WAAK,eACQ,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,iCAAyB,IAAY,YAGnE,EACF,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,aAAa,CAAA,CAAC,UAAU,6BACzB,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,WACE,EAAW,MAAM,CAAC,WAAQ,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,iCAAyB,IACnE,EAAW,KAAK,CAAG,EAClB,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,gDAAsC,KACjD,EAAW,KAAK,CAAC,YAEpB,WAGN,EACF,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,UAAU,4BACvB,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,WAAK,gBACS,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,iCAAyB,IACrD,EAAW,KAAK,CAAG,EAClB,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,gDAAsC,KACjD,EAAW,KAAK,CAAC,YAEpB,WAGN,OAEL,CAAC,GAAc,CAAA,CAAS,EAAK,CAAC,EAC7B,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,QAAS,EACT,SAAU,EACV,UAAU,kJACV,aAAY,EAAE,+CAEd,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,SAAS,CAAA,CAAC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EAAC,SAAU,GAAe,oBAElD,QAEL,GAAY,CAAC,EACZ,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,gBACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CACX,MAAO,EAAE,iCACT,QAAS,EACT,SAAS,EACT,MAAO,CAAC,CAAC,EACT,KAAM,EACN,QAAQ,UACR,KAAK,SAGP,KACH,EAAc,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,6CAAqC,IAAmB,OAG1F,CAIA,SAAS,GAAc,MAAE,CAAI,CAA6B,SAEhC,AAOxB,IAAI,CAAC,CAPH,EAAK,EAOG,WAPU,EACL,MAAb,EAAK,IAAI,EACM,MAAf,EAAK,MAAM,EACX,AAAuB,QAAlB,cAAc,EACnB,AAAuB,QAAlB,cAAc,EACD,MAAlB,EAAK,SAAS,EACM,MAApB,EAAK,WAAW,CACD,KAGf,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAQ,KAAM,GAAA,QAAQ,CAAE,MAAM,oBAC7B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mCACZ,EAAK,aAAa,CACjB,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,WACC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,+GACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAY,UAAU,WAAW,cAEpC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,kCACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAK,GAAI,EAAK,aAAa,CAAC,QAAQ,CAAE,MAAM,QAC7C,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAK,GAAI,EAAK,aAAa,CAAC,SAAS,CAAE,MAAM,SAC9C,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAK,GAAI,EAAK,aAAa,CAAC,UAAU,CAAE,MAAM,gBAGjD,KACoB,MAAvB,EAAK,cAAc,CAClB,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,WACC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,+GACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,UAAU,WAAW,eAEnC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,kCACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAK,GAAI,EAAK,cAAc,CAAE,MAAM,YACb,MAAvB,EAAK,cAAc,CAClB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAK,GAAI,EAAK,cAAc,CAAE,MAAM,cACnC,WAGN,KACU,MAAb,EAAK,IAAI,EACK,MAAf,EAAK,MAAM,EACY,MAAvB,EAAK,cAAc,EACC,MAApB,EAAK,WAAW,EACE,MAAlB,EAAK,SAAS,CACZ,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,WACC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,+GACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,SAAS,CAAA,CAAC,UAAU,WAAW,UAElC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,kCACC,MAAb,EAAK,IAAI,CAAW,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAK,GAAI,EAAK,IAAI,CAAE,MAAM,SAAY,KAC5C,MAAf,EAAK,MAAM,CAAW,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAK,GAAI,EAAK,MAAM,CAAE,MAAM,OAAU,KACtC,MAAvB,EAAK,cAAc,CAAW,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAK,GAAI,EAAK,cAAc,CAAE,MAAM,UAAa,KAC5D,MAApB,EAAK,WAAW,CAAW,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAK,GAAI,EAAK,WAAW,CAAE,MAAM,UAAa,KACxD,MAAlB,EAAK,SAAS,CAAW,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAK,GAAI,EAAK,SAAS,CAAE,MAAM,SAAY,WAGxE,SAIZ,oBmB1emB,EAAA,uDAfiC,IAAA,UAAe,CEAC,ADAC,+DDCA,CAAA,AEAA,CAAA,AFAA,CEAA,AFAA,CEAA,AFAA,alBDrE,IAAA,GAAA,EAAA,CAAA,CAAA,OAAA,GAAA,EAAA,CAAA,CAAA,qUAgCA,SAAS,GAAqB,CAAuB,CAAE,CAAW,EAChE,GAAyB,MAArB,EAAO,UAAU,EAAY,EAAO,UAAU,CAAG,EAAG,OAAO,EAAO,UAAU,CAChF,GAAI,CAAC,EAAO,WAAW,EAAI,EAAO,SAAS,CAAE,CAC3C,IAAM,EAAU,IAAI,KAAK,EAAO,SAAS,EAAE,OAAO,GAClD,GAAI,CAAC,OAAO,KAAK,CAAC,GAAU,OAAO,KAAK,GAAG,CAAC,EAAG,EAAM,EACvD,CACA,OAAO,CACT,CA8BA,SAAS,GAAa,CAAa,SACjC,AAAI,GAAS,IAAkB,CAAA,EAAG,CAAC,EAAQ,CAAnB,EAAmB,CAAS,CAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAC/D,GAAS,IAAc,CAAA,EAAP,AAAU,CAAC,EAAQ,GAAA,CAAK,CAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CACpD,OAAO,EAChB,CAGA,SAAS,GAAgB,CAA8B,EACrD,IAAM,EAAI,aAAiB,KAAO,EAAQ,IAAI,KAAK,OAAO,WAC1D,AAAI,OAAO,KAAK,CAAC,EAAE,OAAO,IAAY,CAAP,EACxB,EAAE,kBAAkB,CAAC,EAAE,CAAE,CAAE,KAAM,UAAW,OAAQ,UAAW,OAAQ,SAAU,EAC1F,CAGA,SAAS,GAAW,CAAW,SAC7B,AAAI,GAAO,EAAU,CAAP,AAAQ,CAAC,EAAE,EAAI,OAAO,CAAC,GAAA,CAAI,CACrC,GAAO,IAAa,CAAC,CAAR,AAAS,EAAE,EAAI,OAAO,CAAC,GAAA,CAAI,CACrC,CAAC,CAAC,EAAE,EAAI,OAAO,CAAC,GAAA,CAAI,AAC7B,CASA,IAAM,GAAwC,CAC5C,QAAS,YACT,aAAc,eACd,SAAU,cACV,KAAM,WACN,UAAW,eACX,OAAQ,WACR,iBAAkB,iBAClB,SAAU,WACV,SAAU,aACV,OAAQ,YACR,MAAO,SACT,EAEM,GAGF,CACF,cAAe,CACb,MAAO,UACP,WAAY,gBACZ,QAAS,iCACT,KAAM,EAAA,IAAI,AACZ,EACA,cAAe,CACb,MAAO,UACP,WAAY,gBACZ,QAAS,iCACT,KAAM,EAAA,SAAS,AACjB,EACA,gBAAiB,CACf,MAAO,YACP,WAAY,mBACZ,QAAS,uCACT,KAAM,GAAA,WAAW,AACnB,EACA,aAAc,CACZ,MAAO,SACP,WAAY,eACZ,QAAS,+BACT,KAAM,GAAA,OAAO,AACf,EACA,cAAe,CACb,MAAO,UACP,WAAY,iBACZ,QAAS,mCACT,KAAM,EAAA,MAAM,AACd,EACA,cAAe,CACb,MAAO,UACP,WAAY,eACZ,QAAS,+BACT,KAAM,GAAA,OAAO,AACf,EACA,eAAgB,CACd,MAAO,WACP,WAAY,kBACZ,QAAS,qCACT,KAAM,GAAA,GAAG,AACX,CACF,EAEA,SAAS,GAAiB,CAAa,EACrC,OAAO,EAAM,UAAU,CAAC,OAC1B,CAmIO,SAAS,GAAY,SAAE,CAAO,SAAE,CAAO,OAAE,CAAK,mBAAE,CAAiB,CAAoB,EAC1F,GAAM,GAAE,CAAC,CAAE,CAAG,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,OACvB,EAAM,AAtPd,SAAS,AAAc,CAAiC,EACtD,GAAM,CAAC,EAAK,EAAO,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,KAAK,GAAG,EACjC,EAAc,CAAA,EAAA,EAAA,MAAA,AAAM,EAAwC,MAgBlE,MAdA,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACQ,AACZ,GADsC,AATrC,EAAQ,IAAI,AAUJ,CADa,AATR,AAAC,GAAM,CAS4B,AAT3B,EAAE,KAAK,CAAC,UAAU,CAAC,SAAW,CAAC,EAAE,WAAW,EAAI,EAAE,SAAS,IAYnF,EAAY,OAAO,CAAG,YAAY,IAAM,EAAO,KAAK,GAAG,IAAK,IAAA,EAEvD,KACD,EAAY,OAAO,EAAE,CACvB,cAAc,EAAY,OAAO,EACjC,EAAY,OAAO,CAAG,KAE1B,GACC,CAAC,EAAQ,EAEL,CACT,EAmO4B,GAE1B,GAAI,EACF,MACE,CAAA,AAFS,EAET,EAAA,GAAA,EAAC,MAAA,CAAI,cAAY,uBAAuB,UAAU,gDAChD,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,YAAY,CAAA,CAAC,UAAU,iDAK9B,GAAI,EACF,KADS,CAEP,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,+DACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,WAAW,CAAA,CAAC,UAAU,qBACvB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,UAAM,OAKb,GAAI,CAAC,GAA8B,GAAG,CAAtB,EAAQ,MAAM,CAC5B,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,gEACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,UAAU,kCACjB,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,2CAAmC,EAAE,uCAKxD,IAAM,EAAc,EAAQ,MAAM,CAAC,AAAC,GAAM,CAAC,GAAiB,EAAE,KAAK,GAC7D,EAAgB,KAAK,GAAG,IACzB,EAAY,GAAG,CAAE,AAAD,GAAO,GAAqB,EAAG,OAC/C,EAAY,GAAG,CAAC,AAAC,GAAM,EAAE,cAAc,EAAI,GAC9C,GAGI,EArID,AAqIc,SArIL,AACd,CAA0B,CAC1B,CAAkC,EAElC,GAAI,CAAC,EAAQ,MAAM,CAAE,MAAO,EAAE,CAG9B,IAAM,EAAyB,EAAQ,MAAM,CAAC,AAAC,GAAkB,iBAAZ,EAAE,KAAK,EAAqB,MAAM,CACjF,EAAgB,GAAU,QAAU,EAGtC,EAAY,EAChB,GAAI,EAAgB,EAAwB,CAC1C,EAAY,IAAI,EAAQ,CAGxB,IAAM,EAAgB,CAAO,CAAC,EAAQ,MAAM,CAAG,EAAE,CAAC,UAAU,CAE5D,IAAK,IAAI,EAAI,EAAwB,EAAI,EAAe,IAAK,CAC3D,IAAM,EAAK,CAAS,CAAC,EAAE,CAEnB,EAAI,GACN,EAAU,IAAI,CAAC,CACb,WAAY,EAFgB,AAG5B,MAAO,cACP,UAAW,EAAG,SAAS,EAAI,CAAC,kBAAkB,EAAE,EAAA,CAClD,AADqD,GAIvD,EAAU,IAAI,CAAC,CACb,WAAY,EACZ,MAAO,eACP,UAAW,EAAG,SAAS,EAAI,CAAC,UAAU,EAAE,EAAA,CAC1C,AAD6C,EAE/C,CACF,CAGA,IAAM,EAAkC,EAAE,CACtC,EAAmC,EAAE,CACrC,EAAiB,EAErB,IAAK,IAAM,KAAK,EAGd,GAFA,EAAc,GADW,CACP,CAAC,GAEH,iBAAZ,EAAE,KAAK,CAAqB,CAC9B,IAAM,EAAK,GAAU,CAAC,EAAe,CACrC,EAAW,IAAI,CAAC,CACd,OAAQ,EAAW,MAAM,CAAG,EAC5B,QAAS,EACT,iBAAkB,GAAI,QACtB,qBAAsB,GAAI,WAC5B,GACA,EAAgB,EAAE,CAClB,GACF,CAWF,OAPI,EAAc,MAAM,CAAG,GAAG,AAC5B,EAAW,IAAI,CAAC,CACd,OAAQ,EAAW,MAAM,CAAG,EAC5B,QAAS,CACX,GAGK,CACT,EAkE4C,EAAS,GAC7C,EAAwB,EAAW,MAAM,CAAG,EAE5C,EAAc,EAAY,MAAM,CAAC,CAAC,EAAK,IAAM,EAAM,GAAqB,EAAG,GAAM,GACjF,EAAc,EAAY,MAAM,CAAC,CAAC,EAAK,IAAM,GAAO,EAAE,CAAH,aAAiB,EAAI,CAAC,EAAG,GAC5E,EAAmB,EAAY,MAAM,CAAC,CAAC,EAAK,IAAM,GAAO,EAAE,CAAH,UAAc,GAAI,CAAC,CAAG,GAC9E,EAAoB,EAAY,MAAM,CAAC,CAAC,EAAK,IAAM,GAAO,EAAE,CAAH,WAAe,GAAI,CAAC,CAAG,GAChF,EAAe,EAAY,MAAM,CAAC,CAAC,EAAK,IAAM,EAAO,GAAE,CAAH,MAAU,GAAI,CAAC,CAAG,GAE5E,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oCACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,cAAY,mBAAmB,UAAU,+BAC3C,EAAW,GAAG,CAAC,AAAC,GACf,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAEC,UAAW,EACX,WAAY,EACZ,cAAe,EACf,IAAK,GAJA,EAAU,MAAM,KAQ1B,EAAc,EACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,YAAa,EACb,YAAa,EACb,iBAAkB,EAClB,kBAAmB,EACnB,aAAc,IAEd,OAGV,CAMA,SAAS,GAAe,WACtB,CAAS,YACT,CAAU,eACV,CAAa,KACb,CAAG,CAMJ,EACC,IAAM,EAjHR,AAiHkB,SAjHT,AACP,CAA4B,EAE5B,IAAM,EAAgB,IAAI,EAAU,OAAO,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,AAAC,GAAM,GAAiB,EAAE,KAAK,GAC3F,GAAI,CAAC,EAAe,OAAO,KAE3B,OAAQ,EAAc,KAAK,EACzB,IAAK,eACH,MAAO,CAAE,MAAO,WAAY,WAAY,kBAAmB,SAAU,eAAgB,CACvF,KAAK,gBACH,MAAO,CAAE,MAAO,YAAa,WAAY,mBAAoB,SAAU,gBAAiB,CAC1F,KAAK,aACH,MAAO,CAAE,MAAO,SAAU,WAAY,eAAgB,SAAU,YAAa,CAC/E,KAAK,cACH,MAAO,CAAE,MAAO,UAAW,WAAY,eAAgB,SAAU,YAAa,CAChF,KAAK,cACH,MAAO,CAAE,MAAO,UAAW,WAAY,iBAAkB,SAAU,cAAe,CACpF,SACE,OAAO,IACX,CACF,EA6FsC,GAEpC,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CACC,cAAa,CAAC,UAAU,EAAE,EAAU,MAAM,CAAA,CAAE,CAC5C,UAAU,wFAGT,EACC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,gGACb,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,sEAA4D,aAC/D,EAAU,MAAM,IAE5B,EACC,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAW,CAAC,4CAA4C,EAAE,EAAQ,UAAU,CAAA,CAAE,WAClF,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAW,CAAC,sCAAsC,EAAE,EAAQ,QAAQ,CAAA,CAAE,GAC3E,EAAQ,KAAK,IAEd,QAEJ,KAGJ,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mCAEb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,4DAEd,EAAU,OAAO,CAAC,GAAG,CAAC,CAAC,EAAG,KACzB,GAAI,GAAiB,EAAE,KAAK,EAAG,CAC7B,IAII,EAJE,EAA0B,iBAAZ,EAAE,KAAK,CACrB,EACQ,eAAZ,EAAE,KAAK,EAAiC,gBAAZ,EAAE,KAAK,EAAkC,gBAAZ,EAAE,KAAK,CAGlE,GAAI,EACF,EAAU,EAAU,OADL,SACqB,MAC/B,GAAI,EAAW,CACpB,IAAM,EAAiB,IAAI,EAAU,OAAO,CAAC,CAC1C,OAAO,GACP,IAAI,CAAC,AAAC,GAAM,CAAC,GAAiB,EAAE,KAAK,GAAK,EAAE,YAAY,EAC3D,EAAU,GAAgB,cAAgB,EAAE,YAAY,AAC1D,CACA,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAEC,OAAQ,EACR,QAAS,EACT,YAAa,EAAc,EAAU,oBAAoB,MAAG,EAC5D,QAAS,AAAQ,MACjB,OAAQ,IAAQ,EAAU,OAAO,CAAC,MAAM,CAAG,GALtC,CAAA,EAAG,EAAE,UAAU,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,SAAS,CAAA,CAAE,CAQtD,CACA,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAEC,OAAQ,EACR,cAAe,EACf,IAAK,GAHA,CAAA,EAAG,EAAE,UAAU,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,SAAS,CAAA,CAAE,CAMtD,QAIR,CAMA,SAAS,GAAkB,QACzB,CAAM,SACN,CAAO,aACP,CAAW,SACX,CAAO,CACP,QAAM,CAOP,EACC,IAiCgB,EAjCV,EAAQ,EAAgB,CAAC,EAAO,KAAK,CAAC,CAC5C,GAAI,CAAC,EAAO,OAAO,KAEnB,IAAM,EAAiB,GAAe,EAAY,MAAM,CAAG,EACrD,EAAO,EAAM,IAAI,CAEvB,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CACC,UAAW,CAAC,kCAAkC,EAAE,EAAU,OAAS,OAAO,CAAC,EAAE,EAAS,OAAS,OAAA,CAAQ,WAEvG,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oCAEb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,UAAW,CAAC,6EAA6E,EAAE,EAAM,OAAO,CAAA,CAAE,UAE1G,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAK,UAAW,CAAC,QAAQ,EAAE,EAAM,UAAU,CAAA,CAAE,KAIhD,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAW,CAAC,oBAAoB,EAAE,EAAM,UAAU,CAAA,CAAE,UAAG,EAAM,KAAK,GAGvE,EAAO,SAAS,EACjB,CAAC,CAA6B,UAA5B,OAAO,EAAO,SAAS,EAAiB,EAAO,SAAS,CAAC,UAAU,CAAC,YAAA,CAAY,CAChF,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,iEACb,GAAgB,OAAO,EAAO,SAAS,KAExC,QAIL,KAGwB,KAFrB,CAAC,SAEG,EAAO,KAAK,EACK,gBAAjB,EAAO,KAAK,EACK,gBAAjB,EAAO,KAAK,CAEZ,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CACC,UAAW,CAAC,0DAA0D,EACpE,EACI,kCACA,wCAAA,CACJ,WAED,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,WAAW,CAAA,CAAC,UAAU,6CAEvB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,aAAa,CAAA,CAAC,UAAU,gDAE3B,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CACC,cAAa,EAAU,qBAAuB,0BAC9C,UAAU,iEACX,KACU,SAKjB,KACH,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,cAAY,iCAAiC,UAAU,qBAC1D,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAkB,KAAK,GAAG,gBAAiB,MAE5C,OAGV,CAEA,SAAS,GAAc,QACrB,CAAM,eACN,CAAa,KACb,CAAG,CAKJ,EACC,GAAM,GAAE,CAAC,CAAE,CAAG,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,OACvB,EAAO,EAAO,KAAK,CAAC,QAAQ,CAAC,KAAO,EAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAG,EAAO,KAAK,CAC7E,EAAS,EAAO,KAAK,CAAC,QAAQ,CAAC,KAAO,EAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAG,KACnE,EAAwB,OAAX,EACb,EAAc,GAAQ,WAAW,WAAa,GAC9C,EAAW,EAAa,CAAC,EAAK,EAAI,EAClC,EAAQ,EACV,CAAC,MAAM,EAAE,EAAQ,OAAO,CAAC,SAAU,IAAA,CAAK,CAC7B,OAAX,EACE,CAAA,EAAG,EAAS,EAAE,EAAE,EAAA,CAAQ,CACxB,EAEA,EAAa,GAAqB,EAAQ,GAC1C,EAAY,CAAC,EAAO,WAAW,EAAI,CAAC,CAAC,EAAO,SAAS,CAErD,EAAa,EAAY,GAAK,EAC9B,EACJ,EAAgB,EAAI,KAAK,GAAG,CAAC,EAAa,EAAa,EAAiB,KAAO,EAC3E,EAAgB,EAAO,WAAW,CACpC,EACE,iBACA,EACE,eACA,iBACJ,cACE,EACkB,AAAtB,QAAO,WAAW,EAAmC,MAAvB,EAAO,YAAY,CAC7C,AAAC,GAAO,WAAW,GAAI,CAAC,EAAK,EAAD,AAAQ,YAAY,GAAI,CAAC,CACrD,KAEA,CAAC,EAAQ,EAAU,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GAC/B,EAAmB,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,KAC9B,EAAO,MAAM,EAClB,AADoB,UACV,SAAS,CAAC,SAAS,CAAC,EAAO,MAAM,EAAE,IAAI,CAAC,KAChD,GAAU,GACV,WAAW,IAAM,GAAU,GAAQ,KACrC,EACF,EAAG,CAAC,EAAO,MAAM,CAAC,EAElB,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CACC,UAAW,CAAC,uDAAuD,EAAE,EAAa,OAAS,GAAA,CAAI,WAE/F,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,cAAa,CAAC,WAAW,EAAE,EAAO,KAAK,CAAA,CAAE,CAAE,UAAU,oCAExD,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,2EACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,UAAW,CAAC,aAAa,EAAE,EAAY,wBAA0B,cAAc,CAAC,EAC9E,EACI,cACA,EAAO,WAAW,CAChB,iBACA,yBAAA,CACN,KAKN,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CACC,UAAW,CAAC,2CAA2C,EACrD,EAAa,wBAA0B,qBAAA,CACvC,UAED,IAIF,EAAO,MAAM,CACZ,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,EACT,UAAU,8HACV,MAAO,EAAE,8CAER,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,KAAK,CAAA,CAAC,UAAU,iCAEjB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,IAAI,CAAA,CAAC,UAAU,kBAGlB,KAGJ,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,UAAW,CAAC,8DAA8D,EAAE,EAAa,QAAU,MAAA,CAAO,UAEzG,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,UAAU,+CACV,MAAO,CACL,gBACE,gFACF,eAAgB,YAChB,UAAW,mCACb,IAGF,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,UAAW,CAAC,gDAAgD,EAAE,EAAA,CAAe,CAC7E,MAAO,CAAE,MAAO,CAAA,EAAG,KAAK,GAAG,CAAC,EAAY,KAAK,CAAC,CAAC,AAAC,MAMtD,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,yFACb,GAAe,QAKpB,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,sDACZ,EAAO,SAAS,CACf,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,iDACb,GAAgB,EAAO,SAAS,IAEjC,KACH,AAAe,SAAQ,EAAc,EACpC,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,sEACd,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,GAAG,CAAA,CAAC,UAAU,uBACd,GAAa,MAEd,KACe,MAAlB,EAAO,OAAO,EAAY,EAAO,OAAO,CAAG,EAC1C,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,sEACd,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,UAAU,uBACrB,GAAW,EAAO,OAAO,KAE1B,QAIoB,MAAzB,EAAO,cAAc,EAAY,EAAO,cAAc,CAAG,EACxD,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAgB,OAAQ,EAAQ,cAAe,IAC9C,OAGV,CAEA,SAAS,GAAgB,QACvB,CAAM,eACN,CAAa,CAId,EACC,IAAM,EAAS,EAAO,cAAc,EAAI,EAClC,EAAa,EAAgB,EAAI,KAAK,GAAG,CAAC,EAAI,EAAS,EAAiB,KAAO,EAErF,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CACC,cAAa,CAAC,cAAc,EAAE,EAAO,KAAK,CAAA,CAAE,CAC5C,UAAU,yGAEV,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,UAAU,wCACjB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,uDAA8C,aAC9D,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,sEACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,UAAU,mCACV,MAAO,CAAE,MAAO,CAAA,EAAG,KAAK,GAAG,CAAC,EAAY,KAAK,CAAC,CAAC,AAAC,MAGpD,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,6EACb,GAAe,OAIxB,CAEA,SAAS,GAAc,aACrB,CAAW,aACX,CAAW,kBACX,CAAgB,mBAChB,CAAiB,cACjB,CAAY,CAOb,EACC,GAAM,CAAE,GAAC,CAAE,CAAG,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,OACvB,EAAc,EAAmB,EACvC,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CACC,cAAY,mBACZ,UAAU,+EAEV,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,qFAA4E,YAG3F,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,6CACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,GAAA,KAAK,CACX,MAAO,EAAE,yBACT,MAAO,GAAe,KAExB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,GAAA,KAAK,CACX,MAAO,EAAE,oBACT,MAAO,EAAc,EAAI,GAAe,GAAe,QAEzD,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,GAAA,KAAK,CACX,MAAM,aACN,MACE,EAAc,EACV,GAAe,EAAc,GAC7B,GAAe,KAGvB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,GACN,MAAO,EAAE,oBACT,MAAO,EAAe,EAAI,GAAW,GAAgB,QAEvD,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,6CACb,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,kEACd,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,GAAG,CAAA,CAAC,UAAU,uBAAuB,YAGvC,EAAc,EACb,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,2DACd,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,UAAM,GAAa,KACpB,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CACC,UAAU,wDACV,MAAM,yCAEN,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,sCACd,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAgB,UAAU,qCAC1B,GAAa,MAEhB,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,sCACd,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAgB,UAAU,wCAC1B,GAAa,YAKpB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,gEAAuD,gBAMnF,CAEA,SAAS,GAAY,CACnB,KAAM,CAAI,CACV,OAAK,CACL,OAAK,WACL,EAAY,EAAE,CAMf,EACC,IAAM,EAAiB,QAAV,EACb,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAW,CAAC,sBAAsB,EAAE,EAAA,CAAW,WAClD,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,kEACd,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAK,UAAU,uBACf,KAEH,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAW,CAAC,qBAAqB,EAAE,EAAO,kCAAoC,GAAA,CAAI,UACrF,MAIT,CE3yBA,IAAA,GAAA,EAAA,CAAA,CAAA,OAAA,GAAA,EAAA,CAAA,CAAA,wUkBAyE,CAAA,CAAA,CAAA,CAAA,AAAK,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAU,CAAA,qBAC9D,OAAA,mCAAqD,CFAL,AEAK,CAAA,AFAL,CEAK,KAAA,CAAU,CAAA,mboB8CnF,GACJ,qGAEI,GACJ,sGAEK,SAAS,GAAa,CAAW,EACtC,IAAM,EAAQ,EAAI,KAAK,CAAC,IAExB,GAAI,CAAC,EACH,KADU,CACH,CACL,UAAW,KACX,MAAO,KACP,MAAO,KACP,MAAO,KACP,IAAK,MACL,QAAS,MACT,CACF,EAGF,GAAM,EAAG,EAAW,EAAQ,EAAQ,EAAQ,EAAK,CAAG,EAQhD,EAAuB,KACvB,EAAuB,KACvB,EAAuB,KACvB,EAAU,GAAQ,GAEtB,GAAc,MAAV,GAA4B,AAAV,MAAgB,EAEpC,GAAI,EAAO,QAAQ,CAAC,KAAM,CAExB,GAAM,CAAC,EAAW,EAAU,CAAG,EAAO,KAAK,CAAC,KAC5C,EAAQ,EACR,EAAQ,GAAa,KAErB,EAAU,CAAC,CAAC,EAAE,EAAO,EAAE,EAAE,GAAQ,GAAA,CACnC,AADuC,MAGrC,CAFK,CAEG,EACR,EAAQ,EACR,EAAQ,GAAU,UAEf,GAAc,MAAV,AAAgB,EAEzB,GAAI,EAAO,QAAQ,CAAC,KAAM,CACxB,GAAM,CAAC,EAAW,EAAU,CAAG,EAAO,KAAK,CAAC,KAC5C,EAAQ,EACR,EAAQ,GAAa,IACvB,MACE,CADK,CACG,EAKZ,IAAM,EAAW,EAAQ,KAAK,CAAC,IAC3B,EAAmB,OAOvB,OALI,IACF,EAAM,CAAQ,CAAC,EADH,AACK,CAAC,WAAW,GAC7B,EAAU,CAAQ,CAAC,EAAE,EAGhB,CACL,UAAW,GAAa,WACxB,QACA,QACA,MACA,EACA,QAAS,EAAQ,IAAI,OACrB,CACF,CACF,CvClGO,SAAS,GAAe,SAAE,CAAO,CAAuB,EAC7D,IAAM,EAAQ,CAAA,EAAA,EAAA,OAAA,AAAO,EAAC,IuCuJtB,AvCvJ4B,EuCwJrB,AvCxJqC,EuCuJxC,AAED,CAFE,IAEG,CAAC,IAFK,EAGX,MAAM,CAAC,AAAC,GAAS,EAAK,IAAI,GAAG,MAAM,CAAG,GACtC,GAAG,CAAC,IAJc,EAAE,CvCvJ+B,CAAC,EAAQ,SAE/D,AAAqB,GAAG,CAApB,EAAM,MAAM,CAAe,KAG7B,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,yBACZ,EAAM,GAAG,CAAC,CAAC,EAAM,IAChB,AACA,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAmB,KAAM,GAAT,KAIzB,CAMA,SAAS,GAAW,MAAE,CAAI,CAA2B,EACnD,OAAQ,EAAK,GAAG,EACd,IAAK,OACH,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAY,CAd8E,IAcxE,GAC5B,KAAK,cACH,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAc,KAAM,GAC9B,KAAK,OACL,IAAK,QACH,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAQ,KAAM,GACxB,KAAK,SACH,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,KAAM,GAC1B,KAAK,SACL,IAAK,OACH,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,KAAM,GAC1B,KAAK,MACH,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,KAAM,GAC3B,KAAK,OACH,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAc,KAAM,GAC9B,KAAK,SACL,IAAK,QAML,IAAK,OALH,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAQ,KAAM,GACxB,KAAK,QACH,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAS,KAAM,GACzB,KAAK,SACH,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,KAAM,GAG1B,KAAK,IAEH,MAAO,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAO,KAAM,GACzB,CACF,CAMA,SAAS,GAAU,OAAE,CAAK,CAA4B,EACpD,GAAI,CAAC,EAAO,OAAO,KAEnB,IAAM,EAAO,EAAM,OAAO,CAAC,OAAQ,IAAI,OAAO,CAAC,IAAK,IAC9C,EAAQ,EAAK,KAAK,CAAC,KACnB,EAAU,EAAM,MAAM,EAAI,EAAI,CAAA,EAAG,CAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAA,CAAE,CAAG,EAC9E,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,wEAAgE,GAEpF,CAEA,SAAS,GAAW,OAAE,CAAK,CAA4B,SACrD,AAAK,EAEH,CAAA,CAFE,CAEF,EAFU,AAEV,GAAA,EAAC,OAAA,CACC,UAAU,gHACV,MAAO,WAEN,IANc,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,iBASrC,CAMA,SAAS,GAAY,MAAE,CAAI,CAA2B,cAC9C,CAAE,UAAQ,CAAE,MAAI,CAAE,CuCyBpB,AAAa,CAAC,CvCzBS,EuCyBN,EADf,EAAW,CADW,EvCvBa,EAAK,GuCuBH,IvCvBU,EuCwB5B,OAAO,CAAC,MAExB,CAAE,SAAU,EAAS,KAAM,EAAG,EAEhC,CACL,SAAU,EAAQ,KAAK,CAAC,EAAG,GAC3B,KAAM,EAAQ,KAAK,CAAC,EAAW,EACjC,EvC5BM,EAAS,AA+BjB,SAAS,AAAc,CAAgB,CAAE,CAAY,EACnD,GAAI,CACF,IAAM,EAAS,KAAK,KAAK,CAAC,GAC1B,GAAiB,SAAb,GAAuB,EAAO,SAAS,EAC1B,UAAb,GAAwB,EAAO,SAAS,EAAE,AAC7B,OADoC,EACjD,GAAuB,EADiC,AAC1B,SADmC,AAC1B,CAFE,CAEA,MAFO,CAEA,CAFO,MAEA,GAFS,CAGpE,GAAiB,EADmD,OAChE,GAAuB,EAAO,OAAO,EACxB,SAAb,GAAuB,EAAO,OAAO,CADE,CACA,MADO,CACA,CADO,MACA,CADO,CAEhE,GAAiB,EAD+C,OAC5D,GAAuB,EAAO,OAAO,CACvC,CADyC,MAClC,EAAO,OAAO,CAEvB,GAAiB,SAAb,GAAuB,EAAO,WAAW,CAAE,OAAO,EAAO,WAAW,AAC1E,CAAE,KAAM,CAEN,GAAI,EAAK,MAAM,CAAG,EAAG,OAAO,CAC9B,CACA,OAAO,IACT,EAhD+B,EAAU,GAEvC,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,+GACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,MAAO,EAAK,SAAS,GAChC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,MAAO,EAAK,KAAK,GAC7B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oDACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAS,SAAU,IACpB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,sEACb,IAEF,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,qEACb,IAED,UAIZ,CAEA,SAAS,GAAS,UAAE,CAAQ,CAAwB,EAClD,IAAM,EAAQ,EAAS,WAAW,SAClC,AAAI,AAAU,QAAQ,GAAO,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,QAAQ,CAAA,CAAC,UAAU,4CAC7C,AAAU,YAAU,AAAU,YAAoB,QACpD,CAD0C,EACnC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,QAAQ,CAAA,CAAC,UAAU,4CACf,UAAV,GAA+B,QACjC,CADuB,EAChB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAS,UAAU,4CACtB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,QAAQ,CAAA,CAAC,UAAU,2CAC7B,CAqBA,SAAS,GAAQ,MAAE,CAAI,CAA2B,EAChD,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mFACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,MAAO,EAAK,SAAS,GAChC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,MAAO,EAAK,KAAK,GAC7B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oDACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,aAAa,CAAA,CAAC,UAAU,0CACzB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,8DAAsD,EAAK,OAAO,QAI1F,CAEA,SAAS,GAAU,MAAE,CAAI,CAA2B,MuCzBjB,OAAe,CAE1C,EvCwBA,OAAE,CAAK,CAAE,EuCzBT,CvCyBY,CuCzBC,GvCyBkB,EAAK,OAAO,EuCzBtB,KAAK,CAAC,oBACZ,EAAQ,KAAK,CAAC,iBAC5B,CACL,MAAO,EAAa,SAAS,CAAU,CAAC,EAAE,CAAE,IAAM,EAClD,UAAW,EAAe,CAAY,CAAC,EAAE,CAAG,IAC9C,GvCqBA,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mFACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,MAAO,EAAK,SAAS,GAChC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,MAAO,EAAK,KAAK,GAC7B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oDACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,UAAU,6CACvB,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,uEAA6D,WAClE,EAAM,cAAc,GAAG,iBAK1C,CAEA,SAAS,GAAU,MAAE,CAAI,CAA2B,EAClD,IuCzBM,EvCyBA,aAAE,CAAW,cAAE,CAAY,CAAE,GAAG,CuCzBxB,AvCyB2C,EAAK,OAAO,CuCzB/C,KAAK,CAAC,mCAErB,CACL,YAAa,SAAS,CAAK,CAAC,EAAE,CAAE,IAChC,aAAc,SAAS,CAAK,CAAC,EAAE,CAAE,GACnC,EAJmB,CAAE,YAAa,EAAG,aAAc,CAAE,EvCyBrD,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mFACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,MAAO,EAAK,SAAS,GAChC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,MAAO,EAAK,KAAK,GAC7B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oDACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAM,UAAU,2CACjB,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,0CACd,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,8CAAsC,EAAY,cAAc,KAC/E,SACD,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,8CACb,EAAa,cAAc,KAE7B,eAKX,CAEA,SAAS,GAAU,CAAE,MAAI,CAA2B,EAClD,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,kHACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,MAAO,EAAK,SAAS,GAChC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,MAAO,EAAK,KAAK,GAC7B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oDACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAO,UAAU,0CAClB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,+DAAuD,EAAK,OAAO,QAI3F,CAEA,SAAS,GAAc,MAAE,CAAI,CAA2B,EACtD,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,iFACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,MAAO,EAAK,SAAS,GAChC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,MAAO,EAAK,KAAK,GAC7B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oDACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,UAAU,4CACtB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,yEACb,EAAK,OAAO,QAKvB,CAEA,SAAS,GAAW,MAAE,CAAI,CAA2B,EACnD,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mFACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,MAAO,EAAK,SAAS,GAChC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,MAAO,EAAK,KAAK,GAC7B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oDACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,IAAI,CAAA,CAAC,UAAU,0CAChB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,gFACb,EAAK,OAAO,QAKvB,CAEA,SAAS,GAAc,MAAE,CAAI,CAA2B,EACtD,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mFACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,MAAO,EAAK,SAAS,GAChC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,MAAO,EAAK,KAAK,GAC7B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oDACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAS,UAAU,4CACpB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,0EACb,EAAK,OAAO,QAKvB,CAEA,SAAS,GAAS,MAAE,CAAI,CAA2B,EACjD,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,gHACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,MAAO,EAAK,SAAS,GAChC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,MAAO,EAAK,KAAK,GAC7B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oDACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,WAAW,CAAA,CAAC,UAAU,yCACvB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,gFACb,EAAK,OAAO,QAKvB,CAEA,SAAS,GAAQ,MAAE,CAAI,CAA2B,EAChD,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mFACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAU,MAAO,EAAK,SAAS,GAChC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAW,MAAO,EAAK,KAAK,GAC7B,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,2DAAmD,EAAK,OAAO,KAGrF,CAEA,SAAS,GAAO,MAAE,CAAI,CAA2B,EAC/C,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,uBACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,wFACb,EAAK,GAAG,IAIjB,CCtSO,SAAS,GAAO,SAAE,CAAO,CAAE,aAAW,CAAE,OAAK,CAAe,EACjE,GAAM,CAAE,GAAC,CAAE,CAAG,CAAA,EAAA,EAAA,cAAc,AAAd,EAAe,OACvB,EAAe,CAAA,EAAA,EAAA,MAAA,AAAM,EAAiB,MACtC,CAAC,EAAY,EAAc,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACvC,CAAC,EAAU,EAAY,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAW,cAE7C,EAAe,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,KAC/B,IAAM,EAAK,EAAa,OACxB,AAD+B,CAC1B,GAEL,AAFI,CAAK,CACU,EAAG,UACR,EADoB,CAAG,EAAG,SAAS,CAAG,EAAG,YAAY,CAAG,GAExE,EAAG,EAAE,EAEC,EAAe,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,KAC/B,IAAM,EAAK,EAAa,OAAO,CAC1B,IAAI,AACT,EAAG,SAAS,CAAG,EAAG,YAAY,CAC9B,GAAc,GAChB,EAAG,EAAE,QASL,CANA,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACJ,GAAc,EAAa,OAAO,EAAE,CACtC,EAAa,OAAO,CAAC,SAAS,CAAG,EAAa,OAAO,CAAC,YAAA,AAAY,CAEtE,EAAG,CAAC,EAAS,EAAW,EAEpB,GAEA,CAAA,EAAA,CAFO,CAEP,IAAA,EAAC,MAAA,CAAI,UAAU,6DACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,WAAW,CAAA,CAAC,UAAU,qBACvB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,UAAM,OAKR,EAaH,CAAA,EAAA,EAAA,EAbY,EAaZ,EAAC,MAAA,CAAI,UAAU,uBAAuB,cAAY,oBAEhD,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,yDACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CACC,UAAW,CAAC,qBAAqB,EAAE,EAAc,iBAAmB,cAAA,CAAe,GAErF,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,yCACb,EAAc,OAAS,iBAI1B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,4CACb,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM,EAAY,cAC3B,UAAW,CAAC,8BAA8B,EAC3B,eAAb,EACI,2BACA,8CAAA,CACJ,CACF,MAAO,EAAE,kCAET,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,QAAQ,CAAA,CAAC,UAAU,kBAEtB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM,EAAY,OAC3B,UAAW,CAAC,8BAA8B,EAC3B,QAAb,EACI,2BACA,8CAAA,CACJ,CACF,MAAO,EAAE,2BAET,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,IAAI,CAAA,CAAC,UAAU,kBAGjB,AAAC,EASE,KARF,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,EACT,UAAU,6FAEV,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,SAAS,CAAA,CAAC,UAAU,YAAY,0BAQzC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,IAAK,EACL,SAAU,EACV,UAAW,CAAC,uBAAuB,EACpB,QAAb,EACI,gGACA,gBAAA,CACJ,UAEY,eAAb,EAA4B,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAe,QAAS,IAAc,OAvEtE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,gEACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,QAAQ,CAAA,CAAC,UAAU,kCACpB,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yCAAiC,EAAE,wBAC/C,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yCAAgC,4BAC3C,OAsEZ,wPuBxHoE,CAAU,CAAA,GtBJ9E,IAAA,GAAA,EAAA,CAAA,CAAA,OAAA,GAAA,EAAA,CAAA,CAAA,6CcqBuD,2CArBN,IAAA,UAAe,iDACT,+DACI,sEAExD,gDAAoD,CAAA,AIYR,AMAN,AHZQ,ACAK,ACYb,CDZa,ACYb,ACAA,ANAgB,AJZF,EAAA,UAAe,CQAF,ACYL,ACAA,CFZK,AEYK,ADAA,CCAA,AFZL,ACYK,CDZL,QRCpD,iCAAkC,CEYA,ACAR,AHZQ,GAAK,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAU,CAAA,UACpD,EAAA,wCAA6C,UAAU,iDACd,CYAH,AIAH,AhBAM,AMA7C,AOAuC,ACAA,APYN,AQZM,CRYN,ADZjC,AWAuC,ALAG,AZAG,EAAA,adShD,GASF,CACF,KAAM,CACJ,KAAM,GAAA,MAAM,CACZ,WAAY,wBACZ,YAAa,gBACb,MAAO,MACT,EACA,mBAAoB,CAClB,KAAM,EAAA,YAAY,CAClB,WAAY,gBACZ,YAAa,kBACb,UAAU,EACV,MAAO,aACT,EACA,KAAM,CACJ,KAAM,EAAA,KAAK,CACX,WAAY,mBACZ,YAAa,qBACb,MAAO,MACT,EACA,OAAQ,CACN,KAAM,GAAA,GAAG,CACT,WAAY,iBACZ,YAAa,mBACb,MAAO,QACT,CACF,EAEM,GAAoB,CACxB,KAAM,GAAA,MAAM,CACZ,WAAY,wBACZ,YAAa,gBACb,MAAO,SACT,EAEO,SAAS,GAAiB,OAAE,CAAK,CAAyB,EAC/D,GAAM,GAAE,CAAC,CAAE,CAAG,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,cAC7B,AAAqB,GAAG,CAApB,EAAM,MAAM,CAEZ,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,gEACb,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yCAAiC,EAAE,mCAMpD,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,cAAY,qBAAqB,UAAU,gCAC9C,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAgB,MAAO,IACxB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,cAAY,qBAAqB,UAAU,+BAC7C,EAAM,GAAG,CAAC,CAAC,EAAM,IAChB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAA6C,KAAM,EAAM,MAAO,GAAlD,EAAK,KAAK,EAAI,CAAC,KAAK,EAAE,EAAA,CAAO,OAKtD,CAIA,SAAS,GAAgB,OAAE,CAAK,CAA6B,EAC3D,GAAM,GAAE,CAAC,CAAE,CAAG,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,OACvB,EAAS,CAAA,EAAA,EAAA,OAAA,AAAO,EAAC,KACrB,IAAM,EAAO,EAAM,MAAM,CAAC,AAAC,GAAkB,SAAZ,EAAE,KAAK,EAAa,MAAM,CACrD,EAAM,EAAM,MAAM,CAAC,AAAC,GAAkB,qBAAZ,EAAE,KAAK,EAAyB,MAAM,CAChE,EAAS,EAAM,MAAM,CAAC,AAAC,GAAM,AAAY,aAAV,KAAK,EAAe,MAAM,CACzD,EAAO,EAAM,MAAM,CACvB,AAAC,GAAkB,SAAZ,EAAE,KAAK,EAA2B,qBAAZ,EAAE,KAAK,EAAuC,WAAZ,EAAE,KAAK,EACtE,MAAM,CACF,EAAQ,EAAM,MAAM,CACpB,EAAU,EAAQ,EAAI,KAAK,KAAK,CAAE,EAAO,EAAS,KAAO,EAC/D,MAAO,MAAE,MAAM,EAAK,cAAQ,QAAM,UAAO,CAAQ,CACnD,EAAG,CAAC,EAAM,EAEV,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,cAAY,wBAAwB,UAAU,gCACjD,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8CACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,qDAA4C,kBAC5D,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,0CACb,EAAO,IAAI,CAAC,OAAK,EAAO,KAAK,CAAC,cAGnC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,4DACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,cAAY,oBACZ,UAAU,oDACV,MAAO,CAAE,MAAO,CAAA,EAAG,EAAO,OAAO,CAAC,CAAC,CAAC,AAAC,MAGzC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,iCACZ,EAAO,IAAI,CAAG,EACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,EAAA,KAAK,CACX,MAAO,EAAE,qBACT,MAAO,EAAO,IAAI,CAClB,UAAU,qBAEV,KACH,EAAO,GAAG,CAAG,EACZ,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,EAAA,YAAY,CAClB,MAAO,EAAE,2BACT,MAAO,EAAO,GAAG,CACjB,UAAU,kBAEV,KACH,EAAO,MAAM,CAAG,EACf,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,GAAA,GAAG,CACT,MAAO,EAAE,uBACT,MAAO,EAAO,MAAM,CACpB,UAAU,mBAEV,KACH,EAAO,IAAI,CAAG,EACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,GAAA,MAAM,CACZ,MAAO,EAAE,qBACT,MAAO,EAAO,IAAI,CAClB,UAAU,0BAEV,UAIZ,CAEA,SAAS,GAAS,CAChB,KAAM,CAAI,OACV,CAAK,OACL,CAAK,CACL,WAAS,CAMV,EACC,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EAAC,kCAAmC,aACrD,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAK,UAAU,YACf,EAAM,IAAE,IAGf,CAIA,SAAS,GAAS,MAAE,CAAI,OAAE,CAAK,CAAyC,EACtE,GAAM,CAAC,EAAU,EAAY,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACnC,EAAS,EAAe,CAAC,EAAK,KAAK,CAAC,EAAI,GACxC,EAAO,EAAO,IAAI,CAClB,EAAa,EAAK,WAAW,CAAC,MAAM,CAAG,EAEvC,EAAe,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,KAC3B,GACF,EAAY,AAAC,GAAS,CAAC,EAE3B,CAHkB,CAGf,CAAC,EAAW,EAEf,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,cAAa,CAAC,UAAU,EAAE,EAAA,CAAO,CAAE,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EAAC,oBAAqB,EAAO,WAAW,YAC3F,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,EACT,SAAU,CAAC,EACX,UAAW,CAAA,EAAA,EAAA,EAAE,AAAF,EACT,uDACA,GAAc,gEAGhB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,0BACA,EAAO,UAAU,CACjB,EAAO,QAAQ,EAAI,kBAGvB,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,iDACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EAAC,sBAAuB,EAAO,UAAU,WAAI,EAAK,KAAK,GACzE,EAAK,WAAW,CACf,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,yCAAiC,EAAK,WAAW,GAC/D,QAEL,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CACX,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,qEACA,GAAY,eAGd,QAGL,GAAY,EACX,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,gCACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,+BACZ,EAAK,WAAW,CAAC,GAAG,CAAC,CAAC,EAAM,IAC3B,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAiD,KAAM,GAApC,EAAK,IAAI,EAAI,CAAC,GAAG,EAAE,EAAA,CAAS,OAIpD,OAGV,CAIA,SAAS,GAAc,MAAE,CAAI,CAA4B,EACvD,IAAM,EAAgB,EAAK,kBAAkB,CAAC,MAAM,CAC9C,EAAmB,EAAK,kBAAkB,CAAC,MAAM,CAAC,AAAC,GAAO,EAAG,QAAQ,EAAE,MAAM,CAC7E,EAAc,EAAgB,GAAK,IAAqB,EAE9D,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,cAAY,cAAc,UAAU,kCACvC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mCACZ,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,UAAU,iDAEvB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAa,UAAU,sDAE1B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,0CACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,+BAAuB,EAAK,IAAI,GAC/C,EAAK,WAAW,CACf,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,6CAAqC,EAAK,WAAW,GACnE,QAEL,EAAgB,EACf,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,+DACb,EAAiB,IAAE,KAEpB,QAEL,EAAgB,EACf,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,sCACZ,EAAK,kBAAkB,CAAC,GAAG,CAAC,CAAC,EAAI,IAChC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAA+D,UAAW,GAA9C,EAAG,WAAW,EAAI,CAAC,GAAG,EAAE,EAAA,CAAS,KAGhE,OAGV,CAIA,SAAS,GAAuB,WAC9B,CAAS,CAGV,EACC,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,cAAY,uBAAuB,UAAU,qCAC/C,EAAU,QAAQ,CACjB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,KAAK,CAAA,CAAC,UAAU,6CAEjB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,MAAM,CAAA,CAAC,UAAU,kDAEpB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAE,AAAF,EACT,cACA,EAAU,QAAQ,CAAG,qCAAuC,4BAG7D,EAAU,WAAW,KAI9B,CC3RA,IAAM,GAA+C,CACnD,aAAc,+DACd,sBAAuB,kEACvB,MAAO,iEACT,EAEO,SAAS,GAAQ,CAAE,MAAI,SAAE,CAAO,OAAE,CAAK,CAAgB,SAC5D,AAAI,EAEA,CAAA,EAAA,EAAA,EAFS,CAET,EAAC,MAAA,CAAI,cAAY,mBAAmB,UAAU,gDAC5C,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,YAAY,CAAA,CAAC,UAAU,iDAK1B,EAEA,CAAA,EAAA,EAAA,AAFO,IAEP,EAAC,MAAA,CAAI,UAAU,6DACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,WAAW,CAAA,CAAC,UAAU,qBACvB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,UAAM,OAKR,EAUH,CAAA,EAAA,CAVS,CAUT,IAAA,EAAC,MAAA,CAAI,UAAU,oCACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oCACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,qDAA4C,eAC5D,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CACJ,UACE,EAAoB,CAAC,EAAK,KAAK,CAAC,EAAI,uDAGrC,EAAK,KAAK,MAGd,EAAK,QAAQ,CACZ,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,gCACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,qDAA4C,aAC5D,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,mCAA2B,EAAK,QAAQ,MAErD,KACJ,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAiB,MAAO,EAAK,KAAK,MAzBnC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,gEACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAS,UAAU,kCACpB,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yCAAgC,0BA0BrD,CGjBA,IAAA,GAAA,EAAA,CAAA,CAAA,ODxBA,SAAS,KACP,MAAO,CAAE,KAAM,KAAM,SAAS,EAAO,MAAO,IAAK,CACnD,CCwCA,IAAM,GAAqB,CACzB,CAAE,IAAK,WAAY,MAAO,WAAY,KAAM,EAAA,eAAe,AAAC,EAC5D,CAAE,IAAK,WAAY,MAAO,WAAY,KAAM,EAAA,QAAQ,AAAC,EACrD,CAAE,IAAK,MAAO,MAAO,MAAO,KAAM,CAAW,EAC7C,CAAE,IAAK,OAAQ,MAAO,OAAQ,KAAM,CAAI,EACxC,CAAE,IAAK,aAAc,MAAO,aAAc,KAAM,CAAU,EAC1D,CAAE,IAAK,iBAAkB,MAAO,iBAAkB,KAAM,EAAA,GAAG,AAAC,EAC5D,CAAE,IAAK,oBAAqB,MAAO,UAAW,KAAM,EAAA,OAAO,AAAC,EAC5D,CAAE,IAAK,eAAgB,MAAO,eAAgB,KAAM,CAAS,EAC7D,CAAE,IAAK,OAAQ,MAAO,OAAQ,KAAM,EAAA,aAAa,AAAC,EACnD,CAmHK,GAAwC,CAC5C,SAbF,CAaY,cAbG,AAAc,CAAiB,EAC5C,IAAM,EAAS,MAAM,GAAuB,GAC5C,GAAI,UAAW,EAAQ,MAAM,AAAI,MAAM,EAAO,KAAK,EACnD,MAAO,CAAE,QAAS,EAAO,OAAO,CAAE,kBAAmB,EAAO,iBAAiB,AAAC,CAChF,EAUE,KARF,CAQQ,cARO,AAAU,CAAiB,EACxC,IAAM,EAAS,MAAM,GAAe,GACpC,GAAI,UAAW,EAAQ,MAAM,AAAI,MAAM,EAAO,KAAK,EACnD,OAAO,EAAO,IAAI,AACpB,CAKA,EAEO,SAAS,GAAkB,aAChC,CAAW,eACX,CAAa,aACb,CAAW,CACX,WAAS,YACT,CAAU,QACV,CAAM,SACN,CAAO,eACP,CAAa,CACb,aAAW,cACX,CAAY,aACZ,CAAW,cACX,CAAY,UACZ,CAAQ,eACR,CAAa,CACb,cAAY,CACZ,eAAa,CACb,aAAW,WACX,CAAS,gBACT,CAAc,eACd,CAAa,gBACb,CAAc,YACd,CAAU,aACV,CAAW,WACX,CAAS,eACT,CAAa,gBACb,CAAc,eACd,CAAa,aACb,CAAW,aACX,CAAW,CACX,WAAS,mBACT,CAAiB,WACjB,CAAS,yBACT,GAA0B,CAAI,SAC9B,CAAO,QACP,CAAM,CACN,SAAO,CACgB,EACvB,MAAM,EAAW,CAAA,EAAA,EAAA,WAAA,AAAW,IAEtB,EAAc,CAAA,EAAA,EAAA,OAAA,AAAO,EACzB,IAAM,CA9JV,SAAS,AACP,CAAqB,CACrB,GAA0B,CAAI,EAE9B,IAAM,EAAwB,CAAC,WAAY,WAAW,CA2BtD,OAzBI,EAAK,WAAW,EAAE,AACpB,EAAK,IAAI,CAAC,OAGR,EAAK,OAAO,EAAE,AAChB,EAAK,IAAI,CAAC,QAEW,iBAAnB,EAAK,SAAS,EAAsC,mBAAmB,CAAlC,EAAK,KAAK,EACjD,EAAK,IAAI,CAAC,cAEW,mBAAnB,EAAK,SAAS,EAAwC,mBAAmB,CAAlC,EAAK,KAAK,EACnD,EAAK,IAAI,CAAC,iBAAkB,qBAEP,WAAnB,CAA+B,CAA1B,SAAS,GAAiC,AAAf,sBAAK,KAAK,EAAyC,UAAf,EAAK,KAAK,AAAK,CAAO,EAC5F,CAD+F,CAC1F,IAAI,CAAC,gBAEW,aAAnB,EAAK,SAAS,EAAmB,EAAK,EAAE,EAAE,AAC5C,EAAK,IAAI,CAAC,gBAIR,GACF,EAAK,IAAI,CAAC,QAGL,EACT,EA8H6B,EAAa,CAnIX,EAoI3B,CAAC,EAAa,EAAwB,EAElC,EAAiB,CAAA,EAAA,EAAA,OAAA,AAAO,EAC5B,IACE,GAAS,MAAM,CAAE,AAAD,GAAO,EAAY,QAAQ,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,AAAC,GAC7C,iBAAV,EAAE,GAAG,EAAiD,aAA1B,EAAY,SAAS,CAC7C,CAAE,GAAG,CAAC,CAAE,MAAO,eAAgB,EAC/B,GAER,CAAC,EAAa,EAAY,SAAS,CAAC,EAKhC,EAAW,CAAA,EAAA,EAAA,OAAA,AAAO,EAAC,KACvB,IAAM,EAAQ,EAAS,KAAK,CAAC,uBAC7B,OAAO,EAAQ,CAAK,CAAC,EAAE,CAAG,CAC5B,EAAG,CAAC,EAAS,EAGP,EAAmB,CAAA,EAAA,EAAA,OAAA,AAAO,EAAC,IAC/B,AAAI,GAAU,EAAY,QAAQ,CAAC,GAAgB,EAC/C,GAAc,CAD0B,CACd,QAAQ,CAAC,GAAoB,EACpD,QAD6C,GAInD,EAAE,EACC,CAAC,GAAW,GAAa,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,GAIpD,GFtQD,AEsQe,SFtQN,AAAe,CAAoC,EACjE,GAAM,CAAC,EAAS,EAAW,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,IACjC,CAAC,EAAa,EAAe,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACzC,CAAC,EAAO,EAAS,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MAC5C,EAAiB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAqB,MAE5C,EAAU,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,KACtB,EAAe,OAAO,EAAE,CAC1B,EAAe,OAAO,CAAC,KAAK,GAC5B,EAAe,OAAO,CAAG,MAE3B,GAAe,EACjB,EAAG,EAAE,EAmDL,MAjDA,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,GAAI,CAAC,EAAW,CACd,EAAW,IACX,GAAe,GACf,EAAS,MACT,MACF,CAGA,EAAW,IACX,EAAS,MAGT,IAAM,EAAK,IAAI,YAAY,CAAC,4BAA4B,EAAE,EAAA,CAAW,EA8BrE,OA7BA,EAAe,OAAO,CAAG,EAEzB,EAAG,MAAM,CAAG,KACV,GAAe,EACjB,EAEA,EAAG,gBAAgB,CAAC,UAAW,AAAC,IAE9B,EADkC,AACvB,KAD4B,KAAK,CAAC,EAAM,IAAI,EACvC,OAAO,CACzB,GAEA,EAAG,gBAAgB,CAAC,MAAO,AAAC,IAC1B,IAAM,EAA4B,KAAK,KAAK,CAAC,EAAM,IAAI,EACvD,EAAW,AAAC,GAAS,EAAO,EAAK,OAAO,CAC1C,GAEA,EAAG,gBAAgB,CAAC,QAAS,AAAC,IAC5B,GAAI,CACF,IAAM,EAA0B,KAAK,KAAK,CAAC,EAAM,IAAI,EACrD,EAAS,EAAK,KAAK,CACrB,CAAE,KAAM,CACN,EAAS,EAAM,IAAI,CAAG,OAAO,EAAM,IAAI,EAAI,yBAC7C,CACF,GAEA,EAAG,OAAO,CAAG,KACX,GAAe,EACjB,EAEO,KACL,EAAG,KAAK,GACR,EAAe,OAAO,CAAG,IAC3B,CACF,EAAG,CAAC,EAAW,EAAQ,EAEhB,CAAE,sBAAS,EAAa,OAAM,CACvC,EEsMmD,QAAd,GAAsB,EAAY,MAE/D,MAAE,EAAI,CAAE,WAAQ,YAAE,EAAU,CAAE,CAAG,AD1OlC,SAAS,AACd,CAAiB,CACjB,CAAwB,EAExB,IAAM,EAAU,OAAO,IAAI,CAAC,GAEtB,CAAC,EAAW,EAAa,CAAG,CAAA,EAAA,EAAA,QAAQ,AAAR,EAA8B,KAC9D,IAAM,EAAU,CAAC,EACjB,IAAK,IAAM,KAAO,EAChB,CAAO,CAAC,EAAI,CAAG,CADU,IAG3B,OAAO,CACT,GAGM,EAAc,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,GAC3B,EAAY,OAAO,CAAG,EAGtB,IAAM,EAAe,CAAA,EAAA,EAAA,MAAM,AAAN,EAAO,GAC5B,EAAa,OAAO,CAAG,EAGvB,IAAM,EAAa,CAAA,EAAA,EAAA,MAAA,AAAM,GAAC,GAC1B,CAAA,EAAA,EAAA,SAAS,AAAT,EAAU,KACR,EAAW,OAAO,EAAG,EACd,KACL,EAAW,OAAO,EAAG,CACvB,GACC,EAAE,EAGL,IAAM,EAAmB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,GAChC,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACJ,EAAiB,OAAO,GAAK,IAC/B,EAAiB,KADyB,EAClB,CAAG,EAC3B,EAAa,AAAC,IACZ,IAAM,EAAU,CAAC,EACjB,IAAK,IAAM,KAAO,OAAO,IAAI,CAAC,GAC5B,CAAO,CAAC,CADkC,CAC9B,CAAG,KAEjB,OAAO,CACT,GAEJ,EAAG,CAAC,EAAU,EAEd,IAAM,EAAU,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,MAAO,IACjC,IAAM,EAAU,EAAY,OAAO,CAAC,EAAI,CAClC,EAAmB,EAAa,OAAO,CAE7C,GAAK,CAAD,EAKA,EAAW,IALD,GAKQ,EAAE,AACtB,EAAa,AAAC,GACI,AAChB,CADoB,CAAC,EAAI,AACrB,EADuB,OAAS,AACvB,KAAO,EACb,CAAE,GADiB,AACd,CAAI,CAAE,CAAC,EAAI,CAAE,CAAE,GAAG,CAAI,CAAC,EAAI,CAAE,SAAS,EAAM,MAAO,IAAK,CAAE,GAI1E,GAAI,CACF,CANyE,GAMnE,EAAO,MAAM,EAAQ,GACvB,EAAW,OAAO,EAAE,AACtB,EAAa,AAAC,IAAU,CACtB,EADqB,CAClB,CAAI,CACP,CAAC,EAAI,CAAE,MAAE,EAAM,SAAS,EAAO,MAAO,IAAK,CAC7C,CAAC,EAEL,CAAE,MAAO,EAAgB,CACnB,EAAW,OAAO,EACpB,AADsB,EACR,AAAD,IACX,IAAM,EAAU,aAAiB,MAAQ,EAAM,OAAO,CAAG,2BAEnD,EAAe,CAAI,CAAC,EAAI,EAAE,MAAQ,KACxC,MAAO,CACL,GAAG,CAAI,CACP,CAAC,EAAI,CAAE,CAAE,KAAM,EAAc,SAAS,EAAO,MAAO,EAAe,KAAO,CAAQ,CACpF,CACF,EAEJ,EACF,EAAG,EAAE,EAEC,EAAW,CAAA,EAAA,EAAA,WAAW,AAAX,EACf,MAAO,IAEL,IAAM,EAAU,CAAS,CAAC,EAAI,AAC9B,CAAI,GAAW,AAAiB,MAAM,GAAf,IAAI,EAEvB,GAAW,EAAQ,OAAO,EAAE,AAChC,MAAM,EAAQ,EAChB,EACA,CAAC,EAAW,EAAQ,EAUtB,MAAO,CACL,KAAM,WACN,EACA,WAViB,CAAA,EAAA,EAAA,WAAA,AAAW,EAC5B,MAAO,IACL,MAAM,EAAQ,EAChB,EACA,CAAC,EAAQ,CAOX,CACF,EC4HqE,EAAW,IAKxE,GAAoB,CAAA,EAAA,EAAA,MAAA,AAAM,GAAC,GACjC,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,GAAI,CAAC,GAAkB,OAAO,CAAE,OAChC,GAAkB,OAAO,CAAG,GAG5B,IAAM,EAA0B,aAAd,GAA2B,EAAW,CAAA,EAAG,EAAS,CAAC,EAAE,GAAA,CAAW,CAE9E,IAAc,GAChB,OAAO,AADmB,OACZ,CAAC,SAAS,CAAC,KAAM,GAAI,EAEvC,EAAG,CAAC,GAAW,EAAU,EAAS,EAIlC,IAAM,GAAkB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,GAC/B,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,GAAI,GAAgB,OAAO,GAAK,IAChC,GAAgB,OAAO,CAAG,EACtB,GAAkB,OAAO,EAFa,AAEX,OAC/B,CAHkD,AAEX,GACjC,EAAW,EAAS,KAAK,CAAC,KAE1B,EAAU,CALuD,CAK9C,MAAM,EAAI,EAAK,CAAQ,CAAC,EAAE,AAHwB,CAGH,OAClE,EAAW,GAAW,EAAY,QAAQ,CAAC,GAAW,EAAU,WAClE,IAAa,KACf,GAAa,GADa,CAET,aAAb,GAAwC,SAAb,CAAa,GAC1C,AADkD,GACzC,GAGf,EAAG,CAAC,EAAS,EAKb,CALgB,GAKV,GAAkB,CAAA,EAAA,EAAA,MAAA,AAAM,GAAC,GAC/B,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,IAAI,EAP4D,CAO5C,OAAO,EAAE,CAC7B,GAAgB,OAAO,EAAG,EAEtB,CAAC,GAA+B,aAArB,GAAiC,CAC9C,IAAM,EAAY,CAAA,EAAG,EAAS,CAAC,EAAE,EAAA,CAAkB,CAC/C,IAAc,GAChB,OAD0B,AACnB,OAAO,CAAC,YAAY,CAAC,KAAM,GAAI,EAE1C,CAEF,EAAG,EAAE,EAGL,IAAM,GAAmB,CAAA,EAAA,EAAA,MAAA,AAAM,GAAC,GAChC,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACJ,GAAiB,OAAO,EAAE,CAC9B,GAAiB,OAAO,EAAG,GACT,aAAd,IAA0C,SAAd,EAAc,GAAQ,AACpD,GAAS,IAEb,EAAG,CAAC,GAAW,GAAS,EAGxB,IAAM,GAAmB,CAAA,EAAA,EAAA,MAAM,AAAN,EAAO,GAChC,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACJ,GAAiB,OAAO,GAAK,IAC/B,GAAiB,IADyB,GAClB,CAAG,EAC3B,GAAa,YAEjB,EAAG,CAAC,EAAU,EAKd,IAAM,GAAoB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,GACjC,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,GACE,GAAkB,OAAO,GAAK,GAC9B,GACA,EAAY,QAAQ,CAAC,GACrB,CACA,GAAkB,OAAO,CAAG,EAC5B,GAAa,IAET,AAAe,gBAA6B,SAAf,CAAe,GAAQ,AACtD,GAAS,GAGX,IAAM,EAAY,AAAe,eAAa,EAAW,CAAA,EAAG,EAAS,CAAC,EAAE,EAAA,CAAY,CAChF,IAAc,OAAO,QAAQ,CAAC,QAAQ,EAAE,AAC1C,OAAO,OAAO,CAAC,YAAY,CAAC,KAAM,GAAI,EAE1C,CACF,EAAG,CAAC,EAAY,EAAa,EAAU,GAAS,EAIhD,CAAA,EAAA,EAAA,SAAS,AAAT,EAAU,KACH,EAAY,QAAQ,CAAC,MACxB,GAAa,GADuB,SAEhC,OAAO,QAAQ,CAAC,QAAQ,GAAK,GAC/B,OADyC,AAClC,OAAO,CAAC,YAAY,CAAC,KAAM,GAAI,GAG5C,EAAG,CAAC,EAAa,GAAW,EAAS,EAMrC,IAAM,GAAe,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,IAC5B,GAAa,OAAO,CAAG,GACvB,IAAM,GAAkB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,GAE/B,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,GAAI,CAAC,GAAkC,IAArB,EAAU,MAAM,GAE9B,GAAgB,OAAO,CAAG,EAAU,MAAM,EAAE,CAC9C,GAAgB,OAAO,EAAG,EAExB,EAAU,MAAM,EAAI,GAAgB,OAAO,EAAE,AALP,OAO1C,IAAM,EAAY,EAAU,KAAK,CAAC,GAAgB,OAAO,EAIzD,GAHA,GAAgB,OAAO,CAAG,EAAU,MAAM,CAGtC,CADqB,AACpB,EAD8B,IAAI,CAAC,AAAC,GAAM,EAAE,SAAS,GAAK,GACxC,OAGvB,GAAW,YAEX,IAAM,EAAU,GAAa,OAAO,AACpB,QAAQ,EAApB,GACF,GAAW,EAEf,EAAG,CAAC,EAAW,EAAW,GAAW,EAMrC,IAAM,GAAwC,YAAtB,EAAY,KAAK,EAAkB,AAAsB,eAAV,KAAK,CAC5E,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,GAAI,CAAC,GAAiB,OACtB,IAAM,EAAW,YAAY,KAC3B,GAAW,WACb,EAAG,KACH,MAAO,IAAM,cAAc,EAC7B,EAAG,CAAC,GAAiB,GAAW,EAEhC,IAAM,GAAkB,CAAA,EAAA,EAAA,WAAA,AAAW,EACjC,AAAC,IAEC,GAAkB,OAAO,CAAG,GAC5B,OACY,AAAR,MADS,UACa,AAAQ,SAHtB,CAGsB,GAChC,AADwC,KAG5C,EACA,CAAC,CAHY,EAGH,EAGZ,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,wCACb,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,IAAI,CAAA,CACH,MAAO,GACP,cAAe,GACf,UAAU,yCAGV,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,QAAQ,CAAA,CAAC,UAAU,4FACjB,EAAe,GAAG,CAAC,AAAC,IACnB,IAAM,EAAO,EAAI,IAAI,CACrB,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,GAAA,WAAW,CAAA,CAEV,MAAO,EAAI,GAAG,CACd,UAAU,qcAEV,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAK,UAAU,kBACf,EAAI,KAAK,GALL,EAAI,GAAG,CAQlB,KAGF,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,0CAEZ,EACC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CACC,UAAU,0CACV,cAAY,kCAGZ,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,6BACZ,EAAY,QAAQ,CACnB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,GAAG,CAAA,CAAC,UAAU,mCAEf,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAO,UAAU,+CAItB,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,qGACX,IAGF,EAAY,cAAc,CACzB,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,2FACd,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,4CAAmC,MAClD,EAAY,SAAS,CACpB,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CACC,KAAM,EAAY,SAAS,CAC3B,OAAO,SACP,IAAI,sBACJ,UAAU,+DAET,EAAY,cAAc,GAG7B,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,yCACb,EAAY,cAAc,MAKjC,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,kDACd,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,4CAAmC,MACnD,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,+CAKpB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,eAAe,CAAA,CAAC,cAAe,aAC9B,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,+FACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAE,AAAF,EACT,8CACA,GAAA,sBAAsB,CAAC,EAAY,KAAK,CAAC,CAAC,UAAU,YAG/B,YAAtB,EAAY,KAAK,CAChB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAa,KAAK,KAAK,UAAU,cAG1B,CADR,CAAC,AACW,GAAA,sBAAsB,CAAC,EAAY,KAAK,CAAC,CAAC,IAAI,CACjD,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAE,UAAU,uBAGvB,GAAA,sBAAsB,CAAC,EAAY,KAAK,CAAC,CAAC,KAAK,IAG3B,YAAtB,EAAY,KAAK,EAAkB,EAClC,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM,EAAQ,EAAY,SAAS,EAC5C,UAAU,uIACV,cAAY,wCAEZ,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,IAAI,CAAA,CAAC,UAAU,aAAa,YAEP,UAAtB,EAAY,KAAK,EAAgB,EACnC,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM,EAAQ,EAAY,SAAS,EAC5C,UAAU,iIACV,cAAY,wCAEZ,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,SAAS,CAAA,CAAC,UAAU,aAAa,YAEZ,YAAtB,EAAY,KAAK,EAAkB,EACrC,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAM,EAAO,EAAY,SAAS,EAC3C,UAAU,iIACV,cAAY,uCAEZ,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CAAC,UAAU,aAAa,WAE/B,UAGP,EAAY,YAAY,CACvB,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,cAAc,CAAA,CACb,KAAK,SACL,MAAM,MACN,WAAY,EACZ,UAAU,sEACV,QAAS,KACF,UAAU,SAAS,CAAC,SAAS,CAAC,EAAY,YAAY,CAC7D,YAEC,EAAY,YAAY,CACzB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,yDAAgD,uBAIhE,aAIR,KAEH,KAGH,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,MAAM,WAAW,UAAU,uCACtC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,EACN,WAAY,EACZ,YAAa,EACb,UAAW,EACX,cAAe,EACf,eAAgB,EAChB,cAAe,EACf,YAAa,MAIjB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,MAAM,WAAW,UAAU,uCACtC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,QAAU,GAAK,QAAQ,CAAC,IAAI,EAA0B,SAAW,KACjE,QAAS,GAAK,QAAQ,CAAC,OAAO,CAC9B,MAAO,GAAK,QAAQ,CAAC,KAAK,CAC1B,kBAAoB,GAAK,QAAQ,CAAC,IAAI,EAA0B,sBAIpE,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,MAAM,MAAM,UAAU,uCACjC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,QAAS,GAAY,OAAO,CAC5B,YAAa,GAAY,WAAW,CACpC,MAAO,GAAY,KAAK,KAI5B,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,MAAM,OAAO,UAAU,uCAClC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,GAAK,IAAI,CAAC,IAAI,CACpB,QAAS,GAAK,IAAI,CAAC,OAAO,CAC1B,MAAO,GAAK,IAAI,CAAC,KAAK,KAKzB,EAAY,QAAQ,CAAC,cACpB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,MAAM,aAAa,UAAU,6CACvC,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,EACN,WAAY,GAAiB,CAAC,EAC9B,SAAU,IAAgB,IAAM,MAAA,CAAS,AAAhB,CACzB,UAAW,IAAiB,SAAM,CAAA,CAAS,CAAhB,AAC3B,SAAU,EACV,aAAc,EACd,YAAa,EACb,UAAW,EACX,kBAAmB,IAGrB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,gDACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,YAAY,CAAA,CAAC,UAAU,mDAI5B,KAGH,EAAY,QAAQ,CAAC,kBACpB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,MAAM,iBAAiB,UAAU,6CAC3C,EACC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,yCACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,kCACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAqB,KAAM,MAE9B,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,UAAW,IAAkB,SAAM,CAAA,CAAS,CAC5C,CAD4B,QAClB,EACV,aAAc,EACd,YAAa,EACb,UAAW,EACX,kBAAmB,OAIvB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,gDACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,YAAY,CAAA,CAAC,UAAU,mDAI5B,KAGH,EAAY,QAAQ,CAAC,qBACpB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,MAAM,oBAAoB,UAAU,uCAC9B,OAAhB,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,gDACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,YAAY,CAAA,CAAC,UAAU,iDAExB,EACF,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAwB,KAAM,IAE/B,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yDAAgD,sCAK/D,KAGH,EAAY,QAAQ,CAAC,gBACpB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,MAAM,eAAe,UAAU,6CACzC,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,EACN,SAAU,AAA0B,eAAd,SAAS,CAC/B,UAAW,IAAmB,SAAM,CAAA,CAAS,CAC7C,EAD6B,OACnB,EACV,aAAc,EACd,YAAa,EACb,UAAW,EACX,kBAAmB,IAGrB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,gDACZ,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,YAAY,CAAA,CAAC,UAAU,+CAExB,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,2EACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,WAAW,CAAA,CAAC,UAAU,YACvB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,UAAK,yCAMd,KAGH,EAAY,QAAQ,CAAC,QACpB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAC,MAAM,OAAO,UAAU,6DAClC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,OAAO,CAAA,CAAC,UAAW,EAAW,aAAc,EAAY,YAAY,KAErE,SAIZ,CAIA,SAAS,GAAuB,WAC9B,CAAS,CACT,UAAQ,cACR,CAAY,aACZ,CAAW,WACX,CAAS,mBACT,CAAiB,CAQlB,EACC,GAAM,GAAE,CAAC,CAAE,CAAG,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,OAC7B,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,SAAU,EACV,UAAW,EACX,aAAc,EAAE,6BAChB,oBAAoB,+BACpB,aAAc,EACd,YAAa,EACb,UAAW,EACX,kBAAmB,GAGzB,CEjvBA,IAAA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,ODLuT,IAAM,GAAmC,CAAA,EAAA,EAAA,iBAAb,IAAa,AAAqB,EAAC,KAAxB,wCAAqE,EAAA,UAAU,CAAC,KAAK,EAAE,EAAA,gBAAgB,CAAC,iBvB8Ctc,IAAA,GAAA,EAAA,CAAA,CAAA,OkDSO,SAAS,GAAiB,CAAqB,QACpD,AAAuB,iBAAnB,EAAK,SAAS,EAAsC,mBAAmB,CAAlC,EAAK,KAAK,CAA+B,aAC3D,mBAAnB,EAAK,SAAS,EAAyB,AAAe,mBACxD,GAD8C,KAAK,CAC5C,iBACc,WAAnB,CAA+B,CAA1B,SAAS,GAAiC,oBAAf,EAAK,KAAK,EAAyC,UAAf,EAAK,KAAU,AAAL,CAAY,CACrF,EAAP,aACK,UACT,CzB7CO,SAAS,GACd,CAAwB,CACxB,CAAyC,CACzC,CAAoC,CACpC,CAAmB,CACnB,CAAqB,CACrB,CAAmB,EAEnB,GAAM,CAAC,EAAW,EAAa,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GAGrC,EAAe,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,GACtB,EAAa,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,GA2B1B,OA1BA,EAAa,OAAO,CAAG,EACvB,EAAW,OAAO,CAAG,EAErB,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KAER,GADA,EAAW,OAAO,GACd,CAAC,EAAW,OAEhB,IAAI,GAAY,EAchB,OAbA,GAAa,GAEb,EAAQ,GACL,IAAI,CAAC,AAAC,IACD,AAAC,GAAW,EAAa,OAAO,CAAC,EACvC,GACC,KAAK,CAAC,KACD,CAAC,GAAa,GAAc,EAAA,KAAK,CAAC,KAAK,CAAC,EAC9C,GACC,OAAO,CAAC,KACH,AAAC,GAAW,EAAa,GAC/B,GAEK,KACL,EAAY,EACd,CACF,EAAG,CAAC,EAAW,EAAS,EAAc,EAAW,EAE1C,CACT,CCzDuU,IAAM,GAAmC,CAAA,EAAA,EAAA,iBAAb,IAAa,AAAqB,EAAC,KAAxB,wCAAqE,EAAA,UAAU,CAAC,KAAK,EAAE,EAAA,gBAAgB,CAAC,wBEA3I,GAAmC,CAAA,EAAA,EAAA,iBAAb,IAAa,AAAqB,EAAC,KAAxB,wCAAqE,EAAA,UAAU,CAAC,KAAK,EAAE,EAAA,gBAAgB,CAAC,uB9BsB9c,GAAQ,IAAI,iCEuCX,SAAS,AAAoB,CAClC,KAAM,CAAW,QACjB,CAAM,yBACN,GAA0B,CAAI,CACL,M2B3CzB,E3B4CA,I2BzCM,EACA,CAJkB,EACxB,CAQM,EAoBA,E3BmiBF,EAphBE,A2B3CmD,E3B2CpC,CAAA,EAAA,EAAA,OAohBgB,QAphBD,AAAf,IACf,GAAE,CAAC,CAAE,CAAG,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,OACvB,EAAS,CAAA,EAAA,EAAA,SAAA,AAAS,IAClB,EAAc,CAAA,EAAA,EAAA,cAAA,AAAc,EAAC,UAG7B,CAAC,EAAM,EAAQ,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,GAMjC,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,EAAQ,AAAC,GAES,AADhB,YACE,EAAK,IAAI,EACY,YAArB,EAAY,IAAI,EAChB,EAAK,IAAI,CAAC,SAAS,GAAK,EAAY,IAAI,CAAC,SAAS,CAE3C,CADP,AAEE,GAAG,CAAW,CACd,KAAM,CAAE,GAAG,EAAK,IAAI,CAAE,GAAG,EAAY,IAAI,AAAC,CAC5C,EAEK,EAEX,EAAG,CAAC,EAAY,EAEhB,IAAM,EAA4B,YAAd,EAAK,IAAI,CAAiB,EAAK,IAAI,CAAG,KAGpD,QAAE,CAAM,CAAE,CAAG,CAAA,EAAA,EAAA,qBAAA,AAAqB,IAClC,EAAoB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,GAEjC,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KAKR,GAHI,EAAkB,OAAO,CAAG,EAAO,MAAM,EAAE,CAC7C,EAAkB,OAAO,CAAG,GAE1B,CAAC,GAAe,EAAO,MAAM,EAAI,EAAkB,OAAO,CAAE,OAEhE,IAAM,EAAY,EAAO,KAAK,CAAC,EAAkB,OAAO,EAGxD,IAAK,IAAM,KAFX,EAAkB,OAAO,CAAG,EAAO,MAAM,CAEpB,CAAA,EAAA,GAAA,sBAAA,AAAsB,EAAC,IACtC,EAAO,KAD2C,IAClC,GAAK,EAAY,SAAS,EAAE,AAKtB,YAAY,CAAlC,EAAY,KAAK,QAEA,IAAjB,EAAO,KAAK,OAAuC,IAArB,EAAO,SAAS,AAAK,GAAW,AAGhE,EAAS,AAAD,IACN,GAAkB,YAAd,EAAK,IAAI,CAAgB,OAAO,EACpC,IAAM,EAAc,CAClB,GAAG,EAAK,IAAI,CACZ,QAAqB,IAAjB,EAAO,KAAK,EAAkB,CAAE,MAAO,EAAO,KAAM,AAAD,CAAE,CACzD,QAAyB,IAArB,EAAO,SAAS,EAAkB,CAAE,UAAW,EAAO,SAAS,AAAC,CAAC,AACvE,EACA,MAAO,CAAE,GAAG,CAAI,CAAE,KAAM,EAAa,WAAY,GAAiB,EAAa,CACjF,EAGN,EAAG,CAAC,EAAQ,EAAY,EAOxB,IAAM,EAAS,AADE,CAAA,EAAA,EAAA,WAAA,AAAW,IACJ,UAAU,CAAC,eAKb,GAAa,WAAa,O2BvH7B,CAAA,EAAA,EAAA,MAAA,AAAM,E3BuHX,A2BvHY,KACJ,CAAA,EAAA,EAAA,MAAM,AAAN,GAAO,GAGvB,EAAgB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,KAEN,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,UACjC,GAAI,CAAC,GAAa,EAAc,OAAO,CAAE,OACzC,EAAc,OAAO,EAAG,EACxB,IAAM,EAAM,EAAc,OAAO,CACjC,GAAI,CACF,IAAM,EAAO,MAAM,GAAqB,GACxC,GAAI,CAAC,GAED,IAAQ,EAAc,OAAO,CAFtB,CAEwB,MACnC,A3BwGkD,E2BxG1C,AAAC,GAAS,AAyCxB,SAAS,CAAiB,CAAgB,CAAE,CAA0B,EACpE,GAAkB,YAAd,EAAK,IAAI,CAAgB,OAAO,EAEpC,IAAM,EAA0B,CAAE,GAAG,EAAK,IAAI,CAAE,GAAG,CAAS,AAAC,EAKvD,EAAa,EAAO,KAAK,GAAK,EAAK,IAAI,CAAC,KAAK,EAAI,EAAO,SAAS,GAAK,EAAK,IAAI,CAAC,SAAS,CAE/F,MAAO,CACL,GAAG,CAAI,CACP,KAAM,EACN,WAAY,EAAa,GAAiB,GAAU,EAAK,UAAU,AACrE,EACF,EAxDyC,EAAM,GAC3C,CAAE,KAAM,CAER,QAAU,CACR,EAAc,OAAO,EAAG,CAC1B,CACF,EAAG,CAAC,IAAmB,IAKM,CAAA,EAAA,EAAA,MAAA,AAAM,GAAC,GACpC,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,SACO,AAAC,EAAW,OAAO,EAAK,EAAD,AAAsB,OAAO,GAAG,AACpE,EAAqB,OAAO,CAAG,GAG/B,EAAc,OAAO,EAAI,EACzB,EAAc,OAAO,EAAG,EACnB,KAEP,EAAW,OAAO,EACpB,CADuB,CACpB,GAAS,EAAe,EAG3B,CAAA,EAAA,EAAA,SAAS,AAAT,EAAU,KACR,GAAI,CAAC,GAAU,CAAC,EAAW,OAE3B,IAAM,EAAQ,YAAY,KACnB,GACP,EA7DgC,CA6D7B,KAEH,MAAO,IAAM,cAAc,EAC7B,EAAG,GAAS,EAAW,EAAe,E3ByEtC,IAAM,EAAU,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,KAC1B,EAAO,IAAI,CAAC,IACd,EAAG,CAAC,EAAO,EAGL,CAAC,EAAW,GAAa,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,IAGrC,CAAC,GAAS,GAAW,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAA8B,MAC9D,CAAC,GAAe,GAAiB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAyB,CAAC,GACtE,CAAC,GAAsB,GAAwB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAyB,CAAC,GAGpF,CAAC,GAAU,GAAY,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAiC,MAGnE,CAAC,GAAiB,GAAmB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,OAEpD,GAGI,CAAC,GAAW,GAAa,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAyB,MAG7D,CAAC,GAAY,GAAc,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACvC,CAAC,GAAkB,GAAoB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,IAGnD,CAAC,GAAa,GAAe,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GAKzC,GAAkB,CAAA,EAAG,GAAa,UAAU,CAAC,EAAE,GAAa,MAAA,CAAO,CACnE,GAAyB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,IACtC,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACJ,KAAoB,GAAuB,OAAO,EAAE,CACtD,GAAuB,OAAO,CAAG,GACjC,IAAe,GAEnB,EAAG,CAAC,GAAgB,EAGpB,GAAM,CAAC,GAAa,GAAe,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACzC,GAAiB,CAAA,EAAA,EAAA,MAAA,AAAM,GAAC,GAGxB,GAA2B,YAAd,EAAK,IAAI,CAAiB,EAAK,UAAU,MAAG,EAC/D,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,GAAa,GACf,EAAG,CAAC,GAAW,EAQf,IAAM,GAAwB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,GAC/B,GAAe,CAAA,EAAA,EAAA,MAAM,AAAN,EAAO,GAAa,OACnC,GAAmB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,GAAa,WAE3C,IAAa,QAAU,GAAa,OAAO,EAC3C,GAAa,YAAc,GAAiB,OAAA,AAAO,EACnD,EACA,GAAa,OAAO,CAAG,GAAa,MACpC,GAAiB,OAAO,CAAG,GAAa,UACxC,GAAsB,OAAO,EAAI,GAEnC,IAAM,GAAqB,GAAsB,OAAO,CAQlD,GAAe,GAHnB,GAAa,WAIb,CAJ2B,gBAAkB,GAAa,QAAU,kBAChE,EAAY,SAAS,CACrB,KAGJ,EACA,AAAC,IACC,GAAI,EAAO,KAAK,CAAE,YAChB,EAAA,KAAK,CAAC,KAAK,CAAC,EAAO,KAAK,EAG1B,GAAI,EAAO,aAAa,CAAE,CACxB,GAAW,EAAO,aAAa,EAC/B,IAAM,EAAmC,CAAC,EAC1C,IAAK,IAAM,KAAK,EAAO,aAAa,CAAC,SAAS,CAAE,CAC9C,IAAM,EAAc,EAAE,OAAO,CAAC,IAAI,CAAC,AAAC,GAAM,EAAE,WAAW,EACnD,IAAa,CAAQ,CAAC,EAAE,EAAE,CAAC,CAAG,EAAY,EAAA,AAAE,CAClD,CACA,GAAiB,GACjB,GAAwB,EAC1B,CACF,EACA,KACE,GAAiB,CAAC,GAClB,GAAwB,CAAC,GACzB,GAAW,KACb,EACA,+BACA,IAGI,GACJ,GAAa,YAAc,kBAAoB,GAAa,QAAU,kBAClE,EAAY,SAAS,CACrB,KACA,GAAgB,GACpB,GACA,EACA,AAAC,IACK,AAAJ,EAAW,KAAK,CACd,CADgB,CAChB,KAAK,CAAC,KAAK,CAAC,EAAO,KAAK,EAGtB,EAAO,aAAa,EAAE,GAAY,EAAO,aAAa,CAC5D,EACA,IAAM,GAAY,MAClB,gCACA,IAGI,GAAuB,GAC3B,GACA,EACC,AAAD,IACM,EAAO,gBAAgB,EAAE,GAAmB,EAAO,gBAAgB,CACzE,EACA,IAAM,QAAmB,GACzB,OACA,IASI,GAAiB,GALpB,GAAa,WAMd,CAN4B,WACzB,CAAD,EAAc,QAAU,mBAAqB,GAAa,QAAU,OAAA,CAAO,EAC5E,GAAa,YAAc,YAAc,GAAa,GACnD,EAAY,SAAS,CACrB,KAGJ,EACA,AAAC,IACK,AAAJ,UAAe,EACb,EAAA,IADqB,CAChB,CAAC,KAAK,CAAC,EAAO,KAAK,EAG1B,GAAa,EACf,EACA,IAAM,GAAa,MACnB,mCACA,IAII,GAAc,EAAU,IAAI,GAAG,MAAM,CAAG,EACxC,GACJ,GAAa,YAAc,gBAC3B,GAAa,QAAU,mBACvB,OAAO,IAAI,CAAC,IAAsB,IAAI,CAAC,AAAC,GAAM,EAAoB,CAAC,EAAE,GAAK,EAAa,CAAC,EAAE,EAGtF,GAAU,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,KAC1B,GAAa,IACb,GAAiB,CAAE,GAAG,EAAoB,AAAC,EAC7C,EAAG,CAAC,GAAqB,EAEnB,cAAE,EAAY,CAAE,CAAG,CAAA,EAAA,EAAA,qBAAA,AAAqB,EAAC,CAAE,KAAM,EAAQ,QAP/C,IAAe,WAOyC,EAAS,UAAQ,GAInF,GAAe,CAAA,EAAA,EAAA,WAAA,AAAW,EAC9B,MACE,EACA,EACA,EAAkC,EAAE,CACpC,KAEA,GAAK,CAAD,EAAc,WAAW,AAC7B,GAAe,OAAO,EAAG,EACzB,IAAe,GACf,GAAI,CACF,IAAM,EAAkB,EAAY,GAAG,CAAC,AAAC,GAAM,EAAE,IAAI,EAAE,MAAM,CAAC,SACxD,EAAmB,EAAY,MAAM,CAAC,AAAC,GAAM,EAAE,KAAK,EAAE,QACtD,EACJ,EAAiB,MAAM,CAAG,EACtB,CAAA,EAAG,SAAS;AAAA;AAAA;AAAkB,EAAE,EAAiB,GAAG,CAAE,AAAD,GAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,CAAE,IAAI,GAAA,CAAI,EAAE,IAAI,CAAC,MAAA,CAAO,CAC5G,EACA,EAAS,MAAM,EACnB,EAAY,SAAS,CACrB,EACA,GAEF,GAAI,CAAC,EAAO,QAAQ,CAAE,YACpB,EAAA,KAAK,CAAC,KAAK,CAAC,EAAO,KAAK,EAAI,CAAC,iBAAiB,EAAE,EAAM,WAAW,GAAA,CAAI,EAGvE,EAAY,IAAI,GAChB,GAAa,IACb,EAAA,KAAK,CAAC,OAAO,CAAC,CAAA,EAAG,EAAM,0CAA0C,EAAE,EAAO,SAAS,CAAC,CAAC,CAAC,EAClF,EAAO,gBAAgB,EAAE,AAC3B,EAAA,KAAK,CAAC,OAAO,CACX,CAAC,UAAU,EAAE,EAAO,SAAS,CAAC,yEAAyE,CAAC,EAI5G,OAAO,aAAa,CAClB,IAAI,YAAY,6BAA8B,CAC5C,OAAQ,CAAE,UAAW,EAAY,SAAS,AAAC,CAC7C,IAEF,IACA,KACF,QAAU,CACR,GAAe,OAAO,EAAG,EACzB,IAAe,EACjB,EACF,EACA,CAAC,EAAa,EAAS,EAAY,EAG/B,GAAkB,CAAA,EAAA,EAAA,WAAA,AAAW,EACjC,CAAC,EAAkB,IACjB,GAAa,EAAU,eAAgB,EAAa,IAAM,GAAiB,CAAC,IAC9E,CAAC,GAAa,EAEV,GAAmB,CAAA,EAAA,EAAA,WAAA,AAAW,EAClC,CAAC,EAAkB,IACjB,GAAa,EAAU,OAAQ,GACjC,CAAC,GAAa,EAEV,GAAoB,CAAA,EAAA,EAAA,WAAA,AAAW,EACnC,CAAC,EAAkB,IACjB,GAAa,EAAU,QAAS,GAClC,CAAC,GAAa,EAGV,GAAsB,CAAA,EAAA,EAAA,WAAA,AAAW,EACrC,MAAO,IACL,GAAI,CAAC,GAAa,UAAW,OAC7B,IAAM,EAAS,MAAM,EAAe,EAAY,SAAS,CACzD,CAAK,EAAO,CAAR,OAAgB,EAAE,AAItB,GAAa,IACb,EAAA,KAAK,CAAC,OAAO,CAAC,CAAA,EAAG,EAAM,0BAA0B,CAAC,EAElD,OAAO,aAAa,CAClB,IAAI,YAAY,6BAA8B,CAC5C,OAAQ,CAAE,UAAW,EAAY,SAAS,AAAC,CAC7C,IAEF,KAXE,EAAA,KAAK,CAAC,KAAK,CAAC,EAAO,KAAK,EAAI,CAAC,kBAAkB,EAAE,EAAM,WAAW,GAAA,CAAI,CAY1E,EACA,CAAC,EAAa,EAAQ,EAGlB,GAAmB,CAAA,EAAA,EAAA,WAAA,AAAW,EAClC,MAAO,QAED,EADJ,GAAkB,YAAd,EAAK,IAAI,EAAkB,CAAC,EAAa,OAE7C,GAAI,GAAS,CACX,IAAM,EAA+C,EAAE,CACvD,IAAK,GAAM,CAAC,EAAY,EAAS,GAAI,OAAO,OAAO,CAAC,IAAgB,CAClE,IAAM,EAAW,GAAQ,SAAS,CAAC,IAAI,CAAC,AAAC,GAAM,EAAE,EAAE,GAAK,GAClD,EAAS,GAAU,QAAQ,KAAK,AAAC,GAAM,EAAE,EAAE,GAAK,GAClD,GAAY,GACd,EAAkB,GADI,CACA,CAAC,CAAE,WAAY,EAAS,QAAQ,CAAE,eAAgB,EAAO,KAAK,AAAC,EAEzF,CACA,EAAU,CAAE,UAAU,oBAAM,CAAkB,CAChD,CACA,IAAM,EAAS,MAAM,EAAe,EAAY,SAAS,CAAE,EAC3D,CAAK,EAAO,CAAR,OAAgB,EAIpB,AAJsB,GAIT,IACb,EAAA,KAAK,CAAC,OAAO,CAAC,0CAEd,OAAO,aAAa,CAClB,IAAI,YAAY,6BAA8B,CAC5C,OAAQ,CAAE,UAAW,EAAY,SAAS,AAAC,CAC7C,IAEF,GAAiB,CAAC,GAClB,KAZE,EAAA,KAAK,CAAC,KAAK,CAAC,EAAO,KAAK,EAAI,iCAahC,EACA,CAAC,EAAM,EAAa,GAAS,GAAe,EAAQ,EAGhD,GAAoB,CAAA,EAAA,EAAA,WAAW,AAAX,EAAY,IAAM,GAAoB,QAAS,CAAC,GAAoB,EACxF,GAAqB,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,IAAM,GAAoB,SAAU,CAAC,GAAoB,EAE1F,GAAe,CAAA,EAAA,EAAA,WAAA,AAAW,EAC9B,MAAO,EAAmB,EAAmB,EAAyB,KACpE,IAAc,GAKd,GAAoB,IACpB,OAAO,aAAa,CAClB,IAAI,YAAY,qCAAsC,CACpD,OAAQ,WAAE,UAAW,gBAAS,UAAe,CAAQ,CACvD,IAEF,EAAO,IAAI,CAAC,IACd,EACA,CAAC,EAAO,EAGJ,GAAgB,CAAA,EAAA,EAAA,WAAA,AAAW,EAC/B,AAAC,IACC,IAAe,GACf,OAAO,aAAa,CAClB,IAAI,YAAY,sCAAuC,CACrD,OAAQ,WAAE,CAAU,CACtB,IAEF,EAAO,IAAI,CAAC,IACd,EACA,CAAC,EAAO,EAGJ,GAAkB,CAAA,EAAA,EAAA,WAAA,AAAW,EACjC,AAAC,IACC,IAAe,GACf,OAAO,aAAa,CAClB,IAAI,YAAY,wCAAyC,CACvD,OAAQ,WAAE,CAAU,CACtB,IAEF,EAAO,IAAI,CAAC,IACd,EACA,CAAC,EAAO,EAGJ,GAAc,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,MAAO,IACrC,IAAM,EAAS,MAAM,CAAA,EAAA,EAAA,aAAA,AAAa,EAAC,EACnC,CAAI,EAAO,KAAK,CACd,CADgB,CAChB,KAAK,CAAC,KAAK,CAAC,EAAO,KAAK,GAG1B,EAAA,KAAK,CAAC,OAAO,CAAC,sCACd,OAAO,aAAa,CAClB,IAAI,YAAY,6BAA8B,CAC5C,OAAQ,CAAE,WAAU,CACtB,IAEF,EAAQ,AAAC,GACP,AAAkB,WAAW,CAAzB,EAAK,IAAI,CAAuB,EAC7B,CAAE,GAAG,CAAI,CAAE,KAAM,CAAE,GAAG,EAAK,IAAI,CAAE,MAAO,SAAU,CAAE,GAE/D,EAAG,EAAE,EAEC,GAAa,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,MAAO,IACpC,IAAM,EAAS,MAAM,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,EACjC,CAAK,EAAO,CAAR,MAAe,EAAE,AAIrB,EAAA,KAAK,CAAC,OAAO,CAAC,iBACd,EAAQ,AAAC,GACP,AAAI,AAAc,WAAW,GAApB,IAAI,CAAuB,EAC7B,CAAE,GAAG,CAAI,CAAE,KAAM,CAAE,GAAG,EAAK,IAAI,CAAE,MAAO,OAAQ,CAAE,IANzD,EAAA,KAAK,CAAC,KAAK,CAAC,EAAO,KAAK,EAAI,iBAQhC,EAAG,EAAE,EAEC,GAAc,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,MAAO,IACrC,IAAM,EAAS,MAAM,CAAA,EAAA,EAAA,YAAA,AAAY,EAAC,EAClC,CAAI,EAAO,KAAK,CACd,CADgB,CAChB,KAAK,CAAC,KAAK,CAAC,EAAO,KAAK,GAG1B,EAAA,KAAK,CAAC,OAAO,CAAC,mBAEd,EAAQ,AAAC,GACP,AAAkB,WAAW,CAAzB,EAAK,IAAI,CAAuB,EAC7B,CAAE,GAAG,CAAI,CAAE,KAAM,CAAE,GAAG,EAAK,IAAI,CAAE,MAAO,SAAU,CAAE,GAE/D,EAAG,EAAE,EAIC,GACJ,GAAa,gBAAkB,GAAa,OACxC,CACE,UAAW,EAAY,SAAS,CAChC,eAAgB,EAAY,cAAc,CAC1C,OAAQ,EAAY,MAAM,CAC1B,aAAc,EAAY,YAAY,CACtC,SAAU,EAAY,QAAQ,AAChC,EACA,KACA,GAAiB,AwB5flB,SAAS,AAAkB,CAAiC,EACjE,GAAM,CAAC,EAAY,EAAc,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACvC,CAAC,EAAc,EAAgB,CAAG,CAAA,EAAA,EAAA,QAAQ,AAAR,EAAS,IAC3C,CAAC,EAAe,EAAiB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GAC7C,CAAC,EAAc,EAAgB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,IAC3C,CAAC,EAAe,EAAiB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GAC7C,CAAC,EAAU,EAAY,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MAClD,CAAC,EAAY,EAAc,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MACtD,CAAC,EAAa,EAAe,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MACxD,CAAC,EAAY,EAAc,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MACtD,CAAC,EAAa,EAAe,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MAExD,EAAc,CAAA,EAAA,EAAA,MAAM,AAAN,EAA6C,MAC3D,EAAgB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAuC,MAC7D,EAAiB,CAAA,EAAA,EAAA,MAAM,AAAN,EAA6C,MAC9D,EAAgB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAuC,MAC7D,EAAiB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAuC,MAIpE,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,IAAM,EAAO,CAAC,EAAa,EAAe,EAAgB,EAAe,EAAe,CACxF,MAAO,KACL,IAAK,IAAM,KAAO,EACZ,EAAI,CADc,MACP,EAAE,aAAa,EAAI,OAAO,CAE7C,CACF,EAAG,EAAE,EAEL,IAAM,EAAgB,CAAA,EAAA,EAAA,WAAA,AAAW,EAC/B,MACE,EAIA,EACA,EACA,EACA,KAEA,GAAI,AAAC,IAAS,GAGV,EAAS,MAHY,CAGL,EAAE,aAAa,EAAS,OAAO,EAEnD,GAAW,GACX,EAAS,MAET,GAAI,CACF,IAAM,EAAS,MAAM,EAAO,CAC1B,eAAgB,EAAM,cAAc,CACpC,OAAQ,EAAM,MAAM,AACtB,GAEA,GAAI,CAAC,EAAO,OAAO,CAAE,CACnB,IAAM,EAAe,EAAO,KAAK,EAAI,+BACrC,EAAS,GACT,EAAS,OAAO,CAAG,WAAW,IAAM,EAAS,OAAO,GACtD,CACF,CAAE,MAAO,EAAc,CAErB,EADqB,OACZ,MAD2B,MAAQ,EAAI,OAAO,CAAG,gCAE1D,EAAS,OAAO,CAAG,WAAW,IAAM,EAAS,OAAO,GACtD,QAAU,CACR,GAAW,EACb,EACF,EACA,CAAC,EAAM,EAyFT,MAAO,CACL,UAvFoB,CAuFT,AAvFS,EAAA,EAAA,WAAA,AAAW,EAC/B,IAAM,EAAc,GAAA,OAAO,CAAE,EAAe,EAAa,EAAa,GACtE,CAAC,EAAe,EAAW,EAsF3B,YAnFsB,CAmFT,AAnFS,EAAA,EAAA,WAAW,AAAX,EACtB,IAAM,EAAc,GAAA,SAAS,CAAE,EAAiB,EAAe,EAAe,GAC9E,CAAC,EAAe,EAAa,EAkF7B,WA/EuB,CA+EX,AA/EW,EAAA,EAAA,WAAA,AAAW,EAAC,UACnC,GAAI,AAAC,IAAS,GAEV,EAAe,OAAO,EAAE,CAFC,YAEY,EAAe,OAAO,EAE/D,GAAiB,GACjB,EAAe,MAEf,GAAI,CACF,IAAM,EAAa,EAAM,YAAY,EAAI,EAAM,cAAc,CACvD,EAAS,MAAM,CAAA,EAAA,GAAA,UAAA,AAAU,EAAC,GAEhC,GAAI,CAAC,EAAO,OAAO,CAAE,CACnB,IAAM,EAAe,EAAO,KAAK,EAAI,+BACrC,EAAe,GACf,EAAe,OAAO,CAAG,WAAW,IAAM,EAAe,OAAO,GAClE,CACF,CAAE,MAAO,EAAc,CAErB,EADqB,aAAe,AACrB,MAD6B,EAAI,OAAO,CAAG,gCAE1D,EAAe,OAAO,CAAG,WAAW,IAAM,EAAe,OAAO,GAClE,QAAU,CACR,GAAiB,EACnB,EACF,EAAG,CAAC,EAAO,EAAc,EAwDvB,gBAtD4B,CAsDX,AAtDW,EAAA,EAAA,WAAA,AAAW,EAAC,UACxC,GAAI,AAAC,GAAO,WAAY,GAEpB,EAAc,OAAO,EAFa,AAEX,aAAa,EAAc,OAAO,EAE7D,GAAgB,GAChB,EAAc,MAEd,GAAI,CACF,IAAM,EAAS,MAAM,CAAA,EAAA,GAAA,UAAA,AAAU,EAAC,EAAM,QAAQ,EAE9C,GAAI,CAAC,EAAO,OAAO,CAAE,CACnB,IAAM,EAAe,EAAO,KAAK,EAAI,+BACrC,EAAc,GACd,EAAc,OAAO,CAAG,WAAW,IAAM,EAAc,OAAO,GAChE,CACF,CAAE,MAAO,EAAc,CAErB,EADqB,YACP,CADsB,MAAQ,EAAI,OAAO,CAAG,gCAE1D,EAAc,OAAO,CAAG,WAAW,IAAM,EAAc,OAAO,GAChE,QAAU,CACR,GAAgB,EAClB,EACF,EAAG,CAAC,EAAO,EAAa,EAgCtB,aA9ByB,CAAA,AA8BX,EA9BW,EAAA,WAAA,AAAW,EAAC,UACrC,GAAI,AAAC,GAAO,YAAa,GAErB,EAAe,OAAO,EAAE,CAFY,YAEC,EAAe,OAAO,EAE/D,GAAiB,GACjB,EAAe,MAEf,GAAI,CACF,IAAM,EAAS,MAAM,GAAc,EAAM,SAAS,EAElD,GAAI,CAAC,EAAO,OAAO,CAAE,CACnB,IAAM,EAAe,EAAO,KAAK,EAAI,+BACrC,EAAe,GACf,EAAe,OAAO,CAAG,WAAW,IAAM,EAAe,MAnJvC,CAmJ8C,GAClE,CACF,CAAE,MAAO,EAAc,CAErB,EADqB,aAAe,AACrB,MAD6B,EAAI,OAAO,CAAG,gCAE1D,EAAe,OAAO,CAAG,WAAW,IAAM,EAAe,OAAO,GAClE,QAAU,CACR,GAAiB,EACnB,EACF,EAAG,CAAC,EAAO,EAAc,EAQvB,aACA,6BACA,eACA,gBACA,WACA,aACA,cACA,aACA,EACA,aACF,CACF,ExB+U2C,IAInC,GACJ,EAAa,aAAa,EAAI,GAAa,QAAU,GAAa,UAC9D,EAAY,SAAS,CACrB,KACA,CACJ,KAAM,EAAQ,CACd,QAAS,EAAW,CACpB,MAAO,EAAS,CAChB,QAAS,EAAW,CACrB,CFrhBI,AEqhBD,SFrhBU,AAAoB,CAAwB,EAC1D,GAAM,CAAC,EAAM,EAAQ,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAwB,KACtD,GAAI,CAAC,EAAW,OAAO,KACvB,IAAM,EAAS,GAAM,GAAG,CAAC,GACzB,OAAO,EAAS,EAAO,IAAI,CAAG,IAChC,GACM,CAAC,EAAS,EAAW,CAAG,CAAA,EAAA,EAAA,QAAQ,AAAR,GAAS,GACjC,CAAC,EAAO,EAAS,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MAC5C,EAAe,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,EAC5B,GAAa,OAAO,CAAG,EAEvB,IAAM,EAAc,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,MAAO,IACrC,GAAW,GACX,EAAS,MACT,GAAI,CACF,IAAM,EAAS,MAAM,GAAoB,GAEzC,GAAI,EAAa,OAAO,GAAK,EAAI,OACjC,GAAI,EAAO,OAAO,EAAI,EAAO,IAAI,CAAE,CACjC,IAAM,EAA2B,EAAO,IAAI,CAC5C,GAAM,GAAG,CAAC,EAAI,CAAE,KAAM,EAAU,UAAW,KAAK,GAAG,EAAG,GACtD,EAAQ,EACV,MACE,CADK,CACI,EAAO,KAAK,EAAI,8BAE7B,CAAE,KAAM,CACN,GAAI,EAAa,OAAO,GAAK,EAAI,OACjC,EAAS,8BACX,QAAU,CACJ,EAAa,OAAO,GAAK,GAC3B,CAD+B,EACpB,EAEf,CACF,EAAG,EAAE,EAyBL,MAtBA,CAAA,EAAA,EAAA,SAAS,AAAT,EAAU,KACR,GAAI,CAAC,EAAW,CACd,EAAQ,MACR,EAAS,MACT,MACF,CAEA,IAAM,EAAS,GAAM,GAAG,CAAC,GACrB,IACF,EAAQ,EADE,AACK,IAAI,EACf,KAAK,GAAG,GAAK,EAAO,SAAS,CAnDlB,EAmDqB,IAGjC,EAAY,EACnB,EAAG,CAAC,EAAW,CAJuC,CAI3B,EAQpB,MAAE,EAAM,gBAAS,EAAO,QANf,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,KACtB,GACG,EAAY,EAErB,EAAG,CAAC,CAHa,CAGF,EAAY,CAEY,CACzC,EE0d0B,IAGlB,GAAuB,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,GAAe,aAAa,EAChE,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KAEN,IAAqB,OAAO,EAC3B,EAAD,CAAgB,aAAa,EAC5B,EAAD,CAAgB,WAAW,EAC3B,AACA,KAEF,GAAqB,OAAO,CAAG,GAAe,aAAa,AAC7D,EAAG,CAAC,GAAe,aAAa,CAAE,GAAe,WAAW,CAAE,GAAY,EAE1E,IAAM,GACJ,GAAa,gBAAkB,EAAY,MAAM,CAC7C,CACE,SAAU,EAAY,SAAS,CAC/B,WAAY,UACZ,eAAgB,EAAY,cAAc,CAC1C,OAAQ,EAAY,MAAM,AAC5B,EACA,KAEA,GAAe,CAAA,EAAA,EAAA,eAAe,AAAf,EAAgB,IAC/B,GACoB,YAAxB,GAAa,MAAM,EAA0C,UAAxB,GAAa,MAAM,CAIpD,CAAC,GAAU,GAAY,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACnC,GAAe,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,KAC1B,GAAa,WAAW,CACxB,UAAU,SAAS,CAAC,SAAS,CAAC,EAAY,SAAS,EACxD,IAAY,GACZ,WAAW,IAAM,IAAY,GANH,KAO5B,AADuC,EACpC,CAAC,GAAa,UAAU,EAM3B,GAAI,EAAa,CACf,IAAM,EAAU,EAAY,SAAS,CAAC,KAAK,CAAC,EAAG,GAIzC,EACJ,qJACI,EAAQ,wCAEd,EACE,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,cAAY,kCACf,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8BAA8B,cAAY,mCAEtD,IAAuB,GAAa,QAAU,OAC7C,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,QAAS,GACT,eAAgB,GAAoB,cAAc,CAClD,aAAc,GAAoB,YAAY,CAC9C,UAAW,CAAC,CAAC,GAAoB,QAAQ,GAEzC,KACH,IACD,GAAa,QAAU,QACvB,EAAa,SAAS,EACtB,GACE,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAW,IAChB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,eAAe,CAAA,CAAC,cAAe,aAC9B,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,SAAU,GAAa,aAAa,EAAI,GAAa,WAAW,CAChE,QAAS,GAAwB,GAAa,IAAI,CAAG,GAAa,MAAM,CACxE,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,mFACA,GACI,sDACA,4DAEN,YAAA,CAEM,EADJ,GACM,8BACA,GAAF,sCAGL,GAAa,aAAa,EAAI,GAAa,WAAW,CACrD,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,YAAY,CAAA,CAAC,UAAU,wBACtB,GACF,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CAAC,UAAU,WAElB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,IAAI,CAAA,CAAC,UAAU,eAItB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,KAAK,SAAS,UAAU,mBAElC,EADH,AACK,iCACF,AAAE,uCAIX,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,qBAAqB,CAAA,CACpB,OAAQ,GAAa,MAAM,CAC3B,IAAK,GAAa,GAAG,CACrB,SAAU,IAAqB,WAE/B,QAEJ,KAGJ,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,WAGf,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8BACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,oFACb,IAEH,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,eAAe,CAAA,CAAC,cAAe,aAC9B,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,GACT,UAAW,EACX,aAAY,EAAE,+BACd,cAAY,kCAEX,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,KAAK,CAAA,CAAC,UAAU,0BAEjB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,IAAI,CAAA,CAAC,UAAU,eAItB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,KAAK,SAAS,UAAU,mBACrC,EAAE,sCAIR,EAAY,SAAS,CACpB,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAW,IAChB,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,eAAe,CAAA,CAAC,cAAe,cACP,aAAtB,EAAY,KAAK,CAChB,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,SAAU,GACV,UAAW,EACX,aAAY,EAAE,kCACd,cAAY,2BACZ,QAAS,IAAM,GAAgB,EAAY,SAAS,WAEnD,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,YAAY,CAAA,CAAC,UAAU,wBAExB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,UAAU,eAIhC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,KAAK,SAAS,UAAU,mBACrC,EAAE,uCAGiB,aAAtB,EAAY,KAAK,CACnB,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,SAAU,GACV,UAAW,EACX,aAAY,EAAE,gCACd,cAAY,yBACZ,QAAS,IAAM,GAAc,EAAY,SAAS,WAEjD,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,YAAY,CAAA,CAAC,UAAU,wBAExB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,OAAO,CAAA,CAAC,UAAU,eAIzB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,KAAK,SAAS,UAAU,mBACrC,EAAE,qCAGL,KACJ,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,OAAO,CAAA,WACN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,OAAO,CAAA,CAAA,WACrB,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,SAAU,GACV,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EAAC,EAAO,kDACrB,aAAY,EAAE,+BACd,cAAY,wBACZ,QAAS,IAAM,IAAoB,YAElC,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,YAAY,CAAA,CAAC,UAAU,wBAExB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CAAC,UAAU,eAIxB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,cAAc,CAAA,CAAC,KAAK,SAAS,UAAU,mBACrC,EAAE,uCAIT,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,mBAAmB,CAAA,CAClB,KAAM,GACN,aAAc,GACd,UAAW,CAAC,EAAS,EAAe,IAClC,GAAa,EAAY,SAAS,CAAE,EAAS,EAAe,GAE9D,WAAY,GACZ,YAAa,EAAY,IAAI,CAC7B,UAAW,EAAY,SAAS,CAChC,YAAa,EAAY,WAAW,CACpC,UAAW,CAAC,CAAC,EAAY,EAAE,EAA8B,SAA1B,EAAY,EAAE,CAAC,MAAM,MAGtD,YAKd,CAIA,IAAI,GAAwB,KAE5B,GAAkB,YAAd,EAAK,IAAI,EAAkB,EAAa,CAC1C,IAAM,EAAe,CACnB,GAAG,CAAW,CACd,GAA0B,UAAtB,EAAY,KAAK,EAAgB,CAAE,QAAS,EAAY,CAAC,CAC7D,GAA0B,YAAtB,EAAY,KAAK,EAAkB,CAAE,QAAS,EAAY,CAAC,AACjE,EACA,GACE,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,YAAa,EAAY,IAAI,CAC7B,cAAe,EACf,YAAa,EACb,UAAW,EAAY,SAAS,CAChC,WAAY,EAAK,UAAU,CAC3B,OAAQ,EACR,UAAW,EACX,QAAS,GACT,cAAe,GACf,YAAa,CAAC,EAAK,IAAQ,GAAiB,AAAC,IAAU,CAAE,EAAH,CAAM,CAAI,CAAE,CAAC,EAAI,CAAE,EAAI,CAAC,EAC9E,aAAc,GACd,YAAa,GACb,aAAc,GACd,SAAU,GACV,cAAe,GACf,aAAc,GACd,cAAe,GACf,YAAa,GAAuB,KAAO,GAC3C,UAAW,GACX,eAAgB,GAChB,cAAe,GACf,eAAgB,GAChB,WAAY,GAAgB,QAAW,EACvC,YAAa,GACb,UAAW,GACX,cAAe,GAAgB,QAAc,EAC7C,eAAgB,GAAgB,GAAe,YAAY,MAAG,EAC9D,cAAe,GAAe,aAAa,CAC3C,YAAa,GAAe,WAAW,CACvC,YAAa,GACb,UAAW,EACX,kBAAmB,GACnB,wBAAyB,EACzB,QAAS,GACT,OAAQ,GACR,QAAS,IAGf,CAEA,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,UAAU,CAAA,CACT,KAAM,EACN,QAAS,GACT,KAAK,KACL,OAAO,EACP,cAA2B,YAAd,EAAK,IAAI,CAAiB,iBAAmB,6BAEzD,IAGP","ignoreList":[35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,54,55,56,57]}
|