{"version":3,"file":"static/js/4831.js?sha=ec5be26472e8","sources":["webpack://ide/./src/agent/components/AgentComposerCard.tsx","webpack://ide/./src/agent/errorRecovery.ts","webpack://ide/./src/agent/components/ErrorTurn.tsx","webpack://ide/./src/agent/components/ConversationTurn.tsx","webpack://ide/./src/agent/formElicitation.ts","webpack://ide/./src/agent/components/FormElicitationCard.tsx","webpack://ide/./src/agent/components/LoginPrompts.tsx","webpack://ide/./src/agent/components/promptComposer/configurationChooser.tsx","webpack://ide/./src/agent/agentChooser.tsx","webpack://ide/./src/agent/components/PromptDictation.tsx","webpack://ide/./src/agent/components/promptComposer/completions.ts","webpack://ide/./src/agent/components/promptComposer/decorations.tsx","webpack://ide/./src/agent/components/promptComposer/editorFeatures.ts","webpack://ide/./src/agent/components/promptComposer/images.tsx","webpack://ide/./src/agent/components/promptComposer/ui.tsx","webpack://ide/./src/agent/components/PromptComposer.tsx","webpack://ide/./src/agent/components/promptComposer/submit.ts","webpack://ide/./src/agent/components/agentToolCallDiffs.ts","webpack://ide/./src/agent/components/AgentToolCallDiff.tsx","webpack://ide/./src/agent/components/AgentTurnDiff.tsx","webpack://ide/./src/agent/components/agentImageUrls.ts","webpack://ide/./src/agent/components/AgentImageContent.tsx","webpack://ide/./src/agent/components/MarkdownLinks.tsx","webpack://ide/./src/agent/components/MarkdownComponents.tsx","webpack://ide/./src/agent/components/AgentContent.tsx","webpack://ide/./src/agent/components/ProposedPlan.tsx","webpack://ide/./src/agent/components/PermissionRequestCard.tsx","webpack://ide/./src/agent/components/agentToolCallFiles.ts","webpack://ide/./src/agent/components/ToolCall.tsx","webpack://ide/./src/agent/components/PromptTurn.tsx","webpack://ide/./src/agent/responseTimeline.ts","webpack://ide/./src/agent/components/SchemaMigrationBanner.tsx","webpack://ide/./src/agent/components/TemporaryDatabase.tsx","webpack://ide/./src/agent/components/agentMarkdownLinks.ts","webpack://ide/./src/agent/components/conversationSearch/conversationSearchDom.ts","webpack://ide/./src/agent/components/conversationSearch/ConversationSearch.tsx","webpack://ide/./src/agent/components/conversationSearch/conversationSearchIndex.ts","webpack://ide/./src/agent/components/conversationSearch/useConversationSearch.ts","webpack://ide/./src/agent/components/conversationSearch/useConversationSearchFeature.tsx","webpack://ide/./src/agent/components/conversationSkillCommands.ts","webpack://ide/./src/agent/components/promptComposer/completionCommandHelpers.ts","webpack://ide/./src/agent/context.ts","webpack://ide/./src/agent/conversationModel.ts","webpack://ide/./src/agent/conversationConfig.ts","webpack://ide/./src/agent/hooks.ts","webpack://ide/./src/agent/promptDraftStore.ts","webpack://ide/./src/agent/promptDrafts.ts","webpack://ide/./src/agent/schemaMigration.ts","webpack://ide/./src/agent/sessionCapabilities.ts","webpack://ide/./src/agent/usage.ts","webpack://ide/./src/analysis/diagnostics.ts","webpack://ide/./src/analysis/quick-fixes.ts","webpack://ide/./src/analysis/jump-pointer.ts","webpack://ide/./src/analysis/editor-tools-extension.ts","webpack://ide/./src/analysis/hover.ts","webpack://ide/./src/analysis/session.ts","webpack://ide/./src/analysis/ide-analysis.ts","webpack://ide/./src/analysis/inlay-hints.ts","webpack://ide/./src/analysis/positions.ts","webpack://ide/./src/analysis/material3-property-types.ts","webpack://ide/./src/analysis/project.ts","webpack://ide/./src/analysis/rename-history.ts","webpack://ide/./src/analysis/signatures.ts","webpack://ide/./src/analysis/source-nav-target.ts","webpack://ide/./src/analysis/workspace-edits.ts","webpack://ide/./src/analysis/workspace-renames.ts","webpack://ide/./src/api/agents.ts","webpack://ide/./src/api/tables.ts","webpack://ide/./src/code_mirror/autocompletions/python-globals.ts","webpack://ide/./src/code_mirror/autocompletions/autocompletions.ts","webpack://ide/./src/code_mirror/autocompletions/completion-extension.ts","webpack://ide/./src/code_mirror/utils/fold.ts","webpack://ide/./src/code_mirror/utils/paste.ts","webpack://ide/./src/code_mirror/basic_setup.tsx","webpack://ide/./src/code_mirror/editors/asset_editor.tsx","webpack://ide/./src/code_mirror/editors/index.ts","webpack://ide/./src/code_mirror/element.tsx","webpack://ide/./src/code_mirror/repl/index.ts","webpack://ide/./src/code_mirror/ruff/config.ts","webpack://ide/./src/code_mirror/theme/base_styles.ts","webpack://ide/./src/code_mirror/theme/css_styles.ts","webpack://ide/./src/code_mirror/theme/html_styles.ts","webpack://ide/./src/code_mirror/theme/js_styles.ts","webpack://ide/./src/code_mirror/theme/markdown_styles.ts","webpack://ide/./src/code_mirror/theme/yaml_styles.ts","webpack://ide/./src/code_mirror/theme/index.ts","webpack://ide/./src/code_mirror/theme/py_styles.ts","webpack://ide/./src/code_mirror/utils/class_body_scan.ts","webpack://ide/./src/code_mirror/utils/conflict_markers.ts","webpack://ide/./src/code_mirror/utils/conflict_minimap.ts","webpack://ide/./src/code_mirror/utils/conflict_state.ts","webpack://ide/./src/code_mirror/utils/css_dropzone_linter.ts","webpack://ide/./src/code_mirror/utils/extensions.ts","webpack://ide/./src/code_mirror/utils/helpers.ts","webpack://ide/./src/code_mirror/utils/hooks.ts","webpack://ide/./src/code_mirror/utils/indentation_guides.ts","webpack://ide/./src/code_mirror/utils/method_focus.ts","webpack://ide/./src/code_mirror/utils/python_tokens.ts","webpack://ide/./src/code_mirror/utils/reindent.ts","webpack://ide/./src/code_mirror/utils/server-test-gutter.ts","webpack://ide/./src/code_mirror/utils/server-test-locations.ts","webpack://ide/./src/code_mirror/utils/tab_keybinding.ts","webpack://ide/./src/components/AccountPage.tsx","webpack://ide/./src/components/reusable/TagInput.tsx","webpack://ide/./src/components/AppList.tsx","webpack://ide/./src/components/StartPage.tsx","webpack://ide/./src/agent/AgentBottomPanel.tsx","webpack://ide/./src/components/bottom_panel/BuildThis.tsx","webpack://ide/./src/components/reusable/Stepper.tsx","webpack://ide/./src/components/bottom_panel/IDETutorialPanel.tsx","webpack://ide/./src/components/bottom_panel/IntroVideoPanel.tsx","webpack://ide/./src/components/bottom_panel/RoadmapPanel.tsx","webpack://ide/./src/components/bottom_panel/ScriptOutputTab.tsx","webpack://ide/./src/components/bottom_panel/Breakpoints.tsx","webpack://ide/./src/components/bottom_panel/Conflicts.tsx","webpack://ide/./src/components/bottom_panel/DesignerOutputTab.tsx","webpack://ide/./src/components/bottom_panel/TutorialPanel.tsx","webpack://ide/./src/testing/ServerTestsResults.tsx","webpack://ide/./src/testing/ServerTestsBottomPanel.tsx","webpack://ide/./src/components/bottom_panel/BottomPanel.tsx","webpack://ide/./src/components/DesktopIDE.tsx","webpack://ide/./src/components/NewUserSurvey.tsx","webpack://ide/./src/components/TalkToUsOffer.tsx","webpack://ide/./src/components/WhereToStartSurvey.tsx","webpack://ide/./src/components/bottom_panel/DebugInspector.tsx","webpack://ide/./src/components/reusable/RefSelector.tsx","webpack://ide/./src/components/bottom_panel/History.tsx","webpack://ide/./src/components/bottom_panel/WhereToStartTutorialPanel.tsx","webpack://ide/./src/components/mobile-ide/AppPicker.tsx","webpack://ide/./src/components/mobile-ide/sample-content.ts","webpack://ide/./src/components/mobile-ide/ChatPicker.tsx","webpack://ide/./src/components/mobile-ide/tabs.ts","webpack://ide/./src/components/mobile-ide/MobileHeader.tsx","webpack://ide/./src/components/mobile-ide/NavigationDrawer.tsx","webpack://ide/./src/components/mobile-ide/SampleContent.tsx","webpack://ide/./src/components/mobile-ide/MobileIDE.tsx","webpack://ide/./src/components/modals/Alert.tsx","webpack://ide/./src/components/modals/Confirm.tsx","webpack://ide/./src/components/modals/ConfirmWithCheckBox.tsx","webpack://ide/./src/util/modalHeightContext.ts","webpack://ide/./src/components/modals/mobile-modal.module.css?803e","webpack://ide/./src/components/modals/Modal.tsx","webpack://ide/./src/components/modals/Prompt.tsx","webpack://ide/./src/components/modals/QuickSwitcherModal.tsx","webpack://ide/./src/components/modals/SimpleModal.tsx","webpack://ide/./src/components/modals/account/keys_and_tokens/OAuthTokens.tsx","webpack://ide/./src/components/modals/account/keys_and_tokens/SSHKeys.tsx","webpack://ide/./src/components/modals/account/keys_and_tokens/AIConnections.tsx","webpack://ide/./src/components/modals/account/keys_and_tokens/KeysAndTokens.tsx","webpack://ide/./src/components/modals/account/Authentication.tsx","webpack://ide/./src/components/modals/account/Communications.tsx","webpack://ide/./src/components/modals/account/LookAndFeel.tsx","webpack://ide/./src/components/modals/account/ManageDevelopers.tsx","webpack://ide/./src/components/modals/account/ScheduledTasksDashboard.tsx","webpack://ide/./src/components/modals/account/Account.tsx","webpack://ide/./src/components/modals/account/Billing.tsx","webpack://ide/./src/components/modals/account/OrgApps.tsx","webpack://ide/./src/components/modals/account/usage/ComputeUsage.tsx","webpack://ide/./src/components/reusable/BarChart.tsx","webpack://ide/./src/util/lazy/react-tabulator.tsx","webpack://ide/./src/components/modals/account/usage/DatabaseUsage.tsx","webpack://ide/./src/components/modals/account/Quotas.tsx","webpack://ide/./src/components/modals/account/usage/AiCreditBar.tsx","webpack://ide/./src/components/modals/database/SortModal.tsx","webpack://ide/./src/components/modals/environments/EnvironmentsModal.tsx","webpack://ide/./src/components/modals/RemoveUsersFromSubscription.tsx","webpack://ide/./src/components/modals/TerminateSubscription.tsx","webpack://ide/./src/components/modals/UnTerminateSubscription.tsx","webpack://ide/./src/components/modals/UpdatePaymentCard.tsx","webpack://ide/./src/components/modals/UpgradePaymentForm.jsx","webpack://ide/./src/components/modals/Upgrade.jsx","webpack://ide/./src/components/modals/names/account-modals.ts","webpack://ide/./src/components/modals/names/ide-modals.ts","webpack://ide/./src/agent/components/ApiKeyLoginModal.tsx","webpack://ide/./src/analysis/CodeLocationsModal.tsx","webpack://ide/./src/components/reusable/FileUploadButton.tsx","webpack://ide/./src/components/modals/AddAssetModal.tsx","webpack://ide/./src/components/modals/AddTableAndMappings.tsx","webpack://ide/./src/components/modals/AppCta.tsx","webpack://ide/./src/components/modals/AppHistoryModal.tsx","webpack://ide/./src/components/modals/BetaWelcome.tsx","webpack://ide/./src/components/modals/ChooseFormTypeModal.tsx","webpack://ide/./src/components/modals/ClaimedAchievement.tsx","webpack://ide/./src/components/modals/customcomponent/Parameters.tsx","webpack://ide/./src/components/modals/customcomponent/EventBody.tsx","webpack://ide/./src/components/modals/customcomponent/types.ts","webpack://ide/./src/components/modals/customcomponent/PropEventHeader.tsx","webpack://ide/./src/components/modals/customcomponent/PropertyDesigner.tsx","webpack://ide/./src/components/modals/customcomponent/PropertyEditors.tsx","webpack://ide/./src/components/modals/customcomponent/PropertyWriteback.tsx","webpack://ide/./src/components/modals/customcomponent/PropertyBody.tsx","webpack://ide/./src/components/modals/customcomponent/SubComponents.tsx","webpack://ide/./src/components/modals/customcomponent/helpers.tsx","webpack://ide/./src/components/modals/customcomponent/LayoutMetadataConfig.tsx","webpack://ide/./src/components/modals/customcomponent/IconUploader.tsx","webpack://ide/./src/components/modals/customcomponent/ToolboxSettings.tsx","webpack://ide/./src/components/modals/customcomponent/Events.tsx","webpack://ide/./src/components/modals/customcomponent/HelpText.tsx","webpack://ide/./src/components/modals/customcomponent/Properties.tsx","webpack://ide/./src/components/modals/customcomponent/CustomComponent.tsx","webpack://ide/./src/components/modals/ConfigureDependency.tsx","webpack://ide/./src/components/modals/ConfigureRunner.tsx","webpack://ide/./src/components/modals/CreateTag.tsx","webpack://ide/./src/components/modals/DeleteApp.tsx","webpack://ide/./src/components/modals/DirectSQLAccessModal.tsx","webpack://ide/./src/components/reusable/BranchSelector.tsx","webpack://ide/./src/components/modals/DockerExport.tsx","webpack://ide/./src/components/modals/Git.tsx","webpack://ide/./src/components/modals/HawthornDeployModal.tsx","webpack://ide/./src/api/hawthorn.ts","webpack://ide/./src/components/modals/HtmlLayout.tsx","webpack://ide/./src/components/modals/IdeTutorialIntro.tsx","webpack://ide/./src/components/modals/IntroVideoModal.tsx","webpack://ide/./src/components/modals/MergeCompletionConflict.tsx","webpack://ide/./src/components/modals/NewServiceModal.tsx","webpack://ide/./src/components/modals/PreCommitModal.tsx","webpack://ide/./src/components/modals/PreMergeModal.tsx","webpack://ide/./src/components/modals/PreviewV3Designer.tsx","webpack://ide/./src/components/modals/RemapDependency.tsx","webpack://ide/./src/components/modals/SchemaMismatch.tsx","webpack://ide/./src/components/modals/Tableau.tsx","webpack://ide/./src/components/modals/TableauCTA.tsx","webpack://ide/./src/components/modals/UplinkModal.tsx","webpack://ide/./src/components/modals/UploadAppYaml.tsx","webpack://ide/./src/components/modals/WelcomeModal.tsx","webpack://ide/./src/components/modals/database/AddColumn.tsx","webpack://ide/./src/components/modals/database/AddLinkedRow.tsx","webpack://ide/./src/components/modals/database/DatabasesForDeploymentPools.tsx","webpack://ide/./src/components/modals/database/DeleteAllRows.tsx","webpack://ide/./src/components/modals/database/EditColumn.tsx","webpack://ide/./src/components/modals/database/TableIndexes.tsx","webpack://ide/./src/components/modals/database/TextEditor.tsx","webpack://ide/./src/components/modals/environments/EnvUrlEditModal.tsx","webpack://ide/./src/components/modals/git_remotes/AddHTTPRemote.tsx","webpack://ide/./src/components/modals/git_remotes/GitCloneApp.tsx","webpack://ide/./src/components/modals/git_remotes/GitDesync.tsx","webpack://ide/./src/types/app-remotes.ts","webpack://ide/./src/components/modals/git_remotes/GitRemotes.tsx","webpack://ide/./src/components/modals/git_remotes/GithubAccountChooser.tsx","webpack://ide/./src/components/modals/git_remotes/GithubChooseVisibilityAndLicence.tsx","webpack://ide/./src/testing/RemoveTestingService.tsx","webpack://ide/./src/components/modals/SizedImageModal.tsx","webpack://ide/./src/components/modals/TemplatesModal.tsx","webpack://ide/./src/components/modals/UpdateFormItemType.tsx","webpack://ide/./src/components/modals/agent/AgentClaudeLogin.tsx","webpack://ide/./src/agent/components/UrlElicitation.tsx","webpack://ide/./src/components/modals/agent/AgentCodexLogin.tsx","webpack://ide/./src/components/modals/agent/AgentCustomModelProvider.tsx","webpack://ide/./src/components/modals/agent/AgentUsage.tsx","webpack://ide/./src/components/modals/agent/AgentZaiLogin.tsx","webpack://ide/./src/components/modals/database/LazyJsonEditor.tsx","webpack://ide/./src/components/modals/names/manager-modals.ts","webpack://ide/./src/components/reusable/Button.tsx","webpack://ide/./src/components/reusable/ButtonGroup.tsx","webpack://ide/./src/components/reusable/Breadcrumbs.tsx","webpack://ide/./src/components/reusable/CommitDetail.tsx","webpack://ide/./src/components/reusable/CopyButton.tsx","webpack://ide/./src/components/reusable/DropdownMenu.tsx","webpack://ide/./src/components/reusable/ErrorBoundary.tsx","webpack://ide/./src/components/reusable/Expander.tsx","webpack://ide/./src/components/reusable/Forms.tsx","webpack://ide/./src/components/reusable/HelpLink.tsx","webpack://ide/./src/components/reusable/IconHooks.tsx","webpack://ide/./src/components/reusable/Link.tsx","webpack://ide/./src/components/reusable/LinkInternal.tsx","webpack://ide/./src/components/reusable/embedded-output-growth.ts","webpack://ide/./src/components/bottom_panel/RunnerBgTaskWidget.tsx","webpack://ide/./src/components/reusable/LiveOutput.tsx","webpack://ide/./src/components/reusable/Loading.tsx","webpack://ide/./src/components/reusable/LoadingSpinner.tsx","webpack://ide/./src/components/reusable/NavNodeRenamer.tsx","webpack://ide/./src/components/reusable/SaveIndicator.tsx","webpack://ide/./src/components/reusable/SharedComponents.tsx","webpack://ide/./src/components/reusable/StructuralValueDiff.tsx","webpack://ide/./src/components/reusable/Text.tsx","webpack://ide/./src/components/reusable/TextInput.tsx","webpack://ide/./src/components/reusable/Tooltip.tsx","webpack://ide/./src/components/reusable/UpgradeBadge.tsx","webpack://ide/./src/components/reusable/ZenModeButtons.tsx","webpack://ide/./src/components/reusable/datepicker/DatePickerStore.ts","webpack://ide/./src/components/reusable/datepicker/Calendar.tsx","webpack://ide/./src/components/reusable/datepicker/DateInput.tsx","webpack://ide/./src/components/reusable/datepicker/Picker.tsx","webpack://ide/./src/components/reusable/datepicker/DatePicker.tsx","webpack://ide/./src/components/reusable/datepicker/TimePicker.tsx","webpack://ide/./src/components/reusable/datepicker/DateTimePicker.tsx","webpack://ide/./src/components/reusable/datepicker/OffsetPicker.tsx","webpack://ide/./src/components/reusable/datepicker/DateTimePickerWithOffset.tsx","webpack://ide/./src/components/reusable/selectdropdown/MultiSelectDropDown.tsx","webpack://ide/./src/components/reusable/selectdropdown/SingleSelectDropDown.tsx","webpack://ide/./src/components/sidebar/ResizePanel.tsx","webpack://ide/./src/components/sidebar/CodeNavFile.tsx","webpack://ide/./src/components/sidebar/CodeNav.tsx","webpack://ide/./src/controllers/app/themeSnarfer.ts","webpack://ide/./src/components/sidebar/ExtraFileTreeDragging.ts","webpack://ide/./src/components/sidebar/ExtraFileTreeRow.tsx","webpack://ide/./src/testing/TestsSidebar.tsx","webpack://ide/./src/testing/test-file-menus.tsx","webpack://ide/./src/agent/AgentSidebar.tsx","webpack://ide/./src/components/sidebar/DatabaseNav.tsx","webpack://ide/./src/components/sidebar/LogsNav.tsx","webpack://ide/./src/components/sidebar/SearchNav.tsx","webpack://ide/./src/components/sidebar/SettingsNav.tsx","webpack://ide/./src/components/sidebar/ThemeNav.tsx","webpack://ide/./src/components/sidebar/Sidebar.tsx","webpack://ide/./src/components/tabs/EmailServiceTab.tsx","webpack://ide/./src/controllers/app/emailServices.ts","webpack://ide/./src/components/tabs/FacebookServiceTab.tsx","webpack://ide/./src/components/tabs/FileServiceTab.tsx","webpack://ide/./src/controllers/googleservice.ts","webpack://ide/./src/components/tabs/GoogleServiceTab.tsx","webpack://ide/./src/components/tabs/hawthorn-deployment-schema.ts","webpack://ide/./src/components/tabs/HawthornDeploymentFields.tsx","webpack://ide/./src/components/tabs/HawthornDeploymentServiceTab.tsx","webpack://ide/./src/components/tabs/MicrosoftServiceTab.tsx","webpack://ide/./src/components/tabs/SAMLServiceTab.tsx","webpack://ide/./src/components/tabs/SchemaTab.tsx","webpack://ide/./src/controllers/stripeservice.ts","webpack://ide/./src/components/tabs/StripeServiceTab.tsx","webpack://ide/./src/components/tabs/TabPanel.tsx","webpack://ide/./src/components/tabs/TabToolbar.tsx","webpack://ide/./src/components/tabs/TableauServiceTab.tsx","webpack://ide/./src/components/reusable/LexicalEditor.tsx","webpack://ide/./src/components/tabs/UserServiceTab.tsx","webpack://ide/./src/components/tabs/code/DesignerHistoryState.ts","webpack://ide/./src/components/tabs/code/History.ts","webpack://ide/./src/components/tabs/code/NewFormEditor.tsx","webpack://ide/./src/components/tabs/code/designer/features/component-yaml-types.ts","webpack://ide/./src/components/tabs/code/designer/features/move-objects-in-form.ts","webpack://ide/./src/components/tabs/code/designer/features/resolve-event-handler.ts","webpack://ide/./src/components/tabs/code/designer/rpc/state.ts","webpack://ide/./src/components/tabs/code/designer/utils/component-tree.ts","webpack://ide/./src/components/tabs/code/designer/utils/index.ts","webpack://ide/./src/components/tabs/code/designer/utils/names.ts","webpack://ide/./src/components/tabs/code/designer/utils/other-layout-updates.ts","webpack://ide/./src/components/tabs/code/designer/utils/slots.ts","webpack://ide/./src/components/tabs/database/TableBody.tsx","webpack://ide/./src/components/tabs/database/TableFooter.tsx","webpack://ide/./src/components/tabs/database/TableHead.tsx","webpack://ide/./src/components/tabs/database/Toolbar.tsx","webpack://ide/./src/components/tabs/database/cells/Cell.tsx","webpack://ide/./src/components/tabs/database/cells/EditingCell.tsx","webpack://ide/./src/components/tabs/database/cells/FooterCell.tsx","webpack://ide/./src/components/tabs/database/cells/FooterEditCell.tsx","webpack://ide/./src/components/tabs/database/cells/LazyJsonEditor.tsx","webpack://ide/./src/components/tabs/database/cells/MediaCell.tsx","webpack://ide/./src/components/tabs/database/columns/AddColumn.tsx","webpack://ide/./src/components/tabs/database/columns/Columns.tsx","webpack://ide/./src/components/tabs/database/columns/SelectColumn.tsx","webpack://ide/./src/components/tabs/database/features/columnSorting.ts","webpack://ide/./src/components/tabs/database/features/hiddenColumns.ts","webpack://ide/./src/components/tabs/database/features/selection.ts","webpack://ide/./src/components/tabs/database/features/rowSizing.ts","webpack://ide/./src/components/tabs/database/header/ColumnHeader.tsx","webpack://ide/./src/components/tabs/database/header/DraggableColumnHeader.tsx","webpack://ide/./src/components/tabs/scheduled_tasks/ScheduledTaskItem.tsx","webpack://ide/./src/components/tabs/scheduled_tasks/ScheduledTasksTab.tsx","webpack://ide/./src/components/tabs/sessions/SessionLogs.tsx","webpack://ide/./src/components/tabs/settings/DependencyTree.tsx","webpack://ide/./src/components/tabs/settings/PersistentServerSetting.tsx","webpack://ide/./src/components/tabs/settings/python-environment/migration.ts","webpack://ide/./src/components/tabs/settings/PythonAndPackagesConfig.tsx","webpack://ide/./src/components/tabs/settings/dependency-configuration.ts","webpack://ide/./src/components/tabs/settings/dependency-tree.ts","webpack://ide/./src/components/tabs/settings/python-environment/lifecycle.ts","webpack://ide/./src/components/tabs/settings/python-version/pypiQueries.ts","webpack://ide/./src/components/tabs/settings/python-version/requirements.ts","webpack://ide/./src/components/tabs/settings/styles.ts","webpack://ide/./src/components/tabs/theme/EditRole.tsx","webpack://ide/./src/controllers/app-list-query.ts","webpack://ide/./src/controllers/app/autocompleter.ts","webpack://ide/./src/workers/rpc.ts","webpack://ide/./src/controllers/app/code.ts","webpack://ide/./src/analysis/module-conversion.ts","webpack://ide/./src/controllers/app/extra-files.ts","webpack://ide/./src/controllers/app/form-spec-readers.ts","webpack://ide/./src/controllers/app/form-spec-renames.ts","webpack://ide/./src/controllers/app/form-spec-writers.ts","webpack://ide/./src/controllers/app/history.ts","webpack://ide/./src/controllers/app/permissions.ts","webpack://ide/./src/controllers/background-tasks-query.ts","webpack://ide/./src/controllers/bottom-tabs.ts","webpack://ide/./src/controllers/db.ts","webpack://ide/./src/controllers/db_new.ts","webpack://ide/./src/controllers/debugger.ts","webpack://ide/./src/controllers/dependencies.ts","webpack://ide/./src/controllers/designer.ts","webpack://ide/./src/controllers/docs.ts","webpack://ide/./src/controllers/dynamic_downlinks.ts","webpack://ide/./src/controllers/environments.ts","webpack://ide/./src/workers/autocompleter/parser-ast.ts","webpack://ide/./src/controllers/ideTutorial.ts","webpack://ide/./src/controllers/tutorial-property-assignments.ts","webpack://ide/./src/controllers/ide_tasks.ts","webpack://ide/./src/controllers/log-events.ts","webpack://ide/./src/controllers/modals.ts","webpack://ide/./src/controllers/ossLicences.ts","webpack://ide/./src/controllers/payment.ts","webpack://ide/./src/controllers/record_types.ts","webpack://ide/./src/controllers/repl.ts","webpack://ide/./src/controllers/runner-bg-tasks.ts","webpack://ide/./src/controllers/runner.ts","webpack://ide/./src/controllers/scheduledtasks.ts","webpack://ide/./src/controllers/scripts.ts","webpack://ide/./src/controllers/secret-values.ts","webpack://ide/./src/controllers/server-test-logs.ts","webpack://ide/./src/controllers/server-test-runs.ts","webpack://ide/./src/controllers/server-tests.ts","webpack://ide/./src/controllers/services.ts","webpack://ide/./src/controllers/sidebar.ts","webpack://ide/./src/controllers/table-data-query.ts","webpack://ide/./src/controllers/tableau.ts","webpack://ide/./src/controllers/tabs.ts","webpack://ide/./src/controllers/talkToUsOffer.ts","webpack://ide/./src/controllers/user-agent-types.ts","webpack://ide/./src/controllers/user.ts","webpack://ide/./src/controllers/util.ts","webpack://ide/./src/controllers/whereToStartTutorials.ts","webpack://ide/./src/data/appTemplates.ts","webpack://ide/./src/data/customIcons.ts","webpack://ide/./src/manager/components/Developers.tsx","webpack://ide/./src/manager/components/Managers.tsx","webpack://ide/./src/manager/components/NavBar.tsx","webpack://ide/./src/manager/components/OrgSummary.tsx","webpack://ide/./src/manager/components/Organisation.tsx","webpack://ide/./src/manager/components/TableauUsers.tsx","webpack://ide/./src/pwa.ts","webpack://ide/./src/pyspace/common/components/NotificationsButton.tsx","webpack://ide/./src/pyspace/common/modals/DeleteGadget.tsx","webpack://ide/./src/pyspace/common/util/image-resize.ts","webpack://ide/./src/pyspace/utils/hooks/use-master-env.ts","webpack://ide/./src/router/navTypes.ts","webpack://ide/./src/router/navigation-hooks.ts","webpack://ide/./src/store/index.ts","webpack://ide/./src/testing/test-file-icons.ts","webpack://ide/./src/testing/test-status-display.ts","webpack://ide/./src/theme/theme.ts","webpack://ide/./src/theme/utils.ts","webpack://ide/./src/types/code.ts","webpack://ide/./src/types/index.ts","webpack://ide/./src/types/user.ts","webpack://ide/./src/util/TabPanelRefContext.tsx","webpack://ide/./src/util/asset-content.ts","webpack://ide/./src/util/assetUploads.ts","webpack://ide/./src/util/defer.ts","webpack://ide/./src/util/discounts.ts","webpack://ide/./src/util/dnd.ts","webpack://ide/./src/util/features.ts","webpack://ide/./src/util/fetch.ts","webpack://ide/./src/util/hooks/ab-flags.ts","webpack://ide/./src/util/hooks/assets.tsx","webpack://ide/./src/util/hooks/edit-sequence-number.ts","webpack://ide/./src/util/hooks/global-key-bindings.ts","webpack://ide/./src/util/hooks/use-apps-infinite-query.ts","webpack://ide/./src/util/hooks/use-debounce-fn.ts","webpack://ide/./src/util/hooks/use-delayed-flag.ts","webpack://ide/./src/util/hooks/use-developer-query.ts","webpack://ide/./src/util/hooks/use-intersection-observer.ts","webpack://ide/./src/util/hooks/use-throttle-fn.ts","webpack://ide/./src/util/hooks/use-timeout.ts","webpack://ide/./src/util/icons.ts","webpack://ide/./src/util/iconsets/index.ts","webpack://ide/./src/util/image-mime-type.ts","webpack://ide/./src/util/index.ts","webpack://ide/./src/util/lazy/index.tsx","webpack://ide/./src/util/lazy/plotly.tsx","webpack://ide/./src/util/python-version.ts","webpack://ide/./src/util/queryClient.ts","webpack://ide/./src/util/replace-equal-deep.ts","webpack://ide/./src/util/search-history.ts","webpack://ide/./src/util/time.ts","webpack://ide/./src/util/useEffectEvent.ts","webpack://ide/./src/util/useEventCallback.ts","webpack://ide/./src/util/useLongPress.tsx","webpack://ide/./src/util/userSurveys.ts","webpack://ide/./src/workers/search/search.ts","webpack://ide/../../../runtime/client/js/lib/b64.js","webpack://ide/../../../runtime/client/js/runner/component-spec-constants.ts","webpack://ide/../../../runtime/client/js/runner/slot-ordering.ts"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { getAgentsChatsLocation } from \"@/controllers/ide\";\nimport { cx } from \"@/theme/styles\";\n\ntype AgentComposerCardProps = ComponentProps<\"div\"> & {\n    highlighted?: boolean;\n};\n\nexport const AgentComposerCard = ({\n    children,\n    className,\n    highlighted = false,\n    ...props\n}: AgentComposerCardProps) => {\n    const agentChatsLocation = useSelector(getAgentsChatsLocation);\n\n    return (\n        <div\n            className={cx(\n                \"@container/composer relative overflow-hidden rounded-xl border bg-white shadow-[0px_4px_10px_0px_rgba(0,0,0,0.10)] transition-colors dark:bg-[#151718]\",\n                highlighted\n                    ? \"border-primary bg-primary-50\"\n                    : \"border-sectionborder dark:border-dark-sectionborder\",\n                agentChatsLocation === \"bottom\" && \"rounded-none border-x-0 border-b-0 shadow-none\",\n                className\n            )}\n            {...props}>\n            {children}\n        </div>\n    );\n};\n","import type { ErrorEvent } from \"@/agent/types\";\nimport type { AiCreditQuota } from \"@/components/modals/account/Quotas\";\n\nexport type AgentErrorRecoveryAction = \"restart\" | \"logout\";\n\nconst isObject = (value: unknown): value is Record<string, unknown> => typeof value === \"object\" && value !== null;\n\nconst codexErrorInfo = (error: ErrorEvent[\"event\"]): unknown =>\n    isObject(error.data) ? (error.data.codexErrorInfo ?? error.data.codex_error_info) : undefined;\n\n// \"The account this agent runs on is out of credit / usage allowance\" — Codex's\n// typed enum value, or claude-agent-acp's errorKind (claude and zai).\nexport const isOutOfCreditError = (error: ErrorEvent[\"event\"]): boolean =>\n    codexErrorInfo(error) === \"usageLimitExceeded\" ||\n    (isObject(error.data) && error.data.errorKind === \"billing_error\");\n\nexport type ErrorCardKind =\n    | \"credit-exhausted-refills\"\n    | \"credit-exhausted-grant\"\n    | \"credit-lapsed-subscription\"\n    | \"not-entitled\"\n    | \"token-invalid\"\n    | \"upstream-error\"\n    | \"external\";\n\n// Renderer-side classification: provider × codexErrorInfo × credit state. The proxy\n// sends every credit-flavoured refusal as the same usage_limit_reached 429 (one\n// non-retried code path in Codex); the *distinction* is made here, from the credit\n// state the IDE fetches anyway for the credit bar.\nexport function classifyModelError(\n    agentType: string,\n    error: ErrorEvent[\"event\"],\n    credit: AiCreditQuota | undefined\n): ErrorCardKind {\n    if (agentType !== \"codex-anvil\") return \"external\";\n    const info = codexErrorInfo(error);\n    if (info === \"usageLimitExceeded\") {\n        if (credit?.lapsed) return \"credit-lapsed-subscription\";\n        if (credit && !credit[\"infinite?\"] && !(credit[\"bucket-size\"] ?? 0)) return \"not-entitled\";\n        return (credit?.[\"refill-rate\"] ?? 0) > 0 ? \"credit-exhausted-refills\" : \"credit-exhausted-grant\";\n    }\n    if (info === \"unauthorized\" || error.code === -32000) return \"token-invalid\";\n    if (\n        isObject(info) &&\n        isObject(info.responseStreamConnectionFailed) &&\n        info.responseStreamConnectionFailed.httpStatusCode === 403\n    ) {\n        return \"not-entitled\";\n    }\n    return \"upstream-error\";\n}\n\n// Where to buy more capacity for an external agent's account, by how it is signed in.\nexport function getProviderBillingLink(\n    agentType: string,\n    authType: string | undefined\n): { label: string; url: string } | null {\n    switch (agentType) {\n        case \"codex\":\n            if (authType === \"api_key\") {\n                return { label: \"OpenAI billing\", url: \"https://platform.openai.com/settings/organization/billing/overview\" };\n            }\n            if (authType === \"auth_files\") {\n                return { label: \"ChatGPT usage settings\", url: \"https://chatgpt.com/codex/settings/usage\" };\n            }\n            return null; // model_provider: bring-your-own endpoint, no known dashboard\n        case \"claude\":\n            return authType === \"api_key\"\n                ? { label: \"Anthropic Console billing\", url: \"https://console.anthropic.com/settings/billing\" }\n                : { label: \"Claude usage settings\", url: \"https://claude.ai/settings/usage\" };\n        case \"zai\":\n            return { label: \"Z.ai plan\", url: \"https://z.ai/subscribe\" };\n        default:\n            return null;\n    }\n}\n\nconst isErrorThatNeedsLogout = (data: Record<string, unknown>): boolean =>\n    isCodexErrorThatNeedsLogout(data) ||\n    isClaudeErrorThatNeedsLogout(data);\n\nfunction isCodexErrorThatNeedsLogout(data: Record<string, unknown>): boolean {\n    const codexErrorInfo: any = data.codexErrorInfo ?? data.codex_error_info;\n    return (\n        codexErrorInfo === \"unauthorized\" ||\n        codexErrorInfo === \"usageLimitExceeded\" ||\n        codexErrorInfo?.responseStreamDisconnected?.httpStatusCode === 401\n    );\n}\n\nconst isClaudeErrorThatNeedsLogout = (data: Record<string, unknown>): boolean =>\n    data.errorKind === \"authentication_failed\" ||\n    data.errorKind === \"billing_error\" ||\n    data.errorKind === \"oauth_org_not_allowed\";\n\nexport function getAgentErrorRecoveryAction(error: ErrorEvent[\"event\"], agentType?: string): AgentErrorRecoveryAction {\n    // The Anvil-managed type has no user credential: there is nothing to log out of,\n    // and its auth problems are the platform's to fix (or a restart's).\n    if (agentType === \"codex-anvil\") return \"restart\";\n    return error.code === -32000 ||\n        (error.code === -32603 && isObject(error.data) && isErrorThatNeedsLogout(error.data))\n        ? \"logout\"\n        : \"restart\";\n}\n","import { faExclamationTriangle } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport {\n    classifyModelError,\n    getAgentErrorRecoveryAction,\n    getProviderBillingLink,\n    isOutOfCreditError,\n} from \"@/agent/errorRecovery\";\nimport { useAgentAuth, useConversationCallbacks } from \"@/agent/hooks\";\nimport { ErrorTurn as ErrorTurnType } from \"@/agent/types.ts\";\nimport { useConversationContext } from \"@/agent/context.ts\";\nimport { getQuota } from \"@/api\";\nimport { Button } from \"@/components/reusable/Button.tsx\";\nimport { restartAgent } from \"@/controllers/agents.ts\";\nimport { navigate } from \"@/router/navigation\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\n\n// All copy is dollar-free and unit-free: \"AI credit\" is an arbitrary unit.\nconst ANVIL_CREDIT_CARDS = {\n    \"credit-exhausted-refills\": {\n        message: \"You've used your included AI credit for now — it refills continuously.\",\n        actions: [\"upgrade\", \"connect\", \"usage\"],\n    },\n    \"credit-exhausted-grant\": {\n        message: \"You've used your free AI credit.\",\n        actions: [\"upgrade\", \"connect\"],\n    },\n    \"credit-lapsed-subscription\": {\n        message: \"Your organisation's Anvil subscription has lapsed, so included AI credit is paused.\",\n        actions: [\"subscription\"],\n    },\n    \"not-entitled\": {\n        message: \"Anvil-managed Codex isn't enabled for this account.\",\n        actions: [\"connect\"],\n    },\n} as const;\n\ntype AnvilCreditKind = keyof typeof ANVIL_CREDIT_CARDS;\n\nconst isAnvilCreditKind = (kind: string): kind is AnvilCreditKind => kind in ANVIL_CREDIT_CARDS;\n\nconst CardActions = ({ actions }: { actions: readonly string[] }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    return (\n        <div className={\"mt-8 flex flex-wrap items-center gap-4\"}>\n            {actions.includes(\"upgrade\") && (\n                <Button variant=\"primary\" onClick={() => dispatch(navigate({ type: \"ACCOUNT\", section: \"SUBSCRIPTION\" }))}>\n                    Upgrade plan\n                </Button>\n            )}\n            {actions.includes(\"subscription\") && (\n                <Button\n                    variant=\"primary\"\n                    onClick={() => dispatch(navigate({ type: \"ACCOUNT\", section: \"SUBSCRIPTION\" }))}>\n                    Manage subscription\n                </Button>\n            )}\n            {actions.includes(\"connect\") && (\n                <Button\n                    variant=\"secondary\"\n                    onClick={() => dispatch(navigate({ type: \"ACCOUNT\", section: \"AUTHENTICATION\", hash: \"AI\" }))}>\n                    Connect your own provider\n                </Button>\n            )}\n            {actions.includes(\"usage\") && (\n                <Button variant=\"secondary\" onClick={() => dispatch(navigate({ type: \"ACCOUNT\", section: \"QUOTAS\" }))}>\n                    View usage\n                </Button>\n            )}\n        </div>\n    );\n};\n\nexport const ErrorTurn = ({ turn }: { turn: ErrorTurnType }) => {\n    const { info, conversation } = useConversationContext();\n    const agentType = turn.agentType;\n    const { doLogout } = useConversationCallbacks(info);\n    const { data: agentAuth } = useAgentAuth();\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const [hasRestarted, setHasRestarted] = useState(false);\n\n    const outOfCredit = isOutOfCreditError(turn.error);\n    // On an anvil usage-limit error, refetch the credit state so the card reflects\n    // what caused the refusal (lapsed vs no-allowance vs exhausted) rather than a\n    // stale bar. Keyed per turn so a later error re-checks.\n    const { data: quotas } = useQuery({\n        queryKey: [\"quota\", \"ai-credits\", turn.eventPid],\n        queryFn: () => getQuota([\"ai-credits\"]),\n        enabled: agentType === \"codex-anvil\" && outOfCredit,\n    });\n    const kind = classifyModelError(agentType, turn.error, quotas?.[\"ai-credits\"]);\n\n    const recoveryAction = getAgentErrorRecoveryAction(turn.error, agentType);\n    const authType = agentAuth?.[agentType]?.auth_type;\n    const isConnected = !!agentAuth?.[agentType];\n    const isLatest = conversation?.latestErrorTurn?.eventPid === turn.eventPid;\n    const canRecover = isLatest && agentType === info.agent_type;\n    const billingLink = kind === \"external\" && outOfCredit ? getProviderBillingLink(agentType, authType) : null;\n\n    const message = isAnvilCreditKind(kind)\n        ? ANVIL_CREDIT_CARDS[kind].message\n        : kind === \"token-invalid\"\n          ? \"The connection to Anvil's AI service failed.\"\n          : kind === \"upstream-error\"\n            ? \"The AI model service is temporarily unavailable. Please try again in a few minutes.\"\n            : turn.error.message || \"An error occurred.\";\n\n    const showRestart = canRecover && !isAnvilCreditKind(kind) && recoveryAction === \"restart\";\n    const showLogout = canRecover && !isAnvilCreditKind(kind) && recoveryAction === \"logout\";\n\n    return (\n        <div\n            className={cx(\n                \"flex flex-col w-full p-4 items-center\",\n                \"border rounded border-tertiary-300 bg-tertiary-50 text-tertiary-700\"\n            )}>\n            <div className={cx(\"flex items-center gap-6  w-full\")}>\n                <div>\n                    <FontAwesomeIcon className=\"text-[2.25rem]\" icon={faExclamationTriangle} />\n                </div>\n                <div data-conversation-search-scope=\"true\" data-conversation-search-scope-kind=\"error\">\n                    <div>{message}</div>\n                    {canRecover && billingLink && (\n                        <div className={\"mt-2\"}>\n                            You can top up or upgrade in your{\" \"}\n                            <a\n                                className={\"underline\"}\n                                href={billingLink.url}\n                                rel=\"noreferrer\"\n                                target=\"_blank\">\n                                {billingLink.label}\n                            </a>\n                            , or{\" \"}\n                            <a\n                                className={\"cursor-pointer underline\"}\n                                onClick={() =>\n                                    dispatch(navigate({ type: \"ACCOUNT\", section: \"AUTHENTICATION\", hash: \"AI\" }))\n                                }>\n                                connect a different provider\n                            </a>\n                            .\n                        </div>\n                    )}\n                </div>\n            </div>\n            {canRecover && isAnvilCreditKind(kind) && <CardActions actions={ANVIL_CREDIT_CARDS[kind].actions} />}\n            {(showRestart || showLogout) && (\n                <div className={\"mt-8 flex gap-4 items-center\"}>\n                    {showLogout ? (\n                        isConnected ? (\n                            <>\n                                <Button variant=\"danger\" onClick={doLogout}>\n                                    Log out\n                                </Button>\n                                <div>Log out of this agent connection, then sign in again to continue.</div>\n                            </>\n                        ) : (\n                            <div>Sign in again to continue.</div>\n                        )\n                    ) : hasRestarted ? (\n                        <>\n                            <div>Agent has restarted. Send a new message to resume the conversation.</div>\n                        </>\n                    ) : (\n                        <>\n                            <Button\n                                variant=\"danger\"\n                                onClick={async () => {\n                                    if (await dispatch(restartAgent(info.conversation_pid, turn.eventPid))) {\n                                        setHasRestarted(true);\n                                    }\n                                }}>\n                                Restart this Agent\n                            </Button>\n                            <div>This can help if your agent is stuck</div>\n                        </>\n                    )}\n                </div>\n            )}\n        </div>\n    );\n};\n","import { faDatabase } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { ErrorTurn } from \"@/agent/components/ErrorTurn.tsx\";\nimport * as types from \"@/agent/types.ts\";\nimport { PromptTurn } from \"./PromptTurn.tsx\";\n\nexport const ConversationTurn = ({ turn }: { turn: types.ConversationTurn }) => {\n    switch (turn.turnType) {\n        case \"prompt\":\n            return <PromptTurn turn={turn} />;\n        case \"error\":\n            return <ErrorTurn turn={turn} />;\n        case \"schema_migration\":\n            return (\n                <div\n                    className=\"flex items-center gap-3 text-[1.4rem] text-light-bg6 dark:text-primary-200\"\n                    data-conversation-search-scope=\"true\"\n                    data-conversation-search-scope-kind=\"schema_migration\">\n                    <FontAwesomeIcon icon={faDatabase} />\n                    {turn.summary}\n                </div>\n            );\n        case \"session_boundary\":\n            return null; // For now, don't display anything here. <hr/> is useful for debugging.\n    }\n};\n","import type {\n    ElicitationContentValue,\n    ElicitationPropertySchema,\n    FormElicitationRequestMessage,\n} from \"@agent-host/rpc_types\";\n\nexport type FormValues = Record<string, ElicitationContentValue>;\n\ntype SupportedFormProperty = Extract<\n    ElicitationPropertySchema,\n    { type: \"string\" | \"number\" | \"integer\" | \"boolean\" | \"array\" }\n>;\n\nexport type FormProperty = ElicitationPropertySchema & {\n    _meta?: {\n        [key: string]: unknown;\n        codex?: {\n            role?: string;\n            questionId?: string;\n            isOtherAnswer?: boolean;\n        };\n    } | null;\n};\n\nexport type FormQuestion = {\n    key: string;\n    property: FormProperty;\n    associatedField?: {\n        key: string;\n        property: FormProperty;\n        // Other answers replace a choice; answers or notes can accompany one.\n        kind: \"other-answer\" | \"answer-or-note\";\n    };\n};\n\nexport type DisplayOption = { value: string; label: string; description?: string | null };\n\ntype FormSchema = FormElicitationRequestMessage[\"requested_schema\"];\n\nconst schemaEntries = (schema: FormSchema) => Object.entries(schema.properties ?? {}) as [string, FormProperty][];\n\nexport const isSupportedFormProperty = (property: FormProperty): property is SupportedFormProperty & FormProperty =>\n    property.type === \"string\" ||\n    property.type === \"number\" ||\n    property.type === \"integer\" ||\n    property.type === \"boolean\" ||\n    property.type === \"array\";\n\nconst isUserNote = (key: string, property: FormProperty) =>\n    key.endsWith(\"_note\") && property._meta?.codex?.role === \"user_note\";\n\nconst customAnswerQuestionId = (key: string, property: FormProperty) => {\n    if (property._meta?.codex?.isOtherAnswer) {\n        return property._meta.codex.questionId;\n    }\n    // claude-agent-acp emits each AskUserQuestion choice as `question_<n>` and\n    // its adjacent free-text answer or note as `question_<n>_custom`.\n    return property.type === \"string\" ? /^(question_\\d+)_custom$/.exec(key)?.[1] : undefined;\n};\n\nexport const questionsForSchema = (schema: FormSchema): FormQuestion[] => {\n    const entries = schemaEntries(schema);\n    const byKey = new Map(entries);\n    const associatedFields = new Map<string, NonNullable<FormQuestion[\"associatedField\"]>>();\n    for (const [key, property] of entries) {\n        const questionId = customAnswerQuestionId(key, property);\n        if (questionId && byKey.has(questionId)) {\n            associatedFields.set(questionId, {\n                key,\n                property,\n                kind:\n                    byKey.get(questionId)?.type === \"array\" && !property._meta?.codex?.isOtherAnswer\n                        ? \"answer-or-note\"\n                        : \"other-answer\",\n            });\n        } else if (\n            isUserNote(key, property) &&\n            byKey.has(key.slice(0, -\"_note\".length)) &&\n            associatedFields.get(key.slice(0, -\"_note\".length))?.kind !== \"other-answer\"\n        ) {\n            const parentKey = key.slice(0, -\"_note\".length);\n            associatedFields.set(parentKey, {\n                key,\n                property,\n                kind:\n                    byKey.get(parentKey)?.type === \"string\" && optionsForProperty(byKey.get(parentKey)!)\n                        ? \"other-answer\"\n                        : \"answer-or-note\",\n            });\n        }\n    }\n\n    return entries\n        .filter(([key, property]) => {\n            const questionId = customAnswerQuestionId(key, property);\n            if (questionId && byKey.has(questionId)) return false;\n            return !isUserNote(key, property) || !byKey.has(key.slice(0, -\"_note\".length));\n        })\n        .map(([key, property]) => ({ key, property, associatedField: associatedFields.get(key) }));\n};\n\nexport const initialFormValues = (schema: FormSchema): FormValues =>\n    Object.fromEntries(\n        schemaEntries(schema).flatMap(([key, property]) =>\n            isSupportedFormProperty(property) && property.default !== undefined && property.default !== null\n                ? [[key, property.default]]\n                : []\n        )\n    );\n\nexport const optionsForProperty = (property: FormProperty): DisplayOption[] | undefined => {\n    if (!isSupportedFormProperty(property)) return undefined;\n    if (property.type === \"string\") {\n        return (\n            property.oneOf?.map((option) => ({\n                value: option.const,\n                label: option.title,\n                description: option.description,\n            })) ?? property.enum?.map((value) => ({ value, label: value }))\n        );\n    }\n    if (property.type === \"array\") {\n        const anyOf = \"anyOf\" in property.items ? property.items.anyOf : undefined;\n        if (Array.isArray(anyOf)) {\n            return anyOf.flatMap((option) =>\n                typeof option === \"object\" &&\n                option !== null &&\n                \"const\" in option &&\n                typeof option.const === \"string\" &&\n                \"title\" in option &&\n                typeof option.title === \"string\"\n                    ? [\n                          {\n                              value: option.const,\n                              label: option.title,\n                              description:\n                                  \"description\" in option &&\n                                  (typeof option.description === \"string\" || option.description === null)\n                                      ? option.description\n                                      : undefined,\n                          },\n                      ]\n                    : []\n            );\n        }\n        const enumValues = \"enum\" in property.items ? property.items.enum : undefined;\n        if (Array.isArray(enumValues)) {\n            return enumValues.flatMap((value) => (typeof value === \"string\" ? [{ value, label: value }] : []));\n        }\n    }\n    return undefined;\n};\n\nexport const selectionCommitsQuestion = (question: FormQuestion) => {\n    if (!isSupportedFormProperty(question.property)) return false;\n    return (\n        question.property.type === \"boolean\" ||\n        (question.property.type === \"string\" && !!optionsForProperty(question.property))\n    );\n};\n\nconst hasValue = (value: ElicitationContentValue | undefined) =>\n    value !== undefined &&\n    (typeof value !== \"string\" || value.trim() !== \"\") &&\n    (!Array.isArray(value) || value.length > 0);\n\nexport const updateFormQuestionValue = (\n    current: FormValues,\n    question: FormQuestion,\n    key: string,\n    value: ElicitationContentValue | undefined\n): FormValues => {\n    const next = { ...current };\n    if (value === undefined) {\n        delete next[key];\n    } else {\n        next[key] = value;\n    }\n    if (question.associatedField?.kind === \"other-answer\") {\n        if (key === question.key) {\n            delete next[question.associatedField.key];\n        } else if (key === question.associatedField.key && value !== undefined && value !== \"\") {\n            delete next[question.key];\n        }\n    }\n    return next;\n};\n\nconst valueIsValid = (property: FormProperty, value: ElicitationContentValue | undefined, required: boolean) => {\n    if (!isSupportedFormProperty(property)) return !required;\n    if (!hasValue(value)) return !required;\n    if (property.type === \"array\") {\n        return (\n            Array.isArray(value) &&\n            (property.minItems === undefined || property.minItems === null || value.length >= property.minItems) &&\n            (property.maxItems === undefined || property.maxItems === null || value.length <= property.maxItems)\n        );\n    }\n    if (property.type === \"number\" || property.type === \"integer\") {\n        return (\n            typeof value === \"number\" &&\n            Number.isFinite(value) &&\n            (property.type !== \"integer\" || Number.isInteger(value)) &&\n            (property.minimum === undefined || property.minimum === null || value >= property.minimum) &&\n            (property.maximum === undefined || property.maximum === null || value <= property.maximum)\n        );\n    }\n    if (property.type === \"string\" && typeof value === \"string\") {\n        return (\n            (property.minLength === undefined || property.minLength === null || value.length >= property.minLength) &&\n            (property.maxLength === undefined || property.maxLength === null || value.length <= property.maxLength)\n        );\n    }\n    return true;\n};\n\nexport const questionIsComplete = (question: FormQuestion, values: FormValues, required: string[]) => {\n    if (question.associatedField?.kind === \"other-answer\") {\n        const answer = values[question.key];\n        const otherAnswer = values[question.associatedField.key];\n        if (!hasValue(answer) && !hasValue(otherAnswer)) {\n            return !required.includes(question.key) && !required.includes(question.associatedField.key);\n        }\n        return (\n            (hasValue(answer) && valueIsValid(question.property, answer, true)) ||\n            (hasValue(otherAnswer) && valueIsValid(question.associatedField.property, otherAnswer, true))\n        );\n    }\n    // An answer or note can satisfy the question without a selected choice.\n    const hasNoteAnswer =\n        question.associatedField?.kind === \"answer-or-note\" && hasValue(values[question.associatedField.key]);\n    return [\n        { key: question.key, property: question.property },\n        ...(question.associatedField ? [question.associatedField] : []),\n    ].every(({ key, property }) =>\n        valueIsValid(property, values[key], required.includes(key) && !(key === question.key && hasNoteAnswer))\n    );\n};\n\nexport const formIsComplete = (questions: FormQuestion[], values: FormValues, required: string[]) =>\n    questions.every((question) => questionIsComplete(question, values, required));\n\nconst displayValue = (property: FormProperty, value: ElicitationContentValue | undefined): string | null => {\n    if (\n        value === undefined ||\n        (typeof value === \"string\" && value.trim() === \"\") ||\n        (Array.isArray(value) && value.length === 0)\n    ) {\n        return null;\n    }\n    const options = optionsForProperty(property);\n    if (Array.isArray(value)) {\n        return value.map((item) => options?.find((option) => option.value === item)?.label ?? item).join(\", \");\n    }\n    if (typeof value === \"boolean\") {\n        return value ? \"Yes\" : \"No\";\n    }\n    if (typeof value === \"string\") {\n        return options?.find((option) => option.value === value)?.label ?? value.trim();\n    }\n    return String(value);\n};\n\nexport const answerLinesForQuestion = (question: FormQuestion, values: FormValues): string[] => {\n    const answer = displayValue(question.property, values[question.key]);\n    const associatedAnswer = question.associatedField\n        ? displayValue(question.associatedField.property, values[question.associatedField.key])\n        : null;\n    if (question.associatedField?.kind === \"other-answer\" && associatedAnswer) {\n        return [associatedAnswer];\n    }\n    return [...(answer ? [answer] : []), ...(associatedAnswer ? [`Note: ${associatedAnswer}`] : [])];\n};\n","import { useState } from \"react\";\nimport { faChevronDown } from \"@fortawesome/pro-light-svg-icons/faChevronDown\";\nimport { faChevronLeft } from \"@fortawesome/pro-light-svg-icons/faChevronLeft\";\nimport { faChevronRight } from \"@fortawesome/pro-light-svg-icons/faChevronRight\";\nimport { faCircleQuestion } from \"@fortawesome/pro-regular-svg-icons/faCircleQuestion\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useConversationContext } from \"@/agent/context\";\nimport {\n    type FormProperty,\n    type FormQuestion,\n    type FormValues,\n    answerLinesForQuestion,\n    formIsComplete,\n    initialFormValues,\n    isSupportedFormProperty,\n    optionsForProperty,\n    questionIsComplete,\n    questionsForSchema,\n    selectionCommitsQuestion,\n    updateFormQuestionValue,\n} from \"@/agent/formElicitation\";\nimport type { FormElicitationSection } from \"@/agent/types\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { CheckBox, RadioButton, TextArea, TextBox } from \"@/components/reusable/Forms\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { cx } from \"@/theme/styles\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { useConversationCallbacks } from \"../hooks\";\nimport { AgentComposerCard } from \"./AgentComposerCard\";\n\nconst choiceClass = (selected: boolean) =>\n    cx(\n        \"w-full cursor-pointer rounded px-2 py-3 text-[1.4rem] leading-normal font-normal! transition-colors focus-within:ring-2 focus-within:ring-primary\",\n        selected ? \"bg-primary-50 dark:bg-primary-800\" : \"hover:bg-light-bg1 dark:hover:bg-dark-bg2\"\n    );\n\nconst propertyText = (property: FormProperty, key: \"title\" | \"description\") => {\n    const value = property[key];\n    return typeof value === \"string\" ? value : undefined;\n};\n\nconst OptionText = ({ label, description, index }: { label: string; description?: string | null; index?: number }) => (\n    <>\n        {index !== undefined && (\n            <span\n                aria-hidden=\"true\"\n                className=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-full border border-sectionborder text-[1.2rem] text-light-grey1 dark:border-dark-sectionborder\">\n                {index + 1}\n            </span>\n        )}\n        <span className=\"ml-3 flex min-w-0 flex-col gap-1 text-left\">\n            <span className=\"text-light-grey2 dark:text-white\">{label}</span>\n            {description && <span className=\"text-[1.2rem] leading-normal font-normal text-light-grey1\">{description}</span>}\n        </span>\n    </>\n);\n\nconst QuestionInput = ({\n    question,\n    value,\n    setValue,\n    disabled,\n}: {\n    question: FormQuestion;\n    value: FormValues[string] | undefined;\n    setValue(value: FormValues[string] | undefined, commit?: boolean): void;\n    disabled: boolean;\n}) => {\n    const { key, property } = question;\n    if (!isSupportedFormProperty(property)) {\n        return (\n            <div className=\"rounded-lg border border-sectionborder bg-light-bg2 px-3 py-2 text-light-grey1 dark:border-dark-sectionborder dark:bg-dark-bg2\">\n                This field type ({property.type}) isn&apos;t supported. You can skip the form to continue.\n            </div>\n        );\n    }\n    const options = optionsForProperty(property)?.filter(\n        (option) =>\n            question.associatedField?.property._meta?.codex?.role !== \"user_note\" ||\n            option.value !== \"None of the above\"\n    );\n\n    if (property.type === \"array\" && options) {\n        const selected = Array.isArray(value) ? value : [];\n        return (\n            <div className=\"flex flex-col gap-1\">\n                {options.map((option) => {\n                    const checked = selected.includes(option.value);\n                    const atLimit =\n                        property.maxItems !== undefined &&\n                        property.maxItems !== null &&\n                        selected.length >= property.maxItems;\n                    return (\n                        <CheckBox\n                            key={option.value}\n                            className={choiceClass(checked)}\n                            checked={checked}\n                            disabled={disabled || (!checked && atLimit)}\n                            onChange={(event) =>\n                                setValue(\n                                    event.target.checked\n                                        ? [...selected, option.value]\n                                        : selected.filter((item) => item !== option.value)\n                                )\n                            }>\n                            <OptionText label={option.label} description={option.description} />\n                        </CheckBox>\n                    );\n                })}\n            </div>\n        );\n    }\n\n    if (options) {\n        return (\n            <div className=\"flex flex-col gap-1\">\n                {options.map((option, index) => (\n                    <RadioButton\n                        key={option.value}\n                        name={key}\n                        aria-label={option.label}\n                        className={cx(choiceClass(value === option.value), \"[&>svg]:hidden!\")}\n                        checked={value === option.value}\n                        disabled={disabled}\n                        onChange={() => setValue(option.value, true)}>\n                        <OptionText label={option.label} description={option.description} index={index} />\n                    </RadioButton>\n                ))}\n            </div>\n        );\n    }\n\n    if (property.type === \"boolean\") {\n        return (\n            <div className=\"flex flex-col gap-1\">\n                {[\n                    { label: \"Yes\", value: true },\n                    { label: \"No\", value: false },\n                ].map((option, index) => (\n                    <RadioButton\n                        key={option.label}\n                        name={key}\n                        aria-label={option.label}\n                        className={cx(choiceClass(value === option.value), \"[&>svg]:hidden!\")}\n                        checked={value === option.value}\n                        disabled={disabled}\n                        onChange={() => setValue(option.value, true)}>\n                        <OptionText label={option.label} index={index} />\n                    </RadioButton>\n                ))}\n            </div>\n        );\n    }\n\n    if (property.type === \"number\" || property.type === \"integer\") {\n        return (\n            <TextBox\n                autoFocus\n                className=\"border!\"\n                disabled={disabled}\n                type=\"number\"\n                step={property.type === \"integer\" ? 1 : \"any\"}\n                min={property.minimum ?? undefined}\n                max={property.maximum ?? undefined}\n                value={typeof value === \"number\" ? value : \"\"}\n                onChange={(event) => setValue(event.target.value === \"\" ? undefined : Number(event.target.value))}\n            />\n        );\n    }\n\n    return (\n        <TextArea\n            autoFocus\n            className=\"min-h-24 resize-y border!\"\n            disabled={disabled}\n            value={typeof value === \"string\" ? value : \"\"}\n            onChange={(event) => setValue(event.target.value)}\n        />\n    );\n};\n\nconst NoteInput = ({\n    value,\n    onChange,\n    onSubmit,\n    disabled,\n    placeholder,\n}: {\n    value: FormValues[string] | undefined;\n    onChange(value: string): void;\n    onSubmit(): void;\n    disabled: boolean;\n    placeholder: string;\n}) => (\n    <TextArea\n        rows={1}\n        aria-label={placeholder}\n        placeholder={placeholder}\n        className=\"[field-sizing:content] h-auto! max-h-36 min-h-10 min-w-0 flex-1 resize-none border-0! bg-transparent! px-1! py-1! text-[1.4rem]! shadow-none! placeholder:text-light-grey1!\"\n        disabled={disabled}\n        value={typeof value === \"string\" ? value : \"\"}\n        onChange={(event) => onChange(event.target.value)}\n        onKeyDown={(event) => {\n            if (event.key === \"Enter\" && !event.shiftKey && !event.nativeEvent.isComposing) {\n                event.preventDefault();\n                onSubmit();\n            }\n        }}\n    />\n);\n\nexport const FormElicitationComposer = ({ section }: { section: FormElicitationSection }) => {\n    const { info } = useConversationContext();\n    const { onRespondToElicitation } = useConversationCallbacks(info);\n    const schema = section.request.event.requested_schema;\n    const questions = questionsForSchema(schema);\n    const required = schema.required ?? [];\n    const [values, setValues] = useState<FormValues>(() => initialFormValues(schema));\n    const [step, setStep] = useState(0);\n    const [submitting, setSubmitting] = useState(false);\n    const question = questions[step];\n    // Codex puts the short question heading in description and the full prompt in title.\n    const questionHeading = question?.property._meta?.codex && propertyText(question.property, \"description\");\n    const message = section.request.event.message;\n    const showMessage =\n        ![\"Codex needs your input to continue.\", \"Please answer the following questions.\", \"Input requested\"].includes(\n            message\n        ) &&\n        (!question || message !== propertyText(question.property, \"title\"));\n\n    const submit = useEvent((responseValues = values) => {\n        setSubmitting(true);\n        void onRespondToElicitation(section.request.event.elicitation_id, \"accept\", responseValues).catch(() =>\n            setSubmitting(false)\n        );\n    });\n\n    const finalStep = step >= questions.length - 1;\n\n    const commitQuestion = useEvent((nextValues: FormValues) => {\n        if (!question || !questionIsComplete(question, nextValues, required)) return;\n        if (!finalStep) {\n            setStep(step + 1);\n        } else if (formIsComplete(questions, nextValues, required)) {\n            submit(nextValues);\n        }\n    });\n\n    const updateValue = useEvent(\n        (question: FormQuestion, key: string, value: FormValues[string] | undefined, commit = false) => {\n            const nextValues = updateFormQuestionValue(values, question, key, value);\n            setValues(nextValues);\n            if (commit && selectionCommitsQuestion(question)) {\n                commitQuestion(nextValues);\n            }\n        }\n    );\n\n    const skipQuestion = useEvent(() => {\n        if (!question) return;\n        const nextValues = { ...values };\n        delete nextValues[question.key];\n        if (question.associatedField) {\n            delete nextValues[question.associatedField.key];\n        }\n        setValues(nextValues);\n        if (finalStep) {\n            submit(nextValues);\n        } else {\n            setStep(step + 1);\n        }\n    });\n    const onPreviousQuestion = useEvent(() => setStep((current) => current - 1));\n    const onNextQuestion = useEvent(() => setStep((current) => current + 1));\n    const onQuestionValueChange = useEvent((value: FormValues[string] | undefined, commit?: boolean) => {\n        if (question) {\n            updateValue(question, question.key, value, commit);\n        }\n    });\n    const onAssociatedValueChange = useEvent((value: string) => {\n        if (question?.associatedField) {\n            updateValue(question, question.associatedField.key, value);\n        }\n    });\n    const onAssociatedSubmit = useEvent(() => commitQuestion(values));\n\n    return (\n        <AgentComposerCard className=\"text-[1.4rem] text-light-grey2 dark:text-white\">\n            <div className=\"flex items-center gap-3 border-b border-sectionborder px-4 py-3 dark:border-dark-sectionborder\">\n                <FontAwesomeIcon className=\"text-light-grey1\" icon={faCircleQuestion} />\n                <div className=\"min-w-0 flex-1\">\n                    <div className=\"font-medium\">{schema.title || questionHeading || \"Question\"}</div>\n                    {schema.description && <div className=\"mt-1 text-light-grey1\">{schema.description}</div>}\n                </div>\n                <div className=\"shrink-0 text-[1.2rem] text-light-grey1\">\n                    {questions.length > 0 && (\n                        <div className=\"flex items-center gap-1\">\n                            <Button\n                                tiny\n                                variant=\"hidden\"\n                                icon={faChevronLeft}\n                                aria-label=\"Previous question\"\n                                className={cx((submitting || step === 0) && \"opacity-25\")}\n                                linkClassName=\"rounded! border-0! bg-transparent! p-1! shadow-none!\"\n                                disabled={submitting || step === 0}\n                                onClick={onPreviousQuestion}\n                            />\n                            <span className=\"min-w-12 text-center\">\n                                {step + 1} of {questions.length}\n                            </span>\n                            <Button\n                                tiny\n                                variant=\"hidden\"\n                                icon={faChevronRight}\n                                aria-label=\"Next question\"\n                                className={cx((submitting || finalStep) && \"opacity-25\")}\n                                linkClassName=\"rounded! border-0! bg-transparent! p-1! shadow-none!\"\n                                disabled={submitting || finalStep}\n                                onClick={onNextQuestion}\n                            />\n                        </div>\n                    )}\n                </div>\n            </div>\n\n            {showMessage && <div className=\"px-4 pt-3 text-[1.2rem] text-light-grey1\">{message}</div>}\n            {question && (\n                <div className=\"px-4 py-4\">\n                    <div className=\"mb-5 leading-normal font-medium\">\n                        {propertyText(question.property, \"title\") || question.key}\n                    </div>\n                    {!questionHeading && propertyText(question.property, \"description\") && (\n                        <div className=\"mb-2 text-light-grey1\">{propertyText(question.property, \"description\")}</div>\n                    )}\n                    <QuestionInput\n                        question={question}\n                        value={values[question.key]}\n                        disabled={submitting}\n                        setValue={onQuestionValueChange}\n                    />\n                </div>\n            )}\n\n            <div className=\"flex flex-wrap items-center gap-2 border-t border-sectionborder px-4 py-3 dark:border-dark-sectionborder\">\n                {question?.associatedField && (\n                    <NoteInput\n                        value={values[question.associatedField.key]}\n                        onChange={onAssociatedValueChange}\n                        onSubmit={onAssociatedSubmit}\n                        disabled={submitting}\n                        placeholder={\n                            question.property.type === \"array\" ? \"Add another answer\" : \"Or write your own response\"\n                        }\n                    />\n                )}\n                <div className=\"ml-auto flex shrink-0 items-center gap-2\">\n                    <Button small variant=\"outlined\" disabled={submitting} onClick={skipQuestion}>\n                        Skip\n                    </Button>\n                    {finalStep ? (\n                        <Button\n                            small\n                            variant=\"primary\"\n                            disabled={submitting || !formIsComplete(questions, values, [])}\n                            onClick={() => submit()}>\n                            Submit\n                        </Button>\n                    ) : (\n                        <Button\n                            small\n                            variant=\"primary\"\n                            disabled={submitting || !questionIsComplete(question, values, required)}\n                            onClick={onAssociatedSubmit}>\n                            Next\n                        </Button>\n                    )}\n                </div>\n            </div>\n        </AgentComposerCard>\n    );\n};\n\nexport const FormElicitationHistory = ({ section }: { section: FormElicitationSection }) => {\n    const [expanded, setExpanded] = useState(false);\n    const onToggleExpanded = useEvent(() => setExpanded((current) => !current));\n    const schema = section.request.event.requested_schema;\n    const questions = questionsForSchema(schema);\n    const response = section.response;\n    if (!response) return null;\n    const answerLines = (question: FormQuestion) => {\n        if (response.event_type === \"form_elicitation_cancelled\") {\n            return [\"No answer provided\"];\n        }\n        if (response.event.action === \"decline\") return [\"Skipped\"];\n        if (response.event.action !== \"accept\") return [\"No answer provided\"];\n        const lines = answerLinesForQuestion(question, response.event.content ?? {});\n        return lines.length > 0 ? lines : [\"No answer provided\"];\n    };\n\n    return (\n        <div className=\"-m-2 py-1 dark:text-dark-fg1\">\n            <div className=\"relative flex items-start gap-x-8 pt-1 dark:text-light-bg6\">\n                <FontAwesomeIcon\n                    className=\"shrink-0 bg-white py-1 text-light-bg6 dark:bg-dark-bg0\"\n                    icon={faCircleQuestion}\n                />\n                <LinkInternal\n                    iconRight\n                    className=\"relative -top-1 text-[1.25rem] dark:text-light-bg6\"\n                    icon={expanded ? faChevronDown : faChevronRight}\n                    onClick={onToggleExpanded}>\n                    Asked {questions.length} {questions.length === 1 ? \"question\" : \"questions\"}\n                </LinkInternal>\n            </div>\n            <Expander isOpen={expanded} className=\"pl-14\">\n                <div className=\"flex flex-col gap-3 pt-2 text-[1.25rem]\">\n                    {questions.map((question) => (\n                        <div key={question.key}>\n                            <div className=\"text-light-grey2 dark:text-dark-fg1\">\n                                {propertyText(question.property, \"title\") ||\n                                    (questions.length === 1 ? section.request.event.message : question.key)}\n                            </div>\n                            {answerLines(question).map((line, index) => (\n                                <div key={index} className=\"text-light-grey1\">\n                                    {line}\n                                </div>\n                            ))}\n                        </div>\n                    ))}\n                </div>\n            </Expander>\n        </div>\n    );\n};\n","import { useDispatch, useSelector } from \"react-redux\";\nimport { faArrowRight } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { wakeConversation} from \"@/agent/hooks.ts\";\nimport { ConversationInfo, ConversationModel, ConversationTurn as ConversationTurnModel } from \"@/agent/types.ts\";\nimport { getAgentsChatsLocation } from \"@/controllers/ide.ts\";\nimport { cx } from \"@/theme/styles.ts\";\nimport useEvent from \"@/util/useEventCallback.ts\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { modal } from \"@/controllers/modals\";\nimport { AnvilDispatch } from \"@/types\";\nimport { getEnabledAgentTypes } from \"@/controllers/user-agent-types\";\n\ninterface ConversationProps {\n    conversationInfo: ConversationInfo;\n    conversation: ConversationModel;\n}\n\nexport const LoginPrompts = ({ conversationInfo, conversation }: ConversationProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const agentChatsLocation = useSelector(getAgentsChatsLocation);\n    const enabledAgentTypes = useSelector(getEnabledAgentTypes);\n\n\n    const onClickOpenCodexLogin = useEvent(async () => {\n        wakeConversation(conversationInfo.conversation_pid); // No await\n        dispatch(modal(\"agentCodexLogin\", { conversationInfo }));\n    });\n    const onClickOpenClaudeLogin = useEvent(() => {\n        dispatch(modal(\"agentClaudeLogin\", { conversationInfo }));\n    });\n    const onClickOpenZaiLogin = useEvent(() => {\n        dispatch(modal(\"agentZaiLogin\", { conversationInfo }));\n    });\n    const onClickOpenCustomLogin = useEvent(() => {\n        dispatch(modal(\"agentCustomModelProvider\", {}));\n    });\n\n\n    return (<div\n        className={cx(\n            \" justify-center flex flex-col pb-8 text-center text-2xl text-grey-2 dark:text-white gap-2\",\n            agentChatsLocation !== \"bottom\" && \"mt-[20vh]\"\n        )}>\n        <div>\n            <div className=\"\">You're not currently connected to any AI provider.</div>\n            <div className=\"mb-2\">Log in to start building with AI.</div>\n\n            <div className=\"flex flex-col items-center gap-4 text-light-fg1 mb-8\">\n                {enabledAgentTypes.includes(\"codex\") && (\n                    <LinkInternal className={cx(\"cursor flex justify-between border border-sectionborder items-center rounded w-full max-w-140 gap-8 px-8 hover:bg-light-bg2\", \"dark:border-dark-sectionborder dark:text-dark-fg1 dark:bg-dark-bg2 dark:hover:bg-dark-bg1\")}\n                        onClick={onClickOpenCodexLogin}>\n                        <div className=\"py-6 font-semibold text-3xl\">ChatGPT/Codex</div>\n                        <FontAwesomeIcon className={\"text-light-bg6\"} icon={faArrowRight} />\n                    </LinkInternal>\n                )}\n                {enabledAgentTypes.includes(\"claude\") && (\n                    <LinkInternal className={cx(\"cursor flex justify-between border border-sectionborder items-center rounded w-full max-w-140 gap-8 px-8 hover:bg-light-bg2\", \"dark:border-dark-sectionborder dark:text-dark-fg1 dark:bg-dark-bg2 dark:hover:bg-dark-bg1\")}\n                        onClick={onClickOpenClaudeLogin}>\n                        <div className=\"py-6 font-semibold text-3xl\">Claude</div>\n                        <FontAwesomeIcon className={\"text-light-bg6\"} icon={faArrowRight} />\n                    </LinkInternal>\n                )}\n                {enabledAgentTypes.includes(\"zai\") && (\n                    <LinkInternal className={cx(\"cursor flex justify-between border border-sectionborder items-center rounded w-full max-w-140 gap-8 px-8 hover:bg-light-bg2\", \"dark:border-dark-sectionborder dark:text-dark-fg1 dark:bg-dark-bg2 dark:hover:bg-dark-bg1\")}\n                        onClick={onClickOpenZaiLogin}>\n                        <div className=\"py-6 font-semibold text-3xl\">Z.ai</div>\n                        <FontAwesomeIcon className={\"text-light-bg6\"} icon={faArrowRight} />\n                    </LinkInternal>\n                )}\n                <LinkInternal className={cx(\"cursor flex justify-between border border-sectionborder items-center rounded w-full max-w-140 gap-8 px-8 hover:bg-light-bg2\", \"dark:border-dark-sectionborder dark:text-dark-fg1 dark:bg-dark-bg2 dark:hover:bg-dark-bg1\")}\n                    onClick={onClickOpenCustomLogin}>\n                    <div className=\"flex flex-col py-2 items-start\">\n                        <div className=\"font-semibold text-3xl\">Custom Model Provider</div>\n                        <div>Enterprise Only</div>\n                    </div>\n                    <FontAwesomeIcon className={\"text-light-bg6\"} icon={faArrowRight} />\n                </LinkInternal>\n            </div>\n        </div>\n    </div>\n    );\n};\n","import { SessionConfigSelectOption } from \"@agent-host/rpc_types\";\nimport { faCheck } from \"@fortawesome/pro-regular-svg-icons/faCheck\";\nimport { faChevronDown } from \"@fortawesome/pro-regular-svg-icons/faChevronDown\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { ConversationConfig, SessionConfigUpdateByCategory } from \"@/agent/types\";\nimport { Button } from \"@/components/reusable/Button\";\nimport DropdownMenu, { MenuItems } from \"@/components/reusable/DropdownMenu\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { cx } from \"@/theme/styles\";\nimport {useSelector} from \"react-redux\";\nimport {getAgentsChatsLocation} from \"@/controllers/ide.ts\";\n\ninterface ComposerConfigurationProps {\n    config: ConversationConfig;\n    /** The session is starting or the latest configuration request has not settled. */\n    pending?: boolean;\n    onChangeConfig(configUpdate: SessionConfigUpdateByCategory): Promise<void> | void;\n}\n\nconst selectedOptionName = (options: SessionConfigSelectOption[], currentValue: string) =>\n    options.find((option) => option.value === currentValue)?.name ?? currentValue;\n\nconst ConfigurationOptionLabel = ({ option }: { option: SessionConfigSelectOption }) => {\n    const [tooltip, tooltipRef] = useTooltip(option.description, \"top\", { delay: true });\n\n    return (\n        <span ref={tooltipRef} className=\"block w-full truncate font-normal\">\n            {tooltip}\n            {option.name}\n        </span>\n    );\n};\n\nexport const ComposerConfiguration = ({ config, pending = false, onChangeConfig }: ComposerConfigurationProps) => {\n    const modelConfig = config.session.model;\n    const effortConfig = config.session.thought_level;\n\n    const agentChatsLocation = useSelector(getAgentsChatsLocation);\n\n    if (!modelConfig || modelConfig.type !== \"select\") {\n        return (\n            <div className={cx(\n                \"min-w-0 truncate text-light-bg5\",\n                agentChatsLocation === \"side\" && \"text-xl\")} title=\"Loading Configurations ...\">\n                Loading Configurations ...\n            </div>\n        );\n    }\n\n    const modelOptions = modelConfig.options as SessionConfigSelectOption[];\n    const selectableEffortConfig = effortConfig && effortConfig.type === \"select\" ? effortConfig : null;\n    const effortOptions = selectableEffortConfig\n        ? (selectableEffortConfig.options as SessionConfigSelectOption[])\n        : null;\n    // Pending choices are requests, not provider confirmations. After settlement,\n    // currentValue is authoritative, including rejected or unsupported choices.\n    const modelValue = pending ? modelConfig.selectedValue ?? modelConfig.currentValue : modelConfig.currentValue;\n    const effortValue = pending\n        ? selectableEffortConfig?.selectedValue ?? selectableEffortConfig?.currentValue\n        : selectableEffortConfig?.currentValue;\n    const modelName = selectedOptionName(modelOptions, modelValue);\n    const effortName = selectableEffortConfig\n        ? selectedOptionName(effortOptions!, effortValue!)\n        : null;\n    const checkIcon = (selected: boolean) => (\n        <FontAwesomeIcon className={cx(!selected && \"invisible\")} icon={faCheck} />\n    );\n\n    const compactMenuItems = (): MenuItems => [\n        <div className=\"px-2 py-1 text-[1.1rem] font-medium text-light-grey1 dark:text-dark-fg1\">Model</div>,\n        ...modelOptions.map(\n            (option) =>\n                [\n                    <ConfigurationOptionLabel option={option} />,\n                    () => onChangeConfig({ model: option.value }),\n                    checkIcon(option.value === modelValue),\n                ] as const\n        ),\n        ...(selectableEffortConfig\n            ? [\n                  <hr />,\n                  <div className=\"px-2 py-1 text-[1.1rem] font-medium text-light-grey1 dark:text-dark-fg1\">Effort</div>,\n                  ...effortOptions!.map(\n                      (option) =>\n                          [\n                              <ConfigurationOptionLabel option={option} />,\n                              () => onChangeConfig({ thought_level: option.value }),\n                              checkIcon(option.value === effortValue),\n                          ] as const\n                  ),\n              ]\n            : []),\n    ];\n\n    return (\n        <div className=\"min-w-0\">\n            <DropdownMenu\n                align=\"right\"\n                anchorToTrigger\n                menuClassName=\"max-w-[min(32rem,calc(100vw-1.6rem))] overflow-x-hidden\"\n                offset={8}\n                render={(showMenu, anchor) => (\n                    <div className=\"min-w-0\">\n                        <Button\n                            small\n                            shrinkable\n                            variant=\"outlined\"\n                            icon={faChevronDown}\n                            iconRight\n                            className=\"w-full max-w-none! min-w-0 overflow-hidden\"\n                            linkClassName=\"min-w-0 rounded-full! leading-normal!\"\n                            title={pending ? \"Waiting for the agent to confirm these choices\" : undefined}\n                            aria-label={`Model ${modelName}${effortName ? `, reasoning effort ${effortName}` : \"\"}${pending ? \", awaiting confirmation\" : \"\"}`}\n                            onClick={(e) => showMenu(null, e.currentTarget)}>\n                            <span className=\"font-normal\">\n                                {modelName}\n                                {effortName ? <span className=\"text-light-bg6\"> · {effortName}</span> : null}\n                            </span>\n                        </Button>\n                        {anchor}\n                    </div>\n                )}\n                items={compactMenuItems}\n            />\n        </div>\n    );\n};\n","import { useSelector } from \"react-redux\";\nimport type { AgentTypeId } from \"@/agent/types.ts\";\nimport { DropDown } from \"@/components/reusable/Forms.tsx\";\nimport { AGENT_TYPE_NAMES, getEnabledAgentTypes } from \"@/controllers/user-agent-types\";\nimport { cx } from \"@/theme/styles\";\n\ninterface AgentChooserProps {\n    agentType: AgentTypeId;\n    disabled: boolean;\n    onChangeAgentType: (agentType: AgentTypeId) => void;\n}\n\nexport const AgentChooser = ({ agentType, disabled, onChangeAgentType }: AgentChooserProps) => (\n    <DropDown\n        aria-label={\"Agent type\"}\n        variant={\"small\"}\n        value={agentType}\n        disabled={disabled}\n        containerClassName={disabled ? \"opacity-50\" : undefined}\n        className={cx(\"disabled:cursor-not-allowed! border-0! bg-transparent!\",\n            \"hover:bg-[#d6e9ef40]! dark:hover:bg-[#66666640]!\",\n            \"text-light-bg5!\")}\n        iconClassName={\"text-light-bg5\"}\n        onChange={(e) => onChangeAgentType(e.target.value as AgentTypeId)}>\n        {useSelector(getEnabledAgentTypes).map((agentTypeId) => (\n            <option key={agentTypeId} value={agentTypeId}>\n                {AGENT_TYPE_NAMES[agentTypeId]}\n            </option>\n        ))}\n    </DropDown>\n);\n","import { type ReactNode, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { EditorView } from \"@codemirror/view\";\nimport { faMicrophone } from \"@fortawesome/pro-light-svg-icons/faMicrophone\";\nimport { keyframes } from \"tss-react\";\nimport { Button } from \"@/components/reusable/Button.tsx\";\nimport { alert } from \"@/controllers/modals.ts\";\nimport { makeStyles } from \"@/theme/styles.ts\";\nimport { AnvilDispatch } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback.ts\";\n\nconst DEFAULT_RECOGNITION_LANGUAGE = \"en-US\";\n\nexport interface PromptDictationState {\n    supported: boolean;\n    isDictating: boolean;\n    error: string | null;\n    toolbarComponent: ReactNode;\n    toggle(): void;\n    stop(): void;\n}\n\ninterface DictationRange {\n    from: number;\n    to: number;\n}\n\nfunction getSpeechRecognitionConstructor(): SpeechRecognitionConstructor | undefined {\n    return window.SpeechRecognition ?? window.webkitSpeechRecognition;\n}\n\nfunction getRecognitionLanguage(): string {\n    const language = navigator.language;\n    if (!language) {\n        return DEFAULT_RECOGNITION_LANGUAGE;\n    }\n\n    return language.toLowerCase().startsWith(\"en\") ? DEFAULT_RECOGNITION_LANGUAGE : language;\n}\n\nfunction transcriptWithSpacing(view: EditorView, transcript: string, range: DictationRange): string {\n    const text = transcript.trim();\n    if (!text) {\n        return \"\";\n    }\n\n    const before = range.from > 0 ? view.state.sliceDoc(range.from - 1, range.from) : \"\";\n    const after = range.to < view.state.doc.length ? view.state.sliceDoc(range.to, range.to + 1) : \"\";\n    const prefix = before && !/\\s/.test(before) ? \" \" : \"\";\n    const suffix = after && !/\\s/.test(after) && !/[,.;:!?)]/.test(after) ? \" \" : \"\";\n    return `${prefix}${text}${suffix}`;\n}\n\nfunction replaceDictationTranscript(\n    view: EditorView,\n    transcript: string,\n    range: DictationRange\n): DictationRange | null {\n    const docLength = view.state.doc.length;\n    const from = Math.min(range.from, docLength);\n    const to = Math.min(Math.max(range.to, from), docLength);\n    const safeRange = { from, to };\n    const insert = transcriptWithSpacing(view, transcript, safeRange);\n    if (!insert) {\n        return null;\n    }\n    view.dispatch({\n        changes: { from, to, insert },\n        selection: { anchor: from + insert.length },\n    });\n    view.focus();\n    return { from, to: from + insert.length };\n}\n\nexport function usePromptDictation(view: EditorView, isVisible: boolean): PromptDictationState {\n    const recognitionRef = useRef<SpeechRecognition | null>(null);\n    const intentionallyStoppingRef = useRef(false);\n    const insertionRangeRef = useRef<DictationRange | null>(null);\n    const draftRangeRef = useRef<DictationRange | null>(null);\n    const [isDictating, setIsDictating] = useState(false);\n    const [error, setError] = useState<string | null>(null);\n    const SpeechRecognitionCtor = useMemo(() => getSpeechRecognitionConstructor(), []);\n    const supported = !!SpeechRecognitionCtor;\n\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const stop = useEvent(() => {\n        const recognition = recognitionRef.current;\n        if (!recognition) {\n            return;\n        }\n        intentionallyStoppingRef.current = true;\n        draftRangeRef.current = null;\n        insertionRangeRef.current = null;\n        recognition.stop();\n        view.focus();\n    });\n\n    const toggle = useEvent(() => {\n        if (isDictating) {\n            stop();\n            return;\n        }\n        if (!SpeechRecognitionCtor || recognitionRef.current) {\n            return;\n        }\n\n        setError(null);\n        insertionRangeRef.current = {\n            from: view.state.selection.main.from,\n            to: view.state.selection.main.to,\n        };\n        draftRangeRef.current = null;\n        const recognition = new SpeechRecognitionCtor();\n        recognition.continuous = true;\n        recognition.interimResults = true;\n        recognition.lang = getRecognitionLanguage();\n        recognition.onresult = (event) => {\n            let finalTranscript = \"\";\n            let interimTranscript = \"\";\n            for (let i = event.resultIndex; i < event.results.length; i += 1) {\n                const result = event.results[i];\n                const transcript = result[0]?.transcript ?? \"\";\n                if (result.isFinal) {\n                    finalTranscript += transcript;\n                } else {\n                    interimTranscript += transcript;\n                }\n            }\n\n            if (finalTranscript) {\n                const range = draftRangeRef.current ?? insertionRangeRef.current;\n                if (range) {\n                    const insertedRange = replaceDictationTranscript(view, finalTranscript, range);\n                    if (insertedRange) {\n                        insertionRangeRef.current = { from: insertedRange.to, to: insertedRange.to };\n                    }\n                }\n                draftRangeRef.current = null;\n            }\n\n            if (interimTranscript) {\n                const range = draftRangeRef.current ?? insertionRangeRef.current;\n                if (range) {\n                    draftRangeRef.current = replaceDictationTranscript(view, interimTranscript, range);\n                }\n            }\n        };\n        recognition.onerror = (event) => {\n            if (intentionallyStoppingRef.current && event.error === \"aborted\") {\n                return;\n            }\n            let message: string;\n            switch (event.error) {\n                case \"no-speech\":\n                    message = \"No speech detected.\";\n                    break;\n                case \"audio-capture\":\n                    message = \"No microphone found.\";\n                    break;\n                case \"not-allowed\":\n                    message = \"Microphone permission was denied.\";\n                    break;\n                case \"service-not-allowed\":\n                    message = \"Microphone permission was denied.\";\n                    break;\n                case \"language-not-supported\":\n                    message = `Dictation language isn't available (${recognition.lang}).`;\n                    break;\n                case \"network\":\n                    message = \"Dictation service is unavailable.\";\n                    break;\n                default:\n                    message = `Dictation stopped (${event.error}).`;\n                    break;\n            }\n            setError(message);\n            dispatch(alert(\"Dictation stopped\", message));\n        };\n\n        recognition.onend = () => {\n            recognitionRef.current = null;\n            draftRangeRef.current = null;\n            insertionRangeRef.current = null;\n            intentionallyStoppingRef.current = false;\n            setIsDictating(false);\n        };\n\n        recognitionRef.current = recognition;\n        setIsDictating(true);\n        try {\n            recognition.start();\n        } catch {\n            recognitionRef.current = null;\n            draftRangeRef.current = null;\n            insertionRangeRef.current = null;\n            intentionallyStoppingRef.current = false;\n            setIsDictating(false);\n            setError(\"Dictation could not start.\");\n        }\n    });\n\n    useEffect(() => {\n        if (!isVisible && recognitionRef.current) {\n            stop();\n        }\n    }, [isVisible]);\n\n    useEffect(() => {\n        return () => {\n            const recognition = recognitionRef.current;\n            if (!recognition) {\n                return;\n            }\n            recognition.onend = null;\n            recognition.onerror = null;\n            recognition.onresult = null;\n            draftRangeRef.current = null;\n            insertionRangeRef.current = null;\n            try {\n                intentionallyStoppingRef.current = true;\n                recognition.stop();\n            } catch {\n                // Recognition may already be stopped during unmount.\n            }\n            recognitionRef.current = null;\n        };\n    }, []);\n\n    const toolbarComponent: ReactNode = (\n        <PromptDictation\n            dictation={{\n                supported,\n                isDictating,\n                error,\n                toolbarComponent: null,\n                toggle,\n                stop,\n            }}\n        />\n    );\n\n    return { supported, isDictating, error, toolbarComponent, toggle, stop };\n}\n\nconst dictationWave = keyframes`\n0%, 100% {\n    transform: scaleY(0.35);\n    opacity: 0.55;\n}\n35% {\n    transform: scaleY(1);\n    opacity: 1;\n}\n65% {\n    transform: scaleY(0.65);\n    opacity: 0.75;\n}\n`;\n\nconst useDictationStyles = makeStyles<void, \"bar\">()((theme, _props, classes) => ({\n    indicator: {\n        display: \"flex\",\n        alignItems: \"center\",\n        gap: \"0.3rem\",\n        height: \"2.2rem\",\n        padding: \"0 0.4rem\",\n        color: theme.palette.secondary.toString(),\n        [`& .${classes.bar}`]: {\n            width: \"0.25rem\",\n            height: \"1.8rem\",\n            borderRadius: \"999px\",\n            background: \"currentColor\",\n            transformOrigin: \"center\",\n            animation: `${dictationWave} 0.9s ease-in-out infinite`,\n        },\n        [`& .${classes.bar}:nth-of-type(1)`]: { height: \"0.6rem\", animationDelay: \"-0.72s\" },\n        [`& .${classes.bar}:nth-of-type(2)`]: { height: \"1.1rem\", animationDelay: \"-0.56s\" },\n        [`& .${classes.bar}:nth-of-type(3)`]: { height: \"1.7rem\", animationDelay: \"-0.38s\" },\n        [`& .${classes.bar}:nth-of-type(4)`]: { height: \"1.3rem\", animationDelay: \"-0.21s\" },\n        [`& .${classes.bar}:nth-of-type(5)`]: { height: \"0.8rem\", animationDelay: \"-0.08s\" },\n        [`& .${classes.bar}:nth-of-type(6)`]: { height: \"1.5rem\", animationDelay: \"-0.48s\" },\n        [`& .${classes.bar}:nth-of-type(7)`]: { height: \"1rem\", animationDelay: \"-0.31s\" },\n        [`& .${classes.bar}:nth-of-type(8)`]: { height: \"0.65rem\", animationDelay: \"-0.14s\" },\n    },\n    bar: {},\n}));\n\nconst dictationTitle = (dictation: PromptDictationState): string => {\n    if (!dictation.supported) {\n        return \"Dictation isn't supported in this browser\";\n    }\n    if (dictation.error) {\n        return dictation.error;\n    }\n    return dictation.isDictating ? \"Stop dictation\" : \"Dictate\";\n};\n\nconst DictationIndicator = () => {\n    const { classes } = useDictationStyles();\n    return (\n        <div className={classes.indicator} aria-label={\"Recording\"} role={\"status\"}>\n            {Array.from({ length: 8 }, (_, index) => (\n                <span key={index} className={classes.bar} />\n            ))}\n        </div>\n    );\n};\n\nexport const PromptDictation = ({ dictation }: { dictation: PromptDictationState }) => (\n    <div className={\"flex items-center gap-1\"}>\n        {dictation.isDictating && <DictationIndicator />}\n        <Button\n            small\n            variant={dictation.isDictating ? \"secondary\" : \"hidden\"}\n            icon={faMicrophone}\n            onClick={dictation.toggle}\n            title={<span className=\"block max-w-48 whitespace-pre-wrap\">{dictationTitle(dictation)}</span>}\n            titlePosition={\"top\"}\n            disabled={!dictation.supported}\n        />\n    </div>\n);\n","import { useMemo } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport type { AvailableCommand } from \"@agent-host/rpc_types.ts\";\nimport {\n    getAppAssets,\n    getDependencyAssets,\n    getDependencyStructure,\n    getForms,\n    getModules,\n    getServerModules,\n} from \"@/controllers/app/code.ts\";\nimport type { DependencyStructureItem, StructureItem } from \"@/types\";\nimport { slashCommandDisplayText } from \"../conversationSkillCommands.ts\";\nimport {\n    availableCommandSourceLabel,\n    availableCommandSubmittedTokenName,\n    type ComposerCompletion,\n    commandCompletion,\n    completionSource,\n    dollarCompletionsForCommands,\n    preferLocalSlashCompletions,\n    slashCompletionsForCommands,\n    sourceLabelDisplayText,\n} from \"./completionCommandHelpers.ts\";\n\nexport type { ComposerCompletion } from \"./completionCommandHelpers.ts\";\nexport { commandCompletion, completionSource, slashCompletionsForCommands } from \"./completionCommandHelpers.ts\";\n\nexport interface ComposerSlashCommand {\n    name: string;\n    slashCommandName: string;\n    type: string;\n    description?: string;\n    inputHint?: string;\n}\n\nconst LOCAL_CONTEXT_COMPLETION_BOOST = 100;\nconst DEPENDENCY_CONTEXT_COMPLETION_BOOST = 0;\nconst kindPaths = {\n    form: \"forms\",\n    module: \"modules\",\n    server_module: \"server_modules\",\n    asset: \"assets\",\n} as const;\n\nconst escapeMarkdownLabel = (label: string): string => label.replace(/[\\\\\\[\\]]/g, \"\\\\$&\");\n\nconst encodeMarkdownDestination = (href: string): string =>\n    encodeURI(href).replace(/[()<>]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`);\n\nconst contextMarkdownLink = (label: string, href: string): string =>\n    `[${escapeMarkdownLabel(label)}](<${encodeMarkdownDestination(href)}>)`;\n\nfunction contextCompletionDisplay(kind: keyof typeof kindPaths, fullName: string, packageName?: string) {\n    const separator = kind === \"asset\" ? \"/\" : \".\";\n    const splitAt = fullName.lastIndexOf(separator);\n    const parent = splitAt < 0 ? \"\" : fullName.slice(0, splitAt);\n    return {\n        displayLabel: fullName.slice(splitAt + 1),\n        parentPath: [packageName, parent].filter(Boolean).join(separator),\n        detail: kindPaths[kind],\n    };\n}\n\nfunction contextCompletionForLocal(kind: keyof typeof kindPaths, item: StructureItem): ComposerCompletion {\n    const path = `${kindPaths[kind]}/${item.fullName}`;\n    return {\n        label: item.fullName,\n        ...contextCompletionDisplay(kind, item.fullName),\n        applyText: `${contextMarkdownLink(item.fullName, path)} `,\n        type: kind === \"form\" ? \"class\" : kind === \"asset\" ? \"file\" : \"namespace\",\n        boost: LOCAL_CONTEXT_COMPLETION_BOOST,\n    };\n}\n\nfunction contextCompletionForDependency(\n    kind: keyof typeof kindPaths,\n    item: DependencyStructureItem,\n    packageName: string\n): ComposerCompletion {\n    const label = `${packageName}.${item.fullName}`;\n    const path = `deps/${packageName}/${kindPaths[kind]}/${item.fullName}`;\n    return {\n        label,\n        ...contextCompletionDisplay(kind, item.fullName, packageName),\n        applyText: `${contextMarkdownLink(label, path)} `,\n        type: kind === \"form\" ? \"class\" : kind === \"asset\" ? \"file\" : \"namespace\",\n        boost: DEPENDENCY_CONTEXT_COMPLETION_BOOST,\n    };\n}\n\nfunction agentCommandInfoElement(command: AvailableCommand) {\n    const info = document.createElement(\"div\");\n    info.addEventListener(\"mousedown\", (e) => e.preventDefault());\n    const title = document.createElement(\"div\");\n    title.textContent = slashCommandDisplayText(availableCommandSubmittedTokenName(command));\n    title.setAttribute(\"style\", \"font-weight: 700; font-family: Source Code Pro, monospace;\");\n    info.appendChild(title);\n    const type = document.createElement(\"small\");\n    type.textContent = sourceLabelDisplayText(availableCommandSourceLabel(command));\n    type.className = \"block opacity-70\";\n    info.appendChild(type);\n    if (command.description) {\n        const body = document.createElement(\"small\");\n        body.textContent = command.description;\n        body.className = \"block whitespace-pre-line\";\n        info.appendChild(body);\n    }\n    if (command.input?.hint) {\n        const hint = document.createElement(\"small\");\n        hint.textContent = command.input.hint;\n        hint.className = \"block whitespace-pre-line opacity-70\";\n        info.appendChild(hint);\n    }\n    return info;\n}\n\nfunction useContextCompletions(): ComposerCompletion[] {\n    const forms = useSelector(getForms);\n    const modules = useSelector(getModules);\n    const serverModules = useSelector(getServerModules);\n    const assets = useSelector(getAppAssets);\n    const dependencyStructure = useSelector(getDependencyStructure);\n    const dependencyAssets = useSelector(getDependencyAssets);\n\n    return useMemo(() => {\n        const completions: ComposerCompletion[] = [\n            ...forms.map((item) => contextCompletionForLocal(\"form\", item)),\n            ...modules.map((item) => contextCompletionForLocal(\"module\", item)),\n            ...serverModules.map((item) => contextCompletionForLocal(\"server_module\", item)),\n            ...assets.map((item) => contextCompletionForLocal(\"asset\", item)),\n        ];\n        for (const dependency of Object.values(dependencyStructure)) {\n            const packageName = dependency.packageName || dependency.name;\n            completions.push(\n                ...dependency.forms.map((item) => contextCompletionForDependency(\"form\", item, packageName)),\n                ...dependency.modules.map((item) => contextCompletionForDependency(\"module\", item, packageName)),\n                ...dependency.serverModules.map((item) =>\n                    contextCompletionForDependency(\"server_module\", item, packageName)\n                )\n            );\n        }\n        completions.push(\n            ...dependencyAssets.map((item) => {\n                const dependency = item.dependencyAppId ? dependencyStructure[item.dependencyAppId] : undefined;\n                const packageName = dependency?.packageName || dependency?.name || item.dependencyAppId || item.name;\n                return contextCompletionForDependency(\"asset\", item, packageName);\n            })\n        );\n        return completions;\n    }, [assets, dependencyAssets, dependencyStructure, forms, modules, serverModules]);\n}\n\nfunction useSlashCompletions(\n    availableCommands: AvailableCommand[],\n    localSlashCompletions: ComposerCompletion[]\n): ComposerCompletion[] {\n    return useMemo(() => {\n        return preferLocalSlashCompletions(\n            slashCompletionsForCommands(availableCommands, {\n                commandInfo: (command) => () => agentCommandInfoElement(command),\n            }),\n            localSlashCompletions\n        );\n    }, [availableCommands, localSlashCompletions]);\n}\n\nfunction useDollarCompletions(availableCommands: AvailableCommand[]): ComposerCompletion[] {\n    return useMemo(() => {\n        return dollarCompletionsForCommands(availableCommands, (command) => () => agentCommandInfoElement(command));\n    }, [availableCommands]);\n}\n\nfunction useSlashCommandsByName(availableCommands: AvailableCommand[]): Map<string, ComposerSlashCommand> {\n    return useMemo(() => {\n        const commandsByName = new Map<string, ComposerSlashCommand>();\n        for (const command of availableCommands) {\n            const slashCommandName = availableCommandSubmittedTokenName(command);\n            const promptCommand = {\n                name: slashCommandName.startsWith(\"$\") ? slashCommandName.slice(1) : slashCommandName,\n                slashCommandName,\n                type: availableCommandSourceLabel(command),\n                description: command.description,\n                inputHint: command.input?.hint,\n            };\n            commandsByName.set(slashCommandName, promptCommand);\n        }\n        return commandsByName;\n    }, [availableCommands]);\n}\n\nexport function usePromptComposerCompletions(\n    availableCommands: AvailableCommand[],\n    localSlashCompletions: ComposerCompletion[] = []\n) {\n    const contextCompletions = useContextCompletions();\n    const slashCompletions = useSlashCompletions(availableCommands, localSlashCompletions);\n    const dollarCompletions = useDollarCompletions(availableCommands);\n    const slashCommandsByName = useSlashCommandsByName(availableCommands);\n\n    return { contextCompletions, slashCompletions, dollarCompletions, slashCommandsByName };\n}\n","import { useDispatch, useSelector } from \"react-redux\";\nimport { Range, RangeSetBuilder } from \"@codemirror/state\";\nimport { Decoration, DecorationSet, EditorView, ViewPlugin, ViewUpdate, WidgetType } from \"@codemirror/view\";\nimport { useExtension } from \"@/code_mirror/utils/hooks.ts\";\nimport { getApp } from \"@/controllers/app\";\nimport { alert } from \"@/controllers/modals.ts\";\nimport type { AppNavTarget } from \"@/router/navTypes.ts\";\nimport { getUrlForNavTarget, navigate } from \"@/router/navigation.ts\";\nimport type { AnvilDispatch, AppId, AppState } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback.ts\";\nimport {\n    agentMarkdownDestinationPattern,\n    decodeAgentMarkdownHref,\n    isDependencyCodePath,\n    navTargetFromAgentMarkdownHref,\n} from \"../agentMarkdownLinks.ts\";\nimport { findSlashCommandTokenMatches, slashCommandDisplayText } from \"../conversationSkillCommands.ts\";\nimport { sourceLabelDisplayText } from \"./completionCommandHelpers.ts\";\nimport type { ComposerSlashCommand } from \"./completions.ts\";\n\n// Generated context links use escaped labels and encoded angle-bracket destinations\n// so valid code paths with spaces or markdown delimiters still round-trip into chips.\nconst contextLinkMatcher = new RegExp(\n    String.raw`\\[((?:\\\\.|[^\\]\\\\\\n])+)]\\((?:<(${agentMarkdownDestinationPattern})>|(${agentMarkdownDestinationPattern}))\\)`,\n    \"g\"\n);\nclass ContextLinkWidget extends WidgetType {\n    constructor(\n        readonly label: string,\n        readonly href: string,\n        readonly navTarget: AppNavTarget,\n        readonly appId: AppId,\n        readonly onNavigate: (navTarget: AppNavTarget) => void\n    ) {\n        super();\n    }\n\n    eq(other: ContextLinkWidget) {\n        return (\n            this.label === other.label &&\n            this.href === other.href &&\n            JSON.stringify(this.navTarget) === JSON.stringify(other.navTarget) &&\n            this.appId === other.appId &&\n            this.onNavigate === other.onNavigate\n        );\n    }\n\n    toDOM() {\n        const link = document.createElement(\"a\");\n        link.className = \"cm-agent-context-link\";\n        link.href = getUrlForNavTarget({ ...this.navTarget, appId: this.appId });\n        link.title = this.href;\n        link.textContent = this.label;\n        link.addEventListener(\"mousedown\", (e) => {\n            e.preventDefault();\n        });\n        link.addEventListener(\"click\", (e) => {\n            e.preventDefault();\n            this.onNavigate(this.navTarget);\n        });\n        return link;\n    }\n}\n\nclass DisabledContextLinkWidget extends WidgetType {\n    constructor(\n        readonly label: string,\n        readonly href: string\n    ) {\n        super();\n    }\n\n    eq(other: DisabledContextLinkWidget) {\n        return this.label === other.label && this.href === other.href;\n    }\n\n    toDOM() {\n        const span = document.createElement(\"span\");\n        span.className = \"cm-agent-context-link cm-agent-context-link-disabled\";\n        span.title = this.href;\n        span.textContent = this.label;\n        return span;\n    }\n}\n\nclass SlashTokenWidget extends WidgetType {\n    constructor(\n        readonly command: ComposerSlashCommand,\n        readonly onShowCommand: (command: ComposerSlashCommand) => void\n    ) {\n        super();\n    }\n\n    eq(other: SlashTokenWidget) {\n        return (\n            this.command.name === other.command.name &&\n            this.command.slashCommandName === other.command.slashCommandName &&\n            this.command.type === other.command.type &&\n            this.command.description === other.command.description &&\n            this.command.inputHint === other.command.inputHint &&\n            this.onShowCommand === other.onShowCommand\n        );\n    }\n\n    toDOM() {\n        const button = document.createElement(\"button\");\n        button.type = \"button\";\n        button.className = \"cm-agent-skill-token cursor-pointer\";\n        button.title = [sourceLabelDisplayText(this.command.type), this.command.description].filter(Boolean).join(\": \");\n        button.textContent = slashCommandDisplayText(this.command.slashCommandName);\n        button.addEventListener(\"mousedown\", (e) => {\n            e.preventDefault();\n        });\n        button.addEventListener(\"click\", (e) => {\n            e.preventDefault();\n            this.onShowCommand(this.command);\n        });\n        return button;\n    }\n}\n\nfunction makeDecorations(\n    view: EditorView,\n    onNavigate: (navTarget: AppNavTarget) => void,\n    appId: AppId,\n    app: AppState | null | undefined,\n    commandsByName: Map<string, ComposerSlashCommand>,\n    onShowCommand: (command: ComposerSlashCommand) => void\n): DecorationSet {\n    // The composer only supports a tiny markdown-like subset. A full markdown parser\n    // may be useful if this grows, but it is overkill for these constrained chips.\n    const ranges: Array<Range<Decoration>> = [];\n    const seenRanges = new Set<string>();\n    const addRange = (from: number, to: number, decoration: Decoration) => {\n        const key = `${from}:${to}`;\n        if (seenRanges.has(key)) {\n            return;\n        }\n        seenRanges.add(key);\n        ranges.push(decoration.range(from, to));\n    };\n\n    for (const visibleRange of view.visibleRanges) {\n        const from = view.state.doc.lineAt(visibleRange.from).from;\n        const to = view.state.doc.lineAt(visibleRange.to).to;\n        const text = view.state.sliceDoc(from, to);\n\n        contextLinkMatcher.lastIndex = 0;\n        for (const match of text.matchAll(contextLinkMatcher)) {\n            const href = decodeAgentMarkdownHref(match[2] ?? match[3]);\n            const label = match[1].replace(/\\\\([\\\\\\[\\]])/g, \"$1\");\n            const navTarget = navTargetFromAgentMarkdownHref(href, app);\n            if (navTarget) {\n                addRange(\n                    from + match.index!,\n                    from + match.index! + match[0].length,\n                    Decoration.replace({\n                        widget: new ContextLinkWidget(label, href, navTarget, appId, onNavigate),\n                    })\n                );\n            } else if (isDependencyCodePath(href)) {\n                addRange(\n                    from + match.index!,\n                    from + match.index! + match[0].length,\n                    Decoration.replace({\n                        widget: new DisabledContextLinkWidget(label, href),\n                    })\n                );\n            }\n        }\n\n        for (const match of findSlashCommandTokenMatches(text)) {\n            const rangeFrom = from + match.tokenStart;\n            const command = commandsByName.get(match.commandName);\n            if (command) {\n                addRange(\n                    rangeFrom,\n                    rangeFrom + match.token.length,\n                    Decoration.replace({\n                        widget: new SlashTokenWidget(command, onShowCommand),\n                    })\n                );\n            }\n        }\n    }\n\n    ranges.sort((a, b) => a.from - b.from || a.to - b.to);\n    const builder = new RangeSetBuilder<Decoration>();\n    for (const range of ranges) {\n        builder.add(range.from, range.to, range.value);\n    }\n    return builder.finish();\n}\n\nclass PromptComposerDecorations {\n    decorations: DecorationSet;\n\n    constructor(\n        view: EditorView,\n        readonly onNavigate: (navTarget: AppNavTarget) => void,\n        readonly appId: AppId,\n        readonly app: AppState | null | undefined,\n        readonly commandsByName: Map<string, ComposerSlashCommand>,\n        readonly onShowCommand: (command: ComposerSlashCommand) => void\n    ) {\n        this.decorations = makeDecorations(view, onNavigate, appId, app, commandsByName, onShowCommand);\n    }\n\n    update(update: ViewUpdate) {\n        if (update.docChanged || update.viewportChanged) {\n            this.decorations = makeDecorations(\n                update.view,\n                this.onNavigate,\n                this.appId,\n                this.app,\n                this.commandsByName,\n                this.onShowCommand\n            );\n        }\n    }\n}\n\nconst promptComposerDecorations = (\n    onNavigate: (navTarget: AppNavTarget) => void,\n    appId: AppId,\n    app: AppState | null | undefined,\n    commandsByName: Map<string, ComposerSlashCommand>,\n    onShowCommand: (command: ComposerSlashCommand) => void\n) => {\n    const plugin = ViewPlugin.define(\n        (view) => new PromptComposerDecorations(view, onNavigate, appId, app, commandsByName, onShowCommand),\n        {\n            decorations: (plugin) => plugin.decorations,\n        }\n    );\n    return [plugin, EditorView.atomicRanges.of((view) => view.plugin(plugin)?.decorations ?? Decoration.none)];\n};\n\nexport function usePromptComposerDecorations(\n    view: EditorView,\n    appId: AppId,\n    commandsByName: Map<string, ComposerSlashCommand>\n) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const app = useSelector(getApp);\n    const navigateContextLink = useEvent((navTarget: AppNavTarget) => {\n        dispatch(navigate(navTarget));\n    });\n    const showCommandDetails = useEvent((command: ComposerSlashCommand) => {\n        dispatch(\n            alert(\n                command.name,\n                <div className={\"space-y-4\"}>\n                    <code className={\"inline-block rounded-[0.4rem] bg-secondary-50 px-2 py-1 text-primary-800\"}>\n                        {slashCommandDisplayText(command.slashCommandName)}\n                    </code>\n                    <div className={\"text-light-grey1\"}>{sourceLabelDisplayText(command.type)}</div>\n                    <div className={\"whitespace-pre-line\"}>{command.description || \"No description available.\"}</div>\n                    {command.inputHint && <div className={\"text-light-grey1\"}>{command.inputHint}</div>}\n                </div>\n            )\n        );\n    });\n\n    useExtension(\n        view,\n        () => promptComposerDecorations(navigateContextLink, appId, app, commandsByName, showCommandDetails),\n        [appId, app, navigateContextLink, showCommandDetails, commandsByName]\n    );\n}\n","import { useMemo } from \"react\";\nimport type { AvailableCommand } from \"@agent-host/rpc_types.ts\";\nimport { autocompletion, type Completion, startCompletion } from \"@codemirror/autocomplete\";\nimport { insertNewlineAndIndent } from \"@codemirror/commands\";\nimport { Extension, Prec } from \"@codemirror/state\";\nimport { type Command, EditorView, type KeyBinding, keymap } from \"@codemirror/view\";\nimport { icon } from \"@fortawesome/fontawesome-svg-core\";\nimport { faCube } from \"@fortawesome/pro-regular-svg-icons/faCube\";\nimport { faPage } from \"@fortawesome/pro-regular-svg-icons/faPage\";\nimport { faRobot } from \"@fortawesome/pro-regular-svg-icons/faRobot\";\nimport { useExtension } from \"@/code_mirror/utils/hooks.ts\";\nimport { useTheme } from \"@/theme/styles.ts\";\nimport type { AppId } from \"@/types\";\nimport { checkMeta } from \"@/util\";\nimport {\n    type ComposerCompletion,\n    type ComposerSlashCommand,\n    completionSource,\n    usePromptComposerCompletions,\n} from \"./completions.ts\";\nimport { usePromptComposerDecorations } from \"./decorations.tsx\";\nimport type { AddImageFiles } from \"./images.tsx\";\n\ntype PromptCompletionDisplay = Completion & {\n    sourceLabel?: string;\n    parentPath?: string;\n};\n\nfunction renderPromptCompletionIcon(completion: Completion): Node | null {\n    const completionTypes = completion.type?.split(/\\s+/) ?? [];\n    const iconDefinition = completionTypes.includes(\"agent-skill\")\n        ? faCube\n        : completionTypes.includes(\"agent-command\")\n          ? faRobot\n          : completionTypes.includes(\"file\")\n            ? faPage\n            : null;\n    if (!iconDefinition) {\n        return null;\n    }\n\n    const iconElement = document.createElement(\"span\");\n    iconElement.className = \"cm-agent-completion-icon\";\n    iconElement.appendChild(icon(iconDefinition).node[0]);\n    return iconElement;\n}\n\nfunction renderPromptCompletionParent(completion: Completion): Node | null {\n    const { parentPath } = completion as PromptCompletionDisplay;\n    if (!parentPath) {\n        return null;\n    }\n    const parent = document.createElement(\"span\");\n    parent.className = \"cm-agent-completion-parent\";\n    parent.textContent = parentPath;\n    parent.title = parentPath;\n    return parent;\n}\n\nfunction renderPromptCompletionMetadata(completion: Completion): Node | null {\n    const { sourceLabel } = completion as PromptCompletionDisplay;\n    if (!sourceLabel) {\n        return null;\n    }\n\n    const metadata = document.createElement(\"span\");\n    metadata.className = \"cm-agent-completion-metadata\";\n\n    const sourceElement = document.createElement(\"span\");\n    sourceElement.className = \"cm-agent-completion-source\";\n    sourceElement.textContent = sourceLabel;\n    metadata.appendChild(sourceElement);\n\n    return metadata;\n}\n\nexport function usePromptComposerTheme(view: EditorView) {\n    const theme = useTheme();\n    const composerTheme = useMemo(\n        () =>\n            EditorView.theme(\n                {\n                    \"&\": {\n                        minHeight: \"6.4rem\",\n                        maxHeight: \"18rem\",\n                        border: \"0\",\n                        borderRadius: 0,\n                        background: theme.formInput.background.toString(),\n                        color: theme.formInput.color.toString(),\n                    },\n                    \"&.cm-focused\": {\n                        outline: theme.formInput.focusOutline ?? \"none\",\n                        outlineOffset: theme.formInput.focusOffset ?? 0,\n                    },\n                    \".cm-scroller\": {\n                        maxHeight: \"18rem\",\n                        overflow: \"auto\",\n                        fontFamily: \"Poppins !important\",\n                        fontSize: \"1.5rem !important\",\n                        fontWeight: \"400 !important\",\n                        lineHeight: \"2.3rem !important\",\n                    },\n                    \".cm-content\": {\n                        minHeight: \"6.4rem\",\n                        padding: \"1.1rem 1.5rem\",\n                    },\n                    \".cm-line\": {\n                        color: theme.formInput.color.toString(),\n                    },\n                    \".cm-placeholder\": {\n                        color: `${theme.agentConversations.promptComposer.placeholderColor} !important`,\n                    },\n                    \".cm-content .cm-line span\": {\n                        color: \"inherit\",\n                        fontStyle: \"inherit\",\n                        fontWeight: \"inherit\",\n                        textDecoration: \"none\",\n                    },\n                    \".cm-agent-context-link, .cm-agent-skill-token\": {\n                        borderRadius: \"0.4rem\",\n                        padding: \"0.1rem 0.35rem\",\n                        background: theme.palette.primary.fade(0.86).toString(),\n                        color: theme.palette.primary.toString(),\n                    },\n                    \".cm-agent-skill-token\": {\n                        border: \"0\",\n                        background: theme.palette.secondary.fade(0.86).toString(),\n                        color: theme.palette.secondary.toString(),\n                        cursor: \"pointer\",\n                        font: \"inherit\",\n                        lineHeight: \"inherit\",\n                        margin: \"0\",\n                        verticalAlign: \"baseline\",\n                    },\n                    \".cm-agent-context-link-disabled\": {\n                        cursor: \"default\",\n                        opacity: \"0.75\",\n                    },\n                    \".cm-tooltip-autocomplete.cm-agent-prompt-autocomplete > ul\": {\n                        width: \"min(52rem, 95vw)\",\n                        maxWidth: \"min(52rem, 95vw)\",\n                    },\n                    \".cm-tooltip-autocomplete.cm-agent-prompt-autocomplete > ul > li\": {\n                        display: \"flex\",\n                        alignItems: \"baseline\",\n                        gap: \"0.8rem\",\n                        boxSizing: \"border-box\",\n                        lineHeight: \"1.6\",\n                        padding: \"0.25rem 0.6rem\",\n                    },\n                    \".cm-tooltip-autocomplete.cm-agent-prompt-autocomplete .cm-completionIcon\": {\n                        flex: \"0 0 auto\",\n                    },\n                    \".cm-tooltip-autocomplete.cm-agent-prompt-autocomplete .cm-completionIcon-agent-command, .cm-tooltip-autocomplete.cm-agent-prompt-autocomplete .cm-completionIcon-agent-skill, .cm-tooltip-autocomplete.cm-agent-prompt-autocomplete .cm-completionIcon-file\": {\n                        display: \"none\",\n                    },\n                    \".cm-agent-completion-icon\": {\n                        display: \"inline-flex\",\n                        flex: \"0 0 auto\",\n                        width: \"1.3rem\",\n                        justifyContent: \"center\",\n                        opacity: \"0.7\",\n                    },\n                    \".cm-agent-completion-icon svg\": {\n                        height: \"1.25rem\",\n                        width: \"1.25rem\",\n                    },\n                    \".cm-tooltip-autocomplete.cm-agent-prompt-autocomplete .cm-completionLabel\": {\n                        flex: \"0 0 auto\",\n                        minWidth: \"0\",\n                        maxWidth: \"22rem\",\n                        overflow: \"hidden\",\n                        textOverflow: \"ellipsis\",\n                        fontFamily: \"Source Code Pro, monospace\",\n                        fontWeight: \"600\",\n                    },\n                    \".cm-agent-completion-metadata\": {\n                        display: \"flex\",\n                        alignItems: \"baseline\",\n                        minWidth: \"0\",\n                        flex: \"1 1 auto\",\n                    },\n                    \".cm-tooltip-autocomplete.cm-agent-prompt-autocomplete .cm-agent-context-completion .cm-completionLabel\": {\n                        maxWidth: \"70%\",\n                    },\n                    \".cm-agent-completion-parent\": {\n                        minWidth: \"0\",\n                        flex: \"0 1 auto\",\n                        overflow: \"hidden\",\n                        textOverflow: \"ellipsis\",\n                        fontSize: \"1.2rem\",\n                        opacity: \"0.65\",\n                    },\n                    \".cm-tooltip-autocomplete.cm-agent-prompt-autocomplete .cm-agent-context-completion .cm-completionDetail\": {\n                        flex: \"0 0 auto\",\n                        marginLeft: \"auto\",\n                    },\n                    \".cm-agent-completion-source\": {\n                        flex: \"0 0 auto\",\n                        marginLeft: \"auto\",\n                        fontFamily: \"Poppins, sans-serif\",\n                        fontSize: \"1.2rem\",\n                        fontStyle: \"normal\",\n                        opacity: \"0.65\",\n                    },\n                    \".cm-tooltip-autocomplete.cm-agent-prompt-autocomplete > ul > completion-section\": {\n                        fontFamily: \"Poppins, sans-serif\",\n                        fontSize: \"1.2rem\",\n                        lineHeight: \"1.6\",\n                    },\n                },\n                { dark: theme.isDark }\n            ),\n        [theme]\n    );\n    useExtension(view, () => composerTheme, [composerTheme]);\n}\n\nfunction promptComposerKeymap(submitCommand: Command): KeyBinding[] {\n    return [\n        { key: \"Enter\", run: submitCommand, preventDefault: true },\n        { key: \"Mod-Enter\", run: submitCommand, preventDefault: true },\n        { key: \"Shift-Enter\", run: insertNewlineAndIndent },\n    ];\n}\n\nexport function usePromptTriggerCompletion(view: EditorView) {\n    useExtension(\n        view,\n        () =>\n            EditorView.domEventHandlers({\n                keydown(event, view) {\n                    if (event.key !== \"@\" && event.key !== \"/\" && event.key !== \"$\") {\n                        return false;\n                    }\n                    if (event.metaKey || event.ctrlKey || event.altKey) {\n                        return false;\n                    }\n                    event.preventDefault();\n                    view.dispatch(view.state.replaceSelection(event.key));\n                    startCompletion(view);\n                    return true;\n                },\n            }),\n        []\n    );\n}\n\nexport function usePromptImagePaste(view: EditorView, addImageFiles: AddImageFiles) {\n    useExtension(\n        view,\n        () =>\n            EditorView.domEventHandlers({\n                paste(event) {\n                    const files = event.clipboardData?.files;\n                    if (!files || files.length === 0) {\n                        return false;\n                    }\n                    if (!Array.from(files).some((file) => file.type.startsWith(\"image/\"))) {\n                        return false;\n                    }\n                    event.preventDefault();\n                    void addImageFiles(files);\n                    return true;\n                },\n            }),\n        [addImageFiles]\n    );\n}\n\nexport function usePromptSearchKeymap(view: EditorView, onOpenSearch: () => void) {\n    useExtension(\n        view,\n        () =>\n            Prec.highest(\n                EditorView.domEventHandlers({\n                    keydown(event) {\n                        if (event.key.toLocaleLowerCase() !== \"f\" || !checkMeta(event)) {\n                            return false;\n                        }\n                        event.preventDefault();\n                        event.stopPropagation();\n                        onOpenSearch();\n                        return true;\n                    },\n                })\n            ),\n        []\n    );\n}\n\nexport function usePromptSubmitKeymap(view: EditorView, submitCommand: Command) {\n    useExtension(view, () => Prec.highest(keymap.of(promptComposerKeymap(submitCommand))), [submitCommand]);\n}\n\nexport function usePromptPlanModeKeymap(view: EditorView, togglePlanMode: () => void, enabled: boolean) {\n    useExtension(\n        view,\n        () =>\n            enabled\n                ? Prec.highest(\n                      keymap.of([\n                          {\n                              key: \"Shift-Tab\",\n                              run: () => {\n                                  togglePlanMode();\n                                  return true;\n                              },\n                              preventDefault: true,\n                          },\n                      ])\n                  )\n                : [],\n        [enabled, togglePlanMode]\n    );\n}\n\nexport function usePromptAutocompletion(\n    view: EditorView,\n    availableCommands: AvailableCommand[],\n    localSlashCompletions: ComposerCompletion[] = []\n) {\n    const { contextCompletions, slashCompletions, dollarCompletions, slashCommandsByName } =\n        usePromptComposerCompletions(availableCommands, localSlashCompletions);\n\n    useExtension(\n        view,\n        (): Extension =>\n            autocompletion({\n                override: [\n                    completionSource(\"@\", contextCompletions),\n                    completionSource(\"/\", slashCompletions),\n                    completionSource(\"$\", dollarCompletions),\n                ],\n                tooltipClass: () => \"cm-agent-prompt-autocomplete\",\n                optionClass: (completion) => (completion.displayLabel !== undefined ? \"cm-agent-context-completion\" : \"\"),\n                addToOptions: [\n                    { render: renderPromptCompletionIcon, position: 20 },\n                    { render: renderPromptCompletionParent, position: 60 },\n                    { render: renderPromptCompletionMetadata, position: 75 },\n                ],\n            }),\n        [contextCompletions, dollarCompletions, slashCompletions]\n    );\n\n    return { slashCommandsByName };\n}\n\nexport function usePromptDecorations(\n    view: EditorView,\n    appId: AppId,\n    commandsByName: Map<string, ComposerSlashCommand>\n) {\n    usePromptComposerDecorations(view, appId, commandsByName);\n}\n","import { type ChangeEvent, type DragEvent, useRef, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport type { PromptRequestMessage } from \"@agent-host/rpc_types.ts\";\nimport { getPromptComposerDraft, setPromptComposerDraftImages } from \"@/agent/promptDrafts\";\nimport type { PromptComposerDraftImage } from \"@/agent/promptDrafts\";\nimport type { ConversationPid } from \"@/agent/types\";\nimport { alert } from \"@/controllers/modals.ts\";\nimport type { AnvilDispatch } from \"@/types\";\nimport { useStateWithCustomUpdate } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback.ts\";\n\nexport interface ComposerImage extends PromptComposerDraftImage {}\n\nexport type AddImageFiles = (files: FileList | File[]) => Promise<void>;\n\nexport const MAX_IMAGE_ATTACHMENTS = 8;\nexport const MAX_IMAGE_BYTES = 10 * 1024 * 1024;\nexport const IMAGE_SIZE_LIMIT_LABEL = `${Math.round(MAX_IMAGE_BYTES / (1024 * 1024))}MB`;\n\nconst readFileAsDataUrl = (file: File): Promise<string> =>\n    new Promise((resolve, reject) => {\n        const reader = new FileReader();\n        reader.onload = () => {\n            if (typeof reader.result === \"string\") {\n                resolve(reader.result);\n            } else {\n                reject(new Error(\"Could not read image file.\"));\n            }\n        };\n        reader.onerror = () => reject(reader.error ?? new Error(\"Could not read image file.\"));\n        reader.readAsDataURL(file);\n    });\n\nconst dataUrlPayload = (dataUrl: string): string | null => {\n    const match = /^data:image\\/[^;,]+(?:;[^,]*)?;base64,(.*)$/i.exec(dataUrl);\n    return match?.[1] ?? null;\n};\n\nconst dataTransferHasFiles = (dataTransfer: DataTransfer): boolean =>\n    Array.from(dataTransfer.types).includes(\"Files\") ||\n    Array.from(dataTransfer.items).some((item) => item.kind === \"file\") ||\n    dataTransfer.files.length > 0;\n\nconst dataTransferHasImageFile = (dataTransfer: DataTransfer): boolean => {\n    const items = Array.from(dataTransfer.items);\n    if (items.length > 0) {\n        return items.some((item) => item.kind === \"file\" && item.type.startsWith(\"image/\"));\n    }\n    return Array.from(dataTransfer.files).some((file) => file.type.startsWith(\"image/\"));\n};\n\nexport const imageToContentBlock = (image: ComposerImage): PromptRequestMessage[\"prompt\"][number] => {\n    const data = dataUrlPayload(image.dataUrl);\n    if (!data) {\n        throw new Error(`Image \"${image.name}\" could not be encoded for upload.`);\n    }\n    return {\n        type: \"image\",\n        data,\n        mimeType: image.mimeType,\n        _meta: {\n            name: image.name,\n            sizeBytes: image.sizeBytes,\n        },\n    };\n};\n\nexport function useComposerImages(conversationPid: ConversationPid) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const fileInputRef = useRef<HTMLInputElement>(null);\n    const dragDepthRef = useRef(0);\n    const [images, setImages] = useStateWithCustomUpdate<ComposerImage[]>(\n        () => getPromptComposerDraft(conversationPid)?.images ?? [],\n        (images) => {\n            setPromptComposerDraftImages(conversationPid, images);\n            return images;\n        }\n    );\n    const [draggingImages, setDraggingImages] = useState(false);\n\n    const addImageFiles: AddImageFiles = useEvent(async (files) => {\n        const nextImages: ComposerImage[] = [];\n        let error: string | null = null;\n\n        for (const file of Array.from(files)) {\n            if (!file.type.startsWith(\"image/\")) {\n                error = \"Only image files can be attached.\";\n                continue;\n            }\n            if (file.size > MAX_IMAGE_BYTES) {\n                error = `Images must be ${IMAGE_SIZE_LIMIT_LABEL} or smaller.`;\n                continue;\n            }\n            if (images.length + nextImages.length >= MAX_IMAGE_ATTACHMENTS) {\n                error = `You can attach up to ${MAX_IMAGE_ATTACHMENTS} images per message.`;\n                break;\n            }\n            nextImages.push({\n                id: crypto.randomUUID(),\n                name: file.name || \"image\",\n                mimeType: file.type,\n                sizeBytes: file.size,\n                dataUrl: await readFileAsDataUrl(file),\n            });\n        }\n\n        if (nextImages.length > 0) {\n            setImages((current) => [...current, ...nextImages]);\n        }\n        if (error) {\n            dispatch(alert(\"Image upload\", error));\n        }\n    });\n\n    const removeImage = useEvent((id: string) => {\n        setImages((current) => current.filter((image) => image.id !== id));\n    });\n\n    const clearImages = useEvent(() => {\n        setImages([]);\n    });\n\n    const restoreImages = useEvent((images: ComposerImage[]) => {\n        setImages(images);\n    });\n\n    const onImageInputChange = useEvent((event: ChangeEvent<HTMLInputElement>) => {\n        if (event.currentTarget.files) {\n            void addImageFiles(event.currentTarget.files);\n        }\n        event.currentTarget.value = \"\";\n    });\n\n    const onAttachImageClick = useEvent(() => {\n        if (images.length >= MAX_IMAGE_ATTACHMENTS) {\n            dispatch(alert(\"Image upload\", `You can attach up to ${MAX_IMAGE_ATTACHMENTS} images per message.`));\n            return;\n        }\n        fileInputRef.current?.click();\n    });\n\n    const onDragEnter = useEvent((event: DragEvent<HTMLDivElement>) => {\n        if (!dataTransferHasFiles(event.dataTransfer)) {\n            return;\n        }\n        event.preventDefault();\n        dragDepthRef.current += 1;\n        setDraggingImages(dataTransferHasImageFile(event.dataTransfer));\n    });\n\n    const onDragOver = useEvent((event: DragEvent<HTMLDivElement>) => {\n        if (!dataTransferHasFiles(event.dataTransfer)) {\n            return;\n        }\n        event.preventDefault();\n        event.dataTransfer.dropEffect = \"copy\";\n        setDraggingImages(dataTransferHasImageFile(event.dataTransfer));\n    });\n\n    const onDragLeave = useEvent((event: DragEvent<HTMLDivElement>) => {\n        if (!dataTransferHasFiles(event.dataTransfer)) {\n            return;\n        }\n        event.preventDefault();\n        dragDepthRef.current = Math.max(0, dragDepthRef.current - 1);\n        if (dragDepthRef.current === 0) {\n            setDraggingImages(false);\n        }\n    });\n\n    const onDrop = useEvent((event: DragEvent<HTMLDivElement>) => {\n        const files = event.dataTransfer.files;\n        if (!files || files.length === 0) {\n            return;\n        }\n        event.preventDefault();\n        dragDepthRef.current = 0;\n        setDraggingImages(false);\n        void addImageFiles(files);\n    });\n\n    const inputComponent = (\n        <input\n            ref={fileInputRef}\n            type=\"file\"\n            accept=\"image/*\"\n            multiple\n            className=\"hidden\"\n            onChange={onImageInputChange}\n        />\n    );\n\n    return {\n        images,\n        addImageFiles,\n        removeImage,\n        clearImages,\n        restoreImages,\n        draggingImages,\n        inputComponent,\n        onAttachImageClick,\n        dragHandlers: {\n            onDragEnter: onDragEnter,\n            onDragOver: onDragOver,\n            onDragLeave: onDragLeave,\n            onDrop: onDrop,\n        },\n    };\n}\n","import type { ReactNode } from \"react\";\nimport type { UsageUpdate } from \"@agent-host/rpc_types\";\nimport { faSend } from \"@fortawesome/pro-light-svg-icons/faSend\";\nimport { faTimes } from \"@fortawesome/pro-light-svg-icons/faTimes\";\nimport { faArrowUp } from \"@fortawesome/pro-solid-svg-icons\";\nimport { faStop } from \"@fortawesome/pro-solid-svg-icons/faStop\";\nimport { formatTokenCount, percentUsed } from \"@/agent/usage\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { cx } from \"@/theme/styles\";\nimport type { ComposerImage } from \"./images\";\n\nconst ContextUsageIndicator = ({ usage }: { usage: UsageUpdate | null | undefined }) => {\n    const usedPercent = usage ? percentUsed(usage.used, usage.size) : 0;\n    const radius = 11;\n    const circumference = 2 * Math.PI * radius;\n    const dashOffset = circumference * (1 - usedPercent / 100);\n    const [tooltip, tooltipRef] = useTooltip(\n        usage ? (\n            <div className={\"block w-96 text-center whitespace-pre-wrap\"}>\n                <div>\n                    {usedPercent}% context used ({formatTokenCount(usage.used)}/{formatTokenCount(usage.size)} tokens)\n                </div>\n                {usage.compactsAutomatically && (\n                    <div className={\"text-base text-light-grey1\"}>Automatically compacts its context when needed.</div>\n                )}\n            </div>\n        ) : null,\n        \"top\"\n    );\n\n    if (!usage) {\n        return null;\n    }\n\n    return (\n        <div className={\"flex items-center\"}>\n            {tooltip}\n            <div\n                ref={tooltipRef}\n                tabIndex={0}\n                className={\"focus:outline-none\"}\n                aria-label={`Context window: ${usedPercent}% used, ${formatTokenCount(usage.used)} of ${formatTokenCount(usage.size)} tokens used`}>\n                <svg className={\"block h-10 w-10\"} viewBox={\"0 0 26 26\"} aria-hidden={\"true\"}>\n                    <circle\n                        cx={\"13\"}\n                        cy={\"13\"}\n                        r={radius}\n                        fill={\"none\"}\n                        stroke={\"currentColor\"}\n                        className={\"text-sectionborder\"}\n                        strokeWidth={\"3.4\"}\n                    />\n                    <circle\n                        cx={\"13\"}\n                        cy={\"13\"}\n                        r={radius}\n                        fill={\"none\"}\n                        stroke={\"currentColor\"}\n                        className={\"text-primary\"}\n                        strokeWidth={\"3.4\"}\n                        strokeLinecap={\"round\"}\n                        strokeDasharray={circumference}\n                        strokeDashoffset={dashOffset}\n                        transform={\"rotate(-90 13 13)\"}\n                    />\n                    <text\n                        x={\"13\"}\n                        y={\"13.5\"}\n                        textAnchor={\"middle\"}\n                        dominantBaseline={\"middle\"}\n                        className={\"fill-current text-light-grey1\"}\n                        fontSize={usedPercent === 100 ? \"9\" : \"10\"}\n                        fontWeight={\"600\"}>\n                        {usedPercent}\n                    </text>\n                </svg>\n            </div>\n        </div>\n    );\n};\n\ninterface ComposerImageTrayProps {\n    images: ComposerImage[];\n    onRemoveImage(id: string): void;\n}\n\nexport const ComposerImageTray = ({ images, onRemoveImage }: ComposerImageTrayProps) => {\n    if (images.length === 0) {\n        return null;\n    }\n\n    return (\n        <div\n            className={cx(\n                \"flex flex-wrap gap-3 border-b p-3\",\n                \"border-sectionborder\",\n                \"dark:border-dark-sectionborder\"\n            )}>\n            {images.map((image) => (\n                <div\n                    key={image.id}\n                    className={cx(\n                        \"group relative flex w-28 flex-col overflow-hidden rounded border\",\n                        \"border-sectionborder bg-white\",\n                        \"dark:border-dark-sectionborder dark:bg-dark-bg3\"\n                    )}>\n                    <img src={image.dataUrl} alt={image.name} className={\"h-24 w-full object-cover\"} />\n                    <span\n                        className={cx(\n                            \"truncate border-t px-2 py-1 text-xs\",\n                            \"border-sectionborder text-light-grey1\",\n                            \"dark:border-dark-sectionborder dark:text-dark-fg1\"\n                        )}\n                        title={image.name}>\n                        {image.name}\n                    </span>\n                    <LinkInternal\n                        className={\n                            \"absolute top-1 right-1 flex h-6 w-6 items-center justify-center rounded bg-white/90 text-light-grey1 opacity-0 shadow-sm group-hover:opacity-75 hover:opacity-100\"\n                        }\n                        icon={faTimes}\n                        onClick={() => onRemoveImage(image.id)}\n                        title={`Remove ${image.name}`}\n                        aria-label={`Remove ${image.name}`}\n                    />\n                </div>\n            ))}\n        </div>\n    );\n};\n\ninterface SubmitStopButtonProps {\n    turnActive: boolean;\n    onSubmitClick(): void;\n    onStopClick(): void;\n}\n\nconst SubmitStopButton = ({ turnActive, onSubmitClick, onStopClick }: SubmitStopButtonProps) =>\n    turnActive ? (\n        <Button small variant={\"outlined\"} icon={faStop} onClick={onStopClick} title={\"Stop\"} titlePosition={\"top\"} />\n    ) : (\n        <Button\n            small\n            variant={\"primary\"}\n            icon={faArrowUp}\n            onClick={onSubmitClick}\n            title={\"Send\"}\n            titlePosition={\"top\"}\n            className=\"overflow-hidden rounded-full\"\n        />\n    );\n\ninterface ComposerToolbarProps {\n    usage?: UsageUpdate | null;\n    children?: ReactNode;\n    configuration?: ReactNode;\n    controls?: ReactNode;\n    onSubmitClick(): void;\n    onStopClick(): void;\n    turnActive: boolean;\n}\n\nexport const ComposerToolbar = ({\n    usage,\n    children,\n    configuration,\n    controls,\n    onSubmitClick,\n    onStopClick,\n    turnActive,\n}: ComposerToolbarProps) => (\n    <div\n        className={cx(\n            \"grid min-h-14 min-w-0 grid-cols-[auto_minmax(0,1fr)_auto_auto_auto_auto] items-center gap-2 px-2 pb-1\",\n            \"@min-[60.1rem]/composer:grid-cols-[auto_1fr_auto_auto_auto_auto] @min-[60.1rem]/composer:px-4\"\n        )}>\n        <div className={\"flex shrink-0 items-center gap-2\"}>{children}</div>\n        <div className={\"hidden @min-[60.1rem]/composer:block\"} />\n        <div className={\"shrink-0\"}>\n            <ContextUsageIndicator usage={usage} />\n        </div>\n        <div className={\"min-w-0 @min-[60.1rem]/composer:justify-self-end\"}>{configuration}</div>\n        <div className={\"flex shrink-0 items-center gap-2\"}>{controls}</div>\n        <div className={\"shrink-0\"}>\n            <SubmitStopButton turnActive={turnActive} onSubmitClick={onSubmitClick} onStopClick={onStopClick} />\n        </div>\n    </div>\n);\n","import { type ReactNode, useMemo, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport type { AvailableCommand, InteractionMode, PromptRequestMessage, UsageUpdate } from \"@agent-host/rpc_types.ts\";\nimport { faCheck } from \"@fortawesome/pro-regular-svg-icons/faCheck\";\nimport { faImage } from \"@fortawesome/pro-regular-svg-icons/faImage\";\nimport { faListRadio } from \"@fortawesome/pro-regular-svg-icons/faListRadio\";\nimport { faPlus } from \"@fortawesome/pro-regular-svg-icons/faPlus\";\nimport { faTimes } from \"@fortawesome/pro-regular-svg-icons/faTimes\";\nimport { faXmark } from \"@fortawesome/pro-regular-svg-icons/faXmark\";\nimport { faArrowUp } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { ComposerConfiguration } from \"@/agent/components/promptComposer/configurationChooser.tsx\";\nimport { usePromptComposerDraftView } from \"@/agent/promptDrafts\";\nimport { displayedConversationConfig } from \"@/agent/sessionCapabilities.ts\";\nimport {\n    ConversationConfig,\n    ConversationInfo,\n    ConversationModel,\n    SessionConfigUpdateByCategory,\n} from \"@/agent/types.ts\";\nimport { CodeMirrorElement } from \"@/code_mirror/element.tsx\";\nimport { useBaseTheme } from \"@/code_mirror/theme\";\nimport { useFocusCodeOnSelection } from \"@/code_mirror/utils/hooks.ts\";\nimport { Button } from \"@/components/reusable/Button.tsx\";\nimport DropdownMenu, { type DropDownMenuItems } from \"@/components/reusable/DropdownMenu.tsx\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal.tsx\";\nimport { ContentTextAreaInput } from \"@/components/reusable/SharedComponents.tsx\";\nimport { createAppWithPrompt, getAppId } from \"@/controllers/app\";\nimport { getAgentsChatsLocation, getUser } from \"@/controllers/ide.ts\";\nimport { modal } from \"@/controllers/modals.ts\";\nimport { cx } from \"@/theme/styles.ts\";\nimport { AnvilDispatch } from \"@/types/index.ts\";\nimport useEvent from \"@/util/useEventCallback.ts\";\nimport { AgentChooser } from \"../agentChooser.tsx\";\nimport { isTurnActive, useConversationCallbacks } from \"../hooks.ts\";\nimport { usePromptDictation } from \"./PromptDictation.tsx\";\nimport {\n    type ComposerCompletion,\n    omitProviderPlanCommand,\n} from \"./promptComposer/completionCommandHelpers.ts\";\nimport {\n    usePromptAutocompletion,\n    usePromptComposerTheme,\n    usePromptDecorations,\n    usePromptImagePaste,\n    usePromptPlanModeKeymap,\n    usePromptSearchKeymap,\n    usePromptSubmitKeymap,\n    usePromptTriggerCompletion,\n} from \"./promptComposer/editorFeatures.ts\";\nimport { MAX_IMAGE_ATTACHMENTS, useComposerImages } from \"./promptComposer/images.tsx\";\nimport { usePromptSubmit } from \"./promptComposer/submit.ts\";\nimport { ComposerImageTray, ComposerToolbar } from \"./promptComposer/ui.tsx\";\nimport { AgentComposerCard } from \"./AgentComposerCard.tsx\";\n\ninterface PromptComposerProps {\n    onSubmit(request: {\n        prompt: PromptRequestMessage[\"prompt\"];\n        interaction_mode: InteractionMode;\n    }): Promise<void> | void;\n    onStop(): void;\n    onChangeConfig(config: SessionConfigUpdateByCategory): Promise<void> | void;\n    availableCommands: AvailableCommand[];\n    isVisible: boolean;\n    usage?: UsageUpdate | null;\n    config: ConversationConfig;\n    turnActive: boolean;\n    conversationInfo: ConversationInfo;\n    conversation: ConversationModel;\n    onOpenSearch(): void;\n    disabled: boolean;\n    header?: ReactNode;\n}\n\nconst planCompletion = (togglePlanMode: () => void): ComposerCompletion => ({\n    label: \"plan\",\n    description: \"Toggle Plan mode\",\n    sourceLabel: \"System\",\n    type: \"agent-command\",\n    section: { name: \"Commands\", rank: 0 },\n    apply: (view, from, to) => {\n        view.dispatch({ changes: { from, to, insert: \"\" }, selection: { anchor: from } });\n        togglePlanMode();\n    },\n});\n\nexport const PromptComposer = ({\n    onSubmit,\n    onStop,\n    onChangeConfig,\n    availableCommands,\n    isVisible,\n    usage,\n    config: sessionConfig,\n    turnActive,\n    conversationInfo,\n    conversation,\n    onOpenSearch,\n    disabled,\n    header,\n}: PromptComposerProps) => {\n    // While the session starts, show the options this provider offered last time so the\n    // model, effort and Plan mode can be chosen before the first prompt runs.\n    const sessionStatus = conversation.sessionStatus;\n    const agentType = conversationInfo.agent_type;\n    const config = useMemo(\n        () => displayedConversationConfig(sessionConfig, { sessionStatus, agentType }),\n        [sessionConfig, sessionStatus, agentType]\n    );\n    const user = useSelector(getUser);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const isDisabled = disabled || !!user?.impersonator;\n\n    const appId = useSelector(getAppId)!;\n    const conversationPid = conversationInfo.conversation_pid;\n    const composerImages = useComposerImages(conversationPid);\n\n    const { view, clearSavedDraft } = usePromptComposerDraftView(conversationPid);\n    const { onChangeAgentType, onChangeInteractionMode } = useConversationCallbacks(conversationInfo);\n    const supportsPlan = config.interaction_modes?.includes(\"plan\") ?? false;\n    const interactionMode = conversation.draftInteractionMode?.mode ?? config.interaction_mode;\n    const planModeActive = interactionMode === \"plan\";\n    const togglePlanMode = useEvent(() => {\n        if (supportsPlan && !turnActive) {\n            onChangeInteractionMode(planModeActive ? \"build\" : \"plan\");\n        }\n    });\n    const onPromptSubmit = useEvent((prompt: PromptRequestMessage[\"prompt\"]) =>\n        onSubmit({ prompt, interaction_mode: interactionMode })\n    );\n\n    const dictation = usePromptDictation(view, isVisible);\n    const { submit, submitCommand, submissionError, clearSubmissionError } = usePromptSubmit({\n        onSubmit: onPromptSubmit,\n        onPromptCleared: clearSavedDraft,\n        images: composerImages.images,\n        clearImages: composerImages.clearImages,\n        restoreImages: composerImages.restoreImages,\n        dictation,\n        turnActive,\n    });\n    const onSubmitClick = useEvent(() => void submit(view));\n    const onOpenUsage = useEvent(() => {\n        void dispatch(modal(\"agentUsage\", { agentType: conversationInfo.agent_type, usage }));\n    });\n\n    const usageCompletion = useMemo<ComposerCompletion>(\n        () => ({\n            label: \"usage\",\n            description: \"Show context and provider usage limits\",\n            sourceLabel: \"System\",\n            type: \"agent-command\",\n            section: { name: \"Commands\", rank: 0 },\n            apply: (editorView, from, to) => {\n                editorView.dispatch({ changes: { from, to, insert: \"\" }, selection: { anchor: from } });\n                onOpenUsage();\n            },\n        }),\n        [onOpenUsage]\n    );\n    const localSlashCompletions = useMemo(\n        () => [\n            ...(supportsPlan && !turnActive ? [planCompletion(togglePlanMode)] : []),\n            ...(availableCommands.length > 0 ? [usageCompletion] : []),\n        ],\n        [supportsPlan, togglePlanMode, turnActive, availableCommands.length, usageCompletion]\n    );\n    // Plan is a client-owned command: never expose a provider duplicate, especially when\n    // an older host has not advertised Plan support.\n    const providerCommands = useMemo(() => omitProviderPlanCommand(availableCommands), [availableCommands]);\n\n    // CodeMirror features are kept visible here so each can be understood or disabled independently.\n    useBaseTheme(view);\n    useFocusCodeOnSelection(view, isVisible);\n    usePromptComposerTheme(view);\n    usePromptTriggerCompletion(view);\n    usePromptImagePaste(view, composerImages.addImageFiles);\n    usePromptSearchKeymap(view, onOpenSearch);\n    usePromptSubmitKeymap(view, submitCommand);\n    usePromptPlanModeKeymap(view, togglePlanMode, supportsPlan && !turnActive);\n    const { slashCommandsByName } = usePromptAutocompletion(view, providerCommands, localSlashCompletions);\n    usePromptDecorations(view, appId, slashCommandsByName);\n\n    const composerMenuItems: DropDownMenuItems = () => [\n        ...(supportsPlan\n            ? [\n                  [\n                      <span key=\"plan\" className=\"flex min-w-40 items-center justify-between gap-6\">\n                          <span>Plan</span>\n                          {planModeActive && <FontAwesomeIcon icon={faCheck} />}\n                      </span>,\n                      togglePlanMode,\n                      faListRadio,\n                      { disabled: turnActive },\n                  ] as const,\n              ]\n            : []),\n        [\"Add image\", composerImages.onAttachImageClick, faImage] as const,\n    ];\n\n    const agentChatsLocation = useSelector(getAgentsChatsLocation);\n\n    return (\n        <AgentComposerCard\n            highlighted={composerImages.draggingImages}\n            {...composerImages.dragHandlers}>\n            {header}\n            <div className=\"relative\">\n                <ComposerImageTray images={composerImages.images} onRemoveImage={composerImages.removeImage} />\n                {submissionError && (\n                    <div className={\"flex border-b border-b-red-300 bg-red-200 px-4 text-red-950\"}>\n                        <div className={\"grow\"}>{submissionError}</div>\n                        <div>\n                            <LinkInternal icon={faTimes} onClick={clearSubmissionError} />\n                        </div>\n                    </div>\n                )}\n\n                <div className={cx(\n                    \"relative z-10 flex items-center justify-between gap-2 px-8 pt-2\",\n                    agentChatsLocation === \"side\" && \"px-2\"\n                )}>\n                    <AgentChooser\n                        agentType={conversationInfo.agent_type}\n                        disabled={isTurnActive(conversation)}\n                        onChangeAgentType={onChangeAgentType}\n                    />\n                </div>\n\n                <div className={cx({ \"blur-[1px]\": isDisabled })}>\n                    <div className={\"min-w-0\"}>\n                        {isDisabled ? (\n                            <div className={cx(\"h-15\", { \"h-[5rem]\": agentChatsLocation === \"bottom\" })}> </div>\n                        ) : (\n                            <CodeMirrorElement\n                                view={view}\n                                autoFocus\n                                height={agentChatsLocation === \"bottom\" ? \"5rem\" : \"auto\"}\n                                className={cx(\n                                    agentChatsLocation === \"bottom\" &&\n                                    \"[&_.cm-content]:overflow-y-scroll [&_.cm-content]:!py-1 [&_.cm-content]:!text-[1.3rem] [&_.cm-editor]:!min-h-[5rem]\",\n                                    agentChatsLocation === \"side\" &&\n                                    \"[&_.cm-content]:!px-2 [&_.cm-content]:!py-2 [&_.cm-content]:!text-[1.3rem]\"\n                                )}\n                            />\n                        )}\n                    </div>\n                    <ComposerToolbar\n                        usage={usage}\n                        configuration={\n                            <ComposerConfiguration\n                                config={config}\n                                pending={sessionStatus !== \"running\" || !!sessionConfig.pending}\n                                onChangeConfig={onChangeConfig}\n                            />\n                        }\n                        controls={dictation.toolbarComponent}\n                        onSubmitClick={onSubmitClick}\n                        onStopClick={onStop}\n                        turnActive={turnActive}>\n                        {composerImages.inputComponent}\n                        <DropdownMenu\n                            anchorToTrigger\n                            offset={8}\n                            render={(showMenu, anchor) => (\n                                <div>\n                                    <Button\n                                        small\n                                        variant=\"hidden\"\n                                        icon={faPlus}\n                                        linkClassName=\"rounded-full!\"\n                                        aria-label=\"Add to prompt\"\n                                        onClick={(event) => showMenu(null, event.currentTarget)}\n                                        title=\"Add to prompt\"\n                                        titlePosition=\"top\"\n                                    />\n                                    {anchor}\n                                </div>\n                            )}\n                            items={composerMenuItems}\n                        />\n                        {composerImages.images.length > 0 && (\n                            <div className=\"text-xs text-light-grey1\">\n                                {composerImages.images.length}/{MAX_IMAGE_ATTACHMENTS} images\n                            </div>\n                        )}\n                        {supportsPlan && planModeActive && (\n                            <Button\n                                small\n                                variant=\"hidden\"\n                                icon={faListRadio}\n                                disabled={turnActive}\n                                aria-pressed={true}\n                                className=\"group text-primary\"\n                                linkClassName=\"rounded-full! bg-primary-50! px-3! text-primary! dark:bg-primary-800! dark:text-primary-100!\"\n                                onClick={togglePlanMode}\n                                title=\"Exit Plan mode (Shift+Tab)\"\n                                titlePosition=\"top\">\n                                <span>Plan</span>\n                                <FontAwesomeIcon className=\"ml-2\" icon={faXmark} />\n                            </Button>\n                        )}\n                    </ComposerToolbar>\n                </div>\n                {isDisabled ? (\n                    <div\n                        className={cx(\n                            \"absolute top-0 left-0 flex h-full w-full cursor-not-allowed items-center justify-center\"\n                        )}\n                    />\n                ) : null}\n            </div>\n        </AgentComposerCard>\n    );\n};\n\nexport const StartPagePromptComposer = ({}) => {\n    const user = useSelector(getUser);\n    const dispatch = useDispatch<AnvilDispatch>();\n    const [prompt, setPrompt] = useState<string>(\"\");\n    const [submittingPrompt, setSubmittingPrompt] = useState<boolean>(false);\n\n    const submitPrompt = useEvent(async () => {\n        if (prompt && !user?.impersonator) {\n            if (submittingPrompt) return;\n            setSubmittingPrompt(true);\n            try {\n                await dispatch(createAppWithPrompt([{ type: \"text\", text: prompt }], \"start_page\"));\n            } finally {\n                setSubmittingPrompt(false);\n            }\n        }\n    });\n    return (\n        <div className=\"flex justify-center\">\n            <div\n                className={cx(\n                    \"relative overflow-hidden rounded-xl border border-sectionborder bg-white shadow-[0px_4px_10px_0px_rgba(0,0,0,0.10)] transition-colors dark:border-dark-sectionborder dark:bg-[#151718]\",\n                    \"w-full max-w-[75rem]\"\n                )}>\n                <div className={\"min-w-0\"}>\n                    <div className={cx(\"px-8 pt-2\")}>\n                        {/* leaving this div here cuz i like the spacing but also the agents choose would go here if we can manage to change it outside of a conversation */}\n                    </div>\n                    <ContentTextAreaInput\n                        className={cx(\"border-0! resize-none\")}\n                        placeholder=\"I want to build...\"\n                        value={prompt}\n                        onChange={(e) => setPrompt(e.target.value)}\n                        onKeyDown={(e) => {\n                            if (e.key === \"Enter\" && !e.shiftKey && !e.nativeEvent.isComposing) {\n                                e.preventDefault();\n                                e.stopPropagation();\n                                void submitPrompt();\n                            }\n                        }}\n                    />\n                </div>\n                <div className=\"flex justify-end\">\n                    <Button\n                        disabled={!prompt || !!user?.impersonator}\n                        small\n                        variant={\"primary\"}\n                        icon={faArrowUp}\n                        onClick={submitPrompt}\n                        title={\"Send\"}\n                        titlePosition={\"top\"}\n                        className=\"m-4 overflow-hidden rounded-full\"\n                    />\n                </div>\n            </div>\n        </div>\n    );\n};\n","import { useRef, useState } from \"react\";\nimport type { PromptRequestMessage } from \"@agent-host/rpc_types.ts\";\nimport { acceptCompletion } from \"@codemirror/autocomplete\";\nimport type { Command, EditorView } from \"@codemirror/view\";\nimport useEvent from \"@/util/useEventCallback.ts\";\nimport type { PromptDictationState } from \"../PromptDictation.tsx\";\nimport { type ComposerImage, imageToContentBlock } from \"./images.tsx\";\n\ninterface UsePromptSubmitArgs {\n    onSubmit(prompt: PromptRequestMessage[\"prompt\"]): Promise<void> | void;\n    onPromptCleared?(): void;\n    images: ComposerImage[];\n    clearImages(): void;\n    restoreImages(images: ComposerImage[]): void;\n    dictation: PromptDictationState;\n    turnActive: boolean;\n}\n\nexport function usePromptSubmit({\n    onSubmit,\n    onPromptCleared,\n    images,\n    clearImages,\n    restoreImages,\n    dictation,\n    turnActive,\n}: UsePromptSubmitArgs) {\n    const submittingRef = useRef(false);\n\n    const [submissionError, setSubmissionError] = useState<string | null>(null);\n    const clearSubmissionError = () => setSubmissionError(null);\n\n    const submit = useEvent(async (view: EditorView) => {\n        if (turnActive) {\n            return;\n        }\n        if (submittingRef.current) {\n            return;\n        }\n        const text = view.state.doc.toString();\n        if (!text && images.length === 0) {\n            return;\n        }\n        dictation.stop();\n        const prompt: PromptRequestMessage[\"prompt\"] = [\n            ...(text ? [{ type: \"text\" as const, text }] : []),\n            ...images.map(imageToContentBlock),\n        ];\n        submittingRef.current = true;\n        view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: \"\" } });\n        clearImages();\n        onPromptCleared?.();\n        try {\n            await onSubmit(prompt);\n            clearSubmissionError();\n        } catch (e) {\n            view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: text } });\n            restoreImages(images);\n            setSubmissionError(\n                e instanceof Error || (e instanceof Object && \"message\" in e)\n                    ? (e.message as string)\n                    : `Error: ${JSON.stringify(e)}`\n            );\n            throw e;\n        } finally {\n            submittingRef.current = false;\n        }\n    });\n\n    const submitCommand: Command = useEvent((view: EditorView) => {\n        if (acceptCompletion(view)) {\n            return true;\n        }\n        void submit(view);\n        return true;\n    });\n\n    return {\n        submit,\n        submitCommand,\n        submissionError,\n        clearSubmissionError,\n    };\n}\n","export type DiffDisplayRowType = \"context\" | \"add\" | \"remove\" | \"hunk\";\n\nexport interface DiffDisplayRow {\n    type: DiffDisplayRowType;\n    text: string;\n    oldLineNumber?: number;\n    newLineNumber?: number;\n}\n\nexport interface NormalizedToolCallDiff {\n    path: string;\n    oldText: string | null;\n    newText: string;\n    addedLines: number;\n    deletedLines: number;\n    rows: DiffDisplayRow[];\n}\n\ninterface ToolCallDiffContentLike {\n    type?: unknown;\n    path?: unknown;\n    oldText?: unknown;\n    newText?: unknown;\n}\n\ninterface LineChange {\n    type: \"equal\" | \"add\" | \"remove\";\n    text: string;\n    oldLineNumber?: number;\n    newLineNumber?: number;\n}\n\nconst DEFAULT_CONTEXT_LINES = 3;\nconst MAX_LCS_CELLS = 1_000_000;\n\nconst splitTextLines = (text: string): string[] => {\n    if (text === \"\") {\n        return [];\n    }\n\n    const lines = text.split(/\\r\\n|\\r|\\n/);\n    if (lines[lines.length - 1] === \"\") {\n        lines.pop();\n    }\n    return lines;\n};\n\nconst isStructuredDiffContent = (\n    content: unknown\n): content is ToolCallDiffContentLike & {\n    type: \"diff\";\n    path: string;\n    newText: string;\n} => {\n    if (!content || typeof content !== \"object\") {\n        return false;\n    }\n\n    const diff = content as ToolCallDiffContentLike;\n    return diff.type === \"diff\" && typeof diff.path === \"string\" && typeof diff.newText === \"string\";\n};\n\nconst diffTextLines = (oldText: string | null | undefined, newText: string): LineChange[] => {\n    const oldLines = splitTextLines(oldText ?? \"\");\n    const newLines = splitTextLines(newText);\n    const changes: LineChange[] = [];\n\n    if (oldLines.length * newLines.length > MAX_LCS_CELLS) {\n        oldLines.forEach((text, idx) => {\n            changes.push({ type: \"remove\", text, oldLineNumber: idx + 1 });\n        });\n        newLines.forEach((text, idx) => {\n            changes.push({ type: \"add\", text, newLineNumber: idx + 1 });\n        });\n        return changes;\n    }\n\n    // Dynamic-programming LCS over lines. Walking the table gives a stable unified diff:\n    // equal lines keep both line numbers, removals keep only old, additions keep only new.\n    const dp = Array.from({ length: oldLines.length + 1 }, () => new Uint32Array(newLines.length + 1));\n    for (let i = oldLines.length - 1; i >= 0; i--) {\n        for (let j = newLines.length - 1; j >= 0; j--) {\n            dp[i][j] = oldLines[i] === newLines[j] ? dp[i + 1][j + 1] + 1 : Math.max(dp[i + 1][j], dp[i][j + 1]);\n        }\n    }\n\n    let oldIdx = 0;\n    let newIdx = 0;\n    while (oldIdx < oldLines.length && newIdx < newLines.length) {\n        if (oldLines[oldIdx] === newLines[newIdx]) {\n            changes.push({\n                type: \"equal\",\n                text: oldLines[oldIdx],\n                oldLineNumber: oldIdx + 1,\n                newLineNumber: newIdx + 1,\n            });\n            oldIdx++;\n            newIdx++;\n        } else if (dp[oldIdx + 1][newIdx] >= dp[oldIdx][newIdx + 1]) {\n            changes.push({ type: \"remove\", text: oldLines[oldIdx], oldLineNumber: oldIdx + 1 });\n            oldIdx++;\n        } else {\n            changes.push({ type: \"add\", text: newLines[newIdx], newLineNumber: newIdx + 1 });\n            newIdx++;\n        }\n    }\n\n    while (oldIdx < oldLines.length) {\n        changes.push({ type: \"remove\", text: oldLines[oldIdx], oldLineNumber: oldIdx + 1 });\n        oldIdx++;\n    }\n\n    while (newIdx < newLines.length) {\n        changes.push({ type: \"add\", text: newLines[newIdx], newLineNumber: newIdx + 1 });\n        newIdx++;\n    }\n\n    return changes;\n};\n\nconst countChangedLines = (changes: LineChange[], type: \"add\" | \"remove\") =>\n    changes.filter((change) => change.type === type).length;\n\nconst hunkHeader = (changes: LineChange[]): DiffDisplayRow => {\n    const oldLineNumbers = changes.flatMap((change) =>\n        change.oldLineNumber === undefined ? [] : [change.oldLineNumber]\n    );\n    const newLineNumbers = changes.flatMap((change) =>\n        change.newLineNumber === undefined ? [] : [change.newLineNumber]\n    );\n    const oldStart = oldLineNumbers.length ? Math.min(...oldLineNumbers) : 0;\n    const newStart = newLineNumbers.length ? Math.min(...newLineNumbers) : 0;\n    const oldLineCount = oldLineNumbers.length ? Math.max(...oldLineNumbers) - oldStart + 1 : 0;\n    const newLineCount = newLineNumbers.length ? Math.max(...newLineNumbers) - newStart + 1 : 0;\n\n    return {\n        type: \"hunk\",\n        text: `@@ -${oldStart},${oldLineCount} +${newStart},${newLineCount} @@`,\n    };\n};\n\nconst buildUnifiedDiffRowsFromChanges = (\n    changes: LineChange[],\n    contextLines = DEFAULT_CONTEXT_LINES\n): DiffDisplayRow[] => {\n    const changedIndexes = changes.flatMap((change, idx) => (change.type === \"equal\" ? [] : [idx]));\n    if (!changedIndexes.length) {\n        return [];\n    }\n\n    const hunks: Array<{ start: number; end: number }> = [];\n    for (const changedIndex of changedIndexes) {\n        const start = Math.max(0, changedIndex - contextLines);\n        const end = Math.min(changes.length - 1, changedIndex + contextLines);\n        const previousHunk = hunks[hunks.length - 1];\n        if (previousHunk && start <= previousHunk.end + 1) {\n            previousHunk.end = Math.max(previousHunk.end, end);\n        } else {\n            hunks.push({ start, end });\n        }\n    }\n\n    const rows: DiffDisplayRow[] = [];\n    for (const hunk of hunks) {\n        const hunkChanges = changes.slice(hunk.start, hunk.end + 1);\n        rows.push(hunkHeader(hunkChanges));\n        for (const change of hunkChanges) {\n            rows.push({\n                type: change.type === \"equal\" ? \"context\" : change.type,\n                text: change.text,\n                oldLineNumber: change.oldLineNumber,\n                newLineNumber: change.newLineNumber,\n            });\n        }\n    }\n\n    return rows;\n};\n\nexport const buildUnifiedDiffRows = (\n    oldText: string | null | undefined,\n    newText: string,\n    contextLines = DEFAULT_CONTEXT_LINES\n): DiffDisplayRow[] => buildUnifiedDiffRowsFromChanges(diffTextLines(oldText, newText), contextLines);\n\nexport const normalizeDiff = (diff: ToolCallDiffContentLike & { path: string; newText: string }): NormalizedToolCallDiff => {\n    const oldText = typeof diff.oldText === \"string\" ? diff.oldText : null;\n    const changes = diffTextLines(oldText, diff.newText);\n\n    return {\n        path: diff.path.trim(),\n        oldText,\n        newText: diff.newText,\n        addedLines: countChangedLines(changes, \"add\"),\n        deletedLines: countChangedLines(changes, \"remove\"),\n        rows: buildUnifiedDiffRowsFromChanges(changes),\n    };\n};\n\nexport const extractToolCallDiffs = ({ content }: { content?: unknown[] | null }): NormalizedToolCallDiff[] => {\n    const diffsByPath = new Map<string, NormalizedToolCallDiff>();\n    for (const item of content ?? []) {\n        if (!isStructuredDiffContent(item)) {\n            continue;\n        }\n\n        const path = item.path.trim();\n        if (!path) {\n            continue;\n        }\n\n        diffsByPath.set(path, normalizeDiff({ ...item, path }));\n    }\n\n    return [...diffsByPath.values()];\n};\n","import { useQuery } from \"@tanstack/react-query\";\nimport type { AgentFileDiffContent } from \"@/api/agents\";\nimport { normalizeDiff } from \"./agentToolCallDiffs\";\nimport { useMemo, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { EditorState, RangeSetBuilder, StateField } from \"@codemirror/state\";\nimport { Decoration, DecorationSet, EditorView, GutterMarker, gutter } from \"@codemirror/view\";\nimport { faChevronDown, faChevronRight, faFileCode } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { scrollBar } from \"@/code_mirror/basic_setup.tsx\";\nimport { CodeMirrorElement } from \"@/code_mirror/element.tsx\";\nimport { useBaseTheme } from \"@/code_mirror/theme\";\nimport { useEditorView, useExtension } from \"@/code_mirror/utils/hooks.ts\";\nimport { Expander } from \"@/components/reusable/Expander.tsx\";\nimport Link from \"@/components/reusable/Link.tsx\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal.tsx\";\nimport { getApp } from \"@/controllers/app\";\nimport { cx, useTheme } from \"@/theme/styles.ts\";\nimport {\n    labelForAgentFilePathReference,\n    navTargetFromAgentPathReference,\n    titleForAgentPathReference,\n} from \"./agentMarkdownLinks.ts\";\nimport { DiffDisplayRow, NormalizedToolCallDiff } from \"./agentToolCallDiffs.ts\";\n\nclass DiffGutterMarker extends GutterMarker {\n    constructor(\n        private readonly text: string,\n        private readonly className = \"\"\n    ) {\n        super();\n    }\n\n    toDOM() {\n        const marker = document.createElement(\"span\");\n        marker.className = this.className;\n        marker.textContent = this.text;\n        return marker;\n    }\n}\n\nconst marker = (text: string, className = \"\") => new DiffGutterMarker(text, className);\n\nconst buildDiffDecorations = (state: EditorState, rows: DiffDisplayRow[]): DecorationSet => {\n    const builder = new RangeSetBuilder<Decoration>();\n    rows.forEach((row, idx) => {\n        const line = state.doc.line(idx + 1);\n        builder.add(\n            line.from,\n            line.from,\n            Decoration.line({ attributes: { class: `cm-agent-diff-line cm-agent-diff-line-${row.type}` } })\n        );\n    });\n    return builder.finish();\n};\n\nconst diffLineDecorations = (rows: DiffDisplayRow[]) =>\n    StateField.define<DecorationSet>({\n        create: (state) => buildDiffDecorations(state, rows),\n        update: (decorations) => decorations,\n        provide: (field) => EditorView.decorations.from(field),\n    });\n\nconst rowTypeClass = (row: DiffDisplayRow | undefined) => (row ? `cm-agent-diff-gutter-${row.type}` : \"\");\n\nconst diffGutters = (rows: DiffDisplayRow[]) => [\n    gutter({\n        class: \"cm-agent-diff-sign-gutter\",\n        lineMarker: (view, line) => {\n            const row = rows[view.state.doc.lineAt(line.from).number - 1];\n            const sign = row?.type === \"add\" ? \"+\" : row?.type === \"remove\" ? \"-\" : \"\";\n            return marker(sign, rowTypeClass(row));\n        },\n    }),\n    gutter({\n        class: \"cm-agent-diff-old-gutter\",\n        lineMarker: (view, line) => {\n            const row = rows[view.state.doc.lineAt(line.from).number - 1];\n            return marker(row?.oldLineNumber?.toString() ?? \"\", rowTypeClass(row));\n        },\n    }),\n    gutter({\n        class: \"cm-agent-diff-new-gutter\",\n        lineMarker: (view, line) => {\n            const row = rows[view.state.doc.lineAt(line.from).number - 1];\n            return marker(row?.newLineNumber?.toString() ?? \"\", rowTypeClass(row));\n        },\n    }),\n];\n\nconst useDiffTheme = (view: EditorView) => {\n    const theme = useTheme();\n    const isDark = theme.isDark;\n    const diffTheme = useMemo(\n        () =>\n            EditorView.theme(\n                {\n                    \"&\": {\n                        maxHeight: \"28rem\",\n                        borderRadius: \"0 0 4px 4px\",\n                        backgroundColor: isDark ? \"#111414\" : \"#fbfbfb\",\n                    },\n                    \".cm-scroller\": {\n                        maxHeight: \"28rem\",\n                        overflow: \"auto\",\n                        fontSize: \"1.05rem\",\n                        lineHeight: 1.45,\n                    },\n                    \".cm-content\": {\n                        minWidth: \"max-content\",\n                        padding: \"0.2rem 0\",\n                    },\n                    \".cm-line\": {\n                        padding: \"0 0.75rem\",\n                        whiteSpace: \"pre\",\n                    },\n                    \".cm-gutters\": {\n                        backgroundColor: isDark ? \"#111414\" : \"#f7f7f7\",\n                        borderRight: `1px solid ${isDark ? \"#2b302f\" : \"#e0e0e0\"}`,\n                        color: isDark ? \"#8d9693\" : \"#777\",\n                    },\n                    \".cm-agent-diff-sign-gutter .cm-gutterElement\": {\n                        minWidth: \"1.4rem\",\n                        justifyContent: \"center\",\n                        padding: \"0\",\n                    },\n                    \".cm-agent-diff-old-gutter .cm-gutterElement, .cm-agent-diff-new-gutter .cm-gutterElement\": {\n                        minWidth: \"2.9rem\",\n                        justifyContent: \"flex-end\",\n                        padding: \"0 0.45rem\",\n                    },\n                    \".cm-agent-diff-line-add\": {\n                        backgroundColor: isDark ? \"rgba(35, 134, 54, 0.24)\" : \"rgba(46, 160, 67, 0.14)\",\n                    },\n                    \".cm-agent-diff-line-remove\": {\n                        backgroundColor: isDark ? \"rgba(248, 81, 73, 0.2)\" : \"rgba(248, 81, 73, 0.12)\",\n                    },\n                    \".cm-agent-diff-line-hunk\": {\n                        backgroundColor: isDark ? \"#1b2020\" : \"#eeeeee\",\n                        color: isDark ? \"#aeb6b4\" : \"#666\",\n                    },\n                    \".cm-agent-diff-gutter-add\": {\n                        color: isDark ? \"#3fb950\" : \"#1a7f37\",\n                    },\n                    \".cm-agent-diff-gutter-remove\": {\n                        color: isDark ? \"#ff7b72\" : \"#cf222e\",\n                    },\n                    \".cm-agent-diff-gutter-hunk\": {\n                        color: isDark ? \"#aeb6b4\" : \"#666\",\n                    },\n                },\n                { dark: isDark }\n            ),\n        [isDark]\n    );\n\n    useExtension(view, () => diffTheme, [diffTheme]);\n};\n\nconst DiffCodeMirror = ({ diff }: { diff: NormalizedToolCallDiff }) => {\n    const doc = useMemo(() => diff.rows.map((row) => row.text).join(\"\\n\"), [diff.rows]);\n    const view = useEditorView(\n        () => ({\n            doc,\n            extensions: [\n                EditorState.readOnly.of(true),\n                EditorView.editable.of(false),\n                scrollBar,\n                diffLineDecorations(diff.rows),\n                diffGutters(diff.rows),\n            ],\n        }),\n        [doc, diff.rows]\n    );\n\n    useBaseTheme(view);\n    useDiffTheme(view);\n\n    return <CodeMirrorElement view={view} autoFocus={false} height=\"auto\" className=\"w-full\" />;\n};\n\nconst CountBadge = ({ addedLines, deletedLines }: { addedLines: number; deletedLines: number }) => (\n    <span className=\"inline-flex shrink-0 gap-2 font-mono text-[1.05em]\">\n        <span className=\"text-[#1a7f37] dark:text-[#3fb950]\">+{addedLines}</span>\n        <span className=\"text-[#cf222e] dark:text-[#ff7b72]\">-{deletedLines}</span>\n    </span>\n);\n\nconst DiffPathLabel = ({ path }: { path: string }) => {\n    const app = useSelector(getApp);\n    return <span className=\"min-w-0 truncate font-mono\">{labelForAgentFilePathReference(path, app) ?? path}</span>;\n};\n\nconst openFileSlotClass = \"inline-flex w-5 shrink-0 justify-center\";\n\nexport const AgentFileDiff = ({\n    path,\n    diff: suppliedDiff,\n    load,\n    queryKey,\n    status = \"modified\",\n}: {\n    path: string;\n    diff?: NormalizedToolCallDiff;\n    load?: () => Promise<AgentFileDiffContent>;\n    queryKey?: string[];\n    status?: \"added\" | \"modified\" | \"deleted\";\n}) => {\n    const [collapsed, setCollapsed] = useState(true);\n    const [hasOpened, setHasOpened] = useState(false);\n    const content = useQuery({\n        queryKey: queryKey ?? [\"agent-tool-diff\", path],\n        queryFn: load,\n        enabled: hasOpened && load !== undefined,\n        staleTime: Infinity,\n        retry: false,\n    });\n    const diff = useMemo(\n        () =>\n            suppliedDiff ??\n            (content.data && !content.data.unavailable\n                ? normalizeDiff({ path, oldText: content.data.oldText, newText: content.data.newText ?? \"\" })\n                : undefined),\n        [suppliedDiff, content.data, path]\n    );\n    const app = useSelector(getApp);\n    const navTarget = useMemo(\n        () => (status === \"deleted\" ? null : navTargetFromAgentPathReference(path, app)),\n        [app, path, status]\n    );\n    const label = labelForAgentFilePathReference(path, app) ?? path;\n\n    return (\n        <div className=\"flex min-w-0 flex-col gap-1\">\n            <div className=\"flex min-w-0 items-center gap-2\">\n                {navTarget ? (\n                    <Link\n                        to={navTarget}\n                        title={titleForAgentPathReference(path)}\n                        aria-label={`Open ${label}`}\n                        className={cx(\n                            openFileSlotClass,\n                            \"text-light-fg2 hover:text-primary dark:text-light-bg6 dark:hover:text-primary\"\n                        )}>\n                        <FontAwesomeIcon icon={faFileCode} fixedWidth className=\"text-[0.85em]\" />\n                    </Link>\n                ) : (\n                    <span className={openFileSlotClass} aria-hidden=\"true\" />\n                )}\n                <LinkInternal\n                    iconRight\n                    icon={collapsed ? faChevronRight : faChevronDown}\n                    aria-expanded={!collapsed}\n                    onKeyDown={(event) => {\n                        if (event.key === \"Enter\" || event.key === \" \") {\n                            event.preventDefault();\n                            event.currentTarget.click();\n                        }\n                    }}\n                    className={cx(\"inline-flex min-w-0 items-center gap-2 dark:text-light-bg6\")}\n                    onClick={() => {\n                        setHasOpened(true);\n                        setCollapsed((current) => !current);\n                    }}>\n                    <span className=\"text-light-fg2 shrink-0 dark:text-light-bg6\">\n                        {status === \"added\" ? \"Added\" : status === \"deleted\" ? \"Deleted\" : \"Edited\"}\n                    </span>\n                    <DiffPathLabel path={path} />\n                    {diff && <CountBadge addedLines={diff.addedLines} deletedLines={diff.deletedLines} />}\n                </LinkInternal>\n            </div>\n            <Expander isOpen={!collapsed}>\n                {hasOpened && (\n                    <div className=\"overflow-hidden rounded border border-sectionborder bg-white dark:border-dark-sectionborder dark:bg-dark-bg0\">\n                        {diff && diff.rows.length ? (\n                            <DiffCodeMirror diff={diff} />\n                        ) : (\n                            <div className=\"text-light-fg2 px-3 py-2 font-mono text-[1.05rem] dark:text-dark-fg2\">\n                                {content.isError\n                                    ? \"Could not load file diff\"\n                                    : (content.data?.unavailable ?? (diff ? \"No text changes\" : \"Loading diff...\"))}\n                            </div>\n                        )}\n                    </div>\n                )}\n            </Expander>\n        </div>\n    );\n};\n\nexport const AgentToolCallDiff = ({ diffs }: { diffs: NormalizedToolCallDiff[] }) => {\n    const [collapsed, setCollapsed] = useState(false);\n\n    return (\n        <div className=\"flex min-w-0 flex-col gap-1.5\">\n            <LinkInternal\n                iconRight\n                icon={collapsed ? faChevronRight : faChevronDown}\n                aria-expanded={!collapsed}\n                className={cx(\"inline-flex min-w-0 items-center gap-2 dark:text-light-bg6\")}\n                onClick={() => setCollapsed((current) => !current)}>\n                <span className=\"text-light-fg2 shrink-0 dark:text-light-bg6\">\n                    Edited {diffs.length} {diffs.length === 1 ? \"file\" : \"files\"}\n                </span>\n            </LinkInternal>\n            <Expander isOpen={!collapsed}>\n                <div className=\"flex min-w-0 flex-col gap-1.5\">\n                    {diffs.map((diff) => (\n                        <AgentFileDiff path={diff.path} diff={diff} key={diff.path} />\n                    ))}\n                </div>\n            </Expander>\n        </div>\n    );\n};\n","import { useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { faChevronDown, faChevronUp, faFilePen } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { getTurnDiff, getTurnFileDiff } from \"@/api/agents\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { useConversationContext } from \"../context\";\nimport type { PromptTurn } from \"../types\";\nimport { AgentFileDiff } from \"./AgentToolCallDiff\";\n\nconst PREVIEW_FILE_COUNT = 3;\n\nexport const AgentTurnDiff = ({ turn }: { turn: PromptTurn }) => {\n    const { info } = useConversationContext();\n    const [showAll, setShowAll] = useState(false);\n    const promptPid = turn.promptRequest.event_pid;\n    const queryKey = [\"agent-turn-diff\", info.conversation_pid, promptPid];\n    const diff = turn.turnDiff;\n    const expiredByTime = diff?.expires_at !== undefined && diff.expires_at <= Date.now();\n    const unavailable = diff && (diff.status !== \"ready\" || diff.phase !== \"end\");\n    const files = useQuery({\n        queryKey,\n        queryFn: () => getTurnDiff(info.conversation_pid, promptPid),\n        enabled: !expiredByTime && !unavailable && !!diff?.file_count,\n        staleTime: Infinity,\n        retry: false,\n    });\n    const expired = expiredByTime || files.data?.expired;\n    const fileCount = files.data && !files.data.expired ? files.data.files.length : diff?.file_count;\n    if (!unavailable && !fileCount) return null;\n\n    const visibleFiles = showAll ? files.data?.files : files.data?.files.slice(0, PREVIEW_FILE_COUNT);\n    const hiddenFileCount = (files.data?.files.length ?? 0) - PREVIEW_FILE_COUNT;\n\n    return (\n        <section\n            aria-label=\"Turn changes\"\n            className=\"my-6 overflow-hidden rounded-xl border border-sectionborder bg-white dark:border-dark-sectionborder dark:bg-dark-bg0\">\n            <div\n                className=\"flex items-center gap-4 bg-light-bg2 px-5 py-4 dark:bg-dark-bg2\"\n                title=\"App changes during this turn, including any concurrent edits\">\n                <div className=\"flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-white text-light-fg2 dark:bg-dark-bg0 dark:text-dark-fg2\">\n                    <FontAwesomeIcon icon={faFilePen} fixedWidth />\n                </div>\n                <h3 className=\"m-0 text-[1.4rem] font-semibold text-light-fg1 dark:text-dark-fg1\">\n                    {expired\n                        ? \"Diff expired\"\n                        : unavailable\n                          ? \"Turn diff unavailable\"\n                          : `Edited ${fileCount} ${fileCount === 1 ? \"file\" : \"files\"}`}\n                </h3>\n            </div>\n            {!unavailable && !expired && (\n                <>\n                    <div className=\"divide-y divide-sectionborder border-t border-sectionborder dark:divide-dark-sectionborder dark:border-dark-sectionborder\">\n                        {files.isPending && (\n                            <div className=\"px-5 py-4 text-light-fg2 dark:text-dark-fg2\">Loading changed files...</div>\n                        )}\n                        {files.isError && (\n                            <div className=\"px-5 py-4 text-light-fg2 dark:text-dark-fg2\">Could not load turn diff</div>\n                        )}\n                        {visibleFiles?.map((file) => (\n                            <div key={file.path} className=\"px-5 py-4\">\n                                <AgentFileDiff\n                                    path={file.path}\n                                    status={file.status}\n                                    queryKey={[...queryKey, file.path]}\n                                    load={() => getTurnFileDiff(info.conversation_pid, promptPid, file.path)}\n                                />\n                            </div>\n                        ))}\n                    </div>\n                    {hiddenFileCount > 0 && (\n                        <div className=\"border-t border-sectionborder bg-light-bg2 dark:border-dark-sectionborder dark:bg-dark-bg2\">\n                            <LinkInternal\n                                iconRight\n                                icon={showAll ? faChevronUp : faChevronDown}\n                                aria-expanded={showAll}\n                                className=\"flex! w-full items-center gap-3 px-5 py-4 text-light-fg1 dark:text-dark-fg1\"\n                                onKeyDown={(event) => {\n                                    if (event.key === \"Enter\" || event.key === \" \") {\n                                        event.preventDefault();\n                                        event.currentTarget.click();\n                                    }\n                                }}\n                                onClick={() => setShowAll((value) => !value)}>\n                                {showAll\n                                    ? \"Show fewer files\"\n                                    : `Show ${hiddenFileCount} more ${hiddenFileCount === 1 ? \"file\" : \"files\"}`}\n                            </LinkInternal>\n                        </div>\n                    )}\n                </>\n            )}\n        </section>\n    );\n};\n","// Resolve browser-loadable image srcs for agent conversation UI.\n// Accepted theme-asset references (map to {debugOrigin}/_/theme/...):\n//   assets/foo.png                         — IDE nav / codePath form\n//   theme/assets/foo.png                   — checkout-relative form\n//   /env/<id>/app/theme/assets/foo.png     — env checkout form\n//   asset:foo.png                          — legacy asset: prefix\n// Also: inline base64 data, https: URLs, and data:image/... URIs.\n// Bare filesystem paths are never used as img src.\n\nconst IDE_ASSETS_PATH_RE = /^assets\\/(.+?)(?:\\?|#|$)/;\nconst THEME_ASSETS_PATH_RE = /^theme\\/assets\\/(.+?)(?:\\?|#|$)/;\nconst ENV_THEME_ASSETS_PATH_RE = /^\\/env\\/[^/]+\\/app\\/theme\\/assets\\/(.+?)(?:\\?|#|$)/;\n\nconst decodePathSegments = (path: string): string =>\n    path\n        .split(\"/\")\n        .filter(Boolean)\n        .map((part) => {\n            try {\n                return decodeURIComponent(part);\n            } catch {\n                return part;\n            }\n        })\n        .join(\"/\");\n\nconst themeAssetRelativePath = (ref: string): string | null => {\n    const normalized = ref.replace(/^\\.\\/+/, \"\");\n    const match =\n        IDE_ASSETS_PATH_RE.exec(normalized) ??\n        THEME_ASSETS_PATH_RE.exec(normalized) ??\n        ENV_THEME_ASSETS_PATH_RE.exec(normalized);\n    return match?.[1] ? decodePathSegments(match[1]) : null;\n};\n\nconst themeAssetSrc = (themePrefix: string, assetRelativePath: string): string =>\n    themePrefix + assetRelativePath.split(\"/\").map(encodeURIComponent).join(\"/\");\n\nexport const resolveAgentImageSrc = ({\n    data,\n    mimeType,\n    uri,\n    themePrefix,\n}: {\n    data?: string | null;\n    mimeType?: string | null;\n    uri?: string | null;\n    themePrefix?: string | null;\n}): string | null => {\n    // Prefer inline bytes; only accept image/* so we never build a non-image data: URL.\n    if (typeof data === \"string\" && data.length > 0 && typeof mimeType === \"string\" && mimeType.startsWith(\"image/\")) {\n        return `data:${mimeType};base64,${data}`;\n    }\n    if (!uri) {\n        return null;\n    }\n    if (/^https:/i.test(uri) || /^data:image\\//i.test(uri)) {\n        return uri;\n    }\n    if (!themePrefix) {\n        return null;\n    }\n    if (uri.startsWith(\"asset:\")) {\n        return themeAssetSrc(themePrefix, decodePathSegments(uri.slice(\"asset:\".length)));\n    }\n    const assetPath = themeAssetRelativePath(uri);\n    return assetPath ? themeAssetSrc(themePrefix, assetPath) : null;\n};\n","import { useDebugThemePrefix } from \"@/util/hooks/assets\";\nimport { resolveAgentImageSrc } from \"./agentImageUrls\";\n\nconst AGENT_IMAGE_CLASS_NAME =\n    \"mt-3 max-h-96 max-w-full self-start rounded border border-primary-100 object-contain dark:border-primary-500\";\n\nexport type AgentImageContentProps = {\n    data?: string | null;\n    mimeType?: string | null;\n    uri?: string | null;\n    alt?: string;\n};\n\nexport const AgentImageContent = ({ data, mimeType, uri, alt = \"Image\" }: AgentImageContentProps) => {\n    const themePrefix = useDebugThemePrefix();\n    const src = resolveAgentImageSrc({ data, mimeType, uri, themePrefix });\n    if (!src) {\n        return null;\n    }\n    return <img src={src} alt={alt} className={AGENT_IMAGE_CLASS_NAME} />;\n};\n","import { Children, cloneElement, isValidElement } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { faArrowRight } from \"@fortawesome/pro-solid-svg-icons/faArrowRight\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { getIconFromFile, icons, serviceIcons } from \"@/components/reusable/IconHooks.tsx\";\nimport Link from \"@/components/reusable/Link.tsx\";\nimport { getApp } from \"@/controllers/app\";\nimport type { AppNavTarget } from \"@/router/navTypes.ts\";\nimport type { StructureItem } from \"@/types\";\nimport {\n    displayPathFromAgentPathReference,\n    isAgentFilePathLink,\n    isDependencyCodePath,\n    labelForAgentNavTarget,\n    navTargetFromAgentMarkdownHref,\n    navTargetFromAgentPathReference,\n    splitAgentPathReferenceText,\n    titleForAgentPathReference,\n} from \"./agentMarkdownLinks.ts\";\n\nconst textFromNode = (node: React.ReactNode): string => {\n    if (typeof node === \"string\" || typeof node === \"number\") {\n        return String(node);\n    }\n    if (Array.isArray(node)) {\n        return (node as React.ReactNode[]).map(textFromNode).join(\"\");\n    }\n    if (isValidElement<{ children?: React.ReactNode }>(node)) {\n        return textFromNode(node.props.children);\n    }\n    return \"\";\n};\n\nconst iconForNavTarget = (navTarget: AppNavTarget) =>\n    navTarget.type === \"CODE\"\n        ? iconForCodePath(navTarget.codePath)\n        : navTarget.type === \"SERVICE\"\n          ? serviceIcons[navTarget.service]\n          : icons[navTarget.type];\n\nconst iconForCodePath = (codePath: string) => {\n    const [folder, ...nameParts] = codePath.split(\"/\");\n    const name = nameParts.join(\"/\");\n    const itemTypeByFolder = {\n        forms: \"form\",\n        modules: \"module\",\n        server_modules: \"server_module\",\n        assets: \"asset\",\n    } as const satisfies Record<string, StructureItem[\"type\"]>;\n    const itemType = itemTypeByFolder[folder as keyof typeof itemTypeByFolder];\n\n    return itemType ? getIconFromFile(itemType, { name }) : icons.CODE;\n};\n\nconst IdeTargetLink = ({\n    navTarget,\n    title,\n    children,\n}: {\n    navTarget: AppNavTarget;\n    title?: string;\n    children: React.ReactNode;\n}) => {\n    const icon = iconForNavTarget(navTarget);\n    const label = Children.toArray(children).map(textFromNode).join(\"\").trim();\n    const isCodeLink = navTarget.type === \"CODE\" || navTarget.type === \"EXTRA_FILE\";\n    const showArrow = !isCodeLink;\n\n    return (\n        <Link\n            className={\n                isCodeLink\n                    ? \"cursor-pointer font-semibold text-primary-800 underline decoration-primary-300 underline-offset-2 hover:text-primary-900 hover:decoration-primary-600 dark:text-primary-500 dark:decoration-primary-500 dark:hover:text-primary-600\"\n                    : \"mx-0.5 inline-flex items-center gap-1.5 rounded border border-primary-100 bg-primary-50 px-1.5 py-px font-semibold text-primary-800 no-underline! transition-colors hover:border-primary-300 hover:bg-primary-100 hover:text-primary-900 dark:border-dark-sectionborder dark:bg-primary-800 dark:text-primary-100 dark:hover:border-primary-700 hover:dark:bg-primary-950 hover:dark:text-primary-600\"\n            }\n            to={navTarget}\n            title={title}\n            aria-label={label ? `Open ${label}` : undefined}>\n            {!isCodeLink && icon && <FontAwesomeIcon icon={icon} fixedWidth className={\"text-[0.85em] opacity-80\"} />}\n            <span>{children}</span>\n            {showArrow && <FontAwesomeIcon icon={faArrowRight} className={\"text-[0.75em] opacity-80\"} />}\n        </Link>\n    );\n};\n\nconst ExternalLink = ({ href, children }: { href?: string; children: React.ReactNode }) => {\n    const opensNewTab = !href?.startsWith(\"#\");\n    return (\n        <Link\n            className={\"cursor-pointer underline decoration-primary-500 hover:text-primary-900\"}\n            to={href}\n            title={href}\n            target={opensNewTab ? \"_blank\" : undefined}\n            rel={opensNewTab ? \"noopener noreferrer\" : undefined}>\n            {children}\n        </Link>\n    );\n};\n\nconst DisabledCodeReference = ({ href, children }: { href?: string; children: React.ReactNode }) => (\n    <span className={\"cursor-default underline decoration-primary-300 opacity-75\"} title={href} aria-disabled={\"true\"}>\n        {children}\n    </span>\n);\n\nconst DisabledFileReference = ({ href, children }: { href?: string; children: React.ReactNode }) => (\n    <span\n        className={\n            \"cursor-default rounded bg-gray-100 px-1 py-0.5 font-mono text-[0.95em] text-gray-600 dark:bg-dark-bg1 dark:text-dark-fg2\"\n        }\n        title={href}\n        aria-disabled={\"true\"}>\n        {children}\n    </span>\n);\n\nconst labelLooksLikeAgentPathReference = (label: string): boolean =>\n    /(?:^|\\/)(?:client_code|server_code|theme\\/assets)\\//.test(label);\n\nconst replaceSingleCodeChildText = (children: React.ReactNode, label: string): React.ReactNode => {\n    const childArray = Children.toArray(children);\n    if (childArray.length === 1 && isValidElement<{ children?: React.ReactNode }>(childArray[0])) {\n        const child = childArray[0];\n        if (child.type === \"code\") {\n            return cloneElement(child, undefined, label);\n        }\n    }\n    return label;\n};\n\nconst labelForAgentMarkdownLink = (\n    href: string | undefined,\n    children: React.ReactNode,\n    navTarget: AppNavTarget,\n    app: ReturnType<typeof getApp>\n): React.ReactNode => {\n    const label = Children.toArray(children).map(textFromNode).join(\"\").trim();\n    if (href && navTargetFromAgentPathReference(href, app)) {\n        const pathLabel = labelForAgentNavTarget(navTarget);\n        if (pathLabel && (!label || labelLooksLikeAgentPathReference(label))) {\n            return replaceSingleCodeChildText(children, pathLabel);\n        }\n    }\n\n    if (!label) {\n        return children;\n    }\n\n    const segments = splitAgentPathReferenceText(label, app);\n    if (segments.length === 1 && segments[0].type === \"path\") {\n        return segments[0].label;\n    }\n\n    return children;\n};\n\nconst labelForDisabledFileLink = (href: string | undefined, children: React.ReactNode): React.ReactNode => {\n    const label = Children.toArray(children).map(textFromNode).join(\"\").trim();\n    const displayPath = displayPathFromAgentPathReference(href);\n    if (!label || (displayPath && label === href)) {\n        return displayPath ?? children;\n    }\n    return children;\n};\n\nexport const MarkdownLink = ({\n    href,\n    title,\n    children,\n}: {\n    href?: string;\n    title?: string | null;\n    children?: React.ReactNode;\n}) => {\n    const app = useSelector(getApp);\n    const navTarget = navTargetFromAgentMarkdownHref(href, app);\n    if (navTarget) {\n        return (\n            <IdeTargetLink navTarget={navTarget} title={title ?? titleForAgentPathReference(href)}>\n                {labelForAgentMarkdownLink(href, children, navTarget, app)}\n            </IdeTargetLink>\n        );\n    }\n    if (isDependencyCodePath(href)) {\n        return <DisabledCodeReference href={href}>{children}</DisabledCodeReference>;\n    }\n    if (isAgentFilePathLink(href, app)) {\n        return <DisabledFileReference href={href}>{labelForDisabledFileLink(href, children)}</DisabledFileReference>;\n    }\n    return <ExternalLink href={href}>{children}</ExternalLink>;\n};\n\nexport const AgentPathReference = ({ path }: { path: string }) => {\n    const app = useSelector(getApp);\n    const navTarget = navTargetFromAgentMarkdownHref(path, app);\n    if (navTarget) {\n        return (\n            <IdeTargetLink navTarget={navTarget} title={titleForAgentPathReference(path)}>\n                {labelForAgentNavTarget(navTarget) ?? path}\n            </IdeTargetLink>\n        );\n    }\n    return <span>{path}</span>;\n};\n\nexport const AgentPathReferenceText = ({ text }: { text: string }) => {\n    const app = useSelector(getApp);\n    return splitAgentPathReferenceText(text, app).map((segment, index) =>\n        segment.type === \"path\" ? <AgentPathReference key={index} path={segment.value} /> : segment.value\n    );\n};\n\nexport const markdownLinkComponents = {\n    a: MarkdownLink,\n};\n","import { Children, cloneElement, isValidElement, useMemo } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport Markdown from \"react-markdown\";\nimport type { Components, Options } from \"react-markdown\";\nimport type { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport {\n    faCircleExclamation,\n    faCircleInfo,\n    faLightbulb,\n    faTriangleExclamation,\n} from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport remarkGfm from \"remark-gfm\";\nimport { CopyButton } from \"@/components/reusable/CopyButton\";\nimport { getApp } from \"@/controllers/app\";\nimport { cx } from \"@/theme/styles\";\nimport { AgentImageContent } from \"./AgentImageContent\";\nimport { agentPathReferenceLinks } from \"./agentMarkdownLinks\";\nimport { markdownLinkComponents } from \"./MarkdownLinks\";\n\nconst textFromNode = (node: React.ReactNode): string => {\n    if (typeof node === \"string\" || typeof node === \"number\") {\n        return String(node);\n    }\n    if (Array.isArray(node)) {\n        return (node as React.ReactNode[]).map(textFromNode).join(\"\");\n    }\n    if (isValidElement<{ children?: React.ReactNode }>(node)) {\n        return textFromNode(node.props.children);\n    }\n    return \"\";\n};\n\nconst MarkdownCodeBlock = ({ children, ...props }: React.ComponentProps<\"pre\">) => {\n    const childNodes: React.ReactNode[] = Children.toArray(children);\n    const copyText = childNodes.map(textFromNode).join(\"\");\n\n    return (\n        <div className={\"group relative my-4\"}>\n            <CopyButton\n                copyText={copyText}\n                tiny\n                className={\"absolute top-2 right-2 z-10 opacity-80 hover:opacity-100\"}\n                linkClassName={\n                    \"border-0! bg-gray-100! text-gray-500! shadow-none! hover:bg-gray-200! hover:text-gray-700!\"\n                }\n                title={\"Copy code block\"}\n                titlePosition={\"left\"}\n            />\n            <pre\n                {...props}\n                className={\n                    \"max-w-full overflow-x-auto rounded-md bg-gray-50 p-4 pr-14 leading-8 dark:bg-primary-900 dark:text-dark-fg1 prose-code:text-[1.3rem] prose-code:text-gray-800! dark:prose-code:text-dark-fg1! [&_code]:bg-transparent! [&_code]:p-0!\"\n                }>\n                {children}\n            </pre>\n        </div>\n    );\n};\n\ntype MarkdownAlertType = \"note\" | \"tip\" | \"important\" | \"warning\" | \"caution\";\n\nconst markdownAlertMarkerPattern = /^\\s*\\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)]\\s*(?:\\n+)?/i;\n\nconst markdownAlertStyles: Record<\n    MarkdownAlertType,\n    {\n        label: string;\n        icon: IconDefinition;\n        className: string;\n        iconClassName: string;\n    }\n> = {\n    note: {\n        label: \"Note\",\n        icon: faCircleInfo,\n        className: \"border-sky-300 bg-sky-50 text-sky-950 dark:border-sky-500 dark:bg-sky-950/35 dark:text-sky-100\",\n        iconClassName: \"text-sky-600 dark:text-sky-300\",\n    },\n    tip: {\n        label: \"Tip\",\n        icon: faLightbulb,\n        className:\n            \"border-emerald-300 bg-emerald-50 text-emerald-950 dark:border-emerald-500 dark:bg-emerald-950/35 dark:text-emerald-100\",\n        iconClassName: \"text-emerald-600 dark:text-emerald-300\",\n    },\n    important: {\n        label: \"Important\",\n        icon: faCircleExclamation,\n        className:\n            \"border-violet-300 bg-violet-50 text-violet-950 dark:border-violet-500 dark:bg-violet-950/35 dark:text-violet-100\",\n        iconClassName: \"text-violet-600 dark:text-violet-300\",\n    },\n    warning: {\n        label: \"Warning\",\n        icon: faTriangleExclamation,\n        className:\n            \"border-amber-300 bg-amber-50 text-amber-950 dark:border-amber-500 dark:bg-amber-950/35 dark:text-amber-100\",\n        iconClassName: \"text-amber-600 dark:text-amber-300\",\n    },\n    caution: {\n        label: \"Caution\",\n        icon: faTriangleExclamation,\n        className:\n            \"border-rose-300 bg-rose-50 text-rose-950 dark:border-rose-500 dark:bg-rose-950/35 dark:text-rose-100\",\n        iconClassName: \"text-rose-600 dark:text-rose-300\",\n    },\n};\n\nconst markdownAlertTypeFromText = (text: string): MarkdownAlertType | null => {\n    const match = text.match(markdownAlertMarkerPattern);\n    return match ? (match[1].toLowerCase() as MarkdownAlertType) : null;\n};\n\nconst stripMarkdownAlertMarker = (node: React.ReactNode): { node: React.ReactNode; stripped: boolean } => {\n    if (typeof node === \"string\") {\n        const strippedNode = node.replace(markdownAlertMarkerPattern, \"\");\n        return { node: strippedNode, stripped: strippedNode !== node };\n    }\n    if (typeof node === \"number\") {\n        return { node, stripped: false };\n    }\n    if (Array.isArray(node)) {\n        let stripped = false;\n        const nodeArray = node as React.ReactNode[];\n        const strippedNodes: React.ReactNode[] = nodeArray.map((child) => {\n            if (stripped) {\n                return child;\n            }\n            const result = stripMarkdownAlertMarker(child);\n            stripped = result.stripped;\n            return result.node;\n        });\n        return { node: strippedNodes, stripped };\n    }\n    if (isValidElement(node)) {\n        const element = node as React.ReactElement<{ children?: React.ReactNode }>;\n        const result = stripMarkdownAlertMarker(element.props.children);\n        if (!result.stripped) {\n            return { node, stripped: false };\n        }\n        return { node: cloneElement(element, undefined, result.node), stripped: true };\n    }\n    return { node, stripped: false };\n};\n\nconst MarkdownBlockquote = ({ children, className, ...props }: React.ComponentProps<\"blockquote\">) => {\n    const childNodes = Children.toArray(children);\n    const markerChildIndex = childNodes.findIndex((child) => textFromNode(child).trim() !== \"\");\n    const markerChild = markerChildIndex >= 0 ? childNodes[markerChildIndex] : undefined;\n    const alertType = markerChild ? markdownAlertTypeFromText(textFromNode(markerChild)) : null;\n    if (!alertType) {\n        return (\n            <blockquote {...props} className={className}>\n                {children}\n            </blockquote>\n        );\n    }\n\n    const alertStyle = markdownAlertStyles[alertType];\n    const alertChildren = childNodes\n        .map((child, index) => (index === markerChildIndex ? stripMarkdownAlertMarker(child).node : child))\n        .filter((child) => textFromNode(child).trim() !== \"\");\n\n    return (\n        <div\n            className={cx(\n                \"my-4 rounded-md border border-l-4 px-4 py-3 text-[1.35rem] leading-7\",\n                \"[&_ol]:my-2 [&_p]:my-2 [&_ul]:my-2 [&>:first-child]:mt-0 [&>:last-child]:mb-0\",\n                alertStyle.className\n            )}>\n            <div className={\"mb-1 flex items-center gap-2 font-semibold\"}>\n                <FontAwesomeIcon fixedWidth icon={alertStyle.icon} className={alertStyle.iconClassName} />\n                <span>{alertStyle.label}</span>\n            </div>\n            <div>{alertChildren}</div>\n        </div>\n    );\n};\n\nexport const markdownCodeBlockComponents: Components = {\n    pre: MarkdownCodeBlock,\n};\n\nexport const markdownAlertComponents: Components = {\n    blockquote: MarkdownBlockquote,\n};\n\nconst MarkdownImage = ({ src, alt }: React.ComponentProps<\"img\">) => (\n    <AgentImageContent uri={src} alt={alt || \"Image\"} />\n);\n\nconst markdownImageComponents: Components = {\n    img: MarkdownImage,\n};\n\nexport const markdownConversationComponents: Components = {\n    ...markdownLinkComponents,\n    ...markdownAlertComponents,\n    ...markdownCodeBlockComponents,\n    ...markdownImageComponents,\n};\n\ninterface AgentMarkdownProps extends Omit<React.ComponentProps<\"div\">, \"children\"> {\n    children: string;\n    components?: Components;\n    remarkPlugins?: Options[\"remarkPlugins\"];\n}\n\nexport const AgentMarkdown = ({\n    children,\n    className,\n    components,\n    remarkPlugins = [],\n    ...props\n}: AgentMarkdownProps) => {\n    const app = useSelector(getApp);\n    const agentPathLinks = useMemo(() => agentPathReferenceLinks(app), [app]);\n\n    return (\n        <div\n            {...props}\n            className={cx(\n                \"prose max-w-[unset] dark:text-dark-fg1 dark:prose-invert prose-code:bg-[unset] prose-code:text-primary prose-code:before:content-none prose-code:after:content-none\",\n                className\n            )}>\n            <Markdown\n                remarkPlugins={[[remarkGfm, {}], agentPathLinks, ...(remarkPlugins ?? [])]}\n                components={{ ...markdownConversationComponents, ...components }}>\n                {children}\n            </Markdown>\n        </div>\n    );\n};\n","import { useMemo, type ReactNode } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport * as types from \"@/agent/types\";\nimport { getAgentsChatsLocation } from \"@/controllers/ide\";\nimport { cx } from \"@/theme/styles\";\nimport { AgentImageContent } from \"./AgentImageContent\";\nimport { AgentMarkdown } from \"./MarkdownComponents\";\n\nexport const AgentContent = ({\n    message,\n    finalResponse = false,\n}: {\n    message: types.AgentContentItem;\n    finalResponse?: boolean;\n}) => {\n    // Renders text and image content blocks. Images usually arrive via tool_call content or\n    // markdown asset links; this path covers agent_message_chunk image blocks if they show up.\n    // TODO: Handle other ACP content types (audio, resource, resource_link).\n    const agentChatsLocation = useSelector(getAgentsChatsLocation);\n    const markdownClassName = cx(\"text-[1.4rem]\", agentChatsLocation === \"bottom\" && \"text-[1.3rem]\", {\n        \"text-[1.2rem] text-light-bg6 dark:text-primary-200\": !finalResponse,\n    });\n\n    return useMemo(() => {\n        const nodes: ReactNode[] = [];\n        let textBuffer = \"\";\n        const flushText = (key: string) => {\n            if (!textBuffer) {\n                return;\n            }\n            nodes.push(\n                <AgentMarkdown key={key} className={markdownClassName}>\n                    {textBuffer}\n                </AgentMarkdown>\n            );\n            textBuffer = \"\";\n        };\n\n        message.events.forEach((event, index) => {\n            const { content } = event.event.update;\n            if (content.type === \"text\") {\n                textBuffer += content.text;\n                return;\n            }\n            if (content.type === \"image\") {\n                flushText(`text-${index}`);\n                nodes.push(\n                    <AgentImageContent\n                        key={`image-${index}`}\n                        data={content.data}\n                        mimeType={content.mimeType}\n                        uri={content.uri}\n                        alt={typeof content._meta?.name === \"string\" ? content._meta.name : \"Generated image\"}\n                    />\n                );\n            }\n        });\n        flushText(\"text-end\");\n        return <>{nodes}</>;\n    }, [markdownClassName, message.events]);\n};\n","import { useRef, useState } from \"react\";\nimport { faLightbulb } from \"@fortawesome/pro-solid-svg-icons/faLightbulb\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport type { ProposedPlanSection } from \"@/agent/types\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { cx } from \"@/theme/styles\";\nimport { useResizeObserver } from \"@/util/hooks\";\nimport { AgentMarkdown } from \"./MarkdownComponents\";\n\nexport const ProposedPlanContent = ({ plan }: Pick<ProposedPlanSection, \"plan\">) => {\n    switch (plan.type) {\n        case \"markdown\":\n            return (\n                <AgentMarkdown className=\"text-[1.4rem]\" data-conversation-search-scope=\"true\">\n                    {plan.content}\n                </AgentMarkdown>\n            );\n        case \"file\":\n            return <span>Plan file: {plan.uri}</span>;\n        case \"items\":\n            return (\n                <ul className=\"list-disc pl-6\">\n                    {plan.entries.map((entry, index) => (\n                        <li key={index} className={cx(entry.status === \"completed\" && \"line-through\")}>\n                            {entry.content}\n                        </li>\n                    ))}\n                </ul>\n            );\n    }\n};\n\nexport const ProposedPlanCard = ({\n    plan,\n    isWriting = false,\n}: Pick<ProposedPlanSection, \"plan\"> & { isWriting?: boolean }) => {\n    const scroller = useRef<HTMLDivElement>(null);\n    const content = useRef<HTMLDivElement>(null);\n    const [canScrollDown, setCanScrollDown] = useState(false);\n    const updateFade = () => {\n        const el = scroller.current;\n        if (el) setCanScrollDown(el.scrollTop + el.clientHeight < el.scrollHeight - 1);\n    };\n    useResizeObserver(scroller, updateFade);\n    useResizeObserver(content, updateFade);\n\n    return (\n        <div className=\"dark:border-dark-light-bg5 my-3 overflow-hidden rounded-lg border border-sectionborder bg-light-bg1 text-light-grey2 dark:bg-dark-bg1 dark:text-white\">\n            <div className=\"flex items-center gap-3 px-4 py-3\">\n                <FontAwesomeIcon className=\"text-light-grey1\" icon={faLightbulb} />\n                <div className=\"flex min-w-0 flex-1 items-center justify-between gap-3\">\n                    <span className=\"min-w-0 truncate font-medium\">Plan</span>\n                    {isWriting && (\n                        <div className=\"flex shrink-0 items-center gap-3 text-[1.2rem] font-normal text-light-grey1\">\n                            <span role=\"status\">Writing the plan</span>\n                            <LoadingSpinner inline sizeRem={1.5} />\n                        </div>\n                    )}\n                </div>\n            </div>\n            <div className=\"dark:border-dark-light-bg5 relative border-t border-sectionborder\">\n                <div\n                    ref={scroller}\n                    onScroll={updateFade}\n                    tabIndex={isWriting ? 0 : undefined}\n                    role={isWriting ? \"region\" : undefined}\n                    aria-label={isWriting ? \"Plan preview\" : undefined}\n                    className={cx(\n                        \"px-4 py-4\",\n                        isWriting && \"h-[16.4rem] overflow-y-auto overscroll-contain [overflow-anchor:none]\"\n                    )}>\n                    <div ref={content}>\n                        <ProposedPlanContent plan={plan} />\n                    </div>\n                </div>\n                {isWriting && canScrollDown && (\n                    <div\n                        aria-hidden=\"true\"\n                        className=\"pointer-events-none absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-light-bg1 to-transparent dark:from-dark-bg1\"\n                    />\n                )}\n            </div>\n        </div>\n    );\n};\n","import { useState } from \"react\";\nimport { faChevronDown } from \"@fortawesome/pro-light-svg-icons/faChevronDown\";\nimport { faChevronRight } from \"@fortawesome/pro-light-svg-icons/faChevronRight\";\nimport { faLightbulb } from \"@fortawesome/pro-solid-svg-icons/faLightbulb\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { AgentImageContent } from \"@/agent/components/AgentImageContent\";\nimport { AgentMarkdown } from \"@/agent/components/MarkdownComponents\";\nimport { ProposedPlanContent } from \"./ProposedPlan\";\nimport { useConversationContext } from \"@/agent/context\";\nimport type { PermissionSection } from \"@/agent/types\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { cx } from \"@/theme/styles\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { useConversationCallbacks } from \"../hooks\";\n\nexport const PermissionRequestCard = ({ section }: { section: PermissionSection }) => {\n    const { info } = useConversationContext();\n    const { onRespondToPermission } = useConversationCallbacks(info);\n    const [submitting, setSubmitting] = useState(false);\n    const [resolvedExpanded, setResolvedExpanded] = useState(false);\n    const isPending = section.response === null;\n    const selectedOptionId =\n        section.response?.event_type === \"permission_response\" ? section.response.event.option_id : undefined;\n    const selectedOption = section.request.event.options.find(({ optionId }) => optionId === selectedOptionId);\n    const cancelled =\n        section.response?.event_type === \"permission_cancelled\" ||\n        (section.response?.event_type === \"permission_response\" && !selectedOptionId);\n    const status = isPending\n        ? \"Awaiting approval\"\n        : cancelled\n          ? \"Cancelled\"\n          : selectedOption?.kind.startsWith(\"reject_\")\n            ? \"Kept planning\"\n            : \"Plan approved\";\n    const content = section.plan\n        ? []\n        : (section.request.event.tool_call.content?.flatMap((item) => {\n              if (item.type !== \"content\") return [];\n              if (item.content.type !== \"text\" && item.content.type !== \"image\") return [];\n              return [item.content];\n          }) ?? []);\n    const hasContent = content.length > 0 || section.plan != null;\n    const expanded = isPending || resolvedExpanded;\n    const choose = useEvent(async (optionId: string) => {\n        setSubmitting(true);\n        try {\n            await onRespondToPermission(section.request.event.permission_id, optionId);\n        } catch {\n            setSubmitting(false);\n        }\n    });\n\n    const heading = (\n        <>\n            <FontAwesomeIcon className=\"text-light-grey1\" icon={faLightbulb} />\n            <div className=\"flex min-w-0 flex-1 items-center justify-between gap-3\">\n                <span className=\"min-w-0 truncate font-medium\">Plan</span>\n                <span className=\"shrink-0 text-[1.2rem] font-normal text-light-grey1\">{status}</span>\n            </div>\n            {!isPending && hasContent && (\n                <FontAwesomeIcon className=\"text-light-grey1\" icon={expanded ? faChevronDown : faChevronRight} />\n            )}\n        </>\n    );\n\n    return (\n        <div\n            className={cx(\n                \"dark:border-dark-light-bg5 my-3 overflow-hidden rounded-lg border border-sectionborder text-light-grey2 dark:text-white\",\n                isPending ? \"bg-light-bg1 dark:bg-dark-bg1\" : \"bg-transparent\"\n            )}>\n            {isPending || !hasContent ? (\n                <div className=\"flex items-center gap-3 px-4 py-3\">{heading}</div>\n            ) : (\n                <LinkInternal\n                    aria-expanded={expanded}\n                    className=\"flex w-full items-center gap-3 px-4 py-3 hover:bg-light-bg1 dark:hover:bg-dark-bg1\"\n                    onClick={() => setResolvedExpanded((value) => !value)}>\n                    {heading}\n                </LinkInternal>\n            )}\n            {hasContent && (\n                <Expander isOpen={expanded}>\n                    <div className=\"dark:border-dark-light-bg5 border-t border-sectionborder px-4 py-4\">\n                        {section.plan && <ProposedPlanContent plan={section.plan} />}\n                        {content.map((item, index) => {\n                            if (item.type === \"text\") {\n                                return (\n                                    <AgentMarkdown\n                                        key={index}\n                                        className=\"text-[1.4rem]\"\n                                        data-conversation-search-scope=\"true\">\n                                        {item.text}\n                                    </AgentMarkdown>\n                                );\n                            }\n                            return (\n                                <div key={index} className={cx(index > 0 && \"mt-3\")}>\n                                    <AgentImageContent\n                                        data={item.data}\n                                        mimeType={item.mimeType}\n                                        uri={item.uri}\n                                        alt={\n                                            typeof item._meta?.name === \"string\"\n                                                ? item._meta.name\n                                                : \"Permission request image\"\n                                        }\n                                    />\n                                </div>\n                            );\n                        })}\n                    </div>\n                </Expander>\n            )}\n            {isPending && (\n                <div className=\"dark:border-dark-light-bg5 flex flex-wrap justify-end gap-2 border-t border-sectionborder px-4 py-3\">\n                    {section.request.event.options.map((option, index) => (\n                        <Button\n                            key={option.optionId}\n                            small\n                            variant={index === 0 ? \"primary\" : \"outlined\"}\n                            disabled={submitting}\n                            onClick={() => choose(option.optionId)}>\n                            {option.name}\n                        </Button>\n                    ))}\n                </div>\n            )}\n        </div>\n    );\n};\n","type ToolCallLocationLike = { path?: string | null };\n\nconst uniqueNonEmptyPaths = (paths: Array<string | null | undefined>): string[] => {\n    const seen = new Set<string>();\n    const uniquePaths: string[] = [];\n    for (const path of paths) {\n        const trimmedPath = path?.trim();\n        if (!trimmedPath || seen.has(trimmedPath)) {\n            continue;\n        }\n        seen.add(trimmedPath);\n        uniquePaths.push(trimmedPath);\n    }\n    return uniquePaths;\n};\n\nexport const editToolCallFiles = ({\n    content,\n    title,\n    locations,\n}: {\n    content?: unknown[] | null;\n    title: string;\n    locations?: ToolCallLocationLike[] | null;\n}): string[] => {\n    const locationPaths = uniqueNonEmptyPaths((locations ?? []).map((location) => location.path));\n    if (locationPaths.length) {\n        return locationPaths;\n    }\n\n    const contentPaths = uniqueNonEmptyPaths(\n        (content ?? []).map((item) =>\n            item && typeof item === \"object\" && \"path\" in item && typeof item.path === \"string\" ? item.path : null\n        )\n    );\n    if (contentPaths.length) {\n        return contentPaths;\n    }\n\n    return uniqueNonEmptyPaths(\n        title\n            .replace(/^Edit\\s+/, \"\")\n            .split(\",\")\n            .map((file) => file.trim())\n    );\n};\n","import { useMemo, type ReactNode } from \"react\";\nimport { faFile, faFileCode, faFileLines, faFileMagnifyingGlass } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { CancelableToolCall } from \"@/agent/types\";\nimport { cx } from \"@/theme/styles\";\nimport { useDebugThemePrefix } from \"@/util/hooks/assets\";\nimport { AgentImageContent } from \"./AgentImageContent\";\nimport { resolveAgentImageSrc } from \"./agentImageUrls\";\nimport { AgentToolCallDiff } from \"./AgentToolCallDiff\";\nimport { AgentPathReferenceText } from \"./MarkdownLinks\";\nimport { extractToolCallDiffs } from \"./agentToolCallDiffs\";\nimport { editToolCallFiles } from \"./agentToolCallFiles\";\n\n// const TOOL_CALL_STATUS_LABELS = {\n//     pending: \"Pending\",\n//     in_progress: \"In progress\",\n//     completed: \"Complete\",\n//     failed: \"Failed\",\n//     cancelled: \"Cancelled\",\n// } satisfies Record<ToolCallStatusWithCancelled, string>;\n\nconst ToolPathReference = ({ text }: { text: string }) => (\n    <span className=\"font-mono break-all\">\n        <AgentPathReferenceText text={text} />\n    </span>\n);\n\n// Codex ACP titles imagegen tool calls exactly \"Image generation\".\nconst isCodexImageGeneration = (toolCall: CancelableToolCall) =>\n    toolCall.title.trim().toLowerCase() === \"image generation\";\n\nexport const ToolCall = ({ toolCall }: { toolCall: CancelableToolCall }) => {\n    const themePrefix = useDebugThemePrefix();\n    // Only show execute/search commands (maybe just displaying the title would be better?)\n    // const cmd = (toolCall.rawInput as any)?.parsed_cmd?.[0]?.cmd || toolCall.title;\n    // const showCmd = toolCall.kind === \"execute\" || toolCall.kind === \"search\"\n    //const status = toolCall.status ? TOOL_CALL_STATUS_LABELS[toolCall.status] : \"Unknown\";\n\n    // console.log(toolCall);\n\n    // const callMessage = useMemo(() => {\n    //     if (toolCall.kind === \"execute\")\n    //         return <div className=\"font-mono\">{toolCall.title}</div>;\n\n    //     //todo: change this so that if it's type \"edit\",\n    //     const firstSpaceIndex = toolCall.title.indexOf(\" \");\n    //     if (firstSpaceIndex === -1) {\n    //         return <div>{toolCall.title}</div>;\n    //     }\n\n    //     return (\n    //         <div>\n    //             <span>{toolCall.title.slice(0, firstSpaceIndex)}</span>\n    //             <span className=\"font-mono\">{toolCall.title.slice(firstSpaceIndex)}</span>\n    //         </div>\n    //     );\n    // }, [toolCall.kind, toolCall.title]);\n\n    const { callMessage, toolKindIcon } = useMemo(() => {\n        let toolKindIcon;\n        let callMessage;\n\n        switch (toolCall.kind) {\n            case \"read\":\n                toolKindIcon = faFile;\n                const lines = toolCall.title.split(\",\").map((line) => line.trim());\n                callMessage = lines.map((line, i) => {\n                    const [action, ...restParts] = line.split(\" \");\n                    const rest = restParts.join(\" \");\n                    return (\n                        <div key={`${action}:${rest}:${i}`}>\n                            <span>{action} </span>\n                            {rest && <ToolPathReference text={rest} />}\n                        </div>\n                    );\n                });\n                break;\n            case \"search\":\n                toolKindIcon = faFileMagnifyingGlass;\n                const [action, ...rest] = toolCall.title.split(\" \");\n                callMessage =\n                    action === \"List\" ? (\n                        <div>\n                            <span>{action} </span>\n                            <ToolPathReference text={rest.join(\" \")} />\n                        </div>\n                    ) : (\n                        <div className=\"break-all\">{toolCall.title}</div>\n                    );\n                break;\n            case \"edit\":\n                toolKindIcon = faFileLines;\n                const diffs = extractToolCallDiffs(toolCall);\n                if (diffs.length) {\n                    callMessage = <AgentToolCallDiff diffs={diffs} />;\n                } else {\n                    const files = editToolCallFiles(toolCall);\n                    callMessage = (\n                        <div>\n                            <span className=\"leading-none\">Edit</span>\n                            {files.map((f, i) => (\n                                <div key={`${f}_${i}`} className=\"flex gap-4 font-mono\">\n                                    • <ToolPathReference text={f} />\n                                </div>\n                            ))}\n                        </div>\n                    );\n                }\n                break;\n            default:\n                toolKindIcon = faFileCode;\n                callMessage = <div className=\"font-mono\">{toolCall.title}</div>;\n        }\n        return { callMessage, toolKindIcon };\n    }, [toolCall.content, toolCall.kind, toolCall.locations, toolCall.title]);\n\n    // Image content only — tool text (including Codex \"Revised prompt:\") stays hidden.\n    const contentNodes = useMemo(() => {\n        const nodes: ReactNode[] = [];\n        let renderedImage = false;\n        for (const [index, item] of (toolCall.content ?? []).entries()) {\n            if (item.type !== \"content\" || item.content.type !== \"image\") {\n                continue;\n            }\n            const block = item.content;\n            nodes.push(\n                <AgentImageContent\n                    key={index}\n                    data={block.data}\n                    mimeType={block.mimeType}\n                    uri={block.uri}\n                    alt={typeof block._meta?.name === \"string\" ? block._meta.name : \"Generated image\"}\n                />\n            );\n            // AgentImageContent returns null when src is unresolvable; only then try rawOutput.\n            if (\n                resolveAgentImageSrc({\n                    data: block.data,\n                    mimeType: block.mimeType,\n                    uri: block.uri,\n                    themePrefix,\n                })\n            ) {\n                renderedImage = true;\n            }\n        }\n        // Codex imagegen may leave only a filesystem uri on content; rawOutput.result still has PNG base64.\n        const rawOutput = toolCall.rawOutput as { result?: unknown } | undefined;\n        if (\n            !renderedImage &&\n            isCodexImageGeneration(toolCall) &&\n            typeof rawOutput?.result === \"string\" &&\n            rawOutput.result.length > 0\n        ) {\n            nodes.push(\n                <AgentImageContent\n                    key=\"raw-output-image\"\n                    data={rawOutput.result}\n                    mimeType=\"image/png\"\n                    alt=\"Generated image\"\n                />\n            );\n        }\n        return nodes;\n    }, [themePrefix, toolCall, toolCall.content, toolCall.rawOutput]);\n\n    return (\n        <div className={cx(\"-m-2 py-1 dark:text-dark-fg1\")}>\n            <div className={\"relative flex items-start gap-x-8 pt-1 dark:text-light-bg6\"}>\n                {/* < className={cx(\"flex items-center  -m-2 pb-2\" */}\n                <div className=\"shrink-0\">\n                    <FontAwesomeIcon\n                        className={cx(\"py-1\", \"bg-white text-light-bg6\", \"dark:bg-dark-bg0\")}\n                        icon={toolKindIcon}\n                    />\n                </div>\n                <div className=\"relative -top-1 flex min-w-0 flex-1 flex-col text-[1.25rem]\">\n                    {callMessage}\n                    {contentNodes}\n                </div>\n            </div>\n        </div>\n    );\n};\n","import { AgentTurnDiff } from \"./AgentTurnDiff\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport type { Components } from \"react-markdown\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport type { AvailableCommand, PromptRequestMessage } from \"@agent-host/rpc_types\";\nimport { faChevronDown } from \"@fortawesome/pro-light-svg-icons/faChevronDown\";\nimport { faChevronRight } from \"@fortawesome/pro-light-svg-icons/faChevronRight\";\nimport { faCube } from \"@fortawesome/pro-regular-svg-icons/faCube\";\nimport { faLightbulb } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { AgentContent } from \"@/agent/components/AgentContent.tsx\";\nimport { AgentImageContent } from \"@/agent/components/AgentImageContent\";\nimport { FormElicitationHistory } from \"@/agent/components/FormElicitationCard\";\nimport { PermissionRequestCard } from \"@/agent/components/PermissionRequestCard\";\nimport { ProposedPlanCard } from \"@/agent/components/ProposedPlan\";\nimport { ToolCall } from \"@/agent/components/ToolCall\";\nimport { useConversationContext } from \"@/agent/context\";\nimport { buildResponseTimeline } from \"@/agent/responseTimeline\";\nimport * as types from \"@/agent/types\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { CopyButton } from \"@/components/reusable/CopyButton\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { formatRelativeCalendarTime } from \"@/controllers/agents\";\nimport { getAgentsChatsLocation } from \"@/controllers/ide\";\nimport { alert } from \"@/controllers/modals\";\nimport { getAgentTypeName } from \"@/controllers/user-agent-types\";\nimport { cx } from \"@/theme/styles\";\nimport type { AnvilDispatch } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { isTurnActive } from \"../hooks\";\nimport { AgentMarkdown } from \"./MarkdownComponents\";\nimport { MarkdownLink } from \"./MarkdownLinks\";\nimport { findSlashCommandTokenMatches, slashCommandDisplayText } from \"./conversationSkillCommands\";\nimport {\n    availableCommandSourceLabel,\n    availableCommandSubmittedTokenName,\n    sourceLabelDisplayText,\n} from \"./promptComposer/completionCommandHelpers\";\n\ninterface PromptCommand {\n    name: string;\n    slashCommandName: string;\n    type: string;\n    description?: string;\n    inputHint?: string;\n}\n\nconst skillLinkPrefix = \"agent-skill:\";\n\nconst skillNameFromLinkTitle = (title: string | null | undefined): string | null => {\n    if (!title?.startsWith(skillLinkPrefix)) {\n        return null;\n    }\n    return title.slice(skillLinkPrefix.length);\n};\n\nconst addSkillCommandLinks = (tree: any, commandsByName: Map<string, PromptCommand>) => {\n    const visit = (node: any) => {\n        if (!node?.children) {\n            return;\n        }\n        node.children = node.children.flatMap((child: any) => {\n            if (child.type !== \"text\" || typeof child.value !== \"string\") {\n                visit(child);\n                return [child];\n            }\n            const nodes: any[] = [];\n            let lastIndex = 0;\n            for (const match of findSlashCommandTokenMatches(child.value)) {\n                const command = commandsByName.get(match.commandName);\n                if (!command) {\n                    continue;\n                }\n                if (match.tokenStart > lastIndex) {\n                    nodes.push({ type: \"text\", value: child.value.slice(lastIndex, match.tokenStart) });\n                }\n                nodes.push({\n                    type: \"link\",\n                    url: \"\",\n                    title: `${skillLinkPrefix}${match.commandName}`,\n                    children: [{ type: \"text\", value: slashCommandDisplayText(match.commandName) }],\n                });\n                lastIndex = match.tokenEnd;\n            }\n            if (lastIndex === 0) {\n                return [child];\n            }\n            if (lastIndex < child.value.length) {\n                nodes.push({ type: \"text\", value: child.value.slice(lastIndex) });\n            }\n            return nodes;\n        });\n    };\n    visit(tree);\n};\n\nconst SkillDetails = ({ command }: { command: PromptCommand }) => (\n    <div className={\"space-y-4\"}>\n        <code className={\"inline-block rounded-[0.4rem] bg-secondary-50 px-2 py-1 text-primary-800\"}>\n            {slashCommandDisplayText(command.slashCommandName)}\n        </code>\n        <div className={\"text-light-grey1\"}>{sourceLabelDisplayText(command.type)}</div>\n        <div className={\"whitespace-pre-line\"}>{command.description || \"No description available.\"}</div>\n        {command.inputHint && <div className={\"text-light-grey1\"}>{command.inputHint}</div>}\n    </div>\n);\n\nconst useShowSkillDetails = (commandsByName: Map<string, PromptCommand>) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    return useEvent((skillName: string) => {\n        const command = commandsByName.get(skillName);\n        if (!command) {\n            return;\n        }\n        dispatch(alert(command.name, <SkillDetails command={command} />));\n    });\n};\n\nconst SkillCommandButton = ({\n    skillName,\n    children,\n    showSkillDetails,\n}: {\n    skillName: string;\n    children: React.ReactNode;\n    showSkillDetails(skillName: string): void;\n}) => (\n    <Button\n        tiny\n        icon={faCube}\n        variant={\"secondary\"}\n        className={\"inline-flex align-baseline\"}\n        linkClassName={\"px-2! py-0.5! font-mono text-[1.2rem]!\"}\n        onClick={() => showSkillDetails(skillName)}\n        // title={\n        //     <span className=\"block w-96 whitespace-pre-wrap\">\n        //         {[command?.type, command?.description].filter(Boolean).join(\": \")}\n        //     </span>\n        // }\n    >\n        {children}\n    </Button>\n);\n\nconst makePromptMarkdownComponents = (showSkillDetails: (skillName: string) => void): Components => ({\n    p: ({ children, className, ...props }: React.ComponentProps<\"p\">) => (\n        <p {...props} className={cx(\"whitespace-pre-wrap\", className)}>\n            {children}\n        </p>\n    ),\n    a: ({ href, title, children }: { href?: string; title?: string | null; children?: React.ReactNode }) => {\n        const skillName = skillNameFromLinkTitle(title);\n        if (skillName) {\n            return (\n                <SkillCommandButton skillName={skillName} showSkillDetails={showSkillDetails}>\n                    {children}\n                </SkillCommandButton>\n            );\n        }\n\n        return <MarkdownLink href={href}>{children}</MarkdownLink>;\n    },\n});\n\nconst usePromptCommandsByName = (availableCommands: AvailableCommand[]): Map<string, PromptCommand> => {\n    return useMemo(() => {\n        const commandsByName = new Map<string, PromptCommand>();\n        for (const command of availableCommands) {\n            const slashCommandName = availableCommandSubmittedTokenName(command);\n            commandsByName.set(slashCommandName, {\n                name: slashCommandName.startsWith(\"$\") ? slashCommandName.slice(1) : slashCommandName,\n                slashCommandName,\n                type: availableCommandSourceLabel(command),\n                description: command.description,\n                inputHint: command.input?.hint,\n            });\n        }\n        return commandsByName;\n    }, [availableCommands]);\n};\n\ninterface ResponseTimelineProps {\n    turn: types.PromptTurn;\n    timestamp?: string;\n}\n\ninterface PromptTurnProps {\n    turn: types.PromptTurn;\n}\n\ninterface PromptProps {\n    prompt: PromptRequestMessage[\"prompt\"];\n    submitting?: boolean;\n    pending?: boolean;\n    timestamp?: string;\n}\n\nconst textFromPrompt = (prompt: PromptRequestMessage[\"prompt\"]) =>\n    prompt\n        .filter((contentBlock) => contentBlock.type === \"text\")\n        .map((contentBlock) => contentBlock.text)\n        .join(\"\\n\\n\");\n\nexport const Prompt = ({ prompt, submitting, pending, timestamp }: PromptProps) => {\n    const { conversation } = useConversationContext();\n\n    const commandsByName = usePromptCommandsByName(conversation.availableCommands);\n    const skillCommandLinks = useCallback(\n        () => (tree: any) => addSkillCommandLinks(tree, commandsByName),\n        [commandsByName]\n    );\n    const showSkillDetails = useShowSkillDetails(commandsByName);\n\n    const markdownComponents = useMemo(() => makePromptMarkdownComponents(showSkillDetails), [showSkillDetails]);\n    const agentChatsLocation = useSelector(getAgentsChatsLocation);\n    const hasPromptText = prompt.some((contentBlock) => contentBlock.type === \"text\" && contentBlock.text.length > 0);\n\n    return (\n        <div\n            className={cx(\n                \"group flex max-w-3/4 min-w-0 flex-col items-end self-end\",\n                (submitting || pending) && \"opacity-50\"\n            )}>\n            <div\n                className={cx(\n                    \"w-content max-w-full min-w-0 rounded-sm\",\n                    \"bg-[#F1FBFF] p-4 text-light-grey2\",\n                    \"dark:bg-primary-800 dark:text-white\"\n                )}>\n                <div className={\"max-w-full min-w-0 overflow-x-auto\"}>\n                    {prompt.map((cb, i) => {\n                        switch (cb.type) {\n                            case \"text\": {\n                                return (\n                                    <AgentMarkdown\n                                        key={i}\n                                        className={cx(\n                                            \"text-[1.4rem] text-light-grey2 dark:text-white\",\n                                            agentChatsLocation === \"bottom\" && \"text-[1.3rem]\"\n                                        )}\n                                        remarkPlugins={[skillCommandLinks]}\n                                        components={markdownComponents}\n                                        data-conversation-search-scope=\"true\"\n                                        data-conversation-search-scope-kind=\"prompt\">\n                                        {cb.text}\n                                    </AgentMarkdown>\n                                );\n                            }\n                            case \"image\":\n                                return (\n                                    <AgentImageContent\n                                        key={i}\n                                        data={cb.data}\n                                        mimeType={cb.mimeType}\n                                        uri={cb.uri}\n                                        alt={typeof cb._meta?.name === \"string\" ? cb._meta.name : \"Uploaded image\"}\n                                    />\n                                );\n                        }\n                    })}\n                </div>\n            </div>\n            <div className=\"mt-2\">\n                <span className=\"mr-2 text-xl text-grey-1\">{formatRelativeCalendarTime(timestamp)}</span>\n                {hasPromptText && (\n                    <CopyButton\n                        copyText={() => textFromPrompt(prompt)}\n                        tiny\n                        className={\n                            \"mt-1 opacity-20 transition-opacity group-focus-within:opacity-70 group-hover:opacity-70 hover:opacity-100\"\n                        }\n                        title={\"Copy message\"}\n                        titlePosition={\"left\"}\n                    />\n                )}\n            </div>\n        </div>\n    );\n};\n\ninterface SectionProps<T extends types.ResponseSection> {\n    promptTurn: types.PromptTurn;\n    section: T;\n}\n\ntype AgentContentSectionProps = SectionProps<types.AgentMessagesSection | types.AgentThoughtsSection> & {\n    contentType: \"message\" | \"thought\";\n};\n\nconst AgentContentSection = ({ section, contentType }: AgentContentSectionProps) => {\n    const [collapsed, setCollapsed] = useState(false);\n    return (\n        <div>\n            <div className={cx(\"-m-2 flex items-center gap-x-8 pb-2\")}>\n                <FontAwesomeIcon\n                    className={cx(\"py-1\", \"bg-white text-light-bg6\", \"dark:bg-dark-bg0 dark:text-light-bg6\")}\n                    icon={faLightbulb}\n                />\n                <LinkInternal\n                    iconRight\n                    className={\"text-[1.25rem] dark:text-light-bg6\"}\n                    icon={collapsed ? faChevronRight : faChevronDown}\n                    onClick={() => setCollapsed((c) => !c)}>\n                    Agent {contentType === \"message\" ? \"message\" : \"thought\"}{\" \"}\n                </LinkInternal>{\" \"}\n                {/* todo: include \"for %some amount of time%\" */}\n            </div>\n            <Expander isOpen={!collapsed} className=\"pl-14\">\n                {section.messages.map((message, idx) => (\n                    <AgentContent message={message} key={idx} />\n                ))}\n            </Expander>\n        </div>\n    );\n    // return section.messages.map((message, idx) => <AgentMessage message={message} key={idx} />);\n};\n\nconst ToolCallsSection = ({ promptTurn, section }: SectionProps<types.ToolCallsSection>) => {\n    const [collapsed, setCollapsed] = useState(true);\n    const allDone = useMemo(() => {\n        return section.toolCalls.every(\n            (call) => call.status === \"completed\" || call.status === \"failed\" || call.status === \"cancelled\"\n        );\n    }, [section.toolCalls]);\n    const elicitationToolCallIds = new Set(\n        promptTurn.responseSections\n            .filter((candidate): candidate is types.FormElicitationSection => candidate.sectionType === \"form_elicitation\")\n            .map((candidate) => candidate.request.event.tool_call_id)\n            .filter((toolCallId): toolCallId is string => !!toolCallId)\n    );\n    const permissionToolCallIds = new Set(\n        promptTurn.responseSections\n            .filter((candidate): candidate is types.PermissionSection => candidate.sectionType === \"permission\")\n            .map((candidate) => candidate.toolCall.toolCallId)\n    );\n    const visibleToolCalls = section.toolCalls.filter(\n        (call) => !elicitationToolCallIds.has(call.toolCallId) && !permissionToolCallIds.has(call.toolCallId)\n    );\n    return (\n        <div>\n            {/* <div className=\"hidden\">\n                <div>\n                    <LinkInternal\n                        iconRight\n                        icon={collapsed ? faChevronRight : faChevronDown}\n                        onClick={() => setCollapsed((c) => !c)}>\n                        {allDone ? \"Worked\" : \"Working...\"}\n                    </LinkInternal>{\" \"}\n                </div>\n                {!collapsed && section.toolCalls.map((call, idx) => <ToolCall toolCall={call} key={idx} />)}\n            </div> */}\n            <div>\n                {visibleToolCalls.map((call, idx) => (\n                    <ToolCall toolCall={call} key={call.toolCallId ?? idx} />\n                ))}\n            </div>\n        </div>\n    );\n};\n\nconst ResponseSection = ({ promptTurn, section }: SectionProps<types.ResponseSection>) => {\n    switch (section.sectionType) {\n        case \"agent_messages\":\n            return <AgentContentSection promptTurn={promptTurn} section={section} contentType={\"message\"} />;\n        case \"agent_thoughts\":\n            return <AgentContentSection promptTurn={promptTurn} section={section} contentType={\"thought\"} />;\n        case \"tool_calls\":\n            return <ToolCallsSection promptTurn={promptTurn} section={section} />;\n        case \"proposed_plan\":\n            return <ProposedPlanCard plan={section.plan} />;\n        case \"form_elicitation\":\n            return <FormElicitationHistory section={section} />;\n        case \"permission\":\n            return <PermissionRequestCard section={section} />;\n    }\n};\n\nconst AgentFinalMessage = ({ promptTurn, section }: SectionProps<types.AgentMessagesSection>) => {\n    return section.messages.map((message, idx) => (\n        <div key={idx} data-conversation-search-scope=\"true\" data-conversation-search-scope-kind=\"final\">\n            <AgentContent message={message} finalResponse />\n        </div>\n    ));\n};\nconst ResponseTimeline = ({ turn, timestamp }: ResponseTimelineProps) => {\n    const { conversation } = useConversationContext();\n    const currentPromptTurn =\n        conversation.currentPromptTurnIndex !== null && conversation.currentPromptTurnIndex !== undefined\n            ? conversation.turns[conversation.currentPromptTurnIndex]\n            : undefined;\n    const isWorkingOnThisTurn = turn === currentPromptTurn && isTurnActive(conversation!);\n\n    const [collapsed, setCollapsed] = useState(true);\n\n    // Permission requests are chronological checkpoints. The plan immediately before one and\n    // any later final response stay visible, while work on either side remains collapsible in place.\n    const timeline = useMemo(\n        () =>\n            buildResponseTimeline(turn.responseSections, {\n                isTurnActive: isWorkingOnThisTurn && !turn.cancellationRequested,\n            }),\n        [turn, isWorkingOnThisTurn]\n    );\n    const isWritingPlan = timeline.some((item) => item.itemType === \"writing_plan\");\n    const hasWorkingSections = timeline.some((item) => item.itemType === \"working\");\n    const awaitingPermission = turn.responseSections.some(\n        (section) => section.sectionType === \"permission\" && section.response === null\n    );\n\n    const agentChatsLocation = useSelector(getAgentsChatsLocation);\n\n    let duration: string | null = null;\n    if (turn.promptRequest && turn.promptResponse) {\n        const startTime = new Date(turn.promptRequest.created_at);\n        const endTime = new Date(turn.promptResponse.created_at);\n        const diffMs = endTime.getTime() - startTime.getTime();\n        duration = Math.ceil(diffMs / 1000).toString() + \"s\";\n    }\n\n    return (\n        <div className={cx(\"flex flex-col gap-y-6 pt-4\", agentChatsLocation === \"bottom\" && \"gap-y-3\")}>\n            {((isWorkingOnThisTurn && !isWritingPlan) || hasWorkingSections) && (\n                <LinkInternal\n                    iconRight\n                    icon={!hasWorkingSections ? undefined : collapsed ? faChevronRight : faChevronDown}\n                    className={\"text-[1.4rem] text-light-bg6 dark:text-primary-200\"}\n                    onClick={() => setCollapsed((c) => !c)}>\n                    {isWritingPlan ? \"Work details\" : getAgentTypeName(turn.promptRequest.agent_type)}\n                    {isWritingPlan\n                        ? \"\"\n                        : isWorkingOnThisTurn\n                          ? awaitingPermission\n                              ? \" is awaiting approval...\"\n                              : \" is working...\"\n                          : ` worked for ${duration}`}{\" \"}\n                </LinkInternal>\n            )}\n            <div>\n                {timeline.map((item, index) => {\n                    if (item.itemType === \"working\") {\n                        return (\n                            <Expander key={`working-${index}`} isOpen={!collapsed}>\n                                <div className=\"ml-2 flex flex-col gap-y-2 border-l border-light-bg5 text-light-bg5 dark:border-light-bg7\">\n                                    {item.sections.map((section, sectionIndex) => (\n                                        <ResponseSection key={sectionIndex} promptTurn={turn} section={section} />\n                                    ))}\n                                </div>\n                            </Expander>\n                        );\n                    }\n                    if (item.itemType === \"writing_plan\") {\n                        return (\n                            <div key={`plan-${item.section.plan.planId}`} className=\"pt-4\">\n                                <ProposedPlanCard plan={item.section.plan} isWriting />\n                            </div>\n                        );\n                    }\n                    if (item.itemType === \"permission_checkpoint\") {\n                        return (\n                            <div key={`permission-${item.section.request.event.permission_id}`} className=\"pt-4\">\n                                <PermissionRequestCard section={item.section} />\n                            </div>\n                        );\n                    }\n                    if (item.itemType === \"settled\" && item.section.sectionType === \"agent_messages\") {\n                        return (\n                            <div key={`message-${index}`} className=\"pt-4\">\n                                <AgentFinalMessage promptTurn={turn} section={item.section} />\n                            </div>\n                        );\n                    }\n                    return (\n                        <div key={`settled-${index}`} className=\"pt-4\">\n                            <ResponseSection promptTurn={turn} section={item.section} />\n                        </div>\n                    );\n                })}\n                {!isWorkingOnThisTurn && <AgentTurnDiff turn={turn} />}\n                {isWorkingOnThisTurn && !awaitingPermission && !isWritingPlan ? (\n                    <div className={\"ml-1 min-h-10 pt-2 pb-2 text-center\"}>\n                        <LoadingSpinner inline sizeRem={1.5} />\n                    </div>\n                ) : !isWorkingOnThisTurn ? (\n                    <span className=\"mr-2 text-xl text-grey-1\">{formatRelativeCalendarTime(timestamp)}</span>\n                ) : null}\n            </div>\n        </div>\n    );\n};\n\nexport const PromptTurn = ({ turn }: PromptTurnProps) => {\n    return (\n        <>\n            <Prompt prompt={turn.promptRequest.event.prompt} timestamp={turn.promptRequest.created_at} />\n            <div>\n                <ResponseTimeline turn={turn} timestamp={turn.promptResponse?.created_at} />\n            </div>\n        </>\n    );\n};\n","import type { PermissionSection, ProposedPlanSection, ResponseSection } from \"@/agent/types\";\n\ntype ResponseTimelineItem =\n    | { itemType: \"working\"; sections: ResponseSection[] }\n    | { itemType: \"permission_checkpoint\"; section: PermissionSection }\n    | { itemType: \"writing_plan\"; section: ProposedPlanSection }\n    | { itemType: \"settled\"; section: ResponseSection };\n\nexport const buildResponseTimeline = (\n    sections: ResponseSection[],\n    { isTurnActive = false }: { isTurnActive?: boolean } = {}\n): ResponseTimelineItem[] => {\n    const awaitingPermission = sections.some(\n        (section) => section.sectionType === \"permission\" && section.response === null\n    );\n    const settledIndexes = new Set<number>();\n    let latestMessageIndex: number | null = null;\n\n    for (const [index, section] of sections.entries()) {\n        if (section.sectionType === \"agent_messages\") latestMessageIndex = index;\n        if (section.sectionType === \"proposed_plan\") settledIndexes.add(index);\n        if (section.sectionType === \"permission\") settledIndexes.add(index);\n    }\n    if (latestMessageIndex !== null) settledIndexes.add(latestMessageIndex);\n\n    const timeline: ResponseTimelineItem[] = [];\n    let workingSections: ResponseSection[] = [];\n    const flushWorking = () => {\n        if (workingSections.length > 0) {\n            timeline.push({ itemType: \"working\", sections: workingSections });\n            workingSections = [];\n        }\n    };\n\n    sections.forEach((section, index) => {\n        if (section.sectionType === \"form_elicitation\" && section.response === null) return;\n        if (section.sectionType === \"permission\") {\n            flushWorking();\n            timeline.push({ itemType: \"permission_checkpoint\", section });\n            return;\n        }\n        if (\n            isTurnActive &&\n            !awaitingPermission &&\n            section.sectionType === \"proposed_plan\" &&\n            section.plan.type === \"markdown\"\n        ) {\n            flushWorking();\n            timeline.push({ itemType: \"writing_plan\", section });\n            return;\n        }\n        if (settledIndexes.has(index)) {\n            flushWorking();\n            timeline.push({ itemType: \"settled\", section });\n        } else {\n            workingSections.push(section);\n        }\n    });\n    flushWorking();\n    return timeline;\n};\n","import { useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faCheck, faListCheck, faTriangleExclamation } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { canApplySchemaDiffDirectly, summariseSchemaDiff } from \"@/agent/schemaMigration\";\nimport type { ConversationInfo } from \"@/agent/types\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { updateAppSchemaSync } from \"@/controllers/app\";\nimport { updateTableMappingSchema } from \"@/controllers/db\";\nimport { alert } from \"@/controllers/modals\";\nimport { getAgentTypeName } from \"@/controllers/user-agent-types\";\nimport { navigate } from \"@/router/navigation\";\nimport { cx } from \"@/theme/styles\";\nimport type { AnvilDispatch } from \"@/types\";\nimport type { TableMapping } from \"@/types/database\";\n\nexport const SchemaMigrationBanner = ({\n    conversationInfo,\n    tableMapping,\n    turnActive,\n    isNewConversation,\n}: {\n    conversationInfo: ConversationInfo;\n    tableMapping: TableMapping;\n    turnActive: boolean;\n    isNewConversation: boolean;\n}) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const canApplyDirectly = !isNewConversation && canApplySchemaDiffDirectly(tableMapping.diff);\n    const summary = summariseSchemaDiff(tableMapping.diff);\n    const agentName = getAgentTypeName(conversationInfo.agent_type);\n    const [applying, setApplying] = useState(false);\n\n    const reportFailure = async (error: unknown) => {\n        const message =\n            typeof error === \"object\" && error !== null\n                ? \"message\" in error\n                    ? String(error.message)\n                    : \"error\" in error\n                      ? String(error.error)\n                      : \"Unable to update the Debug database.\"\n                : \"Unable to update the Debug database.\";\n        await dispatch(alert(\"Could not apply schema changes\", message));\n    };\n\n    const resolveChanges = () =>\n        dispatch(navigate({ type: \"APP_SCHEMA\", tableMappingId: tableMapping.table_mapping_id }));\n\n    const applyChanges = async () => {\n        setApplying(true);\n        try {\n            await dispatch(updateTableMappingSchema(tableMapping, tableMapping.diff));\n            await dispatch(updateAppSchemaSync());\n        } catch (error) {\n            await reportFailure(error);\n        } finally {\n            setApplying(false);\n        }\n    };\n\n    return (\n        <div\n            className={cx(\n                \"flex w-full flex-wrap items-center gap-x-6 gap-y-3 border-b px-5 py-4\",\n                isNewConversation\n                    ? \"border-amber-300 bg-amber-50 dark:border-amber-500 dark:bg-amber-950/35\"\n                    : turnActive\n                      ? \"border-sectionborder bg-light-bg1/60 dark:border-primary-800 dark:bg-primary-700/10\"\n                      : \"border-primary-300 bg-primary-50 dark:border-primary-700 dark:bg-primary-700/30\"\n            )}>\n            <div className=\"min-w-60 grow text-xl text-light-fg1 dark:text-dark-fg1\">\n                {isNewConversation ? (\n                    <>\n                        <FontAwesomeIcon\n                            icon={faTriangleExclamation}\n                            size=\"lg\"\n                            className=\"mr-2 text-amber-600 dark:text-amber-300\"\n                        />\n                        <strong>Schema Mismatch</strong> Your app is expecting a schema that does not match <strong>{tableMapping.name}</strong>.\n                    </>\n                ) : (\n                    <>\n                        {agentName} wants to {summary}. Apply to <strong>{tableMapping.name}</strong>?\n                    </>\n                )}\n            </div>\n            <div className=\"flex shrink-0 gap-3\">\n                <Button\n                    size=\"small\"\n                    icon={faListCheck}\n                    variant={canApplyDirectly ? \"outlined\" : \"primary\"}\n                    disabled={applying}\n                    onClick={resolveChanges}>\n                    Resolve\n                </Button>\n                {canApplyDirectly && (\n                    <Button\n                        size=\"small\"\n                        icon={faCheck}\n                        variant=\"primary\"\n                        disabled={applying}\n                        onClick={applyChanges}>\n                        Apply\n                    </Button>\n                )}\n            </div>\n        </div>\n    );\n};\n","import { type KeyboardEventHandler, useEffect, useMemo, useRef } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faDatabase } from \"@fortawesome/pro-light-svg-icons/faDatabase\";\nimport { faTable } from \"@fortawesome/pro-light-svg-icons/faTable\";\nimport { faTimes } from \"@fortawesome/pro-light-svg-icons/faTimes\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { sortBy } from \"lodash-es\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { SecondaryNavLink } from \"@/components/sidebar/SecondaryNavSection\";\nimport { getAllTableMappings, getAppId } from \"@/controllers/app\";\nimport { getTableNavTarget, reloadTableMapping } from \"@/controllers/db\";\nimport { useNavTargetSelector } from \"@/router/navigation-hooks\";\nimport type { AnvilDispatch } from \"@/types\";\n\nconst activateButtonOnKeyDown: KeyboardEventHandler<HTMLSpanElement> = (event) => {\n    if (event.key === \"Enter\" || event.key === \" \") {\n        event.preventDefault();\n        event.currentTarget.click();\n    }\n};\n\nexport const TemporaryDatabaseDialog = ({\n    tableMappingId,\n    id,\n    closeOnTableClick,\n    onClose,\n}: {\n    tableMappingId: number;\n    id: string;\n    closeOnTableClick: boolean;\n    onClose(): void;\n}) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const appId = useSelector(getAppId);\n    const mappings = useSelector(getAllTableMappings);\n    const mapping = mappings?.find((mapping) => mapping.table_mapping_id === tableMappingId);\n    const tables = useMemo(() => sortBy(mapping?.tables ?? [], \"name\"), [mapping?.tables]);\n    const selectedTableId = useNavTargetSelector((target) =>\n        target?.type === \"DB_TABLE\" && target.tableMappingId === tableMappingId ? target.tableId : undefined\n    );\n    const dialogRef = useRef<HTMLDialogElement>(null);\n\n    useEffect(() => {\n        const dialog = dialogRef.current;\n        const previousFocus = document.activeElement;\n        dialog?.focus();\n        return () => {\n            // Return focus on dismissal, without taking focus back from a newly opened table tab.\n            if (\n                previousFocus instanceof HTMLElement &&\n                (dialog?.contains(document.activeElement) || document.activeElement === document.body)\n            ) {\n                previousFocus.focus();\n            }\n        };\n    }, []);\n    const { isPending, isError } = useQuery({\n        queryKey: [\"conversation-database\", appId, tableMappingId],\n        queryFn: () => dispatch(reloadTableMapping(tableMappingId)),\n        enabled: !!appId,\n        // Refetch on reopening: the agent may have changed this database while another chat was open.\n        staleTime: 0,\n        retry: false,\n    });\n\n    return (\n        <div\n            className=\"absolute inset-0 z-30 flex items-center justify-center overflow-hidden bg-black/15 p-4\"\n            onClick={(event) => {\n                if (event.target === event.currentTarget) onClose();\n            }}>\n            <dialog\n                open\n                ref={dialogRef}\n                id={id}\n                tabIndex={-1}\n                aria-labelledby={`${id}-title`}\n                aria-describedby={`${id}-description`}\n                className=\"relative m-0 max-h-full w-full max-w-[52rem] overflow-x-hidden overflow-y-auto rounded-xl border border-sectionborder bg-white p-8 text-grey-2 shadow-lg outline-none dark:border-dark-sectionborder dark:bg-dark-bg0 dark:text-white\"\n                onKeyDown={(event) => {\n                    if (event.key === \"Escape\") {\n                        event.preventDefault();\n                        event.stopPropagation();\n                        onClose();\n                    }\n                }}>\n                <div className=\"sticky top-0 z-10 flex items-center gap-2 bg-white pb-5 dark:bg-dark-bg0\">\n                    <span id={`${id}-title`} className=\"flex grow items-center gap-3 font-semibold\">\n                        <FontAwesomeIcon icon={faDatabase} fixedWidth aria-hidden=\"true\" />\n                        Temporary Database\n                    </span>\n                    <Button\n                        size=\"small\"\n                        variant=\"hidden\"\n                        icon={faTimes}\n                        aria-label=\"Close Temporary Database\"\n                        onKeyDown={activateButtonOnKeyDown}\n                        onClick={onClose}\n                    />\n                </div>\n                <p id={`${id}-description`} className=\"mb-8 text-[1.4rem] leading-relaxed\">\n                    This database is used only by the AI agent to test your app.<br/>\n                    {!isPending && !isError && mapping && tables.length === 0\n                        ? \"There are no tables in this temporary database yet.\"\n                        : \"You can open the tables below to inspect its test data.\"}\n                </p>\n                {isError ? (\n                    <p className=\"px-2 py-2 text-[1.4rem]\" role=\"status\">\n                        Unable to load the temporary database. It may no longer be available. Close and reopen this\n                        dialog to try again.\n                    </p>\n                ) : isPending ? (\n                    <LoadingSpinner />\n                ) : !mapping ? (\n                    <p className=\"px-2 py-2 text-[1.4rem]\" role=\"status\">\n                        This temporary database is no longer available.\n                    </p>\n                ) : (\n                    <div>\n                        {tables.map((table) => (\n                            <SecondaryNavLink\n                                key={table.id}\n                                className=\"[&>a]:rounded-md!\"\n                                to={getTableNavTarget(mapping, table)}\n                                icon={faTable}\n                                isSelected={selectedTableId === table.id}\n                                hideOverlayOnClick={false}\n                                onClick={closeOnTableClick ? onClose : undefined}>\n                                {table.name || <>&nbsp;</>}\n                            </SecondaryNavLink>\n                        ))}\n                    </div>\n                )}\n            </dialog>\n        </div>\n    );\n};\n","import { htmlTemplateBodyLineOffset } from \"@/controllers/app/html-form-parser.ts\";\nimport type { AppNavTarget } from \"@/router/navTypes.ts\";\nimport type { AppState, CodePath, FormItemYaml, FullView, TableMappingId, ViewMode, ViewValue } from \"@/types\";\n\nconst localCodePathMatcher = /^(forms|modules|server_modules|assets)\\/([^#]+)(#.*)?$/;\nconst dependencyCodePathMatcher = /^(?:deps|\\.anvil\\/deps)\\/[^/]+\\/(?:forms|modules|server_modules|assets)\\/.+$/;\nconst dependencyFilesystemPathMatcher =\n    /(?:^|\\/)(?:deps|\\.anvil\\/deps)\\/[^/]+\\/(?:client_code|server_code|theme)(?:\\/|$)/;\nconst viewModes = new Set<ViewMode>([\"design\", \"code\", \"html\", \"htmlProperty\"]);\n\nconst tableMappingIdFromSchemaRoute = (\n    routeSegment: string | undefined\n): TableMappingId | \"debug\" | undefined => {\n    if (routeSegment === undefined || routeSegment === \"debug\") {\n        return routeSegment;\n    }\n    return routeSegment === \"default\" ? null : Number(routeSegment);\n};\n\nexport const agentMarkdownDestinationPattern =\n    \"(?:forms|modules|server_modules|assets)/[^>\\\\n)\\\\s]+|deps/[^/]+/(?:forms|modules|server_modules|assets)/[^>\\\\n)\\\\s]+|(?:client_code|server_code|theme/assets)/[^>\\\\n)\\\\s]+|db/tables/[^>\\\\n)\\\\s]+|/?db/schema(?:/[^>\\\\n)\\\\s]+)?|users|files|secrets|email-service|google-service|facebook-service|stripe-service|microsoft-service|saml-auth|tableau|scheduled-tasks|(?:app|python|javascript)-dependencies|settings/(?:runtime|dependencies)|native-libraries(?:/default)?\";\n\nconst serviceTargets = {\n    users: { type: \"SERVICE\", service: \"USERS\" },\n    files: { type: \"SERVICE\", service: \"FILES\" },\n    secrets: { type: \"SERVICE\", service: \"SECRETS\" },\n    \"email-service\": { type: \"SERVICE\", service: \"EMAIL\" },\n    \"google-service\": { type: \"SERVICE\", service: \"GOOGLE\" },\n    \"facebook-service\": { type: \"SERVICE\", service: \"FACEBOOK\" },\n    \"stripe-service\": { type: \"SERVICE\", service: \"STRIPE\" },\n    \"microsoft-service\": { type: \"SERVICE\", service: \"MICROSOFT\" },\n    \"saml-auth\": { type: \"SERVICE\", service: \"SAML\" },\n    tableau: { type: \"SERVICE\", service: \"TABLEAU\" },\n} as const satisfies Record<string, AppNavTarget>;\n\n// Logical IDE hrefs are the route-shaped links agents may write explicitly,\n// such as forms/Home#code:4 or db/schema.\nexport const decodeAgentMarkdownHref = (href: string): string => {\n    try {\n        return decodeURIComponent(href);\n    } catch {\n        try {\n            return decodeURI(href);\n        } catch {\n            return href;\n        }\n    }\n};\n\nconst parseAgentMarkdownViewHash = (hash: string | undefined): FullView | undefined => {\n    if (!hash?.startsWith(\"#\")) {\n        return undefined;\n    }\n\n    let view: FullView | undefined;\n    for (const item of hash.slice(1).split(\";\")) {\n        const [viewType, ...viewRest] = item.split(\":\");\n        if (viewType === \"focus\") {\n            const focus = viewRest[0];\n            if (viewModes.has(focus as ViewMode)) {\n                view ??= {};\n                view.focus = focus as ViewMode;\n            }\n            continue;\n        }\n\n        if (!viewModes.has(viewType as ViewMode)) {\n            continue;\n        }\n\n        const mode = viewType as ViewMode;\n        const viewValue: ViewValue =\n            viewRest.length === 0 ? true : viewRest.length === 1 ? [viewRest[0]] : [viewRest[0], viewRest[1]];\n        view ??= {};\n        if (mode === \"html\") {\n            view.design ??= true;\n        }\n        view[mode] = viewValue;\n        if (viewRest.length) {\n            view.focus = mode;\n        }\n    }\n\n    return view;\n};\n\nconst dotPathFromFilesystemPath = (path: string): string => path.split(\"/\").filter(Boolean).join(\".\");\n\n// Filesystem Path Normalization\n\nconst codeView: FullView = { code: true, focus: \"code\" };\nconst designView: FullView = { design: true, focus: \"design\" };\nconst htmlView: FullView = { design: true, html: true, focus: \"html\" };\nconst sourcePathLineSuffixMatcher = /^(.+\\.(?:py|html|ya?ml|css|json|toml|md|txt|js|ts|tsx|jsx)):(\\d+)$/i;\n\nconst formExists = (app: AppState | null | undefined, className: string): boolean =>\n    app?.initialCode.forms?.some((form) => form.class_name === className) ?? false;\n\nconst formForClassName = (app: AppState | null | undefined, className: string): FormItemYaml | undefined =>\n    app?.initialCode.forms?.find((form) => form.class_name === className);\n\nconst normalizeAgentPathReference = (path: string): string => path.replace(/^file:\\/\\//, \"\").replace(/\\\\/g, \"/\");\nconst urlSchemeMatcher = /^[a-z][a-z0-9+.-]*:\\/\\//i;\nconst agentCheckoutPathMatcher = /(?:^|\\/)env\\/[^/]+\\/app\\/(.+)$/;\n\n// App-relative paths are raw checkout paths after the app root, for example\n// anvil.yaml or client_code/Home/__init__.py. App-storage paths are the subset\n// that map onto IDE code tree storage roots: client_code, server_code, theme/assets.\nexport const appRelativePathFromAgentPathReference = (path: string | undefined): string | null => {\n    if (!path) {\n        return null;\n    }\n\n    const normalizedPath = normalizeAgentPathReference(decodeAgentMarkdownHref(path)).replace(/^\\.\\/+/, \"\");\n    const agentCheckoutPath = normalizedPath.match(agentCheckoutPathMatcher)?.[1];\n    if (agentCheckoutPath) {\n        return agentCheckoutPath;\n    }\n\n    if (urlSchemeMatcher.test(normalizedPath)) {\n        return null;\n    }\n\n    if (normalizedPath.startsWith(\"app/\")) {\n        return normalizedPath.slice(\"app/\".length);\n    }\n\n    const appIndex = normalizedPath.lastIndexOf(\"/app/\");\n    return appIndex >= 0 ? normalizedPath.slice(appIndex + \"/app/\".length) : null;\n};\n\nconst displayUnlinkedAppRelativePath = (path: string): string =>\n    path.replace(/\\/__init__\\.py$/, \"\").replace(/^client_code\\/(.+?)\\/form_template\\.html$/, \"client_code/$1\");\n\nconst pythonCodeNameFromStoragePath = (path: string): string | null => {\n    const packageMatch = path.match(/^(.*)\\/__init__\\.py$/);\n    if (packageMatch?.[1]) {\n        return dotPathFromFilesystemPath(packageMatch[1]);\n    }\n\n    const fileMatch = path.match(/^(.*)\\.py$/);\n    return fileMatch?.[1] ? dotPathFromFilesystemPath(fileMatch[1]) : null;\n};\n\nconst stripToAppStoragePath = (path: string): string | null => {\n    const decodedFilePath = normalizeAgentPathReference(path);\n    const appRelativePath = appRelativePathFromAgentPathReference(decodedFilePath);\n    if (appRelativePath) {\n        return stripToAppStoragePath(appRelativePath);\n    }\n\n    if (urlSchemeMatcher.test(decodedFilePath)) {\n        return null;\n    }\n\n    const normalizedPath = decodedFilePath.replace(/^\\.\\/+/, \"\");\n    if (dependencyFilesystemPathMatcher.test(normalizedPath)) {\n        return null;\n    }\n\n    const roots = [\"client_code\", \"server_code\", \"theme/assets\"] as const;\n    let bestMatchIndex = -1;\n    for (const root of roots) {\n        const startMatch = normalizedPath.startsWith(`${root}/`) ? 0 : -1;\n        const innerMatch = normalizedPath.lastIndexOf(`/${root}/`);\n        const index = innerMatch >= 0 ? innerMatch + 1 : startMatch;\n        if (index > bestMatchIndex) {\n            bestMatchIndex = index;\n        }\n    }\n\n    return bestMatchIndex >= 0 ? normalizedPath.slice(bestMatchIndex) : null;\n};\n\nconst splitSourcePathLineSuffix = (path: string): { path: string; line?: string } => {\n    const lineMatch = path.match(sourcePathLineSuffixMatcher);\n    return lineMatch?.[1] && lineMatch[2] ? { path: lineMatch[1], line: lineMatch[2] } : { path };\n};\n\nconst codeViewForLine = (line: string | undefined): FullView => (line ? { code: [line], focus: \"code\" } : codeView);\nconst htmlViewForLine = (line: string | undefined): FullView =>\n    line ? { design: true, html: [line], focus: \"html\" } : htmlView;\nconst designViewForLine = (line: string | undefined): FullView =>\n    line ? { design: [line], focus: \"design\" } : designView;\n\nconst htmlBodyLineForSourceLine = (\n    sourceLine: string | undefined,\n    app: AppState | null | undefined,\n    className: string\n): string | undefined => {\n    if (!sourceLine) {\n        return undefined;\n    }\n\n    const form = formForClassName(app, className);\n    if (!form) {\n        return undefined;\n    }\n\n    const offset = htmlTemplateBodyLineOffset(form);\n    if (offset === null) {\n        return undefined;\n    }\n\n    const bodyLine = Number.parseInt(sourceLine, 10) - offset;\n    return bodyLine >= 1 ? String(bodyLine) : undefined;\n};\n\n// Test files are extra files under tests/, which the IDE opens at tests/<path>.\n// Captures the file path (with an optional :line suffix) and an optional view hash. Directories don't match.\nconst testFileReferenceMatcher = /^(tests\\/(?:[^#]*\\/)?[^/#]+\\.[^/#]+)(#.*)?$/;\n\nconst testFileNavTargetFromAgentPathReference = (path: string): AppNavTarget | null => {\n    const normalizedPath = normalizeAgentPathReference(path).replace(/^\\.\\/+/, \"\");\n    const match = (appRelativePathFromAgentPathReference(normalizedPath) ?? normalizedPath).match(\n        testFileReferenceMatcher\n    );\n    if (!match?.[1]) {\n        return null;\n    }\n\n    const { path: filePath, line } = splitSourcePathLineSuffix(match[1]);\n    const view = parseAgentMarkdownViewHash(match[2]) ?? (line ? codeViewForLine(line) : undefined);\n    const target: AppNavTarget = { type: \"EXTRA_FILE\", filePath };\n    if (view) {\n        target.view = view;\n    }\n    return target;\n};\n\n// IDE Target Resolution\n\n/** Convert an agent-visible checkout/app-storage path into an IDE navigation target. */\nexport const navTargetFromAgentPathReference = (\n    path: string | undefined,\n    app?: AppState | null\n): AppNavTarget | null => {\n    if (!path) {\n        return null;\n    }\n\n    const decodedPath = decodeAgentMarkdownHref(path);\n    const testFileTarget = testFileNavTargetFromAgentPathReference(decodedPath);\n    if (testFileTarget) {\n        return testFileTarget;\n    }\n    const appStoragePathReference = stripToAppStoragePath(decodedPath);\n    if (!appStoragePathReference) {\n        return null;\n    }\n    const { path: appStoragePath, line } = splitSourcePathLineSuffix(appStoragePathReference);\n\n    const clientPath = appStoragePath.match(/^client_code\\/(.+)$/)?.[1];\n    if (clientPath) {\n        const htmlTemplateMatch = clientPath.match(/^(.*?)(?:\\/form_template|)\\.html$/);\n        if (htmlTemplateMatch?.[1]) {\n            const className = dotPathFromFilesystemPath(htmlTemplateMatch[1]);\n            return {\n                type: \"CODE\",\n                codePath: `forms/${className}` as CodePath,\n                view: htmlViewForLine(htmlBodyLineForSourceLine(line, app, className)),\n            };\n        }\n\n        const yamlTemplateMatch = clientPath.match(/^(.*?)(?:\\/form_template|)\\.ya?ml$/);\n        if (yamlTemplateMatch?.[1]) {\n            return {\n                type: \"CODE\",\n                codePath: `forms/${dotPathFromFilesystemPath(yamlTemplateMatch[1])}` as CodePath,\n                view: designViewForLine(line),\n            };\n        }\n\n        const codeName = pythonCodeNameFromStoragePath(clientPath);\n        if (codeName) {\n            return {\n                type: \"CODE\",\n                codePath: `${formExists(app, codeName) ? \"forms\" : \"modules\"}/${codeName}` as CodePath,\n                view: codeViewForLine(line),\n            };\n        }\n    }\n\n    const serverPath = appStoragePath.match(/^server_code\\/(.+)$/)?.[1];\n    if (serverPath) {\n        const codeName = pythonCodeNameFromStoragePath(serverPath);\n        if (codeName) {\n            return {\n                type: \"CODE\",\n                codePath: `server_modules/${codeName}` as CodePath,\n                view: codeViewForLine(line),\n            };\n        }\n    }\n\n    const assetPath = appStoragePath.match(/^theme\\/assets\\/(.+)$/)?.[1];\n    if (assetPath) {\n        const target: AppNavTarget = { type: \"CODE\", codePath: `assets/${assetPath}` as CodePath };\n        if (line) {\n            target.view = codeViewForLine(line);\n        }\n        return target;\n    }\n\n    return null;\n};\n\n/** Resolve either a filesystem path reference or an explicit logical IDE href. */\nexport const navTargetFromAgentMarkdownHref = (\n    href: string | undefined,\n    app?: AppState | null\n): AppNavTarget | null => {\n    if (!href) {\n        return null;\n    }\n\n    const decodedHref = decodeAgentMarkdownHref(href);\n    const pathTarget = navTargetFromAgentPathReference(decodedHref, app);\n    if (pathTarget) {\n        return pathTarget;\n    }\n\n    const localCodePathMatch = decodedHref.match(localCodePathMatcher);\n    if (localCodePathMatch) {\n        const [, codePathType, codePathName, hash] = localCodePathMatch;\n        const target: AppNavTarget = { type: \"CODE\", codePath: `${codePathType}/${codePathName}` as CodePath };\n        const view = parseAgentMarkdownViewHash(hash);\n        if (view) {\n            target.view = view;\n        }\n        return target;\n    }\n    const schemaRoute = decodedHref.match(/^\\/?db\\/schema(?:\\/(.+))?$/);\n    if (schemaRoute) {\n        return { type: \"APP_SCHEMA\", tableMappingId: tableMappingIdFromSchemaRoute(schemaRoute[1]) };\n    }\n    if (decodedHref === \"scheduled-tasks\") {\n        return { type: \"SCHEDULED_TASKS\" };\n    }\n    switch (decodedHref) {\n        case \"app-dependencies\":\n        case \"settings/dependencies\":\n            return { type: \"APP_DEPENDENCIES\" };\n        case \"python-dependencies\":\n        case \"settings/runtime\":\n            return { type: \"PYTHON_DEPENDENCIES\" };\n        case \"javascript-dependencies\":\n        case \"native-libraries\":\n        case \"native-libraries/default\":\n            return { type: \"JAVASCRIPT_DEPENDENCIES\" };\n    }\n    const dataTableName = decodedHref.match(/^db\\/tables\\/([^/]+)$/)?.[1];\n    if (dataTableName) {\n        const defaultMapping = app?.tableMappings.find(({ table_mapping_id }) => table_mapping_id === null);\n        const table = defaultMapping?.tables.find(({ python_name }) => python_name === dataTableName);\n        if (table) {\n            return { type: \"DB_TABLE\", tableMappingId: null, tableId: table.id };\n        }\n    }\n    return serviceTargets[decodedHref as keyof typeof serviceTargets] ?? null;\n};\n\n// Labels And Non-Navigable File References\n\nexport const labelForAgentNavTarget = (navTarget: AppNavTarget): string | null => {\n    switch (navTarget.type) {\n        case \"CODE\": {\n            const [codePathType, ...codeNameParts] = navTarget.codePath.split(\"/\");\n            const codeName = codeNameParts.join(\"/\");\n            if (codePathType === \"forms\") {\n                if (navTarget.view?.code) {\n                    return `${codeName} (form code)`;\n                }\n                if (navTarget.view?.html) {\n                    return `${codeName} (form HTML)`;\n                }\n                if (navTarget.view?.design) {\n                    return `${codeName} (form design)`;\n                }\n                return `${codeName} (form)`;\n            }\n            if (codePathType === \"modules\") {\n                return `${codeName} (module)`;\n            }\n            if (codePathType === \"server_modules\") {\n                return `${codeName} (server module)`;\n            }\n            if (codePathType === \"assets\") {\n                return codeName;\n            }\n            return navTarget.codePath;\n        }\n        case \"APP_SCHEMA\":\n            return navTarget.tableMappingId === undefined\n                ? \"db/schema\"\n                : `db/schema/${navTarget.tableMappingId ?? \"default\"}`;\n        case \"SERVICE\":\n            return navTarget.service.toLowerCase().replace(\"_\", \"-\");\n        case \"EXTRA_FILE\":\n            return navTarget.filePath;\n        default:\n            return null;\n    }\n};\n\nexport const isDependencyCodePath = (href: string | undefined): boolean =>\n    !!href &&\n    (dependencyCodePathMatcher.test(decodeAgentMarkdownHref(href)) ||\n        dependencyFilesystemPathMatcher.test(decodeAgentMarkdownHref(href).replace(/\\\\/g, \"/\")));\n\nconst filesystemRootMatcher = /^(?:\\.\\/)?(?:client_code|server_code|theme|\\.anvil)(?:\\/|$)/;\nconst anvilYamlMatcher = /^anvil\\.yaml(?::\\d+)?(?:#|$)/;\nconst sourceFileExtensionMatcher = /\\.(?:py|html|yaml|yml|css|json|toml|md|txt|js|ts|tsx|jsx)(?::\\d+)?(?:#|$)/i;\n\n/** Filesystem paths the IDE cannot navigate to. Agents should not emit these as links. */\nexport const isAgentFilePathLink = (href: string | undefined, app?: AppState | null): boolean => {\n    if (!href) {\n        return false;\n    }\n\n    const decodedHref = decodeAgentMarkdownHref(href);\n    if (navTargetFromAgentMarkdownHref(decodedHref, app) || isDependencyCodePath(decodedHref)) {\n        return false;\n    }\n    const appRelativePath = appRelativePathFromAgentPathReference(decodedHref);\n    if (urlSchemeMatcher.test(decodedHref) && !appRelativePath) {\n        return false;\n    }\n\n    return (\n        filesystemRootMatcher.test(decodedHref) ||\n        appRelativePath !== null ||\n        stripToAppStoragePath(decodedHref) !== null ||\n        anvilYamlMatcher.test(decodedHref) ||\n        sourceFileExtensionMatcher.test(decodedHref)\n    );\n};\n\nconst pathReferenceMatcher = /(?:\\.\\/|\\/|~\\/)?[^\\s`<>\"']*(?:client_code|server_code|theme\\/assets)\\/[^\\s`<>\"']+/g;\nconst unlinkedAppPathMatcher = /(?:file:\\/\\/)?(?:\\.\\/|\\/|~\\/)?[^\\s`<>\"']*\\/app\\/[^\\s`<>\"']+|app\\/[^\\s`<>\"']+/g;\nconst trailingPunctuationMatcher = /[),.;:!?]+$/;\nconst quoteCharacters = new Set([\"'\", '\"']);\n\n// Text Linkification\n\nconst splitPathReference = (\n    candidate: string,\n    app: AppState | null | undefined\n): { linkText: string; trailingText: string } | null => {\n    let linkText = candidate;\n    let trailingText = \"\";\n    while (linkText) {\n        if (navTargetFromAgentPathReference(linkText, app) || isDependencyCodePath(linkText)) {\n            return { linkText, trailingText };\n        }\n        const trailingMatch = linkText.match(trailingPunctuationMatcher);\n        if (!trailingMatch?.[0]) {\n            return null;\n        }\n        linkText = linkText.slice(0, -trailingMatch[0].length);\n        trailingText = trailingMatch[0] + trailingText;\n    }\n    return null;\n};\n\nexport type AgentPathReferenceTextSegment =\n    | { type: \"text\"; value: string }\n    | { type: \"path\"; value: string; label: string };\n\nexport const displayPathFromAgentPathReference = (path: string | undefined): string | null => {\n    const appRelativePath = appRelativePathFromAgentPathReference(path);\n    if (appRelativePath) {\n        return appRelativePath;\n    }\n    return path ? (stripToAppStoragePath(decodeAgentMarkdownHref(path)) ?? null) : null;\n};\n\nexport const labelForAgentFilePathReference = (path: string | undefined, app?: AppState | null): string | null => {\n    if (!path) {\n        return null;\n    }\n\n    const navTarget = navTargetFromAgentPathReference(path, app);\n    if (navTarget) {\n        return labelForAgentNavTarget(navTarget) ?? displayPathFromAgentPathReference(path) ?? path;\n    }\n\n    return displayPathFromAgentPathReference(path) ?? path;\n};\n\nconst navTargetFromInlineCodeReference = (value: string, app?: AppState | null): AppNavTarget | null => {\n    const pathTarget = navTargetFromAgentPathReference(value, app);\n    if (pathTarget) {\n        return pathTarget;\n    }\n\n    return localCodePathMatcher.test(decodeAgentMarkdownHref(value))\n        ? navTargetFromAgentMarkdownHref(value, app)\n        : null;\n};\n\nexport const titleForAgentPathReference = (path: string | undefined): string | undefined =>\n    path\n        ? (appRelativePathFromAgentPathReference(path) ?? stripToAppStoragePath(decodeAgentMarkdownHref(path)) ?? path)\n        : undefined;\n\n// Shared by prose auto-linking and tool-call rows: split a string into text\n// and navigable app path references, while shortening quoted non-navigable\n// checkout paths such as '/env/.../app/README.md'.\nconst appendTextSegments = (segments: AgentPathReferenceTextSegment[], value: string) => {\n    let lastIndex = 0;\n    unlinkedAppPathMatcher.lastIndex = 0;\n\n    for (const match of value.matchAll(unlinkedAppPathMatcher)) {\n        const candidate = match[0];\n        const appRelativePath = appRelativePathFromAgentPathReference(candidate);\n        if (!appRelativePath) {\n            continue;\n        }\n\n        const start = match.index!;\n        const end = start + candidate.length;\n        const quote = value[start - 1];\n        const isQuoted = quoteCharacters.has(quote) && value[end] === quote;\n        const prefixEnd = isQuoted ? start - 1 : start;\n        if (prefixEnd > lastIndex) {\n            segments.push({ type: \"text\", value: value.slice(lastIndex, prefixEnd) });\n        }\n        segments.push({ type: \"text\", value: displayUnlinkedAppRelativePath(appRelativePath) });\n        lastIndex = end + (isQuoted ? 1 : 0);\n    }\n\n    if (lastIndex === 0) {\n        if (value) {\n            segments.push({ type: \"text\", value });\n        }\n        return;\n    }\n    if (lastIndex < value.length) {\n        segments.push({ type: \"text\", value: value.slice(lastIndex) });\n    }\n};\n\nexport const splitAgentPathReferenceText = (value: string, app?: AppState | null): AgentPathReferenceTextSegment[] => {\n    const segments: AgentPathReferenceTextSegment[] = [];\n    let lastIndex = 0;\n    pathReferenceMatcher.lastIndex = 0;\n\n    for (const match of value.matchAll(pathReferenceMatcher)) {\n        const candidate = match[0];\n        const split = splitPathReference(candidate, app);\n        if (!split) {\n            continue;\n        }\n\n        const start = match.index!;\n        const end = start + candidate.length;\n        const quote = value[start - 1];\n        const isQuoted = quoteCharacters.has(quote) && value[end] === quote;\n        const prefixEnd = isQuoted ? start - 1 : start;\n        if (prefixEnd > lastIndex) {\n            appendTextSegments(segments, value.slice(lastIndex, prefixEnd));\n        }\n        const navTarget = navTargetFromAgentPathReference(split.linkText, app);\n        segments.push({\n            type: \"path\",\n            value: split.linkText,\n            label: navTarget ? (labelForAgentNavTarget(navTarget) ?? split.linkText) : split.linkText,\n        });\n        if (split.trailingText) {\n            segments.push({ type: \"text\", value: split.trailingText });\n        }\n        lastIndex = end + (isQuoted ? 1 : 0);\n    }\n\n    if (lastIndex === 0) {\n        appendTextSegments(segments, value);\n        return segments.length ? segments : [{ type: \"text\", value }];\n    }\n    if (lastIndex < value.length) {\n        appendTextSegments(segments, value.slice(lastIndex));\n    }\n    return segments;\n};\n\nconst linkifyTextValue = (value: string, app: AppState | null | undefined, inlineCode = false): any[] => {\n    if (inlineCode) {\n        if (/\\s/.test(value)) {\n            return [{ type: \"inlineCode\", value }];\n        }\n        const navTarget = navTargetFromInlineCodeReference(value, app);\n        if (navTarget) {\n            return [\n                {\n                    type: \"link\",\n                    url: value,\n                    title: titleForAgentPathReference(value),\n                    children: [{ type: \"inlineCode\", value: labelForAgentNavTarget(navTarget) ?? value }],\n                },\n            ];\n        }\n        const displayPath = displayPathFromAgentPathReference(value);\n        if (displayPath && isAgentFilePathLink(value, app)) {\n            return [{ type: \"inlineCode\", value: displayPath }];\n        }\n        return [{ type: \"inlineCode\", value }];\n    }\n\n    const segments = splitAgentPathReferenceText(value, app);\n\n    const nodes = segments.map((segment) =>\n        segment.type === \"text\"\n            ? { type: \"text\", value: segment.value }\n            : {\n                  type: \"link\",\n                  url: segment.value,\n                  title: titleForAgentPathReference(segment.value),\n                  children: [{ type: \"text\", value: segment.label }],\n              }\n    );\n    return nodes;\n};\n\nexport const linkifyAgentPathReferences = (tree: any, app?: AppState | null) => {\n    const visit = (node: any) => {\n        if (!node?.children) {\n            return;\n        }\n\n        node.children = node.children.flatMap((child: any) => {\n            if (child.type === \"link\" || child.type === \"code\") {\n                return [child];\n            }\n            if (child.type === \"text\" && typeof child.value === \"string\") {\n                return linkifyTextValue(child.value, app);\n            }\n            if (child.type === \"inlineCode\" && typeof child.value === \"string\") {\n                return linkifyTextValue(child.value, app, true);\n            }\n            visit(child);\n            return [child];\n        });\n    };\n\n    visit(tree);\n};\n\nexport const agentPathReferenceLinks = (app?: AppState | null) => () => (tree: any) =>\n    linkifyAgentPathReferences(tree, app);\n","import { ConversationSearchMatchForTurn } from \"./conversationSearchIndex.ts\";\n\nexport interface SearchHighlight {\n    left: number;\n    top: number;\n    width: number;\n    height: number;\n    matchIndex: number;\n    occurrenceIndex: number;\n    scopeKind: string;\n    sourceText: string;\n    turnIndex: number;\n}\n\ninterface TurnSearchOccurrence {\n    occurrenceIndex: number;\n    parentElement: HTMLElement;\n    range: Range;\n    scopeKind: string;\n    sourceText: string;\n}\n\nconst SEARCH_REVEAL_PADDING = 24;\nconst SCROLLABLE_OVERFLOW_RE = /^(auto|hidden|scroll)$/;\nconst USER_SCROLLABLE_OVERFLOW_RE = /^(auto|scroll)$/;\nconst CONVERSATION_SEARCH_PANEL_SELECTOR = \"[data-conversation-search-panel='true']\";\n\nconst TEXT_NODE_FILTER: NodeFilter = {\n    acceptNode: (node: Node) => {\n        const parent = node.parentNode;\n        if (!parent || /^(script|style)$/i.test(parent.nodeName)) {\n            return NodeFilter.FILTER_REJECT;\n        }\n        return NodeFilter.FILTER_ACCEPT;\n    },\n};\n\nconst highlightFromRangeRect = (\n    rangeRect: DOMRect,\n    turnRect: DOMRect,\n    clipElement: Element,\n    boundaryElement: Element,\n    matchIndex: number,\n    turnIndex: number,\n    occurrenceIndex: number,\n    scopeKind: string,\n    sourceText: string\n): SearchHighlight | null => {\n    let visibleLeft = rangeRect.left;\n    let visibleTop = rangeRect.top;\n    let visibleRight = rangeRect.right;\n    let visibleBottom = rangeRect.bottom;\n\n    for (let el: Element | null = clipElement; el; el = el.parentElement) {\n        const style = getComputedStyle(el);\n        const clips = [style.overflow, style.overflowX, style.overflowY].some((overflow) =>\n            SCROLLABLE_OVERFLOW_RE.test(overflow)\n        );\n        if (clips) {\n            const rect = el.getBoundingClientRect();\n            visibleLeft = Math.max(visibleLeft, rect.left);\n            visibleTop = Math.max(visibleTop, rect.top);\n            visibleRight = Math.min(visibleRight, rect.right);\n            visibleBottom = Math.min(visibleBottom, rect.bottom);\n        }\n        if (el === boundaryElement) {\n            break;\n        }\n    }\n\n    if (visibleLeft >= visibleRight || visibleTop >= visibleBottom) {\n        return null;\n    }\n\n    return {\n        left: visibleLeft - turnRect.left,\n        top: visibleTop - turnRect.top,\n        width: visibleRight - visibleLeft,\n        height: visibleBottom - visibleTop,\n        matchIndex,\n        occurrenceIndex,\n        scopeKind,\n        sourceText,\n        turnIndex,\n    };\n};\n\nconst isNestedScrollableElement = (element: HTMLElement) => {\n    const style = getComputedStyle(element);\n    const canScrollX = USER_SCROLLABLE_OVERFLOW_RE.test(style.overflowX) && element.scrollWidth > element.clientWidth;\n    const canScrollY = USER_SCROLLABLE_OVERFLOW_RE.test(style.overflowY) && element.scrollHeight > element.clientHeight;\n    return canScrollX || canScrollY;\n};\n\nconst isHorizontalScrollableElement = (element: HTMLElement) => {\n    const style = getComputedStyle(element);\n    return USER_SCROLLABLE_OVERFLOW_RE.test(style.overflowX) && element.scrollWidth > element.clientWidth;\n};\n\nconst isVerticalScrollableElement = (element: HTMLElement) => {\n    const style = getComputedStyle(element);\n    return USER_SCROLLABLE_OVERFLOW_RE.test(style.overflowY) && element.scrollHeight > element.clientHeight;\n};\n\nexport const nestedScrollableElements = (turnElement: HTMLElement) =>\n    Array.from(turnElement.querySelectorAll<HTMLElement>(\"*\")).filter(isNestedScrollableElement);\n\nconst nearestHorizontalScrollableAncestor = (element: HTMLElement, boundaryElement: HTMLElement) => {\n    for (let el: HTMLElement | null = element; el; el = el.parentElement) {\n        if (isHorizontalScrollableElement(el)) {\n            return el;\n        }\n        if (el === boundaryElement) {\n            break;\n        }\n    }\n    return null;\n};\n\nconst nearestVerticalScrollableAncestor = (element: HTMLElement) => {\n    for (let el: HTMLElement | null = element; el; el = el.parentElement) {\n        if (isVerticalScrollableElement(el)) {\n            return el;\n        }\n        if (el === el.ownerDocument.body || el === el.ownerDocument.documentElement) {\n            break;\n        }\n    }\n    return null;\n};\n\nconst occludedScrollTop = (scrollElement: HTMLElement, scrollRect: DOMRect) => {\n    let top = scrollRect.top;\n    for (const panel of scrollElement.ownerDocument.querySelectorAll<HTMLElement>(CONVERSATION_SEARCH_PANEL_SELECTOR)) {\n        const panelRect = panel.getBoundingClientRect();\n        const overlapsScrollElement =\n            panelRect.bottom > scrollRect.top &&\n            panelRect.top < scrollRect.bottom &&\n            panelRect.right > scrollRect.left &&\n            panelRect.left < scrollRect.right;\n        if (overlapsScrollElement) {\n            top = Math.max(top, panelRect.bottom);\n        }\n    }\n    return top;\n};\n\nconst revealRangeVertically = (\n    range: Range,\n    element: HTMLElement,\n    virtualScrollerElement: HTMLElement | null,\n    scrollVirtualizerByDelta: (delta: number) => void\n) => {\n    const scrollElement = nearestVerticalScrollableAncestor(element);\n    if (!scrollElement) {\n        return false;\n    }\n\n    const rangeRect = range.getBoundingClientRect();\n    const scrollRect = scrollElement.getBoundingClientRect();\n    const revealPadding = Math.min(SEARCH_REVEAL_PADDING, scrollRect.height / 4);\n    const visibleTop = occludedScrollTop(scrollElement, scrollRect);\n    const revealTop = visibleTop + revealPadding;\n    const revealBottom = scrollRect.bottom - revealPadding;\n    const revealCenter = revealTop + (revealBottom - revealTop) / 2;\n    const rangeCenter = rangeRect.top + rangeRect.height / 2;\n    let scrollDelta = 0;\n    if (rangeRect.top < revealTop) {\n        scrollDelta = rangeCenter - revealCenter;\n    } else if (rangeRect.bottom > revealBottom) {\n        scrollDelta = rangeCenter - revealCenter;\n    }\n    if (scrollDelta !== 0) {\n        if (scrollElement === virtualScrollerElement) {\n            scrollVirtualizerByDelta(scrollDelta);\n        } else {\n            scrollElement.scrollTop += scrollDelta;\n        }\n    }\n    return scrollDelta !== 0;\n};\n\nconst forEachTurnSearchOccurrence = (\n    turnElement: HTMLElement,\n    searchTerm: string,\n    onOccurrence: (occurrence: TurnSearchOccurrence) => boolean | void\n) => {\n    const normalizedSearchTerm = searchTerm.trim().toLocaleLowerCase();\n    if (!normalizedSearchTerm) {\n        return;\n    }\n\n    const range = document.createRange();\n    let occurrenceIndex = 0;\n    try {\n        const searchScopes = turnElement.querySelectorAll<HTMLElement>(\"[data-conversation-search-scope='true']\");\n        for (const searchScope of searchScopes) {\n            const walker = document.createTreeWalker(searchScope, NodeFilter.SHOW_TEXT, TEXT_NODE_FILTER);\n            let currentNode: Node | null;\n            while ((currentNode = walker.nextNode())) {\n                if (currentNode.nodeType !== Node.TEXT_NODE || !currentNode.textContent?.trim()) {\n                    continue;\n                }\n\n                const text = currentNode.textContent;\n                const normalizedText = text.toLocaleLowerCase();\n                let startPos = 0;\n                let index: number;\n                while ((index = normalizedText.indexOf(normalizedSearchTerm, startPos)) !== -1) {\n                    const parentElement = currentNode.parentElement;\n                    if (parentElement) {\n                        range.setStart(currentNode, index);\n                        range.setEnd(currentNode, index + searchTerm.trim().length);\n                        const shouldContinue = onOccurrence({\n                            occurrenceIndex,\n                            parentElement,\n                            range,\n                            scopeKind: searchScope.dataset.conversationSearchScopeKind ?? \"unknown\",\n                            sourceText: text.trim().slice(0, 140),\n                        });\n                        if (shouldContinue === false) {\n                            return;\n                        }\n                    }\n\n                    occurrenceIndex++;\n                    startPos = index + normalizedSearchTerm.length;\n                }\n            }\n        }\n    } finally {\n        range.detach();\n    }\n};\n\nexport const collectTurnHighlights = (\n    turnElement: HTMLElement,\n    searchTerm: string,\n    matches: ConversationSearchMatchForTurn[]\n) => {\n    const normalizedSearchTerm = searchTerm.trim().toLocaleLowerCase();\n    if (!normalizedSearchTerm || matches.length === 0) {\n        return [];\n    }\n\n    const turnIndex = Number(turnElement.dataset.conversationTurnIndex);\n    if (!Number.isFinite(turnIndex)) {\n        return [];\n    }\n\n    const turnRect = turnElement.getBoundingClientRect();\n    const visibleHighlights: SearchHighlight[] = [];\n    const visibleMatchIndexes = new Map<string, number[]>();\n\n    matches.forEach((match) => {\n        const key = `${match.turnIndex}:${match.occurrenceIndex}`;\n        const indexes = visibleMatchIndexes.get(key);\n        if (indexes) {\n            indexes.push(match.matchIndex);\n        } else {\n            visibleMatchIndexes.set(key, [match.matchIndex]);\n        }\n    });\n\n    forEachTurnSearchOccurrence(turnElement, searchTerm, (occurrence) => {\n        const matchIndexes = visibleMatchIndexes.get(`${turnIndex}:${occurrence.occurrenceIndex}`);\n        const matchIndex = matchIndexes?.shift();\n        if (matchIndex === undefined) {\n            return;\n        }\n\n        for (const rangeRect of occurrence.range.getClientRects()) {\n            const highlight = highlightFromRangeRect(\n                rangeRect,\n                turnRect,\n                occurrence.parentElement,\n                turnElement,\n                matchIndex,\n                turnIndex,\n                occurrence.occurrenceIndex,\n                occurrence.scopeKind,\n                occurrence.sourceText\n            );\n            if (highlight) {\n                visibleHighlights.push(highlight);\n            }\n        }\n    });\n\n    return visibleHighlights.sort((a, b) => a.matchIndex - b.matchIndex);\n};\n\nexport const revealActiveMatch = (\n    turnElement: HTMLElement,\n    searchTerm: string,\n    matches: ConversationSearchMatchForTurn[],\n    currentMatchIndex: number,\n    virtualScrollerElement: HTMLElement | null,\n    scrollVirtualizerByDelta: (delta: number) => void\n) => {\n    const activeMatch = matches.find((match) => match.matchIndex === currentMatchIndex);\n    if (!activeMatch || !searchTerm.trim()) {\n        return false;\n    }\n\n    let didScroll = false;\n    forEachTurnSearchOccurrence(turnElement, searchTerm, (occurrence) => {\n        if (occurrence.occurrenceIndex !== activeMatch.occurrenceIndex) {\n            return;\n        }\n\n        const scrollElement = nearestHorizontalScrollableAncestor(occurrence.parentElement, turnElement);\n        if (!scrollElement) {\n            didScroll = revealRangeVertically(\n                occurrence.range,\n                occurrence.parentElement,\n                virtualScrollerElement,\n                scrollVirtualizerByDelta\n            );\n            return false;\n        }\n\n        const rangeRect = occurrence.range.getBoundingClientRect();\n        const scrollRect = scrollElement.getBoundingClientRect();\n        const revealPadding = Math.min(SEARCH_REVEAL_PADDING, scrollRect.width / 4);\n        if (rangeRect.left < scrollRect.left + revealPadding) {\n            scrollElement.scrollLeft -= scrollRect.left + revealPadding - rangeRect.left;\n            didScroll = true;\n        } else if (rangeRect.right > scrollRect.right - revealPadding) {\n            scrollElement.scrollLeft += rangeRect.right - (scrollRect.right - revealPadding);\n            didScroll = true;\n        }\n        didScroll =\n            revealRangeVertically(\n                occurrence.range,\n                occurrence.parentElement,\n                virtualScrollerElement,\n                scrollVirtualizerByDelta\n            ) || didScroll;\n        return false;\n    });\n\n    return didScroll;\n};\n","import React, { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { faAngleDown, faAngleUp, faTimes } from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Button } from \"@/components/reusable/Button.tsx\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal.tsx\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents.tsx\";\nimport useEvent from \"@/util/useEventCallback.ts\";\nimport {\n    SearchHighlight,\n    collectTurnHighlights,\n    nestedScrollableElements,\n    revealActiveMatch,\n} from \"./conversationSearchDom.ts\";\nimport type { ConversationSearchMatchForTurn, ConversationSearchState } from \"./conversationSearchIndex.ts\";\nimport { type ConversationSearchController } from \"./useConversationSearch.ts\";\n\nexport type {\n    ConversationSearchMatch,\n    ConversationSearchMatchForTurn,\n    ConversationSearchState,\n} from \"./conversationSearchIndex.ts\";\n\ninterface ConversationSearchProps {\n    search: ConversationSearchController;\n}\n\nconst MAX_REVEAL_SETTLE_ATTEMPTS = 8;\n\nexport const ConversationTurnSearchHighlights = ({\n    currentMatchIndex,\n    matches,\n    searchTerm,\n    scrollVirtualizerByDelta,\n    totalMatchCount,\n    turnRef,\n    virtualScrollerElement,\n}: {\n    currentMatchIndex: number;\n    matches: ConversationSearchMatchForTurn[];\n    searchTerm: string;\n    scrollVirtualizerByDelta: (delta: number) => void;\n    totalMatchCount: number;\n    turnRef: React.RefObject<HTMLDivElement | null>;\n    virtualScrollerElement: HTMLElement | null;\n}) => {\n    const [highlights, setHighlights] = useState<SearchHighlight[]>([]);\n    const trimmedSearchTerm = searchTerm.trim();\n\n    const updateHighlights = useEvent(() => {\n        const turnElement = turnRef.current;\n        if (!turnElement || !trimmedSearchTerm) {\n            setHighlights([]);\n            return;\n        }\n        setHighlights(collectTurnHighlights(turnElement, trimmedSearchTerm, matches));\n    });\n\n    useLayoutEffect(() => {\n        updateHighlights();\n    }, [matches, trimmedSearchTerm, updateHighlights]);\n\n    useEffect(() => {\n        if (!trimmedSearchTerm || matches.length === 0) {\n            return;\n        }\n\n        let animationFrame: number | null = null;\n        const settleReveal = (attempt: number) => {\n            animationFrame = requestAnimationFrame(() => {\n                const turnElement = turnRef.current;\n                if (!turnElement) {\n                    return;\n                }\n\n                const didScroll = revealActiveMatch(\n                    turnElement,\n                    trimmedSearchTerm,\n                    matches,\n                    currentMatchIndex,\n                    virtualScrollerElement,\n                    scrollVirtualizerByDelta\n                );\n                updateHighlights();\n                if (didScroll && attempt < MAX_REVEAL_SETTLE_ATTEMPTS) {\n                    settleReveal(attempt + 1);\n                }\n            });\n        };\n\n        settleReveal(1);\n\n        return () => {\n            if (animationFrame !== null) {\n                cancelAnimationFrame(animationFrame);\n            }\n        };\n    }, [\n        currentMatchIndex,\n        matches,\n        scrollVirtualizerByDelta,\n        trimmedSearchTerm,\n        turnRef,\n        updateHighlights,\n        virtualScrollerElement,\n    ]);\n\n    useEffect(() => {\n        const turnElement = turnRef.current;\n        if (!turnElement) {\n            return;\n        }\n        let animationFrame: number | null = null;\n        const scheduleHighlightUpdate = () => {\n            if (animationFrame !== null) {\n                cancelAnimationFrame(animationFrame);\n            }\n            animationFrame = requestAnimationFrame(updateHighlights);\n        };\n        const resizeObserver = new ResizeObserver(scheduleHighlightUpdate);\n        const scrollableElements = nestedScrollableElements(turnElement);\n\n        resizeObserver.observe(turnElement);\n        for (const scrollableElement of scrollableElements) {\n            scrollableElement.addEventListener(\"scroll\", scheduleHighlightUpdate, { passive: true });\n        }\n        return () => {\n            if (animationFrame !== null) {\n                cancelAnimationFrame(animationFrame);\n            }\n            for (const scrollableElement of scrollableElements) {\n                scrollableElement.removeEventListener(\"scroll\", scheduleHighlightUpdate);\n            }\n            resizeObserver.disconnect();\n        };\n    }, [matches, trimmedSearchTerm, turnRef, updateHighlights]);\n\n    if (!trimmedSearchTerm || matches.length === 0) {\n        return null;\n    }\n\n    return (\n        <div className=\"pointer-events-none absolute inset-0 z-1\">\n            {highlights.map((highlight) => {\n                const isCurrent = highlight.matchIndex === currentMatchIndex;\n                return (\n                    <mark\n                        key={`${highlight.matchIndex}:${highlight.left}:${highlight.top}`}\n                        className={isCurrent ? \"absolute bg-[#ff00ff8a]\" : \"absolute bg-[#00ffff8a]\"}\n                        data-conversation-search-highlight=\"true\"\n                        data-conversation-search-current={isCurrent ? \"true\" : \"false\"}\n                        data-conversation-search-match-index={highlight.matchIndex}\n                        data-conversation-search-turn-index={highlight.turnIndex}\n                        data-conversation-search-occurrence-index={highlight.occurrenceIndex}\n                        data-conversation-search-scope-kind={highlight.scopeKind}\n                        data-conversation-search-term={trimmedSearchTerm}\n                        data-conversation-search-rect={`${Math.round(highlight.left)},${Math.round(highlight.top)},${Math.round(highlight.width)},${Math.round(highlight.height)}`}\n                        data-conversation-search-source-text={highlight.sourceText}\n                        title={`Conversation search match ${highlight.matchIndex + 1} of ${totalMatchCount}, ${highlight.scopeKind}, turn ${highlight.turnIndex}, occurrence ${highlight.occurrenceIndex}: ${highlight.sourceText}`}\n                        style={{\n                            left: `${highlight.left}px`,\n                            top: `${highlight.top}px`,\n                            width: `${highlight.width}px`,\n                            height: `${highlight.height}px`,\n                        }}\n                    />\n                );\n            })}\n        </div>\n    );\n};\n\nexport const ConversationSearch = ({ search }: ConversationSearchProps) => {\n    const {\n        actions,\n        state: { currentMatchIndex, isOpen, matches, searchTerm },\n    } = search;\n    const inputRef = useRef<HTMLInputElement>(null);\n\n    useEffect(() => {\n        if (isOpen) {\n            inputRef.current?.select();\n        }\n    }, [isOpen]);\n\n    const closeSearch = useEvent(() => {\n        actions.close();\n    });\n\n    const resetSearch = useEvent(() => {\n        actions.reset();\n    });\n\n    const onSearchTermChange: React.ChangeEventHandler<HTMLInputElement> = useEvent((e) => {\n        actions.setTerm(e.target.value);\n    });\n\n    const onPreviousClick = useEvent(() => {\n        actions.previous();\n    });\n\n    const onNextClick = useEvent(() => {\n        actions.next();\n    });\n\n    const onEnter: React.KeyboardEventHandler<HTMLInputElement> = useEvent((e) => {\n        if (e.shiftKey) {\n            onPreviousClick();\n        } else {\n            onNextClick();\n        }\n    });\n\n    if (!isOpen) {\n        return null;\n    }\n\n    return (\n        <div\n            className=\"absolute top-0 right-4 z-2 flex w-fit items-center gap-3 border-r border-b border-l border-sectionborder bg-white p-4 dark:border-dark-sectionborder dark:bg-dark-bg0\"\n            data-conversation-search-panel=\"true\">\n            <div className={\"relative\"}>\n                <ContentTextInput\n                    ref={inputRef}\n                    className=\"h-[2.6rem]! pr-32! pl-2! text-lg!\"\n                    value={searchTerm}\n                    placeholder={\"Search conversation...\"}\n                    onChange={onSearchTermChange}\n                    onEscape={closeSearch}\n                    onEnter={onEnter}\n                    autoFocus\n                    autoComplete=\"off\"\n                />\n                <div className=\"absolute top-1/2 right-3 flex -translate-y-1/2\">\n                    {searchTerm && (\n                        <LinkInternal\n                            className=\"text-light-bg6 opacity-50 hover:opacity-100 dark:text-dark-fg1\"\n                            icon={faTimes}\n                            onClick={resetSearch}\n                        />\n                    )}\n                </div>\n            </div>\n            <span className=\"min-w-24 text-center text-sm text-light-bg6 dark:text-dark-fg1\">\n                {matches.length ? `${currentMatchIndex + 1} of ${matches.length}` : \"No Results\"}\n            </span>\n            <Button small onClick={onPreviousClick} disabled={matches.length === 0}>\n                <FontAwesomeIcon icon={faAngleUp} />\n            </Button>\n            <Button small onClick={onNextClick} disabled={matches.length === 0}>\n                <FontAwesomeIcon icon={faAngleDown} />\n            </Button>\n            <LinkInternal\n                className=\"text-light-bg6 opacity-50 hover:opacity-100 dark:text-dark-fg1\"\n                icon={faTimes}\n                onClick={closeSearch}\n            />\n        </div>\n    );\n};\n","import { TextContent } from \"@agent-host/rpc_types.ts\";\nimport * as types from \"@/agent/types.ts\";\n\ninterface SearchableTurn {\n    turnIndex: number;\n    text: string;\n}\n\nexport interface ConversationSearchMatch {\n    turnIndex: number;\n    occurrenceIndex: number;\n}\n\nexport interface ConversationSearchMatchForTurn extends ConversationSearchMatch {\n    matchIndex: number;\n}\n\nexport interface ConversationSearchState {\n    currentMatchIndex: number;\n    matches: ConversationSearchMatch[];\n    searchTerm: string;\n}\n\nconst agentMessageText = (message: types.AgentMessage) =>\n    message.events\n        .filter((e) => e.event.update.content.type === \"text\")\n        .map((e) => (e.event.update.content as TextContent).text)\n        .join(\"\");\n\nconst approximateRenderedText = (text: string) =>\n    // The search index intentionally approximates rendered text; DOM range lookup remains the highlight authority.\n    text\n        .replace(/!\\[[^\\]]*\\]\\([^)]+\\)/g, \"\")\n        .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\")\n        .replace(/```[^\\n]*\\n([\\s\\S]*?)```/g, \"$1\")\n        .replace(/`([^`]*)`/g, \"$1\")\n        .replace(/[*_~#>`]/g, \"\")\n        .trim();\n\nconst promptText = (turn: types.PromptTurn) =>\n    turn.promptRequest.event.prompt\n        .filter((content) => content.type === \"text\")\n        .map((content) => approximateRenderedText(content.text))\n        .join(\"\\n\");\n\nconst finalAgentMessageText = (turn: types.PromptTurn) => {\n    const finalSection = turn.responseSections.at(-1);\n    if (finalSection?.sectionType !== \"agent_messages\") {\n        return \"\";\n    }\n    return finalSection.messages.map(agentMessageText).map(approximateRenderedText).join(\"\\n\");\n};\n\nconst searchableTextForTurn = (turn: types.ConversationTurn) => {\n    switch (turn.turnType) {\n        case \"error\":\n            return turn.error.message || \"An error occurred.\";\n        case \"schema_migration\":\n            return turn.summary;\n        case \"prompt\":\n            return [promptText(turn), finalAgentMessageText(turn)].join(\"\\n\");\n        case \"session_boundary\":\n            return \"\";\n    }\n};\n\nconst searchableTurns = (conversation: types.ConversationModel): SearchableTurn[] =>\n    conversation.turns.map((turn, turnIndex) => ({\n        turnIndex,\n        text: searchableTextForTurn(turn),\n    }));\n\nexport const searchConversation = (\n    conversation: types.ConversationModel,\n    searchTerm: string\n): ConversationSearchMatch[] => {\n    const normalizedSearchTerm = searchTerm.trim().toLocaleLowerCase();\n    if (!normalizedSearchTerm) {\n        return [];\n    }\n    return searchableTurns(conversation).flatMap(({ text, turnIndex }) => {\n        const normalizedText = text.toLocaleLowerCase();\n        const matches: ConversationSearchMatch[] = [];\n        let startPos = 0;\n        let occurrenceIndex = 0;\n        let index: number;\n        while ((index = normalizedText.indexOf(normalizedSearchTerm, startPos)) !== -1) {\n            matches.push({ turnIndex, occurrenceIndex });\n            occurrenceIndex++;\n            startPos = index + normalizedSearchTerm.length;\n        }\n        return matches;\n    });\n};\n","import { useEffect, useMemo, useReducer } from \"react\";\nimport type {\n    ConversationSearchMatch,\n    ConversationSearchState,\n} from \"@/agent/components/conversationSearch/conversationSearchIndex.ts\";\nimport { searchConversation } from \"@/agent/components/conversationSearch/conversationSearchIndex.ts\";\nimport type { ConversationModel } from \"@/agent/types.ts\";\n\ninterface ConversationSearchUiState {\n    currentMatchIndex: number;\n    isOpen: boolean;\n    searchTerm: string;\n}\n\ntype ConversationSearchAction =\n    | { type: \"close\" }\n    | { type: \"conversationChanged\" }\n    | { type: \"next\"; matchCount: number }\n    | { type: \"open\" }\n    | { type: \"previous\"; matchCount: number }\n    | { type: \"reset\" }\n    | { type: \"setTerm\"; searchTerm: string };\n\nexport interface ConversationSearchActions {\n    close(): void;\n    next(): void;\n    open(): void;\n    previous(): void;\n    reset(): void;\n    setTerm(searchTerm: string): void;\n}\n\nexport interface ConversationSearchControllerState {\n    currentMatch: ConversationSearchMatch | undefined;\n    currentMatchIndex: number;\n    isOpen: boolean;\n    matches: ConversationSearchMatch[];\n    searchTerm: string;\n    transcriptSearchState: ConversationSearchState;\n}\n\nexport interface ConversationSearchController {\n    actions: ConversationSearchActions;\n    state: ConversationSearchControllerState;\n}\n\nconst INITIAL_CONVERSATION_SEARCH: ConversationSearchUiState = {\n    currentMatchIndex: -1,\n    isOpen: false,\n    searchTerm: \"\",\n};\n\nconst clampMatchIndex = (currentMatchIndex: number, matchCount: number) => {\n    if (matchCount === 0) {\n        return -1;\n    }\n    return Math.min(Math.max(currentMatchIndex, 0), matchCount - 1);\n};\n\nconst conversationSearchReducer = (\n    state: ConversationSearchUiState,\n    action: ConversationSearchAction\n): ConversationSearchUiState => {\n    switch (action.type) {\n        case \"open\":\n            return { ...state, isOpen: true };\n        case \"close\":\n        case \"conversationChanged\":\n            return INITIAL_CONVERSATION_SEARCH;\n        case \"reset\":\n            return { ...state, currentMatchIndex: -1, searchTerm: \"\" };\n        case \"setTerm\":\n            return { ...state, currentMatchIndex: 0, searchTerm: action.searchTerm };\n        case \"previous\": {\n            if (action.matchCount === 0) {\n                return { ...state, currentMatchIndex: -1 };\n            }\n            const currentMatchIndex = clampMatchIndex(state.currentMatchIndex, action.matchCount);\n            return {\n                ...state,\n                currentMatchIndex: currentMatchIndex <= 0 ? action.matchCount - 1 : currentMatchIndex - 1,\n            };\n        }\n        case \"next\": {\n            if (action.matchCount === 0) {\n                return { ...state, currentMatchIndex: -1 };\n            }\n            const currentMatchIndex = clampMatchIndex(state.currentMatchIndex, action.matchCount);\n            return {\n                ...state,\n                currentMatchIndex: currentMatchIndex < action.matchCount - 1 ? currentMatchIndex + 1 : 0,\n            };\n        }\n    }\n};\n\nexport const useConversationSearch = (\n    conversation: ConversationModel,\n    conversationPid: string | undefined\n): ConversationSearchController => {\n    const [state, dispatch] = useReducer(conversationSearchReducer, INITIAL_CONVERSATION_SEARCH);\n    const matches = useMemo(() => searchConversation(conversation, state.searchTerm), [conversation, state.searchTerm]);\n    const searchTerm = state.searchTerm.trim();\n    const currentMatchIndex = clampMatchIndex(state.currentMatchIndex, matches.length);\n    const currentMatch = matches[currentMatchIndex];\n\n    useEffect(() => {\n        dispatch({ type: \"conversationChanged\" });\n    }, [conversationPid]);\n\n    const transcriptSearchState = useMemo<ConversationSearchState>(\n        () => ({\n            currentMatchIndex,\n            matches,\n            searchTerm,\n        }),\n        [currentMatchIndex, matches, searchTerm]\n    );\n\n    const actions = useMemo<ConversationSearchActions>(\n        () => ({\n            close: () => dispatch({ type: \"close\" }),\n            next: () => dispatch({ type: \"next\", matchCount: matches.length }),\n            open: () => dispatch({ type: \"open\" }),\n            previous: () => dispatch({ type: \"previous\", matchCount: matches.length }),\n            reset: () => dispatch({ type: \"reset\" }),\n            setTerm: (searchTerm) => dispatch({ type: \"setTerm\", searchTerm }),\n        }),\n        [matches.length]\n    );\n\n    const controllerState = useMemo<ConversationSearchControllerState>(\n        () => ({\n            currentMatch,\n            currentMatchIndex,\n            isOpen: state.isOpen,\n            matches,\n            searchTerm: state.searchTerm,\n            transcriptSearchState,\n        }),\n        [currentMatch, currentMatchIndex, matches, state.isOpen, state.searchTerm, transcriptSearchState]\n    );\n\n    return useMemo(\n        () => ({\n            actions,\n            state: controllerState,\n        }),\n        [actions, controllerState]\n    );\n};\n","import { type KeyboardEventHandler, useEffect, useMemo } from \"react\";\nimport { ConversationSearch } from \"@/agent/components/conversationSearch/ConversationSearch.tsx\";\nimport { useConversationSearch } from \"@/agent/components/conversationSearch/useConversationSearch.ts\";\nimport { ConversationModel } from \"@/agent/types.ts\";\nimport { checkMeta } from \"@/util\";\nimport useEvent from \"@/util/useEventCallback.ts\";\n\nconst isEditableEventTarget = (target: EventTarget | null) =>\n    target instanceof HTMLElement &&\n    (target.tagName === \"INPUT\" ||\n        target.tagName === \"TEXTAREA\" ||\n        target.tagName === \"SELECT\" ||\n        target.isContentEditable ||\n        !!target.closest(\"[contenteditable='true']\"));\n\nexport const useConversationSearchFeature = ({\n    conversation,\n    conversationPid,\n    isTab,\n    isTurnMounted,\n    isVisible,\n    scrollToTurnIndex,\n}: {\n    conversation: ConversationModel;\n    conversationPid: string | undefined;\n    isTab: boolean;\n    isTurnMounted: (turnIndex: number) => boolean;\n    isVisible: boolean;\n    scrollToTurnIndex: (turnIndex: number, behavior?: \"auto\" | \"smooth\") => void;\n}) => {\n    const search = useConversationSearch(conversation, conversationPid);\n    const {\n        actions,\n        state: { currentMatch, transcriptSearchState },\n    } = search;\n\n    const open = useEvent(() => {\n        actions.open();\n    });\n\n    useEffect(() => {\n        if (currentMatch && !isTurnMounted(currentMatch.turnIndex)) {\n            scrollToTurnIndex(currentMatch.turnIndex, \"auto\");\n        }\n    }, [currentMatch?.turnIndex, isTurnMounted, scrollToTurnIndex, transcriptSearchState.searchTerm]);\n\n    const onKeyDown: KeyboardEventHandler<HTMLDivElement> = useEvent((e) => {\n        if (e.key.toLocaleLowerCase() === \"f\" && checkMeta(e)) {\n            e.preventDefault();\n            e.stopPropagation();\n            open();\n        }\n    });\n\n    useEffect(() => {\n        if (!isVisible || !isTab) {\n            return;\n        }\n\n        const onDocumentKeyDown = (e: KeyboardEvent) => {\n            if (\n                e.key.toLocaleLowerCase() !== \"f\" ||\n                !checkMeta(e) ||\n                e.shiftKey ||\n                e.altKey ||\n                isEditableEventTarget(e.target)\n            ) {\n                return;\n            }\n            e.preventDefault();\n            e.stopPropagation();\n            open();\n        };\n\n        document.body.addEventListener(\"keydown\", onDocumentKeyDown, { capture: true });\n        return () => document.body.removeEventListener(\"keydown\", onDocumentKeyDown, { capture: true });\n    }, [isTab, isVisible]);\n\n    const panel = useMemo(() => <ConversationSearch search={search} />, [search]);\n\n    return {\n        onKeyDown,\n        open,\n        panel,\n        transcriptSearchState,\n    };\n};\n","const SLASH_COMMAND_NAME_START_PATTERN = String.raw`[A-Za-z0-9]`;\nexport const SLASH_COMMAND_NAME_BODY_PATTERN = String.raw`[\\w./:-]`;\nexport const SLASH_COMMAND_NAME_PATTERN = `${SLASH_COMMAND_NAME_START_PATTERN}${SLASH_COMMAND_NAME_BODY_PATTERN}*`;\nexport const SLASH_COMMAND_COMPLETION_PATTERN = String.raw`${SLASH_COMMAND_NAME_BODY_PATTERN}*`;\nexport const DOLLAR_COMMAND_COMPLETION_PATTERN = String.raw`${SLASH_COMMAND_NAME_BODY_PATTERN}*`;\n\nconst slashCommandTokenMatcher = new RegExp(\n    String.raw`(^|\\s)(?:/(${SLASH_COMMAND_NAME_PATTERN})|(\\$(${SLASH_COMMAND_NAME_PATTERN})))(?=\\s|$)`,\n    \"g\"\n);\n\nexport interface SlashCommandTokenMatch {\n    commandName: string;\n    leadingText: string;\n    token: string;\n    tokenStart: number;\n    tokenEnd: number;\n}\n\nexport function findSlashCommandTokenMatches(text: string): SlashCommandTokenMatch[] {\n    slashCommandTokenMatcher.lastIndex = 0;\n    return [...text.matchAll(slashCommandTokenMatcher)].map((match) => {\n        const leadingText = match[1] ?? \"\";\n        const slashCommandName = match[2];\n        const dollarToken = match[3];\n        const dollarCommandName = match[4];\n        const commandName = slashCommandName ?? (dollarCommandName ? `$${dollarCommandName}` : \"\");\n        const tokenStart = match.index! + leadingText.length;\n        return {\n            commandName,\n            leadingText,\n            token: slashCommandName ? `/${slashCommandName}` : (dollarToken ?? \"\"),\n            tokenStart,\n            tokenEnd: tokenStart + (slashCommandName ? slashCommandName.length + 1 : (dollarToken ?? \"\").length),\n        };\n    });\n}\n\nexport function slashCommandApplyText(slashCommandName: string): string {\n    return `${slashCommandTokenText(slashCommandName)} `;\n}\n\nexport function slashCommandTokenText(slashCommandName: string): string {\n    return slashCommandName.startsWith(\"$\") ? slashCommandName : `/${slashCommandName}`;\n}\n\nexport function slashCommandDisplayText(slashCommandName: string): string {\n    return slashCommandName.startsWith(\"$\") ? slashCommandName.slice(1) : `/${slashCommandName}`;\n}\n\nexport function commandsBySlashCommandName<T extends { slashCommandName: string }>(commands: T[]): Map<string, T> {\n    return new Map(commands.map((command) => [command.slashCommandName, command]));\n}\n","import type { AvailableCommand } from \"@agent-host/rpc_types.ts\";\nimport type { Completion, CompletionContext, CompletionResult } from \"@codemirror/autocomplete\";\nimport { closeCompletion } from \"@codemirror/autocomplete\";\nimport type { EditorView } from \"@codemirror/view\";\nimport {\n    DOLLAR_COMMAND_COMPLETION_PATTERN,\n    SLASH_COMMAND_COMPLETION_PATTERN,\n    SLASH_COMMAND_NAME_PATTERN,\n    slashCommandApplyText,\n} from \"../conversationSkillCommands.ts\";\n\ninterface ComposerCompletionBase {\n    label: string;\n    // When present, this is a suffix of label, which remains the search text.\n    displayLabel?: string;\n    parentPath?: string;\n    detail?: string;\n    description?: string;\n    sourceLabel?: string;\n    type: Completion[\"type\"];\n    section?: Completion[\"section\"];\n    boost?: number;\n    info?: Completion[\"info\"];\n}\n\nexport type ComposerCompletion = ComposerCompletionBase &\n    (\n        | { applyText: string; apply?: never }\n        | { applyText?: never; apply: (view: EditorView, from: number, to: number) => void }\n    );\n\nfunction commandMetaSourceLabel(command: AvailableCommand): string | undefined {\n    const anvilMeta = command._meta?.[\"anvil\"];\n    if (!anvilMeta || typeof anvilMeta !== \"object\" || Array.isArray(anvilMeta)) {\n        return undefined;\n    }\n    const sourceLabel = (anvilMeta as Record<string, unknown>).sourceLabel;\n    return typeof sourceLabel === \"string\" && sourceLabel.length > 0 ? sourceLabel : undefined;\n}\n\nfunction commandMetaCommandKind(command: AvailableCommand): string | undefined {\n    const anvilMeta = command._meta?.[\"anvil\"];\n    if (!anvilMeta || typeof anvilMeta !== \"object\" || Array.isArray(anvilMeta)) {\n        return undefined;\n    }\n    const commandKind = (anvilMeta as Record<string, unknown>).commandKind;\n    return typeof commandKind === \"string\" && commandKind.length > 0 ? commandKind : undefined;\n}\n\nexport function isAvailableCommandSkill(command: AvailableCommand): boolean {\n    return command.name.startsWith(\"$\") || commandMetaCommandKind(command) === \"skill\";\n}\n\nexport function availableCommandSubmittedTokenName(command: AvailableCommand): string {\n    if (!isAvailableCommandSkill(command)) {\n        return command.name;\n    }\n    return command.name.startsWith(\"$\") ? command.name : `$${command.name}`;\n}\n\nexport function availableCommandSourceLabel(command: AvailableCommand): string {\n    return commandMetaSourceLabel(command) ?? (isAvailableCommandSkill(command) ? \"Skill\" : \"System\");\n}\n\nexport function sourceLabelDisplayText(sourceLabel: string): string {\n    return sourceLabel === \"System\" ? \"System\" : `Source: ${sourceLabel}`;\n}\n\nfunction sourceLabelBoost(sourceLabel: string): number | undefined {\n    switch (sourceLabel) {\n        case \"App\":\n            return 30;\n        case \"Anvil\":\n            return 20;\n        case \"Personal\":\n            return 10;\n        default:\n            return undefined;\n    }\n}\n\nfunction sourceLabelRank(sourceLabel: string | undefined): number {\n    switch (sourceLabel) {\n        case \"App\":\n            return 0;\n        case \"Anvil\":\n            return 1;\n        case \"Personal\":\n            return 2;\n        case \"System\":\n            return 3;\n        default:\n            return 4;\n    }\n}\n\nfunction completionSectionRank(completion: ComposerCompletion): number {\n    const section = completion.section;\n    if (!section) {\n        return 0;\n    }\n    if (typeof section === \"string\") {\n        return section === \"Commands\" ? 0 : 1;\n    }\n    return section.rank ?? (section.name === \"Commands\" ? 0 : 1);\n}\n\nfunction compareCompletions(a: ComposerCompletion, b: ComposerCompletion): number {\n    return (\n        completionSectionRank(a) - completionSectionRank(b) ||\n        sourceLabelRank(a.sourceLabel) - sourceLabelRank(b.sourceLabel) ||\n        a.label.localeCompare(b.label)\n    );\n}\n\nexport function commandCompletion(\n    command: AvailableCommand,\n    info?: Completion[\"info\"],\n    {\n        includeSection = true,\n        applyText,\n    }: {\n        includeSection?: boolean;\n        applyText?: string;\n    } = {}\n): ComposerCompletion {\n    const isSkill = isAvailableCommandSkill(command);\n    const submittedTokenName = availableCommandSubmittedTokenName(command);\n    const sourceLabel = availableCommandSourceLabel(command);\n    const boost = sourceLabelBoost(sourceLabel);\n    return {\n        label: submittedTokenName.startsWith(\"$\") ? submittedTokenName.slice(1) : submittedTokenName,\n        description: command.description,\n        sourceLabel,\n        applyText: applyText ?? slashCommandApplyText(submittedTokenName),\n        type: isSkill ? \"agent-skill\" : \"agent-command\",\n        ...(boost !== undefined ? { boost } : {}),\n        ...(includeSection ? { section: isSkill ? { name: \"Skills\", rank: 1 } : { name: \"Commands\", rank: 0 } } : {}),\n        ...(info ? { info } : {}),\n    };\n}\n\nexport function slashCompletionsForCommands(\n    availableCommands: AvailableCommand[],\n    {\n        commandInfo,\n    }: {\n        commandInfo?: (command: AvailableCommand) => Completion[\"info\"];\n    } = {}\n): ComposerCompletion[] {\n    return availableCommands\n        .map((command) => commandCompletion(command, commandInfo?.(command)))\n        .toSorted(compareCompletions);\n}\n\nexport function omitProviderPlanCommand(availableCommands: AvailableCommand[]): AvailableCommand[] {\n    return availableCommands.filter((command) => availableCommandSubmittedTokenName(command) !== \"plan\");\n}\n\nexport function preferLocalSlashCompletions(\n    providerCompletions: ComposerCompletion[],\n    localCompletions: ComposerCompletion[]\n): ComposerCompletion[] {\n    const localLabels = new Set(localCompletions.map(({ label }) => label));\n    return [...providerCompletions.filter(({ label }) => !localLabels.has(label)), ...localCompletions];\n}\n\nexport function dollarCompletionsForCommands(\n    availableCommands: AvailableCommand[],\n    commandInfo?: (command: AvailableCommand) => Completion[\"info\"]\n): ComposerCompletion[] {\n    return availableCommands\n        .filter((command) => isAvailableCommandSkill(command))\n        .map((command) =>\n            commandCompletion(command, commandInfo?.(command), {\n                includeSection: false,\n            })\n        )\n        .toSorted(compareCompletions);\n}\n\nexport function completionSource(trigger: \"@\" | \"/\" | \"$\", options: ComposerCompletion[]) {\n    const triggerPattern = trigger === \"$\" ? String.raw`\\$` : trigger;\n    const matcher =\n        trigger === \"@\"\n            ? /(^|\\s)@[\\w.-]*$/\n            : new RegExp(\n                  String.raw`(^|\\s)${triggerPattern}${\n                      trigger === \"$\" ? DOLLAR_COMMAND_COMPLETION_PATTERN : SLASH_COMMAND_COMPLETION_PATTERN\n                  }$`\n              );\n    const validFor =\n        trigger === \"@\"\n            ? /^[\\w.-]*$/\n            : new RegExp(String.raw`^(?:${SLASH_COMMAND_NAME_PATTERN})?$`);\n\n    return (context: CompletionContext): CompletionResult | null => {\n        const token = context.matchBefore(matcher);\n        if (!token) {\n            return null;\n        }\n        const triggerIndex = trigger === \"/\" ? token.text.indexOf(trigger) : token.text.lastIndexOf(trigger);\n        const tokenFrom = token.from + triggerIndex;\n        const from = tokenFrom + 1;\n        return {\n            from,\n            getMatch: (completion, matched = []) => {\n                const offset = completion.displayLabel ? completion.label.length - completion.displayLabel.length : 0;\n                const ranges: number[] = [];\n                for (let i = 0; i < matched.length; i += 2) {\n                    if (matched[i + 1] > offset) {\n                        ranges.push(Math.max(0, matched[i] - offset), matched[i + 1] - offset);\n                    }\n                }\n                return ranges;\n            },\n            options: options.map(({ applyText, apply, ...option }) => ({\n                ...option,\n                apply: (view: EditorView, _completion: Completion, from: number, to: number) => {\n                    if (apply) {\n                        apply(view, tokenFrom, to);\n                    } else if (applyText !== undefined) {\n                        view.dispatch({\n                            changes: { from: tokenFrom, to, insert: applyText },\n                            selection: { anchor: tokenFrom + applyText.length },\n                        });\n                    }\n                    closeCompletion(view);\n                },\n            })),\n            validFor,\n        };\n    };\n}\n","import { createContext } from \"react\";\nimport * as types from \"@/agent/types\";\nimport { createContextHook } from \"@/util/hooks\";\n\nexport const ConversationContext = createContext<types.ConversationContext | null>(null);\n\nexport const useConversationContext = createContextHook(ConversationContext, \"ConversationContext\");\n","import type { SessionUpdate } from \"@agent-host/rpc_types\";\nimport type {\n    ConversationEvent,\n    ConversationModel,\n    FormElicitationCancelledEvent,\n    FormElicitationResponseEvent,\n    PermissionCancelledEvent,\n    PermissionResponseEvent,\n    PromptTurn,\n    ProposedPlanSection,\n    TurnDiffEvent,\n} from \"@/agent/types\";\n\nexport const createConversationModel = (): ConversationModel => ({\n    history: \"unloaded\",\n    turns: [],\n    currentPromptTurnIndex: null,\n    usage: null,\n    sessionStatus: null,\n    urlElicitation: null,\n    availableCommands: [],\n    config: { session: {}, interaction_mode: \"build\", interaction_modes: [\"build\"] },\n    draftInteractionMode: null,\n    submittingPrompt: null,\n    pendingPrompt: null,\n    receivedEventPids: {},\n    latestReceivedEventPid: null,\n    latestReceivedEvent: null,\n    latestErrorTurn: null,\n});\n\nconst cancelOpenPromptSections = (turn: PromptTurn | null, evt: ConversationEvent) => {\n    for (const section of turn?.responseSections ?? []) {\n        if (section.sectionType === \"tool_calls\") {\n            for (const toolCall of section.toolCalls) {\n                if (toolCall.status !== \"completed\" && toolCall.status !== \"failed\") {\n                    toolCall.status = \"cancelled\";\n                }\n            }\n        } else if (section.sectionType === \"form_elicitation\" && section.response === null) {\n            // Cancellation events are durable, so this derived answer is stable across replay.\n            section.response = {\n                ...evt,\n                event_type: \"form_elicitation_response\",\n                event: {\n                    elicitation_id: section.request.event.elicitation_id,\n                    action: \"cancel\",\n                },\n            };\n        } else if (section.sectionType === \"permission\" && section.response === null) {\n            section.response = {\n                ...evt,\n                event_type: \"permission_response\",\n                event: { permission_id: section.request.event.permission_id },\n            };\n        }\n    }\n};\n\nconst updateProposedPlan = (\n    conversation: ConversationModel,\n    currentPromptTurn: PromptTurn | null,\n    plan: ProposedPlanSection[\"plan\"]\n) => {\n    let existingPlan: ProposedPlanSection | undefined;\n    let existingPlanTurn: PromptTurn | undefined;\n    for (const turn of conversation.turns) {\n        if (turn.turnType !== \"prompt\") continue;\n        const section = turn.responseSections.find(\n            (candidate) => candidate.sectionType === \"proposed_plan\" && candidate.plan.planId === plan.planId\n        );\n        if (section?.sectionType === \"proposed_plan\") {\n            existingPlan = section;\n            existingPlanTurn = turn;\n            break;\n        }\n    }\n\n    if (!existingPlan) {\n        currentPromptTurn?.responseSections.push({ sectionType: \"proposed_plan\", plan });\n        return;\n    }\n\n    existingPlan.plan = plan;\n    if (currentPromptTurn && existingPlanTurn && existingPlanTurn !== currentPromptTurn) {\n        existingPlanTurn.responseSections = existingPlanTurn.responseSections.filter(\n            (section) => section !== existingPlan\n        );\n        currentPromptTurn.responseSections.push(existingPlan);\n    }\n};\n\nconst removeProposedPlan = (conversation: ConversationModel, planId: string) => {\n    for (const turn of conversation.turns) {\n        if (turn.turnType === \"prompt\") {\n            turn.responseSections = turn.responseSections.filter(\n                (section) => section.sectionType !== \"proposed_plan\" || section.plan.planId !== planId\n            );\n        }\n    }\n};\n\nconst findFormElicitationSection = (conversation: ConversationModel, elicitationId: string) => {\n    for (const turn of conversation.turns) {\n        if (turn.turnType !== \"prompt\") continue;\n        const section = turn.responseSections.find(\n            (candidate) =>\n                candidate.sectionType === \"form_elicitation\" &&\n                candidate.request.event.elicitation_id === elicitationId\n        );\n        if (section?.sectionType === \"form_elicitation\") {\n            return section;\n        }\n    }\n};\n\nconst recordFormElicitationResponse = (\n    conversation: ConversationModel,\n    response: FormElicitationResponseEvent\n) => {\n    const section = findFormElicitationSection(conversation, response.event.elicitation_id);\n    if (section && section.response === null) {\n        section.response = response;\n    }\n};\n\nconst recordFormElicitationCancellation = (\n    conversation: ConversationModel,\n    cancellation: FormElicitationCancelledEvent\n) => {\n    const section = findFormElicitationSection(conversation, cancellation.event.elicitation_id);\n    if (section) {\n        // The provider is authoritative about whether it accepted a racing IDE response.\n        section.response = cancellation;\n    }\n};\n\nconst findPermissionSection = (conversation: ConversationModel, permissionId: string) => {\n    for (const turn of conversation.turns) {\n        if (turn.turnType !== \"prompt\") continue;\n        const section = turn.responseSections.find(\n            (candidate) =>\n                candidate.sectionType === \"permission\" && candidate.request.event.permission_id === permissionId\n        );\n        if (section?.sectionType === \"permission\") return section;\n    }\n};\n\nconst recordPermissionResponse = (conversation: ConversationModel, response: PermissionResponseEvent) => {\n    const section = findPermissionSection(conversation, response.event.permission_id);\n    if (!section || section.response !== null) return;\n\n    section.response = response;\n};\n\nconst recordPermissionCancellation = (conversation: ConversationModel, cancellation: PermissionCancelledEvent) => {\n    const section = findPermissionSection(conversation, cancellation.event.permission_id);\n    if (!section) return;\n    section.response = cancellation;\n};\n\nexport const applyConversationSectionEvent = (\n    conversation: ConversationModel,\n    currentPromptTurn: PromptTurn | null,\n    event: ConversationEvent\n) => {\n    switch (event.event_type) {\n        case \"prompt_cancel\":\n            if (currentPromptTurn) currentPromptTurn.cancellationRequested = true;\n            cancelOpenPromptSections(currentPromptTurn, event);\n            break;\n        case \"session_stopped\":\n            cancelOpenPromptSections(currentPromptTurn, event);\n            break;\n        case \"error\":\n            if (currentPromptTurn?.promptRequest.event.request_id === event.event.request_id) {\n                cancelOpenPromptSections(currentPromptTurn, event);\n            }\n            break;\n        case \"session_notification\":\n            if (event.event.update.sessionUpdate === \"plan_update\") {\n                updateProposedPlan(conversation, currentPromptTurn, event.event.update.plan);\n            } else if (event.event.update.sessionUpdate === \"plan_removed\") {\n                removeProposedPlan(\n                    conversation,\n                    (event.event.update as Extract<SessionUpdate, { sessionUpdate: \"plan_removed\" }>).planId\n                );\n            }\n            break;\n        case \"form_elicitation_request\":\n            if (currentPromptTurn) {\n                currentPromptTurn.responseSections.push({\n                    sectionType: \"form_elicitation\",\n                    request: event,\n                    response: null,\n                });\n            }\n            break;\n        case \"form_elicitation_response\":\n            recordFormElicitationResponse(conversation, event);\n            break;\n        case \"form_elicitation_cancelled\":\n            recordFormElicitationCancellation(conversation, event);\n            break;\n        case \"permission_request\":\n            if (currentPromptTurn) {\n                const planIndex =\n                    event.event.tool_call.kind === \"switch_mode\"\n                        ? currentPromptTurn.responseSections.findLastIndex(\n                              (section) => section.sectionType === \"proposed_plan\"\n                          )\n                        : -1;\n                const planSection =\n                    planIndex === -1 ? null : currentPromptTurn.responseSections.splice(planIndex, 1)[0];\n                currentPromptTurn.responseSections.push({\n                    sectionType: \"permission\",\n                    request: event,\n                    response: null,\n                    // Tool results can replace content; the reviewed request stays immutable.\n                    toolCall: structuredClone(event.event.tool_call),\n                    plan: planSection?.sectionType === \"proposed_plan\" ? planSection.plan : null,\n                });\n            }\n            break;\n        case \"permission_response\":\n            recordPermissionResponse(conversation, event);\n            break;\n        case \"permission_cancelled\":\n            recordPermissionCancellation(conversation, event);\n            break;\n    }\n};\n\nexport const applyConversationSessionStopped = (\n    conversation: ConversationModel,\n    currentPromptTurn: PromptTurn | null,\n    event: ConversationEvent\n) => {\n    const latestPromptTurn = conversation.turns.findLast((turn): turn is PromptTurn => turn.turnType === \"prompt\");\n    applyConversationSectionEvent(conversation, currentPromptTurn ?? latestPromptTurn ?? null, event);\n};\n\nexport const applyConversationTurnDiff = (conversation: ConversationModel, event: TurnDiffEvent) => {\n    const turn = conversation.turns.find(\n        (turn) => turn.turnType === \"prompt\" && turn.promptRequest.event_pid === event.event.prompt_event_pid\n    );\n    if (turn?.turnType === \"prompt\" && turn.turnDiff?.phase !== \"end\") {\n        turn.turnDiff = event.event;\n    }\n};\n","import type { ConversationConfig, ConversationModel } from \"@/agent/types\";\n\nexport const normalizeConversationConfig = (config: Partial<ConversationConfig>): ConversationConfig => {\n    const interactionModes = config.interaction_modes ?? [\"build\"];\n    const interactionMode = config.interaction_mode ?? \"build\";\n    return {\n        ...config,\n        session: config.session ?? {},\n        interaction_modes: interactionModes,\n        interaction_mode: interactionModes.includes(interactionMode) ? interactionMode : \"build\",\n    };\n};\n\nexport const mergeConversationConfigUpdate = (\n    current: ConversationConfig,\n    update: Partial<ConversationConfig>\n): ConversationConfig => {\n    const interactionModes = update.interaction_modes ?? current.interaction_modes;\n\n    return normalizeConversationConfig({\n        ...update,\n        interaction_modes: interactionModes,\n        interaction_mode: update.interaction_mode ?? current.interaction_mode,\n    });\n};\n\nexport const applyConversationConfigUpdate = (conversation: ConversationModel, update: Partial<ConversationConfig>) => {\n    conversation.config = mergeConversationConfigUpdate(conversation.config, update);\n    if (\n        conversation.draftInteractionMode &&\n        !conversation.config.interaction_modes.includes(conversation.draftInteractionMode.mode)\n    ) {\n        conversation.draftInteractionMode = null;\n    }\n};\n","import { applyConversationTurnDiff } from \"./conversationModel\";\nimport { useCallback, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport type {\n    ElicitationContentValue,\n    InteractionMode,\n    PromptRequestMessage,\n    PromptSource,\n} from \"@agent-host/rpc_types.ts\";\nimport { type QueryClient, queryOptions, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { type Draft, freeze, produce } from \"immer\";\nimport { summariseSchemaDiff } from \"@/agent/schemaMigration\";\nimport {\n    AgentAuthMap,\n    AgentMessageChunkEvent,\n    AgentThoughtChunkEvent,\n    AgentTypeId,\n    AgentUrlElicitation,\n    ApiKeyLoginType,\n    CancelableToolCall,\n    ConversationEvent,\n    ConversationHistoryNotice,\n    ConversationInfo,\n    ConversationModel,\n    ConversationPid, ErrorTurn,\n    ParsedAgentUrlElicitation,\n    PermissionSection,\n    PromptTurn,\n    ResponseSection,\n    SessionConfigUpdateByCategory,\n} from \"@/agent/types.ts\";\nimport { cacheSessionCapabilities } from \"@/agent/sessionCapabilities.ts\";\nimport { dropProviderUsage, mergeUsageUpdate } from \"@/agent/usage.ts\";\nimport { getAgentAuth } from \"@/api\";\nimport { getConversation } from \"@/api/agents.ts\";\nimport {\n    getConversationListQueryKey,\n    getQueryOptions,\n    ingestConversationInfoUpdate,\n    openConversation,\n    updateConversationInfo,\n    updateConversationListQuery,\n} from \"@/controllers/agents.ts\";\nimport { getAppId, updateAppSchemaSync } from \"@/controllers/app\";\nimport { alert } from \"@/controllers/modals.ts\";\nimport { updateUserEditorPrefs } from \"@/controllers/user\";\nimport { getAgentTypeName } from \"@/controllers/user-agent-types\";\nimport * as ws from \"@/controllers/websocket.ts\";\nimport { EventCallback, WebsocketEvent, useWebsocketEventListener } from \"@/controllers/websocket.ts\";\nimport { useRemToPixels } from \"@/theme/ThemeProvider\";\nimport { AnvilDispatch, AppId } from \"@/types\";\nimport { DEFAULT_QUERY_STALE_TIME } from \"@/util/queryClient\";\nimport useEvent from \"@/util/useEventCallback.ts\";\nimport { applyConversationConfigUpdate, normalizeConversationConfig } from \"./conversationConfig\";\nimport {\n    applyConversationSectionEvent,\n    applyConversationSessionStopped,\n    createConversationModel,\n} from \"./conversationModel\";\n\nconst SCROLL_END_THRESHOLD_PX = 30;\n\nexport type ConversationVirtualRow =\n    | {\n          kind: \"turn\";\n          key: string;\n          turn: ConversationModel[\"turns\"][number];\n      }\n    | {\n          kind: \"submitting\";\n          key: string;\n          submittingPrompt: NonNullable<ConversationModel[\"submittingPrompt\"]>;\n      }\n    | {\n          kind: \"pending\";\n          key: string;\n          pendingPrompt: NonNullable<ConversationModel[\"pendingPrompt\"]>;\n      }\n    | {\n          kind: \"active\";\n          key: string;\n      };\n\nexport const EMPTY_CONVERSATION_MODEL = freeze(createConversationModel());\n\nconst activeAgentErrorAlerts = new Set<string>();\n\nconst normalizeAgentSessionError = (error: unknown) =>\n    typeof error === \"string\" ? error : (JSON.stringify(error) ?? String(error));\n\nconst showAgentSessionErrorAlert = (\n    queryClient: QueryClient,\n    dispatch: AnvilDispatch,\n    appId: AppId,\n    event: WebsocketEvent\n) => {\n    if (!event.error || !event.conversation_pid) {\n        return;\n    }\n\n    const conversationPid = event.conversation_pid as ConversationPid;\n    const message = normalizeAgentSessionError(event.error);\n    const alertKey = `${appId}:${event.event}:${conversationPid}:${event.status ?? \"\"}:${message}`;\n\n    if (activeAgentErrorAlerts.has(alertKey)) {\n        return;\n    }\n\n    activeAgentErrorAlerts.add(alertKey);\n\n    const conversation = queryClient\n        .getQueryData<ConversationInfo[]>(getConversationListQueryKey(appId))\n        ?.find((c) => c.conversation_pid === conversationPid);\n    const title = `${getAgentTypeName(conversation?.agent_type)} error`;\n    const text = `The agent reported an error.\\n\\n${message}`;\n\n    void dispatch(\n        alert(title, text, {\n            buttons: [\n                {\n                    text: \"Open conversation\",\n                    defaultButton: true,\n                    clickActionCreator: () => openConversation(conversationPid),\n                },\n                { text: \"OK\" },\n            ],\n        })\n    ).finally(() => {\n        activeAgentErrorAlerts.delete(alertKey);\n    });\n};\n\nexport const applyConversationEvent = (conv: ConversationModel, evt: ConversationEvent) => {\n    if (evt.event_pid in conv.receivedEventPids) {\n        console.warn(\"Discarding duplicate conversation event\", evt);\n        return;\n    }\n    const currentPromptTurn =\n        conv.currentPromptTurnIndex !== null ? (conv.turns[conv.currentPromptTurnIndex] as PromptTurn) : null;\n\n    const fullyReceived = () => {\n        conv.latestReceivedEventPid = evt.event_pid;\n        conv.receivedEventPids[evt.event_pid] = true;\n    };\n    switch (evt.event_type) {\n        case \"prompt_request\":\n            fullyReceived();\n            conv.config.interaction_mode = conv.config.interaction_modes.includes(evt.event.interaction_mode ?? \"build\")\n                ? (evt.event.interaction_mode ?? \"build\")\n                : \"build\";\n            conv.currentPromptTurnIndex = conv.turns.length;\n            conv.turns.push({\n                turnType: \"prompt\",\n                promptRequest: evt,\n                promptResponse: null,\n                responseSections: [],\n            });\n            if (evt.event.request_id === conv.submittingPrompt?.request_id) {\n                if (conv.draftInteractionMode?.id === conv.submittingPrompt.draftInteractionModeId) {\n                    conv.draftInteractionMode = null;\n                }\n                conv.submittingPrompt = null;\n            }\n            break;\n        case \"turn_diff\":\n            fullyReceived();\n            applyConversationTurnDiff(conv, evt);\n            break;\n        case \"prompt_response\":\n            fullyReceived();\n            if (currentPromptTurn?.promptRequest.event.request_id === evt.event.request_id) {\n                currentPromptTurn.promptResponse = evt;\n                conv.currentPromptTurnIndex = null;\n                if (evt.event.stopReason === \"end_turn\") {\n                    conv.latestErrorTurn = null;\n                }\n            }\n            break;\n        case \"prompt_cancel\":\n            fullyReceived();\n            applyConversationSectionEvent(conv, currentPromptTurn, evt);\n            break;\n        case \"session_notification\":\n            switch (evt.event.update.sessionUpdate) {\n                case \"usage_update\":\n                    fullyReceived();\n                    conv.usage = mergeUsageUpdate(conv.usage, evt.event.update);\n                    break;\n                case \"available_commands_update\":\n                    fullyReceived();\n                    conv.availableCommands = evt.event.update.availableCommands;\n                    break;\n                case \"agent_message_chunk\":\n                    if (currentPromptTurn) {\n                        let latestSection: ResponseSection | undefined =\n                            currentPromptTurn.responseSections[currentPromptTurn.responseSections.length - 1];\n                        if (!latestSection || latestSection.sectionType !== \"agent_messages\") {\n                            latestSection = {\n                                sectionType: \"agent_messages\",\n                                messages: [],\n                            };\n                            currentPromptTurn.responseSections.push(latestSection);\n                        }\n                        // Look for an existing event to be updated\n                        let matched: AgentMessageChunkEvent | null = null;\n                        for (let i = latestSection.messages.length - 1; i >= 0; i--) {\n                            const m = latestSection.messages[i];\n                            for (let j = m.events.length - 1; j >= 0; j--) {\n                                const e = m.events[j];\n                                if (e.event_pid === evt.event_pid) {\n                                    matched = e;\n                                    break;\n                                }\n                            }\n                        }\n                        if (matched) {\n                            matched.event = evt.event as AgentMessageChunkEvent[\"event\"];\n                            matched.max_seqno = evt.max_seqno;\n                        } else {\n                            // This would be much easier if ACP would give us message IDs. For now, start a new section\n                            // whenever we get an event of a different type in between message chunks.\n                            if (\n                                latestSection.messages.length === 0 ||\n                                (conv.latestReceivedEvent &&\n                                    (conv.latestReceivedEvent.event_type !== \"session_notification\" ||\n                                        conv.latestReceivedEvent.event.update.sessionUpdate !== \"agent_message_chunk\"))\n                            ) {\n                                latestSection.messages.push({ events: [] });\n                            }\n                            latestSection.messages[latestSection.messages.length - 1].events.push(\n                                evt as AgentMessageChunkEvent\n                            );\n                        }\n                    } else {\n                        // Got a session update with a message from the agent, but not currently waiting for a prompt response. Wat.\n                    }\n                    break;\n                case \"agent_thought_chunk\":\n                    if (currentPromptTurn) {\n                        let latestSection: ResponseSection | undefined =\n                            currentPromptTurn.responseSections[currentPromptTurn.responseSections.length - 1];\n                        if (!latestSection || latestSection.sectionType !== \"agent_thoughts\") {\n                            latestSection = {\n                                sectionType: \"agent_thoughts\",\n                                messages: [],\n                            };\n                            currentPromptTurn.responseSections.push(latestSection);\n                        }\n                        // Look for an existing event to be updated\n                        let matched: AgentThoughtChunkEvent | null = null;\n                        for (let i = latestSection.messages.length - 1; i >= 0; i--) {\n                            const m = latestSection.messages[i];\n                            for (let j = m.events.length - 1; j >= 0; j--) {\n                                const e = m.events[j];\n                                if (e.event_pid === evt.event_pid) {\n                                    matched = e;\n                                    break;\n                                }\n                            }\n                        }\n                        if (matched) {\n                            matched.event = evt.event as AgentThoughtChunkEvent[\"event\"];\n                            matched.max_seqno = evt.max_seqno;\n                        } else {\n                            // This would be much easier if ACP would give us message IDs. For now, start a new section\n                            // whenever we get an event of a different type in between thought chunks.\n                            if (\n                                latestSection.messages.length === 0 ||\n                                (conv.latestReceivedEvent &&\n                                    (conv.latestReceivedEvent.event_type !== \"session_notification\" ||\n                                        conv.latestReceivedEvent.event.update.sessionUpdate !== \"agent_thought_chunk\"))\n                            ) {\n                                latestSection.messages.push({ events: [] });\n                            }\n                            latestSection.messages[latestSection.messages.length - 1].events.push(\n                                evt as AgentThoughtChunkEvent\n                            );\n                        }\n                    } else {\n                        // Got a session update with a message from the agent, but not currently waiting for a prompt response. Wat.\n                    }\n                    break;\n                case \"tool_call\":\n                    fullyReceived();\n                    if (currentPromptTurn) {\n                        let latestSection: ResponseSection | undefined =\n                            currentPromptTurn.responseSections[currentPromptTurn.responseSections.length - 1];\n                        if (!latestSection || latestSection.sectionType !== \"tool_calls\") {\n                            latestSection = {\n                                sectionType: \"tool_calls\",\n                                toolCalls: [],\n                            };\n                            currentPromptTurn.responseSections.push(latestSection);\n                        }\n\n                        latestSection.toolCalls.push(evt.event.update);\n                    } else {\n                        console.warn(\"Got tool call event when not waiting for a prompt response\", evt);\n                    }\n                    break;\n                case \"tool_call_update\":\n                    if (currentPromptTurn) {\n                        const update = evt.event.update;\n                        let toolCall: CancelableToolCall | PermissionSection[\"toolCall\"] | null = null;\n\n                        search: for (let i = currentPromptTurn.responseSections.length - 1; i >= 0; i--) {\n                            const section = currentPromptTurn.responseSections[i];\n                            if (section.sectionType === \"tool_calls\") {\n                                for (let j = section.toolCalls.length - 1; j >= 0; j--) {\n                                    const tc = section.toolCalls[j];\n                                    if (tc.toolCallId === update.toolCallId) {\n                                        toolCall = tc;\n                                        break search;\n                                    }\n                                }\n                            } else if (\n                                section.sectionType === \"permission\" &&\n                                section.toolCall.toolCallId === update.toolCallId\n                            ) {\n                                toolCall = section.toolCall;\n                                break search;\n                            }\n                        }\n\n                        if (toolCall && toolCall.status !== \"cancelled\") {\n                            if (\"content\" in update) {\n                                toolCall.content = update.content ?? undefined;\n                            }\n                            if (\"kind\" in update) {\n                                toolCall.kind = update.kind ?? undefined;\n                            }\n                            if (\"locations\" in update) {\n                                toolCall.locations = update.locations ?? undefined;\n                            }\n                            if (\"rawInput\" in update) {\n                                toolCall.rawInput = update.rawInput ?? undefined;\n                            }\n                            if (\"rawOutput\" in update) {\n                                toolCall.rawOutput = update.rawOutput ?? undefined;\n                            }\n                            if (\"status\" in update) {\n                                toolCall.status = update.status ?? undefined;\n                            }\n                            // The title field ACP type is broken, since it's a mandatory field. Just ignore null/undefined.\n                            if (typeof update.title === \"string\") {\n                                toolCall.title = update.title;\n                            }\n                        } else {\n                            console.warn(\"Got tool call update event for non-existent tool call\", evt);\n                        }\n                    } else {\n                        console.warn(\"Got tool call update event when not waiting for a prompt response\", evt);\n                    }\n                    break;\n                case \"plan_update\":\n                case \"plan_removed\":\n                    fullyReceived();\n                    applyConversationSectionEvent(conv, currentPromptTurn, evt);\n                    break;\n                // TODO: Deal with thinking, etc.\n                default:\n                    console.warn(\"Got unknown session notification event\", evt.event.update.sessionUpdate);\n            }\n            break;\n        case \"form_elicitation_request\":\n            fullyReceived();\n            applyConversationSectionEvent(conv, currentPromptTurn, evt);\n            break;\n        case \"form_elicitation_response\":\n        case \"form_elicitation_cancelled\":\n            fullyReceived();\n            applyConversationSectionEvent(conv, currentPromptTurn, evt);\n            break;\n        case \"permission_request\":\n        case \"permission_response\":\n        case \"permission_cancelled\":\n            fullyReceived();\n            applyConversationSectionEvent(conv, currentPromptTurn, evt);\n            break;\n        case \"config_update\":\n            fullyReceived();\n            applyConversationConfigUpdate(conv, evt.event.config);\n            break;\n        case \"schema_migration_applied\":\n            fullyReceived();\n            conv.turns.push({\n                turnType: \"schema_migration\",\n                eventPid: evt.event_pid,\n                summary: `${getAgentTypeName(evt.agent_type)} ${summariseSchemaDiff(evt.event.diff, { pastTense: true })}`,\n            });\n            break;\n        case \"error\":\n            fullyReceived();\n            const errorTurn: ErrorTurn = {\n                turnType: \"error\",\n                agentType: evt.agent_type,\n                error: evt.event,\n                eventPid: evt.event_pid,\n            };\n            conv.turns.push(errorTurn);\n            conv.latestErrorTurn = errorTurn;\n            if (currentPromptTurn && currentPromptTurn.promptRequest.event.request_id === evt.event.request_id) {\n                applyConversationSectionEvent(conv, currentPromptTurn, evt);\n                currentPromptTurn.promptResponse = evt;\n                conv.currentPromptTurnIndex = null;\n            }\n            break;\n        case \"session_created\":\n            fullyReceived();\n            addSessionBoundaryTurn(conv);\n            break;\n        case \"session_stopped\":\n            // Don't set session status here. This is an historical event, not an indication of current status.\n            fullyReceived();\n            applyConversationSessionStopped(conv, currentPromptTurn, evt);\n            addSessionBoundaryTurn(conv);\n            break;\n        default:\n            console.warn(\"Got unknown conversation event\", evt);\n    }\n    conv.latestReceivedEvent = evt;\n};\n\nconst addSessionBoundaryTurn = (conv: ConversationModel) => {\n    conv.currentPromptTurnIndex = null;\n    conv.submittingPrompt = null;\n    if (conv.turns.length > 0 && conv.turns[conv.turns.length - 1].turnType !== \"session_boundary\") {\n        conv.turns.push({ turnType: \"session_boundary\" });\n    }\n};\n\nconst parseAgentUrlElicitation = (e: AgentUrlElicitation): ParsedAgentUrlElicitation => {\n    // Extract the code (something like ABC1-D23GF) from e.message.\n    const codeMatch = /\\s+([A-Z0-9]{4}-[A-Z0-9]{5})/.exec(e.message);\n    return {\n        ...e,\n        code: codeMatch?.[1],\n    };\n};\n\nexport const buildConversationModel = (conversation: ConversationInfo, events: ConversationEvent[]) => {\n    const conv = createConversationModel();\n    conv.sessionStatus = conversation.session_status;\n    conv.pendingPrompt = conversation.pending_prompt ?? null;\n    for (const evt of events) {\n        applyConversationEvent(conv, evt);\n    }\n    // The current server config supersedes config and mode changes in recorded history.\n    conv.config = normalizeConversationConfig(conversation.config);\n    conv.usage = dropProviderUsage(conv.usage);\n    if (conversation.session_status === \"running\" && !conversation.config.pending) {\n        // The response config describes the current session; replayed events may be older.\n        cacheSessionCapabilities(conversation.agent_type, normalizeConversationConfig(conversation.config));\n    }\n    conv.history = \"loaded\";\n    console.log(\"Built conversation\", conv);\n    return freeze(conv);\n};\n\nconst buildInitialConversationModel = ({ session_status, config, pending_prompt }: ConversationInfo) =>\n    freeze({\n        ...createConversationModel(),\n        sessionStatus: session_status,\n        config: normalizeConversationConfig(config),\n        pendingPrompt: pending_prompt ?? null,\n    });\n\nconst getConversationQueryKey = (appId: AppId, conversationPid: ConversationPid) =>\n    [\"agent-conversation\", appId, conversationPid] as const;\n\nexport const seedNewConversation = (queryClient: QueryClient, conversation: ConversationInfo) => {\n    queryClient.setQueryData<ConversationModel>(\n        getConversationQueryKey(conversation.app_id, conversation.conversation_pid),\n        (current) => ({\n            ...(current ?? buildInitialConversationModel(conversation)),\n            history: \"new-chat\",\n        })\n    );\n};\n\nconst getConversationQueryOptions = (appId: AppId, conversationPid: ConversationPid) =>\n    queryOptions({\n        queryKey: getConversationQueryKey(appId, conversationPid),\n        queryFn: async () => {\n            const { conversation, events } = await getConversation(conversationPid);\n            updateConversationListQuery(appId, (cs) => {\n                const c = cs?.find((c) => c.conversation_pid === conversationPid);\n                if (c) {\n                    Object.assign(c, conversation);\n                }\n            });\n            return buildConversationModel(conversation, events);\n        },\n        // Session updates can populate the cache before history has been fetched.\n        staleTime: (query) => (query.state.data?.history === \"loaded\" ? DEFAULT_QUERY_STALE_TIME : 0),\n        throwOnError: !!__DEV__, // pay attention to this error!\n    });\n\nexport const updateConversationQuery = (\n    queryClient: QueryClient,\n    appId: AppId,\n    conversationPid: ConversationPid,\n    updater: (conv: Draft<ConversationModel>) => void\n) => {\n    queryClient.setQueryData(\n        getConversationQueryKey(appId, conversationPid),\n        produce((conv: ConversationModel | undefined) => {\n            if (!conv) {\n                conv = createConversationModel();\n            }\n            try {\n                updater(conv);\n            } catch (e) {\n                console.error(e);\n                throw e;\n            }\n            return conv;\n        })\n    );\n};\n\nexport const ingestAgentSessionUpdate = (\n    queryClient: QueryClient,\n    dispatch: AnvilDispatch,\n    appId: AppId,\n    event: WebsocketEvent\n) => {\n    const agentType = queryClient\n        .getQueryData<ConversationInfo[]>(getConversationListQueryKey(appId))\n        ?.find((c) => c.conversation_pid === event.conversation_pid)?.agent_type;\n    updateConversationQuery(queryClient, appId, event.conversation_pid, (conv) => {\n        conv.sessionStatus = event.status;\n        if (\"config\" in event) {\n            applyConversationConfigUpdate(conv, event.config);\n            if (event.status === \"running\" && agentType && !conv.config.pending) {\n                cacheSessionCapabilities(agentType, conv.config);\n            }\n        }\n        if (event.status !== \"needs_auth_to_continue\" && event.status !== \"needs_auth_to_start\") {\n            conv.urlElicitation = null;\n        }\n    });\n    showAgentSessionErrorAlert(queryClient, dispatch, appId, event);\n    ingestConversationInfoUpdate(appId, event.conversation_pid, { session_status: event.status });\n};\n\nexport const useConversation = (conversationPid: ConversationPid) => {\n    const appId = useSelector(getAppId)!;\n    const queryClient = useQueryClient();\n    const {\n        isStale,\n        fetchStatus,\n        failureCount,\n        refetch,\n        data: conversationModel = EMPTY_CONVERSATION_MODEL,\n    } = useQuery({\n        ...getConversationQueryOptions(appId, conversationPid),\n        initialData: () => {\n            const conversation = queryClient\n                .getQueryData<ConversationInfo[]>(getConversationListQueryKey(appId))\n                ?.find((c) => c.conversation_pid === conversationPid);\n            if (!conversation) {\n                return undefined;\n            }\n            return buildInitialConversationModel(conversation);\n        },\n    });\n\n    const dispatch: AnvilDispatch = useDispatch();\n\n    const onWsEvent: EventCallback = useEvent((event) => {\n        //console.log(\"WS event\", event);\n        if (event.conversation_pid === conversationPid) {\n            switch (event.event) {\n                case \"AGENT_EVENT\":\n                    // console.log(\"Conversation event\", conversationEvent);\n                    updateConversationQuery(queryClient, appId, conversationPid, (conv) => {\n                        applyConversationEvent(conv, event.event_data);\n                        if (event.event_data.event_type === \"config_update\" && conv.sessionStatus === \"running\" && !conv.config.pending) {\n                            cacheSessionCapabilities(event.event_data.agent_type, conv.config);\n                        }\n                    });\n                    break;\n                case \"AGENT_EVENT_COMPLETE\":\n                    updateConversationQuery(queryClient, appId, conversationPid, (conv) => {\n                        conv.receivedEventPids[event.event_pid] = true;\n                    });\n                    break;\n                case \"AGENT_SESSION_UPDATE\":\n                    ingestAgentSessionUpdate(queryClient, dispatch, appId, event);\n                    if (event.status === \"running\") {\n                        // We might have just completed ChatGPT OAuth, refresh auth status just in case\n                        refreshAgentAuth(queryClient);\n                    }\n                    break;\n                case \"AGENT_URL_ELICITATION\":\n                    updateConversationQuery(queryClient, appId, conversationPid, (conv) => {\n                        conv.urlElicitation = parseAgentUrlElicitation(event.elicitation);\n                    });\n                    break;\n                case \"AGENT_CONVERSATION_UPDATED\":\n                    ingestConversationInfoUpdate(appId, conversationPid, event.updates);\n                    if (\"pending_prompt\" in event.updates) {\n                        updateConversationQuery(queryClient, appId, conversationPid, (conv) => {\n                            conv.pendingPrompt = event.updates.pending_prompt ?? null;\n                        });\n                    }\n                    break;\n                case \"AGENT_SCHEMA_MIGRATION_APPLIED\":\n                    void dispatch(updateAppSchemaSync());\n                    break;\n            }\n        }\n    });\n\n    const cursors = { conversation_events: { [conversationPid]: conversationModel.latestReceivedEventPid } };\n\n    // Using isStale here: Don't register the websocket listener until we've received the full conversation object and initialised the events (and hence our cursor).\n    useWebsocketEventListener(\n        appId,\n        onWsEvent,\n        undefined,\n        {\n            conversation_session_updates: true,\n            conversation_pid: isStale ? undefined : conversationPid,\n        },\n        cursors\n    );\n\n    const { data: conversationInfo } = useQuery({\n        ...getQueryOptions(appId),\n        select: (conversations) => conversations.find((c) => c.conversation_pid === conversationPid),\n    });\n\n    let historyNotice: ConversationHistoryNotice | null = null;\n    if (conversationModel.history !== \"loaded\") {\n        // A session update can replace query data after a failed fetch without clearing failureCount.\n        if (fetchStatus === \"idle\" && failureCount > 0) {\n            historyNotice = { status: \"failed\", retry: () => void refetch() };\n        } else if (conversationModel.history !== \"new-chat\") {\n            historyNotice = { status: \"loading\" };\n        }\n    }\n\n    return {\n        conversationInfo,\n        conversation: conversationModel,\n        historyNotice,\n    };\n};\n\nexport const useConversationScrolling = (conversation: ConversationModel, conversationPid?: ConversationPid) => {\n    const [showScrollToTop, setShowScrollToTop] = useState(false);\n    const [showScrollToBottom, setShowScrollToBottom] = useState(false);\n\n    const [scrollingToBottom, setScrollingToBottom] = useState(false);\n    const [scrollingToTop, setScrollingToTop] = useState(false);\n\n    const scroller = useRef<HTMLDivElement>(null);\n    const didInitialScrollToEnd = useRef(false);\n    const estimatedTurnHeight = useRemToPixels(4);\n    const turnPaddingStart = useRemToPixels(3);\n    const turnGap = useRemToPixels(2);\n    const showActiveTurn = isTurnActive(conversation);\n    const virtualRows = useMemo<ConversationVirtualRow[]>(() => {\n        const rows: ConversationVirtualRow[] = conversation.turns.map((turn, turnIndex) => {\n            switch (turn.turnType) {\n                case \"prompt\":\n                    return {\n                        kind: \"turn\",\n                        key: `prompt:${turn.promptRequest.event.request_id}`,\n                        turn,\n                    };\n                case \"error\":\n                    return {\n                        kind: \"turn\",\n                        key: `error:${turn.error.request_id ?? turnIndex}`,\n                        turn,\n                    };\n                case \"session_boundary\":\n                    return {\n                        kind: \"turn\",\n                        key: `session_boundary:${turnIndex}`,\n                        turn,\n                    };\n                case \"schema_migration\":\n                    return {\n                        kind: \"turn\",\n                        key: `schema_migration:${turn.eventPid}`,\n                        turn,\n                    };\n            }\n        });\n\n        if (conversation.pendingPrompt) {\n            rows.push({\n                kind: \"pending\",\n                key: `pending:${conversation.pendingPrompt.request_id ?? \"pending\"}`,\n                pendingPrompt: conversation.pendingPrompt,\n            });\n        } else if (conversation.submittingPrompt) {\n            rows.push({\n                kind: \"submitting\",\n                key: `submitting:${conversation.submittingPrompt.request_id ?? \"pending\"}`,\n                submittingPrompt: conversation.submittingPrompt,\n            });\n        }\n\n        if (showActiveTurn && conversation.currentPromptTurnIndex === null) {\n            rows.push({\n                kind: \"active\",\n                key: \"active-turn\",\n            });\n        }\n\n        return rows;\n    }, [conversation.currentPromptTurnIndex, conversation.submittingPrompt, conversation.pendingPrompt, conversation.turns, showActiveTurn]);\n    const virtualRowsRef = useRef(virtualRows);\n    virtualRowsRef.current = virtualRows;\n    const getVirtualRowKey = useCallback((i: number) => virtualRowsRef.current[i]?.key ?? i, []);\n    const itemCount = virtualRows.length;\n\n    const rowVirtualizer = useVirtualizer({\n        count: itemCount,\n        overscan: 6,\n        getScrollElement: () => scroller.current,\n        estimateSize: () => estimatedTurnHeight,\n        paddingStart: turnPaddingStart,\n        gap: turnGap,\n        anchorTo: \"end\",\n        followOnAppend: \"auto\",\n        scrollEndThreshold: SCROLL_END_THRESHOLD_PX,\n        getItemKey: getVirtualRowKey,\n    });\n    const virtualItems = rowVirtualizer.getVirtualItems();\n    const totalSize = rowVirtualizer.getTotalSize();\n\n    const updateScrollAffordances = useEvent((el: HTMLDivElement) => {\n        const isAtTop = el.scrollTop <= 10;\n        const distanceFromBottom = Math.max(el.scrollHeight - el.clientHeight - el.scrollTop, 0);\n        const isAtBottom = distanceFromBottom <= SCROLL_END_THRESHOLD_PX;\n\n        if (scrollingToTop && isAtTop) {\n            setScrollingToTop(false);\n            setShowScrollToTop(!isAtTop);\n        } else {\n            setShowScrollToTop(!isAtTop && !scrollingToTop);\n        }\n        if (scrollingToBottom && isAtBottom) {\n            setScrollingToBottom(false);\n            setShowScrollToBottom(!isAtBottom);\n        } else {\n            setShowScrollToBottom(!isAtBottom && !scrollingToBottom);\n        }\n    });\n\n    const onScroll = useEvent((e: React.UIEvent<HTMLDivElement>) => {\n        updateScrollAffordances(e.currentTarget);\n    });\n\n    const scrollToTop = useEvent(() => {\n        setScrollingToTop(true);\n        setScrollingToBottom(false);\n        const el = scroller.current;\n        if (el) {\n            setShowScrollToBottom(el.scrollTop + el.clientHeight + 10 < el.scrollHeight);\n        }\n        scroller.current?.scrollTo({ top: 0, behavior: \"smooth\" });\n    });\n\n    const scrollToBottomWithOptions = useEvent((behavior: \"auto\" | \"smooth\", trackAnimation: boolean) => {\n        if (trackAnimation) {\n            setScrollingToBottom(true);\n        }\n        setScrollingToTop(false);\n        const el = scroller.current;\n        if (el) {\n            setShowScrollToTop(el.scrollTop > 10);\n        }\n        rowVirtualizer.scrollToEnd({ behavior });\n        requestAnimationFrame(() => {\n            const updatedEl = scroller.current;\n            if (updatedEl) {\n                updateScrollAffordances(updatedEl);\n            }\n        });\n    });\n\n    const scrollToBottom = useEvent(() => {\n        scrollToBottomWithOptions(\"smooth\", true);\n    });\n\n    useLayoutEffect(() => {\n        didInitialScrollToEnd.current = false;\n    }, [conversationPid]);\n\n    useLayoutEffect(() => {\n        if (itemCount === 0 || !scroller.current || didInitialScrollToEnd.current) return;\n        didInitialScrollToEnd.current = true;\n        rowVirtualizer.scrollToEnd({ behavior: \"auto\" });\n    }, [conversationPid, conversation.history, itemCount]);\n\n    useLayoutEffect(() => {\n        const el = scroller.current;\n        if (!el) return;\n        updateScrollAffordances(el);\n    }, [totalSize, virtualItems]);\n\n    return {\n        showScrollToTop,\n        showScrollToBottom,\n        onScroll,\n        scrollToTop,\n        scrollToBottom,\n        scroller,\n        rowVirtualizer,\n        virtualItems,\n        virtualRows,\n        totalSize,\n    };\n};\n\nexport const wakeConversation = async (conversationPid: ConversationPid) => {\n    await ws.call({\n        cmd: \"AGENT_WAKE_CONVERSATION\",\n        conversation_pid: conversationPid,\n    });\n};\n\nexport const onSubmitMessage = async (\n    queryClient: QueryClient,\n    appId: AppId,\n    conversationInfo: ConversationInfo,\n    request: {\n        prompt: PromptRequestMessage[\"prompt\"];\n        interaction_mode: InteractionMode;\n        source?: PromptSource;\n        prompt_id?: string | null;\n    },\n) => {\n    const { prompt, interaction_mode, source = \"conversation\", prompt_id } = request;\n    if (prompt.length === 0) {\n        return;\n    }\n    console.log(\"Submitting message\", prompt);\n    // The server uses prompt_id as the durable request_id, so choosing it here lets an\n    // event that arrives before the RPC reply replace this optimistic prompt by identity.\n    const requestId = prompt_id ?? crypto.randomUUID();\n    let draftInteractionModeId: string | undefined;\n    updateConversationQuery(queryClient, appId!, conversationInfo.conversation_pid, (conv) => {\n        draftInteractionModeId = conv.draftInteractionMode?.id;\n        conv.submittingPrompt = {\n            prompt,\n            interaction_mode,\n            request_id: requestId,\n            draftInteractionModeId,\n        };\n    });\n    try {\n        const msg: PromptRequestMessage = await ws.call({\n            cmd: \"AGENT_PROMPT_REQUEST\",\n            conversation_pid: conversationInfo.conversation_pid,\n            prompt,\n            interaction_mode,\n            source,\n            prompt_id: requestId,\n        });\n        updateConversationQuery(queryClient, appId, conversationInfo.conversation_pid, (conv) => {\n            if (conv.draftInteractionMode?.id === draftInteractionModeId) {\n                conv.draftInteractionMode = null;\n            }\n            for (let i = conv.turns.length - 1; i >= 0; i--) {\n                const t = conv.turns[i];\n                if (t.turnType === \"prompt\" && t.promptRequest.event.request_id === msg.request_id) {\n                    // The prompt we just submitted has already arrived, so don't wait for it.\n                    conv.submittingPrompt = null;\n                    return;\n                }\n            }\n            // The prompt is accepted, but its durable event has not arrived yet.\n            conv.config = normalizeConversationConfig({\n                ...conv.config,\n                interaction_mode: msg.interaction_mode ?? \"build\",\n            });\n            conv.submittingPrompt = msg;\n        });\n    } catch (e) {\n        updateConversationQuery(queryClient, appId, conversationInfo.conversation_pid, (conv) => {\n            conv.submittingPrompt = null;\n        });\n        throw e;\n    }\n};\n\nexport const useConversationCallbacks = (conversationInfo: ConversationInfo) => {\n    const appId = useSelector(getAppId);\n    const queryClient = useQueryClient();\n    const dispatch: AnvilDispatch = useDispatch();\n    return {\n        onSubmitMessage: useEvent(onSubmitMessage.bind(null, queryClient, appId!, conversationInfo!)),\n        onStop: useEvent(async () => {\n            console.log(\"WAKE UP CONVERSATION!\");\n            await ws.call({\n                cmd: \"AGENT_STOP_REQUEST\",\n                conversation_pid: conversationInfo.conversation_pid,\n            });\n        }),\n        onChangeConfig: useEvent(async (config: SessionConfigUpdateByCategory) => {\n            const queryKey = getConversationQueryKey(appId!, conversationInfo.conversation_pid);\n            updateConversationQuery(queryClient, appId!, conversationInfo.conversation_pid, (conv) => {\n                conv.config.pending = true;\n                for (const [category, value] of Object.entries(config)) {\n                    conv.config.session[category] = { ...conv.config.session[category], selectedValue: value };\n                }\n            });\n            const configAfterThisChoice = queryClient.getQueryData<ConversationModel>(queryKey)?.config;\n            try {\n                await ws.call({\n                    cmd: \"AGENT_CONFIG_UPDATE\",\n                    conversation_pid: conversationInfo.conversation_pid,\n                    config,\n                });\n            } catch (error) {\n                // Config updates replace this object. Only undo this failed choice if\n                // no newer choice or provider update has replaced it.\n                if (queryClient.getQueryData<ConversationModel>(queryKey)?.config === configAfterThisChoice) {\n                    updateConversationQuery(queryClient, appId!, conversationInfo.conversation_pid, (conv) => {\n                        conv.config.pending = false;\n                        // A previous snapshot may contain another failed save.\n                        // Clear provisional choices and refetch instead of restoring it.\n                        for (const option of Object.values(conv.config.session)) delete option.selectedValue;\n                    });\n                    void queryClient.invalidateQueries({ queryKey });\n                }\n                dispatch(alert(\"Could not change agent configuration\", error instanceof Error ? error.message : normalizeAgentSessionError(error)));\n            }\n        }),\n        onChangeInteractionMode: useEvent((interactionMode: InteractionMode) => {\n            updateConversationQuery(queryClient, appId!, conversationInfo.conversation_pid, (conv) => {\n                conv.draftInteractionMode = { mode: interactionMode, id: crypto.randomUUID() };\n            });\n        }),\n        onRespondToElicitation: useEvent(async (\n            elicitationId: string,\n            action: \"accept\" | \"decline\" | \"cancel\",\n            content?: Record<string, ElicitationContentValue>,\n        ) => {\n            await ws.call({\n                cmd: \"AGENT_ELICITATION_RESPONSE\",\n                conversation_pid: conversationInfo.conversation_pid,\n                elicitation_id: elicitationId,\n                action,\n                ...(action === \"accept\" ? { content: content ?? {} } : {}),\n            });\n        }),\n        onRespondToPermission: useEvent(async (permissionId: string, optionId?: string) => {\n            await ws.call({\n                cmd: \"AGENT_PERMISSION_RESPONSE\",\n                conversation_pid: conversationInfo.conversation_pid,\n                permission_id: permissionId,\n                ...(optionId ? { option_id: optionId } : {}),\n            });\n        }),\n        onChangeAgentType: useEvent(async (agentType: AgentTypeId) => {\n            if (conversationInfo.agent_type === agentType) {\n                return;\n            }\n            updateConversationQuery(queryClient, conversationInfo.app_id, conversationInfo.conversation_pid, (conv) => {\n                conv.usage = null;\n                // The provider name changes optimistically. Its old live options must\n                // not override the new provider's cached capabilities while it starts.\n                conv.config = normalizeConversationConfig({});\n                conv.sessionStatus = \"pending\";\n                conv.draftInteractionMode = null;\n            });\n            try {\n                await updateConversationInfo(conversationInfo.app_id, conversationInfo.conversation_pid, {\n                    agent_type: agentType,\n                });\n                dispatch(updateUserEditorPrefs(\"defaultAgent\", agentType));\n            } catch (error) {\n                void queryClient.invalidateQueries({ queryKey: getConversationQueryKey(conversationInfo.app_id, conversationInfo.conversation_pid) });\n                const message = error instanceof Error ? error.message : normalizeAgentSessionError(error);\n                dispatch(alert(\"Could not switch agent\", message));\n            }\n        }),\n        doLogin: useEvent(async () => {\n            await ws.call({\n                cmd: \"AGENT_LOGIN_REQUEST\",\n                conversation_pid: conversationInfo.conversation_pid,\n                login_type: \"chatgpt\",\n            });\n            // We're not logged in yet, need to wait until the session goes to \"running\"\n        }),\n        doApiKeyLogin: useEvent(async (apiKey: string, loginType: ApiKeyLoginType) => {\n            if (!apiKey) {\n                return;\n            }\n            await ws.call({\n                cmd: \"AGENT_API_KEY_LOGIN_REQUEST\",\n                conversation_pid: conversationInfo.conversation_pid,\n                login_type: loginType,\n                api_key: apiKey,\n            });\n            // API key has been added to agent_auth\n            refreshAgentAuth(queryClient);\n        }),\n        doLogout: useEvent(async () => {\n            await ws.call({\n                cmd: \"AGENT_LOGOUT_REQUEST\",\n                agent_type: conversationInfo.agent_type,\n                conversation_pid: conversationInfo.conversation_pid,\n            });\n            refreshAgentAuth(queryClient);\n        }),\n    };\n};\n\nexport const isTurnActive = (conversation: ConversationModel) => {\n    return (\n        (conversation.submittingPrompt !== null || conversation.pendingPrompt !== null || conversation.currentPromptTurnIndex !== null) &&\n        (conversation.sessionStatus === \"running\" || conversation.sessionStatus === \"pending\")\n    );\n};\n\nexport const doDisconnectAgent = async (agentType: AgentTypeId) =>\n    await ws.call({\n        cmd: \"AGENT_LOGOUT_REQUEST\",\n        agent_type: agentType,\n    });\n\nexport const useAgentAuth = () =>\n     useQuery<AgentAuthMap>({\n        queryKey: [\"agent-auth\"],\n        queryFn: () => getAgentAuth(),\n    });\n\nexport const refreshAgentAuth = (queryClient: QueryClient) => queryClient.invalidateQueries({ queryKey: [\"agent-auth\"] } );\n","import { EditorState } from \"@codemirror/state\";\nimport type { ConversationPid } from \"@/agent/types\";\n\nexport interface PromptComposerDraftImage {\n    id: string;\n    name: string;\n    mimeType: string;\n    sizeBytes: number;\n    dataUrl: string;\n}\n\nexport type SerializedPromptComposerEditorState = ReturnType<EditorState[\"toJSON\"]>;\n\nexport interface PromptComposerDraft {\n    editorState?: SerializedPromptComposerEditorState;\n    images: PromptComposerDraftImage[];\n}\n\nconst promptComposerDrafts = new Map<ConversationPid, PromptComposerDraft>();\nconst draftStorageKey = (conversationPid: ConversationPid) => `anvil:prompt-draft:${conversationPid}`;\n\nconst persistDraftText = (conversationPid: ConversationPid, text: string) => {\n    try {\n        if (text) {\n            sessionStorage.setItem(draftStorageKey(conversationPid), text);\n        } else {\n            sessionStorage.removeItem(draftStorageKey(conversationPid));\n        }\n    } catch {\n        // Storage can be unavailable or full. Keep the in-memory draft usable.\n    }\n};\n\nconst copyDraft = (draft: PromptComposerDraft): PromptComposerDraft => ({\n    editorState: draft.editorState,\n    images: draft.images.map((image) => ({ ...image })),\n});\n\nconst hasDraftContent = (draft: PromptComposerDraft) => {\n    const doc = draft.editorState?.doc;\n    return (typeof doc === \"string\" && doc.length > 0) || draft.images.length > 0;\n};\n\nexport const getPromptComposerDraft = (conversationPid: ConversationPid): PromptComposerDraft | undefined => {\n    let draft = promptComposerDrafts.get(conversationPid);\n    if (!draft) {\n        try {\n            const text = sessionStorage.getItem(draftStorageKey(conversationPid));\n            if (text) {\n                draft = { editorState: EditorState.create({ doc: text }).toJSON(), images: [] };\n                promptComposerDrafts.set(conversationPid, draft);\n            }\n        } catch {\n            // The composer must still work when browser storage is unavailable.\n        }\n    }\n    return draft ? copyDraft(draft) : undefined;\n};\n\nexport const setPromptComposerDraft = (conversationPid: ConversationPid, draft: PromptComposerDraft) => {\n    // Persist only text: images and undo history can exceed the session storage quota.\n    persistDraftText(conversationPid, draft.editorState?.doc ?? \"\");\n    if (!hasDraftContent(draft)) {\n        promptComposerDrafts.delete(conversationPid);\n        return;\n    }\n    promptComposerDrafts.set(conversationPid, copyDraft(draft));\n};\n\nexport const setPromptComposerDraftEditorState = (\n    conversationPid: ConversationPid,\n    editorState: SerializedPromptComposerEditorState\n) => {\n    setPromptComposerDraft(conversationPid, {\n        editorState,\n        images: getPromptComposerDraft(conversationPid)?.images ?? [],\n    });\n};\n\nexport const setPromptComposerDraftImages = (conversationPid: ConversationPid, images: PromptComposerDraftImage[]) => {\n    setPromptComposerDraft(conversationPid, {\n        editorState: getPromptComposerDraft(conversationPid)?.editorState,\n        images,\n    });\n};\n\nexport const clearPromptComposerDraft = (conversationPid: ConversationPid) => {\n    promptComposerDrafts.delete(conversationPid);\n    persistDraftText(conversationPid, \"\");\n};\n","import { historyField } from \"@codemirror/commands\";\nimport { EditorState, type EditorStateConfig } from \"@codemirror/state\";\nimport { EditorView, keymap, placeholder } from \"@codemirror/view\";\nimport type { ConversationPid } from \"@/agent/types\";\nimport { completionTab } from \"@/code_mirror/autocompletions/autocompletions\";\nimport { basicExtensions, basicKeyMap, scrollBar } from \"@/code_mirror/basic_setup\";\nimport { useEditorView, useUpdateListener } from \"@/code_mirror/utils/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport {\n    clearPromptComposerDraft,\n    getPromptComposerDraft,\n    setPromptComposerDraftEditorState,\n} from \"./promptDraftStore\";\n\nexport * from \"./promptDraftStore\";\n\nconst createPromptComposerState = (conversationPid: ConversationPid) => {\n    const stateObject: EditorStateConfig = {\n        extensions: [\n            basicExtensions,\n            scrollBar,\n            EditorState.allowMultipleSelections.of(false),\n            EditorView.lineWrapping,\n            placeholder(\"Type a message...\"),\n            completionTab,\n            keymap.of(basicKeyMap),\n        ],\n    };\n    const draft = getPromptComposerDraft(conversationPid);\n\n    if (draft?.editorState) {\n        try {\n            return EditorState.fromJSON(draft.editorState, stateObject, { history: historyField });\n        } catch (e) {\n            console.warn(\"Could not restore prompt composer draft\", e);\n            clearPromptComposerDraft(conversationPid);\n        }\n    }\n\n    return EditorState.create(stateObject);\n};\n\nexport const usePromptComposerDraftView = (conversationPid: ConversationPid) => {\n    const view = useEditorView(() => createPromptComposerState(conversationPid), [conversationPid]);\n\n    useUpdateListener(\n        view,\n        (update) => {\n            if (update.docChanged || update.selectionSet) {\n                setPromptComposerDraftEditorState(conversationPid, view.state.toJSON({ history: historyField }));\n            }\n        },\n        [conversationPid]\n    );\n\n    const clearSavedDraft = useEvent(() => {\n        clearPromptComposerDraft(conversationPid);\n    });\n\n    return { view, clearSavedDraft };\n};\n","import type { Diff } from \"@/types/database\";\n\nconst SAFE_CHANGE_TYPES = new Set<Diff[\"type\"]>([\"CREATE_TABLES\", \"ADD_COLUMN\", \"ADD_INDEX\"]);\nconst MAX_SUMMARISED_OPERATIONS = 3;\n\nconst describeCount = (count: number, singular: string, plural: string) =>\n    `${count} ${count === 1 ? singular : plural}`;\n\nconst joinActions = (actions: string[], { pastTense = false } = {}) => {\n    if (actions.length === 0) return pastTense ? \"changed the database schema\" : \"change the database schema\";\n    if (actions.length === 1) return actions[0];\n    return `${actions.slice(0, -1).join(\", \")} and ${actions.at(-1)}`;\n};\n\nconst getSchemaChangeActions = (diff: Diff[], { pastTense = false } = {}) => {\n    const counts = {\n        createTables: 0,\n        deleteTables: 0,\n        updateTables: 0,\n        addColumns: 0,\n        deleteColumns: 0,\n        renameColumns: 0,\n        updateColumns: 0,\n        addIndexes: 0,\n        deleteIndexes: 0,\n        unknownChanges: 0,\n    };\n\n    for (const change of diff) {\n        switch (change.type) {\n            case \"CREATE_TABLES\":\n                counts.createTables += Object.keys(change.tables).length;\n                break;\n            case \"DELETE_TABLE\":\n                counts.deleteTables++;\n                break;\n            case \"UPDATE_TABLE\":\n                counts.updateTables++;\n                break;\n            case \"ADD_COLUMN\":\n                counts.addColumns++;\n                break;\n            case \"DELETE_COLUMN\":\n                counts.deleteColumns++;\n                break;\n            case \"RENAME_COLUMN\":\n                counts.renameColumns++;\n                break;\n            case \"UPDATE_COLUMN\":\n                counts.updateColumns++;\n                break;\n            case \"ADD_INDEX\":\n                counts.addIndexes++;\n                break;\n            case \"DELETE_INDEX\":\n                counts.deleteIndexes++;\n                break;\n            default:\n                counts.unknownChanges++;\n                break;\n        }\n    }\n\n    return [\n        counts.createTables &&\n            `${pastTense ? \"created\" : \"create\"} ${describeCount(counts.createTables, \"new table\", \"new tables\")}`,\n        counts.addColumns &&\n            `${pastTense ? \"added\" : \"add\"} ${describeCount(counts.addColumns, \"new column\", \"new columns\")}`,\n        counts.addIndexes &&\n            `${pastTense ? \"added\" : \"add\"} ${describeCount(counts.addIndexes, \"new index\", \"new indexes\")}`,\n        counts.renameColumns &&\n            `${pastTense ? \"renamed\" : \"rename\"} ${describeCount(counts.renameColumns, \"column\", \"columns\")}`,\n        counts.updateTables &&\n            `${pastTense ? \"updated\" : \"update\"} ${describeCount(counts.updateTables, \"table\", \"tables\")}`,\n        counts.updateColumns &&\n            `${pastTense ? \"updated\" : \"update\"} ${describeCount(counts.updateColumns, \"column\", \"columns\")}`,\n        counts.deleteIndexes &&\n            `${pastTense ? \"deleted\" : \"delete\"} ${describeCount(counts.deleteIndexes, \"index\", \"indexes\")}`,\n        counts.deleteColumns &&\n            `${pastTense ? \"deleted\" : \"delete\"} ${describeCount(counts.deleteColumns, \"column\", \"columns\")}`,\n        counts.deleteTables &&\n            `${pastTense ? \"deleted\" : \"delete\"} ${describeCount(counts.deleteTables, \"table\", \"tables\")}`,\n        counts.unknownChanges &&\n            `${pastTense ? \"made\" : \"make\"} ${describeCount(counts.unknownChanges, \"unknown change\", \"unknown changes\")}`,\n    ].filter((action): action is string => Boolean(action));\n};\n\nexport const canApplySchemaDiffDirectly = (diff: Diff[], safeChangeTypes = SAFE_CHANGE_TYPES) => {\n    const operations = getSchemaChangeActions(diff);\n    return (\n        operations.length > 0 &&\n        operations.length <= MAX_SUMMARISED_OPERATIONS &&\n        diff.every(({ type }) => safeChangeTypes.has(type))\n    );\n};\n\nexport const summariseSchemaDiff = (diff: Diff[], { pastTense = false } = {}) => {\n    const operations = getSchemaChangeActions(diff, { pastTense });\n    const actions = operations.slice(0, MAX_SUMMARISED_OPERATIONS);\n    const otherOperationCount = operations.length - actions.length;\n\n    if (otherOperationCount > 0) {\n        actions.push(`${otherOperationCount} other ${otherOperationCount === 1 ? \"change\" : \"changes\"}`);\n    }\n\n    return joinActions(actions, { pastTense });\n};\n","import type { AgentTypeId } from \"@agent-host/rpc_types\";\nimport type { ConversationConfig, ConversationModel } from \"./types\";\n\n// What a provider offered the last time one of its sessions ran in this browser.\n// The server stores the requested selection (selectedValue); this only lets the composer\n// show the chooser and Plan toggle before the new session has reported its options.\ntype SessionCapabilities = Pick<ConversationConfig, \"session\" | \"interaction_modes\">;\n\nconst storageKey = (agentType: AgentTypeId) => `agent-session-capabilities:${agentType}`;\n\nexport function readSessionCapabilities(agentType: AgentTypeId): SessionCapabilities | undefined {\n    try {\n        return JSON.parse(localStorage.getItem(storageKey(agentType)) ?? \"null\") ?? undefined;\n    } catch {\n        return undefined;\n    }\n}\n\nexport function cacheSessionCapabilities(agentType: AgentTypeId, config: ConversationConfig) {\n    const session = Object.fromEntries(\n        Object.entries(config.session).map(([category, { selectedValue: _selected, ...option }]) => [category, option])\n    );\n    try {\n        localStorage.setItem(storageKey(agentType), JSON.stringify({ session, interaction_modes: config.interaction_modes }));\n    } catch {\n        // Storage may be full or unavailable; the composer just waits for the live session.\n    }\n}\n\n/**\n * The config the composer should display. While the session is starting, cached\n * capabilities stand in for the live options, with the conversation's saved\n * selections preserved for the chooser to display while pending.\n */\nexport function displayedConversationConfig(\n    config: ConversationConfig,\n    { sessionStatus, agentType }: { sessionStatus: ConversationModel[\"sessionStatus\"]; agentType: AgentTypeId }\n): ConversationConfig {\n    if (sessionStatus === \"running\" && !config.pending) return config;\n    const cached = readSessionCapabilities(agentType);\n    if (!cached) return config;\n    const session = { ...cached.session };\n    for (const [category, option] of Object.entries(config.session)) {\n        // Startup can report the default model's effort options before applying\n        // the requested model. Keep the cached label until the request finishes;\n        // the early return above then makes live configuration authoritative.\n        const offered = option.type === \"select\" && option.options.some(entry =>\n            \"value\" in entry ? entry.value === option.selectedValue : entry.options.some(entry => entry.value === option.selectedValue));\n        const base = option.type === \"select\" && (option.selectedValue === undefined || offered)\n            ? option : session[category] ?? option;\n        session[category] =\n            option.selectedValue === undefined\n                ? base\n                : { ...base, selectedValue: option.selectedValue };\n    }\n    return {\n        ...config,\n        session,\n        interaction_modes: [...new Set([...config.interaction_modes, ...cached.interaction_modes])],\n    };\n}\n","import type { ProviderUsage, ProviderUsageWindow, UsageUpdate } from \"@agent-host/rpc_types\";\n\nconst mergeProviderUsage = (\n    current: ProviderUsage | undefined,\n    incoming: ProviderUsage | undefined\n): ProviderUsage | undefined => {\n    if (!incoming) return current;\n\n    const windows = new Map(current?.windows.map((window) => [window.id, window]) ?? []);\n    for (const window of incoming.windows) {\n        windows.set(window.id, window);\n    }\n\n    return {\n        windows: [...windows.values()],\n        credits: incoming.credits ?? current?.credits,\n        extraUsage: incoming.extraUsage ?? current?.extraUsage,\n    };\n};\n\nexport const mergeUsageUpdate = (current: UsageUpdate | null, incoming: UsageUpdate): UsageUpdate => ({\n    ...incoming,\n    providerUsage: mergeProviderUsage(current?.providerUsage, incoming.providerUsage),\n});\n\n// Context usage belongs to the conversation, but replayed account-wide provider limits may be stale.\nexport const dropProviderUsage = (usage: UsageUpdate | null): UsageUpdate | null =>\n    usage ? { ...usage, providerUsage: undefined } : null;\n\nexport const formatTokenCount = (tokens: number): string => {\n    if (tokens >= 1_000_000) return `${Math.round(tokens / 100_000) / 10}m`;\n    if (tokens >= 1_000) return `${Math.round(tokens / 1_000)}k`;\n    return `${tokens}`;\n};\n\nexport const percentUsed = (used: number, size: number): number => {\n    if (size <= 0) return 0;\n    return Math.min(100, Math.max(0, Math.floor((100 * used) / size)));\n};\n\nexport const percentLeft = (usedPercent: number): number => Math.max(0, Math.min(100, Math.round(100 - usedPercent)));\n\nexport const sortedUsageWindows = (windows: ProviderUsageWindow[]): ProviderUsageWindow[] =>\n    [...windows].sort(\n        (a, b) =>\n            (a.durationMins ?? Number.POSITIVE_INFINITY) - (b.durationMins ?? Number.POSITIVE_INFINITY) ||\n            a.label.localeCompare(b.label)\n    );\n\nexport const formatResetTime = (resetsAtEpochSeconds: number): string => {\n    const resetDate = new Date(resetsAtEpochSeconds * 1_000);\n    const now = new Date();\n    const time = resetDate.toLocaleTimeString([], { hour: \"numeric\", minute: \"2-digit\" });\n    if (resetDate.toDateString() === now.toDateString()) return `resets ${time}`;\n    const date = resetDate.toLocaleDateString([], { day: \"numeric\", month: \"short\" });\n    return `resets ${time} on ${date}`;\n};\n","import { type Action, type Diagnostic, type LintSource, forEachDiagnostic } from \"@codemirror/lint\";\nimport { StateEffect } from \"@codemirror/state\";\nimport type { EditorView } from \"@codemirror/view\";\nimport { type LspRange, lspRangeToOffsets } from \"./positions\";\nimport { type PythonQuickFix, applyPythonQuickFix } from \"./quick-fixes\";\n\nexport const refreshPythonDiagnostics = StateEffect.define<null>();\n\nexport interface DiagnosticReport {\n    kind: \"full\";\n    items: { code?: string; range: LspRange; message: string; severity?: number; source?: string }[];\n}\n\nexport type DiagnosticRequest = (\n    view: EditorView,\n    signal: AbortSignal\n) => Promise<\n    | {\n          result: DiagnosticReport;\n          isCurrent(): boolean;\n          effects?: readonly StateEffect<unknown>[];\n          publishMetadata?(): void;\n          quickFixes?: { uri: string; actions: PythonQuickFix[] };\n      }\n    | undefined\n>;\n\nexport function deduplicateHoverActions(diagnostics: readonly Diagnostic[]): Diagnostic[] {\n    const seen = new Set<readonly Action[]>();\n    return diagnostics.map((diagnostic) => {\n        if (!diagnostic.actions?.length) return diagnostic;\n        // Keep actions on every diagnostic in the Problems panel. In a shared hover,\n        // retain the original diagnostic for the first button so CodeMirror can locate it.\n        if (seen.has(diagnostic.actions)) return { ...diagnostic, actions: undefined };\n        seen.add(diagnostic.actions);\n        return diagnostic;\n    });\n}\n\n/** Publish only after both the Python report and accompanying metadata are current. */\nexport function pythonDiagnosticSource(\n    request: DiagnosticRequest,\n    { syntaxDiagnostics = true }: { syntaxDiagnostics?: boolean } = {}\n): LintSource {\n    let pending: AbortController | undefined;\n    return async (view) => {\n        pending?.abort();\n        const controller = (pending = new AbortController());\n        const doc = view.state.doc;\n        const discard = () => {\n            // CodeMirror only checks document identity. A superseded same-document\n            // pull must preserve diagnostics already published by the newer pull.\n            const current: Diagnostic[] = [];\n            forEachDiagnostic(view.state, (diagnostic, from, to) => current.push({ ...diagnostic, from, to }));\n            return current;\n        };\n        try {\n            const answer = await request(view, controller.signal);\n            if (!answer || controller.signal.aborted || view.state.doc !== doc || !answer.isCurrent()) return discard();\n            const { quickFixes } = answer;\n            const diagnosticKey = ({ code, range }: { code?: string; range: LspRange }) =>\n                JSON.stringify([code, range]);\n            const fixesByDiagnostic = new Map<string, Map<string, Action>>();\n            if (quickFixes) {\n                const { uri } = quickFixes;\n                for (const action of quickFixes.actions) {\n                    const fixKey = JSON.stringify([action.title, action.edit]);\n                    const fix: Action = {\n                        name: action.title,\n                        apply: (editor) => {\n                            if (editor === view)\n                                applyPythonQuickFix(editor, { uri, action, isCurrent: answer.isCurrent });\n                        },\n                    };\n                    for (const diagnostic of action.diagnostics) {\n                        const key = diagnosticKey(diagnostic);\n                        let fixes = fixesByDiagnostic.get(key);\n                        if (!fixes) fixesByDiagnostic.set(key, (fixes = new Map()));\n                        fixes.set(fixKey, fix);\n                    }\n                }\n            }\n            // Union variants can have distinct messages for one rule and range.\n            const sharedActions = new Map(Array.from(fixesByDiagnostic, ([key, fixes]) => [key, [...fixes.values()]]));\n            const diagnostics = answer.result.items\n                .filter((item) => syntaxDiagnostics || item.source !== \"ty\" || item.code !== \"invalid-syntax\")\n                .map(\n                    (item): Diagnostic => ({\n                        ...lspRangeToOffsets(view.state, item.range),\n                        message: item.message,\n                        severity:\n                            item.severity === 2\n                                ? \"warning\"\n                                : item.severity === 3 || item.severity === 4\n                                  ? \"info\"\n                                  : \"error\",\n                        source: item.source,\n                        actions: sharedActions.get(diagnosticKey(item)),\n                    })\n                );\n            // Designer's handler/endpoint store must observe the same freshness\n            // decision as the editor widgets and diagnostics.\n            answer.publishMetadata?.();\n            if (answer.effects) view.dispatch({ effects: answer.effects });\n            return diagnostics;\n        } catch (error) {\n            if (controller.signal.aborted) return discard();\n            throw error;\n        }\n    };\n}\n","import { isolateHistory } from \"@codemirror/commands\";\nimport { ChangeSet, EditorState, Transaction } from \"@codemirror/state\";\nimport { EditorView } from \"@codemirror/view\";\nimport { type LspRange, lspRangeToOffsets } from \"./positions\";\n\nexport interface PythonQuickFix {\n    title: string;\n    diagnostics: { range: LspRange; code?: string }[];\n    edit: { changes: Record<string, { range: LspRange; newText: string }[]> };\n}\n\nexport function applyPythonQuickFix(\n    view: EditorView,\n    { uri, action, isCurrent }: { uri: string; action: PythonQuickFix; isCurrent(): boolean }\n) {\n    if (!isCurrent() || view.state.facet(EditorState.readOnly)) return false;\n    const changes = action.edit.changes;\n    if (Object.keys(changes).some((target) => target !== uri) || !changes[uri]?.length) return false;\n    const edits = changes[uri].map((edit) => ({ ...lspRangeToOffsets(view.state, edit.range), insert: edit.newText }));\n    view.dispatch({\n        changes: ChangeSet.of(edits, view.state.doc.length),\n        annotations: [isolateHistory.of(\"full\"), Transaction.userEvent.of(\"input\")],\n    });\n    view.focus();\n    return true;\n}\n","import { syntaxTree } from \"@codemirror/language\";\nimport { EditorView, ViewPlugin, type ViewUpdate } from \"@codemirror/view\";\n\nexport function jumpCandidateAt(view: EditorView, coords: { x: number; y: number }) {\n    const hit = view.posAndSideAtCoords(coords);\n    if (!hit) return;\n    const token = syntaxTree(view.state).resolveInner(hit.pos, hit.assoc);\n    if (token.name === \"Comment\" || token.from === token.to) return;\n    if (token.name === \"Number\" || token.name === \"Boolean\" || token.name === \"None\" || token.name === \"Ellipsis\")\n        return;\n    const quoted = token.name === \"String\" || token.name === \"Escape\";\n    const candidate = { offset: hit.pos, token, quoted };\n    if (!quoted) return token.firstChild ? undefined : candidate;\n\n    // Quoted annotations, type aliases, subscript keys and call arguments can name a target.\n    for (let context = token.parent; context; context = context.parent) {\n        if (\n            context.name === \"TypeDef\" ||\n            context.name === \"TypeDefinition\" ||\n            (context.name === \"AssignStatement\" && context.getChild(\"TypeDef\")) ||\n            context.name === \"MemberExpression\" ||\n            context.name === \"ArgList\"\n        )\n            return candidate;\n    }\n}\n\nconst pointerClass = \"cm-python-jump-pointer\";\nconst pointerTheme = EditorView.theme({ [`&.${pointerClass} .cm-content`]: { cursor: \"pointer\" } });\n\nexport function pythonJumpPointer(\n    enabled: () => boolean,\n    hasJumpTarget: (view: EditorView, options: { offset: number; signal: AbortSignal }) => Promise<boolean>\n) {\n    return [\n        pointerTheme,\n        ViewPlugin.fromClass(\n            class {\n                private readonly window: Window | null;\n                private coords?: { x: number; y: number };\n                private previewTimer?: ReturnType<typeof setTimeout>;\n                private lookup?: {\n                    from: number;\n                    to: number;\n                    controller: AbortController;\n                };\n\n                constructor(private view: EditorView) {\n                    this.window = view.dom.ownerDocument.defaultView;\n                    // The mouse can rest over an editor while another element has focus.\n                    this.window?.addEventListener(\"keydown\", this.modifierChanged, true);\n                    this.window?.addEventListener(\"keyup\", this.modifierChanged, true);\n                    this.window?.addEventListener(\"blur\", this.leave);\n                    view.dom.addEventListener(\"mousemove\", this.move);\n                    view.dom.addEventListener(\"mouseleave\", this.leave);\n                    view.scrollDOM.addEventListener(\"scroll\", this.clear);\n                }\n\n                private move = (event: MouseEvent) => {\n                    if (!this.view.contentDOM.contains(event.target as Node)) return this.leave();\n                    const previous = this.coords;\n                    const { clientX: x, clientY: y } = event;\n                    this.coords = { x, y };\n                    if (!this.hasJumpModifier(event)) return this.clear();\n                    // Safari emits a mousemove at the same position when Cmd is pressed.\n                    if (previous?.x === x && previous.y === y) return;\n                    if (previous) this.previewAtPointer(75);\n                    else this.scheduleStationaryPreview();\n                };\n\n                private clear = () => {\n                    clearTimeout(this.previewTimer);\n                    this.previewTimer = undefined;\n                    if (!this.lookup) return;\n                    this.lookup.controller.abort();\n                    this.lookup = undefined;\n                    this.view.dom.classList.remove(pointerClass);\n                };\n\n                private leave = () => {\n                    this.coords = undefined;\n                    this.clear();\n                };\n\n                private modifierChanged = (event: KeyboardEvent) => {\n                    if (!this.coords) return;\n                    const isModifier =\n                        event.key === \"Meta\" || event.key === \"Control\" || event.key === \"Alt\" || event.key === \"Shift\";\n                    if (!this.hasJumpModifier(event) || (!isModifier && event.type === \"keydown\")) return this.clear();\n                    if (isModifier) this.scheduleStationaryPreview();\n                };\n\n                private hasJumpModifier(event: MouseEvent | KeyboardEvent) {\n                    return (event.metaKey || event.ctrlKey) && !event.altKey;\n                }\n\n                private scheduleStationaryPreview() {\n                    if (this.previewTimer !== undefined || this.lookup || !enabled()) return;\n                    // Give shortcuts time to complete before asking CodeMirror to measure the editor.\n                    this.previewTimer = setTimeout(() => this.previewAtPointer(0), 200);\n                }\n\n                private previewAtPointer(delay: number) {\n                    if (!this.coords || !enabled()) return this.clear();\n                    const candidate = jumpCandidateAt(this.view, this.coords);\n                    if (!candidate) return this.clear();\n                    const { offset, token } = candidate;\n                    // Other tokens, such as quoted annotations, can have targets at individual offsets.\n                    const { from, to } =\n                        token.name === \"VariableName\" || token.name === \"PropertyName\"\n                            ? token\n                            : { from: offset, to: offset };\n                    if (this.lookup?.from === from && this.lookup.to === to) return;\n                    this.clear();\n                    const controller = new AbortController();\n                    this.lookup = { from, to, controller };\n                    this.previewTimer = setTimeout(async () => {\n                        try {\n                            const found = await hasJumpTarget(this.view, { offset, signal: controller.signal });\n                            if (!controller.signal.aborted && enabled())\n                                this.view.dom.classList.toggle(pointerClass, found);\n                        } catch {\n                            // A speculative lookup can fail while the analysis session refreshes.\n                        }\n                    }, delay);\n                }\n\n                update(update: ViewUpdate) {\n                    if (update.docChanged || update.viewportChanged) this.clear();\n                }\n\n                destroy() {\n                    this.leave();\n                    this.window?.removeEventListener(\"keydown\", this.modifierChanged, true);\n                    this.window?.removeEventListener(\"keyup\", this.modifierChanged, true);\n                    this.window?.removeEventListener(\"blur\", this.leave);\n                    this.view.dom.removeEventListener(\"mousemove\", this.move);\n                    this.view.dom.removeEventListener(\"mouseleave\", this.leave);\n                    this.view.scrollDOM.removeEventListener(\"scroll\", this.clear);\n                }\n            }\n        ),\n    ];\n}\n","import { StateEffect, StateField } from \"@codemirror/state\";\nimport {\n    type EditorView,\n    type Tooltip,\n    ViewPlugin,\n    type ViewUpdate,\n    closeHoverTooltips,\n    keymap,\n    showTooltip,\n} from \"@codemirror/view\";\nimport { pythonHover } from \"./hover\";\nimport { jumpCandidateAt, pythonJumpPointer } from \"./jump-pointer\";\nimport type { EditorToolAction } from \"./session\";\n\nconst setNavigationNotice = StateEffect.define<Tooltip | null>();\n\nconst navigationNotice = StateField.define<Tooltip | null>({\n    create: () => null,\n    update(value, transaction) {\n        for (const effect of transaction.effects) {\n            if (effect.is(setNavigationNotice)) return effect.value;\n        }\n        return transaction.docChanged || transaction.selection ? null : value;\n    },\n    provide: (field) => showTooltip.from(field),\n});\n\n/** Shared by the IDE hook and the real-browser interaction check. */\nexport function pythonEditorTools(options: {\n    enabled(): boolean;\n    /** Returns false when a current lookup completed without a destination. */\n    request(\n        view: EditorView,\n        options: { action: EditorToolAction; offset: number; signal: AbortSignal }\n    ): Promise<void | false>;\n    rename?(view: EditorView, options: { offset: number; signal: AbortSignal }): Promise<void>;\n    hasJumpTarget?(view: EditorView, options: { offset: number; signal: AbortSignal }): Promise<boolean>;\n    hover?: Parameters<typeof pythonHover>[0][\"request\"];\n    onError(error: unknown): void;\n}) {\n    const plugin = ViewPlugin.fromClass(\n        class {\n            private pending?: { controller: AbortController; action: EditorToolAction | \"rename\" };\n            private noticeTimeout?: ReturnType<typeof setTimeout>;\n            private click = (event: MouseEvent) => {\n                if (this.pending?.action === \"jump\") this.pending.controller.abort();\n                if (event.button !== 0 || !(event.ctrlKey || event.metaKey) || event.altKey || !options.enabled())\n                    return;\n                const candidate = jumpCandidateAt(this.view, { x: event.clientX, y: event.clientY });\n                if (!candidate) return;\n                // Only Ty can distinguish a quoted type alias from an ordinary string assignment.\n                if (!candidate.quoted) {\n                    event.preventDefault();\n                    event.stopPropagation();\n                }\n                this.request(\"jump\", candidate.offset);\n            };\n            constructor(private view: EditorView) {\n                view.dom.addEventListener(\"mousedown\", this.click, true);\n            }\n\n            request(action: EditorToolAction | \"rename\", offset: number) {\n                // Close the hover before navigation can resize the editor beneath it.\n                clearTimeout(this.noticeTimeout);\n                this.view.dispatch({ effects: [closeHoverTooltips, setNavigationNotice.of(null)] });\n                this.pending?.controller.abort();\n                const pending = new AbortController();\n                this.pending = { controller: pending, action };\n                const request =\n                    action === \"rename\"\n                        ? options.rename?.(this.view, { offset, signal: pending.signal })\n                        : options.request(this.view, { action, offset, signal: pending.signal });\n                request\n                    ?.then((result) => {\n                        if (result !== false || pending.signal.aborted || action === \"jump\") return;\n                        this.view.dispatch({\n                            effects: setNavigationNotice.of({\n                                pos: offset,\n                                above: true,\n                                create() {\n                                    const dom = document.createElement(\"div\");\n                                    dom.setAttribute(\"role\", \"status\");\n                                    dom.className = \"px-2 py-1\";\n                                    dom.textContent = \"No definition found.\";\n                                    return { dom };\n                                },\n                            }),\n                        });\n                        this.noticeTimeout = setTimeout(() => {\n                            this.view.dispatch({ effects: setNavigationNotice.of(null) });\n                        }, 1800);\n                    })\n                    .catch((error) => {\n                        if (!pending.signal.aborted) options.onError(error);\n                    });\n            }\n\n            update(update: ViewUpdate) {\n                // Prompts can reset the DOM selection when focus returns. F2\n                // already captured its target; outline and symbol search do not\n                // depend on the caret. Only caret navigation becomes obsolete.\n                const followsCaret =\n                    this.pending?.action === \"definition\" ||\n                    this.pending?.action === \"typeDefinition\" ||\n                    this.pending?.action === \"references\";\n                if (update.docChanged || (update.selectionSet && followsCaret)) this.pending?.controller.abort();\n            }\n\n            destroy() {\n                this.pending?.controller.abort();\n                clearTimeout(this.noticeTimeout);\n                this.view.dom.removeEventListener(\"mousedown\", this.click, true);\n            }\n        }\n    );\n    return [\n        plugin,\n        navigationNotice,\n        options.hasJumpTarget ? pythonJumpPointer(options.enabled, options.hasJumpTarget) : [],\n        options.hover\n            ? pythonHover({\n                  enabled: options.enabled,\n                  request: options.hover,\n                  onReferences: (view, offset) => view.plugin(plugin)?.request(\"references\", offset),\n                  onDefinition: (view, offset) => view.plugin(plugin)?.request(\"definition\", offset),\n                  onTypeDefinition: (view, offset) => view.plugin(plugin)?.request(\"typeDefinition\", offset),\n                  onRename: options.rename\n                      ? (view, offset) => view.plugin(plugin)?.request(\"rename\", offset)\n                      : undefined,\n              })\n            : [],\n        keymap.of([\n            {\n                key: \"F2\",\n                run: (view: EditorView) => {\n                    if (!options.enabled() || !options.rename) return false;\n                    view.plugin(plugin)?.request(\"rename\", view.state.selection.main.head);\n                    return true;\n                },\n            },\n            ...(\n                [\n                    [\"F12\", \"definition\"],\n                    [\"Ctrl-Alt-F12\", \"typeDefinition\"],\n                    [\"Shift-F12\", \"references\"],\n                    [\"Ctrl-F12\", \"outline\"],\n                    [\"Ctrl-Shift-F12\", \"symbols\"],\n                ] as const\n            ).map(([key, action]) => ({\n                key,\n                run: (view: EditorView) => {\n                    if (!options.enabled()) return false;\n                    view.plugin(plugin)?.request(action, view.state.selection.main.head);\n                    return true;\n                },\n            })),\n        ]),\n    ];\n}\n","import type { Extension } from \"@codemirror/state\";\nimport { type EditorView, ViewPlugin, hoverTooltip } from \"@codemirror/view\";\nimport { type PythonDocumentation, pythonDocumentationElement } from \"@/code_mirror/autocompletions/info\";\nimport { type LspRange, lspRangeToOffsets } from \"./positions\";\n\nexport interface PythonHover {\n    contents: PythonDocumentation;\n    range?: LspRange;\n    actions?: { definition: boolean; typeDefinition: boolean; rename: boolean };\n}\n\nexport function pythonHover(options: {\n    enabled(): boolean;\n    request(options: {\n        offset: number;\n        signal: AbortSignal;\n    }): Promise<{ result: PythonHover | null; isCurrent(): boolean } | undefined>;\n    onReferences?(view: EditorView, offset: number): void;\n    onDefinition?(view: EditorView, offset: number): void;\n    onTypeDefinition?(view: EditorView, offset: number): void;\n    onRename?(view: EditorView, offset: number): void;\n}): Extension {\n    let pending: AbortController | undefined;\n    return [\n        hoverTooltip(\n            async (view, pos, side) => {\n                pending?.abort();\n                if (!options.enabled()) return null;\n                const controller = (pending = new AbortController());\n                try {\n                    const answer = await options.request({ offset: pos, signal: controller.signal });\n                    if (controller.signal.aborted || !answer?.isCurrent() || !answer.result) return null;\n                    const hover = answer.result;\n                    const selection = hover.range ? lspRangeToOffsets(view.state, hover.range) : view.state.wordAt(pos);\n                    if (!selection || (pos === selection.from && side < 0) || (pos === selection.to && side > 0))\n                        return null;\n                    const onAction = (run: ((view: EditorView, offset: number) => void) | undefined) =>\n                        run\n                            ? () => {\n                                  if (!controller.signal.aborted && options.enabled() && answer.isCurrent())\n                                      run(view, pos);\n                              }\n                            : undefined;\n                    return {\n                        pos: selection.from,\n                        end: selection.to,\n                        above: true,\n                        create: () =>\n                            pythonDocumentationElement({\n                                documentation: hover.contents,\n                                state: view.state,\n                                onGoToDefinition: onAction(\n                                    hover.actions?.definition ? options.onDefinition : undefined\n                                ),\n                                onGoToTypeDefinition: onAction(\n                                    hover.actions?.typeDefinition ? options.onTypeDefinition : undefined\n                                ),\n                                onFindReferences: onAction(options.onReferences),\n                                onRename: onAction(hover.actions?.rename ? options.onRename : undefined),\n                            }),\n                    };\n                } catch (error) {\n                    if (!controller.signal.aborted) console.error(\"Python hover unavailable\", error);\n                    return null;\n                }\n            },\n            { hoverTime: 500, hideOnChange: true }\n        ),\n        ViewPlugin.define(() => ({\n            update(update) {\n                if (update.docChanged) pending?.abort();\n            },\n            destroy() {\n                pending?.abort();\n            },\n        })),\n    ];\n}\n","import { isAtLocation } from \"./positions\";\nimport { type AnalysisLocation, type AnalysisProject, diffAnalysisFiles } from \"./project\";\n\nexport type EditorToolAction = \"definition\" | \"typeDefinition\" | \"references\" | \"outline\" | \"symbols\" | \"jump\";\n\nexport type PythonContext =\n    | { kind: \"repl\"; id: string; isServer: boolean; previousCode: string; code: string }\n    | { kind: \"binding\"; id: string; formUri: string; code: string };\n\ninterface SymbolInformation {\n    name: string;\n    containerName?: string;\n    kind?: number;\n    location: AnalysisLocation;\n}\n\n/** The subset of the browser package used by IDE code tools. No analyzer internals cross this boundary. */\nexport interface BrowserSession {\n    readonly revision: number;\n    updateFiles(files: Record<string, string | null>): Promise<number>;\n    openDocument(uri: string, text: string): Promise<number>;\n    changeDocument(uri: string, text: string): Promise<number>;\n    closeDocument(uri: string): Promise<number>;\n    query<T>(\n        method: string,\n        params: unknown,\n        options?: { signal?: AbortSignal }\n    ): Promise<{ revision: number; result: T }>;\n    readSource?(\n        uri: string,\n        options?: { signal?: AbortSignal }\n    ): Promise<{ revision: number; result: { text: string; readOnly: true } }>;\n    setContext(context: PythonContext): Promise<number>;\n    closeContext(id: string): Promise<number>;\n    queryContext<T>(\n        id: string,\n        method: string,\n        params: unknown,\n        options?: { signal?: AbortSignal }\n    ): Promise<{ revision: number; result: T }>;\n    dispose(): void;\n}\n\nexport interface BrowserSessionModule {\n    BrowserAnalysisSession: new (options: {\n        workerUrl?: string;\n        rootUri: string;\n        files: Record<string, string>;\n        apiStubsUrl?: string;\n    }) => BrowserSession;\n}\n\ntype CompletionTarget = { uri: string } | { contextId: string };\ninterface CompletionPreparation {\n    target: CompletionTarget;\n    signal: AbortSignal;\n    resolve(): void;\n    reject(error: unknown): void;\n}\n\nexport class ProjectAnalysis {\n    private files: Record<string, string>;\n    private documents = new Map<string, string>();\n    private synchronization = Promise.resolve();\n    private completionPreparations = new Set<CompletionPreparation>();\n    private preparingCompletions = false;\n    private completionIdleUntil = 0;\n    private completionTimer: ReturnType<typeof setTimeout> | undefined;\n    private wakeCompletionPreparation: (() => void) | undefined;\n    private disposed = false;\n\n    constructor(\n        readonly session: BrowserSession,\n        project: AnalysisProject\n    ) {\n        this.files = project.files;\n    }\n\n    synchronize(project: AnalysisProject, documents: Map<string, string>) {\n        const snapshot = new Map(documents);\n        const pending = this.synchronization.then(() => this.synchronizeSnapshot(project, snapshot));\n        this.synchronization = pending.catch(() => {});\n        return pending;\n    }\n\n    private async synchronizeSnapshot(project: AnalysisProject, documents: Map<string, string>) {\n        const changes = diffAnalysisFiles(this.files, project.files);\n        if (Object.keys(changes).length) {\n            await this.session.updateFiles(changes);\n            this.files = project.files;\n        }\n        for (const uri of this.documents.keys()) {\n            if (!documents.has(uri)) {\n                await this.session.closeDocument(uri);\n                this.documents.delete(uri);\n            }\n        }\n        for (const [uri, code] of documents) {\n            if (!this.documents.has(uri)) await this.session.openDocument(uri, code);\n            else if (this.documents.get(uri) !== code) await this.session.changeDocument(uri, code);\n            this.documents.set(uri, code);\n        }\n    }\n\n    /** Typing takes priority over the next background batch, including while a batch is in flight. */\n    pauseCompletionPreparation() {\n        this.completionIdleUntil = performance.now() + 100;\n    }\n\n    async completions<T>(\n        target: CompletionTarget,\n        position: { line: number; character: number },\n        { autoImport, signal }: { autoImport?: false | \"only\"; signal: AbortSignal }\n    ): Promise<{ revision: number; result: T }> {\n        if (autoImport !== \"only\") this.pauseCompletionPreparation();\n        for (;;) {\n            if (autoImport === \"only\") await this.prepareCompletions(target, { signal });\n            const params = { position, context: { autoImport } };\n            const response =\n                \"uri\" in target\n                    ? await this.session.query<T>(\n                          \"textDocument/completion\",\n                          { ...params, textDocument: { uri: target.uri } },\n                          { signal }\n                      )\n                    : await this.session.queryContext<T>(target.contextId, \"textDocument/completion\", params, {\n                          signal,\n                      });\n            const result = response.result;\n            // A lazy library load or a changed module catalogue can replace the\n            // workspace between preparation and this query. Never run its cold search.\n            if (\n                autoImport !== \"only\" ||\n                !result ||\n                typeof result !== \"object\" ||\n                !(\"preparationRequired\" in result) ||\n                !result.preparationRequired\n            )\n                return response;\n        }\n    }\n\n    prepareCompletions(target: CompletionTarget, { signal }: { signal: AbortSignal }): Promise<void> {\n        if (signal.aborted) return Promise.reject(signal.reason);\n        if (this.disposed) return Promise.reject(new DOMException(\"Analysis session is disposed\", \"AbortError\"));\n        return new Promise((resolve, reject) => {\n            const finish = () => {\n                signal.removeEventListener(\"abort\", abort);\n                this.completionPreparations.delete(job);\n            };\n            const job: CompletionPreparation = {\n                target,\n                signal,\n                resolve: () => {\n                    finish();\n                    resolve();\n                },\n                reject: (error) => {\n                    finish();\n                    reject(error);\n                },\n            };\n            const abort = () => job.reject(signal.reason);\n            signal.addEventListener(\"abort\", abort, { once: true });\n            this.completionPreparations.add(job);\n            void this.runCompletionPreparation();\n        });\n    }\n\n    private async runCompletionPreparation() {\n        if (this.preparingCompletions) return;\n        this.preparingCompletions = true;\n        try {\n            while (this.completionPreparations.size) {\n                // One batch at a time, with an event-loop yield for edits and foreground queries.\n                await new Promise<void>((resolve) => {\n                    this.wakeCompletionPreparation = resolve;\n                    this.completionTimer = setTimeout(\n                        resolve,\n                        Math.max(0, this.completionIdleUntil - performance.now())\n                    );\n                });\n                this.completionTimer = undefined;\n                this.wakeCompletionPreparation = undefined;\n                if (performance.now() < this.completionIdleUntil) continue;\n                const job = this.completionPreparations.values().next().value;\n                if (!job) break;\n                try {\n                    const { target, signal } = job;\n                    const response =\n                        \"uri\" in target\n                            ? await this.session.query<{ complete: boolean }>(\n                                  \"anvil/prepareCompletion\",\n                                  { textDocument: { uri: target.uri } },\n                                  { signal }\n                              )\n                            : await this.session.queryContext<{ complete: boolean }>(\n                                  target.contextId,\n                                  \"anvil/prepareCompletion\",\n                                  {},\n                                  { signal }\n                              );\n                    if (response.result.complete) job.resolve();\n                } catch (error) {\n                    job.reject(error);\n                }\n            }\n        } finally {\n            this.preparingCompletions = false;\n        }\n    }\n\n    async targets(\n        action: Exclude<EditorToolAction, \"jump\">,\n        uri: string,\n        options: { position: { line: number; character: number }; signal: AbortSignal; query?: string }\n    ) {\n        const method = {\n            definition: \"textDocument/definition\",\n            typeDefinition: \"textDocument/typeDefinition\",\n            references: \"textDocument/references\",\n            outline: \"textDocument/documentSymbol\",\n            symbols: \"workspace/symbol\",\n        }[action];\n        const params =\n            action === \"symbols\"\n                ? { query: options.query ?? \"\" }\n                : {\n                      textDocument: { uri },\n                      ...(action === \"outline\" ? {} : { position: options.position }),\n                      ...(action === \"references\"\n                          ? { context: { includeDeclaration: false, includeImports: false } }\n                          : {}),\n                  };\n        const response = await this.session.query<AnalysisLocation[] | AnalysisLocation | SymbolInformation[] | null>(\n            method,\n            params,\n            { signal: options.signal }\n        );\n        if (response.revision !== this.session.revision) return undefined;\n        const results = response.result ? (Array.isArray(response.result) ? response.result : [response.result]) : [];\n        const targets = results.map((result) =>\n            \"location\" in result\n                ? {\n                      ...result.location,\n                      name: result.name,\n                      containerName: result.containerName,\n                      kind: result.kind,\n                  }\n                : { ...result, name: undefined, containerName: undefined, kind: undefined }\n        );\n        const readSource = this.session.readSource?.bind(this.session);\n        if (!readSource) return targets;\n        // Many outline entries can share one large stub. Read its source once\n        // for this result set rather than copying it through the worker per symbol.\n        const sources = new Map<string, ReturnType<NonNullable<BrowserSession[\"readSource\"]>>>();\n        const readable = await Promise.all(\n            targets.map(async (target) => {\n                if (\n                    this.files[decodeURIComponent(new URL(target.uri).pathname)] !== undefined &&\n                    !target.uri.endsWith(\".pyi\")\n                )\n                    return target;\n                let pending = sources.get(target.uri);\n                if (!pending) sources.set(target.uri, (pending = readSource(target.uri, { signal: options.signal })));\n                const source = await pending;\n                return { ...target, source: source.result };\n            })\n        );\n        return response.revision === this.session.revision ? readable : undefined;\n    }\n\n    /** Modifier-click on a definition reverses the usual direction to its usages. */\n    async jump(uri: string, options: { position: { line: number; character: number }; signal: AbortSignal }) {\n        const definitions = await this.targets(\"definition\", uri, options);\n        if (!definitions) return undefined;\n        const atDefinition = definitions.some((target) => isAtLocation(target, uri, options.position));\n        if (!atDefinition) return { action: \"definition\" as const, targets: definitions };\n        const references = await this.targets(\"references\", uri, options);\n        return references && { action: \"references\" as const, targets: references };\n    }\n\n    dispose() {\n        this.disposed = true;\n        for (const job of this.completionPreparations)\n            job.reject(new DOMException(\"Analysis session is disposed\", \"AbortError\"));\n        clearTimeout(this.completionTimer);\n        this.wakeCompletionPreparation?.();\n        this.session.dispose();\n    }\n}\n","import type { EditorView } from \"@codemirror/view\";\nimport { getCachedCodeItem, getForms, getModules, getServerModules } from \"@/controllers/app/code\";\nimport { getDebugEnvironmentTableMapping, getDebugEnvironmentTables } from \"@/controllers/db\";\nimport { getUser } from \"@/controllers/ide\";\nimport { getUserTabSize } from \"@/controllers/user\";\nimport type { AnvilAsyncAction, CodePath, EditorPath, State } from \"@/types\";\nimport { getAbTyAnalysis } from \"@/util/hooks/ab-flags\";\nimport { getServerPythonMinorVersion } from \"@/util/python-version\";\nimport type { PythonHover } from \"./hover\";\nimport type { PythonItemMetadata } from \"./metadata\";\nimport { type LspRange, isAtLocation } from \"./positions\";\nimport {\n    type AnalysisItem,\n    type AnalysisLocation,\n    type AnalysisProject,\n    type AnalysisProjectKind,\n    analysisProjectKind,\n    buildAnalysisProject,\n    diffAnalysisFiles,\n    pythonSourceUri,\n    sourceForLocation,\n} from \"./project\";\nimport { type EditorToolAction, ProjectAnalysis, type PythonContext } from \"./session\";\n\nexport type CodeTarget = NonNullable<ReturnType<typeof sourceForLocation>> & {\n    uri: string;\n    symbol?: string;\n    containerName?: string;\n    kind?: number;\n    range?: import(\"./project\").AnalysisLocation[\"range\"];\n};\n\nexport function getTyAnalysisEnabled(state: State) {\n    return getAbTyAnalysis(state);\n}\n\nconst editors = new Map<EditorView, { codePath: EditorPath; appId: string | undefined }>();\nexport function getAnalysisEditors(appId: string) {\n    return [...editors].filter(([, registration]) => registration.appId === appId);\n}\n\nconst contexts = new Map<EditorView, { id: string; appId: string | undefined }>();\nconst designers = new Set<{ appId: string }>();\nconst sourceEditors = new Map<EditorView, { uri: string; appId: string | undefined }>();\n\nexport function registerReadOnlySource(view: EditorView, uri: string, appId: string | undefined) {\n    sourceEditors.set(view, { uri, appId });\n    return () => {\n        sourceEditors.delete(view);\n        disposeUnusedAnalysis();\n    };\n}\n\nexport function getReadOnlySourceEditor(appId: string, uri: string) {\n    return [...sourceEditors].find(([, source]) => source.appId === appId && source.uri === uri)?.[0];\n}\n// Task discovery and app metadata can outlive the last code tab. Pending requests\n// keep shared workers alive until every request has settled.\nlet pendingProjectQueries = 0;\nconst projectCache = new Map<AnalysisProjectKind, { inputs: unknown[]; project: AnalysisProject }>();\n// Test-only packages and requirements must not change the app's import environment.\nconst owners = new Map<AnalysisProjectKind, { appId: string; analysis: Promise<ProjectAnalysis> }>();\n\nfunction disposeAnalysis(projectKind?: AnalysisProjectKind) {\n    for (const kind of projectKind ? [projectKind] : [...owners.keys()]) {\n        const previous = owners.get(kind);\n        owners.delete(kind);\n        previous?.analysis.then(\n            (analysis) => analysis.dispose(),\n            () => {}\n        );\n    }\n}\n\nfunction disposeUnusedAnalysis() {\n    for (const kind of [\"app\", \"serverTests\"] as const) {\n        if (\n            pendingProjectQueries ||\n            (kind === \"app\" && (contexts.size || designers.size)) ||\n            [...editors.values()].some((editor) => analysisProjectKind(editor.codePath) === kind) ||\n            [...sourceEditors.values()].some((editor) => analysisProjectKind(editor.uri) === kind)\n        )\n            continue;\n        projectCache.delete(kind);\n        disposeAnalysis(kind);\n    }\n}\n\nexport function registerAnalysisDesigner(appId: string) {\n    const designer = { appId };\n    designers.add(designer);\n    return () => {\n        designers.delete(designer);\n        disposeUnusedAnalysis();\n    };\n}\n\nexport function registerAnalysisEditor(view: EditorView, codePath: EditorPath, appId: string | undefined) {\n    editors.set(view, { codePath, appId });\n    return () => {\n        editors.delete(view);\n        disposeUnusedAnalysis();\n    };\n}\n\nexport function registerAnalysisContext(view: EditorView, id: string, appId: string | undefined) {\n    contexts.set(view, { id, appId });\n    return () => {\n        contexts.delete(view);\n        const currentOwner = owners.get(\"app\");\n        if (currentOwner && currentOwner.appId === appId) {\n            void currentOwner.analysis.then((analysis) => analysis.session.closeContext(id)).catch(() => {});\n        }\n        disposeUnusedAnalysis();\n    };\n}\n\n/** Inputs whose changes require a new app analysis snapshot, including Designer notifications. */\nexport function getAnalysisInputs(state: State): unknown[] {\n    const app = state.app;\n    if (!app) return [];\n    return [\n        app.id,\n        app.config,\n        app.initialCode,\n        app.codeStructure,\n        app.dependencyCode,\n        getUser(state)?.python_environment_catalog,\n        state.itemCache,\n        state.editor.designer?.jsCustomComponents,\n        state.editor.sequenceNumbers,\n        getDebugEnvironmentTables(state),\n        getDebugEnvironmentTableMapping(state)?.schema,\n        getUserTabSize(state),\n    ];\n}\n\n/** Authoritative unopened app items; callers may add live editor overlays. */\nexport function getAnalysisItems(state: State): AnalysisItem[] {\n    const app = state.app;\n    if (!app) return [];\n    const items: AnalysisItem[] = [];\n    for (const [structures, group, itemType] of [\n        [getForms(state), app.initialCode.forms, \"form\"],\n        [getModules(state), app.initialCode.modules, \"module\"],\n        [getServerModules(state), app.initialCode.server_modules, \"server_module\"],\n    ] as const) {\n        for (const structure of structures) {\n            const cached = getCachedCodeItem(structure.codePath, state);\n            if (cached.deleted) continue;\n            const item =\n                cached.item ||\n                group.find((item) => item.id === structure.id || (item.class_name || item.name) === structure.fullName);\n            if (!item) throw new Error(`Code unavailable: ${structure.fullName}`);\n            if (typeof item.code !== \"string\") throw new Error(`Code unavailable: ${structure.fullName}`);\n            items.push({ codePath: structure.codePath, itemType, item: { ...item, code: item.code } });\n        }\n    }\n    return items;\n}\n\nfunction collectProject(state: State, projectKind: AnalysisProjectKind = \"app\") {\n    const app = state.app;\n    if (!app) throw new Error(\"No app open\");\n    // Cached Designer objects mutate outside Redux, but every notified edit\n    // advances editor.sequenceNumbers. Other inputs use Redux/selector identity.\n    // Typing overlays stay separate, so unchanged HTML need not be serialized.\n    const tables = getDebugEnvironmentTables(state);\n    const inputs = getAnalysisInputs(state);\n    const cached = projectCache.get(projectKind);\n    if (cached && inputs.every((input, index) => input === cached.inputs[index])) return cached.project;\n    const items = getAnalysisItems(state);\n    const project = buildAnalysisProject({\n        kind: projectKind,\n        // Match the running debug environment, including a database whose schema differs from the app's.\n        config: { ...app.config, db_schema: getDebugEnvironmentTableMapping(state)?.schema ?? app.config.db_schema },\n        items,\n        dependencies: app.dependencyCode,\n        serverPythonMinorVersion: getServerPythonMinorVersion(\n            app.config.runtime_options,\n            getUser(state)?.python_environment_catalog\n        ),\n        serverBundledRequirements: getUser(state)?.python_environment_catalog?.find(\n            (image) => image.base === app.config.runtime_options?.server_spec?.base\n        )?.migration_requirements,\n        jsComponents: state.editor.designer?.jsCustomComponents,\n        tables,\n    });\n    projectCache.set(projectKind, { inputs, project });\n    return project;\n}\n\nfunction collectDocuments(project: ReturnType<typeof collectProject>, appId: string) {\n    const documents = new Map<string, string>();\n    for (const [editor, registration] of editors) {\n        if (registration.appId !== appId) continue;\n        const uri = project.uris[registration.codePath];\n        if (uri) documents.set(uri, editor.state.doc.toString());\n    }\n    return documents;\n}\n\n/** Effective project files for a saved UI result, without retaining a worker/request. */\nexport function getAnalysisFiles(state: State, source?: string) {\n    const project = collectProject(state, analysisProjectKind(source));\n    const files = { ...project.files };\n    for (const [uri, code] of collectDocuments(project, state.app!.id))\n        files[decodeURIComponent(new URL(uri).pathname)] = code;\n    return files;\n}\n\nfunction withPythonAnalysis<T>(\n    view: EditorView | undefined,\n    source: EditorPath | ((project: AnalysisProject) => PythonContext) | undefined,\n    {\n        offset,\n        signal,\n        completionActivity,\n        projectKind: requestedProjectKind,\n        request,\n    }: {\n        offset: number;\n        signal: AbortSignal;\n        completionActivity?: boolean;\n        projectKind?: AnalysisProjectKind;\n        request(\n            analysis: ProjectAnalysis,\n            source: { uri: string } | { context: PythonContext } | { project: true },\n            position: { line: number; character: number },\n            options: { project: AnalysisProject }\n        ): Promise<T | undefined>;\n    }\n): AnvilAsyncAction<{ result: T; project: ReturnType<typeof collectProject>; isCurrent(): boolean } | undefined> {\n    return async (_dispatch, getState) => {\n        const state = getState();\n        const appId = state.app?.id;\n        if (!appId || !getTyAnalysisEnabled(state)) return undefined;\n        const projectKind =\n            requestedProjectKind ??\n            analysisProjectKind(typeof source === \"string\" ? source : view && sourceEditors.get(view)?.uri);\n        const project = collectProject(state, projectKind);\n        const documents = collectDocuments(project, appId);\n        let input: { uri: string } | { context: PythonContext } | { project: true };\n        if (typeof source === \"string\") {\n            const uri = project.uris[source];\n            if (!uri) throw new Error(\"Analysis is available for app Forms and Python modules.\");\n            input = { uri };\n        } else if (source) {\n            input = { context: source(project) };\n        } else {\n            input = { project: true };\n        }\n        // Closing a context can happen while synchronization is pending. Its\n        // registration, rather than a queued close, owns whether it may open.\n        const contextIsRegistered = () =>\n            !(\"context\" in input) || (view && contexts.get(view)?.id === input.context.id);\n        const originalDoc = view?.state.doc;\n        const line = originalDoc?.lineAt(offset);\n        if ([...owners.values()].some((owner) => owner.appId !== appId)) disposeAnalysis();\n        if (!owners.has(projectKind)) {\n            owners.set(projectKind, {\n                appId,\n                analysis: import(\"./browser-session\").then(\n                    (module) =>\n                        new ProjectAnalysis(\n                            new module.BrowserAnalysisSession({\n                                rootUri: project.rootUri,\n                                files: project.files,\n                                apiStubsUrl: module.apiStubsUrl,\n                            }),\n                            project\n                        )\n                ),\n            });\n        }\n        const currentOwner = owners.get(projectKind)!;\n        const result = await currentOwner.analysis\n            .then(async (analysis) => {\n                if (completionActivity) analysis.pauseCompletionPreparation();\n                await analysis.synchronize(project, documents);\n                if (signal.aborted || !contextIsRegistered() || owners.get(projectKind) !== currentOwner)\n                    return undefined;\n                // Library tabs retain their view while refreshed metadata is loading.\n                // Never interpret an old displayed position against newer library text.\n                const library = view && sourceEditors.get(view);\n                if (view && library && analysis.session.readSource) {\n                    // Dependency tabs use the project's original source, as readPythonSource does.\n                    // The analysis copy can contain type-only compatibility annotations.\n                    const source =\n                        project.sources[library.uri]?.code ??\n                        (await analysis.session.readSource(library.uri, { signal })).result.text;\n                    if (!originalDoc || !view.state.toText(source).eq(originalDoc)) return undefined;\n                }\n                return request(\n                    analysis,\n                    input,\n                    line ? { line: line.number - 1, character: offset - line.from } : { line: 0, character: 0 },\n                    { project }\n                );\n            })\n            .catch((error) => {\n                if (\n                    signal.aborted ||\n                    !contextIsRegistered() ||\n                    (error instanceof Error && error.name === \"AbortError\") ||\n                    owners.get(projectKind) !== currentOwner ||\n                    getState().app?.id !== appId\n                )\n                    return undefined;\n                throw error;\n            });\n        const isCurrent = () => {\n            // Recheck metadata and live editors again if a result picker stays open.\n            if (\n                signal.aborted ||\n                !contextIsRegistered() ||\n                owners.get(projectKind) !== currentOwner ||\n                getState().app?.id !== appId ||\n                !getTyAnalysisEnabled(getState())\n            )\n                return false;\n            if (view && view.state.doc !== originalDoc) return false;\n            const latest = collectProject(getState(), projectKind);\n            if (\n                typeof source === \"function\" &&\n                \"context\" in input &&\n                JSON.stringify(source(latest)) !== JSON.stringify(input.context)\n            )\n                return false;\n            const currentDocuments = collectDocuments(latest, appId);\n            if (currentDocuments.size !== documents.size) return false;\n            for (const [uri, code] of documents) if (currentDocuments.get(uri) !== code) return false;\n            // Autosave updates the stored source underneath an unchanged live\n            // overlay. The analyzer already used that overlay, so its answer\n            // remains valid. Other file changes and removals still invalidate it.\n            for (const path of Object.keys(diffAnalysisFiles(project.files, latest.files))) {\n                if (latest.files[path] === undefined || !documents.has(pythonSourceUri(path))) return false;\n            }\n            return true;\n        };\n        if (result === undefined || !isCurrent()) return undefined;\n        return { result, project, isCurrent };\n    };\n}\n\n/** Scheduled-task discovery also works when every code tab is closed. A query\n * without a live consumer releases its workers after mapping original sources. */\nexport const getPythonBackgroundTasks =\n    (): AnvilAsyncAction<{ name: string; moduleName: string }[]> => async (dispatch, getState) => {\n        pendingProjectQueries++;\n        try {\n            const signal = new AbortController().signal;\n            const answer = await dispatch(\n                withPythonAnalysis<{ name: string; filePath: string }[]>(undefined, undefined, {\n                    offset: 0,\n                    signal,\n                    request: async (analysis) => {\n                        const response = await analysis.session.query<{ name: string; filePath: string }[]>(\n                            \"anvil/getBackgroundTasks\",\n                            {},\n                            { signal }\n                        );\n                        return response.revision === analysis.session.revision ? response.result : undefined;\n                    },\n                })\n            );\n            if (!answer) throw new Error(\"App changed while discovering background tasks. Retry.\");\n            const app = getState().app!;\n            return answer.result\n                .flatMap((task) => {\n                    const source = answer.project.sources[new URL(`file://${task.filePath}`).href];\n                    if (!source || (source.dependencyId && task.name.startsWith(\"_\"))) return [];\n                    const config = source.dependencyId ? app.dependencyCode[source.dependencyId] : app.config;\n                    return [\n                        { name: task.name, moduleName: `${config.package_name || \"main_app_package\"}.${source.label}` },\n                    ];\n                })\n                .sort((a, b) => a.name.localeCompare(b.name));\n        } finally {\n            pendingProjectQueries--;\n            disposeUnusedAnalysis();\n        }\n    };\n\n/** Initialize unopened Forms and server panels in one worker request. Publish\n * while the shared session is still owned, including when no editor is open. */\nexport const refreshPythonAppMetadata =\n    (publish: (project: AnalysisProject, items: (PythonItemMetadata & { uri: string })[]) => void): AnvilAsyncAction =>\n    async (dispatch) => {\n        pendingProjectQueries++;\n        try {\n            const signal = new AbortController().signal;\n            const answer = await dispatch(\n                withPythonAnalysis<(PythonItemMetadata & { uri: string })[]>(undefined, undefined, {\n                    offset: 0,\n                    signal,\n                    request: async (analysis, _input, _position, { project }) => {\n                        const uris = Object.entries(project.sources)\n                            .filter(\n                                ([, source]) =>\n                                    source.codePath?.startsWith(\"forms/\") ||\n                                    source.codePath?.startsWith(\"server_modules/\")\n                            )\n                            .map(([uri]) => uri);\n                        const response = await analysis.session.query<(PythonItemMetadata & { uri: string })[]>(\n                            \"anvil/getAppMetadata\",\n                            { uris },\n                            { signal }\n                        );\n                        return response.revision === analysis.session.revision ? response.result : undefined;\n                    },\n                })\n            );\n            if (answer?.isCurrent()) publish(answer.project, answer.result);\n        } finally {\n            pendingProjectQueries--;\n            disposeUnusedAnalysis();\n        }\n    };\n\nexport const findPythonTargets =\n    (\n        view: EditorView,\n        codePath: EditorPath | undefined,\n        options: { action: EditorToolAction; offset: number; signal: AbortSignal; query?: string; uri?: string }\n    ): AnvilAsyncAction<\n        | {\n              action: Exclude<EditorToolAction, \"jump\">;\n              targets: (CodeTarget | undefined)[];\n              isCurrent(): boolean;\n          }\n        | undefined\n    > =>\n    async (dispatch, getState) => {\n        const answer = await dispatch(\n            withPythonAnalysis(view, codePath, {\n                ...options,\n                request: async (analysis, input, position) => {\n                    const uri = options.uri ?? (\"uri\" in input ? input.uri : undefined);\n                    if (!uri) throw new Error(\"Missing analysis document\");\n                    if (options.action === \"jump\") return analysis.jump(uri, { ...options, position });\n                    const targets = await analysis.targets(options.action, uri, { ...options, position });\n                    return targets && { action: options.action, targets };\n                },\n            })\n        );\n        if (!answer) return undefined;\n        const documents = new Map(\n            getAnalysisEditors(getState().app!.id).map(([editor, registration]) => [\n                registration.codePath,\n                editor.state.doc.toString(),\n            ])\n        );\n        const targets = answer.result.targets.map((location) => {\n            const source = sourceForLocation(answer.project, location);\n            return source\n                ? {\n                      ...source,\n                      code: source.codePath ? (documents.get(source.codePath) ?? source.code) : source.code,\n                      uri: location.uri,\n                      symbol: location.name,\n                      containerName: location.containerName,\n                      kind: location.kind,\n                      range: location.range,\n                  }\n                : undefined;\n        });\n        // Symbol search lists original sources. Definitions/references retain unmapped\n        // results so the UI cannot silently present an incomplete answer.\n        return {\n            action: answer.result.action,\n            targets:\n                options.action === \"symbols\" || options.action === \"outline\"\n                    ? targets.filter((target) => !!target)\n                    : targets,\n            isCurrent: answer.isCurrent,\n        };\n    };\n\n/** Read-only tabs can reload a source independently of the editor that opened them. */\nexport const readPythonSource =\n    (uri: string, { signal }: { signal: AbortSignal }): AnvilAsyncAction<string> =>\n    async (dispatch, getState) => {\n        const state = getState();\n        const cached = state.app && collectProject(state, analysisProjectKind(uri)).sources[uri];\n        if (cached) return cached.code;\n        pendingProjectQueries++;\n        try {\n            const answer = await dispatch(\n                withPythonAnalysis<string>(undefined, undefined, {\n                    projectKind: analysisProjectKind(uri),\n                    offset: 0,\n                    signal,\n                    request: async (analysis) => {\n                        if (!analysis.session.readSource)\n                            throw new Error(\"This analysis backend cannot read library sources.\");\n                        const response = await analysis.session.readSource(uri, { signal });\n                        return response.revision === analysis.session.revision ? response.result.text : undefined;\n                    },\n                })\n            );\n            if (!answer) throw new Error(\"Source unavailable in the current app version.\");\n            return answer.result;\n        } finally {\n            pendingProjectQueries--;\n            disposeUnusedAnalysis();\n        }\n    };\n\nexport const requestPython = <T>(\n    view: EditorView,\n    codePath: EditorPath | undefined,\n    options: {\n        method: string;\n        offset: number;\n        signal: AbortSignal;\n        params?: unknown;\n        uri?: string;\n        range?: LspRange;\n        autoImport?: false | \"only\";\n    }\n): AnvilAsyncAction<{ result: T; project: AnalysisProject; isCurrent(): boolean } | undefined> =>\n    withPythonAnalysis<T>(view, codePath, {\n        ...options,\n        completionActivity: options.method === \"textDocument/completion\" && options.autoImport !== \"only\",\n        request: async (analysis, input, position) => {\n            const uri = options.uri ?? (\"uri\" in input ? input.uri : undefined);\n            if (!uri) throw new Error(\"Missing analysis document\");\n            if (options.method === \"anvil/prepareCompletion\") {\n                await analysis.prepareCompletions({ uri }, { signal: options.signal });\n                return undefined;\n            }\n            if (options.method === \"textDocument/completion\") {\n                const requestedRevision = analysis.session.revision;\n                const response = await analysis.completions<T>({ uri }, position, options);\n                // A save can advance the worker revision without changing the live overlay.\n                // withPythonAnalysis checks that the request's editor and project still match.\n                const revisionMatches =\n                    response.revision === analysis.session.revision ||\n                    (options.autoImport !== \"only\" && response.revision === requestedRevision);\n                return revisionMatches ? response.result : undefined;\n            }\n            const response = await analysis.session.query<T>(\n                options.method,\n                options.params ?? {\n                    textDocument: { uri },\n                    ...(options.range ? { range: options.range } : { position }),\n                },\n                { signal: options.signal }\n            );\n            return response.revision === analysis.session.revision ? response.result : undefined;\n        },\n    });\n\n/** Resolve hover actions in the same snapshot, before CodeMirror measures the tooltip. */\nexport const requestPythonHover = (\n    view: EditorView,\n    codePath: EditorPath | undefined,\n    options: { offset: number; signal: AbortSignal; uri?: string; canRename: boolean }\n) =>\n    withPythonAnalysis<PythonHover | null>(view, codePath, {\n        ...options,\n        request: async (analysis, input, position) => {\n            const uri = options.uri ?? (\"uri\" in input ? input.uri : undefined);\n            if (!uri) throw new Error(\"Missing analysis document\");\n            const params = { textDocument: { uri }, position };\n            const [hover, definition, typeDefinition, rename] = await Promise.all([\n                analysis.session.query<PythonHover | null>(\"textDocument/hover\", params, options),\n                analysis.session.query<AnalysisLocation[] | AnalysisLocation | null>(\n                    \"textDocument/definition\",\n                    params,\n                    options\n                ),\n                analysis.session.query<AnalysisLocation[] | AnalysisLocation | null>(\n                    \"textDocument/typeDefinition\",\n                    params,\n                    options\n                ),\n                options.canRename\n                    ? analysis.session\n                          .query<LspRange | { range: LspRange } | null>(\"textDocument/prepareRename\", params, options)\n                          .catch(() => undefined)\n                    : undefined,\n            ]);\n            if (\n                [hover, definition, typeDefinition, rename].some(\n                    (response) => response && response.revision !== analysis.session.revision\n                )\n            )\n                return undefined;\n            // Hover accepts the token's right edge; its start is always inside the identifier.\n            const hoveredPosition = hover.result?.range?.start ?? position;\n            const destinations = (result: AnalysisLocation[] | AnalysisLocation | null) =>\n                (result ? (Array.isArray(result) ? result : [result]) : [])\n                    .filter((target) => !isAtLocation(target, uri, hoveredPosition))\n                    .map(({ uri, range: { start, end } }) =>\n                        JSON.stringify([uri, start.line, start.character, end?.line, end?.character])\n                    );\n            const definitions = new Set(destinations(definition.result));\n            const types = new Set(destinations(typeDefinition.result));\n            const sameDestinations =\n                definitions.size === types.size && [...types].every((target) => definitions.has(target));\n            return (\n                hover.result && {\n                    ...hover.result,\n                    actions: {\n                        definition: definitions.size > 0,\n                        typeDefinition: types.size > 0 && !sameDestinations,\n                        rename: !!rename?.result,\n                    },\n                }\n            );\n        },\n    });\n\nexport const requestPythonItemMetadata = (view: EditorView, codePath: CodePath, options: { signal: AbortSignal }) =>\n    withPythonAnalysis<PythonItemMetadata>(view, codePath, {\n        offset: 0,\n        signal: options.signal,\n        request: async (analysis, input) => {\n            if (!(\"uri\" in input)) throw new Error(\"Missing analysis document\");\n            const response = await analysis.session.query<PythonItemMetadata>(\n                \"anvil/getItemMetadata\",\n                { uri: input.uri },\n                { signal: options.signal }\n            );\n            return response.revision === analysis.session.revision ? response.result : undefined;\n        },\n    });\n\nexport const requestPythonContext = <T>(\n    view: EditorView,\n    getContext: (project: AnalysisProject) => PythonContext,\n    options: { method: string; offset: number; signal: AbortSignal; params?: unknown; autoImport?: false | \"only\" }\n): AnvilAsyncAction<{ result: T; project: AnalysisProject; isCurrent(): boolean } | undefined> =>\n    withPythonAnalysis<T>(view, getContext, {\n        ...options,\n        completionActivity: options.method === \"textDocument/completion\" && options.autoImport !== \"only\",\n        request: async (analysis, input, position) => {\n            if (!(\"context\" in input)) throw new Error(\"Missing analysis context\");\n            // Resolve belongs to the projection that produced the completion.\n            // Reopening a binding would replace its generation and reject the item.\n            // The imports source waits for the ordinary result for this document.\n            // Reopening its identical context would invalidate the ordinary items.\n            if (options.method !== \"completionItem/resolve\" && options.autoImport !== \"only\")\n                await analysis.session.setContext(input.context);\n            if (options.signal.aborted || contexts.get(view)?.id !== input.context.id) return undefined;\n            if (options.method === \"anvil/prepareCompletion\") {\n                await analysis.prepareCompletions({ contextId: input.context.id }, { signal: options.signal });\n                return undefined;\n            }\n            if (options.method === \"textDocument/completion\") {\n                const response = await analysis.completions<T>({ contextId: input.context.id }, position, options);\n                return response.revision === analysis.session.revision ? response.result : undefined;\n            }\n            const response = await analysis.session.queryContext<T>(\n                input.context.id,\n                options.method,\n                options.params ?? { position },\n                { signal: options.signal }\n            );\n            return response.revision === analysis.session.revision ? response.result : undefined;\n        },\n    });\n\nexport const requestPythonRename = <T>(\n    view: EditorView,\n    codePath: CodePath,\n    options: { offset: number; signal: AbortSignal; newName?: string }\n) =>\n    withPythonAnalysis<T>(view, codePath, {\n        ...options,\n        request: async (analysis, input, position) => {\n            if (!(\"uri\" in input)) throw new Error(\"Missing rename source\");\n            const response = await analysis.session.query<T>(\n                options.newName === undefined ? \"textDocument/prepareRename\" : \"textDocument/rename\",\n                {\n                    textDocument: { uri: input.uri },\n                    position,\n                    ...(options.newName === undefined ? {} : { newName: options.newName }),\n                },\n                { signal: options.signal }\n            );\n            return response.revision === analysis.session.revision ? response.result : undefined;\n        },\n    });\n\nexport const requestPythonResourceRename = <T>(codePath: CodePath, options: { newName: string; signal: AbortSignal }) =>\n    withPythonAnalysis<T>(undefined, codePath, {\n        offset: 0,\n        signal: options.signal,\n        request: async (analysis, input, _position, { project }) => {\n            if (!(\"uri\" in input)) throw new Error(\"Missing resource rename source\");\n            const response = await analysis.session.query<T>(\n                \"anvil/renameResource\",\n                {\n                    uri: input.uri,\n                    newName: options.newName,\n                    sourceUris: Object.keys(project.sources),\n                },\n                { signal: options.signal }\n            );\n            return response.revision === analysis.session.revision ? response.result : undefined;\n        },\n    });\n\nexport const requestPythonComponentRename = <T>(\n    codePath: CodePath,\n    options: { componentName: string; newName: string; signal: AbortSignal }\n) =>\n    withPythonAnalysis<T>(undefined, codePath, {\n        offset: 0,\n        signal: options.signal,\n        request: async (analysis, input) => {\n            if (!(\"uri\" in input)) throw new Error(\"Missing component rename source\");\n            const response = await analysis.session.query<T>(\n                \"anvil/renameComponent\",\n                {\n                    formUri: input.uri,\n                    componentName: options.componentName,\n                    newName: options.newName,\n                },\n                { signal: options.signal }\n            );\n            return response.revision === analysis.session.revision ? response.result : undefined;\n        },\n    });\n","import { type Extension, StateEffect, StateField } from \"@codemirror/state\";\nimport { Decoration, type DecorationSet, EditorView, ViewPlugin, WidgetType } from \"@codemirror/view\";\nimport { type LspRange, lspRangeToOffsets } from \"./positions\";\n\nexport interface PythonInlayHint {\n    position: LspRange[\"start\"];\n    label: string;\n    kind?: number;\n}\ntype Options = {\n    request(\n        range: LspRange,\n        signal: AbortSignal\n    ): Promise<{ result: PythonInlayHint[]; isCurrent(): boolean } | undefined>;\n};\nconst setHints = StateEffect.define<DecorationSet>();\nconst hints = StateField.define<DecorationSet>({\n    create: () => Decoration.none,\n    update(value, transaction) {\n        return transaction.effects.find((effect) => effect.is(setHints))?.value ?? value.map(transaction.changes);\n    },\n    provide: (field) => EditorView.decorations.from(field),\n});\nclass HintWidget extends WidgetType {\n    constructor(readonly label: string) {\n        super();\n    }\n\n    eq(other: HintWidget) {\n        return other.label === this.label;\n    }\n\n    toDOM() {\n        const span = document.createElement(\"span\");\n        span.className = \"cm-python-inlay-hint\";\n        span.textContent = this.label;\n        span.setAttribute(\"aria-hidden\", \"true\");\n        return span;\n    }\n}\n\n/** Install only while the user's preference is enabled. Widgets never edit Python. */\nexport function pythonInlayHints(options: Options): Extension {\n    return [\n        hints,\n        EditorView.baseTheme({ \".cm-python-inlay-hint\": { opacity: \".65\", padding: \"0 .2em\", whiteSpace: \"pre\" } }),\n        ViewPlugin.fromClass(\n            class {\n                private timer?: ReturnType<typeof setTimeout>;\n                private pending?: AbortController;\n                constructor(private view: EditorView) {\n                    this.schedule();\n                }\n\n                schedule() {\n                    clearTimeout(this.timer);\n                    this.pending?.abort();\n                    const controller = (this.pending = new AbortController());\n                    this.timer = setTimeout(async () => {\n                        const doc = this.view.state.doc;\n                        const position = (offset: number) => {\n                            const line = doc.lineAt(offset);\n                            return { line: line.number - 1, character: offset - line.from };\n                        };\n                        const visible = this.view.visibleRanges;\n                        const range = { start: position(visible[0].from), end: position(visible.at(-1)!.to) };\n                        try {\n                            const answer = await options.request(range, controller.signal);\n                            if (controller.signal.aborted || this.view.state.doc !== doc || !answer?.isCurrent())\n                                return;\n                            const widgets = answer.result.map((hint) =>\n                                Decoration.widget({ widget: new HintWidget(hint.label), side: 1 }).range(\n                                    lspRangeToOffsets(this.view.state, { start: hint.position, end: hint.position })\n                                        .from\n                                )\n                            );\n                            this.view.dispatch({ effects: setHints.of(Decoration.set(widgets, true)) });\n                        } catch (error) {\n                            if (!controller.signal.aborted) console.error(\"Python inlay hints unavailable\", error);\n                        }\n                    }, 200);\n                }\n\n                update(update: import(\"@codemirror/view\").ViewUpdate) {\n                    if (update.docChanged || update.viewportChanged) this.schedule();\n                }\n\n                destroy() {\n                    clearTimeout(this.timer);\n                    this.pending?.abort();\n                }\n            }\n        ),\n    ];\n}\n","import type { EditorState } from \"@codemirror/state\";\nimport type { AnalysisLocation } from \"./project\";\n\nexport interface LspRange {\n    start: { line: number; character: number };\n    end: { line: number; character: number };\n}\n\n/** A selected identifier uses a half-open range, just like the editor. */\nexport function isAtLocation(location: AnalysisLocation, uri: string, position: LspRange[\"start\"]) {\n    const { start, end } = location.range;\n    return (\n        location.uri === uri &&\n        end !== undefined &&\n        (start.line < position.line || (start.line === position.line && start.character <= position.character)) &&\n        (end.line > position.line || (end.line === position.line && end.character > position.character))\n    );\n}\n\n/** Validate UTF-16 LSP positions against the exact CodeMirror document. */\nexport function lspRangeToOffsets(state: EditorState, range: LspRange) {\n    const position = ({ line, character }: LspRange[\"start\"]) => {\n        if (!Number.isInteger(line) || line < 0 || line >= state.doc.lines)\n            throw new Error(\"Invalid Python result line\");\n        const text = state.doc.line(line + 1);\n        if (!Number.isInteger(character) || character < 0 || character > text.length)\n            throw new Error(\"Invalid Python result column\");\n        return text.from + character;\n    };\n    const from = position(range.start),\n        to = position(range.end);\n    if (to < from) throw new Error(\"Reversed Python result range\");\n    return { from, to };\n}\n","const material3ThemeAppId = \"4UK6WHQ6UX7AKELK\";\n// Use the resolved commits from the official Anvil app's release tags.\nconst affectedReleases = new Map<string, \"callback\" | \"property\">([\n    [\"cb950498e9bda8f60eab4e99c472c391a721d11e\", \"callback\"], // v1.2.0\n    [\"4afff5e7b96cbdbe7811ab4a107c25ab48d48cac\", \"callback\"], // v1.2.1\n    [\"af2ceba7e7e6e879fb41794fa5a9eff3810ecfd7\", \"property\"], // v1.2.2\n    [\"b2d474511cb1269fccda025d269b650ac3a17f78\", \"property\"], // v1.2.3\n    [\"055868b12f1baa1c00b7d10ef96e22997922d5f1\", \"property\"], // v1.2.4\n    [\"ba1932ac5b41ee3d0a10b9d396293de55dcb44c2\", \"property\"], // v1.2.5\n    [\"e7eb485cad6a8fafbb3ada0428bdf56be1051448\", \"property\"], // v1.2.6\n]);\n\n/**\n * The published Material 3 decorators return either a writable property or\n * another decorator. Tell Ty which one it gets for each call.\n * Remove this when support for these pinned v1.2.x releases ends.\n */\nexport function addMaterial3PropertyTypes(\n    files: Record<string, string>,\n    dependencyRoot: string,\n    { appId, commitId }: { appId: string; commitId?: string }\n) {\n    if (appId !== material3ThemeAppId || !commitId) return;\n    const decoratorInput = affectedReleases.get(commitId);\n    if (!decoratorInput) return;\n\n    const module = `${dependencyRoot}/client_code/_utils/properties.py`;\n    const declarations = `${dependencyRoot}/client_code/_utils/_anvil_property_types.pyi`;\n    const source = files[module];\n    if (!source) return;\n\n    const newline = source.match(/\\r?\\n/)?.[0] ?? \"\\n\";\n    const lines = source.split(newline);\n    const decoratorLine = lines.indexOf(\"def anvil_prop(*args, **kwargs):\") - 1;\n    const importLine = lines.indexOf(\"from . import fui, noop\") + 1;\n    // Replace existing blank lines so locations still refer to the real source.\n    if (importLine === 0 || importLine >= decoratorLine || lines[importLine] !== \"\" || lines[decoratorLine] !== \"\") return;\n\n    const wrapsProperty = decoratorInput === \"property\";\n    const callback = wrapsProperty ? \"property\" : \"Callable[..., Any]\";\n    const namedProperty = wrapsProperty\n        ? \"\"\n        : \"    @overload\\n    def __call__(self, name: str, /, *, default_value: Any = None) -> property: ...\\n\";\n    files[declarations] = `from typing import Any, Callable, Protocol, overload\n\nclass _AnvilProp(Protocol):\n${namedProperty}    @overload\n    def __call__(self, callback: ${callback}, /) -> property: ...\n    @overload\n    def __call__(self, *, default_value: Any = None) -> Callable[[${callback}], property]: ...\n\ndef _type_anvil_prop(original: Callable[..., Any], /) -> _AnvilProp: ...\n`;\n    lines[importLine] = \"from ._anvil_property_types import _type_anvil_prop\";\n    lines[decoratorLine] = \"@_type_anvil_prop\";\n    files[module] = lines.join(newline);\n}\n","import type { CustomComponentSpec } from \"@designer/shared-types\";\nimport type { ExtraFiles } from \"@/types/app\";\nimport type { CodePath } from \"@/types/code\";\nimport type { Table } from \"@/types/database\";\nimport type {\n    AnalysisConfig,\n    AnalysisDependency,\n    AnalysisItem,\n    AnalysisLocation,\n    AnalysisProject,\n    AnalysisSource,\n} from \"@/types/python-analysis\";\nimport { decodeAssetContent } from \"@/util/asset-content\";\nimport type { ServerPythonMinorVersion } from \"@/util/python-version\";\nimport { addMaterial3PropertyTypes } from \"./material3-property-types\";\n\nexport type {\n    AnalysisItem,\n    AnalysisConfig,\n    AnalysisDependency,\n    AnalysisSource,\n    AnalysisProject,\n    AnalysisLocation,\n} from \"@/types/python-analysis\";\n\nexport type AnalysisProjectKind = \"app\" | \"serverTests\";\n\nexport function pythonSourceUri(path: string) {\n    return new URL(path.split(\"/\").map(encodeURIComponent).join(\"/\"), \"file:///\").href;\n}\n\nexport function analysisProjectKind(source: string | undefined): AnalysisProjectKind {\n    return source?.startsWith(\"extra_files/tests/server_tests/\") || source?.startsWith(\"file:///server-tests/\")\n        ? \"serverTests\"\n        : \"app\";\n}\n\nexport function buildAnalysisProject(input: {\n    config: AnalysisConfig;\n    items: AnalysisItem[];\n    dependencies: Record<string, AnalysisDependency>;\n    jsComponents?: CustomComponentSpec[];\n    tables?: readonly Pick<Table, \"id\" | \"python_name\">[];\n    serverBundledRequirements?: readonly string[];\n    serverPythonMinorVersion?: ServerPythonMinorVersion;\n    kind?: AnalysisProjectKind;\n}): AnalysisProject {\n    const root = input.kind === \"serverTests\" ? \"/server-tests\" : \"/app\";\n    const project: AnalysisProject = { rootUri: `file://${root}`, files: {}, sources: {}, uris: {} };\n    const addConfig = (root: string, config: AnalysisConfig) => {\n        const { package_name, db_schema, dependencies, services, runtime_options, startup_form, startup } = config;\n        project.files[`${root}/anvil.yaml`] = JSON.stringify({\n            package_name: package_name || \"main_app_package\",\n            db_schema,\n            dependencies,\n            services,\n            runtime_options,\n            startup_form,\n            startup,\n            // Analysis needs configured names, never secret/key material.\n            secrets:\n                config.secrets &&\n                Object.fromEntries(Object.entries(config.secrets).map(([name, { type }]) => [name, { type }])),\n        });\n        project.files[`${root}/client_code/__init__.py`] = \"\";\n        project.files[`${root}/server_code/__init__.py`] = \"\";\n    };\n    const addItem = (root: string, entry: AnalysisItem, dependencyId?: string) => {\n        const { item, itemType, codePath } = entry;\n        const name = item.class_name || item.name!;\n        const directory = `${root}/${itemType === \"server_module\" ? \"server_code\" : \"client_code\"}`;\n        const path = `${directory}/${name.replaceAll(\".\", \"/\")}`;\n        const codeFile = item.is_package ? `${path}/__init__.py` : `${path}.py`;\n        project.files[codeFile] = item.code;\n        // Anvil packages can contain children without an explicitly stored package module.\n        for (\n            let parent = codeFile.slice(0, codeFile.lastIndexOf(\"/\"));\n            parent !== directory;\n            parent = parent.slice(0, parent.lastIndexOf(\"/\"))\n        ) {\n            project.files[`${parent}/__init__.py`] ??= \"\";\n        }\n        const uri = pythonSourceUri(codeFile);\n        project.sources[uri] = {\n            codePath: dependencyId ? undefined : codePath,\n            dependencyId,\n            label: name,\n            code: item.code,\n        };\n        if (!dependencyId) project.uris[codePath] = uri;\n        if (itemType === \"form\") {\n            const { code, serialized_html, ...template } = item;\n            const table = !dependencyId && input.tables?.find((table) => table.id === template.item_type?.table_id);\n            const metadata = { ...template, item_type: table ? { table_name: table.python_name } : template.item_type };\n            const templatePath = item.is_package ? `${path}/form_template` : path;\n            if (\n                item.save_as_html &&\n                serialized_html !== undefined &&\n                template.container === undefined &&\n                template.layout === undefined\n            ) {\n                // JSON is valid YAML frontmatter. Keep metadata and HTML in one file,\n                // matching app export; a companion YAML would hide the HTML structure.\n                project.files[`${templatePath}.html`] = `---\\n${JSON.stringify(metadata)}\\n---\\n${serialized_html}`;\n            } else {\n                // Cached HTML Forms already have Designer structure. Keep its\n                // anonymous identities; persistence serialization renumbers them.\n                // HTML remains available for named DOM references.\n                project.files[`${templatePath}.yaml`] = JSON.stringify({ ...metadata, serialized_html });\n            }\n        }\n    };\n    const packages: Record<string, string> = {\n        [input.config.package_name || \"main_app_package\"]: `${root}/client_code`,\n    };\n    addConfig(root, input.config);\n    // Export app settings for the browser adapter; Ty validates the native options.\n    for (const name of [\"ty.toml\", \"pyproject.toml\"]) {\n        const content = input.config.extra_files?.[name];\n        if (typeof content === \"string\") project.files[`${root}/${name}`] = decodeAssetContent(content);\n    }\n    project.files[`${root}/.anvil/python-environment.json`] = JSON.stringify({\n        server: `3.${input.serverPythonMinorVersion ?? 10}`,\n    });\n    project.files[`${root}/.anvil/server-requirements.json`] = JSON.stringify(input.serverBundledRequirements ?? []);\n    for (const item of input.items) addItem(root, item);\n    if (input.kind === \"serverTests\") {\n        project.files[`${root}/.anvil/server-tests.json`] = \"true\";\n        const tests = input.config.extra_files?.tests;\n        const files = typeof tests === \"object\" ? tests.server_tests : undefined;\n        const addTests = (files: ExtraFiles, path: string) => {\n            for (const [name, entry] of Object.entries(files)) {\n                const filePath = `${path}/${name}`;\n                if (typeof entry !== \"string\") {\n                    addTests(entry, filePath);\n                } else if (name.endsWith(\".py\") || filePath === \"tests/server_tests/requirements.txt\") {\n                    const code = decodeAssetContent(entry);\n                    const uri = pythonSourceUri(`${root}/${filePath}`);\n                    project.files[`${root}/${filePath}`] = code;\n                    if (name.endsWith(\".py\")) {\n                        const codePath = `extra_files/${filePath}` as const;\n                        project.sources[uri] = { codePath, label: filePath.slice(\"tests/\".length), code };\n                        project.uris[codePath] = uri;\n                    }\n                }\n            }\n        };\n        if (files && typeof files === \"object\") addTests(files, \"tests/server_tests\");\n    }\n    const dependencyRoots: Record<string, string> = {};\n    for (const [id, dependency] of Object.entries(input.dependencies)) {\n        if (dependency.error) continue;\n        const dependencyRoot = `${root}/.anvil/deps/${encodeURIComponent(id)}`;\n        dependencyRoots[id] = dependencyRoot;\n        addConfig(dependencyRoot, dependency);\n        packages[dependency.package_name || \"main_app_package\"] = `${dependencyRoot}/client_code`;\n        for (const [key, itemType] of [\n            [\"forms\", \"form\"],\n            [\"modules\", \"module\"],\n            [\"server_modules\", \"server_module\"],\n        ] as const) {\n            for (const item of dependency[key])\n                addItem(\n                    dependencyRoot,\n                    { codePath: `${key}/${item.class_name || item.name}` as CodePath, itemType, item },\n                    id\n                );\n        }\n        addMaterial3PropertyTypes(project.files, dependencyRoot, { appId: id, commitId: dependency[\"commit-id\"] });\n    }\n    // dependencyCode is the IDE server's resolved set, including transitive apps.\n    // Its logical IDs can differ from the app IDs used by the cache directories.\n    project.files[`${root}/.anvil/dependencies.json`] = JSON.stringify({\n        roots: [...new Set([...(input.config.dependency_order ?? []), ...Object.keys(dependencyRoots)])].flatMap(\n            (id) => (dependencyRoots[id] ? [dependencyRoots[id]] : [])\n        ),\n        ids: {\n            ...dependencyRoots,\n            ...Object.fromEntries(\n                Object.entries(input.config.dependency_ids ?? {}).flatMap(([logicalId, appId]) =>\n                    dependencyRoots[appId] ? [[logicalId, dependencyRoots[appId]]] : []\n                )\n            ),\n        },\n    });\n    if (input.jsComponents?.length) {\n        project.files[`${root}/.anvil/js-components.json`] = JSON.stringify({\n            packages,\n            components: input.jsComponents.map(({ name, properties, layoutProperties, methods, container }) => ({\n                name,\n                container,\n                properties: properties?.map(({ name, description }) => ({ name, description })),\n                layoutProperties: layoutProperties?.map(({ name, description }) => ({ name, description })),\n                methods: methods?.map(({ name, description, args }) => ({\n                    name,\n                    description,\n                    args: args?.map(({ name, type, optional }) => ({ name, type, optional })),\n                })),\n            })),\n        });\n    }\n    return project;\n}\n\nexport function diffAnalysisFiles(before: Record<string, string>, after: Record<string, string>) {\n    const changes: Record<string, string | null> = {};\n    for (const path of Object.keys(before)) if (!(path in after)) changes[path] = null;\n    for (const [path, code] of Object.entries(after)) if (before[path] !== code) changes[path] = code;\n    return changes;\n}\n\n/** Keep full Python module names here; tab headers apply the usual abbreviation. */\nexport function pythonSourceLabel(uri: string) {\n    const url = new URL(uri);\n    const path = decodeURIComponent(url.pathname)\n        .replace(/\\/__init__\\.pyi?$/, \"\")\n        .replace(/\\.pyi?$/, \"\");\n    const relative =\n        path.match(/\\/(?:client_code|server_code|\\.anvil\\/(?:types|analysis)\\/(?:client|server)|stdlib)\\/(.+)$/)?.[1] ??\n        (url.protocol === \"vendored:\" ? path.slice(1) : path.split(\"/\").pop()!);\n    return relative.replaceAll(\"/\", \".\");\n}\n\nexport function sourceForLocation(project: AnalysisProject, location: AnalysisLocation) {\n    const source: AnalysisSource | undefined =\n        project.sources[location.uri] ??\n        (location.source && {\n            label: pythonSourceLabel(location.uri),\n            code: location.source.text,\n        });\n    return source && { ...source, line: location.range.start.line + 1, column: location.range.start.character };\n}\n","import { invertedEffects, isolateHistory, redo, undo } from \"@codemirror/commands\";\nimport { EditorState, StateEffect, StateField, type Transaction } from \"@codemirror/state\";\nimport { type EditorView } from \"@codemirror/view\";\n\nexport type RenameDirection = \"before\" | \"after\";\nconst boundary = StateEffect.define<{ id: number; direction: RenameDirection }>();\nexport const renameBoundaries = StateField.define<ReadonlySet<number>>({\n    create: () => new Set(),\n    update: (value, transaction) => {\n        const ids = transaction.effects.filter((effect) => effect.is(boundary)).map((effect) => effect.value.id);\n        return ids.length ? new Set([...value, ...ids]) : value;\n    },\n});\ninterface RenameHistoryOwner {\n    confirm?(id: number, direction: RenameDirection): boolean | Promise<boolean>;\n    prepare(\n        id: number,\n        direction: RenameDirection,\n        history: { view: EditorView; transaction: Transaction }\n    ): (() => void) | undefined;\n    onError(error: unknown): void;\n}\nexport const renameHistoryEffects = [\n    renameBoundaries,\n    invertedEffects.of((transaction) =>\n        transaction.effects\n            .filter((effect) => effect.is(boundary))\n            .map((effect) =>\n                boundary.of({\n                    id: effect.value.id,\n                    direction: effect.value.direction === \"before\" ? \"after\" : \"before\",\n                })\n            )\n    ),\n];\nconst registered = new WeakMap<EditorView, RenameHistoryOwner>();\nconst pending = new WeakSet<EditorView>();\n\n/** Catch native history before it consumes a coordinated entry, including Vim,\n * Emacs and browser Undo, which do not necessarily use the editor keymap. */\nexport function dispatchWithRenameHistory(transactions: readonly Transaction[], view: EditorView) {\n    const history = registered.has(view)\n        ? transactions.find(\n              (transaction) =>\n                  (transaction.isUserEvent(\"undo\") || transaction.isUserEvent(\"redo\")) &&\n                  transaction.effects.some((effect) => effect.is(boundary))\n          )\n        : undefined;\n    if (history) {\n        void renameHistoryCommand(view, history.isUserEvent(\"undo\") ? \"before\" : \"after\");\n    } else {\n        view.update(transactions);\n    }\n}\n\n/** Native history carries an isolated rename token. Capture its undo transaction\n * before dispatch so a refused cross-file inverse cannot consume the boundary.\n * Tokens in other editors become harmless after one editor reverses the app edit. */\nexport async function renameHistoryCommand(view: EditorView, direction: RenameDirection): Promise<boolean> {\n    if (pending.has(view)) return true;\n    const owner = registered.get(view);\n    const command = direction === \"before\" ? undo : redo;\n    if (!owner) return command(view);\n    for (;;) {\n        let transaction: Transaction | undefined;\n        if (\n            !command({\n                state: view.state,\n                dispatch: (value) => {\n                    transaction = value;\n                },\n            })\n        )\n            return false;\n        const effect = transaction!.effects.find((effect) => effect.is(boundary));\n        if (!effect) {\n            view.dispatch(transaction!);\n            return true;\n        }\n        let commit: (() => void) | undefined;\n        try {\n            const confirmation = owner.confirm?.(effect.value.id, direction) ?? true;\n            if (typeof confirmation !== \"boolean\") {\n                pending.add(view);\n                let accepted: boolean;\n                try {\n                    accepted = await confirmation;\n                } finally {\n                    pending.delete(view);\n                }\n                if (!accepted || registered.get(view) !== owner) return true;\n                transaction = matchingRenameBoundary(view.state, effect.value.id, direction);\n                if (!transaction) return true;\n            } else if (!confirmation) return true;\n            commit = owner.prepare(effect.value.id, direction, { view, transaction: transaction! });\n        } catch (error) {\n            owner.onError(error);\n            return true;\n        }\n        if (commit) {\n            commit();\n            return true;\n        }\n        view.update([transaction!]);\n        // Another participating editor already performed this operation. Consume\n        // its stale token and continue to the next real native history event.\n    }\n}\n\nexport function registerRenameHistory(view: EditorView, owner: RenameHistoryOwner) {\n    registered.set(view, owner);\n    view.dispatch({\n        effects: StateEffect.appendConfig.of(renameHistoryEffects),\n    });\n    return () => {\n        registered.delete(view);\n    };\n}\n\n/** Move other providers' matching top tokens with the same app operation.\n * Later ordinary edits stay on top and keep their normal undo order. */\nexport function matchingRenameBoundary(state: EditorState, id: number, direction: RenameDirection) {\n    let transaction: Transaction | undefined;\n    (direction === \"before\" ? undo : redo)({\n        state,\n        dispatch: (value) => {\n            transaction = value;\n        },\n    });\n    return transaction?.changes.empty &&\n        transaction.effects.some((effect) => effect.is(boundary) && effect.value.id === id)\n        ? transaction\n        : undefined;\n}\n\nexport function renameBoundary(state: EditorState, id: number) {\n    if (state.field(renameBoundaries, false)?.has(id)) return undefined;\n    return state.update({\n        effects: boundary.of({ id, direction: \"after\" }),\n        annotations: isolateHistory.of(\"full\"),\n    });\n}\n","import { syntaxTree } from \"@codemirror/language\";\nimport { type EditorState, type Extension, Prec, StateEffect, StateField } from \"@codemirror/state\";\nimport { EditorView, type Tooltip, ViewPlugin, type ViewUpdate, keymap, showTooltip } from \"@codemirror/view\";\n\nexport interface SignatureHelp {\n    signatures: {\n        label: string;\n        documentation?: string | { value: string };\n        parameters?: { label: string | [number, number]; documentation?: string | { value: string } }[];\n        activeParameter?: number;\n    }[];\n    activeSignature?: number;\n    activeParameter?: number;\n}\ntype SignatureTooltip = Tooltip & { callStart: number };\n\nconst setSignature = StateEffect.define<SignatureTooltip | null>();\n\nfunction callArguments(state: EditorState) {\n    const head = state.selection.main.head;\n    for (let node = syntaxTree(state).resolveInner(head, -1); node.parent; node = node.parent) {\n        if (\n            node.name === \"ArgList\" &&\n            head > node.from &&\n            (head < node.to || state.sliceDoc(node.to - 1, node.to) !== \")\")\n        )\n            return node;\n    }\n    return undefined;\n}\n\nconst signatureField = StateField.define<readonly SignatureTooltip[]>({\n    create: () => [],\n    update(value, transaction) {\n        for (const effect of transaction.effects)\n            if (effect.is(setSignature)) return effect.value ? [effect.value] : [];\n        if (!transaction.docChanged && !transaction.selection) return value;\n        const call = callArguments(transaction.state);\n        return value.flatMap((tooltip) =>\n            call && transaction.changes.mapPos(tooltip.callStart) === call.from\n                ? [{ ...tooltip, pos: transaction.changes.mapPos(tooltip.pos), callStart: call.from }]\n                : []\n        );\n    },\n    provide: (field) => showTooltip.computeN([field], (state) => state.field(field)),\n});\n\nfunction signatureElement(help: SignatureHelp) {\n    const signature = help.signatures[help.activeSignature ?? 0] ?? help.signatures[0];\n    const dom = document.createElement(\"div\");\n    dom.className = \"cm-tooltip-parameterhelper cm-python-signature max-w-3xl whitespace-pre-wrap\";\n    const parameter = signature.parameters?.[signature.activeParameter ?? help.activeParameter ?? 0];\n    const label = parameter?.label;\n    const start = typeof label === \"string\" ? signature.label.indexOf(label) : label?.[0];\n    const end = typeof label === \"string\" ? (start ?? 0) + label.length : label?.[1];\n    if (start !== undefined && start >= 0 && end !== undefined) {\n        dom.append(signature.label.slice(0, start));\n        const active = document.createElement(\"strong\");\n        active.textContent = signature.label.slice(start, end);\n        dom.append(active, signature.label.slice(end));\n    } else dom.textContent = signature.label;\n    return dom;\n}\n\n/** Standard signature help follows typing and cursor movement inside the active call. */\nexport function pythonSignatures(options: {\n    enabled(): boolean;\n    request(options: {\n        offset: number;\n        signal: AbortSignal;\n    }): Promise<{ result: SignatureHelp | null; isCurrent(): boolean } | undefined>;\n    onError(error: unknown): void;\n}): Extension {\n    const plugin = ViewPlugin.fromClass(\n        class {\n            pending?: AbortController;\n            timer?: ReturnType<typeof setTimeout>;\n            wanted = false;\n            constructor(readonly view: EditorView) {\n                this.wanted = !!callArguments(view.state);\n                if (this.wanted && view.hasFocus) this.timer = setTimeout(() => this.request(), 100);\n            }\n\n            cancel() {\n                this.pending?.abort();\n                clearTimeout(this.timer);\n            }\n\n            request() {\n                this.cancel();\n                const call = callArguments(this.view.state);\n                if (!this.view.hasFocus || !options.enabled() || !call) return;\n                this.wanted = true;\n                const controller = (this.pending = new AbortController());\n                const offset = this.view.state.selection.main.head;\n                void options\n                    .request({ offset, signal: controller.signal })\n                    .then((answer) => {\n                        if (controller.signal.aborted || !this.view.hasFocus || !answer?.isCurrent()) return;\n                        const help = answer.result;\n                        this.wanted = !!help?.signatures.length;\n                        this.view.dispatch({\n                            effects: setSignature.of(\n                                help?.signatures.length\n                                    ? {\n                                          pos: offset,\n                                          callStart: call.from,\n                                          above: true,\n                                          create: () => ({ dom: signatureElement(help) }),\n                                      }\n                                    : null\n                            ),\n                        });\n                    })\n                    .catch((error) => {\n                        if (!controller.signal.aborted) {\n                            this.wanted = false;\n                            this.view.dispatch({ effects: setSignature.of(null) });\n                            options.onError(error);\n                        }\n                    });\n            }\n\n            update(update: ViewUpdate) {\n                if (!update.docChanged && !update.selectionSet && !update.focusChanged) return;\n                this.cancel();\n                if (!this.view.hasFocus) return;\n                const active = update.startState.field(signatureField).length > 0;\n                const head = update.state.selection.main.head;\n                const call = callArguments(update.state);\n                if (!call) {\n                    this.wanted = false;\n                    return;\n                }\n                const trigger =\n                    update.docChanged && /[(,)]/.test(update.state.doc.sliceString(Math.max(0, head - 1), head));\n                this.wanted ||=\n                    update.focusChanged || active || trigger || call.from !== callArguments(update.startState)?.from;\n                if (this.wanted) this.timer = setTimeout(() => this.request(), 100);\n            }\n\n            destroy() {\n                this.cancel();\n            }\n        }\n    );\n    return [\n        signatureField,\n        EditorView.focusChangeEffect.of((_state, focusing) => (focusing ? null : setSignature.of(null))),\n        plugin,\n        Prec.high(\n            keymap.of([\n                {\n                    key: \"Ctrl-Shift-Space\",\n                    run: (view) => {\n                        if (!options.enabled()) return false;\n                        view.plugin(plugin)?.request();\n                        return true;\n                    },\n                },\n                {\n                    key: \"Escape\",\n                    run: (view) => {\n                        const active = view.state.field(signatureField).length > 0;\n                        const instance = view.plugin(plugin);\n                        instance?.cancel();\n                        if (instance) instance.wanted = false;\n                        if (active) view.dispatch({ effects: setSignature.of(null) });\n                        return active;\n                    },\n                },\n            ])\n        ),\n    ];\n}\n","import type { NavTarget } from \"@/router/navTypes\";\nimport { isCodePath } from \"@/types/code\";\nimport type { CodeTarget } from \"./ide-analysis\";\n\nexport function pythonSourceNavTarget(target: CodeTarget): NavTarget {\n    const view = { code: [String(target.line), String(target.column)] as const };\n    if (!target.codePath)\n        return { type: \"PYTHON_SOURCE\", uri: target.uri, label: target.label, view, refocusView: Date.now() };\n    if (isCodePath(target.codePath)) return { type: \"CODE\", codePath: target.codePath, essentialView: view };\n    return {\n        type: \"EXTRA_FILE\",\n        filePath: target.codePath.slice(\"extra_files/\".length),\n        view,\n        refocusView: Date.now(),\n    };\n}\n","import { ChangeSet, EditorState } from \"@codemirror/state\";\nimport { findComponentByNameInTree } from \"@/components/tabs/code/designer/utils/component-tree\";\nimport type { CodeItemYaml, CodePath, FormItemYaml } from \"@/types\";\nimport { isCodePath } from \"@/types/code\";\nimport { type LspRange, lspRangeToOffsets } from \"./positions\";\nimport type { AnalysisProject } from \"./project\";\n\ninterface TextEdit {\n    range: LspRange;\n    newText: string;\n}\ninterface DocumentEdit {\n    textDocument: { uri: string; version: number | null };\n    edits: TextEdit[];\n}\nexport interface AnvilWorkspaceEdit {\n    resourceRenames?: { uri: string; oldName: string; newName: string }[];\n    configEdits?: { uri: string; path: string[]; before: string; after: string }[];\n    formEdits?: {\n        formUri: string;\n        componentName: string | null;\n        path: (string | number)[];\n        before: string;\n        after: string;\n    }[];\n    changes?: Record<string, TextEdit[]>;\n    documentChanges?: (DocumentEdit | { kind: string })[];\n    componentRenames?: { formUri: string; oldName: string; newName: string; eventHandlers: Record<string, string> }[];\n    eventHandlerRenames?: { formUri: string; oldName: string; newName: string }[];\n    bindingEdits?: {\n        formUri: string;\n        componentName: string | null;\n        property: string;\n        index: number;\n        expression: string;\n        edits: TextEdit[];\n    }[];\n}\n\n/** Field paths are relative to a named component, or to the Form when names are absent.\n * Both names identify the same component on either side of a rename. This allows\n * undo after unrelated Designer edits or component-tree reordering. */\nexport interface FormFieldEdit {\n    codePath: CodePath;\n    ownerNames?: { before: string; after: string };\n    path: (string | number)[];\n    before: string;\n    after: string;\n}\nexport interface PreparedWorkspaceEdit {\n    items: Map<CodePath, CodeItemYaml>;\n    code: Map<CodePath, { before: string; changes: ChangeSet }>;\n    fields: FormFieldEdit[];\n    packageChanges?: { codePath: CodePath; before: boolean; after: boolean }[];\n    resources?: { codePath: CodePath; newCodePath: CodePath; before: string; after: string }[];\n    configEdits?: NonNullable<AnvilWorkspaceEdit[\"configEdits\"]>;\n}\n\nfunction sourcePath(project: AnalysisProject, uri: string) {\n    const source = project.sources[uri];\n    if (!source?.codePath || !isCodePath(source.codePath) || source.dependencyId)\n        throw new Error(\"Rename requires an editable original app source.\");\n    return source.codePath;\n}\n\nfunction textChanges(code: string, edits: TextEdit[]) {\n    const state = EditorState.create({ doc: code });\n    const changes = edits.map((edit) => ({ ...lspRangeToOffsets(state, edit.range), insert: edit.newText }));\n    changes.sort((a, b) => a.from - b.from || a.to - b.to);\n    for (let i = 1; i < changes.length; i++) {\n        if (changes[i].from < changes[i - 1].to || changes[i].from === changes[i - 1].from)\n            throw new Error(\"Rename contains overlapping edits.\");\n    }\n    return ChangeSet.of(changes, state.doc.length);\n}\n\n/** Resolve one original Designer/config field without assuming the shape of its parents. */\nexport function resolveField(root: unknown, path: readonly (string | number)[]) {\n    let object: unknown = root;\n    for (const key of path.slice(0, -1)) {\n        if (object === null || typeof object !== \"object\") return undefined;\n        object = (object as Record<string | number, unknown>)[key];\n    }\n    const key = path.at(-1);\n    return key !== undefined && object !== null && typeof object === \"object\"\n        ? { object: object as Record<string | number, unknown>, key }\n        : undefined;\n}\n\n/** Prepare every original field before publishing any app change. Used for rename\n * and its inverse; a stale required field refuses the complete operation. */\nexport function applyFormFields(\n    items: Map<CodePath, CodeItemYaml>,\n    fields: FormFieldEdit[],\n    options: { direction: \"before\" | \"after\"; historicalSnapshot?: boolean }\n) {\n    const source = options.direction === \"after\" ? \"before\" : \"after\";\n    const resolved = fields.map((edit) => {\n        const form = items.get(edit.codePath) as FormItemYaml | undefined;\n        if (!form?.class_name) {\n            if (options.historicalSnapshot) return undefined;\n            throw new Error(\"Rename requires an app Form.\");\n        }\n        const owner = edit.ownerNames ? findComponentByNameInTree(form, edit.ownerNames[source])?.component : form;\n        const field = resolveField(owner, edit.path);\n        if (!field || field.object[field.key] !== edit[source]) {\n            if (options.historicalSnapshot) return undefined;\n            throw new Error(\"A required Designer field changed. Retry rename.\");\n        }\n        const { object, key } = field;\n        if (!options.historicalSnapshot && edit.ownerNames && edit.path.length === 1 && key === \"name\") {\n            const other = findComponentByNameInTree(form, edit[options.direction])?.component;\n            if (other && other !== owner) throw new Error(\"Component rename destination is in use.\");\n        }\n        return { object, key, value: edit[options.direction] };\n    });\n    for (const field of resolved) if (field) field.object[field.key] = field.value;\n}\n\nexport function prepareWorkspaceEdit(\n    project: AnalysisProject,\n    edit: AnvilWorkspaceEdit,\n    options: { items: ReadonlyMap<CodePath, CodeItemYaml>; documents?: ReadonlyMap<CodePath, string> }\n): PreparedWorkspaceEdit {\n    const plan: PreparedWorkspaceEdit = { items: new Map(), code: new Map(), fields: [] };\n    const item = (codePath: CodePath) => {\n        if (!plan.items.has(codePath)) {\n            const original = options.items.get(codePath);\n            if (!original) throw new Error(`Rename source was not loaded: ${codePath}`);\n            plan.items.set(codePath, structuredClone(original));\n        }\n        return plan.items.get(codePath)!;\n    };\n    const documents = new Map<string, TextEdit[]>();\n    for (const [uri, edits] of Object.entries(edit.changes ?? {})) documents.set(uri, [...edits]);\n    for (const change of edit.documentChanges ?? []) {\n        if (!(\"textDocument\" in change)) throw new Error(\"Resource rename is not supported by this consumer yet.\");\n        const { uri } = change.textDocument;\n        documents.set(uri, [...(documents.get(uri) ?? []), ...change.edits]);\n    }\n    for (const [uri, edits] of documents) {\n        if (!edits.length) continue;\n        const codePath = sourcePath(project, uri);\n        const original = item(codePath);\n        const before = options.documents?.get(codePath) ?? original.code;\n        if (typeof before !== \"string\") throw new Error(\"Rename requires Python source.\");\n        const changes = textChanges(before, edits);\n        original.code = changes.apply(EditorState.create({ doc: before }).doc).toString();\n        plan.code.set(codePath, { before, changes });\n    }\n    for (const binding of edit.bindingEdits ?? []) {\n        const codePath = sourcePath(project, binding.formUri);\n        const form = item(codePath) as FormItemYaml;\n        const component =\n            binding.componentName === null\n                ? undefined\n                : findComponentByNameInTree(form, binding.componentName)?.component;\n        const containers = component\n            ? ([[[], component]] as const)\n            : binding.componentName === null\n              ? ([\n                    [[], form],\n                    [[\"container\"], form.container],\n                    [[\"layout\"], form.layout],\n                ] as const)\n              : [];\n        const matches = containers.flatMap(([prefix, owner]) => {\n            const value: unknown = (owner as { data_bindings?: unknown[] } | undefined)?.data_bindings?.[binding.index];\n            const property = Array.isArray(value) ? value[0] : resolveField(value, [\"property\"])?.object.property;\n            const expression = Array.isArray(value) ? value[1] : resolveField(value, [\"code\"])?.object.code;\n            return property === binding.property && expression === binding.expression ? [{ prefix, value }] : [];\n        });\n        if (matches.length !== 1) throw new Error(\"A required Form binding changed. Retry rename.\");\n        const { prefix, value } = matches[0];\n        const renamed = edit.componentRenames?.find(\n            (rename) => rename.formUri === binding.formUri && rename.oldName === binding.componentName\n        );\n        const after = textChanges(binding.expression, binding.edits)\n            .apply(EditorState.create({ doc: binding.expression }).doc)\n            .toString();\n        plan.fields.push({\n            codePath,\n            ownerNames:\n                binding.componentName === null\n                    ? undefined\n                    : { before: binding.componentName, after: renamed?.newName ?? binding.componentName },\n            path: [...prefix, \"data_bindings\", binding.index, Array.isArray(value) ? 1 : \"code\"],\n            before: binding.expression,\n            after,\n        });\n    }\n    for (const rename of edit.componentRenames ?? []) {\n        const codePath = sourcePath(project, rename.formUri);\n        const form = item(codePath) as FormItemYaml;\n        const component = findComponentByNameInTree(form, rename.oldName)?.component;\n        if (!component || findComponentByNameInTree(form, rename.newName))\n            throw new Error(\"Component rename target changed or its new name is in use.\");\n        const ownerNames = { before: rename.oldName, after: rename.newName };\n        plan.fields.push({ codePath, ownerNames, path: [\"name\"], before: rename.oldName, after: rename.newName });\n        for (const [name, slot] of Object.entries(form.slots ?? {})) {\n            if (slot.target?.type === \"container\" && slot.target.name === rename.oldName)\n                plan.fields.push({\n                    codePath,\n                    path: [\"slots\", name, \"target\", \"name\"],\n                    before: rename.oldName,\n                    after: rename.newName,\n                });\n        }\n    }\n    const handlerRenames = new Map<string, Map<string, string>>();\n    for (const rename of edit.componentRenames ?? []) {\n        const names = handlerRenames.get(rename.formUri) ?? new Map<string, string>();\n        for (const [before, after] of Object.entries(rename.eventHandlers)) names.set(before, after);\n        handlerRenames.set(rename.formUri, names);\n    }\n    for (const rename of edit.eventHandlerRenames ?? []) {\n        const names = handlerRenames.get(rename.formUri) ?? new Map<string, string>();\n        names.set(rename.oldName, rename.newName);\n        handlerRenames.set(rename.formUri, names);\n    }\n    for (const [uri, names] of handlerRenames) {\n        const codePath = sourcePath(project, uri);\n        const form = item(codePath) as FormItemYaml;\n        const handlers = (\n            bindings: Record<string, string> | undefined,\n            path: (string | number)[],\n            ownerNames?: FormFieldEdit[\"ownerNames\"]\n        ) => {\n            for (const [event, handler] of Object.entries(bindings ?? {})) {\n                const replacement = names.get(handler);\n                if (replacement)\n                    plan.fields.push({\n                        codePath,\n                        ownerNames,\n                        path: [...path, event],\n                        before: handler,\n                        after: replacement,\n                    });\n            }\n        };\n        handlers(form.container?.event_bindings, [\"container\", \"event_bindings\"]);\n        const layout = form.layout as\n            | { event_bindings?: Record<string, string>; form_event_bindings?: Record<string, string> }\n            | undefined;\n        handlers(layout?.event_bindings, [\"layout\", \"event_bindings\"]);\n        handlers(layout?.form_event_bindings, [\"layout\", \"form_event_bindings\"]);\n        const walk = (components: NonNullable<FormItemYaml[\"components\"]>) => {\n            for (const child of components) {\n                const rename = edit.componentRenames?.find(\n                    (rename) => rename.formUri === uri && rename.oldName === child.name\n                );\n                handlers(child.event_bindings, [\"event_bindings\"], {\n                    before: child.name,\n                    after: rename?.newName ?? child.name,\n                });\n                walk(child.components ?? []);\n            }\n        };\n        walk(form.components ?? []);\n        for (const children of Object.values(form.components_by_slot ?? {})) walk(children);\n    }\n    for (const field of edit.formEdits ?? []) {\n        const codePath = sourcePath(project, field.formUri);\n        item(codePath);\n        plan.fields.push({\n            codePath,\n            ownerNames:\n                field.componentName === null ? undefined : { before: field.componentName, after: field.componentName },\n            path: field.path,\n            before: field.before,\n            after: field.after,\n        });\n    }\n    for (const resource of edit.resourceRenames ?? []) {\n        const codePath = sourcePath(project, resource.uri);\n        const original = item(codePath);\n        if ((original.class_name ?? original.name) !== resource.oldName)\n            throw new Error(\"A required resource name changed. Retry rename.\");\n        const newCodePath = `${codePath.split(\"/\")[0]}/${resource.newName}` as CodePath;\n        (plan.resources ??= []).push({ codePath, newCodePath, before: resource.oldName, after: resource.newName });\n        if (original.class_name)\n            plan.fields.push({ codePath, path: [\"class_name\"], before: resource.oldName, after: resource.newName });\n        else original.name = resource.newName;\n        // Resource-only moves also need a native code-history boundary.\n        if (!plan.code.has(codePath)) {\n            const before = options.documents?.get(codePath) ?? original.code;\n            if (typeof before !== \"string\") throw new Error(\"Rename requires Python source.\");\n            original.code = before;\n            plan.code.set(codePath, { before, changes: ChangeSet.empty(before.length) });\n        }\n    }\n    for (const config of edit.configEdits ?? []) {\n        if (\n            config.uri !== \"file:///app/anvil.yaml\" ||\n            ![\"startup_form\", \"startup.module\"].includes(config.path.join(\".\"))\n        )\n            throw new Error(\"Rename contains an unsupported startup reference.\");\n        let value: unknown = JSON.parse(project.files[\"/app/anvil.yaml\"]);\n        for (const key of config.path)\n            value = value && typeof value === \"object\" ? (value as Record<string, unknown>)[key] : undefined;\n        if (value !== config.before) throw new Error(\"A required startup reference changed. Retry rename.\");\n        (plan.configEdits ??= []).push(config);\n    }\n    applyFormFields(plan.items, plan.fields, { direction: \"after\" });\n    return plan;\n}\n","import { historyField, history as nativeHistory } from \"@codemirror/commands\";\nimport { foldState } from \"@codemirror/language\";\nimport { ChangeSet, EditorState, StateEffect, type Text, Transaction } from \"@codemirror/state\";\nimport { EditorView as CodeMirror, type EditorView } from \"@codemirror/view\";\nimport { ExternalUpdate, loadWithEditorHistory } from \"@/code_mirror/utils/hooks\";\nimport { HistoryState } from \"@/components/tabs/code/DesignerHistoryState\";\nimport { getAppIsEditable, updateEditorSequenceAppPaths } from \"@/controllers/app\";\nimport { refreshItemMetadata } from \"@/controllers/app/autocompleter\";\nimport {\n    getCachedCodeItem,\n    getCodeItemHistory,\n    getForms,\n    getModules,\n    getServerModules,\n    openCodeItem,\n    prepareCodeResourceRenames,\n    strHashCode,\n    syncHtmlFormAfterDesignerMutation,\n} from \"@/controllers/app/code\";\nimport { flushUnsavedCallbacks, saveAppOnIdle } from \"@/controllers/app/saving\";\nimport { confirm } from \"@/controllers/modals\";\nimport { navigate } from \"@/router/navigation\";\nimport type { AnvilAsyncAction, AnvilDispatch, CodeItemYaml, CodePath, FormItemYaml, State } from \"@/types\";\nimport { isCodePath } from \"@/types/code\";\nimport { getAnalysisEditors, getTyAnalysisEnabled } from \"./ide-analysis\";\nimport type { AnalysisProject } from \"./project\";\nimport {\n    type RenameDirection,\n    matchingRenameBoundary,\n    registerRenameHistory,\n    renameBoundaries,\n    renameBoundary,\n    renameHistoryEffects,\n} from \"./rename-history\";\nimport {\n    type AnvilWorkspaceEdit,\n    type PreparedWorkspaceEdit,\n    applyFormFields,\n    prepareWorkspaceEdit,\n    resolveField,\n} from \"./workspace-edits\";\n\ninterface TextPatch {\n    from: number;\n    to: number;\n    before: string;\n    after: string;\n}\ninterface RenameRecord {\n    id: number;\n    label: string;\n    applied: boolean;\n    fields: PreparedWorkspaceEdit[\"fields\"];\n    code: Map<CodePath, { expectedDoc: string; patches: TextPatch[] }>;\n    resources: NonNullable<PreparedWorkspaceEdit[\"resources\"]>;\n    configEdits: NonNullable<PreparedWorkspaceEdit[\"configEdits\"]>;\n    packageChanges: NonNullable<PreparedWorkspaceEdit[\"packageChanges\"]>;\n}\ninterface AppOwner {\n    appId: string;\n    dispatch: AnvilDispatch;\n    getState(): State;\n    subscribe(listener: () => void): () => void;\n}\n// Native undo tokens survive closed tabs, so keep their app-wide inverses until\n// app unload, rather than until the last editor closes.\nconst records = new Map<number, RenameRecord>();\ninterface RenameDesigner {\n    appId: string;\n    codePath: CodePath;\n    history: HistoryState;\n    refresh(rename?: { oldName: string; newName: string }): void | Promise<void>;\n}\nconst designers = new Set<RenameDesigner>();\nlet owner: AppOwner | undefined;\nlet unsubscribeOwner: (() => void) | undefined;\nlet nextId = 1;\nlet committing = false;\n\nfunction ownApp(current: AppOwner) {\n    if (owner?.appId !== current.appId) {\n        unsubscribeOwner?.();\n        records.clear();\n        unsubscribeOwner = current.subscribe(releaseUnloadedApp);\n    }\n    owner = current;\n}\n\nfunction releaseUnloadedApp() {\n    if (owner && owner.getState().app?.id !== owner.appId) {\n        records.clear();\n        owner = undefined;\n        unsubscribeOwner?.();\n        unsubscribeOwner = undefined;\n    }\n}\n\nfunction mapRecords(\n    codePath: CodePath,\n    changes: ChangeSet,\n    documents: { before: string | Text; after: string | Text; except?: number }\n) {\n    let before: string | undefined;\n    let after: string | undefined;\n    for (const record of records.values()) {\n        const code = record.code.get(codePath);\n        if (record.id === documents.except || !code) continue;\n        before ??= documents.before.toString();\n        if (code.expectedDoc !== before) continue;\n        for (const patch of code.patches) {\n            patch.from = changes.mapPos(patch.from, 1);\n            patch.to = changes.mapPos(patch.to, -1);\n        }\n        code.expectedDoc = after ??= documents.after.toString();\n    }\n}\n\nfunction abandonRedo() {\n    for (const [id, record] of records) if (!record.applied) records.delete(id);\n}\n\nfunction captureCodeHistory(editorState: EditorState) {\n    const { doc, selection, folding } = editorState.toJSON({ folding: foldState });\n    return {\n        hash: strHashCode(doc),\n        selection,\n        folding,\n        history: editorState.field(historyField),\n        renameBoundaries: editorState.field(renameBoundaries, false),\n    };\n}\n\n/** Live views supply range mappings for unrelated later typing. Cached originals\n * own closed files. Each inverse still checks exact required text and fields. */\nexport function registerAppRenameEditor(\n    view: EditorView,\n    codePath: CodePath,\n    options: AppOwner & { onError(error: unknown): void }\n) {\n    ownApp(options);\n    const unregister = registerRenameHistory(view, {\n        confirm: confirmRenameHistory,\n        prepare: (id, direction, history) => prepareRenameHistory(id, direction, { history }),\n        onError: options.onError,\n    });\n    view.dispatch({\n        effects: StateEffect.appendConfig.of(\n            CodeMirror.updateListener.of((update) => {\n                if (committing || !update.docChanged || owner?.appId !== options.appId || !records.size) return;\n                const currentPath =\n                    getAnalysisEditors(options.appId).find(([editor]) => editor === view)?.[1].codePath ?? codePath;\n                if (!isCodePath(currentPath)) return;\n                mapRecords(currentPath, update.changes, { before: update.startState.doc, after: update.state.doc });\n                if (\n                    update.transactions.some(\n                        (transaction) => !transaction.isUserEvent(\"undo\") && !transaction.isUserEvent(\"redo\")\n                    )\n                )\n                    abandonRedo();\n            })\n        ),\n    });\n    for (const record of records.values()) {\n        if (\n            record.applied &&\n            (record.code.has(codePath) || record.fields.some((field) => field.codePath === codePath))\n        ) {\n            const transaction = renameBoundary(view.state, record.id);\n            if (transaction) view.dispatch(transaction);\n        }\n    }\n    return unregister;\n}\n\nexport function registerRenameDesigner(designer: RenameDesigner) {\n    designers.add(designer);\n    for (const record of records.values())\n        if (\n            owner?.appId === designer.appId &&\n            record.applied &&\n            record.fields.some((field) => field.codePath === designer.codePath)\n        )\n            designer.history.addRenameBoundary(record.id);\n    return () => {\n        designers.delete(designer);\n    };\n}\n\nexport function abandonRenameRedo() {\n    abandonRedo();\n}\n\nfunction prepareCommit(\n    plan: PreparedWorkspaceEdit,\n    options: {\n        id: number;\n        addBoundary: boolean;\n        direction: RenameDirection;\n        history?: { view: EditorView; transaction: Transaction };\n    }\n) {\n    if (!owner || owner.getState().app?.id !== owner.appId || !getAppIsEditable(owner.getState()))\n        throw new Error(\"App is no longer editable.\");\n    const currentOwner = owner;\n    const state = currentOwner.getState();\n    const resources = plan.resources ?? [];\n    const publishResources = prepareCodeResourceRenames(resources, state);\n    for (const config of plan.configEdits ?? []) {\n        const field = resolveField(state.app!.config, config.path);\n        if (!field || field.object[field.key] !== config.before)\n            throw new Error(\"A required startup reference changed. Retry rename.\");\n    }\n    const packageItems = (plan.packageChanges ?? []).map((change) => {\n        const item = [...getForms(state), ...getModules(state), ...getServerModules(state)].find(\n            (item) => item.codePath === change.codePath\n        );\n        const cached = getCachedCodeItem(change.codePath, state);\n        if (!item || !!cached.item?.is_package !== change.before || !!item.isPackage !== change.before)\n            throw new Error(\"Module/package status changed. Retry conversion.\");\n        if (!change.after && (item.children ?? []).length)\n            throw new Error(\"Cannot convert non-empty package to module.\");\n        return change;\n    });\n    const cached = new Map<CodePath, CodeItemYaml>();\n    for (const [codePath, item] of plan.items) {\n        const original = getCachedCodeItem(codePath, state);\n        if (!original.item || original.deleted || original.renamed)\n            throw new Error(`Rename source changed: ${codePath}`);\n        cached.set(codePath, original.item);\n        if (\"class_name\" in item)\n            syncHtmlFormAfterDesignerMutation(item as FormItemYaml, state, { suppressDebug: true });\n    }\n    const activeDesigners = [...designers].filter(\n        (designer) => designer.appId === currentOwner.appId && plan.items.has(designer.codePath)\n    );\n    const liveDesignPaths = new Set(activeDesigners.map((designer) => designer.codePath));\n    const moveDesignHistory = (history: HistoryState, path: CodePath) => {\n        if (options.addBoundary) history.addRenameBoundary(options.id);\n        else history.moveRenameBoundary(options.id, options.direction);\n        history.mapRenameFields(\n            plan.fields.filter((field) => field.codePath === path),\n            options.direction\n        );\n    };\n    // A mounted Designer owns its current history. Only reconstruct cached\n    // histories for closed Designers; live instances are changed after preflight.\n    const designHistories = [...plan.items.keys()].flatMap((path) => {\n        if (liveDesignPaths.has(path)) return [];\n        const design = getCodeItemHistory(path, state)?.design;\n        if (!design) return [];\n        const history = HistoryState.fromJSON(plan.items.get(path) as FormItemYaml, design);\n        moveDesignHistory(history, path);\n        return [{ key: JSON.stringify([currentOwner.appId, \"CODE\", path]), design: history.toJSON() }];\n    });\n    const openPaths = new Set(getAnalysisEditors(currentOwner.appId).map(([, registration]) => registration.codePath));\n    const codeHistories = [...plan.code].flatMap(([path, edit]) => {\n        const saved = getCodeItemHistory(path, state)?.code;\n        if (openPaths.has(path) || !saved || saved.hash !== strHashCode(edit.before)) return [];\n        const loaded = loadWithEditorHistory(\n            { doc: edit.before, extensions: [nativeHistory(), foldState, renameHistoryEffects] },\n            saved\n        );\n        let editorState = loaded instanceof EditorState ? loaded : EditorState.create(loaded);\n        if (options.addBoundary) editorState = renameBoundary(editorState, options.id)?.state ?? editorState;\n        else editorState = matchingRenameBoundary(editorState, options.id, options.direction)?.state ?? editorState;\n        editorState = editorState.update({\n            changes: edit.changes,\n            annotations: Transaction.addToHistory.of(false),\n        }).state;\n        const code = captureCodeHistory(editorState);\n        return [{ key: JSON.stringify([currentOwner.appId, \"CODE\", path]), code }];\n    });\n    const transactions = getAnalysisEditors(currentOwner.appId).flatMap(([view, registration]) => {\n        if (!isCodePath(registration.codePath)) return [];\n        const edits = plan.code.get(registration.codePath);\n        if (!plan.items.has(registration.codePath)) return [];\n        if (edits && view.state.doc.toString() !== edits.before)\n            throw new Error(\"An open editor changed. Retry rename.\");\n        const marker = options.addBoundary ? renameBoundary(view.state, options.id) : undefined;\n        const native =\n            options.history?.view === view\n                ? options.history.transaction\n                : !options.addBoundary\n                  ? matchingRenameBoundary(view.state, options.id, options.direction)\n                  : undefined;\n        const start = native?.state ?? marker?.state ?? view.state;\n        const update = edits\n            ? start.update({\n                  changes: edits.changes,\n                  annotations: [ExternalUpdate.of(true), Transaction.addToHistory.of(false)],\n              })\n            : undefined;\n        const transactions = [native, marker, update].filter((transaction) => transaction !== undefined);\n        // A resource move recreates its view under a new codePath. Save its final\n        // native history now; the cache publisher then moves the history key.\n        if (resources.some((resource) => resource.codePath === registration.codePath)) {\n            const code = captureCodeHistory(transactions.at(-1)?.state ?? view.state);\n            codeHistories.push({ key: JSON.stringify([currentOwner.appId, \"CODE\", registration.codePath]), code });\n        }\n        return [{ view, transactions }];\n    });\n    return () => {\n        committing = true;\n        try {\n            for (const [path, edit] of plan.code)\n                mapRecords(path, edit.changes, {\n                    before: edit.before,\n                    after: plan.items.get(path)!.code as string,\n                    except: options.id,\n                });\n            for (const [path, item] of plan.items) Object.assign(cached.get(path)!, item);\n            for (const { view, transactions: changes } of transactions) if (changes.length) view.update(changes);\n            for (const designer of activeDesigners) {\n                moveDesignHistory(designer.history, designer.codePath);\n                // Redux freezes stored snapshots; keep the live history mutable.\n                designHistories.push({\n                    key: JSON.stringify([currentOwner.appId, \"CODE\", designer.codePath]),\n                    design: structuredClone(designer.history.toJSON()),\n                });\n            }\n            let activeResource: ReturnType<typeof publishResources>;\n            currentOwner.dispatch((dispatch, _getState, updateState) => {\n                updateState(\"Rename Python and Designer sources\", (state) => {\n                    for (const [originalPath] of plan.items) {\n                        const path =\n                            resources.find((resource) => resource.codePath === originalPath)?.newCodePath ??\n                            originalPath;\n                        const appPath = [\"CODE\", path] as const;\n                        state.unsavedAppPaths[JSON.stringify(appPath)] = true;\n                        updateEditorSequenceAppPaths(state.editor, [...appPath]);\n                    }\n                    for (const { key, design } of designHistories)\n                        state.editHistory[key] = { ...state.editHistory[key], design };\n                    for (const { key, code } of codeHistories)\n                        state.editHistory[key] = { ...state.editHistory[key], code };\n                    activeResource = publishResources(state);\n                    for (const change of packageItems) {\n                        const item = [...getForms(state), ...getModules(state), ...getServerModules(state)].find(\n                            (item) => item.codePath === change.codePath\n                        )!;\n                        item.isPackage = change.after;\n                    }\n                    for (const config of plan.configEdits ?? []) {\n                        const field = resolveField(state.app!.config, config.path);\n                        if (!field) throw new Error(\"A required startup field changed. Retry rename.\");\n                        field.object[field.key] = config.after;\n                        const appPath = [\"SETTINGS\", config.path[0] as \"startup_form\" | \"startup\"] as const;\n                        state.unsavedAppPaths[JSON.stringify(appPath)] = true;\n                        updateEditorSequenceAppPaths(state.editor, [...appPath]);\n                    }\n                });\n                dispatch(saveAppOnIdle());\n            });\n            for (const resource of resources) {\n                for (const record of records.values()) {\n                    const code = record.code.get(resource.codePath);\n                    if (code) {\n                        record.code.delete(resource.codePath);\n                        record.code.set(resource.newCodePath, code);\n                    }\n                    for (const field of [...record.fields, ...record.packageChanges])\n                        if (field.codePath === resource.codePath) field.codePath = resource.newCodePath;\n                }\n                for (const [, registration] of getAnalysisEditors(currentOwner.appId))\n                    if (registration.codePath === resource.codePath) registration.codePath = resource.newCodePath;\n            }\n            if (activeResource) currentOwner.dispatch(navigate(activeResource));\n        } finally {\n            committing = false;\n        }\n        const refreshes: (void | Promise<void>)[] = [];\n        for (const designer of designers) {\n            if (designer.appId !== currentOwner.appId || !plan.items.has(designer.codePath)) continue;\n            const name = plan.fields.find(\n                (field) => field.codePath === designer.codePath && field.path.length === 1 && field.path[0] === \"name\"\n            );\n            refreshes.push(\n                designer.refresh(\n                    name\n                        ? {\n                              oldName: name[options.direction === \"after\" ? \"before\" : \"after\"],\n                              newName: name[options.direction],\n                          }\n                        : undefined\n                )\n            );\n        }\n        for (const resource of resources)\n            for (const designer of designers)\n                if (designer.appId === currentOwner.appId && designer.codePath === resource.codePath)\n                    designer.codePath = resource.newCodePath;\n        // Designer-only operations have no CodeMirror diagnostic refresh to\n        // publish renamed decorators. Resource identities must also be rekeyed\n        // before the analyzer reads the published app.\n        if (getTyAnalysisEnabled(currentOwner.getState())) void currentOwner.dispatch(refreshItemMetadata());\n        return Promise.all(refreshes).then(() => {});\n    };\n}\n\n/** Apply a prepared complete operation. Saving remains the normal independent\n * app save; a failure never rolls back local rename or later user edits. */\nexport function commitWorkspaceRename(plan: PreparedWorkspaceEdit, options: AppOwner) {\n    if (!plan.items.size) return;\n    ownApp(options);\n    const id = nextId++;\n    const commit = prepareCommit(plan, { id, addBoundary: true, direction: \"after\" });\n    const code: RenameRecord[\"code\"] = new Map();\n    for (const [path, edit] of plan.code) {\n        const patches: TextPatch[] = [];\n        edit.changes.iterChanges(\n            (from, to, start, end, text) =>\n                patches.push({ from: start, to: end, before: edit.before.slice(from, to), after: text.toString() }),\n            true\n        );\n        code.set(path, { expectedDoc: plan.items.get(path)!.code as string, patches });\n    }\n    abandonRedo();\n    records.set(id, {\n        id,\n        label: plan.packageChanges?.length\n            ? \"module/package conversion\"\n            : plan.resources?.[0]\n              ? `${plan.resources[0].before} → ${plan.resources[0].after}`\n              : [...code.values()][0]?.patches[0]\n                ? `${[...code.values()][0].patches[0].before} → ${[...code.values()][0].patches[0].after}`\n                : \"component rename\",\n        fields: plan.fields.map((field) => ({ ...field })),\n        code,\n        resources: plan.resources ?? [],\n        configEdits: plan.configEdits ?? [],\n        packageChanges: plan.packageChanges ?? [],\n        applied: true,\n    });\n    return commit();\n}\n\n/** Confirm the complete inverse before either native history provider consumes\n * its token. prepareRenameHistory revalidates the sources after this resolves. */\nexport function confirmRenameHistory(id: number, direction: RenameDirection): boolean | Promise<boolean> {\n    const record = records.get(id);\n    if (direction === \"after\" || !record?.applied || !owner) return true;\n    const paths = new Set([\n        ...record.code.keys(),\n        ...record.fields.map((field) => field.codePath),\n        ...record.resources.map((resource) => resource.newCodePath),\n    ]);\n    const structural = record.fields.length || record.resources.length || record.configEdits.length;\n    if (paths.size < 2 && !structural) return true;\n    const scope = `${paths.size} ${paths.size === 1 ? \"code item\" : \"code items\"}`;\n    const details = [\n        record.fields.length && \"Form and Designer references\",\n        record.configEdits.length && \"app settings\",\n    ]\n        .filter(Boolean)\n        .join(\" and \");\n    return owner\n        .dispatch(\n            confirm(\n                \"Undo rename?\",\n                `Undo ${record.label} across ${scope}${details ? `, including ${details}` : \"\"}? The complete rename will be undone together.`,\n                { text: \"Undo rename\", defaultButton: false },\n                { text: \"Cancel\", defaultButton: true }\n            )\n        )\n        .then((result) => result === true);\n}\n\n/** Load original sources before asking the analyzer to establish a rename target. */\nexport const loadWorkspaceRenameSources = (): AnvilAsyncAction<void> => async (dispatch, getState) => {\n    flushUnsavedCallbacks();\n    const paths = [...getForms(getState()), ...getModules(getState()), ...getServerModules(getState())].map(\n        (item) => item.codePath\n    );\n    await Promise.all(paths.map((path) => dispatch(openCodeItem(path))));\n};\n\n/** Both code and Designer consumers apply the same fresh, original-source operation. */\nexport async function applyPythonRename(\n    answer: { result: AnvilWorkspaceEdit; project: AnalysisProject; isCurrent(): boolean },\n    options: AppOwner\n) {\n    if (!answer.isCurrent()) return false;\n    const items = new Map<CodePath, CodeItemYaml>();\n    const state = options.getState();\n    for (const { codePath } of [...getForms(state), ...getModules(state), ...getServerModules(state)]) {\n        const cached = getCachedCodeItem(codePath, state);\n        if (cached.item && !cached.deleted && !cached.renamed) items.set(codePath, cached.item);\n    }\n    const documents = new Map(\n        getAnalysisEditors(options.appId).flatMap(([editor, { codePath }]) =>\n            isCodePath(codePath) ? [[codePath, editor.state.doc.toString()] as const] : []\n        )\n    );\n    const plan = prepareWorkspaceEdit(answer.project, answer.result, { items, documents });\n    if (!answer.isCurrent()) return false;\n    if (!plan.items.size) throw new Error(\"This symbol cannot be renamed to that name.\");\n    await commitWorkspaceRename(plan, options);\n    return true;\n}\n\nexport function prepareRenameHistory(\n    id: number,\n    direction: RenameDirection,\n    options: { history?: { view: EditorView; transaction: Transaction } } = {}\n): (() => void) | undefined {\n    const record = records.get(id);\n    if (!record || record.applied === (direction === \"after\")) return undefined;\n    if (!owner || owner.getState().app?.id !== owner.appId) return undefined;\n    const source = direction === \"after\" ? \"before\" : \"after\";\n    const plan: PreparedWorkspaceEdit = {\n        items: new Map(),\n        code: new Map(),\n        fields: record.fields,\n        resources: record.resources.map((resource) =>\n            direction === \"after\"\n                ? resource\n                : {\n                      codePath: resource.newCodePath,\n                      newCodePath: resource.codePath,\n                      before: resource.after,\n                      after: resource.before,\n                  }\n        ),\n        packageChanges: record.packageChanges.map((change) =>\n            direction === \"after\" ? change : { ...change, before: change.after, after: change.before }\n        ),\n        configEdits: record.configEdits.map((config) =>\n            direction === \"after\" ? config : { ...config, before: config.after, after: config.before }\n        ),\n    };\n    const paths = new Set([...record.code.keys(), ...record.fields.map((field) => field.codePath)]);\n    for (const path of paths) {\n        const original = getCachedCodeItem(path, owner.getState());\n        if (!original.item || original.deleted || original.renamed)\n            throw new Error(\"A required rename source changed.\");\n        plan.items.set(path, structuredClone(original.item));\n    }\n    const nextPatches = new Map<CodePath, TextPatch[]>();\n    for (const [path, code] of record.code) {\n        const views = getAnalysisEditors(owner.appId).filter(([, registration]) => registration.codePath === path);\n        const before = views[0]?.[0].state.doc.toString() ?? plan.items.get(path)!.code;\n        if (before !== code.expectedDoc)\n            throw new Error(\"A required rename source changed. Undo its later edits first.\");\n        for (const patch of code.patches)\n            if (before.slice(patch.from, patch.to) !== patch[source])\n                throw new Error(\"A renamed identifier changed. Undo its later edits first.\");\n        const changes = ChangeSet.of(\n            code.patches.map((patch) => ({ from: patch.from, to: patch.to, insert: patch[direction] })),\n            before.length\n        );\n        plan.code.set(path, { before, changes });\n        plan.items.get(path)!.code = changes.apply(EditorState.create({ doc: before }).doc).toString();\n        const patches: TextPatch[] = [];\n        let index = 0;\n        changes.iterChanges(\n            (_from, _to, start, end) => patches.push({ ...code.patches[index++], from: start, to: end }),\n            true\n        );\n        nextPatches.set(path, patches);\n    }\n    applyFormFields(plan.items, plan.fields, { direction });\n    for (const resource of plan.resources ?? []) {\n        const item = plan.items.get(resource.codePath);\n        if (!item) throw new Error(\"A required resource identity changed.\");\n        if (!item.class_name) item.name = resource.after;\n    }\n    for (const change of plan.packageChanges ?? []) plan.items.get(change.codePath)!.is_package = change.after;\n    const commit = prepareCommit(plan, { id, addBoundary: false, direction, history: options.history });\n    return () => {\n        record.applied = direction === \"after\";\n        for (const [path, patches] of nextPatches)\n            record.code.set(path, { patches, expectedDoc: plan.items.get(path)!.code as string });\n        commit();\n    };\n}\n","import { AgentTypeId, ConversationEvent, ConversationInfo, ConversationPid, ConversationUpdates } from \"@/agent/types\";\nimport { AppId } from \"@/types\";\nimport { del, get, post, put } from \"@/util/fetch\";\n\nexport const listConversations = (appId: AppId) =>\n    get(`/ide/agents/conversations?app_id=${appId}`) as Promise<ConversationInfo[]>;\n\nexport const getConversation = (conversationPid: ConversationPid) =>\n    get(`/ide/agents/conversations/${conversationPid}`) as Promise<{\n        conversation: ConversationInfo;\n        events: ConversationEvent[];\n    }>;\n\nexport const createConversation = (app_id: AppId, agent_type: AgentTypeId, env_id?: number) =>\n    post(`/ide/agents/conversations`, { app_id, agent_type, env_id }) as Promise<ConversationInfo>;\n\nexport const deleteConversation = (conversationPid: ConversationPid) =>\n    del(`/ide/agents/conversations/${conversationPid}`);\n\nexport const updateConversationInfo = (conversationPid: ConversationPid, updates: ConversationUpdates) =>\n    put(`/ide/agents/conversations/${conversationPid}`, updates) as Promise<ConversationInfo>;\n\nexport const resetAllAgents = (appId: AppId) => post(`/ide/agents/reset?app_id=${appId}`);\n\nexport const restartAgent = (conversationPid: ConversationPid) =>\n    post(`/ide/agents/conversations/${conversationPid}/restart`);\n\nexport interface TurnDiffFile {\n    path: string;\n    status: \"added\" | \"modified\" | \"deleted\";\n}\n\nexport type AgentFileDiffContent =\n    | { oldText: string | null; newText: string | null; unavailable?: never }\n    | { unavailable: string; oldText?: never; newText?: never };\n\nconst turnDiffUrl = (conversationPid: ConversationPid, promptPid: string) =>\n    `/ide/agents/conversations/${conversationPid}/turns/${promptPid}/diff`;\n\nexport const getTurnDiff = (conversationPid: ConversationPid, promptPid: string) =>\n    get(turnDiffUrl(conversationPid, promptPid)) as Promise<{ files: TurnDiffFile[]; expired?: boolean }>;\n\nexport const getTurnFileDiff = (conversationPid: ConversationPid, promptPid: string, path: string) =>\n    get(`${turnDiffUrl(conversationPid, promptPid)}?path=${encodeURIComponent(path)}`) as Promise<AgentFileDiffContent>;\n","import { omit } from \"lodash-es\";\nimport type { IDETask } from \"@/controllers/ide_tasks\";\nimport { AppId } from \"@/types\";\nimport type {\n    AccessibleTableMapping,\n    AppSchema,\n    ColumnSpec,\n    Diff,\n    Table,\n    TableId,\n    TableIndex,\n    TableMapping,\n    TableMappingId,\n} from \"@/types/database\";\nimport { valOrDefault } from \"../util\";\nimport { del, get, post, put, urlQueryParams } from \"../util/fetch\";\n\nexport const getAppAccessibleTableMappings = (appId: string, abort?: AbortController) =>\n    get<AccessibleTableMapping[]>(`/ide/tables/${appId}/accessible-table-mappings`, { signal: abort?.signal });\n\nexport const linkExistingMapping = (appId: string, mappingId: TableMappingId) =>\n    post<void>(`/ide/tables/${appId}/add-table-mapping/${mappingId}`);\n\ntype AppTableMap = Record<string, { id?: string; [key: string]: unknown }>;\n\n// TODO: code taken from TableServiceApi.js - needs updating\n// Called from addService in services.js\nexport const getAppTables = async (appId: string) => {\n    const appMap = await get<AppTableMap>(`/ide/tables/${appId}/tables`);\n    const apps = [];\n    for (const appId in appMap) {\n        appMap[appId].id = appId;\n        apps.push(appMap[appId]);\n    }\n    return apps;\n};\n\ntype LinkedTable = Pick<Table, \"id\" | \"name\" | \"python_name\">;\n\ninterface LinkedTableAccessResponse {\n    table_id: TableId;\n    python_name: string;\n    client: Table[\"client\"];\n    server: Table[\"server\"];\n    schema: TableMapping[\"schema\"][string];\n}\n\nexport const linkExistingTable = (appId: string, mappingId: TableMappingId, table: LinkedTable) =>\n    post<LinkedTableAccessResponse>(\n        `/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${table.id}/access`,\n        table\n    );\n\ninterface CreatedTableResponse {\n    id: TableId;\n    name: string;\n    access: {\n        python_name: string;\n        client: Table[\"client\"];\n        server: Table[\"server\"];\n    };\n    schema: TableMapping[\"schema\"][string];\n}\n\nexport const createTable = (\n    appId: string,\n    mappingId: TableMappingId,\n    table: { name: string; python_name: string },\n    split: boolean\n) => post<CreatedTableResponse>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/new`, { ...table, split });\n\nexport const updateTable = (appId: string, mappingId: TableMappingId, table: Table) =>\n    post<Partial<Table>>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${table.id}`, table);\n\nexport const deleteTable = (appId: string, mappingId: TableMappingId, table: Table) =>\n    del<void>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${table.id}/access`);\n\nexport const applySchemaDiff = (appId: string, mappingId: TableMappingId, actions: Diff[], split: boolean) =>\n    post<TableMapping>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/batch`, { actions, split });\n\nexport const forceSetSchema = (appId: string, mappingId: TableMappingId, schema: AppSchema) =>\n    post<void>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/force-set-schema`, { schema });\n\nexport const saveTableCol = (\n    appId: string,\n    mappingId: TableMappingId,\n    tableId: TableId,\n    colId: string,\n    colSpec: ColumnSpec\n) =>\n    post<ColumnSpec & { id: string; schema: TableMapping[\"schema\"][string] }>(\n        `/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/cols${colId ? `/${colId}` : \"\"}`,\n        colSpec\n    );\n\nexport const deleteTableCol = (appId: string, mappingId: TableMappingId, tableId: TableId, colId: string) =>\n    del<void>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/cols/${colId}`);\n\nexport const modifyTableIndex = (\n    appId: AppId,\n    mappingId: TableMappingId | undefined,\n    tableId: TableId,\n    index: TableIndex,\n    action: \"create\" | \"delete\"\n): Promise<TableIndex[]> =>\n    post(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/indexes/${action}`, index);\n\ninterface AccessDef {\n    app_id: string;\n    table_mapping_id: TableMappingId;\n    table_id: TableId;\n    python_name: string;\n}\n\nexport const updateTableAccess = (access: AccessDef) =>\n    put<void>(\n        `/ide/tables/${access.app_id}/db/${valOrDefault(access.table_mapping_id)}/tables/${access.table_id}/access`,\n        access\n    );\n\ntype Hints = Record<string, unknown> | undefined;\n\nexport const getTableMappings = (appId: string, app_schema: AppSchema, hints: Hints, abort?: AbortController) =>\n    post<TableMapping[]>(`/ide/tables/${appId}/get-dbs`, { app_schema, hints }, { signal: abort?.signal });\n\nexport const getTableMapping = (appId: string, mappingId: TableMappingId, app_schema: AppSchema, hints: Hints) =>\n    post<TableMapping>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}`, { app_schema, hints });\n\nexport const createTableMapping = (\n    appId: string,\n    name: string,\n    schema: AppSchema,\n    split: boolean,\n    deploymentPoolId: string | null = null\n) => post<TableMapping>(`/ide/tables/${appId}/db/new`, { name, schema, split, into_dp: deploymentPoolId });\n\n// Can't rename default table mapping.\nexport const renameTableMapping = (appId: string, mapping: TableMapping, name: string) =>\n    put<void>(`/ide/tables/${appId}/db/${mapping.table_mapping_id}/`, { name });\n\nexport const setTableMappingRestricted = (appId: string, mapping: TableMapping, restricted: boolean) =>\n    put<TableMapping>(`/ide/tables/${appId}/db/${mapping.table_mapping_id}/restricted`, { restricted });\n\n// Can't delete default table mapping\nexport const deleteTableMapping = (appId: string, mappingId: TableMappingId) =>\n    del<{ error?: unknown }>(`/ide/tables/${appId}/db/${mappingId}/`);\n\nexport const removeTableMappingAccess = (appId: string, mappingId: TableMappingId) =>\n    post<{ error?: unknown }>(`/ide/tables/${appId}/db/${mappingId}/remove`);\n\ninterface RowFetchParams {\n    more?: number | string | null;\n    pageSize: number;\n    sort: unknown;\n}\n\nexport interface TableRowsPage<\n    TRow extends Record<string, unknown> & { id: number } = Record<string, unknown> & { id: number },\n> {\n    more?: number | null;\n    rows: TRow[];\n}\n\nexport const getTableRows = async <\n    TRow extends Record<string, unknown> & { id: number } = Record<string, unknown> & { id: number },\n>(\n    appId: string,\n    mappingId: TableMappingId,\n    tableId: TableId,\n    params: RowFetchParams\n) =>\n    get<TableRowsPage<TRow>>(\n        urlQueryParams(\n            `/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/rows`,\n            params.more ? params : omit(params, \"more\")\n        )\n    );\n\nexport const addTableRow = (appId: string, mappingId: TableMappingId, tableId: TableId, row: Record<string, unknown>) =>\n    post<Record<string, unknown> & { id: string | number }>(\n        `/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/rows`,\n        row\n    );\n\nexport const getTableRow = (appId: string, mappingId: TableMappingId, tableId: TableId, rowId: string | number) =>\n    get<Record<string, unknown>>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/rows/${rowId}`);\n\nexport const getLiveObject = (appId: string, mappingId: TableMappingId, tableId: TableId, rowId: string | number) =>\n    get<Record<string, unknown>>(\n        `/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/rows/${rowId}/link.json`\n    );\n\n// Must pass either rowId or rowToCreate\nexport const uploadMedia = async (\n    appId: string,\n    mappingId: TableMappingId,\n    tableId: TableId,\n    rowId: string | undefined | number,\n    colId: string,\n    blob: File,\n    rowToCreate: Record<string, unknown> | null = null,\n    onProgressUpdate: null | ((chunk: number) => void) = null,\n    aborter: null | AbortController = null\n) => {\n    const rootUrl = `/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/rows/${rowId}`;\n    const resp = await fetch(\n        urlQueryParams(`${rootUrl}/start-chunked-media-upload/${colId}/${encodeURIComponent(blob.name)}`, {\n            type: blob.type,\n        }),\n        {\n            method: \"POST\",\n            body: rowToCreate && JSON.stringify(rowToCreate),\n            headers: { \"Content-Type\": \"application/json\" },\n        }\n    );\n    const server = /platform-server-(.*)/.exec(resp.headers.get(\"x-server\") ?? \"\")?.[1] ?? \"\";\n    const { uploadId } = await resp.json();\n\n    const CHUNK_SIZE = 1000000; // 1 Mb chunks\n\n    const chunkCount = Math.ceil(blob.size / CHUNK_SIZE);\n    console.log(`Uploading ${chunkCount} chunks for file of size ${blob.size}`);\n    for (let i = 0; i < chunkCount; i++) {\n        const last = i === chunkCount - 1;\n        if (aborter?.signal.aborted) {\n            console.log(\"Upload aborted\");\n            return;\n        }\n        const chunkResp = await (\n            await fetch(`${rootUrl}/add-media-chunk/${encodeURIComponent(uploadId)}?last=${last}`, {\n                method: \"POST\",\n                body: blob.slice(i * CHUNK_SIZE, Math.min((i + 1) * CHUNK_SIZE, blob.size)),\n                headers: {\n                    \"Content-Type\": \"application/octet-stream\",\n                    \"Platform-Server\": server,\n                },\n            })\n        ).json();\n        onProgressUpdate?.(((i + 1) * 100) / chunkCount);\n        if (last) {\n            console.log(\"Upload finished:\", chunkResp);\n            return chunkResp;\n        } else {\n            //console.log(`Chunk ${i} response:`, chunkResp);\n        }\n    }\n};\n\nexport const deleteMedia = (appId: string, mappingId: TableMappingId, tableId: TableId, rowId: string, colId: string) =>\n    del<void>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/rows/${rowId}/media/${colId}`);\n\nexport const deleteTableRow = (appId: string, mappingId: TableMappingId, tableId: TableId, rowId: string | number) =>\n    del<void>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/rows/${rowId}`);\n\nexport const updateTableRow = (\n    appId: string,\n    mappingId: TableMappingId,\n    tableId: TableId,\n    rowId: string | number,\n    data: Record<string, unknown>\n) => post<void>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/rows/${rowId}`, data);\n\nexport const deleteAllRows = (appId: string, mappingId: TableMappingId, tableId: TableId) =>\n    del<void>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/rows`);\n\nexport const getTableDownloadUrl = (appId: string, mappingId: TableMappingId, tableId: TableId) =>\n    `/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/export.csv`;\n\nexport const getMediaDownloadUrl = (\n    appId: string,\n    mappingId: TableMappingId,\n    tableId: TableId,\n    rowId: string,\n    colId: string\n) => `/ide/tables/${appId}/db/${valOrDefault(mappingId)}/tables/${tableId}/rows/${rowId}/media/${colId}`;\n\nexport const cloneDatabase = (\n    appId: string,\n    mappingId: TableMappingId,\n    withoutMedia = false,\n    deploymentPoolId: string | null = null,\n    split: boolean | null = null\n) =>\n    post<TableMapping>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/clone`, {\n        without_media: withoutMedia,\n        into_dp: deploymentPoolId,\n        split,\n    });\n\ninterface RestoreDatabaseResponse {\n    newMapping: TableMapping;\n    task: IDETask;\n}\n\nexport const restoreDatabase = (\n    appId: string,\n    mappingId: TableMappingId,\n    withoutMedia = false,\n    deploymentPoolId: string | null = null,\n    targetTime: string\n) =>\n    post<RestoreDatabaseResponse>(`/ide/tables/${appId}/db/${valOrDefault(mappingId)}/restore`, {\n        without_media: withoutMedia,\n        into_dp: deploymentPoolId,\n        target_time: targetTime,\n    });\n","import { CompletionContext, type CompletionSource } from \"@codemirror/autocomplete\";\nimport { globalCompletion } from \"@codemirror/lang-python\";\nimport { syntaxTree } from \"@codemirror/language\";\n\nexport const pythonGlobalCompletions: CompletionSource = async (context) => {\n    const beforeSpace = context.matchBefore(/[ \\t]*$/)?.from ?? context.pos;\n    const node = syntaxTree(context.state).resolveInner(beforeSpace, -1);\n    // lang-python suppresses PropertyName, but still offers globals immediately\n    // after a dot. Imports also need module names rather than builtin names.\n    if (\n        node.name === \".\" ||\n        (node.name === \"MemberExpression\" && node.getChild(\".\")) ||\n        node.name === \"ImportStatement\" ||\n        node.parent?.name === \"ImportStatement\"\n    ) {\n        return null;\n    }\n    // The worker offers suggestions even before a word is typed. Include globals\n    // in that result too, since CodeMirror reuses it as the user starts typing.\n    const result = await globalCompletion(new CompletionContext(context.state, context.pos, true, context.view));\n    return result ? { ...result, options: result.options.filter(({ type }) => type !== \"keyword\") } : null;\n};\n","import { useEffect, useId, useMemo } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport {\n    Completion,\n    CompletionContext,\n    CompletionResult,\n    type CompletionSource,\n    acceptCompletion,\n    startCompletion,\n} from \"@codemirror/autocomplete\";\nimport { syntaxTree } from \"@codemirror/language\";\nimport { Prec } from \"@codemirror/state\";\nimport { EditorView, keymap } from \"@codemirror/view\";\nimport { SyntaxNode } from \"@lezer/common\";\nimport { type LspCompletion, type LspCompletionList, pythonCompletionSources } from \"@/analysis/completions\";\nimport { type DiagnosticReport, type DiagnosticRequest } from \"@/analysis/diagnostics\";\nimport {\n    getTyAnalysisEnabled,\n    registerAnalysisContext,\n    requestPython,\n    requestPythonContext,\n    requestPythonItemMetadata,\n} from \"@/analysis/ide-analysis\";\nimport { type AnalysisProject, analysisProjectKind } from \"@/analysis/project\";\nimport type { PythonQuickFix } from \"@/analysis/quick-fixes\";\nimport type { PythonContext } from \"@/analysis/session\";\nimport { getAppId } from \"@/controllers/app\";\nimport { alert } from \"@/controllers/modals\";\nimport { AnvilDispatch, CodeItemType, CodeItemYaml, CodePath, type EditorPath, type ExtraFilePath } from \"@/types\";\nimport {\n    analyseIsolatedFormCode,\n    analyseItem,\n    analyseReplCode,\n    updateItemMetadata,\n} from \"../../controllers/app/autocompleter\";\nimport useEvent from \"../../util/useEventCallback\";\nimport { useExtension } from \"../utils/hooks\";\nimport { analysisFailuresField, setAnalysisFailures } from \"./analysis-status\";\nimport { pythonAutocompletion, pythonCompletionAllowed } from \"./completion-extension\";\nimport { metadataEffects, useDiagnostics } from \"./diagnostics\";\nimport { CompletionInfoElement } from \"./info\";\nimport { clearParamaterHelper, paramaterTooltipField, setParamaterHelper } from \"./paramater_tooltip\";\nimport { pythonGlobalCompletions } from \"./python-globals\";\nimport type { Analysis, DoAnalysisFunc } from \"./types\";\n\nexport const completionTab = Prec.highest(keymap.of([{ key: \"Tab\", run: acceptCompletion }]));\n\nconst getCompletions = Prec.highest(\n    keymap.of([\n        {\n            key: \"Tab\",\n            run: (view) => {\n                const { ranges } = view.state.selection;\n                if (ranges.length !== 1 || !ranges[0].empty) {\n                    // must be a single cursor\n                    return false;\n                }\n                const pos = ranges[0].head;\n                const line = view.state.doc.lineAt(pos);\n                // if we're at the start of a line then don't autcomplete\n                if (/^\\s*$/.test(line.text.slice(0, pos - line.from))) {\n                    return false;\n                }\n                return startCompletion(view);\n            },\n        },\n    ])\n);\n\n/** Select Ty or the original completer here, including the delayed import source. */\nfunction usePythonCompletionEngine(\n    view: EditorView,\n    doAnalysis: DoAnalysisFunc | undefined,\n    options?: {\n        completionSources: [CompletionSource, CompletionSource];\n        diagnosticRequest?: DiagnosticRequest;\n        prepareCompletion(signal: AbortSignal): Promise<unknown>;\n    }\n) {\n    const analysisEnabled = useSelector(getTyAnalysisEnabled);\n    const tyCompletionEnabled = Boolean(options?.completionSources && analysisEnabled);\n    const diagnosticLinter = useDiagnostics(\n        view,\n        doAnalysis,\n        options?.diagnosticRequest ? { request: options.diagnosticRequest } : undefined\n    );\n\n    const completionOverride = useEvent((context: CompletionContext) => {\n        if (tyCompletionEnabled && options) return options.completionSources[0](context);\n        return doAnalysis ? requestCompletions(view, context, doAnalysis) : null;\n    });\n\n    const importCompletionOverride = useEvent((context: CompletionContext) =>\n        tyCompletionEnabled && options ? options.completionSources[1](context) : null\n    );\n    const dispatch = useDispatch<AnvilDispatch>();\n    const prepareCompletion = useEvent((signal: AbortSignal) => options?.prepareCompletion(signal));\n    useEffect(() => {\n        if (!tyCompletionEnabled) return;\n        const controller = new AbortController();\n        void prepareCompletion(controller.signal)?.catch((error) => {\n            if (!controller.signal.aborted) dispatch(alert(\"Python completion unavailable\", String(error)));\n        });\n        return () => controller.abort();\n    }, [view, tyCompletionEnabled, options?.completionSources]);\n\n    useExtension(\n        view,\n        () =>\n            doAnalysis || tyCompletionEnabled\n                ? [\n                      completionTab,\n                      getCompletions,\n                      Prec.highest(\n                          keymap.of([\n                              {\n                                  key: \"Escape\",\n                                  run: (view) => {\n                                      clearParamaterHelper(view);\n                                      return false;\n                                  },\n                              },\n                          ])\n                      ),\n                      pythonAutocompletion(\n                          tyCompletionEnabled ? [completionOverride, importCompletionOverride] : completionOverride,\n                          { analysis: tyCompletionEnabled }\n                      ),\n                      EditorView.domEventHandlers({\n                          blur: (_event, view) => {\n                              clearParamaterHelper(view);\n                          },\n                      }),\n                      paramaterTooltipField,\n                      diagnosticLinter,\n                      analysisFailuresField,\n                  ]\n                : [],\n        [tyCompletionEnabled]\n    );\n}\n\nfunction useTyCompletions(view: EditorView, codePath: EditorPath) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const completionSources = useMemo(\n        () =>\n            pythonCompletionSources(\n                ({ method, offset, signal, item, autoImport }) =>\n                    dispatch(\n                        requestPython<LspCompletionList | LspCompletion | null>(view, codePath, {\n                            method,\n                            offset,\n                            signal,\n                            params: item,\n                            autoImport,\n                        })\n                    ),\n                { onError: (error) => dispatch(alert(\"Python completion unavailable\", String(error))) }\n            ),\n        [view, codePath]\n    );\n    const prepareCompletion = useEvent((signal: AbortSignal) =>\n        dispatch(requestPython(view, codePath, { method: \"anvil/prepareCompletion\", offset: 0, signal }))\n    );\n    return { completionSources, prepareCompletion };\n}\n\nexport function useServerTestAutoComplete(view: EditorView, codePath: ExtraFilePath) {\n    const completions = useTyCompletions(view, codePath);\n    const diagnosticRequest = useTyDiagnosticRequest(codePath);\n    usePythonCompletionEngine(\n        view,\n        undefined,\n        analysisProjectKind(codePath) === \"serverTests\" ? { ...completions, diagnosticRequest } : undefined\n    );\n}\n\nfunction useTyDiagnosticRequest(codePath: EditorPath): DiagnosticRequest {\n    const dispatch = useDispatch<AnvilDispatch>();\n    return useEvent(async (editor: EditorView, signal: AbortSignal) => {\n        const answer = await dispatch(\n            requestPython<DiagnosticReport>(editor, codePath, {\n                method: \"textDocument/diagnostic\",\n                offset: 0,\n                signal,\n            })\n        );\n        const uri = answer?.project.uris[codePath];\n        const fixes =\n            uri && answer?.result.items.length\n                ? await dispatch(\n                      requestPython<PythonQuickFix[]>(editor, codePath, {\n                          method: \"textDocument/codeAction\",\n                          offset: 0,\n                          signal,\n                          params: {\n                              textDocument: { uri },\n                              range: {\n                                  start: { line: 0, character: 0 },\n                                  end: {\n                                      line: editor.state.doc.lines - 1,\n                                      character: editor.state.doc.line(editor.state.doc.lines).length,\n                                  },\n                              },\n                              context: { diagnostics: answer.result.items },\n                          },\n                      })\n                  )\n                : undefined;\n        return (\n            answer && {\n                result: answer.result,\n                isCurrent: () => answer.isCurrent() && (!fixes || fixes.isCurrent()),\n                quickFixes: uri && fixes ? { uri, actions: fixes.result } : undefined,\n            }\n        );\n    });\n}\n\nexport function useAutoComplete(\n    view: EditorView,\n    itemType: CodeItemType,\n    codeItem: CodeItemYaml,\n    options: { codePath: CodePath }\n) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { completionSources, prepareCompletion } = useTyCompletions(view, options.codePath);\n    const requestDiagnostics = useTyDiagnosticRequest(options.codePath);\n    const diagnosticRequest: DiagnosticRequest = useEvent(async (editor: EditorView, signal: AbortSignal) => {\n        const [answer, metadata] = await Promise.all([\n            requestDiagnostics(editor, signal),\n            dispatch(requestPythonItemMetadata(editor, options.codePath, { signal })),\n        ]);\n        return (\n            answer &&\n            metadata && {\n                ...answer,\n                isCurrent: () => answer.isCurrent() && metadata.isCurrent(),\n                effects: metadataEffects(metadata.result),\n                publishMetadata: () => updateItemMetadata(codeItem, itemType, metadata.result),\n            }\n        );\n    });\n    const doAnalysis: DoAnalysisFunc = useEvent(\n        (autocomplete: boolean, line?: number, col?: number, pos?: number, seed?: string) => {\n            const item = { ...codeItem, code: view.state.doc.toString() };\n            return dispatch(analyseItem(item, itemType, autocomplete, line, col, pos, seed));\n        }\n    );\n    usePythonCompletionEngine(\n        view,\n        doAnalysis,\n        itemType === \"script\" ? undefined : { completionSources, diagnosticRequest, prepareCompletion }\n    );\n}\n\ntype CompletionContextScope =\n    | { kind: \"repl\"; isServer: boolean; previousCode: string }\n    | { kind: \"binding\"; formUri: string };\n\nfunction useContextCompletion(view: EditorView, getScope: (project: AnalysisProject) => CompletionContextScope) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const appId = useSelector(getAppId);\n    const id = useId();\n    const getContext = useEvent(\n        (project: AnalysisProject): PythonContext => ({\n            ...getScope(project),\n            id,\n            code: view.state.doc.toString(),\n        })\n    );\n    useEffect(() => registerAnalysisContext(view, id, appId), [view, id, appId]);\n    const completionSources = useMemo(\n        () =>\n            pythonCompletionSources(\n                ({ method, offset, signal, item, autoImport }) =>\n                    dispatch(\n                        requestPythonContext<LspCompletionList | LspCompletion | null>(view, getContext, {\n                            method,\n                            offset,\n                            signal,\n                            params: item,\n                            autoImport,\n                        })\n                    ),\n                { onError: (error) => dispatch(alert(\"Python completion unavailable\", String(error))) }\n            ),\n        [view, appId]\n    );\n    const prepareCompletion = useEvent((signal: AbortSignal) =>\n        dispatch(requestPythonContext(view, getContext, { method: \"anvil/prepareCompletion\", offset: 0, signal }))\n    );\n    return { completionSources, prepareCompletion };\n}\n\nexport function useIsolatedFormCodeAutoComplete(view: EditorView, form: CodeItemYaml) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const completion = useContextCompletion(view, (project) => {\n        const formUri = project.uris[`forms/${form.class_name}`];\n        if (!formUri) throw new Error(\"Binding Form is unavailable\");\n        return { kind: \"binding\", formUri };\n    });\n    const doAnalysis: DoAnalysisFunc = useEvent(\n        (autocomplete: boolean, line?: number, col?: number, pos?: number, seed?: string) => {\n            const code = view.state.doc.toString();\n            return dispatch(analyseIsolatedFormCode(autocomplete, line!, col!, pos!, seed!, form, code));\n        }\n    );\n    usePythonCompletionEngine(view, doAnalysis, completion);\n}\n\nexport function useReplAutoComplete(\n    view: EditorView,\n    codeItem: CodeItemYaml,\n    isServer: boolean,\n    invalidate: () => void\n) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const completion = useContextCompletion(view, () => ({\n        kind: \"repl\",\n        isServer,\n        previousCode: codeItem.code ?? \"\",\n    }));\n    const doAnalysis: DoAnalysisFunc = useEvent(\n        async (autocomplete: boolean, line?: number, col?: number, pos?: number, seed?: string) => {\n            const code = view.state.doc.toString();\n            const rv = await dispatch(analyseReplCode(code, codeItem, isServer, autocomplete, line, col, pos, seed));\n            // if replCodeFailed then invalidate the last session\n            if (rv === undefined) {\n                invalidate();\n            }\n            return rv ?? {};\n        }\n    );\n    usePythonCompletionEngine(view, doAnalysis, completion);\n}\n\nasync function requestCompletions(\n    view: EditorView,\n    context: CompletionContext,\n    doAnalysis: DoAnalysisFunc\n): Promise<CompletionResult | null> {\n    if (!pythonCompletionAllowed(context)) {\n        // it's super annoying to autocomplete after a `:` character!\n        clearParamaterHelper(view);\n        return null;\n    }\n    const { seed, from, to, filter, validFor } = getCompletionProps(context);\n\n    const { pos, state } = context;\n    const line = state.doc.lineAt(pos);\n    const col = pos - line.from;\n    const [analysis, globals] = await Promise.all([\n        doAnalysis(true, line.number - 1, col, pos, seed),\n        pythonGlobalCompletions(context),\n    ]);\n    if (context.aborted || view.state.doc !== state.doc) return null;\n    view.dispatch({ effects: setAnalysisFailures.of(analysis.analysisFailures || []) });\n    const { completions, messages, references, httpEndpoints, emailEndpoints, routes, eventHandlers } = analysis;\n\n    setParamaterHelper(view, completions?.parameterHelper, { pos, from, to });\n\n    const options = getCompletionOptions(analysis, seed);\n    // Keep enum values and known subscript keys focused on the analyzer's suggestions.\n    const globalOptions =\n        analysis.subscripts || completions?.some(({ text }) => text.startsWith(\"'\")) ? [] : (globals?.options ?? []);\n    const scopeNames = new Set(options.map(({ label }) => label));\n    return {\n        from,\n        to,\n        filter,\n        validFor,\n        options: [...options, ...globalOptions.filter(({ label }) => !scopeNames.has(label))],\n    };\n}\n\nconst Spans = {\n    normal: /\\w*$/,\n    string: /['\"]\\w+$/,\n    // we want the autocomplete to retrigger if it's an empty string so we use \\w+\n};\n\nfunction tokenStringMatch(context: CompletionContext) {\n    let token: null | SyntaxNode = syntaxTree(context.state).resolve(context.pos);\n    while (token && token.name !== \"String\") token = token.parent;\n    if (token === null) {\n        return null;\n    }\n    const text = context.state.sliceDoc(token.from, context.pos);\n    const to = token.to;\n    return { from: token.from, to, text };\n}\n\nfunction getCompletionProps(context: CompletionContext) {\n    const { pos } = context;\n    let seed = \"\";\n    let from = pos;\n    let to = pos;\n    let filter = true;\n    let validFor = Spans.normal;\n    let importMatch, wordMatch, stringMatch;\n    if (context.matchBefore(/^\\s*from\\s+\\.+\\s*\\S*$/) && (importMatch = context.matchBefore(/\\.+\\s*\\S*$/))) {\n        /**@todo find the end of the identifier/import statement match */\n        ({ text: seed, from } = importMatch);\n    } else if (context.matchBefore(/^\\s*from\\s+[\\w.]+$/) && (importMatch = context.matchBefore(/[\\w.]+$/))) {\n        // Replace the whole module path so the worker can complete it as a module lookup.\n        ({ text: seed, from } = importMatch);\n    } else if ((stringMatch = tokenStringMatch(context))) {\n        ({ text: seed, from, to } = stringMatch);\n        validFor = Spans.string;\n        // the span determines whether codemirror calls the autocompletions based on the current from/to\n        filter = seed.length > 1;\n        // don't filter for an empty string because the fuzzy search doesn't work on ''\n        // an alternative approach would be to make the completionFrom value 1 less\n        // and insert the add insert the additional quote at the end.\n    } else if ((wordMatch = context.matchBefore(/\\w+$/))) {\n        ({ text: seed, from } = wordMatch);\n    }\n    return { seed, from, to, filter, validFor };\n}\n\nconst typeMatcher =\n    /(String|String constant| constant| module| constant| object| property| package|^string|^number|^object)$/;\nconst iconMap = {\n    \" module\": \"namespace\",\n    \" package\": \"namespace\",\n    \"String constant\": \"text\",\n    string: \"text\",\n    String: \"text\",\n    \" constant\": \"constant\",\n    \" property\": \"property\",\n    \" object\": \"interface\",\n    object: \"interface\",\n    number: \"variable\",\n};\n\nfunction getCompletionOptions({ completions, defaultCompletionIndex }: Analysis, seed: string) {\n    const isDouble = seed[0] === '\"';\n    const options = (completions ?? []).map(({ text, priority, call, popup }) => {\n        let apply: Completion[\"apply\"];\n        if (call) {\n            apply = (view: EditorView, completion: Completion, from: number, to: number) => {\n                view.dispatch({\n                    changes: { from, to, insert: text + \"()\" },\n                    selection: { anchor: from + text.length + 1 },\n                });\n                // autoCompletion only triggered by user typing\n                // so force startCompletion after changing selection to inside parentheses\n                startCompletion(view);\n            };\n        }\n        if (isDouble) {\n            text = text.replace(/'(.*)'/, '\"$1\"');\n        }\n        let info: Completion[\"info\"];\n        let type: Completion[\"type\"];\n        if (popup) {\n            info = () => CompletionInfoElement(popup);\n            /** @todo put something like popop.type.icon in the Autocompleter popup return */\n            if (popup.type?.classInstance) {\n                type = \"class\";\n            } else if (popup.callable) {\n                type = \"function\";\n            } else {\n                const typeName = popup.type?.name;\n                const typeEnding = typeName?.match(typeMatcher)?.[1];\n                if (typeEnding) {\n                    type = iconMap[typeEnding as keyof typeof iconMap];\n                } else {\n                    type = \"property\";\n                    //console.log(\"Can't figure out type icon:\", popup);\n                }\n            }\n        }\n\n        return { label: text, boost: priority, apply, info, type };\n    });\n    if (defaultCompletionIndex) {\n        // since codemirror out the box doesn't support this\n        // we just double the boost number (for now)\n        const defaultOption = options[defaultCompletionIndex];\n        if (defaultOption !== undefined) {\n            defaultOption.boost = defaultOption.boost * 2;\n        }\n    }\n    return options;\n}\n","import { type CompletionContext, type CompletionSource, autocompletion } from \"@codemirror/autocomplete\";\nimport { syntaxTree } from \"@codemirror/language\";\n\n/** Leave separators free for Enter; import lists can continue after a comma. */\nexport function pythonCompletionAllowed(context: CompletionContext) {\n    return (\n        !context.tokenBefore([\":\", \";\", \",\"]) ||\n        syntaxTree(context.state).resolveInner(context.pos, -1).parent?.name === \"ImportStatement\"\n    );\n}\n\n/** Shared editor configuration, also exercised by the browser performance suite. */\nexport function pythonAutocompletion(\n    source: CompletionSource | CompletionSource[],\n    { analysis }: { analysis: boolean }\n) {\n    return autocompletion({\n        override: Array.isArray(source) ? source : [source],\n        ...(analysis\n            ? {\n                  updateSyncTime: 0,\n                  activateOnTypingDelay: 0,\n                  // Accept Enter/Tab even if analysis only just finished.\n                  interactionDelay: 0,\n              }\n            : {}),\n    });\n}\n","import {\n    foldEffect,\n    foldState,\n    foldable,\n    getIndentation,\n    unfoldAll,\n    unfoldCode,\n    unfoldEffect,\n} from \"@codemirror/language\";\nimport { EditorState, StateEffect } from \"@codemirror/state\";\nimport { BlockInfo, Command, EditorView, KeyBinding } from \"@codemirror/view\";\n\ntype Range = { from: number; to: number };\n\nfunction foldRangeRecursively(\n    view: EditorView,\n    { from = 0, to, invalid }: { from?: number; to?: number; invalid?: (range: Range) => boolean } = {}\n) {\n    const { state } = view;\n    const effects = [];\n    to ??= state.doc.length;\n    for (let pos = from; pos < to; ) {\n        const line = view.lineBlockAt(pos),\n            range = foldable(state, line.from, line.to);\n\n        if (range && !invalid?.(range)) {\n            effects.push(foldEffect.of(range));\n        }\n        pos = line.to + 1;\n    }\n    if (effects.length) view.dispatch({ effects });\n    return !!effects.length;\n}\n\n/** Folds all code recursively */\nexport const foldAll: Command = foldRangeRecursively;\n\nfunction announceFold(view: EditorView, range: Range, fold = true) {\n    const lineFrom = view.state.doc.lineAt(range.from).number,\n        lineTo = view.state.doc.lineAt(range.to).number;\n    return EditorView.announce.of(\n        `${view.state.phrase(fold ? \"Folded lines\" : \"Unfolded lines\")} ${lineFrom} ${view.state.phrase(\n            \"to\"\n        )} ${lineTo}.`\n    );\n}\n\nfunction findFold(state: EditorState, from: number, to: number) {\n    let found: Range | null = null;\n    state.field(foldState, false)?.between(from, to, (from, to) => {\n        if (!found || found.from > from) found = { from, to };\n    });\n    return found as Range | null;\n}\n\nfunction getFoldableRegion(view: EditorView, pos: number) {\n    const { state } = view;\n    let startingIndent: number | undefined;\n    while (pos >= 0) {\n        const lineBlock = view.lineBlockAt(pos);\n        if (startingIndent === undefined) {\n            startingIndent = getIndentation(state, pos) as number;\n            // check if we're already folded\n            if (findFold(state, lineBlock.from, lineBlock.to)) break;\n        } else if (getIndentation(state, pos)! > startingIndent) {\n            // ignore this\n            pos = lineBlock.from - 1;\n            continue;\n        }\n\n        const range = foldable(state, lineBlock.from, lineBlock.to);\n        if (range) {\n            return range;\n        }\n        pos = lineBlock.from - 1;\n    }\n    return null;\n}\n\nconst doFold = (view: EditorView, onRangeFound: (range: Range) => void) => {\n    const { state } = view;\n    for (const { head } of state.selection.ranges) {\n        const range = getFoldableRegion(view, head);\n        if (range) {\n            onRangeFound(range);\n            return true;\n        }\n    }\n    return false;\n};\n\n/** improve codemirror version by supporting folding from inside a block */\nexport const foldCode: Command = (view) => {\n    return doFold(view, (range) => view.dispatch({ effects: [foldEffect.of(range), announceFold(view, range)] }));\n};\n\nconst foldRecursively: Command = (view) => {\n    return doFold(view, (range) => foldRangeRecursively(view, { from: range.from, to: range.to }));\n};\n\nfunction selectedLines(view: EditorView) {\n    const lines: BlockInfo[] = [];\n    for (const { head } of view.state.selection.ranges) {\n        if (lines.some((l) => l.from <= head && l.to >= head)) continue;\n        lines.push(view.lineBlockAt(head));\n    }\n    return lines;\n}\n\nexport const unfoldRecursively: Command = (view) => {\n    const { state } = view;\n    const field = state.field(foldState, false);\n    if (!field || !field.size) return false;\n    const effects: StateEffect<any>[] = [];\n    for (const line of selectedLines(view)) {\n        let hasRegions = false;\n        field.between(line.from, line.to, (from, to) => {\n            hasRegions = true;\n            effects.push(unfoldEffect.of({ from, to }));\n        });\n        if (!hasRegions) {\n            // get the foldable region above us\n            const range = getFoldableRegion(view, line.from);\n            if (range) {\n                field.between(range.from, range.to, (from, to) => {\n                    effects.push(unfoldEffect.of({ from, to }));\n                });\n            }\n        }\n    }\n    if (effects.length) view.dispatch({ effects });\n    return !!effects.length;\n};\n\nfunction foldAtLevel(level: number) {\n    const foldAtLevelCommand: Command = (view) => {\n        const { state } = view;\n\n        const lines = selectedLines(view);\n        const invalid = (range: Range) =>\n            lines.some((e) => (e.from >= range.from && e.to <= range.to) || (range.from >= e.from && range.to <= e.to));\n\n        const levels: ReturnType<typeof foldable>[] = new Array(level - 1).fill(null);\n        const effects = [];\n        for (let pos = 0; pos < state.doc.length; ) {\n            const line = view.lineBlockAt(pos);\n            let range = foldable(state, line.from, line.to);\n\n            if (range) {\n                for (let i = 0; i < levels.length; i++) {\n                    if (levels[i] === null) {\n                        levels[i] = range;\n                        range = null;\n                        break;\n                    }\n                }\n            }\n\n            if (range && !invalid(range)) {\n                effects.push(foldEffect.of(range));\n            }\n\n            pos = (range ? view.lineBlockAt(range.to) : line).to + 1;\n\n            for (let i = 0; i < levels.length; i++) {\n                const levelRange = levels[i];\n                if (levelRange !== null && pos > levelRange.to) {\n                    levels[i] = null;\n                }\n            }\n        }\n\n        if (effects.length) view.dispatch({ effects });\n        return !!effects.length;\n    };\n\n    return foldAtLevelCommand;\n}\n\nconst foldExcept: Command = (view) => {\n    const regions: Range[] = [];\n    for (const line of selectedLines(view)) {\n        const range = getFoldableRegion(view, line.from);\n        if (range) regions.push(range);\n    }\n    const invalid = (range: Range) =>\n        regions.some((e) => (e.from >= range.from && e.to <= range.to) || (range.from >= e.from && range.to <= e.to));\n    foldRangeRecursively(view, { invalid });\n\n    return true;\n};\n\ntype Handlers = { [event: string]: (view: EditorView, line: BlockInfo, event: Event) => boolean };\n\nexport const foldEventHandlers: Handlers = {\n    click(view, line, event) {\n        const { state } = view;\n        const { altKey, shiftKey } = event as MouseEvent;\n        const field = state.field(foldState);\n        const effects: StateEffect<any>[] = [];\n\n        if (altKey) {\n            let range = findFold(state, line.from, line.to);\n            if (!range) {\n                range = foldable(state, line.from, line.to);\n            }\n            if (range === null) return false;\n            field.between(0, range.from - 1, (from, to) => {\n                effects.push(unfoldEffect.of({ from, to }));\n            });\n            field.between(range.to + 1, state.doc.length, (from, to) => {\n                effects.push(unfoldEffect.of({ from, to }));\n            });\n\n            if (effects.length) {\n                view.dispatch({ effects });\n            } else {\n                const invalid = (e: Range) => {\n                    if (range === null) return false;\n                    return (e.from >= range.from && e.to <= range.to) || (range.from >= e.from && range.to <= e.to);\n                };\n                foldRangeRecursively(view, { invalid });\n            }\n            return true;\n        } else if (shiftKey) {\n            const folded = findFold(state, line.from, line.to);\n            if (folded) {\n                field.between(line.from, line.to, (from, to) => {\n                    effects.push(unfoldEffect.of({ from, to }));\n                });\n                view.dispatch({ effects });\n                return true;\n            }\n            const range = foldable(state, line.from, line.to);\n            if (range) {\n                foldRangeRecursively(view, range);\n                return true;\n            }\n            return false;\n        }\n        // let codemirror handle this with default implementation\n        return false;\n    },\n};\n\nexport const foldKeymap: readonly KeyBinding[] = [\n    { key: \"Ctrl-Alt-[\", run: foldAll },\n    { key: \"Ctrl-Alt-]\", run: unfoldAll },\n    { key: \"Mod-Alt-k Mod-Alt-0\", run: foldAll },\n    { key: \"Mod-Alt-k Mod-Alt-1\", run: foldAtLevel(1) },\n    { key: \"Mod-Alt-k Mod-Alt-2\", run: foldAtLevel(2) },\n    { key: \"Mod-Alt-k Mod-Alt-3\", run: foldAtLevel(3) },\n    { key: \"Mod-Alt-k Mod-Alt-4\", run: foldAtLevel(4) },\n    { key: \"Mod-Alt-k Mod-Alt-5\", run: foldAtLevel(5) },\n    { key: \"Mod-Alt-k Mod-Alt-6\", run: foldAtLevel(6) },\n    { key: \"Mod-Alt-k Mod-Alt-[\", run: foldRecursively },\n    { key: \"Mod-Alt-k Mod-Alt-]\", run: unfoldRecursively },\n    { key: \"Mod-Alt-k Mod-Alt--\", run: foldExcept },\n    { key: \"Mod-Alt-k Mod-Alt-j\", run: unfoldAll },\n    { key: \"Ctrl-Shift-[\", mac: \"Cmd-Alt-[\", run: foldCode },\n    { key: \"Ctrl-Shift-]\", mac: \"Cmd-Alt-]\", run: unfoldCode },\n];\n","import { isolateHistory } from \"@codemirror/commands\";\nimport { getIndentation, indentString } from \"@codemirror/language\";\nimport { type EditorState, Text, countColumn } from \"@codemirror/state\";\nimport { EditorView, ViewPlugin } from \"@codemirror/view\";\nimport { MapConflictsFrom } from \"./conflict_state\";\n\nconst clipboardMimeType = \"application/x-anvil-code\";\nconst leadingWhitespace = (text: string) => /^[\\t ]*/.exec(text)![0];\n\nfunction firstNonBlankLine(text: Text) {\n    for (let n = 1; n <= text.lines; n++) {\n        const line = text.line(n);\n        if (/\\S/.test(line.text)) return line;\n    }\n    return text.line(1);\n}\n\ninterface CopyMetadata {\n    indent: number;\n    linewise: boolean;\n}\n\nfunction readCopyMetadata(data: DataTransfer): CopyMetadata | null {\n    try {\n        const value: unknown = JSON.parse(data.getData(clipboardMimeType));\n        if (\n            typeof value === \"object\" &&\n            value !== null &&\n            \"indent\" in value &&\n            \"linewise\" in value &&\n            typeof value.indent === \"number\" &&\n            Number.isSafeInteger(value.indent) &&\n            value.indent >= 0 &&\n            typeof value.linewise === \"boolean\"\n        ) {\n            return { indent: value.indent, linewise: value.linewise };\n        }\n    } catch {\n        // External clipboard contents do not carry Anvil's copy metadata.\n    }\n    return null;\n}\n\nfunction indentPastedBlock(state: EditorState, inserted: Text, sourceIndent?: number) {\n    const { from, to } = state.selection.main;\n    const line = state.doc.lineAt(from);\n    const prefix = state.sliceDoc(line.from, from);\n    const afterCode = /\\S/.test(prefix);\n    // A leading line break creates a new block even after existing code.\n    // Other inline pastes keep their original text.\n    if (inserted.lines === 1 || (afterCode && /\\S/.test(inserted.line(1).text))) return null;\n\n    const firstLine = firstNonBlankLine(inserted);\n    const pasted = state.update(state.replaceSelection(inserted)).state;\n    const suggestedIndent = getIndentation(pasted, afterCode ? from + firstLine.from : line.from);\n    if (suggestedIndent === null) return null;\n\n    const column = (text: string) => countColumn(leadingWhitespace(text), state.tabSize);\n    // Existing code establishes the destination even when the caret is only\n    // partway through its leading whitespace.\n    let targetIndent = suggestedIndent;\n    if (!afterCode) {\n        if (/\\S/.test(line.text)) targetIndent = column(line.text);\n        else if (prefix.length) targetIndent = column(prefix);\n    }\n    const originalIndent = sourceIndent ?? column(firstLine.text);\n    const delta = targetIndent - originalIndent;\n    const lines: string[] = [];\n\n    for (let n = 1, pos = from; n <= inserted.lines; n++) {\n        const text = inserted.line(n).text;\n        if (!/\\S/.test(text) || getIndentation(pasted, pasted.doc.lineAt(pos).from) === null) {\n            // In particular, don't change whitespace inside multiline strings.\n            lines.push(text);\n        } else {\n            const sourceColumn = column(text);\n            // Use native paste when the selection starts deeper than later lines.\n            if (n > firstLine.number && sourceColumn < originalIndent) return null;\n            const indent = n === 1 ? targetIndent - column(prefix) : Math.max(0, sourceColumn + delta);\n            lines.push(indentString(state, indent) + text.slice(leadingWhitespace(text).length));\n        }\n        pos += text.length + 1;\n    }\n\n    // A final whitespace-only row shares a line with existing code. Restore the\n    // existing line's original indentation, including when replacing a selection.\n    const endLine = state.doc.lineAt(to);\n    const endPrefix = state.sliceDoc(endLine.from, to);\n    if (!/\\S/.test(lines[lines.length - 1]) && !/\\S/.test(endPrefix) && /\\S/.test(state.sliceDoc(to, endLine.to))) {\n        lines[lines.length - 1] = endPrefix;\n    }\n    return Text.of(lines);\n}\n\nclass SmartPaste {\n    preserveFormatting = false;\n    copyMetadata: CopyMetadata | null = null;\n\n    constructor(readonly view: EditorView) {\n        // CodeMirror writes text/plain on contentDOM. Add our metadata when the\n        // same event then bubbles to the outer editor, including after a cut.\n        view.dom.addEventListener(\"copy\", this.onCopy);\n        view.dom.addEventListener(\"cut\", this.onCopy);\n    }\n\n    onCopy = (event: ClipboardEvent) => {\n        if (event.defaultPrevented && this.copyMetadata) {\n            event.clipboardData?.setData(clipboardMimeType, JSON.stringify(this.copyMetadata));\n        }\n    };\n\n    rememberCopy() {\n        const state = this.view.state;\n        const ranges = state.selection.ranges;\n        const linewise = ranges.every((range) => range.empty);\n        if (ranges.length !== 1 && !linewise) {\n            this.copyMetadata = null;\n            return;\n        }\n        // CodeMirror joins whole-line copies from empty carets in document order.\n        const selection = linewise\n            ? (ranges.find((range) => /\\S/.test(state.doc.lineAt(range.from).text)) ?? ranges[0])\n            : state.selection.main;\n        const { from, to } = selection;\n        const firstLine = firstNonBlankLine(state.doc.slice(from, to));\n        this.copyMetadata = {\n            indent: countColumn(leadingWhitespace(state.doc.lineAt(from + firstLine.from).text), state.tabSize),\n            linewise,\n        };\n    }\n\n    destroy() {\n        this.view.dom.removeEventListener(\"copy\", this.onCopy);\n        this.view.dom.removeEventListener(\"cut\", this.onCopy);\n    }\n}\n\nexport const smartPaste = ViewPlugin.fromClass(SmartPaste, {\n    eventHandlers: {\n        keydown(event) {\n            this.preserveFormatting =\n                event.key.toLowerCase() === \"v\" && (event.metaKey || event.ctrlKey) && event.shiftKey;\n        },\n        keyup() {\n            this.preserveFormatting = false;\n        },\n        blur() {\n            this.preserveFormatting = false;\n        },\n        copy() {\n            this.rememberCopy();\n        },\n        cut() {\n            this.rememberCopy();\n        },\n        paste(event, view) {\n            const preserve = this.preserveFormatting;\n            this.preserveFormatting = false;\n            const { state } = view;\n            if (preserve || state.readOnly || state.selection.ranges.length !== 1 || !event.clipboardData) {\n                return false;\n            }\n            const metadata = readCopyMetadata(event.clipboardData);\n            const { from, empty } = state.selection.main;\n            const linewise = metadata?.linewise && empty;\n            const pasteFrom = linewise ? state.doc.lineAt(from).from : from;\n            // Whole-line copies use the line start for indentation and keep the caret's original column.\n            const indentationState = linewise ? state.update({ selection: { anchor: pasteFrom } }).state : state;\n            const text = state.toText(event.clipboardData.getData(\"text/plain\") + (linewise ? state.lineBreak : \"\"));\n            const indented = indentPastedBlock(indentationState, text, metadata?.indent);\n            if (indented === null) return false;\n            const change = linewise\n                ? {\n                      changes: { from: pasteFrom, insert: text },\n                      selection: { anchor: from + text.length },\n                  }\n                : state.replaceSelection(text);\n            const rawPaste = state.update(change, { userEvent: \"input.paste\", scrollIntoView: true });\n            if (text.eq(indented)) {\n                view.dispatch(rawPaste);\n            } else {\n                const format = rawPaste.state.update({\n                    changes: { from: pasteFrom, to: pasteFrom + text.length, insert: indented },\n                    annotations: [isolateHistory.of(\"full\"), MapConflictsFrom.of(rawPaste)],\n                });\n                // Record both undo steps while showing only the final document.\n                view.dispatch([rawPaste, format]);\n            }\n            return true;\n        },\n    },\n});\n","import { closeBrackets, closeBracketsKeymap } from \"@codemirror/autocomplete\";\nimport { defaultKeymap, deleteLine, history, historyKeymap, redo, toggleComment } from \"@codemirror/commands\";\nimport { pythonLanguage } from \"@codemirror/lang-python\";\nimport {\n    LanguageSupport,\n    bracketMatching,\n    defaultHighlightStyle,\n    foldGutter,\n    indentOnInput,\n    syntaxHighlighting,\n} from \"@codemirror/language\";\nimport { lintKeymap } from \"@codemirror/lint\";\nimport { highlightSelectionMatches } from \"@codemirror/search\";\nimport { EditorState, Extension } from \"@codemirror/state\";\nimport {\n    EditorView,\n    KeyBinding,\n    drawSelection,\n    dropCursor,\n    highlightActiveLine,\n    highlightActiveLineGutter,\n    highlightSpecialChars,\n    keymap,\n    lineNumbers,\n    rectangularSelection,\n} from \"@codemirror/view\";\nimport { icon } from \"@fortawesome/fontawesome-svg-core\";\nimport { faCaretDown, faCaretRight } from \"@fortawesome/pro-solid-svg-icons\";\nimport { foldEventHandlers, foldKeymap } from \"./utils/fold\";\nimport { keyBindingsExtension } from \"./utils/key_bindings\";\nimport { smartPaste } from \"./utils/paste\";\nimport { search } from \"./utils/search\";\nimport { defaultTabBinding, indentMoreOverride } from \"./utils/tab_keybinding\";\n\nexport const basicKeyMap: KeyBinding[] = [\n    defaultTabBinding,\n    ...indentMoreOverride,\n    ...closeBracketsKeymap,\n    ...historyKeymap,\n    { win: \"Ctrl-Shift-z\", run: redo, preventDefault: true }, // because by default this is a linux only command in codemirror\n    ...defaultKeymap.map((b) => (b.key === \"Mod-Enter\" ? { key: \"Shift-Enter\", run: b.run } : b)),\n    // mod-d does find selectNextOccurrence (maybe change this)\n    { key: \"Mod-d\", run: deleteLine },\n    // For german keyboards where / isn't as convenient\n    { key: \"Mod-#\", run: toggleComment },\n];\n\nexport const editorKeyMap = [...basicKeyMap, ...foldKeymap, ...lintKeymap];\n\nexport const scrollBar = EditorView.baseTheme({\n    \".cm-scroller::-webkit-scrollbar\": {\n        width: \"15px\",\n        height: \"15px\",\n        backgroundColor: \"transparent\",\n    },\n    \".cm-scroller::-webkit-scrollbar-track\": {\n        boxShadow: \"inset 0 0 15px 15px transparent\",\n        border: \"solid 5px transparent\",\n        backgroundColor: \"transparent\",\n    },\n    \".cm-scroller::-webkit-scrollbar-thumb\": {\n        boxShadow: \"inset 0 0 15px 15px #bbbbbe55\",\n        border: \"solid 5px transparent\",\n        borderRadius: \"15px\",\n        backgroundColor: \"transparent\",\n        visibility: \"hidden\",\n    },\n    \".cm-scroller::-webkit-scrollbar-thumb:hover\": {\n        boxShadow: \"inset 0 0 15px 15px #bbbbbe\",\n        border: \"solid 3px transparent\",\n    },\n    \".cm-scroller:hover::-webkit-scrollbar-thumb\": {\n        visibility: \"visible\",\n    },\n    \".cm-scroller::-webkit-scrollbar-corner\": {\n        backgroundColor: \"transparent\",\n    },\n    \".cm-panels\": {\n        zIndex: 10,\n    },\n});\n\nexport const basicExtensions: Extension = [\n    highlightSpecialChars(),\n    history(),\n    drawSelection(),\n    indentOnInput(),\n    syntaxHighlighting(defaultHighlightStyle, { fallback: true }),\n    bracketMatching(),\n    scrollBar,\n    closeBrackets(),\n    dropCursor(),\n    rectangularSelection({ eventFilter: (e) => e.altKey && e.shiftKey }),\n    highlightSelectionMatches(),\n    // Fix safari bug with editor\n    EditorView.baseTheme({\n        \"& .cm-content\": { \"-webkit-user-select\": \"text\", userSelect: \"text\" },\n    }),\n];\n\nexport const editorExtensions: Extension = [\n    keyBindingsExtension.of([]),\n    basicExtensions,\n    lineNumbers({\n        domEventHandlers: {\n            click(view, { from, to }) {\n                view.dispatch({\n                    selection: { anchor: from, head: Math.min(view.state.doc.length, to + 1) },\n                    scrollIntoView: true,\n                });\n                view.focus();\n                return true;\n            },\n        },\n    }),\n    highlightActiveLineGutter(),\n    foldGutter({\n        markerDOM: (open) => {\n            const node = document.createElement(\"div\");\n            node.classList.add(\"cm-foldgutter-marker\");\n            node.appendChild(icon(open ? faCaretDown : faCaretRight, { classes: \"fa-fw\" }).node[0]);\n            return node;\n        },\n        domEventHandlers: foldEventHandlers,\n    }),\n    highlightActiveLine(),\n    keymap.of(editorKeyMap),\n    search(),\n    EditorView.clickAddsSelectionRange.of((e) => e.altKey && !e.shiftKey),\n    EditorState.allowMultipleSelections.of(true),\n    smartPaste,\n];\n\n// Because we want brackets to be matched within string literals we need to override codemirror's default language option\n// https://discuss.codemirror.net/t/python-f-string-auto-close-match-bracket/5046\n// https://github.com/codemirror/autocomplete/commit/4d7e5d5f5772229b07d39116e7d8a8c1b28220d6#diff-1381cef9776ada6a22a2b6c840d77a86f9a6edb65e691b914296d144555d64c6\nexport function python() {\n    return [\n        pythonLanguage.data.of({\n            closeBrackets: {\n                before: \")]}'\\\":;>\",\n                brackets: [\"(\", \"[\", \"{\", \"'\", '\"', \"'''\", '\"\"\"'],\n                stringPrefixes: [\n                    \"f\",\n                    \"fr\",\n                    \"rf\",\n                    \"r\",\n                    \"u\",\n                    \"b\",\n                    \"br\",\n                    \"rb\",\n                    \"F\",\n                    \"FR\",\n                    \"RF\",\n                    \"R\",\n                    \"U\",\n                    \"B\",\n                    \"BR\",\n                    \"RB\",\n                ],\n            },\n        }),\n        new LanguageSupport(pythonLanguage),\n    ];\n}\n","import React, { useMemo, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport type { EditorView } from \"@codemirror/view\";\nimport {\n    IconDefinition,\n    faCode,\n    faCopy,\n    faEye,\n    faImage,\n    faPencilAlt,\n    faShieldCheck,\n    faShieldTimes,\n    faTrashAlt,\n    faUpload,\n} from \"@fortawesome/pro-light-svg-icons\";\nimport { Button } from \"@/components/reusable/Button\";\nimport TabToolbar from \"@/components/tabs/TabToolbar\";\nimport { deleteCodeItem, renameCodeItem } from \"@/controllers/app/code\";\nimport { alert, prompt } from \"@/controllers/modals\";\nimport { getUserEslintPref, updateUserEditorPrefs } from \"@/controllers/user\";\nimport { makeStyles } from \"@/theme/styles\";\nimport { ignoreSsrWarning } from \"@/theme/utils\";\nimport type { AnvilDispatch, AssetItemYaml, CodePath, CodeTab, EditHistory, StructureItem, View } from \"@/types\";\nimport { decodeAssetContent, useDebugThemePrefix } from \"@/util/hooks/assets\";\nimport { useCopyAssetPath } from \"@/util/hooks/use-copy-asset-path\";\nimport { useReplaceAsset } from \"@/util/hooks/use-replace-asset\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { FormatCodeButton } from \"../FormatCodeButton\";\nimport { Conflicts } from \"../utils/conflict_markers\";\nimport { formatCodeCommand } from \"../utils/format\";\nimport { useViewSelector } from \"../utils/hooks\";\nimport AssetCodeEditor from \"./asset-code-editor\";\nimport type { AssetFileType } from \"./base_asset_editor\";\nimport MarkdownAssetPreview from \"./markdown-asset-preview\";\n\ntype ImageType = \"svg\" | \"jpeg\" | \"jpg\" | \"gif\" | \"png\";\n\ninterface EditorProps {\n    tab: CodeTab;\n    selected: boolean;\n    codeItem: AssetItemYaml;\n    codePath: CodePath;\n    file: StructureItem;\n    conflicts?: Conflicts;\n    hashItem?: View;\n    editHistory?: EditHistory;\n    enableMiniMap?: boolean;\n}\n\ninterface ToolBarBtnProps {\n    onClick: () => void;\n    icon: IconDefinition;\n    children: React.ReactNode;\n}\n\ninterface ToolBarProps {\n    file: StructureItem;\n    isImage: boolean;\n    fileType: AssetFileType | ImageType | null;\n    isEditable: boolean;\n    canPreview: boolean;\n    preview: boolean;\n    setPreview: React.Dispatch<React.SetStateAction<boolean>>;\n    formatButton?: React.ReactNode;\n}\n\ninterface ReplaceBtnProps {\n    file: StructureItem;\n}\n\nconst useToolBarBtnStyles = makeStyles()({\n    toolbarButton: {\n        margin: \"0 0.25rem\",\n        [`&:first-child${ignoreSsrWarning}`]: {\n            marginLeft: 0,\n        },\n    },\n});\n\nconst useImageViewStyles = makeStyles()({\n    textCenter: {\n        textAlign: \"center\",\n    },\n    imgView: {\n        maxHeight: \"50%\",\n        maxWidth: \"50%\",\n    },\n});\n\nconst ToolBarBtn = ({ onClick, icon, children, ref }: ToolBarBtnProps & { ref?: any }) => {\n    const { classes } = useToolBarBtnStyles();\n    return (\n        <Button\n            ref={ref}\n            className={classes.toolbarButton}\n            size={\"small\"}\n            icon={icon}\n            variant={\"outlined\"}\n            onClick={onClick}>\n            {children}\n        </Button>\n    );\n};\n\nconst EDIT_REGEX = /.*\\.(html|css|js|jsx|ts|tsx|svg|json|xml|md|markdown|rst|txt|text|csv|tsv|log|ini|yml|yaml)$/;\nconst IMAGE_REGEX = /\\.(png|gif|jpg|jpeg|svg)$/;\n\nexport const getEditableFileType = (fileName: string) =>\n    (EDIT_REGEX.exec(fileName)?.[1] ?? null) as AssetFileType | null;\n\nconst getImageType = (fileName: string) => (IMAGE_REGEX.exec(fileName)?.[1] ?? null) as ImageType | null;\n\nconst getFileType = (fileName: string) => getEditableFileType(fileName) ?? getImageType(fileName) ?? null;\n\nconst ReplaceBtn = ({ file }: ReplaceBtnProps) => {\n    const [input, onClick] = useReplaceAsset(file);\n    return (\n        <ToolBarBtn onClick={onClick} icon={faUpload}>\n            Replace\n            {input}\n        </ToolBarBtn>\n    );\n};\n\nexport const ESLintButton = ({ fileType }: Pick<ToolBarProps, \"fileType\">) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const eslint = useSelector(getUserEslintPref);\n\n    const onToggleESLint = useEvent(() => {\n        dispatch(updateUserEditorPrefs(\"eslint\", !eslint));\n    });\n\n    if (![\"html\", \"js\", \"jsx\"].includes(fileType!)) return null;\n\n    return (\n        <ToolBarBtn onClick={onToggleESLint} icon={eslint ? faShieldCheck : faShieldTimes}>\n            {`Turn ${eslint ? \"off\" : \"on\"} ESLint`}\n        </ToolBarBtn>\n    );\n};\n\nconst AssetFormatButton = ({ view }: { view: EditorView }) => {\n    const canFormat = useViewSelector(view, () => !!view.state.facet(formatCodeCommand));\n    return canFormat ? <FormatCodeButton view={view} /> : null;\n};\n\nconst ToolBar = ({ file, fileType, isEditable, canPreview, preview, setPreview, formatButton }: ToolBarProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const renameAsset = useEvent(async () => {\n        const newName = await dispatch(prompt(\"Rename Asset\", `Rename ${file.fullName}`, file.name));\n        if (newName) {\n            try {\n                await dispatch(renameCodeItem(file, newName));\n            } catch (e) {\n                await dispatch(alert(\"Error\", `${e}\\nUnable to rename codeItem to ${newName}`));\n            }\n        }\n    });\n    const deleteAsset = useEvent(() => {\n        dispatch(deleteCodeItem(file, true));\n    });\n\n    const [copyClickHandler, copyTooltip, copyRef] = useCopyAssetPath(file);\n    const onTogglePreview = useEvent(() => {\n        setPreview((v) => !v);\n    });\n\n    return (\n        <TabToolbar leftSide={formatButton}>\n            {canPreview ? (\n                <ToolBarBtn onClick={onTogglePreview} icon={preview ? faCode : fileType === \"svg\" ? faImage : faEye}>\n                    {preview ? \"Raw\" : \"Preview\"}\n                    {copyTooltip}\n                </ToolBarBtn>\n            ) : null}\n            <ToolBarBtn onClick={renameAsset} icon={faPencilAlt}>\n                Rename\n            </ToolBarBtn>\n            <ToolBarBtn onClick={deleteAsset} icon={faTrashAlt}>\n                Delete\n            </ToolBarBtn>\n            <ToolBarBtn ref={copyRef} onClick={copyClickHandler} icon={faCopy}>\n                Copy Asset Path\n                {copyTooltip}\n            </ToolBarBtn>\n            <ESLintButton fileType={fileType} />\n            {!isEditable && <ReplaceBtn file={file} />}\n        </TabToolbar>\n    );\n};\n\nconst ImageView = ({ codeItem, imageType }: { codeItem: AssetItemYaml; imageType: ImageType }) => {\n    const mimeType = useMemo(() => (imageType === \"svg\" ? \"svg+xml\" : imageType), [imageType]);\n    const src = useMemo(() => `data:image/${mimeType};base64,${codeItem.content}`, [mimeType, codeItem.content]);\n    const { classes } = useImageViewStyles();\n\n    return (\n        <div className={classes.textCenter}>\n            <img src={src} className={classes.imgView} />\n        </div>\n    );\n};\n\nconst AssetEditor = (props: EditorProps) => {\n    const { codeItem, file } = props;\n    const themePrefix = useDebugThemePrefix();\n    const editableFile = getEditableFileType(file.name);\n    const imageType = getImageType(file.name);\n    const fileType = getFileType(file.name);\n    const isSvg = fileType === \"svg\";\n    const isMarkdown = fileType === \"md\" || fileType === \"markdown\";\n    const markdownContent = useMemo(\n        () => (isMarkdown ? decodeAssetContent(codeItem.content) : \"\"),\n        [isMarkdown, codeItem.content]\n    );\n    const [preview, setPreview] = useState(!isMarkdown);\n    const [editorView, setEditorView] = useState<EditorView | null>(null);\n\n    return (\n        <>\n            <ToolBar\n                file={file}\n                fileType={fileType}\n                isImage={!!imageType}\n                isEditable={!!editableFile}\n                canPreview={isSvg || isMarkdown}\n                preview={preview}\n                setPreview={setPreview}\n                formatButton={editorView && <AssetFormatButton view={editorView} />}\n            />\n            {imageType && preview ? (\n                <ImageView codeItem={codeItem} imageType={imageType} />\n            ) : isMarkdown && preview ? (\n                <MarkdownAssetPreview content={markdownContent} assetName={file.fullName} themePrefix={themePrefix} />\n            ) : editableFile ? (\n                // subtract 5rem for the ToolBar\n                <AssetCodeEditor ref={setEditorView} height=\"calc(100% - 5rem)\" {...props} />\n            ) : null}\n        </>\n    );\n};\n\nexport default AssetEditor;\n","import { lazyComponent } from \"@/util/lazy\";\nimport type { default as TAssetEditor } from \"./asset_editor\";\nimport type { default as TDataBindingEditor } from \"./data_binding_editor\";\nimport type { default as TExtraFileEditor } from \"./extra-file-editor\";\nimport type { default as THtmlFormTemplateEditor } from \"./html_form_template_editor\";\nimport type { default as THtmlPropertyEditor } from \"./html_property_editor\";\nimport type { default as TImportMapEditor } from \"./import-map-editor\";\nimport type { default as TLazyAssetEditor } from \"./lazy-asset-editor\";\nimport type { default as TModuleEditor } from \"./module_editor\";\nimport type { default as TNativeLibrariesEditor } from \"./native_libraries\";\nimport type { default as TStylePropertyEditor } from \"./style_property_editor\";\nimport type { default as THtmlBodyEditor } from \"./user-email-editor\";\n\nexport const ExtraFilePythonEditor = lazyComponent<typeof import(\"./extra-file-python-editor\").default>(\n    () => import(\"./extra-file-python-editor\")\n);\n\nexport const ModuleEditor = lazyComponent<typeof TModuleEditor>(() => import(\"./module_editor\"));\n\nexport const AssetEditor = lazyComponent<typeof TAssetEditor>(() => import(\"./asset_editor\"));\n\nexport const ExtraFileEditor = lazyComponent<typeof TExtraFileEditor>(() => import(\"./extra-file-editor\"));\n\nexport const DataBindingEditor = lazyComponent<typeof TDataBindingEditor>(() => import(\"./data_binding_editor\"));\n\nexport const HtmlFormTemplateEditor = lazyComponent<typeof THtmlFormTemplateEditor>(\n    () => import(\"./html_form_template_editor\")\n);\n\nexport const HtmlPropertyEditor = lazyComponent<typeof THtmlPropertyEditor>(() => import(\"./html_property_editor\"));\n\nexport const ImportMapEditor = lazyComponent<typeof TImportMapEditor>(() => import(\"./import-map-editor\"));\n\nexport const LazyAssetEditor = lazyComponent<typeof TLazyAssetEditor>(() => import(\"./lazy-asset-editor\"));\n\nexport const NativeLibrariesEditor = lazyComponent<typeof TNativeLibrariesEditor>(() => import(\"./native_libraries\"));\n\nexport const StylePropertyEditor = lazyComponent<typeof TStylePropertyEditor>(() => import(\"./style_property_editor\"));\n\nexport const HtmlBodyEditor = lazyComponent<typeof THtmlBodyEditor>(() => import(\"./user-email-editor\"));\n","import React, { useCallback, useMemo } from \"react\";\nimport { EditorView } from \"@codemirror/view\";\nimport { usePreserveNavigationFocus } from \"@/router/navigation-hooks\";\nimport { getRandomString } from \"@/util\";\nimport { EditHistoryType } from \"./editors/base_asset_editor\";\nimport { useFocusCodeOnNavigation, useFocusCodeOnSelection } from \"./utils/hooks\";\nimport { SearchPanel } from \"./utils/search\";\n\ninterface CodeMirrorProps {\n    view: EditorView;\n    autoFocus: boolean;\n    className?: string;\n    height?: string;\n    scrollIntoView?: boolean;\n}\n\n/** returns the EditorView connected to a dom node */\nexport const CodeMirrorElement = ({\n    view,\n    autoFocus,\n    scrollIntoView = true,\n    className,\n    height = \"100%\",\n}: CodeMirrorProps) => {\n    const domWrapperRef: React.RefCallback<HTMLDivElement> = useCallback(\n        (domWrapper) => {\n            if (!domWrapper) return;\n            domWrapper.replaceChildren(view.dom);\n            if (autoFocus) {\n                const pos = view.state.selection.main.head;\n                scrollIntoView && view.dispatch({ effects: EditorView.scrollIntoView(pos, { y: \"center\" }) });\n                view.focus();\n            }\n        },\n        [view]\n    );\n    return <div ref={domWrapperRef} className={className} style={{ height }} />;\n};\n\nexport const CodeMirrorWithSearch = (props: CodeMirrorProps & { selected: boolean; type: EditHistoryType }) => {\n    const { view, selected, type } = props;\n    const autoFocus = props.autoFocus && selected;\n    const id = useMemo(() => getRandomString(), [view]);\n    useFocusCodeOnSelection(view, autoFocus);\n    return (\n        <>\n            <SearchPanel key={id} view={view} selected={selected} type={type} />\n            <CodeMirrorElement {...props} autoFocus={autoFocus} />\n        </>\n    );\n};\n\n/** File-tab focus follows navigation; embedded editors only follow their own selection. */\nexport const NavigableCodeMirrorWithSearch = (\n    props: CodeMirrorProps & { selected: boolean; type: EditHistoryType }\n) => {\n    const preserveFocus = usePreserveNavigationFocus();\n    useFocusCodeOnNavigation(props.view, props.autoFocus && props.selected);\n    return <CodeMirrorWithSearch {...props} autoFocus={props.autoFocus && !preserveFocus} />;\n};\n","import { lazyComponent } from \"@/util/lazy\";\nimport type { ReplEditor as TReplEditor } from \"./repl\";\n\nexport const ReplEditor = lazyComponent<typeof TReplEditor>(() => import(\"./repl\"));\n","import type { ExtraFiles, RuntimeOptions } from \"@/types/app\";\nimport type { PythonEnvironmentCatalog } from \"@/types/user\";\nimport { decodeAssetContent } from \"@/util/asset-content\";\nimport { getServerPythonMinorVersion } from \"@/util/python-version\";\n\nexport type RuffTargetVersion = \"py37\" | \"py38\" | \"py39\" | \"py310\" | \"py311\" | \"py312\" | \"py313\" | \"py314\";\n\nexport function getRuffTargetVersion(\n    runtimeOptions: Pick<RuntimeOptions, \"server_spec\" | \"server_version\"> | undefined,\n    catalog: PythonEnvironmentCatalog | undefined,\n    { isServer = false }: { isServer?: boolean } = {}\n): RuffTargetVersion {\n    if (!isServer) return \"py37\";\n    return `py3${getServerPythonMinorVersion(runtimeOptions, catalog)}`;\n}\n\nexport async function resolveRuffConfig(files: Partial<ExtraFiles>): Promise<Record<string, unknown> | null> {\n    // Ruff uses one config, in this order, even if the selected file is empty.\n    const name = [\".ruff.toml\", \"ruff.toml\", \"pyproject.toml\"].find((name) => typeof files[name] === \"string\");\n    const content = name && files[name];\n    if (typeof content !== \"string\") return null;\n    const { default: parse } = await import(\"@iarna/toml/parse-string\");\n    const config = parse(decodeAssetContent(content));\n    return name === \"pyproject.toml\" ? (config?.tool?.ruff ?? null) : config;\n}\n\n// taken from the ruff playground\nexport const defaultConfig = {\n    preview: true,\n    builtins: [] as string[],\n    \"target-version\": \"py37\",\n    \"line-length\": 88,\n    \"indent-width\": 2,\n    lint: {\n        \"allowed-confusables\": [],\n        \"dummy-variable-rgx\": \"^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$\",\n        \"extend-select\": [],\n        \"extend-fixable\": [],\n        external: [],\n        ignore: [\n            \"E401\", // Multiple imports on one line\n            \"E741\", // Ambiguous variable name\n            \"F401\", // Allow unused imports, because we auto-add lots (overridden if user prefers autoImport false)\n        ],\n        select: [\n            \"F\",\n            \"E4\",\n            \"E7\",\n            \"E9\",\n            \"N804\", // First argument of a class method should be named cls\n            \"N805\", // First argument of a method should be named self\n            // \"E2011\", // not currently supported - no argument to self - remove this in our own autocompletor when ruff support this\n            // \"I001\", // probably needs to be configurable this\n        ],\n        isort: { \"known-third-party\": [\"anvil\"] },\n    },\n    format: {\n        \"indent-style\": \"space\",\n        \"quote-style\": \"double\",\n    },\n};\n","import type { TagStyle } from \"@codemirror/language\";\nimport { Tag, tags } from \"@lezer/highlight\";\nimport type { ColorMap, StyleDef, TagName, TagStyleDef } from \"./theme_types\";\n\nexport const L: ColorMap = {\n    key0: \"#0076C9\",\n    key1: \"#243768\",\n    lit0: \"#B52BAC\",\n    lit1: \"#C25D47\",\n    lit2: \"#FE547C\", //\n    var0: \"#7163CF\",\n    var1: \"#2DAF88\",\n    var2: \"#308374\",\n    comment: \"#7D8C93\",\n    text: \"#333333\",\n};\n\nexport const D: ColorMap = {\n    key0: \"#68CFFF\",\n    key1: \"#779DFF\",\n    lit0: \"#FF64B8\",\n    lit1: \"#9E8ACA\",\n    lit2: \"#FF7967\", //\n    var0: \"#FFB5A5\",\n    var1: \"#4EC9B0\",\n    var2: \"#92F0C3\",\n    comment: \"#7D898E\",\n    text: \"#ebfaff\",\n};\n\nexport const KEY0 = \"key0\";\nexport const KEY1 = \"key1\";\nexport const LIT0 = \"lit0\";\nexport const LIT1 = \"lit1\";\nexport const LIT2 = \"lit2\";\nexport const VAR0 = \"var0\";\nexport const VAR1 = \"var1\";\nexport const VAR2 = \"var2\";\nexport const COMMENT = \"comment\";\nexport const TEXT = \"text\";\n\n/**\n * base styles used for python an js\n * html/css define their own styles\n * js and py can override any of the styles see js_styles.ts\n */\nexport const baseStyles: StyleDef = {\n    comment: { color: COMMENT }, // catch all comments\n    // lineComment: {},\n    // blockComment: {},\n    // docComment: {},\n\n    // name: {},\n    // className: {},\n    // labelName: {},\n    // namespace: {},\n    // macroName: {},\n    variableName: { color: TEXT },\n\n    function_variableName: { color: TEXT }, // foo()\n    function_definition_variableName: { color: VAR0 }, // def foo - keep same as function_propertyName\n    definition_className: { color: VAR0 }, // class Foo\n    definition_variableName: { color: VAR0 }, // js: let foo\n\n    // typeName: {},\n    // tagName: {},\n\n    propertyName: { color: TEXT }, // foo.x\n    attributeName: { color: TEXT },\n    function_propertyName: { color: VAR0 }, // foo.bar()\n    definition_special_propertyName: { color: KEY0 }, // js only\n    special_propertyName: { color: KEY0 }, // js only\n\n    literal: { color: LIT0 }, // fallback\n    bool: { color: LIT0, fontWeight: 600 },\n    regexp: { color: LIT2 }, // for js regex literals\n    // escape: {},\n    // color: {},\n    // url: {},\n\n    string: { color: LIT1 },\n    special_string: { color: LIT1 }, // f-strings in py, template literals in js\n    // docString: {},\n    // character: {},\n    // attributeValue: {},\n\n    number: { color: LIT0 },\n    // integer: {},\n    // float: {},\n\n    keyword: { color: KEY0, fontWeight: 600 }, // py/js: with as; js: debugger new\n    self: { color: VAR0, fontWeight: \"bold\" }, // only releanvant in JS\n    null: { color: LIT0, fontWeight: 600 },\n    atom: { color: VAR0, fontWeight: \"bold\" }, // js: super() (doesn't seem to work)\n    // unit: {}, // css only - should match number\n    modifier: { color: KEY1, fontWeight: \"bold\" }, // py: async, *, **, str formatting; js: get set async static\n    operatorKeyword: { color: KEY0, fontWeight: 600 }, // py: in not and or is del - should be the same as controlKeyword\n    controlKeyword: { color: KEY0, fontWeight: 600 }, // py: for while if elif else try except finally return raise break continue with pass assert await yield\n    moduleKeyword: { color: KEY0, fontWeight: 600 }, // py: import; js: import export from\n    definitionKeyword: { color: KEY0, fontWeight: 600 }, // py: from def class global nonlocal lambda\n\n    operator: { color: TEXT },\n    derefOperator: { color: TEXT }, // .\n    arithmeticOperator: { color: TEXT }, // + - // %\n    logicOperator: { color: TEXT }, // and or\n    bitwiseOperator: { color: TEXT }, // >>\n    compareOperator: { color: TEXT }, // > < != ==\n    updateOperator: { color: TEXT }, // +=\n    definitionOperator: { color: TEXT }, // = :=\n    // typeOperator: {},\n    // controlOperator: {},\n\n    // punctuation: {}, py: ...\n    // separator: {}, py: , ;\n\n    // bracket: {},\n    // angleBracket: {},\n    // squareBracket: {},\n    // paren: {},\n    // brace: {},\n\n    // content: {},\n    // contentSeparator: {},\n    // list: {},\n    // quote: {},\n    // emphasis: {},\n    // strong: {},\n    // link: {},\n    // monospace: {},\n    // strikethrough: {},\n\n    // heading: {},\n    // heading1: {},\n    // heading2: {},\n    // heading3: {},\n    // heading4: {},\n    // heading5: {},\n    // heading6: {},\n\n    // inserted: {},\n\n    // deleted: {},\n\n    // changed: {},\n\n    // invalid: {},\n\n    meta: { color: TEXT, fontWeight: \"bold\" }, // py: @\n    // documentMeta: {},\n    // annotation: {},\n    // processingInstruction: {},\n};\n\n/**\n * underscore in a tagName indicates tag modifier(s) are involved\n * e.g. \"special_string\" -> tags[\"special\"](tags[\"string\"])\n */\nfunction getTag(tagName: string): Tag {\n    const tagNames = tagName.split(\"_\") as TagName[];\n    let tag: Tag = tags[tagNames.pop() as TagName] as Tag;\n    for (const tagName of tagNames.reverse()) {\n        const callableTag = tags[tagName] as (tag: Tag) => Tag;\n        tag = callableTag(tag);\n    }\n    return tag;\n}\n\nexport function makeStyles(colorMap: ColorMap, styleDef: StyleDef): TagStyleDef {\n    const tagStyleDef: TagStyleDef = {};\n    for (const [tagName, { color, ...styles }] of Object.entries(styleDef)) {\n        const tagStyle: TagStyle = { tag: getTag(tagName), ...styles };\n        if (color != null) {\n            tagStyle.color = colorMap[color];\n        }\n        tagStyleDef[tagName] = tagStyle;\n    }\n    return tagStyleDef;\n}\nexport const makeStylesLight = (styleDef: StyleDef) => makeStyles(L, styleDef);\nexport const makeStylesDark = (styleDef: StyleDef) => makeStyles(D, styleDef);\n\nexport const baseStylesLight = makeStylesLight(baseStyles);\nexport const baseStylesDark = makeStylesDark(baseStyles);\n","import { COMMENT, KEY0, KEY1, LIT0, LIT1, VAR0, makeStylesDark, makeStylesLight } from \"./base_styles\";\nimport { StyleDef } from \"./theme_types\";\n\nconst cssStyleDef: StyleDef = {\n    definitionKeyword: { color: KEY1 }, // import charset namespace keyframes\n    controlKeyword: { color: KEY1 }, // media supports\n    keyword: { color: KEY1 }, // from to selector\n    namespace: {},\n    labelName: { color: VAR0 }, // ID e.g. #foo - (just the foo)\n    tagName: { color: LIT0 }, // div\n    className: { color: VAR0 }, // .bar\n    constant_className: { color: KEY0 }, // ::hover\n    propertyName: { color: KEY0 },\n    attributeName: {}, // [data-bar=\"foo\"] - (the data-bar)\n    number: { color: LIT1 },\n    operatorKeyword: {}, // var(), circle(), fromat(), calc()\n    atom: {}, // values after colons e.g. : italic; | url(), domain(), url-prefix();\n    variableName: {}, // --my-variable\n    unit: { color: LIT1 }, // px, %, em etc - should match the number color\n    definitionOperator: {},\n    compareOperator: {},\n    logicOperator: {}, // and, or, | selectors: > ~ < +\n    arithmeticOperator: {}, // calc(100px + 200px)\n    modifier: { color: KEY1, fontWeight: \"bold\" }, // !important\n    blockComment: { color: COMMENT },\n    lineComment: { color: COMMENT },\n    special_name: {},\n    color: {}, // color literals\n    string: { color: LIT1 },\n    punctuation: { color: KEY0 },\n    derefOperator: { color: VAR0 }, // # - should match labelName\n    separator: {}, // ; ,\n    paren: {},\n    squareBracket: {},\n    brace: {},\n};\n\nexport const cssTagsLight = makeStylesLight(cssStyleDef);\nexport const cssTagsDark = makeStylesDark(cssStyleDef);\n\n/*\nstyleTags({\n    \"import charset namespace keyframes\": t.definitionKeyword,\n    \"media supports\": t.controlKeyword,\n    \"from to selector\": t.keyword,\n    NamespaceName: t.namespace,\n    KeyframeName: t.labelName,\n    TagName: t.tagName,\n    ClassName: t.className,\n    PseudoClassName: t.constant_className),\n    IdName: t.labelName,\n    \"FeatureName PropertyName\": t.propertyName,\n    AttributeName: t.attributeName,\n    NumberLiteral: t.number,\n    KeywordQuery: t.keyword,\n    UnaryQueryOp: t.operatorKeyword,\n    \"CallTag ValueName\": t.atom,\n    VariableName: t.variableName,\n    Callee: t.operatorKeyword,\n    Unit: t.unit,\n    \"UniversalSelector NestingSelector\": t.definitionOperator,\n    AtKeyword: t.keyword,\n    MatchOp: t.compareOperator,\n    \"ChildOp SiblingOp, LogicOp\": t.logicOperator,\n    BinOp: t.arithmeticOperator,\n    Important: t.modifier,\n    Comment: t.blockComment,\n    ParenthesizedContent: t.special_name),\n    ColorLiteral: t.color,\n    StringLiteral: t.string,\n    \":\": t.punctuation,\n    \"PseudoOp #\": t.derefOperator,\n    \"; ,\": t.separator,\n    \"( )\": t.paren,\n    \"[ ]\": t.squareBracket,\n    \"{ }\": t.brace\n})\n*/\n","import { COMMENT, KEY0, LIT1, VAR0, makeStylesDark, makeStylesLight } from \"./base_styles\";\nimport { StyleDef, TagStyleDef } from \"./theme_types\";\n\nconst HtmlStyleDef: StyleDef = {\n    content: {},\n    angleBracket: {}, //\n    tagName: { color: VAR0 },\n    invalid: {},\n    attributeName: { color: KEY0 },\n    attributeValue: { color: LIT1 },\n    character: {},\n    blockComment: { color: COMMENT },\n    processingInstruction: {},\n    documentMeta: { color: VAR0 },\n};\n\nexport const htmlTagsLight: TagStyleDef = makeStylesLight(HtmlStyleDef);\nexport const htmlTagsDark: TagStyleDef = makeStylesDark(HtmlStyleDef);\n\n/*\n    styleTags({\n    \"Text RawText\": t.content,\n    \"StartTag StartCloseTag SelfCloserEndTag EndTag SelfCloseEndTag\": t.angleBracket,\n    TagName: t.tagName,\n    \"MismatchedCloseTag/TagName\": [t.tagName,  t.invalid],\n    AttributeName: t.attributeName,\n    \"AttributeValue UnquotedAttributeValue\": t.attributeValue,\n    Is: t.definitionOperator,\n    \"EntityReference CharacterReference\": t.character,\n    Comment: t.blockComment,\n    ProcessingInst: t.processingInstruction,\n    DoctypeDecl: t.documentMeta\n    })\n*/\n","import { LIT0, baseStyles, makeStylesDark, makeStylesLight } from \"./base_styles\";\nimport { StyleDef } from \"./theme_types\";\n\nconst jsStyleDef: StyleDef = {\n    ...baseStyles,\n    propertyName: { color: LIT0 },\n};\n\nexport const jsTagsLight = makeStylesLight(jsStyleDef);\nexport const jsTagsDark = makeStylesDark(jsStyleDef);\n\n/*\n{\n    modifier: {}, // get set async static\n    controlKeyword: {}, // for while do if else switch try catch finally return throw break continue default case\n    operatorKeyword: {}, // in of await yield void typeof delete instanceof\n    definitionKeyword: {}, // let var const function class extends\n    moduleKeyword: {}, // import export from\n    keyword: {}, // in of await yield void typeof delete instanceof\n    special_string: {}, // template string\n    atom: {}, // super\n    bool: {}, // true, false\n    self: {}, // this\n    null: {}, // null\n    variableName: {},\n    function_variableName: {}, // function foo\n    definition_variableName: {}, // let foo\n    // labelName: {},\n    propertyName: {}, // foo.bar\n    // special_propertyName: {},\n    function_propertyName: {}, // foo.bar()\n    // function_definition_variableName: {}, // not sure\n    definition_className: {}, // class Foo\n\n    // definition_special_propertyName: {},\n    // definition_propertyName: {},\n\n    updateOperator: {},\n    lineComment: {},\n    blockComment: {},\n    number: {},\n    string: {},\n    arithmeticOperator: {},\n    logicOperator: {},\n    bitwiseOperator: {},\n    compareOperator: {},\n    regexp: {},\n    definitionOperator: {},\n    punctuation: {},\n    paren: {},\n    squareBracket: {},\n    brace: {},\n    special_brace: {},\n    derefOperator: {},\n    separator: {},\n    typeName: {},\n    definition_typeName: {},\n    attributeValue: {},\n};\n\nstyleTags({\n    \"get set async static\": t.modifier,\n    \"for while do if else switch try catch finally return throw break continue default case\": t.controlKeyword,\n    \"in of await yield void typeof delete instanceof\": t.operatorKeyword,\n    \"let var const function class extends\": t.definitionKeyword,\n    \"import export from\": t.moduleKeyword,\n    \"with debugger as new\": t.keyword,\n    TemplateString: t.special(t.string),\n    Super: t.atom,\n    BooleanLiteral: t.bool,\n    this: t.self,\n    null: t.null,\n    Star: t.modifier,\n    VariableName: t.variableName,\n    \"CallExpression/VariableName TaggedTemplateExpression/VariableName\": t.function(t.variableName),\n    VariableDefinition: t.definition(t.variableName),\n    Label: t.labelName,\n    PropertyName: t.propertyName,\n    PrivatePropertyName: t.special(t.propertyName),\n    \"CallExpression/MemberExpression/PropertyName\": t.function(t.propertyName),\n    \"FunctionDeclaration/VariableDefinition\": t.function(t.definition(t.variableName)),\n    \"ClassDeclaration/VariableDefinition\": t.definition(t.className),\n    PropertyDefinition: t.definition(t.propertyName),\n    PrivatePropertyDefinition: t.definition(t.special(t.propertyName)),\n    UpdateOp: t.updateOperator,\n    LineComment: t.lineComment,\n    BlockComment: t.blockComment,\n    Number: t.number,\n    String: t.string,\n    ArithOp: t.arithmeticOperator,\n    LogicOp: t.logicOperator,\n    BitOp: t.bitwiseOperator,\n    CompareOp: t.compareOperator,\n    RegExp: t.regexp,\n    Equals: t.definitionOperator,\n    \"Arrow : Spread\": t.punctuation,\n    \"( )\": t.paren,\n    \"[ ]\": t.squareBracket,\n    \"{ }\": t.brace,\n    \"InterpolationStart InterpolationEnd\": t.special(t.brace),\n    \".\": t.derefOperator,\n    \", ;\": t.separator,\n\n    TypeName: t.typeName,\n    TypeDefinition: t.definition(t.typeName),\n    \"type enum interface implements namespace module declare\": t.definitionKeyword,\n    \"abstract global Privacy readonly override\": t.modifier,\n    \"is keyof unique infer\": t.operatorKeyword,\n\n    JSXAttributeValue: t.attributeValue,\n    JSXText: t.content,\n    \"JSXStartTag JSXStartCloseTag JSXSelfCloseEndTag JSXEndTag\": t.angleBracket,\n    \"JSXIdentifier JSXNameSpacedName\": t.tagName,\n    \"JSXAttribute/JSXIdentifier JSXAttribute/JSXNameSpacedName\": t.attributeName\n})\n*/\n","import { COMMENT, KEY0, LIT1, TEXT, VAR1, baseStyles, makeStylesDark, makeStylesLight } from \"./base_styles\";\nimport type { StyleDef, TagStyleDef } from \"./theme_types\";\n\nconst markdownStyleDef: StyleDef = {\n    ...baseStyles,\n    content: { color: TEXT },\n    heading1: { color: TEXT, fontWeight: 700 },\n    heading2: { color: TEXT, fontWeight: 700 },\n    heading3: { color: TEXT, fontWeight: 700 },\n    heading4: { color: TEXT, fontWeight: 700 },\n    heading5: { color: TEXT, fontWeight: 700 },\n    heading6: { color: TEXT, fontWeight: 700 },\n    strong: { fontWeight: 700 },\n    emphasis: { fontStyle: \"italic\" },\n    strikethrough: { textDecoration: \"line-through\", textDecorationLine: \"line-through\" },\n    monospace: { color: LIT1 },\n    link: { color: KEY0 },\n    url: { color: VAR1, textDecoration: \"underline\" },\n    list: { color: COMMENT },\n    quote: { color: COMMENT, fontStyle: \"italic\" },\n    contentSeparator: { color: COMMENT },\n    processingInstruction: { color: COMMENT },\n    labelName: { color: COMMENT },\n    atom: { color: COMMENT, fontWeight: 600 },\n};\n\nexport const markdownTagsLight: TagStyleDef = makeStylesLight(markdownStyleDef);\nexport const markdownTagsDark: TagStyleDef = makeStylesDark(markdownStyleDef);\n","import { COMMENT, KEY0, KEY1, LIT0, LIT1, VAR0, baseStyles, makeStylesDark, makeStylesLight } from \"./base_styles\";\nimport type { StyleDef, TagStyleDef } from \"./theme_types\";\n\nconst yamlStyleDef: StyleDef = {\n    ...baseStyles,\n    definition_propertyName: { color: KEY0, fontWeight: 600 },\n    propertyName: { color: KEY0 },\n    attributeValue: { color: LIT1 },\n    string: { color: LIT1 },\n    special_string: { color: LIT1 },\n    content: {},\n    keyword: { color: KEY1, fontWeight: 600 },\n    meta: { color: COMMENT, fontWeight: 600 },\n    labelName: { color: VAR0 },\n    typeName: { color: LIT0 },\n    lineComment: { color: COMMENT },\n    separator: { color: COMMENT },\n    punctuation: { color: COMMENT },\n    squareBracket: {},\n    brace: {},\n};\n\nexport const yamlTagsLight: TagStyleDef = makeStylesLight(yamlStyleDef);\nexport const yamlTagsDark: TagStyleDef = makeStylesDark(yamlStyleDef);\n","import { useMemo } from \"react\";\nimport { cssLanguage } from \"@codemirror/lang-css\";\nimport { javascriptLanguage } from \"@codemirror/lang-javascript\";\nimport { HighlightStyle, LRLanguage, syntaxHighlighting } from \"@codemirror/language\";\nimport { Extension } from \"@codemirror/state\";\nimport { EditorView } from \"@codemirror/view\";\nimport { useTheme } from \"../../theme/styles\";\nimport { useExtension } from \"../utils/hooks\";\nimport { cssTagsDark, cssTagsLight } from \"./css_styles\";\nimport { htmlTagsDark, htmlTagsLight } from \"./html_styles\";\nimport { jsTagsDark, jsTagsLight } from \"./js_styles\";\nimport { markdownTagsDark, markdownTagsLight } from \"./markdown_styles\";\nimport { pyTagsDark, pyTagsLight } from \"./py_styles\";\nimport type { TagStyleDef } from \"./theme_types\";\nimport { yamlTagsDark, yamlTagsLight } from \"./yaml_styles\";\n\nfunction mkHighlightStyle(\n    tagStyleDef: TagStyleDef,\n    options?: { scope?: LRLanguage; themeType?: \"dark\" | \"light\" }\n): Extension {\n    const tagStyles = Object.values(tagStyleDef);\n    const extension = [syntaxHighlighting(HighlightStyle.define(tagStyles, options))];\n\n    // Because codemirror doesn't set styles if the class is part of the tagStyle 🙄\n    // so we create a separate syntaxHighlighting extension with a class definition instead of styles\n    // allows inspecting the CodeMirror editor when creating themes\n    // @ts-ignore\n    if (process.env.NODE_ENV !== \"production\") {\n        const devStyles = Object.entries(tagStyleDef).map(([tagName, { tag }]) => {\n            return { tag, class: `cm-tag-${tagName}` };\n        });\n        extension.push(syntaxHighlighting(HighlightStyle.define(devStyles, options)));\n    }\n    return extension;\n}\n\nfunction lightHighlightStyle(tagStyleDef: TagStyleDef, scope?: LRLanguage) {\n    return mkHighlightStyle(tagStyleDef, { scope, themeType: \"light\" });\n}\n\nfunction darkHighlightStyle(tagStyleDef: TagStyleDef, scope?: LRLanguage) {\n    return mkHighlightStyle(tagStyleDef, { scope, themeType: \"dark\" });\n}\n\nexport const highlightStyles = {\n    js: { light: lightHighlightStyle(jsTagsLight), dark: darkHighlightStyle(jsTagsDark) },\n    jsx: { light: lightHighlightStyle(jsTagsLight), dark: darkHighlightStyle(jsTagsDark) },\n    ts: { light: lightHighlightStyle(jsTagsLight), dark: darkHighlightStyle(jsTagsDark) },\n    tsx: { light: lightHighlightStyle(jsTagsLight), dark: darkHighlightStyle(jsTagsDark) },\n    json: { light: lightHighlightStyle(jsTagsLight), dark: darkHighlightStyle(jsTagsDark) },\n    py: { light: lightHighlightStyle(pyTagsLight), dark: darkHighlightStyle(pyTagsDark) },\n    css: { light: lightHighlightStyle(cssTagsLight), dark: darkHighlightStyle(cssTagsDark) },\n    md: { light: lightHighlightStyle(markdownTagsLight), dark: darkHighlightStyle(markdownTagsDark) },\n    markdown: { light: lightHighlightStyle(markdownTagsLight), dark: darkHighlightStyle(markdownTagsDark) },\n    yml: { light: lightHighlightStyle(yamlTagsLight), dark: darkHighlightStyle(yamlTagsDark) },\n    yaml: { light: lightHighlightStyle(yamlTagsLight), dark: darkHighlightStyle(yamlTagsDark) },\n    html: {\n        light: [\n            lightHighlightStyle(htmlTagsLight),\n            lightHighlightStyle(jsTagsLight, javascriptLanguage),\n            lightHighlightStyle(cssTagsLight, cssLanguage),\n        ],\n        dark: [\n            darkHighlightStyle(htmlTagsDark),\n            darkHighlightStyle(jsTagsDark, javascriptLanguage),\n            darkHighlightStyle(cssTagsDark, cssLanguage),\n        ],\n    },\n    svg: {\n        light: [\n            lightHighlightStyle(htmlTagsLight),\n            lightHighlightStyle(jsTagsLight, javascriptLanguage),\n            lightHighlightStyle(cssTagsLight, cssLanguage),\n        ],\n        dark: [\n            darkHighlightStyle(htmlTagsDark),\n            darkHighlightStyle(jsTagsDark, javascriptLanguage),\n            darkHighlightStyle(cssTagsDark, cssLanguage),\n        ],\n    },\n    xml: {\n        light: [\n            lightHighlightStyle(htmlTagsLight),\n            lightHighlightStyle(jsTagsLight, javascriptLanguage),\n            lightHighlightStyle(cssTagsLight, cssLanguage),\n        ],\n        dark: [\n            darkHighlightStyle(htmlTagsDark),\n            darkHighlightStyle(jsTagsDark, javascriptLanguage),\n            darkHighlightStyle(cssTagsDark, cssLanguage),\n        ],\n    },\n};\n\nexport function useBaseTheme(view: EditorView) {\n    const theme = useTheme();\n    const ThemeExtension = useMemo(() => {\n        const isDark = theme.isDark;\n        const overrides = {\n            \"&\": {\n                height: \"100%\",\n                backgroundColor: isDark ? \"#151718\" : \"\",\n            },\n            \"&.cm-editor.cm-focused\": {\n                outline: \"none\",\n            },\n            \".cm-scroller\": {\n                fontFamily: theme.codeFont,\n                fontSize: \"1.3rem\",\n                fontWeight: \"500\",\n                lineHeight: 1.9,\n            },\n            \".cm-gutterElement\": {\n                display: \"flex\",\n                flexDirection: \"column\",\n                justifyContent: \"flex-end\",\n            },\n            \".cm-line\": {\n                color: isDark ? \"#FFFCFC\" : \"#333\",\n            },\n            \".cm-cursor\": {\n                borderLeftColor: isDark ? \"#ddd\" : \"#444\",\n            },\n            \".cm-selectionLayer .cm-selectionBackground\": {\n                background: isDark ? \"#5559\" : \"#d9d9d9\",\n            },\n            \".cm-tooltip\": {\n                borderColor: `${theme.sectionBorderColor.toString()} !important`,\n                backgroundColor: `${theme.secondaryNav.background.toString()} !important`,\n                borderRadius: \"4px\",\n                position: \"absolute\",\n                \"&.cm-completionInfo\": {\n                    marginTop: \"-2px\",\n                    marginLeft: \"5px\",\n                    marginRight: \"5px\",\n                },\n                \"&.cm-tooltip-autocomplete > ul\": {\n                    maxHeight: \"15em\",\n                    borderRadius: \"4px\",\n                },\n                \"&.cm-tooltip-parameterhelper\": {\n                    padding: \"0px 6px\",\n                    fontFamily: theme.codeFont,\n                },\n            },\n            \".cm-completionLabel\": {\n                lineHeight: 1.4,\n            },\n            \".cm-tooltip-hover:has(.cm-tooltip-lint), .cm-tooltip.cm-tooltip-lint\": {\n                overflowY: \"auto\",\n            },\n            \".cm-tooltip-lint\": {\n                fontSize: \"1.2rem\",\n                lineHeight: 1.5,\n                color: theme.palette.fg1.toString(),\n                maxWidth: \"min(52rem, calc(100vw - 2rem))\",\n            },\n            \".cm-diagnosticText\": {\n                \"-webkit-user-select\": \"text\",\n                userSelect: \"text\",\n            },\n            \".cm-tooltip-lint .cm-diagnostic\": {\n                padding: \"0.75rem\",\n                marginLeft: 0,\n                overflowWrap: \"anywhere\",\n            },\n            \".cm-tooltip-lint .cm-diagnosticAction\": {\n                display: \"block\",\n                margin: \"0.5rem 0 0\",\n                padding: 0,\n                backgroundColor: \"transparent\",\n                color: theme.palette.primary.toString(),\n                textAlign: \"left\",\n                \"&:hover\": { textDecoration: \"underline\" },\n            },\n            \".cm-completionIcon\": {\n                fontSize: \"100%\",\n                width: \"1em\",\n                paddingRight: \"0.3em\",\n            },\n            \".cm-activeLine\": {\n                backgroundColor: \"#c0e0ff2e\",\n            },\n            \".cm-tooltip-autocomplete ul li[aria-selected]\": {\n                color: \"#fff\",\n                backgroundColor: \"#444\",\n            },\n            \".cm-completionMatchedText\": {\n                textDecoration: \"none\",\n                backgroundColor: \"rgba(27, 176, 238, 0.5)\",\n            },\n            \".cm-panel label\": {\n                fontWeight: \"500\",\n                color: theme.button.color.toString(),\n            },\n            \".cm-button\": {\n                borderRadius: `${theme.button.borderRadius}px`,\n                backgroundColor: theme.button.background.toString(),\n                border: `2px solid ${theme.button.border.toString()}`,\n                color: theme.button.color.toString(),\n                backgroundImage: \"none\",\n                \"&:hover:not(:disabled)\": {\n                    backgroundColor: theme.button.hoverBg.toString(),\n                    borderColor: theme.button.hoverBg.toString(),\n                    backgroundImage: \"none\",\n                },\n                \"&:active:not(:disabled)\": {\n                    backgroundColor: theme.button.activeBg.toString(),\n                    borderColor: theme.button.activeBg.toString(),\n                    backgroundImage: \"none\",\n                },\n                \"&:disabled\": {\n                    background: theme.button.disabled?.background?.toString() ?? \"transparent\",\n                    color: theme.button.disabledColor.toString(),\n                    border: `2px solid ${(theme.button.disabled?.border ?? theme.button.background).toString()}`,\n                    cursor: \"not-allowed\",\n                    backgroundImage: \"none\",\n                },\n            },\n        };\n        return EditorView.theme(overrides, { dark: isDark });\n    }, [theme]);\n\n    useExtension(view, () => ThemeExtension, [ThemeExtension]);\n}\n\nexport function useSyntaxHighlighting(view: EditorView, fileExtension: string = \"py\") {\n    const theme = useTheme();\n\n    const syntaxHighlightStyle = useMemo(() => {\n        const highlightStyle = highlightStyles[fileExtension as keyof typeof highlightStyles];\n        if (!highlightStyle) return [];\n        return theme.isDark ? highlightStyle.dark : highlightStyle.light;\n    }, [theme, fileExtension]);\n\n    useExtension(view, () => [syntaxHighlightStyle], [syntaxHighlightStyle]);\n}\n\nexport type EditorThemeKind = \"client\" | \"server\" | \"neutral\" | \"testing\";\n\nexport function useGutters(view: EditorView, kind: EditorThemeKind = \"client\") {\n    const theme = useTheme();\n    const GutterExtension = useMemo(() => {\n        const isDark = theme.isDark;\n        const overrides = {\n            \".cm-gutter.cm-lineNumbers\": {\n                borderLeft: `3px solid ${\n                    kind === \"neutral\"\n                        ? theme.palette.fg3.alpha(0.2)\n                        : kind === \"testing\"\n                          ? theme.secondaryNav.icon4.background\n                          : kind === \"server\"\n                            ? theme.palette.secondary\n                            : theme.palette.primary\n                }`,\n                color: isDark ? \"#999\" : \"#999\",\n            },\n            \".cm-gutterElement\": {\n                display: \"flex\",\n                flexDirection: \"column\",\n                justifyContent: \"flex-end\",\n            },\n        };\n        return EditorView.theme(overrides, { dark: isDark });\n    }, [theme, kind]);\n    useExtension(view, () => GutterExtension, [GutterExtension]);\n}\n\nexport function useEditorTheme(view: EditorView, fileExtension: string, kind: EditorThemeKind = \"client\") {\n    const theme = useTheme();\n    const ThemeExtension = useMemo(() => {\n        const isDark = theme.isDark;\n        const activeLineColor =\n            kind === \"neutral\"\n                ? theme.palette.fg3.alpha(0.06).toString()\n                : kind === \"testing\"\n                  ? theme.secondaryNav.icon4.background.alpha(0.18).toString()\n                  : kind === \"server\"\n                    ? \"#ffa6402e\"\n                    : \"#c0e0ff2e\";\n        const overrides = {\n            \".cm-activeLine\": {\n                backgroundColor: activeLineColor,\n            },\n            ...(kind !== \"client\" && {\n                \".cm-activeLineGutter\": { backgroundColor: activeLineColor },\n            }),\n        };\n        return EditorView.theme(overrides, { dark: isDark });\n    }, [theme, kind]);\n\n    useBaseTheme(view);\n    useGutters(view, kind);\n    useSyntaxHighlighting(view, fileExtension);\n    useExtension(view, () => ThemeExtension, [ThemeExtension]);\n}\n","import { baseStylesDark, baseStylesLight } from \"./base_styles\";\n\nexport const pyTagsLight = baseStylesLight;\nexport const pyTagsDark = baseStylesDark;\n\n/*\n\n{\n    keyword: {},\n    modifier: {}, //(keyword) \"async '*' '**' FormatConversion\" (bug in codemirror for *, **)\n    controlKeyword: {}, //(keyword) for while if elif else try except finally return raise break continue with pass assert await yield\n    operatorKeyword: {}, //(keyword) in not and or is del\n    moduleKeyword: {}, //(keyword) import\n    definitionKeyword: {}, // from def class global nonlocal lambda\n    null: {}, //(keyword) None\n    bool: {}, //(literal) True False\n    number: {}, // 3\n\n    variableName: {}, //(name) x\n    function_variableName: {}, // foo()\n    function_definition_variableName: {}, // def foo\n    definition_className: {}, // class Foo\n    propertyName: {}, //(name) foo.x\n    function_propertyName: {}, // foo.bar()\n    // comment: {},\n    lineComment: {}, // # comment\n    string: {}, // \"hi\"\n    special_string: {}, // fstring\n    meta: {}, // @\n    // bracket: {}, // catch all for brackets\n    paren: {}, // ()\n    squareBracket: {}, // []\n    brace: {}, // {}\n    // operator: {}, // catch all for operators\n    derefOperator: {}, // .\n    updateOperator: {}, // +=\n    arithmeticOperator: {}, // + - / //\n    bitwiseOperator: {}, // & | ^ << >>\n    compareOperator: {}, // \"<\" | \">\" | $[<>=!] \"=\" | \"<>\"\n    definitionOperator: {},\n    punctuation: {}, // ... Ellipsis\n    separator: {}, //(punctuation) , ;\n}\n\nhow codemirror defines it\nstyleTags({\n    \"async '*' '**' FormatConversion\": t.modifier,\n    \"for while if elif else try except finally return raise break continue with pass assert await yield\": t.controlKeyword,\n    \"in not and or is del\": t.operatorKeyword,\n    \"from def class global nonlocal lambda\": t.definitionKeyword,\n    import: t.moduleKeyword,\n    \"with as print\": t.keyword,\n    self: t.self,\n    Boolean: t.bool,\n    None: t.null,\n    VariableName: t.variableName,\n    \"CallExpression/VariableName\": t.function(t.variableName),\n    \"FunctionDefinition/VariableName\": t.function(t.definition(t.variableName)),\n    \"ClassDefinition/VariableName\": t.definition(t.className),\n    PropertyName: t.propertyName,\n    \"CallExpression/MemberExpression/PropertyName\": t.function(t.propertyName),\n    Comment: t.lineComment,\n    Number: t.number,\n    String: t.string,\n    FormatString: t.special(t.string),\n    UpdateOp: t.updateOperator,\n    ArithOp: t.arithmeticOperator,\n    BitOp: t.bitwiseOperator,\n    CompareOp: t.compareOperator,\n    AssignOp: t.definitionOperator,\n    Ellipsis: t.punctuation,\n    At: t.meta,\n    \"( )\": t.paren,\n    \"[ ]\": t.squareBracket,\n    \"{ }\": t.brace,\n    \".\": t.derefOperator,\n    \", ;\": t.separator\n    })\n */\n","import type { Token as TokenInfo } from \"@anvil-works/skulpt-parser/core\";\nimport { scanPython } from \"./python_tokens\";\n\n/**\n * Tokenizer scan of a Python module, locating a class body (and optionally a method within it).\n *\n * This is deliberately free of DOM, React and CodeMirror imports: it runs both on the main thread (from\n * `method_finder`, when actually inserting an event handler) and inside the autocompleter worker (to tell\n * the \"Create Event Handler\" widget where the end of the form class body is). Both callers must agree on\n * that position, so they share this one implementation rather than each computing it.\n *\n * We use the tokenizer rather than Skulpt's AST because Skulpt builds `ClassDef`/`FunctionDef` nodes\n * without `end_lineno`, so the AST cannot tell us where a class body ends. Tokens carry real end\n * positions, so they can.\n */\n\n/** Column of the first non-whitespace character, expanding tabs. */\nexport function countLeadingWhiteSpace(text: string, tabSize: number) {\n    let i = -1;\n    let col = 0;\n    while (++i < text.length) {\n        const chr = text[i];\n        if (chr === \"\\t\") {\n            col += tabSize - (col % tabSize);\n        } else if (chr === \" \") {\n            col += 1;\n        } else {\n            break;\n        }\n    }\n    return col;\n}\n\n/** Thrown to stop the tokenizer once we have what we came for. */\nexport const MethodFound = {};\nexport const ClassDefinitionEnd = {};\n\nexport type ScanStatus = typeof MethodFound | typeof ClassDefinitionEnd;\n\nexport interface ClassBodyScanResult {\n    /** `MethodFound` if `methodName` was found in the class body, `ClassDefinitionEnd` if we ran past it. */\n    status: ScanStatus;\n    /**\n     * 1-based line of the last non-blank line of the region we stopped at — the method when\n     * `status === MethodFound`, otherwise the class body. Trailing blank lines are skipped.\n     */\n    lineNumber: number;\n    /** 1-based line the found method's `def`/decorators start on. */\n    methodStart: number | null;\n    /** Decorator source lines attached to the found method, outermost first. */\n    methodDecorators: string[] | null;\n    decoratorsStart: number | null;\n    /** Indent (in columns) of the class body, i.e. of its `def` lines. */\n    classIndent: number | null;\n}\n\n/**\n * Walks the token stream tracking INDENT/DEDENT depth, looking for `className` at module level and\n * then `methodName` within its body. Pass `methodName: null` to scan for the end of the class body\n * only — with no method to match, the scan always runs on to `ClassDefinitionEnd`.\n */\nexport class ClassBodyScanner {\n    findClass = true;\n    findMethod = false;\n    findClassName = false;\n    findMethodName = false;\n    tempDecorators: string[] = [];\n    methodDecorators: string[] | null = null;\n    tempDecoratorsStart: number | null = null;\n    decoratorsStart: number | null = null;\n    classFound = false;\n    methodFound = false;\n    methodStart: number | null = null;\n    prevToken: TokenInfo | null = null;\n    classIndent: number | null = null;\n    level = 0;\n    blankLines = 0;\n\n    constructor(\n        readonly code: string,\n        readonly className: string,\n        readonly methodName: string | null,\n        readonly tabSize: number\n    ) {\n        this.tokenEater = this.tokenEater.bind(this);\n    }\n\n    /**\n     * Returns null if the class was never found, or the code did not tokenize (i.e. a syntax error).\n     * Pass `quiet` when a syntax error is an expected, uninteresting outcome — the autocompleter worker\n     * re-scans on a timer while the user types, and would otherwise log on every half-finished line.\n     */\n    scan({ quiet = false }: { quiet?: boolean } = {}): ClassBodyScanResult | null {\n        let status: ScanStatus | undefined;\n        try {\n            const source = this.code\n                .split(/\\r\\n?|\\n/)\n                .map((line) => line + \"\\n\")\n                .join(\"\");\n            for (const token of scanPython(source, \"<class-body-scan>\")) this.tokenEater(token);\n        } catch (e) {\n            if (e !== MethodFound && e !== ClassDefinitionEnd) {\n                // probably a syntax error\n                if (!quiet) console.error(e);\n                return null;\n            }\n            status = e as ScanStatus;\n        }\n        if (!status) {\n            return null;\n        }\n        return {\n            status,\n            lineNumber: this.prevToken!.end[0] - this.blankLines + 1,\n            methodStart: this.methodStart,\n            methodDecorators: this.methodDecorators,\n            decoratorsStart: this.decoratorsStart,\n            classIndent: this.classIndent,\n        };\n    }\n\n    tokenEater(token: TokenInfo) {\n        const { type, line, string } = token;\n\n        if (type === \"NEWLINE\") {\n            this.blankLines += 1;\n            this.prevToken = token;\n            if (this.methodFound) {\n                this.methodStart ??= token.start[0];\n                if (!this.methodDecorators) {\n                    this.methodDecorators = this.tempDecorators;\n                    this.decoratorsStart = this.tempDecoratorsStart;\n                }\n                this.tempDecorators = [];\n            } else if (!this.classFound) {\n                this.findClass = true;\n            } else {\n                this.findMethod = true;\n            }\n        } else if (type === \"INDENT\") {\n            this.level += 1;\n        } else if (type === \"DEDENT\") {\n            this.level -= 1;\n            this.tempDecorators = [];\n            this.tempDecoratorsStart = null;\n        } else if (type === \"COMMENT\") {\n            // A comment dedented back out of the class body is not part of it, so leave `blankLines`\n            // alone and let the trailing-blank skip walk back past it — otherwise a module-level\n            // comment after the class drags the reported end of the body outside the class, and a new\n            // method gets appended below it at class-body indent (an IndentationError).\n            // An indented comment *is* part of the body, and resets the count like any other token.\n            if (this.classIndent !== null && this.getIndent(line) < this.classIndent) {\n                return;\n            }\n        } else if (type === \"NL\") {\n            this.blankLines += 1;\n            this.prevToken = token;\n        } else if (type === \"OP\" && string === \"@\" && this.findMethod) {\n            this.tempDecoratorsStart ??= token.start[0];\n            this.tempDecorators.push(line.trim());\n        } else if (this.findClass) {\n            this.findClass = false;\n            if (this.level === 0 && string === \"class\") {\n                this.findClassName = true;\n            }\n        } else if (this.findClassName) {\n            this.findClassName = false;\n            if (type === \"NAME\" && this.className === string) {\n                this.classFound = true;\n            }\n        } else if (this.findMethod) {\n            this.findMethod = false;\n            if (this.level === 0) {\n                // we're no longer in the class body\n                throw ClassDefinitionEnd;\n            } else if (this.level === 1) {\n                this.classIndent ??= this.getIndent(line);\n                if (string === \"def\") {\n                    this.findMethodName = true;\n                }\n            }\n        } else if (this.findMethodName) {\n            this.findMethodName = false;\n            // methodName === null means \"never match\", so the scan runs on to the end of the class body\n            if (type === \"NAME\" && this.methodName !== null && this.methodName === string) {\n                this.methodFound = true;\n            }\n        } else if (this.methodStart) {\n            if (this.level <= 1) {\n                throw MethodFound;\n            }\n        }\n\n        if (type !== \"NEWLINE\" && type !== \"NL\" && type !== \"DEDENT\" && type !== \"ENDMARKER\") {\n            this.blankLines = 0;\n        }\n    }\n\n    getIndent(line: string) {\n        return countLeadingWhiteSpace(line, this.tabSize);\n    }\n}\n\n/**\n * 1-based line of the last non-blank line of `className`'s body, or null if the class isn't there or\n * the code doesn't tokenize. This is the line a new method would be appended after, so it is also\n * where the \"Create Event Handler\" widget anchors itself.\n */\nexport function findFormClassBodyEndLine(\n    code: string,\n    className: string,\n    // Only used to compare one indent against another (a comment's against the class body's), so a\n    // caller with no editor to ask (the worker) can leave it alone.\n    tabSize = 4\n): number | null {\n    // Take the leaf name: forms are addressed as e.g. \"MyApp.Form1\" but declared as \"class Form1\".\n    const leafClassName = className.split(\".\").pop()!;\n    const result = new ClassBodyScanner(code, leafClassName, null, tabSize).scan({ quiet: true });\n    return result && result.status === ClassDefinitionEnd ? result.lineNumber : null;\n}\n","import { type ReactPortal, createElement, useLayoutEffect } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useSelector } from \"react-redux\";\nimport { Transaction } from \"@codemirror/state\";\nimport { Decoration, EditorView, ViewUpdate, WidgetType } from \"@codemirror/view\";\nimport { isEqual } from \"lodash-es\";\nimport { EVENTS, useSubscribeToDispatchEvent } from \"@/actions\";\nimport { getAppEditState } from \"@/controllers/app\";\nimport { getCachedCodeItem, getCodeItemHistory } from \"@/controllers/app/code\";\nimport { useIsDark } from \"@/theme/styles\";\nimport { type Conflicts, type EditorPath, type State as IDEState, isCodePath } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ConflictActions } from \"./conflict_actions\";\nimport { conflictMinimap } from \"./conflict_minimap\";\nimport {\n    ConflictManager,\n    InitializeConflictsEffect,\n    ResolveConflictEffect,\n    RestoreConflictsEffect,\n    conflictManagerState,\n} from \"./conflict_state\";\nimport { SeqNumberEffect, UpdatingCodeItemEffect, isExternalUpdate, useExtension, useViewSelector } from \"./hooks\";\n\nexport type { Conflicts } from \"@/types\";\n\ntype State = \"A\" | \"B\" | \"E\";\n\ntype TextChunk = NonNullable<Conflicts[\"text_chunks\"]>[number];\n\ntype UpdateConflicts = (description: string, conflicts: Conflicts) => Promise<number>;\n\nexport function useConflictMarkers(\n    view: EditorView,\n    codePath: EditorPath,\n    conflicts: Conflicts | undefined,\n    updateCodeItem: UpdateConflicts\n) {\n    const isDark = useIsDark();\n    const mergeIdentity = useSelector((state: IDEState) => {\n        const mergeId = getAppEditState(state)?.merge;\n        if (mergeId === undefined) return undefined;\n        // Pending merge numbers are reused. Its base and parents distinguish\n        // this merge from completed merges whose text history is still cached.\n        // Whole-file resolution can remove the central conflict metadata.\n        const merge =\n            state.app?.conflicts?.merge ??\n            (isCodePath(codePath)\n                ? getCachedCodeItem(codePath, state).resolvedConflictMerge\n                : getCodeItemHistory(codePath, state)?.resolvedConflictMerge);\n        return merge && JSON.stringify([mergeId, merge.base, merge.parents]);\n    });\n    const updater = useEvent(async (description: string, manager: ConflictManager) => {\n        const { text_chunks, item } = manager;\n        let newConflicts: Conflicts;\n        if (text_chunks !== null) {\n            newConflicts = { ...conflicts, item, text_chunks };\n        } else {\n            newConflicts = { ...conflicts, item };\n            delete newConflicts.text_chunks;\n        }\n        view.dispatch({ effects: UpdatingCodeItemEffect.of(true) });\n        const seqNum = await updateCodeItem(description, newConflicts);\n        view.dispatch({ effects: SeqNumberEffect.of(seqNum) });\n    });\n\n    const conflictListener = useEvent(async (update: ViewUpdate) => {\n        // Another extra-file editor already saved the document and its ranges.\n        // Its metadata is authoritative; don't map a full-document replacement back into the store.\n        if (!isCodePath(codePath) && isExternalUpdate(update)) return;\n        const conflictManager = update.state.field(conflictManagerState, false);\n        if (!conflictManager) return;\n        if (update.startState.field(conflictManagerState, false)?.text_chunks === conflictManager.text_chunks) return;\n\n        let description = \"\";\n        if (update.docChanged) {\n            // TODO - we should probably combine this with the other updateListener\n            description = \"Conflict (maybe) moved\";\n        } else {\n            for (const tr of update.transactions) {\n                if (tr.effects.some((e) => e.is(ResolveConflictEffect) || e.is(RestoreConflictsEffect))) {\n                    description = \"Resolved conflict\";\n                    break;\n                }\n            }\n        }\n        if (!description) return;\n        updater(description, conflictManager);\n    });\n\n    useSubscribeToDispatchEvent(\n        EVENTS.CONFLICT_NAVIGATE,\n        ({ codePath: navCodePath, direction }: { codePath: string; direction: \"UP\" | \"DOWN\" }) => {\n            if (navCodePath !== codePath) return;\n            const textChunks = view.state.field(conflictManagerState, false)?.text_chunks;\n            if (!textChunks) return;\n            const anchorLineNumber = view.state.doc.lineAt(view.state.selection.main.anchor).number;\n            let nextConflict;\n\n            if (direction === \"UP\") {\n                // Look for previous conflicts\n                for (const textChunk of [...textChunks].reverse()) {\n                    if (textChunk.start + 1 < anchorLineNumber) {\n                        nextConflict = textChunk.start + 1;\n                        break;\n                    }\n                }\n                // If no previous conflict, cycle to the last one\n                if (nextConflict === undefined && textChunks.length > 0) {\n                    nextConflict = textChunks.at(-1)!.start + 1;\n                }\n            } else {\n                // Look for next conflicts\n                for (const textChunk of textChunks) {\n                    if (textChunk.start + 1 > anchorLineNumber) {\n                        nextConflict = textChunk.start + 1;\n                        break;\n                    }\n                }\n                // If no next conflict, cycle to the first one\n                if (nextConflict === undefined && textChunks.length > 0) {\n                    nextConflict = textChunks.at(0)!.start + 1;\n                }\n            }\n            if (nextConflict === undefined) return;\n\n            const position =\n                nextConflict > view.state.doc.lines ? view.state.doc.length : view.state.doc.line(nextConflict).from;\n            view.dispatch({ selection: { anchor: position }, scrollIntoView: true });\n            view.focus();\n        }\n    );\n\n    useExtension(\n        view,\n        () => [\n            EditorView.updateListener.of(conflictListener),\n            conflictTheme,\n            conflictManagerState.init((state) => ConflictManager.init(state, conflicts ?? {}, mergeIdentity)),\n            EditorView.decorations.compute([conflictManagerState], (state) =>\n                makeMarkers(state.field(conflictManagerState))\n            ),\n            EditorView.decorations.compute([conflictManagerState], (state) =>\n                makeLines(state.field(conflictManagerState))\n            ),\n        ],\n        []\n    );\n\n    useExtension(view, () => {\n        // Canvas cannot resolve CSS variables. Use the same theme shades as\n        // the conflict headers, resolved to colours before drawing.\n        const style = getComputedStyle(document.documentElement);\n        const shade = isDark ? \"300\" : \"700\";\n        return conflictMinimap([\n            style.getPropertyValue(`--color-secondary-${shade}`).trim(),\n            style.getPropertyValue(`--color-primary-${shade}`).trim(),\n        ]);\n    }, [isDark]);\n\n    // A new merge resets the markers. Within a merge, code-item transactions own\n    // their ranges; extra-file editors also take authoritative ranges from central\n    // state when another editor updates the same file.\n    const manager = useViewSelector(view, () => view.state.field(conflictManagerState, false));\n    useLayoutEffect(() => {\n        if (\n            manager?.mergeIdentity !== mergeIdentity ||\n            (conflicts?.text_chunks && !manager?.item && !manager?.text_chunks) ||\n            (!isCodePath(codePath) && !isEqual(conflicts?.text_chunks ?? null, manager?.text_chunks ?? null))\n        ) {\n            view.dispatch({\n                effects: InitializeConflictsEffect.of({\n                    conflicts: {\n                        ...conflicts,\n                        // Resolution can remove the central entry. Keep its item identity\n                        // for undo in this merge, but never carry it into a different merge.\n                        item: conflicts?.item ?? (manager?.mergeIdentity === mergeIdentity ? manager?.item : undefined),\n                    },\n                    mergeIdentity,\n                }),\n                annotations: Transaction.addToHistory.of(false),\n            });\n        }\n    }, [view, conflicts, mergeIdentity, manager]);\n\n    // CodeMirror owns the widget hosts; portals keep the controls in the IDE's\n    // React tree so shared buttons and tooltips receive their usual context.\n    const portals: ReactPortal[] = [];\n    if (manager?.text_chunks) {\n        for (const decorations of view.state.facet(EditorView.decorations)) {\n            if (typeof decorations === \"function\") continue;\n            decorations.between(0, view.state.doc.length, (_from, _to, decoration) => {\n                const widget = decoration.spec.widget;\n                if (widget instanceof InfoBanner && widget.actionsHost) {\n                    portals.push(\n                        createPortal(\n                            createElement(ConflictActions, { view, textChunk: widget.textChunk }),\n                            widget.actionsHost,\n                            String(portals.length)\n                        )\n                    );\n                }\n            });\n        }\n    }\n    return portals;\n}\n\nfunction makeMarkers(manager: ConflictManager | null) {\n    const markers = [];\n    for (const { textChunk, altRanges } of manager?.ranges ?? []) {\n        const [{ from: from0 }, { from: from1 }] = altRanges;\n        const [{ s: s0 }, { s: s1 }] = textChunk.alternatives;\n        markers.push(infoBannerDecoration(s0, true, textChunk).range(from0));\n        markers.push(infoBannerDecoration(s1, false, textChunk).range(from1));\n    }\n    return Decoration.set(markers, true);\n}\n\nfunction makeLines(manager: ConflictManager | null) {\n    const lineDecos = [];\n    for (const { lineStarts } of manager?.ranges ?? []) {\n        const [froms0, froms1] = lineStarts;\n        lineDecos.push(...froms0.map((from) => backgroundColorLine.A.range(from)));\n        lineDecos.push(...froms1.map((from) => backgroundColorLine.B.range(from)));\n    }\n    return Decoration.set(lineDecos, true);\n}\n\nclass InfoBanner extends WidgetType {\n    readonly actionsHost: HTMLDivElement | null;\n    constructor(\n        readonly state: State,\n        readonly original: boolean,\n        readonly textChunk: TextChunk\n    ) {\n        super();\n        this.actionsHost = original ? document.createElement(\"div\") : null;\n    }\n    toDOM(view: EditorView) {\n        const marker = document.createElement(\"div\");\n        marker.className = \"cm-conflict-marker\";\n        if (this.original) {\n            const toolbar = marker.appendChild(document.createElement(\"div\"));\n            toolbar.className = \"cm-conflict-toolbar\";\n            const title = toolbar.appendChild(document.createElement(\"span\"));\n            title.className = \"cm-conflict-title\";\n            title.textContent = \"Conflict\";\n            const actions = toolbar.appendChild(this.actionsHost!);\n            actions.className = \"cm-conflict-actions\";\n            actions.setAttribute(\"role\", \"group\");\n            actions.setAttribute(\"aria-label\", \"Resolve this conflict\");\n        }\n        const banner = marker.appendChild(document.createElement(\"div\"));\n        banner.className = `cm-conflict-header cm-conflict-header-${this.original ? \"A\" : \"B\"}`;\n        const label = banner.appendChild(document.createElement(\"span\"));\n        label.textContent = this.original ? \"You had:\" : \"The version you're merging had:\";\n        if (this.state === \"E\") {\n            const edited = banner.appendChild(document.createElement(\"span\"));\n            edited.className = \"cm-conflict-edited\";\n            edited.textContent = \"Edited\";\n        }\n        if (this.textChunk.alternatives[this.original ? 0 : 1].n === 0) {\n            const empty = banner.appendChild(document.createElement(\"span\"));\n            empty.className = \"cm-conflict-empty\";\n            empty.textContent = \"No lines\";\n        }\n        return marker;\n    }\n\n    ignoreEvent() {\n        return true;\n    }\n}\n\nconst infoBannerDecoration = (state: State, original: boolean, textChunk: TextChunk) =>\n    Decoration.widget({\n        widget: new InfoBanner(state, original, textChunk),\n        side: -1,\n        block: true,\n    });\n\nconst backgroundColorLine = {\n    A: Decoration.line({\n        attributes: { class: \"cm-conflict-content-A\" },\n    }),\n    B: Decoration.line({\n        attributes: { class: \"cm-conflict-content-B\" },\n    }),\n};\n\nconst conflictTheme = EditorView.baseTheme({\n    \"&light\": {\n        \"--conflict-yours\": \"var(--color-secondary-700)\",\n        \"--conflict-incoming\": \"var(--color-primary-700)\",\n        \"--conflict-yours-header\": \"color-mix(in srgb, var(--color-secondary) 18%, transparent)\",\n        \"--conflict-incoming-header\": \"color-mix(in srgb, var(--color-primary) 16%, transparent)\",\n        \"--conflict-yours-code\": \"color-mix(in srgb, var(--color-secondary) 8%, transparent)\",\n        \"--conflict-incoming-code\": \"color-mix(in srgb, var(--color-primary) 8%, transparent)\",\n        \"--conflict-toolbar\": \"var(--color-light-bg2)\",\n        \"--conflict-border\": \"var(--color-light-bg3)\",\n        \"--conflict-text\": \"var(--color-light-fg1)\",\n    },\n    \"&dark\": {\n        \"--conflict-yours\": \"var(--color-secondary-300)\",\n        \"--conflict-incoming\": \"var(--color-primary-300)\",\n        \"--conflict-yours-header\": \"color-mix(in srgb, var(--color-secondary) 18%, transparent)\",\n        \"--conflict-incoming-header\": \"color-mix(in srgb, var(--color-primary) 18%, transparent)\",\n        \"--conflict-yours-code\": \"color-mix(in srgb, var(--color-secondary) 10%, transparent)\",\n        \"--conflict-incoming-code\": \"color-mix(in srgb, var(--color-primary) 10%, transparent)\",\n        \"--conflict-toolbar\": \"var(--color-dark-bg2)\",\n        \"--conflict-border\": \"var(--color-dark-bg3)\",\n        \"--conflict-text\": \"var(--color-dark-fg1)\",\n    },\n    \".cm-conflict-header-A, .cm-conflict-content-A\": {\n        boxShadow: \"inset 3px 0 var(--conflict-yours)\",\n    },\n    \".cm-conflict-header-B, .cm-conflict-content-B\": {\n        boxShadow: \"inset 3px 0 var(--conflict-incoming)\",\n    },\n    \".cm-conflict-content-A\": { backgroundColor: \"var(--conflict-yours-code)\" },\n    \".cm-conflict-content-B\": { backgroundColor: \"var(--conflict-incoming-code)\" },\n    \".cm-conflict-header-A\": {\n        backgroundColor: \"var(--conflict-yours-header)\",\n        color: \"var(--conflict-yours)\",\n    },\n    \".cm-conflict-header-B\": {\n        backgroundColor: \"var(--conflict-incoming-header)\",\n        color: \"var(--conflict-incoming)\",\n    },\n    \".cm-conflict-marker\": {\n        fontFamily: \"var(--anvil-ui-font)\",\n        fontSize: \"1.2rem\",\n        lineHeight: \"1.5\",\n        whiteSpace: \"normal\",\n        userSelect: \"none\",\n    },\n    \".cm-conflict-header\": {\n        display: \"flex\",\n        flexWrap: \"wrap\",\n        alignItems: \"center\",\n        gap: \"8px\",\n        padding: \"4px 12px\",\n        fontWeight: \"600\",\n    },\n    \".cm-conflict-edited, .cm-conflict-empty\": {\n        fontSize: \"0.9em\",\n        fontWeight: \"400\",\n        color: \"var(--conflict-text)\",\n    },\n    \".cm-conflict-edited\": {\n        border: \"1px solid currentColor\",\n        borderRadius: \"3px\",\n        padding: \"0 4px\",\n    },\n    \".cm-conflict-toolbar\": {\n        display: \"flex\",\n        alignItems: \"center\",\n        flexWrap: \"wrap\",\n        gap: \"8px 16px\",\n        padding: \"6px 12px\",\n        backgroundColor: \"var(--conflict-toolbar)\",\n        borderBottom: \"1px solid var(--conflict-border)\",\n        color: \"var(--conflict-text)\",\n    },\n    \".cm-conflict-title\": { fontWeight: \"600\" },\n    \".cm-conflict-actions\": {\n        display: \"flex\",\n        flexWrap: \"wrap\",\n        alignItems: \"center\",\n        gap: \"4px\",\n    },\n    \".cm-conflict-actions [role=button]:focus-visible\": {\n        outline: \"2px solid var(--color-primary-600)\",\n        outlineOffset: \"2px\",\n    },\n    \".cm-conflict-actions .cm-conflict-mark-resolved\": { marginLeft: \"8px\" },\n});\n","import { foldState, foldedRanges } from \"@codemirror/language\";\nimport { Facet } from \"@codemirror/state\";\nimport { conflictManagerState } from \"./conflict_state\";\n\n// Minimap consumers without a conflict editor receive no gutter marks.\nexport const conflictMinimapGutters = Facet.define<Record<number, string>[], Record<number, string>[]>({\n    combine: (values) => values[0] ?? [],\n});\n\nexport function conflictMinimap(colors: [string, string]) {\n    return [\n        foldState,\n        conflictMinimapGutters.compute([conflictManagerState, foldState], (state) => {\n            const chunks = state.field(conflictManagerState)?.text_chunks;\n            if (!chunks?.length) return [];\n\n            // The minimap numbers its drawn rows, with folded lines collapsed\n            // onto their header. Keep hidden conflicts visible on that row too.\n            const folds: { from: number; to: number }[] = [];\n            foldedRanges(state).between(0, state.doc.length, (from, to) => {\n                const first = state.doc.lineAt(from);\n                const start = Math.max(1, first.number - (from === first.from ? 1 : 0));\n                const end = state.doc.lineAt(Math.max(from, to - 1)).number;\n                const previous = folds.at(-1);\n                if (previous && start <= previous.to) previous.to = Math.max(previous.to, end);\n                else folds.push({ from: start, to: end });\n            });\n            const minimapRow = (line: number) => {\n                let hidden = 0;\n                for (const fold of folds) {\n                    if (line < fold.from) break;\n                    if (line <= fold.to) return fold.from - hidden;\n                    hidden += fold.to - fold.from;\n                }\n                return line - hidden;\n            };\n\n            const gutters: [Record<number, string>, Record<number, string>] = [{}, {}];\n            for (const chunk of chunks) {\n                chunk.alternatives.forEach(({ l, n }, side) => {\n                    // A zero-line alternative still has a conflict header.\n                    for (let line = l + 1; line <= l + Math.max(n, 1); line++) {\n                        const row = minimapRow(Math.min(line, state.doc.lines));\n                        gutters[side][row] = colors[side];\n                    }\n                });\n            }\n            return gutters;\n        }),\n    ];\n}\n","import { invertedEffects, isolateHistory } from \"@codemirror/commands\";\nimport {\n    Annotation,\n    ChangeDesc,\n    EditorState,\n    StateEffect,\n    StateField,\n    Text,\n    Transaction,\n    TransactionSpec,\n} from \"@codemirror/state\";\nimport type { ConflictItemSpec, Conflicts } from \"@/types\";\n\ntype TextChunk = NonNullable<Conflicts[\"text_chunks\"]>[number];\ntype Alt = TextChunk[\"alternatives\"][number];\n\ntype AltRanges = [{ from: number; to: number }, { from: number; to: number }];\ntype AltLineStarts = [number[], number[]];\n\nfunction mapAltsToRanges(alts: [Alt, Alt], doc: Text) {\n    const lineStarts = [];\n    const ranges = [];\n    for (const { l, n } of alts) {\n        const alt_froms = [];\n        let i = 0;\n        while (i < n) {\n            alt_froms.push(doc.line(l + 1 + i).from);\n            i++;\n        }\n        lineStarts.push(alt_froms);\n        const from = l < doc.lines ? doc.line(l + 1).from : doc.length;\n        ranges.push({ from, to: n === 0 ? from : doc.line(l + n).to });\n    }\n    return { altRanges: ranges as AltRanges, lineStarts: lineStarts as AltLineStarts };\n}\n\nclass TextChunkRange {\n    constructor(\n        readonly textChunk: TextChunk,\n        readonly altRanges: AltRanges,\n        readonly lineStarts: AltLineStarts\n    ) {}\n\n    map(state: EditorState, changes: ChangeDesc) {\n        const doc = state.doc;\n        const alts: [Alt, Alt] = [{ ...this.textChunk.alternatives[0] }, { ...this.textChunk.alternatives[1] }];\n        this.altRanges.forEach((range, i) => {\n            const alt = alts[i];\n            const [newFrom, newTo] = [changes.mapPos(range.from, -1), changes.mapPos(range.to, 1)];\n            let deletedLine = false;\n            if (newFrom === newTo) {\n                changes.iterChangedRanges((from, to) => {\n                    // Deleting the line separator removes the alternative's line,\n                    // whereas deleting just its characters leaves an empty line.\n                    if (from <= range.from && to >= range.to && (from < range.from || to > range.to)) {\n                        deletedLine = true;\n                    }\n                });\n            }\n            let lineStart = doc.lineAt(newFrom);\n            if (lineStart.from < newFrom && newFrom < doc.length) {\n                // then it's no longer the start of the line!\n                lineStart = doc.lineAt(newFrom + 1);\n            }\n            // An insertion into a zero-line alternative ends before the next\n            // existing line, even when the inserted text ends with a newline.\n            const lineEnd = doc.lineAt(alt.n === 0 && newTo > newFrom ? newTo - 1 : newTo);\n            const touched = changes.touchesRange(range.from, range.to);\n            const empty = deletedLine || (alt.n === 0 && !touched);\n            alt.l = empty && newFrom === doc.length && lineStart.from < newFrom ? doc.lines : lineStart.number - 1;\n            alt.n = empty ? 0 : Math.max(0, lineEnd.number - lineStart.number + 1);\n            if (alt.s !== \"E\" && touched) {\n                alt.s = \"E\";\n            }\n        });\n        const textChunk = { start: alts[0].l, alternatives: alts };\n        const { altRanges, lineStarts } = mapAltsToRanges(alts, doc);\n        return new TextChunkRange(textChunk, altRanges, lineStarts);\n    }\n}\n\nexport class ConflictManager {\n    constructor(\n        readonly ranges: TextChunkRange[],\n        readonly text_chunks: TextChunk[] | null,\n        readonly item?: ConflictItemSpec,\n        // Text history can survive switching versions; markers belong to one pending merge.\n        readonly mergeIdentity?: string\n    ) {}\n\n    static init(state: EditorState, conflicts: Conflicts, mergeIdentity?: string) {\n        const ranges: TextChunkRange[] = [];\n        if (!conflicts || !conflicts.text_chunks) {\n            return new ConflictManager(ranges, null, conflicts?.item, mergeIdentity);\n        }\n        const { text_chunks } = conflicts;\n        const doc = state.doc;\n        for (const text_chunk of text_chunks) {\n            const { altRanges, lineStarts } = mapAltsToRanges(text_chunk.alternatives, doc);\n            ranges.push(new TextChunkRange(text_chunk, altRanges, lineStarts));\n        }\n        return new ConflictManager(ranges, text_chunks, conflicts.item, mergeIdentity);\n    }\n\n    resolveConflict(textChunk: TextChunk) {\n        let text_chunks: TextChunk[] | null = [...(this.text_chunks ?? [])];\n        const i = text_chunks.indexOf(textChunk);\n        if (i === -1) {\n            return this;\n        }\n        text_chunks.splice(i, 1);\n        if (text_chunks.length === 0) {\n            text_chunks = null;\n        }\n        const ranges = [...this.ranges.slice(0, i), ...this.ranges.slice(i + 1)];\n        return new ConflictManager(ranges, text_chunks, this.item, this.mergeIdentity);\n    }\n\n    map(state: EditorState, changes: ChangeDesc) {\n        if (!this.text_chunks) return this;\n        const newRanges = this.ranges.map((range) => range.map(state, changes));\n        return new ConflictManager(\n            newRanges,\n            newRanges.map((range) => range.textChunk),\n            this.item,\n            this.mergeIdentity\n        );\n    }\n}\n\n/** The preceding transaction in this view update, when both transactions are one edit for conflict ranges. */\nexport const MapConflictsFrom = Annotation.define<Transaction>();\n\nexport const conflictManagerState: StateField<ConflictManager | null> = StateField.define<ConflictManager | null>({\n    create() {\n        return null;\n    },\n    update(value, tr) {\n        if (value == null) {\n            return null;\n        }\n        // Grouped edits carry newest-to-oldest snapshots. The last one restores\n        // the state before the whole undo group, in the restored document.\n        const mergeIdentity = value.mergeIdentity;\n        const restores = tr.effects.filter(\n            (effect) => effect.is(RestoreConflictsEffect) && effect.value.mergeIdentity === mergeIdentity\n        );\n        if (restores.length)\n            return ConflictManager.init(tr.state, restores.at(-1)!.value.conflicts, value.mergeIdentity);\n        for (const effect of tr.effects) {\n            if (effect.is(InitializeConflictsEffect)) {\n                value = ConflictManager.init(tr.state, effect.value.conflicts, effect.value.mergeIdentity);\n            }\n            if (effect.is(ResolveConflictEffect)) {\n                value = value.resolveConflict(effect.value);\n            }\n        }\n        if (tr.docChanged && value.text_chunks) {\n            const preceding = tr.annotation(MapConflictsFrom);\n            if (preceding) {\n                // Round to line boundaries only after both changes have been applied.\n                const before = preceding.startState.field(conflictManagerState);\n                return before?.map(tr.state, preceding.changes.composeDesc(tr.changes)) ?? null;\n            }\n            value = value.map(tr.state, tr.changes);\n        }\n        return value;\n    },\n    provide: () =>\n        invertedEffects.of((tr) => {\n            // Mapping edits backwards cannot recover deleted line boundaries or\n            // the original A/B labels. History restores the pre-edit metadata.\n            const before = tr.startState.field(conflictManagerState, false);\n            const conflictEffect = tr.effects.some(\n                (effect) => effect.is(ResolveConflictEffect) || effect.is(RestoreConflictsEffect)\n            );\n            if (!before || (!tr.docChanged && !conflictEffect) || (!before.text_chunks && !conflictEffect)) return [];\n            return [\n                RestoreConflictsEffect.of({\n                    mergeIdentity: before.mergeIdentity,\n                    conflicts: { item: before.item, text_chunks: before.text_chunks ?? undefined },\n                }),\n            ];\n        }),\n});\n\nexport const ResolveConflictEffect = StateEffect.define<TextChunk>();\nexport const RestoreConflictsEffect = StateEffect.define<{ mergeIdentity?: string; conflicts: Conflicts }>();\nexport const InitializeConflictsEffect = StateEffect.define<{ mergeIdentity?: string; conflicts: Conflicts }>();\n\nexport type ConflictChoice = \"yours\" | \"incoming\" | \"both\" | \"edited\";\n\nexport function resolveConflict(state: EditorState, textChunk: TextChunk, choice: ConflictChoice): TransactionSpec {\n    const doc = state.doc;\n    let changes;\n    if (choice === \"yours\" || choice === \"incoming\") {\n        const rejected = textChunk.alternatives[choice === \"yours\" ? 1 : 0];\n        if (rejected.n > 0) {\n            let from = doc.line(rejected.l + 1).from;\n            const nextLine = rejected.l + rejected.n + 1;\n            const to = nextLine <= doc.lines ? doc.line(nextLine).from : doc.length;\n            if (nextLine > doc.lines && from > 0) from--;\n            changes = { from, to };\n        }\n    }\n    return {\n        changes,\n        effects: ResolveConflictEffect.of(textChunk),\n        annotations: [isolateHistory.of(\"full\"), Transaction.userEvent.of(\"input.resolveConflict\")],\n    };\n}\n","import { cssLanguage } from \"@codemirror/lang-css\";\nimport type { Diagnostic, LintSource } from \"@codemirror/lint\";\nimport { linter } from \"@codemirror/lint\";\n\nexport const cssDropzoneWarningLintSource: LintSource = (view) => {\n    const doc = view.state.doc.toString();\n    if (!/anvil-dropzone/i.test(doc)) return [];\n    const warnings: Diagnostic[] = [];\n    // The editor's incremental tree can stop beyond the viewport in large assets.\n    cssLanguage.parser.parse(doc).iterate({\n        enter(node) {\n            if (node.name === \"SelectorQuery\") return false;\n            if (\n                node.name === \"TagName\" &&\n                node.node.parent?.name === \"TagSelector\" &&\n                doc.slice(node.from, node.to).toLowerCase() === \"anvil-dropzone\"\n            ) {\n                warnings.push({\n                    from: node.from,\n                    to: node.to,\n                    severity: \"warning\",\n                    source: \"anvil-dropzone-selector\",\n                    message:\n                        \"HtmlComponent no longer renders anvil-dropzone elements. Target a component class or its surrounding element instead.\",\n                });\n            }\n        },\n    });\n    return warnings;\n};\n\nexport const cssDropzoneWarningLinter = () => linter(cssDropzoneWarningLintSource, { delay: 1000 });\n","import { useLayoutEffect, useMemo, useRef } from \"react\";\nimport { Compartment, type Extension, StateEffect } from \"@codemirror/state\";\nimport { EditorView, type ViewUpdate } from \"@codemirror/view\";\n\nexport function useExtension(view: EditorView, extensionCreator: () => Extension, deps: readonly unknown[]) {\n    const compartmentRef = useRef<Compartment | null>(null);\n\n    if (compartmentRef.current === null) {\n        compartmentRef.current = new Compartment();\n    }\n\n    const compartment = compartmentRef.current;\n    const extension = useMemo(extensionCreator, [view, ...deps]);\n\n    useLayoutEffect(() => {\n        if (!compartment.get(view.state)) {\n            view.dispatch({\n                effects: StateEffect.appendConfig.of(compartment.of(extension)),\n            });\n        } else {\n            view.dispatch({\n                effects: compartment.reconfigure(extension),\n            });\n        }\n    }, [view, compartment, extension]);\n}\n\nexport function useUpdateListener(view: EditorView, callback: (update: ViewUpdate) => void, deps: readonly unknown[]) {\n    useExtension(view, () => EditorView.updateListener.of(callback), deps);\n}\n","import { StateEffectType } from \"@codemirror/state\";\nimport { ViewUpdate } from \"@codemirror/view\";\n\nexport function effectValueFromUpdate<T, N>(update: ViewUpdate, effect: StateEffectType<T>, ifNotFound: N) {\n    for (const tr of update.transactions) {\n        for (const ef of tr.effects) {\n            if (ef.is(effect)) {\n                return ef.value;\n            }\n        }\n    }\n    return ifNotFound;\n}\n","import React, {\n    useCallback,\n    useEffect,\n    useImperativeHandle,\n    useLayoutEffect,\n    useMemo,\n    useRef,\n    useState,\n    useSyncExternalStore,\n} from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { historyField, redo, redoDepth, undo, undoDepth } from \"@codemirror/commands\";\nimport { foldState, indentRange, indentUnit } from \"@codemirror/language\";\nimport {\n    Annotation,\n    Compartment,\n    EditorState,\n    EditorStateConfig,\n    Extension,\n    Prec,\n    StateEffect,\n    StateField,\n    Transaction,\n} from \"@codemirror/state\";\nimport { Command, EditorView, ViewUpdate, keymap } from \"@codemirror/view\";\nimport { showMinimap } from \"@replit/codemirror-minimap\";\nimport { isEmpty, isEqual } from \"lodash-es\";\nimport { EVENTS, offEvent, onEvent } from \"@/actions\";\nimport { dispatchWithRenameHistory, renameBoundaries, renameHistoryCommand } from \"@/analysis/rename-history\";\nimport { useSetGlobalHistory } from \"@/components/tabs/code/History\";\nimport { cacheView, getAppIsEditable, markUnsaved } from \"@/controllers/app\";\nimport { getCacheKey, setCodeItemHistory, strHashCode, updateCodeItem } from \"@/controllers/app/code\";\nimport { getExtraFileConflicts, getExtraFileContent, saveExtraFile } from \"@/controllers/app/extra-files\";\nimport { confirmItemConflictsResolved } from \"@/controllers/app/history\";\nimport { notifyUnsavedCallback } from \"@/controllers/app/saving\";\nimport { getUserMinimapPref, getUserTabSize, getUserUiPrefs } from \"@/controllers/user\";\nimport { CodeNavTarget, ExtraFileNavTarget, FullNavTarget } from \"@/router/navTypes\";\nimport { insertHistoryStateBeforeNextNavigation, navigate } from \"@/router/navigation\";\nimport { useNavTargetSelector, usePreserveNavigationFocus } from \"@/router/navigation-hooks\";\nimport { useRemToPixels } from \"@/theme/ThemeProvider\";\nimport type {\n    AnvilDispatch,\n    CodeItemYaml,\n    CodePath,\n    Conflicts,\n    EditHistory,\n    EditorPath,\n    ExtraFilePath,\n    FullView,\n    HistoryState,\n    ModuleItemYaml,\n    State,\n    View,\n} from \"@/types\";\nimport {\n    useConstant,\n    useEditSequenceNumber,\n    useEffectAsync,\n    useEffectWhen,\n    useLayoutEffectWhen,\n    useResizeObserver,\n} from \"@/util/hooks\";\nimport useEffectEvent from \"@/util/useEffectEvent\";\nimport useEvent from \"@/util/useEventCallback\";\nimport type { AssetFileType } from \"../editors/base_asset_editor\";\nimport { CustomHtmlFormYaml } from \"../types\";\nimport { useConflictMarkers } from \"./conflict_markers\";\nimport { conflictMinimapGutters } from \"./conflict_minimap\";\nimport { ResolveConflictEffect, RestoreConflictsEffect, conflictManagerState } from \"./conflict_state\";\nimport { useExtension, useUpdateListener } from \"./extensions\";\nimport { reindent } from \"./reindent\";\n\nexport { useExtension, useUpdateListener } from \"./extensions\";\nexport type EditorViewRef = EditorView;\n\nexport function useEditorView(\n    initState: (() => EditorStateConfig | EditorState) | EditorStateConfig = {},\n    deps: any[] = [],\n    viewRef?: React.Ref<EditorViewRef>\n): EditorView {\n    const view = useMemo(() => {\n        initState = typeof initState === \"function\" ? initState() : initState;\n        if (!(initState instanceof EditorState)) {\n            initState = EditorState.create(initState);\n        }\n        const state = initState as EditorState;\n        return new EditorView({ state, dispatchTransactions: dispatchWithRenameHistory });\n    }, deps);\n\n    useImperativeHandle(viewRef, () => view, [view]);\n\n    useEffect(() => {\n        return () => view.destroy();\n    }, [view]);\n\n    return view;\n}\n\nexport function loadWithEditorHistory(stateObject: EditorStateConfig, historyState?: HistoryState) {\n    const doc = stateObject.doc as string;\n    if (!historyState || !historyState.selection) {\n        // either we weren't in the cache or we were but we have an old version of editHistory\n        return stateObject;\n    } else if (strHashCode(doc) !== historyState.hash) {\n        console.info(\"Not loading code editor history: Hash mismatch.\");\n        return stateObject;\n    }\n    try {\n        const { history: _history, renameBoundaries: ids, ...withoutHistory } = historyState;\n        return EditorState.fromJSON(\n            { doc, ...withoutHistory },\n            {\n                ...stateObject,\n                extensions: [\n                    stateObject.extensions ?? [],\n                    historyField.init(() => historyState.history),\n                    ids ? renameBoundaries.init(() => ids) : [],\n                ],\n            },\n            {\n                folding: foldState,\n            }\n        );\n    } catch (e) {\n        console.warn(e);\n        return stateObject;\n    }\n}\n\nexport function useUpdateIndent(view: EditorView) {\n    const tabSize = useSelector<any, number>(getUserTabSize);\n    return useExtension(view, () => [EditorState.tabSize.of(tabSize), indentUnit.of(\" \".repeat(tabSize))], [tabSize]);\n}\n\nconst pythonReindenter: Command = ({ state, dispatch }) => {\n    /** @todo - evaluate whether reindent is better than codemirrorReindnenter below (It should be) */\n    const doc = state.doc;\n    const source = doc.toString();\n    reindent(source, state.tabSize).then((insert) => {\n        if (insert !== source) {\n            dispatch({ changes: { from: 0, to: doc.length, insert } });\n        }\n    });\n    return true;\n};\n\nexport const codemirrorReindenter: Command = ({ state, dispatch }) => {\n    dispatch({ changes: indentRange(state, 0, state.doc.length) });\n    return true;\n};\n\nexport function useReindent(view: EditorView, fileType: AssetFileType | \"py\") {\n    // TODO support lazy loading skulpt\n    // const reindenter = fileType === \"py\" ? pythonReindenter : codemirrorReindenter;\n    const reindenter = codemirrorReindenter;\n    const run: Command = useEvent(reindenter);\n    useExtension(view, () => Prec.high(keymap.of([{ key: \"Mod-i\", run }])), []);\n}\n\nexport function useAsyncExtension(view: EditorView, extensionCreator: () => Promise<Extension>, deps: any[]) {\n    const compartment = useConstant(() => new Compartment());\n\n    useEffectAsync(\n        async function* () {\n            const extension = await extensionCreator();\n            yield;\n            if (!compartment.get(view.state)) {\n                view.dispatch({ effects: StateEffect.appendConfig.of(compartment.of(extension)) });\n            } else {\n                view.dispatch({ effects: compartment.reconfigure(extension) });\n            }\n        },\n        [view, compartment, ...deps]\n    );\n}\n\nexport function useViewSelector<T>(view: EditorView, snapshot: () => T) {\n    const subscribe = useCallback(\n        (cb: () => void) => {\n            const compartment = new Compartment();\n            view.dispatch({ effects: StateEffect.appendConfig.of(compartment.of(EditorView.updateListener.of(cb))) });\n            return () => {\n                view.dispatch({ effects: compartment.reconfigure([]) });\n            };\n        },\n        [view]\n    );\n    return useSyncExternalStore(subscribe, snapshot);\n}\n\nexport const ExternalUpdate = Annotation.define<true>();\n\nexport function useDependOnEditorSequenceNumber(view: EditorView, path: string, getDoc: () => string) {\n    const sequenceNum = useEditSequenceNumber(path);\n\n    const onSequenceNumChanged = useEvent((sequenceNum: number) => {\n        // fast common case\n        const [localSequenceNum, updating] = view.state.field(SequenceNumberState);\n        if (updating) return;\n        if (sequenceNum === localSequenceNum) return;\n        // otherwise check if our doc has changed\n        // a sequence number might change if something in the item changed\n        // but we only care about the code\n        const { doc } = view.state;\n        const currentItemDoc = getDoc();\n        if (currentItemDoc === doc.toString()) return;\n\n        view.dispatch({\n            changes: { from: 0, to: doc.length, insert: currentItemDoc },\n            annotations: ExternalUpdate.of(true),\n        });\n    });\n\n    useLayoutEffect(() => {\n        onSequenceNumChanged(sequenceNum);\n    }, [sequenceNum]);\n}\n\n/** Our code might be updated by an external source - e.g. import preludes */\nexport function useDependOnEditorSequenceNumberCode(\n    view: EditorView,\n    codeItem: CodeItemYaml,\n    codePath: CodePath,\n    getDoc: (codeItem: CodeItemYaml) => string = (codeItem) => (codeItem as ModuleItemYaml).code\n) {\n    const path = useMemo(() => JSON.stringify([\"CODE\", codePath]), [codePath]);\n    return useDependOnEditorSequenceNumber(view, path, () => getDoc(codeItem));\n}\n\n/** Used for rendering react components in a Panel */\nexport function usePanelPortal(outerContainer: HTMLElement) {\n    const portalDiv = useConstant(() => document.createElement(\"div\"));\n    useLayoutEffect(() => {\n        outerContainer.replaceChildren(portalDiv);\n        return () => outerContainer.replaceChildren();\n    }, [outerContainer, portalDiv]);\n    return portalDiv;\n}\n\n/** @todo can we make module immutable? */\nexport function useUpdateCodeItem(\n    view: EditorView,\n    codePath: CodePath,\n    codeItem: CodeItemYaml,\n    conflicts: Conflicts | undefined,\n    saveCode: boolean,\n    saveRest: boolean\n) {\n    const updater = useEvent((code: string) => ({ ...codeItem, code }));\n    return useUpdateCodeItemWithUpdater(view, codePath, updater, conflicts, saveCode, saveRest);\n}\n\nexport function useUpdateCodeItemWithUpdater(\n    view: EditorView,\n    codePath: CodePath,\n    updater: (doc: string) => CustomHtmlFormYaml | CodeItemYaml,\n    conflicts: Conflicts | undefined,\n    saveCode: boolean,\n    saveRest: boolean\n) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    /** when conflicts is provided this signals that the conflicts should be updated */\n    return useEvent((description?: string, conflicts_?: Conflicts) => {\n        description ??= \"saving on idle\";\n        if (conflicts_ === undefined) {\n            conflicts_ = conflicts;\n            const manager = view.state.field(conflictManagerState, false);\n            // A resolved file retains its editor history, but ordinary edits must\n            // not recreate its conflict entry. Undo supplies reopened text chunks.\n            if (manager?.item && (manager.text_chunks || conflicts)) {\n                conflicts_ = { ...conflicts, item: manager.item };\n                if (manager.text_chunks) conflicts_.text_chunks = manager.text_chunks;\n                else delete conflicts_.text_chunks;\n            }\n        }\n        return dispatch(\n            updateCodeItem(codePath, updater(view.state.doc.toString()), conflicts_, description, saveCode, saveRest)\n        );\n    });\n}\n\nexport function isExternalUpdate(update: ViewUpdate) {\n    return update.transactions.some((tr) => tr.annotation(ExternalUpdate));\n}\n\nexport const SeqNumberEffect = StateEffect.define<number>();\nexport const UpdatingCodeItemEffect = StateEffect.define<true>();\nexport interface SaveCodeItemEffectValue {\n    description?: string;\n    afterSave?: () => void | Promise<void>;\n}\nexport const SaveCodeItemEffect = StateEffect.define<SaveCodeItemEffectValue>();\n\nexport const SequenceNumberState = StateField.define<[seqNum: number, updating: boolean]>({\n    create() {\n        return [0, false];\n    },\n    update(value, tr) {\n        for (const effect of tr.effects) {\n            if (effect.is(SeqNumberEffect)) {\n                value = [effect.value, false];\n                break;\n            } else if (effect.is(UpdatingCodeItemEffect)) {\n                value = [value[0], true];\n                break;\n            }\n        }\n        return value;\n    },\n});\n\nexport function useUpdateCodeItemLazy(\n    view: EditorView,\n    codeItemUpdater: (description?: string) => number | Promise<number>,\n    selected: boolean\n) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const timeoutRef = useRef<number | undefined>(undefined);\n    const unsavedRef = useRef<(() => void) | null>(null);\n    const unsavedCb = useRef<(() => void) | null>(null);\n\n    const onSaveCode = useEvent(async (description?: string) => {\n        clearTimeout(timeoutRef.current);\n        if (!unsavedRef.current) return;\n        unsavedCb.current?.();\n        unsavedRef.current?.();\n        unsavedRef.current = null;\n        unsavedCb.current = null;\n\n        view.dispatch({ effects: UpdatingCodeItemEffect.of(true) });\n        const seqNum = await codeItemUpdater(description);\n        view.dispatch({ effects: SeqNumberEffect.of(seqNum) });\n    });\n\n    useExtension(view, () => SequenceNumberState.extension, []);\n    useUpdateListener(\n        view,\n        async (update) => {\n            if (update.docChanged && !isExternalUpdate(update)) {\n                unsavedRef.current ??= dispatch(markUnsaved());\n                let saveEffect: SaveCodeItemEffectValue | undefined;\n                for (const transaction of update.transactions) {\n                    saveEffect = transaction.effects.find((effect) => effect.is(SaveCodeItemEffect))?.value;\n                    if (saveEffect) break;\n                }\n                if (saveEffect) {\n                    const { description, afterSave } = saveEffect;\n                    await onSaveCode(description);\n                    await afterSave?.();\n                } else {\n                    unsavedCb.current ??= notifyUnsavedCallback(onSaveCode);\n                    clearTimeout(timeoutRef.current);\n                    timeoutRef.current = setTimeout(onSaveCode, 300);\n                }\n            }\n        },\n        []\n    );\n    useEffectWhen(selected, () => () => {\n        // force save on cleanup from selected\n        onSaveCode();\n    });\n}\n\nexport function useSaveEditorHistory(\n    view: EditorView,\n    codePath: EditorPath,\n    hashItem?: View,\n    type: keyof EditHistory = \"code\"\n) {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    // Save the departing view under its own path before switching documents or unmounting.\n    // hashItem also changes when FormEditor switches between views of the same file.\n    useLayoutEffect(\n        () => () => {\n            const { doc, selection, folding } = view.state.toJSON({ folding: foldState });\n            const history = view.state.field(historyField);\n            const saved = { hash: strHashCode(doc), history, selection, folding };\n            const savedBoundaries = type === \"code\" ? view.state.field(renameBoundaries, false) : undefined;\n            dispatch(setCodeItemHistory(codePath, { [type]: { ...saved, renameBoundaries: savedBoundaries } }));\n        },\n        [view, codePath, hashItem, type]\n    );\n}\n\nexport function useSaveExtraFileEditorHistory(view: EditorView, codePath: ExtraFilePath) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const cacheKey = useSelector((state: State) => getCacheKey([\"CODE\", codePath], state));\n\n    useLayoutEffect(() => {\n        const saveHistory = () => {\n            dispatch((dispatch, getState) => {\n                const state = getState();\n                const filePath = codePath.slice(\"extra_files/\".length);\n\n                // Avoid saving history into another app or restoring history\n                // for an extra file that has been deleted or renamed.\n                if (\n                    getCacheKey([\"CODE\", codePath], state) !== cacheKey ||\n                    getExtraFileContent(state, filePath) === undefined\n                ) {\n                    return;\n                }\n\n                const { doc, selection, folding } = view.state.toJSON({\n                    folding: foldState,\n                });\n\n                dispatch(\n                    setCodeItemHistory(codePath, {\n                        code: {\n                            hash: strHashCode(doc),\n                            history: view.state.field(historyField),\n                            selection,\n                            folding,\n                        },\n                    })\n                );\n            });\n        };\n\n        const onBeforeRename = (affectedCacheKeys: readonly string[]) => {\n            if (affectedCacheKeys.includes(cacheKey)) {\n                saveHistory();\n            }\n        };\n\n        dispatch(onEvent(EVENTS.EXTRA_FILES_BEFORE_RENAME, onBeforeRename));\n\n        return () => {\n            dispatch(offEvent(EVENTS.EXTRA_FILES_BEFORE_RENAME, onBeforeRename));\n            saveHistory();\n        };\n    }, [dispatch, view, codePath, cacheKey]);\n}\n\nexport function useFocusCodeOnSelection(view: EditorView, selected: boolean) {\n    useLayoutEffect(() => {\n        if (selected) {\n            view.focus();\n        }\n    }, [view, selected]);\n}\n\nexport function useFocusCodeOnNavigation(view: EditorView, autoFocus: boolean) {\n    const preserveFocus = usePreserveNavigationFocus();\n    const refocusView = useNavTargetSelector((target) =>\n        target?.type === \"CODE\" || target?.type === \"EXTRA_FILE\" ? target.refocusView : undefined\n    );\n    // Activation must focus even when the preview already selected this match.\n    useLayoutEffect(() => {\n        if (autoFocus && !preserveFocus && !view.hasFocus) view.focus();\n    }, [view, autoFocus, preserveFocus, refocusView]);\n}\n\nexport function useFocusCodeOnViewChange(\n    view: EditorView,\n    selected: boolean,\n    viewFocus: keyof View | undefined,\n    editorType: keyof View\n) {\n    const preserveFocus = usePreserveNavigationFocus();\n    useLayoutEffectWhen(selected, () => {\n        if (!preserveFocus && viewFocus === editorType) {\n            view.focus();\n        }\n    }, [viewFocus, editorType, view, preserveFocus]);\n}\n\nexport function useUpdateNavigationOnPointerSelection(\n    editorView: EditorView,\n    codePath: EditorPath,\n    navTarget: (CodeNavTarget | ExtraFileNavTarget) & FullNavTarget,\n    view?: FullView,\n    type: \"code\" | \"html\" | \"htmlProperty\" = \"code\"\n) {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const updateView = useEvent((update: ViewUpdate) => {\n        const startAnchor = update.startState.selection.main.anchor;\n        const anchorPos = update.state.selection.main.anchor;\n        if (update.transactions.some((tr) => tr.annotation(NavigationAnnotation))) {\n            // result of a jump to code don't i.e. that Hash already matches\n            return;\n        } else if (startAnchor === anchorPos && !update.selectionSet) {\n            // nothing has changed in the main cursor so ignore this update\n            // BUT we do want to make sure the focus is set to the correct editor in the URL\n            return;\n        }\n        const line = update.state.doc.lineAt(anchorPos);\n        const target = { ...navTarget };\n        const viewVal = [String(line.number), String(anchorPos - line.from)] as const;\n        if (target.type === \"CODE\") delete target.essentialView;\n        target.view = { ...view, [type]: viewVal, focus: type };\n        if (update.transactions.some((tr) => tr.annotation(Transaction.userEvent) === \"select.pointer\")) {\n            dispatch(cacheView(codePath, target.view));\n            dispatch(navigate(target));\n        } else {\n            insertHistoryStateBeforeNextNavigation(target);\n        }\n    });\n\n    useUpdateListener(editorView, updateView, []);\n}\n\nexport function useUpdateSelectionOnHashChange(\n    view: EditorView,\n    hashItem?: FullView,\n    type: keyof View = \"code\",\n    { refocusView }: { refocusView?: number } = {}\n) {\n    const preserveFocus = usePreserveNavigationFocus();\n    const jumpToCode = useJumpToCode(view);\n    const lastProcessHash = useRef<null | [string, string]>(null);\n    const hashObject = hashItem?.[type];\n    const jumpToHash = useEffectEvent((focus = true) => {\n        if (typeof hashObject === \"boolean\" || hashObject == null || isEmpty(hashObject)) {\n            return;\n        }\n        const [line, col = \"0\"] = hashObject;\n        const lineStr = String(line);\n        const colStr = String(col);\n        lastProcessHash.current = [lineStr, colStr];\n        jumpToCode({ line: Number(lineStr), col: Number(colStr) }, focus);\n    });\n\n    // on the first render we might not be the active editor so we don't want to focus\n    const isFirstRenderRef = useRef(true);\n\n    useLayoutEffect(() => {\n        // Explicit conflict navigation must jump again even when its URL line is unchanged.\n        if (!isEqual(hashObject, lastProcessHash.current) || refocusView !== undefined) {\n            jumpToHash(!isFirstRenderRef.current && !preserveFocus);\n        }\n        return () => {\n            isFirstRenderRef.current = false;\n        };\n    }, [hashObject, refocusView]);\n}\n\ntype JumpLoc = { line: number; col: number };\n\nexport const NavigationAnnotation = Annotation.define<true>();\n\nexport function useJumpToCode(view: EditorView) {\n    return useEvent((jumpLoc: JumpLoc, focus = true) => {\n        if (typeof jumpLoc !== \"object\") {\n            return;\n        }\n        const anchorPos = view.state.selection.main.anchor;\n        const { line, col } = jumpLoc;\n        let newAnchorPos = anchorPos;\n        try {\n            newAnchorPos = view.state.doc.line(line).from + col;\n        } catch (e) {\n            console.warn(e);\n        }\n        if (anchorPos === newAnchorPos) {\n            return;\n        }\n        try {\n            view.dispatch({\n                selection: { anchor: newAnchorPos },\n                effects: EditorView.scrollIntoView(newAnchorPos, { y: \"center\" }),\n                annotations: NavigationAnnotation.of(true),\n            });\n            if (focus) {\n                view.focus();\n            }\n        } catch (e: any) {\n            // we are jumping to an invalid location\n            console.warn(e.message);\n        }\n    });\n}\n\nexport function useUpdateGlobalHistory(view: EditorView, selected: boolean) {\n    const [globalHistoryChange, onFocus] = useSetGlobalHistory(\n        {\n            canUndo: () => !!undoDepth(view.state),\n            canRedo: () => !!redoDepth(view.state),\n            undo: () => renameHistoryCommand(view, \"before\"),\n            redo: () => renameHistoryCommand(view, \"after\"),\n        },\n        selected,\n        [view]\n    );\n\n    useExtension(view, () => EditorView.domEventHandlers({ focus: onFocus }), []);\n\n    useUpdateListener(\n        view,\n        (update) => {\n            if (update.docChanged || update.startState.field(historyField) !== update.state.field(historyField)) {\n                globalHistoryChange();\n            }\n        },\n        []\n    );\n}\n\n// Minimum code area width (in rem) and minimap width (in rem)\nconst EDITOR_MIN_WIDTH_REM = 52; // e.g., enough for ~80 code columns\nconst MINIMAP_WIDTH_REM = 8; // width of minimap area\n\nconst create = (v: EditorView) => {\n    const dom = document.createElement(\"div\");\n    // without this the minimap seems to suddenly change width\n    dom.style.width = \"120px\";\n    return { dom };\n};\n\nexport function useMiniMap(view: EditorView, enabled = true) {\n    const includeMiniMap = useSelector(getUserMinimapPref);\n    const [isEditorWideEnoughForMiniMap, setIsEditorWideEnoughForMiniMap] = useState(false);\n    const remToPixels = useRemToPixels();\n    const ref = useRef(view.dom);\n\n    useResizeObserver(ref, () => {\n        const thresholdPx = remToPixels * (EDITOR_MIN_WIDTH_REM + MINIMAP_WIDTH_REM);\n        const editorWidth = view.dom.offsetWidth;\n        const wideEnough = editorWidth > thresholdPx;\n        if (wideEnough !== isEditorWideEnoughForMiniMap) {\n            // Remove the minimap before painting the resized editor, rather than a frame later.\n            flushSync(() => setIsEditorWideEnoughForMiniMap(wideEnough));\n        }\n    });\n\n    useEffect(() => {\n        ref.current = view.dom;\n    }, [view.dom]);\n\n    const shouldUseMiniMap = enabled && includeMiniMap && isEditorWideEnoughForMiniMap;\n\n    useExtension(\n        view,\n        () =>\n            shouldUseMiniMap\n                ? showMinimap.compute([\"doc\", conflictMinimapGutters], (state) => ({\n                      create,\n                      displayText: \"blocks\",\n                      gutters: state.facet(conflictMinimapGutters),\n                  }))\n                : [],\n        [shouldUseMiniMap]\n    );\n}\n\nexport function useFormatOnSave(view: EditorView, run: Command, enabled = true) {\n    const formatOnSave = useSelector((state: State) => getUserUiPrefs(state)?.formatOnSave ?? false);\n    useExtension(view, () => (enabled && formatOnSave ? Prec.high(keymap.of([{ key: \"Mod-s\", run }])) : []), [\n        enabled,\n        formatOnSave,\n    ]);\n}\n\n/** Owns extra-file saving and external document updates, including in read-only apps. */\nexport function useExtraFileDocument(editorView: EditorView, filePath: string, content: string | undefined) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const editable = useSelector(getAppIsEditable) && content !== undefined;\n    const conflicts = useSelector((state: State) => getExtraFileConflicts(state, filePath));\n    useExtension(\n        editorView,\n        () => [\n            EditorState.readOnly.of(!editable),\n            EditorView.editable.of(!!editable),\n            // Formatting and global undo can dispatch changes even in a read-only view.\n            EditorState.transactionFilter.of((tr) =>\n                !editable &&\n                !tr.annotation(ExternalUpdate) &&\n                (tr.docChanged ||\n                    tr.effects.some((effect) => effect.is(ResolveConflictEffect) || effect.is(RestoreConflictsEffect)))\n                    ? []\n                    : tr\n            ),\n        ],\n        [editable]\n    );\n    const onUpdate = useEvent((update: ViewUpdate) => {\n        if (update.docChanged && !isExternalUpdate(update)) {\n            // When conflict ranges move, the marker hook saves both content and metadata.\n            if (\n                update.startState.field(conflictManagerState, false)?.text_chunks !==\n                update.state.field(conflictManagerState, false)?.text_chunks\n            )\n                return;\n            // Store every edit immediately; shared autosave delays server writes.\n            dispatch(saveExtraFile(filePath, update.state.doc.toString()));\n        }\n    });\n    useUpdateListener(editorView, onUpdate, []);\n    useLayoutEffect(() => {\n        const { doc } = editorView.state;\n        if (content === undefined || content === doc.toString()) return;\n        editorView.dispatch({\n            changes: { from: 0, to: doc.length, insert: content },\n            annotations: [ExternalUpdate.of(true), Transaction.addToHistory.of(false)],\n        });\n    }, [editorView, content]);\n    // Install incoming content before the marker hook initialises its corresponding line ranges.\n    const conflictActions = useConflictMarkers(\n        editorView,\n        `extra_files/${filePath}`,\n        conflicts,\n        useEvent(async (_description, updatedConflicts) => {\n            const justResolvedLastConflict = !!conflicts?.text_chunks?.length && !updatedConflicts.text_chunks?.length;\n            const sequenceNumber =\n                dispatch(saveExtraFile(filePath, editorView.state.doc.toString(), { conflicts: updatedConflicts })) ??\n                0;\n            if (justResolvedLastConflict) {\n                await dispatch(confirmItemConflictsResolved([\"extra_files\", filePath]));\n            }\n            return sequenceNumber;\n        })\n    );\n    return conflictActions;\n}\n","/** Some code adapted from: https://github.com/replit/codemirror-indentation-markers */\nimport { useSelector } from \"react-redux\";\nimport { Extension, RangeSetBuilder } from \"@codemirror/state\";\nimport { Decoration, DecorationSet, EditorView, ViewPlugin, ViewUpdate, WidgetType } from \"@codemirror/view\";\nimport { getUserTabSize } from \"../../controllers/user\";\nimport { useExtension } from \"./hooks\";\n\nexport function indentationGuides(isServer = false): Extension {\n    const extension = [\n        ViewPlugin.fromClass(IndentationGuides, { decorations: (v) => v.decorations }),\n        getTheme(isServer),\n    ];\n    return extension;\n}\n\nexport function useIndentationGuides(view: EditorView, isServer = false) {\n    const tabSize = useSelector(getUserTabSize);\n    useExtension(view, () => indentationGuides(isServer), [tabSize]);\n}\n\nfunction createGradient(\n    markerCssProperty: string,\n    thickness: number,\n    indentWidth: number,\n    startOffset: number,\n    columns: number\n) {\n    const gradient = `repeating-linear-gradient(to right, var(${markerCssProperty}) 0 ${thickness}px, transparent ${thickness}px ${indentWidth}ch)`;\n    // Subtract one pixel from the background width to get rid of artifacts of pixel rounding\n    return `${gradient} ${startOffset * indentWidth}.8ch/calc(${indentWidth * columns}ch - 1px) no-repeat`;\n}\n\nfunction makeBackgroundCSS(\n    entry: { level: number; active?: number },\n    indentWidth: number,\n    hideFirstIndent: boolean,\n    thickness: number\n) {\n    const { level, active } = entry;\n    if (hideFirstIndent && level === 0) {\n        return [];\n    }\n    const startAt = hideFirstIndent ? 1 : 0;\n    const backgrounds = [];\n\n    if (active !== undefined) {\n        const markersBeforeActive = active - startAt - 1;\n        if (markersBeforeActive > 0) {\n            backgrounds.push(\n                createGradient(\"--indent-marker-bg-color\", thickness, indentWidth, startAt, markersBeforeActive)\n            );\n        }\n        backgrounds.push(\n            createGradient(\"--indent-marker-active-bg-color\", thickness + 0.2, indentWidth, active - 1, 1)\n        );\n        if (active !== level) {\n            backgrounds.push(\n                createGradient(\"--indent-marker-bg-color\", thickness, indentWidth, active, level - active)\n            );\n        }\n    } else {\n        backgrounds.push(createGradient(\"--indent-marker-bg-color\", thickness, indentWidth, startAt, level - startAt));\n    }\n\n    return backgrounds.join(\",\");\n}\n\nfunction getWhiteSpaceAndColumn(text: string, tabSize: number) {\n    let i = -1;\n    let whiteSpace = 0;\n    let column = 0;\n    while (++i < text.length) {\n        const chr = text[i];\n        if (chr === \"\\t\") {\n            whiteSpace += 1;\n            column += tabSize - (column % tabSize);\n        } else if (chr === \" \") {\n            whiteSpace += 1;\n            column += 1;\n        } else {\n            break;\n        }\n    }\n    return [whiteSpace, column];\n}\n\nfunction makeIndentationDecorators(view: EditorView) {\n    const tabSize = Number(view.state.tabSize);\n    const doc = view.state.doc;\n    const cursorPos = view.state.doc.lineAt(view.state.selection.main.head).number;\n\n    const activeLines: { from: number; indent: number; active?: number }[] = [];\n    const spaceOnlyLines = [];\n    let cursorIndex = -1;\n    let idx = -1;\n\n    for (const { from: visibleFrom, to: visibleTo } of view.visibleRanges) {\n        let to = visibleFrom - 1;\n        let pos, from, length, text, number;\n        while ((pos = to + 1) <= visibleTo) {\n            idx++;\n            ({ from, to, length, text, number } = doc.lineAt(pos));\n            if (number === cursorPos) {\n                cursorIndex = idx;\n            }\n            const [whiteSpace, column] = getWhiteSpaceAndColumn(text, tabSize);\n            const isAllSpaces = whiteSpace === length;\n            if (isAllSpaces) {\n                // we don't know our indentation level\n                spaceOnlyLines.push(from);\n                continue;\n            }\n            // we guide 1 tab less than where the code starts at\n            let indent: number;\n            const offset = column % tabSize;\n            if (column === 0) {\n                indent = 0;\n            } else if (offset === 0) {\n                indent = column - tabSize;\n            } else {\n                indent = column - offset;\n            }\n            for (const from of spaceOnlyLines) {\n                activeLines.push({ from, indent, active: undefined });\n            }\n            spaceOnlyLines.length = 0;\n            activeLines.push({ from, indent, active: undefined });\n        }\n    }\n\n    if (activeLines[cursorIndex]) {\n        let { indent } = activeLines[cursorIndex];\n        // Are we a behaving like the first line of a block statement?\n        if (activeLines[cursorIndex + 1]?.indent === indent + tabSize) {\n            ({ indent } = activeLines[++cursorIndex]);\n        }\n        if (indent) {\n            let idx = cursorIndex;\n            activeLines[idx].active = indent;\n            while (activeLines[--idx]?.indent >= indent) {\n                activeLines[idx].active = indent;\n            }\n            idx = cursorIndex;\n            while (activeLines[++idx]?.indent >= indent) {\n                activeLines[idx].active = indent;\n            }\n        }\n    }\n\n    const builder = new RangeSetBuilder<Decoration>();\n    for (const { from, indent, active } of activeLines) {\n        if (!indent) continue;\n        const level = Math.floor((indent + tabSize) / tabSize);\n        const activeLevel = active ? Math.floor((active + tabSize) / tabSize) : undefined;\n        const backgrounds = makeBackgroundCSS({ active: activeLevel, level }, tabSize, true, 1);\n\n        builder.add(\n            from,\n            from,\n            Decoration.line({\n                class: \"cm-indent-markers\",\n                attributes: {\n                    style: `--indent-markers: ${backgrounds}`,\n                },\n            })\n        );\n    }\n    return builder.finish();\n}\n\nclass IndentationGuides {\n    decorations: DecorationSet;\n    constructor(view: EditorView) {\n        this.decorations = makeIndentationDecorators(view);\n    }\n    update(update: ViewUpdate) {\n        if (update.docChanged || update.viewportChanged || update.selectionSet) {\n            this.decorations = makeIndentationDecorators(update.view);\n        }\n    }\n}\n\nconst clientBg = \"193 199 249\";\nconst serverBg = \"239 198 155\";\n\nconst baseIndentationGuides = EditorView.baseTheme({\n    \"& .anvil-client-module\": {\n        \"--indent-marker-bg-color\": \"rgb(\" + clientBg + \" / 0.4)\",\n        \"--indent-marker-active-bg-color\": \"rgb(\" + clientBg + \" / 0.6)\",\n    },\n    \"& .anvil-server-module\": {\n        \"--indent-marker-bg-color\": \"rgb(\" + serverBg + \" / 0.4)\",\n        \"--indent-marker-active-bg-color\": \"rgb(\" + serverBg + \" / 0.6)\",\n    },\n    \".cm-line\": {\n        position: \"relative\",\n    },\n    \".cm-indent-markers::before\": {\n        content: '\"\"',\n        position: \"absolute\",\n        top: 0,\n        // .cm-line has a padding of 2px\n        // https://github.com/codemirror/view/blob/1c0a0880fc904714339f059658f3ba3a88bb8e6e/src/theme.ts#L85\n        left: `2px`,\n        right: 0,\n        bottom: 0,\n        background: \"var(--indent-markers)\",\n        pointerEvents: \"none\",\n        // otherwise selection doesn't work\n        zIndex: \"-1\",\n    },\n});\n\nconst getTheme = (isServer: boolean) => {\n    return [\n        EditorView.contentAttributes.of({ class: isServer ? \"anvil-server-module\" : \"anvil-client-module\" }),\n        baseIndentationGuides,\n    ];\n};\n","import { ChangeDesc, SelectionRange, StateEffect, StateField } from \"@codemirror/state\";\nimport { Decoration, DecorationSet, EditorView, ViewPlugin, ViewUpdate } from \"@codemirror/view\";\nimport { getRandomString } from \"../../util\";\nimport { useExtension } from \"./hooks\";\n\nexport function useFocusMethod(view: EditorView) {\n    useExtension(view, () => [MethodFocusPlugin, methodFocusTheme, methodFocusField], []);\n}\n\nexport const FocusMethodEffect = StateEffect.define<{ from: number; to: number; targetPos?: number }>();\n\nconst unfocusedLineDeco = Decoration.line({ attributes: { class: \"cm-unfocused-region\" } });\nconst targetDefDeco = Decoration.line({ attributes: { class: \"cm-target-def\" } });\n\n/** Knows the from, to values of the focused method. Adjusts these values if doc/selection chages */\nclass FocusRange {\n    focusFrom: number;\n    focusTo: number;\n    targetPos: number;\n    constructor(\n        { from, to, targetPos }: { from: number; to: number; targetPos?: number },\n        readonly id: string = getRandomString()\n    ) {\n        this.focusFrom = from;\n        this.focusTo = to;\n        this.targetPos = targetPos ?? from;\n    }\n    map(changes: ChangeDesc) {\n        if (changes.touchesRange(this.focusFrom, this.focusTo)) {\n            return null;\n        }\n        const from = changes.mapPos(this.focusFrom, -1);\n        const to = changes.mapPos(this.focusTo, 1);\n        const targetPos = changes.mapPos(this.targetPos, -1);\n        return new FocusRange({ from, to, targetPos }, this.id);\n    }\n    outsideRange(pos: number) {\n        return pos < this.focusFrom || pos > this.focusTo;\n    }\n    mapSelection(ranges: readonly SelectionRange[]) {\n        for (const { from, to } of ranges) {\n            if (this.outsideRange(from) || (from !== to && this.outsideRange(to))) {\n                return null;\n            }\n        }\n        return this;\n    }\n}\n\n/** holds the state for FocusRange */\nconst methodFocusField = StateField.define<FocusRange | null>({\n    create() {\n        return null;\n    },\n    update(value, tr) {\n        for (const effect of tr.effects) {\n            if (effect.is(FocusMethodEffect)) {\n                return new FocusRange(effect.value);\n            }\n        }\n        if (tr.docChanged) {\n            value = value?.map(tr.changes) ?? null;\n        }\n        if (tr.isUserEvent(\"select\")) {\n            value = value?.mapSelection(tr.newSelection.ranges) ?? null;\n        }\n        return value;\n    },\n});\n\n/** Updates the unfocused and targetDef line decorations based on the current FocusRange held by the methodFocusField */\nconst MethodFocusPlugin = ViewPlugin.fromClass(\n    class {\n        decorations: DecorationSet | null = null;\n        focusRange: FocusRange | null = null;\n        constructor(readonly view: EditorView) {}\n        makeTargetDec(focusFieldValue: FocusRange) {\n            const doc = this.view.state.doc;\n            const line = doc.lineAt(focusFieldValue.targetPos);\n            return targetDefDeco.range(line.from);\n        }\n        makeUnfocusedLines(focusFieldValue: FocusRange) {\n            const lineDecos = [];\n            const view = this.view;\n            const doc = view.state.doc;\n            const { focusFrom, focusTo } = focusFieldValue;\n\n            for (const { from: visibleFrom, to: visibleTo } of view.visibleRanges) {\n                let to = visibleFrom - 1;\n                let pos, from;\n                while ((pos = to + 1) <= visibleTo) {\n                    ({ from, to } = doc.lineAt(pos));\n                    if (to <= focusFrom || from >= focusTo) {\n                        lineDecos.push(unfocusedLineDeco.range(from));\n                    }\n                }\n            }\n            return lineDecos;\n        }\n        update(update: ViewUpdate) {\n            const focusFieldValue = update.state.field(methodFocusField, false);\n            if (focusFieldValue == null) {\n                this.decorations = null;\n                this.focusRange = null;\n                return;\n            }\n            const prevRange = this.focusRange;\n            if (prevRange === focusFieldValue && !update.viewportChanged) {\n                return;\n            }\n            this.focusRange = focusFieldValue;\n\n            const unfocusedLines = this.makeUnfocusedLines(focusFieldValue);\n            if (prevRange === null || prevRange.id !== focusFieldValue.id) {\n                const targetDec = this.makeTargetDec(focusFieldValue);\n                this.decorations = Decoration.set([...unfocusedLines, targetDec], true);\n            } else {\n                this.decorations = Decoration.set(unfocusedLines);\n            }\n        }\n    },\n    { decorations: (v) => v.decorations ?? Decoration.none }\n);\n\nconst methodFocusTheme = EditorView.theme({\n    \".cm-unfocused-region\": {\n        opacity: 0.3,\n    },\n    \"@keyframes fade-target\": {\n        from: {\n            backgroundColor: \"rgba(255,255,0,1)\",\n        },\n        to: {\n            backgroundColor: \"rgba(255,255,0,0.2)\",\n        },\n    },\n    \".cm-target-def\": {\n        animationDuration: \"1s\",\n        animationName: \"fade-target\",\n        animationFillMode: \"forwards\",\n    },\n});\n","import { type Token, scan } from \"@anvil-works/skulpt-parser/core\";\n\n/** Editing scans treat interpolated strings as opaque. Their synthetic token has no string contents. */\nexport function* scanPython(source: string, filename: string): Generator<Token> {\n    let literal: Token | undefined;\n    let depth = 0;\n    // Editing scans locate structure without enforcing an app's Python grammar.\n    // Accept legacy string prefixes just as the old Skulpt tokenizer did.\n    for (const token of scan(source, { extraTokens: true, filename, pythonVersion: 2 })) {\n        if (token.type === \"FSTRING_START\" || token.type === \"TSTRING_START\") {\n            literal ??= token;\n            depth++;\n        } else if (token.type === \"FSTRING_END\" || token.type === \"TSTRING_END\") {\n            depth--;\n            if (depth === 0) {\n                yield { ...literal!, type: \"STRING\", string: \"\", end: token.end, endByte: token.endByte };\n                literal = undefined;\n            }\n        } else if (depth === 0) {\n            yield token;\n        }\n    }\n}\n","import type { Token as TokenInfo } from \"@anvil-works/skulpt-parser/core\";\nimport { scanPython } from \"./python_tokens\";\n\n/**\n * Source code adapted from https://pypi.org/project/reindent/#description\n * Originally written by Tim Peters\n *\n * We reindent to 2 or 4 spaces\n * And get rid of trailing whitespace\n */\n\n/** ignores trailing white space */\nconst splitLines = /^(.*?)([ \\t]*)$/gm;\n\nfunction expandTabs(text: string, tabSize: number) {\n    let i = -1;\n    let column = 0;\n    while (++i < text.length) {\n        const chr = text[i];\n        if (chr === \"\\t\") {\n            column += tabSize - (column % tabSize);\n        } else if (chr === \" \") {\n            column += 1;\n        } else {\n            break;\n        }\n    }\n    return \" \".repeat(column) + text.slice(i);\n}\n\n/** takes in a string and retuns a generator that yields each line with the \\n character */\nfunction* readString(text: string, tabSize: number): IterableIterator<string> {\n    for (const match of text.matchAll(splitLines)) {\n        yield expandTabs(match[1], tabSize) + \"\\n\";\n    }\n}\n\nclass Reindenter {\n    find_stmt = 1; // next token begins a fresh statement\n    level = 0;\n    lines: string[] = [\"null\"];\n    stats: [number, number][] = [];\n    after: string[] = [];\n    constructor(\n        readonly source: string,\n        readonly indent: number = 4\n    ) {\n        this.lines.push(...readString(source, indent));\n        this.tokenEater = this.tokenEater.bind(this);\n    }\n\n    run(): string {\n        for (const token of scanPython(this.lines.slice(1).join(\"\"), \"<reindent>\")) this.tokenEater(token);\n        const lines = this.lines;\n        while (lines.length && lines[lines.length - 1] === \"\\n\") {\n            lines.pop();\n        }\n        const stats = this.stats;\n        stats.push([lines.length, 0]);\n\n        const have2want: { [have: number]: number } = {};\n        const after: string[] = (this.after = []);\n        const i = this.stats[0][0];\n        after.push(...(lines.slice(1, i) as string[]));\n        for (let i = 0; i < this.stats.length - 1; i++) {\n            const [thisstmt, thislevel] = stats[i];\n            const nextstmt = stats[i + 1][0];\n            const have = getlspace(lines[thisstmt]);\n            let want = thislevel * this.indent;\n            if (want < 0) {\n                // a comment line\n                if (have) {\n                    want = have2want[have] ?? -1;\n                    if (want < 0) {\n                        for (let j = i + 1; j < stats.length - 1; j++) {\n                            const [jline, jlevel] = stats[j];\n                            if (jlevel >= 0) {\n                                if (have === getlspace(lines[jline])) {\n                                    want = jlevel * this.indent;\n                                }\n                                break;\n                            }\n                        }\n                    }\n                    if (want < 0) {\n                        // maybe it's a hanging comment\n                        for (let j = i - 1; j > -1; j--) {\n                            const [jline, jlevel] = stats[j];\n                            if (jlevel >= 0) {\n                                want = have + (getlspace(after[jline - 1]) - getlspace(lines[jline]));\n                                break;\n                            }\n                        }\n                    }\n                    if (want < 0) {\n                        // no luck\n                        want = have;\n                    }\n                } else {\n                    want = 0;\n                }\n            }\n            have2want[have] = want;\n            const diff = want - have;\n            if (diff === 0 || have === 0) {\n                after.push(...lines.slice(thisstmt, nextstmt));\n            } else {\n                for (const line of lines.slice(thisstmt, nextstmt)) {\n                    if (diff > 0) {\n                        if (line === \"\\n\") {\n                            after.push(line);\n                        } else {\n                            after.push(\" \".repeat(diff) + line);\n                        }\n                    } else {\n                        const remove = Math.min(getlspace(line), -diff);\n                        after.push(line.slice(remove));\n                    }\n                }\n            }\n        }\n        return this.after.join(\"\");\n    }\n\n    tokenEater({ type, start, line }: TokenInfo) {\n        if (type === \"NEWLINE\") {\n            this.find_stmt = 1;\n        } else if (type === \"INDENT\") {\n            this.find_stmt = 1;\n            this.level += 1;\n        } else if (type === \"DEDENT\") {\n            this.find_stmt = 1;\n            this.level -= 1;\n        } else if (type === \"COMMENT\") {\n            if (this.find_stmt) {\n                this.stats.push([start[0], -1]);\n            }\n        } else if (type === \"NL\") {\n            // pass\n        } else if (this.find_stmt) {\n            this.find_stmt = 0;\n            if (line) {\n                this.stats.push([start[0], this.level]);\n            }\n        }\n    }\n}\n\nfunction getlspace(line: string) {\n    let i = 0;\n    const n = line.length;\n    while (i < n && line[i] === \" \") {\n        i += 1;\n    }\n    return i;\n}\n\nexport async function reindent(source: string, tabSize: string | number): Promise<string> {\n    return new Reindenter(source, Number(tabSize || 2)).run();\n}\n","import { useLayoutEffect, useRef } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { MapMode, RangeSet, RangeValue, StateEffect, StateField } from \"@codemirror/state\";\nimport { EditorView, GutterMarker, gutter } from \"@codemirror/view\";\nimport { icon } from \"@fortawesome/fontawesome-svg-core\";\nimport { faCircleQuestion, faPlay } from \"@fortawesome/pro-light-svg-icons\";\nimport { openOrFocusBottomTab } from \"@/controllers/bottom-tabs\";\nimport type { OverlaidTestResult } from \"@/controllers/server-test-runs\";\nimport {\n    getAreServerTestsBusy,\n    getLatestServerTestDiscovery,\n    getServerTestDisplayResults,\n    runServerTests,\n    setSelectedServerTestId,\n} from \"@/controllers/server-tests\";\nimport { getTestingEnabled } from \"@/controllers/services\";\nimport { TestStatusDisplay, getTestStatusDisplay } from \"@/testing/test-status-display\";\nimport { AnvilDispatch } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { useExtension, useUpdateListener } from \"./extensions\";\nimport { findServerTestPositions } from \"./server-test-locations\";\n\nfunction getLineTestDisplay(tests: OverlaidTestResult[]): TestStatusDisplay {\n    const displays = tests.map((test) => getTestStatusDisplay(test.result));\n\n    // Active cases take precedence over completed results.\n    const running = tests.find((test) => test.result?.status === \"running\");\n    if (running) {\n        return getTestStatusDisplay(running.result);\n    }\n\n    const pending = tests.find((test) => test.result?.status === \"pending\");\n    if (pending) {\n        return getTestStatusDisplay(pending.result);\n    }\n\n    for (const outcome of [\"error\", \"failed\"] as const) {\n        const unsuccessful = tests.find(\n            (test) => test.result?.status === \"finished\" && test.result.outcome === outcome\n        );\n\n        if (unsuccessful) {\n            return getTestStatusDisplay(unsuccessful.result);\n        }\n    }\n\n    const first = displays[0];\n\n    if (first && displays.every((display) => display.label === first.label)) {\n        return first;\n    }\n\n    return {\n        icon: faCircleQuestion,\n        label: \"Mixed results\",\n        className: \"text-secondary\",\n    };\n}\n\n// One source location can represent several parametrized test cases.\nclass TestAnchor extends RangeValue {\n    constructor(readonly testIds: readonly string[]) {\n        super();\n\n        this.point = true;\n        this.startSide = 1;\n        this.endSide = 1;\n        this.mapMode = MapMode.TrackDel;\n    }\n}\n\nconst replaceTestAnchors = StateEffect.define<RangeSet<TestAnchor>>();\n\nconst testAnchorsField = StateField.define<RangeSet<TestAnchor>>({\n    create() {\n        return RangeSet.empty;\n    },\n\n    update(anchors, transaction) {\n        let nextAnchors = transaction.docChanged ? anchors.map(transaction.changes) : anchors;\n\n        for (const effect of transaction.effects) {\n            if (effect.is(replaceTestAnchors)) {\n                nextAnchors = effect.value;\n            }\n        }\n\n        return nextAnchors;\n    },\n});\n\nclass ServerTestMarker extends GutterMarker {\n    constructor(\n        private readonly tests: OverlaidTestResult[],\n        private readonly disabled: boolean\n    ) {\n        super();\n    }\n\n    toDOM() {\n        const element = document.createElement(\"span\");\n\n        const display = getLineTestDisplay(this.tests);\n        const showPlay = this.tests.every((test) => !test.result || test.result.status === \"not_run\");\n\n        element.className = [\n            \"inline-flex items-center justify-center\",\n            this.disabled ? \"cursor-not-allowed\" : \"cursor-pointer\",\n            display.className,\n        ].join(\" \");\n\n        const actionLabel = this.disabled\n            ? \"Server tests are busy\"\n            : this.tests.length === 1\n              ? `Run ${this.tests[0].name}`\n              : `Run ${this.tests.length} tests on this line`;\n\n        const statusDetails = this.tests\n            .map((test) => {\n                const status = getTestStatusDisplay(test.result);\n                return `${test.name}: ${status.label}`;\n            })\n            .join(\"\\n\");\n\n        element.title = `${actionLabel}\\n${statusDetails}`;\n\n        const statusIcon = document.createElement(\"span\");\n        statusIcon.className = \"cm-server-test-status-icon\";\n        statusIcon.appendChild(\n            icon(showPlay ? faPlay : display.icon, {\n                classes: display.spin && !showPlay ? [\"fa-spin\"] : [],\n            }).node[0]\n        );\n        element.appendChild(statusIcon);\n\n        if (!this.disabled) {\n            element.classList.add(\"cm-server-test-runnable\");\n\n            const playIcon = document.createElement(\"span\");\n            playIcon.className = \"cm-server-test-play-icon\";\n            playIcon.appendChild(icon(faPlay).node[0]);\n            element.appendChild(playIcon);\n        }\n        return element;\n    }\n}\n\nexport function useServerTestGutter(view: EditorView, filePath: string) {\n    const testingEnabled = useSelector(getTestingEnabled);\n    const results = useSelector(getServerTestDisplayResults);\n\n    const dispatch = useDispatch<AnvilDispatch>();\n    const testsAreBusy = useSelector(getAreServerTestsBusy);\n\n    const onRunTests = useEvent((tests: OverlaidTestResult[]) => {\n        if (!testingEnabled || testsAreBusy || tests.length === 0) {\n            return;\n        }\n\n        dispatch(setSelectedServerTestId(null));\n        dispatch(openOrFocusBottomTab({ type: \"serverTests\" }));\n\n        dispatch(\n            runServerTests({\n                selection: {\n                    test_targets: tests.map((test) => test.test_id),\n                },\n            })\n        );\n    });\n    const discoveredTests = useSelector(getLatestServerTestDiscovery);\n    const scheduleAnchorRefresh = useRef<(() => void) | null>(null);\n\n    const enabled = testingEnabled && filePath.startsWith(\"tests/server_tests/\") && filePath.endsWith(\".py\");\n\n    useExtension(view, () => testAnchorsField, []);\n    useLayoutEffect(() => {\n        if (!enabled || !discoveredTests?.length) {\n            view.dispatch({\n                effects: replaceTestAnchors.of(RangeSet.empty),\n            });\n            return;\n        }\n\n        const discoveredPath = filePath.slice(\"tests/\".length);\n        let pendingFrame: number | undefined;\n        let pendingRefresh: number | undefined;\n\n        const rebuildAnchors = () => {\n            pendingFrame = undefined;\n\n            const positions = findServerTestPositions(view.state, discoveredPath, discoveredTests);\n\n            if (positions === null) {\n                // Parsing is incomplete. Keep existing mapped anchors\n                // and try again on the next frame.\n                pendingFrame = window.requestAnimationFrame(rebuildAnchors);\n                return;\n            }\n\n            const testIdsByPosition = new Map<number, string[]>();\n\n            for (const [testId, position] of positions) {\n                const ids = testIdsByPosition.get(position) ?? [];\n                ids.push(testId);\n                testIdsByPosition.set(position, ids);\n            }\n\n            const anchors = [...testIdsByPosition].map(([position, testIds]) =>\n                new TestAnchor(testIds).range(position)\n            );\n\n            view.dispatch({\n                effects: replaceTestAnchors.of(RangeSet.of(anchors, true)),\n            });\n        };\n\n        const scheduleRefresh = () => {\n            window.clearTimeout(pendingRefresh);\n\n            // An earlier parsing retry must also wait until typing pauses.\n            if (pendingFrame !== undefined) {\n                window.cancelAnimationFrame(pendingFrame);\n                pendingFrame = undefined;\n            }\n\n            pendingRefresh = window.setTimeout(() => {\n                pendingRefresh = undefined;\n                rebuildAnchors();\n            }, 200);\n        };\n\n        scheduleAnchorRefresh.current = scheduleRefresh;\n\n        rebuildAnchors();\n\n        return () => {\n            scheduleAnchorRefresh.current = null;\n\n            window.clearTimeout(pendingRefresh);\n\n            if (pendingFrame !== undefined) {\n                window.cancelAnimationFrame(pendingFrame);\n            }\n        };\n    }, [view, filePath, enabled, discoveredTests]);\n\n    useUpdateListener(\n        view,\n        (update) => {\n            if (update.docChanged) {\n                scheduleAnchorRefresh.current?.();\n            }\n        },\n        []\n    );\n\n    useExtension(view, () => {\n        if (!enabled) {\n            return [];\n        }\n\n        const testsAtLine = (editor: EditorView, lineStart: number): OverlaidTestResult[] => {\n            const line = editor.state.doc.lineAt(lineStart);\n            const tests: OverlaidTestResult[] = [];\n\n            editor.state.field(testAnchorsField).between(line.from, line.to, (from, _to, anchor) => {\n                if (editor.state.doc.lineAt(from).number !== line.number) {\n                    return;\n                }\n\n                for (const testId of anchor.testIds) {\n                    const test = results[testId];\n\n                    if (test) {\n                        tests.push(test);\n                    }\n                }\n            });\n\n            return tests;\n        };\n\n        return [\n            gutter({\n                class: \"cm-server-test-gutter\",\n\n                lineMarker(editor, line) {\n                    const tests = testsAtLine(editor, line.from);\n\n                    return tests.length > 0 ? new ServerTestMarker(tests, testsAreBusy) : null;\n                },\n\n                lineMarkerChange: (update) =>\n                    update.docChanged ||\n                    update.startState.field(testAnchorsField) !== update.state.field(testAnchorsField),\n\n                domEventHandlers: {\n                    click(editor, line, event) {\n                        if (!(event instanceof MouseEvent) || event.button !== 0) {\n                            return false;\n                        }\n\n                        const candidates = testsAtLine(editor, line.from);\n\n                        if (candidates.length === 0) {\n                            return false;\n                        }\n\n                        const positions = findServerTestPositions(\n                            editor.state,\n                            filePath.slice(\"tests/\".length),\n                            candidates\n                        );\n\n                        if (positions === null) {\n                            // Wait until parsing is ready before running a test.\n                            return false;\n                        }\n\n                        const tests = candidates.filter((test) => {\n                            const position = positions.get(test.test_id);\n\n                            return position !== undefined && editor.state.doc.lineAt(position).from === line.from;\n                        });\n\n                        if (tests.length === 0) {\n                            return false;\n                        }\n\n                        event.preventDefault();\n                        event.stopPropagation();\n                        onRunTests(tests);\n\n                        return true;\n                    },\n                },\n            }),\n            EditorView.baseTheme({\n                \".cm-server-test-gutter .cm-gutterElement\": {\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    justifyContent: \"center\",\n                    padding: \"0 4px\",\n                },\n                \".cm-server-test-gutter svg\": {\n                    display: \"block\",\n                    width: \"1em\",\n                    height: \"1em\",\n                },\n                \".cm-server-test-play-icon\": {\n                    display: \"none\",\n                },\n                \".cm-gutters:hover .cm-server-test-runnable .cm-server-test-status-icon\": {\n                    display: \"none\",\n                },\n                \".cm-gutters:hover .cm-server-test-runnable .cm-server-test-play-icon\": {\n                    display: \"inline-flex\",\n                },\n            }),\n        ];\n    }, [enabled, filePath, results, testsAreBusy, onRunTests]);\n}\n","import { pythonLanguage } from \"@codemirror/lang-python\";\nimport { ensureSyntaxTree } from \"@codemirror/language\";\nimport { EditorState } from \"@codemirror/state\";\nimport type { DiscoveredTest } from \"@/controllers/server-test-runs\";\n\n/**\n * Locate discovered tests in the current Python document.\n * Returns null if parsing has not finished.\n */\nexport function findServerTestPositions(\n    state: EditorState,\n    filePath: string, //pytest-relative path\n    tests: readonly DiscoveredTest[]\n): Map<string, number> | null {\n    const tree = ensureSyntaxTree(state, state.doc.length, 10);\n\n    if (!tree) {\n        return null;\n    }\n\n    // Keys are names such as test_example or TestExample::test_method.\n    // null means multiple definitions have the same qualified name.\n    const definitions = new Map<string, number | null>();\n\n    tree.iterate({\n        enter(node) {\n            if (node.name !== \"FunctionDefinition\") {\n                return;\n            }\n\n            const name = node.node.getChild(\"VariableName\");\n\n            if (!name) {\n                return false;\n            }\n\n            const parts = [state.doc.sliceString(name.from, name.to)];\n\n            for (let parent = node.node.parent; parent; parent = parent.parent) {\n                // Functions defined inside another function are not\n                // ordinary module/class tests.\n                if (parent.name === \"FunctionDefinition\") {\n                    return false;\n                }\n\n                if (parent.name === \"ClassDefinition\") {\n                    const className = parent.getChild(\"VariableName\");\n\n                    if (!className) {\n                        return false;\n                    }\n\n                    parts.unshift(state.doc.sliceString(className.from, className.to));\n                }\n            }\n\n            const qualifiedName = parts.join(\"::\");\n\n            definitions.set(qualifiedName, definitions.has(qualifiedName) ? null : name.from);\n\n            // We don't need to inspect this function's body.\n            return false;\n        },\n    });\n\n    const positions = new Map<string, number>();\n    const nodeIdPrefix = `${filePath}::`;\n\n    for (const test of tests) {\n        if (test.file_path !== filePath || !test.test_id.startsWith(nodeIdPrefix)) {\n            continue;\n        }\n\n        const relativeId = test.test_id.slice(nodeIdPrefix.length);\n\n        // Parametrized cases share their function's source location.\n        const parameterStart = relativeId.indexOf(\"[\");\n        const qualifiedName = parameterStart === -1 ? relativeId : relativeId.slice(0, parameterStart);\n\n        const position = definitions.get(qualifiedName);\n\n        if (position !== undefined && position !== null) {\n            positions.set(test.test_id, position);\n        }\n    }\n\n    return positions;\n}\n\n/** Find the current definition line, falling back to pytest's discovery line. */\nexport function getServerTestSourceLine(source: string | undefined, test: DiscoveredTest): number | null {\n    if (source === undefined) return test.line;\n\n    const state = EditorState.create({\n        doc: source,\n        extensions: [pythonLanguage],\n    });\n\n    const position = findServerTestPositions(state, test.file_path, [test])?.get(test.test_id);\n\n    return position === undefined ? test.line : state.doc.lineAt(position).number;\n}\n","import type { ChangeSpec, EditorState, SelectionRange, StateCommand } from \"@codemirror/state\";\nimport { EditorSelection, Line, Transaction, countColumn } from \"@codemirror/state\";\nimport type { KeyBinding } from \"@codemirror/view\";\n\n/** this function iterates over lines rather than from and to positions */\nfunction changeBySelectedLine(\n    state: EditorState,\n    f: (line: Line, changes: ChangeSpec[], range: SelectionRange) => void\n) {\n    let atLine = -1;\n    return state.changeByRange((range) => {\n        const changes: ChangeSpec[] = [];\n        for (let pos = range.from; pos <= range.to; ) {\n            const line = state.doc.lineAt(pos);\n            if (line.number > atLine && (range.empty || range.to > line.from)) {\n                f(line, changes, range);\n                atLine = line.number;\n            }\n            pos = line.to + 1;\n        }\n        const changeSet = state.changes(changes);\n        return {\n            changes,\n            range: EditorSelection.range(changeSet.mapPos(range.anchor, 1), changeSet.mapPos(range.head, 1)),\n        };\n    });\n}\n\nexport function countLeadingWhiteSpace(text: string, tabSize: number) {\n    let i = -1;\n    let col = 0;\n    while (++i < text.length) {\n        const chr = text[i];\n        if (chr === \"\\t\") {\n            col += tabSize - (col % tabSize);\n        } else if (chr === \" \") {\n            col += 1;\n        } else {\n            break;\n        }\n    }\n    return col;\n}\n\n/** Overrides codemirror indentMore to move to the nearest tab rather than always 2/4 spaces */\nexport const indentMore: StateCommand = ({ state, dispatch }) => {\n    if (state.readOnly) return false;\n    const tabSize = state.tabSize;\n    dispatch(\n        state.update(\n            changeBySelectedLine(state, (line, changes) => {\n                const col = countLeadingWhiteSpace(line.text, tabSize);\n                const indent = tabSize - (col % tabSize);\n                changes.push({ from: line.from, insert: \" \".repeat(indent) });\n            }),\n            { userEvent: \"input.indent\" }\n        )\n    );\n    return true;\n};\n\n/** Overrides codemirror indentLess to move to the nearest tab rather than always 2/4 spaces */\nexport const indentLess: StateCommand = ({ state, dispatch }) => {\n    if (state.readOnly) return false;\n    const tabSize = state.tabSize;\n    dispatch(\n        state.update(\n            changeBySelectedLine(state, (line, changes) => {\n                const col = countLeadingWhiteSpace(line.text, tabSize);\n                if (col === 0) return;\n                const unIndent = col % tabSize || tabSize;\n                changes.push({ from: line.from + (col - unIndent), to: line.from + col });\n            }),\n            { userEvent: \"delete.dedent\" }\n        )\n    );\n    return true;\n};\n\nconst insertTab: StateCommand = ({ state, dispatch }) => {\n    if (state.readOnly) return false;\n    if (state.selection.ranges.some((r) => !r.empty)) return indentMore({ state, dispatch });\n\n    const tabSize = state.tabSize;\n\n    const changes = state.changeByRange(({ from, to }) => {\n        const line = state.doc.lineAt(from);\n        // countColumn accounts for surrogate pairs\n        const col = countColumn(line.text, tabSize, from - line.from);\n        const indent = tabSize - (col % tabSize);\n        return {\n            changes: { from, to, insert: \" \".repeat(indent) },\n            range: EditorSelection.cursor(from + indent),\n        };\n    });\n    dispatch(state.update(changes, { scrollIntoView: true, annotations: Transaction.userEvent.of(\"input\") }));\n    return true;\n};\n\nexport const defaultTabBinding: KeyBinding = { key: \"Tab\", run: insertTab, shift: indentLess };\n\n/** Because the default indentMore and indentLess don't move to the nearest tab stop */\nexport const indentMoreOverride: KeyBinding[] = [\n    { key: \"Mod-[\", run: indentLess },\n    { key: \"Mod-]\", run: indentMore },\n];\n","import React from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { faTimes } from \"@fortawesome/pro-regular-svg-icons/faTimes\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { AccountModalContent } from \"@/components/modals/account/Account\";\nimport Link from \"@/components/reusable/Link\";\nimport { Heading } from \"@/components/reusable/Text\";\nimport { getUser, getZenMode } from \"@/controllers/ide\";\nimport { AccountNavTarget } from \"@/router/navTypes\";\nimport { useCurrentNavTarget } from \"@/router/navigation-hooks\";\nimport { cx } from \"@/theme/styles\";\nimport { useDelayWhenFalseFlag } from \"@/util/hooks\";\n\nconst AccountPageContent = () => {\n    const user = useSelector(getUser);\n    const currentNavTarget = useCurrentNavTarget() as AccountNavTarget;\n\n    return (\n        <div className={\"px-8 pb-8\"}>\n            <div className={\"sticky top-0 z-10 flex justify-between bg-light-bg0 pt-8 pb-4 dark:bg-dark-bg0\"}>\n                <div className={\"mb-8 flex items-center gap-4\"}>\n                    <Heading level={1} className={\"!m-0\"}>\n                        My Account\n                    </Heading>\n                    <Heading level={1} className={\"!m-0\"}>\n                        {user?.name ? `${user.name} (${user?.email})` : user?.email}\n                    </Heading>\n                </div>\n                <div>\n                    <Link to={currentNavTarget?.backTo ?? { type: \"START_PAGE\" }}>\n                        <FontAwesomeIcon className={\"text-4xl text-light-fg1 dark:text-dark-fg1\"} icon={faTimes} />\n                    </Link>\n                </div>\n            </div>\n            <AccountModalContent\n                section={currentNavTarget.section || \"SUBSCRIPTION\"}\n                newAccountPage={true}\n                hash={currentNavTarget.hash}\n            />\n        </div>\n    );\n};\n\ninterface AccountPageProps {\n    visible: boolean;\n    contentRef: React.RefObject<HTMLDivElement | null>;\n}\n\nconst AccountPage = ({ visible, contentRef }: AccountPageProps) => {\n    const showContent = useDelayWhenFalseFlag(visible, 1000);\n    const zenMode = useSelector(getZenMode);\n\n    // z-index: Above IDE sidebar, below modals.\n    return (\n        <div\n            className={cx(\n                \"absolute right-0 bottom-0 left-0 z-100 origin-top overflow-y-scroll bg-light-bg0 transition-transform dark:bg-dark-bg0\"\n            )}\n            style={{\n                transform: `rotateX(${visible ? 0 : 90}deg)`,\n                top: zenMode ? 0 : contentRef.current?.offsetTop,\n            }}>\n            {showContent && <AccountPageContent />}\n        </div>\n    );\n};\n\nexport default AccountPage;\n","import React, { useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { faTimes } from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { search as fuzzySearch } from \"fast-fuzzy\";\nimport { useStyles as useDdStyles } from \"@/components/reusable/DropdownMenu\";\nimport { cx } from \"@/theme/styles\";\nimport { preventDefault } from \"@/util\";\nimport { useMergeRefs } from \"@/util/hooks\";\nimport useEffectEvent from \"@/util/useEffectEvent\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { LinkInternal } from \"./LinkInternal\";\n\ninterface TagChipProps {\n    tag: string;\n    onRemove?: () => void;\n    onClick?: (e: React.MouseEvent) => void;\n    className?: string;\n}\n\nexport const TagChip = ({ tag, onRemove, onClick, className }: TagChipProps) => (\n    <span\n        className={cx(\n            \"inline-flex items-center gap-1 rounded-full bg-primary/20 px-3 py-1 text-[1.1rem] font-medium text-primary\",\n            onClick && \"cursor-pointer transition-colors select-none hover:bg-primary/30 active:bg-primary/40\",\n            className\n        )}\n        onClick={onClick}>\n        {tag}\n        {onRemove && (\n            <LinkInternal\n                aria-label={`Remove ${tag}`}\n                title={`Remove ${tag}`}\n                onClick={(e) => {\n                    e.stopPropagation();\n                    e.preventDefault();\n                    onRemove();\n                }}\n                className=\"ml-1 cursor-pointer hover:text-primary-darker\">\n                <FontAwesomeIcon icon={faTimes} className=\"text-[1rem]\" />\n            </LinkInternal>\n        )}\n    </span>\n);\n\ninterface TagInputProps {\n    tags: string[];\n    onChange: (tags: string[]) => void;\n    suggestions?: string[];\n    placeholder?: string;\n    className?: string;\n    ref?: React.Ref<HTMLInputElement>;\n}\n\nconst MAX_TAGS = 20;\nconst MAX_TAG_LENGTH = 50;\nconst VALID_TAG_RE = /^[a-z0-9-_]+$/;\nconst DROPDOWN_GAP_PX = 4;\n\nconst isValidTag = (tag: string): boolean => tag.length <= MAX_TAG_LENGTH && VALID_TAG_RE.test(tag);\n\nexport const TagInput = ({\n    tags,\n    onChange,\n    suggestions = [],\n    placeholder = \"Add tag...\",\n    className,\n    ref,\n}: TagInputProps) => {\n    const { classes: ddClasses } = useDdStyles();\n    const [inputValue, setInputValue] = useState(\"\");\n    const [showDropdown, setShowDropdown] = useState(false);\n    const [hoverIndex, setHoverIndex] = useState<number | null>(null);\n    const [validationError, setValidationError] = useState<string | null>(null);\n    const [dropdownAbove, setDropdownAbove] = useState(false);\n    const [dropdownMeasured, setDropdownMeasured] = useState(false);\n    const containerRef = useRef<HTMLDivElement>(null);\n    const inputRef = useRef<HTMLInputElement>(null);\n    const dropdownRef = useRef<HTMLDivElement>(null);\n    const mergedRef = useMergeRefs(inputRef, ref);\n    const isAtLimit = tags.length >= MAX_TAGS;\n\n    const filteredSuggestions = useMemo(() => {\n        if (isAtLimit) return [];\n        const tagsLower = new Set(tags.map((t) => t.toLowerCase()));\n        const available = suggestions.filter((s) => !tagsLower.has(s.toLowerCase()));\n        if (!inputValue.trim()) return available;\n        return fuzzySearch(inputValue, available, { threshold: 0.7 });\n    }, [inputValue, suggestions, tags, isAtLimit]);\n\n    const checkDropdownPosition = useEffectEvent(() => {\n        if (!showDropdown || filteredSuggestions.length === 0 || !containerRef.current || !dropdownRef.current) return;\n\n        const containerRect = containerRef.current.getBoundingClientRect();\n        const dropdownHeight = dropdownRef.current.offsetHeight;\n        const spaceBelow = window.innerHeight - containerRect.bottom - DROPDOWN_GAP_PX;\n        const spaceAbove = containerRect.top - DROPDOWN_GAP_PX;\n\n        setDropdownAbove(spaceBelow < dropdownHeight && spaceAbove > spaceBelow);\n        setDropdownMeasured(true);\n    });\n\n    useLayoutEffect(() => {\n        if (!showDropdown || filteredSuggestions.length === 0) {\n            setDropdownMeasured(false);\n            return;\n        }\n\n        setDropdownMeasured(false);\n        const frame = requestAnimationFrame(checkDropdownPosition);\n        return () => cancelAnimationFrame(frame);\n    }, [showDropdown, filteredSuggestions.length]);\n\n    useLayoutEffect(() => {\n        if (!showDropdown) return;\n\n        window.addEventListener(\"resize\", checkDropdownPosition);\n        window.addEventListener(\"scroll\", checkDropdownPosition, true);\n        return () => {\n            window.removeEventListener(\"resize\", checkDropdownPosition);\n            window.removeEventListener(\"scroll\", checkDropdownPosition, true);\n        };\n    }, [showDropdown]);\n\n    const addTag = useEvent((tag: string) => {\n        if (isAtLimit) {\n            setValidationError(`Maximum ${MAX_TAGS} tags reached`);\n            return;\n        }\n        const trimmed = tag.trim().toLowerCase();\n        const tagsLower = tags.map((t) => t.toLowerCase());\n        if (!trimmed) {\n            setValidationError(\"Tag cannot be empty\");\n            return;\n        }\n        if (tagsLower.includes(trimmed)) {\n            setValidationError(\"Tag already added\");\n            return;\n        }\n        if (!isValidTag(trimmed)) {\n            setValidationError(\"Use lowercase letters, numbers, hyphens or underscores (max 50 chars)\");\n            return;\n        }\n        onChange([...tags, trimmed]);\n        setValidationError(null);\n        setInputValue(\"\");\n        setHoverIndex(null);\n    });\n\n    const removeTag = useEvent((tagToRemove: string) => {\n        onChange(tags.filter((t) => t !== tagToRemove));\n        setValidationError(null);\n    });\n\n    return (\n        <div ref={containerRef} className={cx(\"relative\", className)}>\n            <div className=\"flex flex-wrap items-center gap-2 rounded border border-solid border-sectionborder p-2 dark:border-dark-sectionborder\">\n                {tags.map((tag) => (\n                    <TagChip key={tag} tag={tag} onRemove={() => removeTag(tag)} />\n                ))}\n                {!isAtLimit && (\n                    <input\n                        ref={mergedRef}\n                        type=\"text\"\n                        value={inputValue}\n                        onChange={(e) => {\n                            setInputValue(e.target.value);\n                            setValidationError(null);\n                            setShowDropdown(true);\n                            setHoverIndex(null);\n                        }}\n                        onFocus={() => setShowDropdown(true)}\n                        onBlur={() => {\n                            setShowDropdown(false);\n                            setHoverIndex(null);\n                        }}\n                        onKeyDown={(e) => {\n                            const numItems = filteredSuggestions.length;\n                            switch (e.key) {\n                                case \"ArrowDown\":\n                                    e.preventDefault();\n                                    if (!showDropdown) {\n                                        setShowDropdown(true);\n                                    } else if (numItems > 0) {\n                                        setHoverIndex((prev) => (prev === null ? 0 : (prev + 1) % numItems));\n                                    }\n                                    break;\n                                case \"ArrowUp\":\n                                    e.preventDefault();\n                                    if (numItems > 0) {\n                                        setHoverIndex((prev) =>\n                                            prev === null ? numItems - 1 : (prev - 1 + numItems) % numItems\n                                        );\n                                    }\n                                    break;\n                                case \"Enter\":\n                                    e.preventDefault();\n                                    if (hoverIndex !== null && filteredSuggestions[hoverIndex]) {\n                                        addTag(filteredSuggestions[hoverIndex]);\n                                    } else if (inputValue.trim()) {\n                                        addTag(inputValue);\n                                    }\n                                    break;\n                                case \"Backspace\":\n                                    if (!inputValue && tags.length > 0) {\n                                        removeTag(tags[tags.length - 1]);\n                                    }\n                                    break;\n                                case \"Escape\":\n                                    setShowDropdown(false);\n                                    setHoverIndex(null);\n                                    break;\n                            }\n                        }}\n                        placeholder={tags.length === 0 ? placeholder : \"\"}\n                        className=\"min-w-32 flex-1 border-none bg-transparent p-1 text-[1.2rem] text-light-grey2 outline-none dark:text-white\"\n                    />\n                )}\n            </div>\n            {isAtLimit && (\n                <div className=\"mt-1 text-[1rem] text-light-grey1 dark:text-dark-fg3\">\n                    Maximum {MAX_TAGS} tags reached\n                </div>\n            )}\n            {validationError && <div className=\"mt-1 text-[1rem] text-danger\">{validationError}</div>}\n            {showDropdown && filteredSuggestions.length > 0 && (\n                <div\n                    ref={dropdownRef}\n                    className={cx(\n                        ddClasses.menu,\n                        \"absolute right-0 left-0 z-10\",\n                        dropdownAbove ? \"bottom-full mb-1\" : \"top-full mt-1\"\n                    )}\n                    style={{\n                        transform: \"scaleY(1)\",\n                        transformOrigin: dropdownAbove ? \"bottom\" : \"top\",\n                        visibility: dropdownMeasured ? undefined : \"hidden\",\n                    }}\n                    onMouseDown={preventDefault}>\n                    {filteredSuggestions.map((suggestion, index) => (\n                        <div\n                            key={suggestion}\n                            className={cx(ddClasses.item, hoverIndex === index && \"bg-light-bg4! dark:bg-dark-bg7!\")}\n                            onMouseEnter={() => setHoverIndex(index)}\n                            onMouseDown={preventDefault}\n                            onClick={() => {\n                                addTag(suggestion);\n                                inputRef.current?.focus();\n                            }}>\n                            {suggestion}\n                        </div>\n                    ))}\n                </div>\n            )}\n        </div>\n    );\n};\n\nexport default TagInput;\n","import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport {\n    faArrowDown,\n    faArrowUp,\n    faFileAlt,\n    faImage,\n    faSearch,\n    faSortAlphaDown,\n    faSortAlphaUpAlt,\n    faSortAlt,\n    faTag,\n    faTimes,\n    faTrashAlt,\n} from \"@fortawesome/pro-light-svg-icons\";\nimport { faStar as faStarRegular } from \"@fortawesome/pro-regular-svg-icons/faStar\";\nimport { faStar as faStarSolid } from \"@fortawesome/pro-solid-svg-icons/faStar\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport moment from \"moment\";\nimport { deleteAppWithConfirm } from \"@/controllers/app/saving\";\nimport { getUserUiPrefs, updateUserEditorPrefs } from \"@/controllers/user\";\nimport { useRemToPixels } from \"@/theme/ThemeProvider\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch, AppItem } from \"@/types\";\nimport { blockEvent, noop } from \"@/util\";\nimport { ExternalState, useExternalState } from \"@/util/external-state\";\nimport { useAppsInfiniteQuery, useDelayWhenTrueFlag } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { updateIdeAppListQueries } from \"../controllers/app-list-query\";\nimport { setAppIsFavourite, setAppTags } from \"../controllers/ide\";\nimport { alert } from \"../controllers/modals\";\nimport { Button } from \"./reusable/Button\";\nimport { ButtonGroup } from \"./reusable/ButtonGroup\";\nimport Link from \"./reusable/Link\";\nimport { LinkInternal } from \"./reusable/LinkInternal\";\nimport { LoadingSpinner } from \"./reusable/LoadingSpinner\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./reusable/Popover\";\nimport { ContentTextInput } from \"./reusable/SharedComponents\";\nimport { TagChip, TagInput } from \"./reusable/TagInput\";\nimport { Heading } from \"./reusable/Text\";\nimport { useTooltip } from \"./reusable/Tooltip\";\nimport ResizePanel from \"./sidebar/ResizePanel\";\n\nconst APP_LIST_STARTING_REM = 47;\nconst APPS_PAGE_SIZE = 50;\nconst SLOW_REFRESH_OVERLAY_TIMEOUT = 800;\nconst SLOW_PAGINATION_SPINNER_TIMEOUT = 800;\n\nconst FILTER_OWNER_OPTIONS = [\n    { title: \"All\", value: \"All\" },\n    { title: \"Shared\", value: \"Shared\" },\n    { title: \"Mine\", value: \"Mine\" },\n] as const;\n\ntype OwnerType = (typeof FILTER_OWNER_OPTIONS)[number][\"value\"];\n\ntype AppListItemModel = {\n    editedAgo: string;\n} & AppItem;\n\nconst Left = ({ className, ...props }: React.HTMLProps<HTMLDivElement>) => (\n    <div\n        className={cx(\"border-b border-solid border-sectionborder p-6 pl-12 dark:border-dark-sectionborder\", className)}\n        {...props}\n    />\n);\n\nconst Middle = ({ className, ...props }: React.HTMLProps<HTMLDivElement>) => (\n    <div\n        className={cx(\"w-48 border-b border-solid border-sectionborder p-6 dark:border-dark-sectionborder\", className)}\n        {...props}\n    />\n);\n\nconst Right = ({ className, ...props }: React.HTMLProps<HTMLDivElement>) => (\n    <div\n        className={cx(\n            \"border-b border-solid border-sectionborder p-6 pr-8 pl-0 text-light-grey1 hover:text-light-grey2 dark:border-dark-sectionborder\",\n            className\n        )}\n        {...props}\n    />\n);\n\ntype SearchProps = {\n    search: string;\n    setSearch: (value: string) => void;\n};\n\nconst AppListSearch = ({ search, setSearch }: SearchProps) => {\n    return (\n        <div className=\"relative m-12\">\n            <ContentTextInput\n                className=\"h-16! rounded-none! border border-solid border-sectionborder pl-16! dark:border-dark-sectionborder\"\n                placeholder=\"Search apps or tags\"\n                value={search}\n                onChange={(e) => setSearch(e.target.value)}\n                onEnter={noop}\n            />\n            <FontAwesomeIcon\n                icon={faSearch}\n                className=\"absolute top-4 left-[1.2rem] text-[2rem] text-light-bg5 dark:text-dark-bg3\"\n            />\n            {search && (\n                <LinkInternal\n                    className=\"absolute top-0 right-0 px-[1.2rem] py-[2px] text-[2rem] text-light-bg5 hover:text-light-grey2 dark:text-dark-bg3 dark:hover:text-dark-fg3\"\n                    onClick={() => {\n                        setSearch(\"\");\n                    }}>\n                    <FontAwesomeIcon icon={faTimes} />\n                </LinkInternal>\n            )}\n        </div>\n    );\n};\n\nconst AppListHeadings = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const userUiPrefs = useSelector(getUserUiPrefs);\n\n    const pinFav = userUiPrefs?.appListPinFav !== false;\n\n    const [tooltip, anchorRef] = useTooltip(\"Pin favourites to top\", \"left\");\n\n    const onTogglePinFav = useEvent(() => {\n        if (userUiPrefs?.appListPinFav === undefined) {\n            dispatch(updateUserEditorPrefs(\"appListPinFav\", false));\n        } else {\n            dispatch(updateUserEditorPrefs(\"appListPinFav\", !userUiPrefs.appListPinFav));\n        }\n    });\n\n    const setSortPriorityAndDirection = useEvent((priority: \"name\" | \"date\") => {\n        dispatch(\n            updateUserEditorPrefs(\n                \"appListDisplayAscending\",\n                priority === userUiPrefs?.appListSortPriority ? !userUiPrefs?.appListDisplayAscending : true\n            )\n        );\n        dispatch(updateUserEditorPrefs(\"appListSortPriority\", priority));\n    });\n\n    return (\n        <>\n            <Left\n                style={{ paddingLeft: \"4rem\" }}\n                onClick={() => setSortPriorityAndDirection(\"name\")}\n                className=\"wrap group sticky top-0 z-1 flex bg-light-bg2 text-[1.4rem] font-semibold text-light-grey2 hover:cursor-pointer dark:bg-dark-bg2 dark:text-white\">\n                App\n                {userUiPrefs?.appListSortPriority === \"name\" && (\n                    <FontAwesomeIcon\n                        className=\"mt-2 ml-2 text-light-grey1 group-hover:text-light-grey2\"\n                        icon={userUiPrefs?.appListDisplayAscending ? faSortAlphaDown : faSortAlphaUpAlt}\n                    />\n                )}\n                {userUiPrefs?.appListSortPriority !== \"name\" && (\n                    <FontAwesomeIcon\n                        className=\"mt-2 ml-2 hidden! text-light-grey2 group-hover:inline\"\n                        icon={faSortAlt}\n                    />\n                )}\n            </Left>\n            <Middle\n                onClick={() => setSortPriorityAndDirection(\"date\")}\n                className=\"wrap group sticky top-0 z-1 flex bg-light-bg2 text-[1.4rem] font-semibold text-light-grey2 hover:cursor-pointer dark:bg-dark-bg2 dark:text-white\">\n                Edited\n                {(userUiPrefs?.appListSortPriority === \"date\" || userUiPrefs?.appListSortPriority === undefined) && (\n                    <FontAwesomeIcon\n                        className=\"mt-2 ml-2 text-light-grey1 group-hover:text-light-grey2\"\n                        icon={userUiPrefs?.appListDisplayAscending ? faArrowDown : faArrowUp}\n                    />\n                )}\n                {userUiPrefs?.appListSortPriority !== \"date\" && userUiPrefs?.appListSortPriority !== undefined && (\n                    <FontAwesomeIcon\n                        className=\"mt-2 ml-2 hidden! text-light-grey2 group-hover:inline\"\n                        icon={faSortAlt}\n                    />\n                )}\n                {tooltip}\n            </Middle>\n            <Right className=\"sticky top-0 z-1 bg-light-bg2 text-light-grey2 dark:bg-dark-bg2 dark:text-white\">\n                <div className=\"relative cursor-pointer px-4 py-0\" onClick={onTogglePinFav} ref={anchorRef}>\n                    <FontAwesomeIcon icon={!pinFav ? faStarRegular : faStarSolid} />\n                </div>\n            </Right>\n        </>\n    );\n};\n\nconst AppListItem = ({\n    app,\n    allTags,\n    onTagSelect,\n    scrollContainerRef,\n}: {\n    app: AppListItemModel;\n    allTags: string[];\n    onTagSelect: (tag: string) => void;\n    scrollContainerRef: React.RefObject<HTMLDivElement | null>;\n}) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const [tagPopoverOpen, setTagPopoverOpen] = useState(false);\n    const tagInputRef = useRef<HTMLInputElement>(null);\n    const canEditApp = !!app.owner;\n    const [disabledTagsTooltip, disabledTagsTooltipRef] = useTooltip(\n        <span className=\"block w-56 whitespace-normal\">Cannot edit tags for an app you don't own</span>,\n        \"top\"\n    );\n    const [disabledDeleteTooltip, disabledDeleteTooltipRef] = useTooltip(\n        <span className=\"block w-56 whitespace-normal\">Cannot delete an app you don't own</span>,\n        \"top\"\n    );\n\n    const onStarClick: React.MouseEventHandler = useEvent((e) => {\n        blockEvent(e);\n        dispatch(setAppIsFavourite(app.id, !app.favourite));\n    });\n\n    const onTagsChange = useEvent(async (newTags: string[]) => {\n        const previousTags = [...(app.tags || [])];\n        try {\n            await dispatch(setAppTags(app.id, newTags));\n        } catch (e) {\n            updateIdeAppListQueries((listedApp) =>\n                listedApp.id === app.id ? { ...listedApp, tags: previousTags } : listedApp\n            );\n            const message = (e as { message?: string })?.message || \"Please try again.\";\n            await dispatch(alert(\"Couldn't update tags\", message));\n        }\n    });\n\n    const onTagButtonClick: React.MouseEventHandler = useEvent((e) => {\n        blockEvent(e);\n        setTagPopoverOpen((prev) => !prev);\n    });\n\n    return (\n        <Link to={{ type: \"APP_ROOT\", appId: app.id }} className=\"group contents\">\n            <Left\n                className=\"flex h-26 items-center overflow-hidden text-[1.2rem] font-semibold whitespace-nowrap text-light-grey2 group-hover:bg-sidebar-highlight1 group-active:bg-light-bg4 dark:text-white dark:group-hover:bg-[#484d5866] dark:group-active:bg-dark-bg3\"\n                title={app.name}>\n                {app.icon ? (\n                    <img />\n                ) : (\n                    <div className=\"hidden! h-20 w-20 rounded-[0.4rem] border-2 border-solid border-light-bg5 text-center align-middle text-[2.6rem] text-light-bg5 @3xl/app-list:inline-block!\">\n                        <FontAwesomeIcon icon={faImage} />\n                    </div>\n                )}\n                <div className=\"inline-flex flex-1 flex-col justify-center overflow-hidden\">\n                    <div className=\"ml-6 inline-block truncate\">{app.name}</div>\n                    <div className=\"ml-6 flex items-center gap-1\">\n                        {!app.owner && <span className=\"text-[1rem] text-light-grey1\">Shared with me</span>}\n                        {app.tags && app.tags.length > 0 && (\n                            <div className=\"flex flex-wrap gap-1\">\n                                {app.tags.map((tag, i) => (\n                                    <TagChip\n                                        key={tag}\n                                        tag={tag}\n                                        onClick={(e) => {\n                                            blockEvent(e);\n                                            onTagSelect(tag);\n                                        }}\n                                        className={cx(\n                                            \"py-0 text-[0.9rem]\",\n                                            i >= 2 && \"hidden @xl/app-list:inline-flex\",\n                                            i >= 3 && \"@xl/app-list:hidden @2xl/app-list:inline-flex\",\n                                            i >= 4 && \"@2xl/app-list:hidden @3xl/app-list:inline-flex\"\n                                        )}\n                                    />\n                                ))}\n                                {app.tags.length > 2 && (\n                                    <span className=\"text-[0.9rem] text-light-grey1 @xl/app-list:hidden\">\n                                        +{app.tags.length - 2}\n                                    </span>\n                                )}\n                                {app.tags.length > 3 && (\n                                    <span className=\"hidden text-[0.9rem] text-light-grey1 @xl/app-list:inline @2xl/app-list:hidden\">\n                                        +{app.tags.length - 3}\n                                    </span>\n                                )}\n                                {app.tags.length > 4 && (\n                                    <span className=\"hidden text-[0.9rem] text-light-grey1 @2xl/app-list:inline @3xl/app-list:hidden\">\n                                        +{app.tags.length - 4}\n                                    </span>\n                                )}\n                            </div>\n                        )}\n                    </div>\n                </div>\n            </Left>\n            <Middle className=\"flex h-26 items-center text-[1.2rem] font-medium text-light-grey1 group-hover:bg-sidebar-highlight1 group-active:bg-light-bg4 dark:group-hover:bg-[#484d5866] dark:group-active:bg-dark-bg3\">\n                <div className={cx(\"inline-block truncate\", tagPopoverOpen ? \"hidden!\" : \"group-hover:hidden!\")}>\n                    {app.editedAgo}\n                </div>\n                <div className={cx(\"items-center gap-2\", tagPopoverOpen ? \"flex!\" : \"hidden! group-hover:flex!\")}>\n                    <Popover open={tagPopoverOpen} onOpenChange={setTagPopoverOpen}>\n                        <PopoverTrigger asChild>\n                            <Button\n                                ref={disabledTagsTooltipRef}\n                                className={\"relative items-center justify-center\"}\n                                linkClassName={\"h-12 w-14\"}\n                                variant={\"secondary\"}\n                                disabled={!canEditApp}\n                                onClick={onTagButtonClick}>\n                                {!canEditApp && disabledTagsTooltip}\n                                <FontAwesomeIcon icon={faTag} />\n                            </Button>\n                        </PopoverTrigger>\n                        <PopoverContent\n                            className=\"z-500 w-80\"\n                            side=\"bottom\"\n                            align=\"start\"\n                            portal\n                            collisionBoundary={scrollContainerRef.current}\n                            hideWhenDetached\n                            onClick={blockEvent}\n                            onOpenAutoFocus={(e) => {\n                                e.preventDefault();\n                                tagInputRef.current?.focus();\n                            }}>\n                            <div\n                                className=\"mb-3 min-w-0 truncate text-[1.15rem] font-semibold text-light-grey2 dark:text-white\"\n                                title={`Tags for ${app.name}`}>\n                                Tags for {app.name}\n                            </div>\n                            <TagInput\n                                ref={tagInputRef}\n                                tags={app.tags || []}\n                                onChange={onTagsChange}\n                                suggestions={allTags}\n                                placeholder=\"Add tag...\"\n                            />\n                        </PopoverContent>\n                    </Popover>\n                    <Button\n                        ref={disabledDeleteTooltipRef}\n                        className={\"relative items-center justify-center\"}\n                        linkClassName={\"h-12 w-14\"}\n                        variant={\"danger\"}\n                        disabled={!canEditApp}\n                        onClick={(e) => {\n                            blockEvent(e);\n                            dispatch(deleteAppWithConfirm(app));\n                        }}>\n                        {!canEditApp && disabledDeleteTooltip}\n                        <FontAwesomeIcon icon={faTrashAlt} />\n                    </Button>\n                </div>\n            </Middle>\n            <Right\n                className={cx(\n                    \"flex h-26 items-center group-hover:bg-sidebar-highlight1 group-active:bg-light-bg4 dark:group-hover:bg-[#484d5866] dark:group-active:bg-dark-bg3\",\n                    app.favourite && \"bg-light-bg2 text-light-grey2 dark:bg-dark-bg2\",\n                    tagPopoverOpen && \"bg-sidebar-highlight1 dark:bg-[#484d5866]\"\n                )}>\n                <div\n                    onClick={onStarClick}\n                    className={cx(\n                        \"mx-auto my-0 flex h-12! w-14! items-center justify-center rounded-[0.4rem]\",\n                        tagPopoverOpen\n                            ? \"bg-primary text-white hover:bg-primary-darker\"\n                            : \"group-hover:bg-primary group-hover:text-white group-hover:hover:bg-primary-darker\"\n                    )}>\n                    <FontAwesomeIcon icon={app.favourite ? faStarSolid : faStarRegular} />\n                </div>\n            </Right>\n        </Link>\n    );\n};\n\nconst searchState = new ExternalState(\"\");\n\nfunction useAppListData() {\n    const userUiPrefs = useSelector(getUserUiPrefs);\n    const [includePySpace, setIncludePySpace] = useState<boolean>(false);\n    const [search, setSearch] = useExternalState(searchState);\n\n    const ownerFilter = (userUiPrefs?.appListOwnershipFilter || \"All\") as OwnerType;\n    const sort = userUiPrefs?.appListSortPriority === \"name\" ? \"name\" : \"date\";\n    const order = userUiPrefs?.appListDisplayAscending ? \"asc\" : \"desc\";\n    const pinFav = userUiPrefs?.appListPinFav !== false;\n\n    const query = useAppsInfiniteQuery({\n        initialQuery: search,\n        owner: ownerFilter,\n        includePySpace,\n        sort,\n        order,\n        pinFav,\n        pageSize: APPS_PAGE_SIZE,\n    });\n\n    const apps = useMemo(() => {\n        const mapped: AppListItemModel[] = query.apps.map((app) => ({\n            ...app,\n            name: app.name || \"Unnamed App\",\n            editedAgo: moment.duration(moment.utc(app.last_updated).diff(moment.utc())).humanize(true),\n        }));\n        if (!pinFav) return mapped;\n        return [...mapped].sort((a, b) => Number(b.favourite) - Number(a.favourite));\n    }, [query.apps, pinFav]);\n\n    const setSearchAndQuery = useEvent((value: string) => {\n        setSearch(value);\n        query.setQuery(value);\n    });\n\n    return {\n        query,\n        apps,\n        includePySpace,\n        setIncludePySpace,\n        ownerFilter,\n        search,\n        setSearch: setSearchAndQuery,\n    };\n}\n\nfunction useHiddenEmptyStateGate() {\n    // Hide the app list panel on first load only when we confirm the unfiltered list is truly empty.\n    // This avoids flashing an empty panel before the initial lightweight existence check resolves.\n    const { isFetched, isFetching, apps, isError } = useAppsInfiniteQuery({\n        includePySpace: true,\n        pageSize: 1,\n    });\n    const hasRevealedPanelRef = useRef(false);\n    const isResolvedEmpty = isFetched && !isFetching && apps.length === 0;\n    const gate = !isError && (!isFetched || isResolvedEmpty) ? \"hide\" : \"render\";\n\n    if (hasRevealedPanelRef.current) return \"render\" as const;\n    if (gate === \"render\") {\n        hasRevealedPanelRef.current = true;\n    }\n    return gate;\n}\n\nconst AppResizePanel = ({ children }: React.PropsWithChildren) => (\n    <ResizePanel\n        style={{ height: \"100%\", minWidth: \"32rem\" }}\n        horizontal={true}\n        panelSize={`${APP_LIST_STARTING_REM}rem`}\n        handleAtStart={true}\n        onFinishDrag={noop}>\n        <div className=\"flex h-full w-full flex-[0_0_auto] flex-col border-l border-solid border-sectionborder bg-light-bg2 text-light-grey2 dark:border-dark-sectionborder dark:bg-dark-bg2\">\n            {children}\n        </div>\n    </ResizePanel>\n);\n\nconst AppListPanel = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { query, apps, includePySpace, setIncludePySpace, ownerFilter, search, setSearch } = useAppListData();\n    const allTags = useMemo(() => {\n        const tagSet = new Set<string>();\n        apps.forEach((app) => {\n            app.tags?.forEach((tag) => {\n                tagSet.add(tag);\n            });\n        });\n        return Array.from(tagSet).sort();\n    }, [apps]);\n    const onTagSelect = useEvent((tag: string) => {\n        setSearch(tag);\n    });\n\n    const updateSelectedFilter = (selected: OwnerType) => {\n        dispatch(updateUserEditorPrefs(\"appListOwnershipFilter\", selected));\n    };\n\n    const containerRef = useRef<HTMLDivElement>(null);\n    const size = useRemToPixels(6.5);\n\n    const rowVirtualizer = useVirtualizer({\n        count: apps.length,\n        overscan: 10,\n        getScrollElement: () => containerRef.current,\n        estimateSize: () => size,\n        getItemKey: (i) => apps[i]?.id || i,\n    });\n    const bodyHeight = apps.length > 0 ? rowVirtualizer.getTotalSize() : size * 8;\n\n    const virtualItems = rowVirtualizer.getVirtualItems();\n    useEffect(() => {\n        const last = virtualItems[virtualItems.length - 1];\n        if (!last) return;\n        if (\n            last.index >= apps.length - 8 &&\n            query.hasNextPage &&\n            !query.isFetchingNextPage &&\n            !query.isPlaceholderData\n        ) {\n            query.fetchNextPage();\n        }\n    }, [virtualItems, apps.length, query]);\n\n    const hiddenEmptyStateGate = useHiddenEmptyStateGate();\n    const isFetchingNextPageWithVisibleResults = query.isFetchingNextPage && apps.length > 0;\n    const showSlowPaginationSpinner = useDelayWhenTrueFlag(\n        isFetchingNextPageWithVisibleResults,\n        SLOW_PAGINATION_SPINNER_TIMEOUT,\n        false\n    );\n    const isRefreshingVisibleResults = query.isFetching && !query.isFetchingNextPage && apps.length > 0;\n    const showSlowPlaceholderOverlay = useDelayWhenTrueFlag(\n        isRefreshingVisibleResults,\n        SLOW_REFRESH_OVERLAY_TIMEOUT,\n        false\n    );\n\n    if (hiddenEmptyStateGate === \"hide\") {\n        return null;\n    }\n\n    return (\n        <AppResizePanel>\n            <Heading className={\"px-14 pt-14\"} level={1}>\n                <FontAwesomeIcon icon={faFileAlt} className=\"mr-6 mb-[-2] text-[2.6rem] text-primary\" />\n                My Apps\n            </Heading>\n            <AppListSearch search={search} setSearch={setSearch} />\n            <ButtonGroup\n                className=\"mx-auto mt-0 mb-4\"\n                options={FILTER_OWNER_OPTIONS}\n                selectedVariant={\"primary\"}\n                selectedOption={ownerFilter || \"All\"}\n                onClick={updateSelectedFilter}\n            />\n            <div className={\"flex justify-end\"}>\n                <LinkInternal\n                    className={\"mt-[.5rem] mr-12 mb-4 text-[1.2rem] text-primary underline\"}\n                    onClick={() => {\n                        setIncludePySpace(!includePySpace);\n                    }}>\n                    {includePySpace ? \"Hide\" : \"Include\"} py.space Apps\n                </LinkInternal>\n            </div>\n            <div\n                ref={containerRef}\n                className=\"@container/app-list grid min-h-0 grid-cols-[auto_max-content_max-content] overflow-x-hidden overflow-y-auto\">\n                <AppListHeadings />\n                {showSlowPaginationSpinner && (\n                    <div className=\"pointer-events-none sticky top-1/2 z-20 col-span-3 h-0 -translate-y-1/2\">\n                        <div className=\"flex justify-center\">\n                            <LoadingSpinner />\n                        </div>\n                    </div>\n                )}\n                <div className=\"relative col-span-3\" style={{ height: `${bodyHeight}px` }}>\n                    {showSlowPlaceholderOverlay && (\n                        <div className=\"pointer-events-none absolute inset-0 z-10 flex items-center justify-center bg-light-bg2/55 dark:bg-dark-bg2/55\">\n                            <LoadingSpinner />\n                        </div>\n                    )}\n                    {apps.length === 0 && query.isLoading && (\n                        <div className=\"absolute inset-0 flex items-center justify-center\">\n                            <LoadingSpinner />\n                        </div>\n                    )}\n                    {apps.length === 0 && !query.isLoading && (\n                        <div className=\"absolute inset-0 flex items-center justify-center text-[1.2rem] text-light-grey1\">\n                            No apps found\n                        </div>\n                    )}\n                    {virtualItems.map(({ size, start, key, index }) => (\n                        <div\n                            className=\"absolute inset-0 grid w-full grid-cols-[auto_max-content_max-content]\"\n                            key={key}\n                            style={{ height: `${size}px`, transform: `translateY(${start}px)` }}>\n                            <AppListItem\n                                app={apps[index]}\n                                allTags={allTags}\n                                onTagSelect={onTagSelect}\n                                scrollContainerRef={containerRef}\n                            />\n                        </div>\n                    ))}\n                </div>\n            </div>\n        </AppResizePanel>\n    );\n};\n\nexport default AppListPanel;\n","import React, { useRef, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { IconDefinition, faQuestion } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faBook, faBooks, faComments, faGraduationCap } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useResizeObserver } from \"@/util/hooks\";\nimport { getUser } from \"../controllers/ide\";\nimport AppList from \"./AppList\";\nimport StartPageContent from \"./StartPageContent\";\nimport Link from \"./reusable/Link\";\n\ninterface MainMenuItem {\n    text: string;\n    url: string;\n    icon?: IconDefinition;\n}\n\nconst mainMenuItems = [\n    { text: \"View documentation\", url: \"/docs/overview?utm_source=start-page:action-menu\", icon: faBook },\n    { text: \"Ask the community\", url: \"https://anvil.works/forum/\", icon: faComments },\n    { text: \"How-to guides\", url: \"/docs/how-to?utm_source=start-page:action-menu\", icon: faBooks },\n    { text: \"Tutorials page\", url: \"/learn/tutorials?utm_source=start-page:action-menu\", icon: faGraduationCap },\n    // Add app tour here when it's ready\n] satisfies MainMenuItem[];\n\nconst additionalMenuItems = [\n    { text: \"Get Support\", url: \"/docs/overview/free-vs-paid?utm_source=start-page:action-menu#production-plan\" },\n    { text: \"Changelog\", url: \"/changelog?utm_source=start-page:action-menu\" },\n] satisfies MainMenuItem[];\n\nconst MenuItem = ({ item }: { item: MainMenuItem }) => {\n    return (\n        <li>\n            <Link\n                to={item.url}\n                target={\"_blank\"}\n                className=\"inline-block w-full px-8 hover:bg-primary hover:text-white\">\n                {item.icon && <FontAwesomeIcon className=\"mr-2\" icon={item.icon} />}\n                {item.text}\n            </Link>\n        </li>\n    );\n};\n\nconst StartPageActionMenu = ({ containerWidth }: { containerWidth: number }) => {\n    return (\n        <div\n            style={{ left: `calc(${containerWidth}px - 23rem)` }}\n            className=\"fixed bottom-32 z-90 h-fit rounded-[4px] border border-solid border-sectionborder bg-light-bg2\">\n            <ul className=\"pt-8 leading-loose\">\n                {mainMenuItems.map((item, i) => (\n                    <MenuItem key={i} item={item} />\n                ))}\n            </ul>\n            <hr className=\"border-sectionborder\" />\n            <ul className=\"pb-8 leading-loose\">\n                {additionalMenuItems.map((item, i) => (\n                    <MenuItem key={i} item={item} />\n                ))}\n            </ul>\n        </div>\n    );\n};\n\nconst StartPageActionButton = ({ containerWidth }: { containerWidth: number }) => {\n    const user = useSelector(getUser);\n    const [openMenu, setOpenMenu] = useState(false);\n\n    if (!user?.$loaded) return null;\n    return (\n        <>\n            {openMenu && <div className=\"absolute inset-0 z-50 h-full w-full\" onClick={() => setOpenMenu(false)}></div>}\n            <button\n                onClick={() => setOpenMenu(!openMenu)}\n                style={{ left: `calc(${containerWidth}px - 7rem)` }}\n                className=\"fixed bottom-8 z-90 flex h-20 w-20 items-center justify-center rounded-full border-0 bg-primary hover:bg-primary-darker\">\n                <FontAwesomeIcon className=\"text-[3rem] text-white\" icon={faQuestion} />\n            </button>\n            {openMenu && <StartPageActionMenu containerWidth={containerWidth} />}\n        </>\n    );\n};\n\nconst StartPage = () => {\n    const startPageContentContainer = useRef<HTMLDivElement>(null);\n    const [containerWidth, setContainerWidth] = useState(0);\n    useResizeObserver(startPageContentContainer, () => {\n        setContainerWidth(startPageContentContainer?.current?.offsetWidth ?? 0);\n    });\n\n    return (\n        <div className=\"flex h-full\">\n            <div\n                className=\"flex w-0 shrink-0 grow flex-wrap content-start justify-center gap-20 overflow-x-hidden bg-white p-20 dark:bg-dark-bg1\"\n                ref={startPageContentContainer}>\n                <StartPageContent />\n                <StartPageActionButton containerWidth={containerWidth} />\n            </div>\n            <AppList />\n        </div>\n    );\n};\n\nexport default StartPage;\n","import { ConversationPid } from \"@/agent/types.ts\";\nimport { Conversation } from \"@/agent/components/Conversation.tsx\";\nimport { useConversation } from \"@/agent/hooks.ts\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useDispatch } from \"react-redux\";\n\nexport const AgentPanel = ({ conversationPid }: { conversationPid: ConversationPid }) => {\n\n    const { conversationInfo, conversation, historyNotice } = useConversation(conversationPid);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    if (!conversationInfo) {\n        return (\n            <div className={\"bg-primary-50\"}>\n                <LoadingSpinner />\n            </div>\n        );\n    } else {\n        return (\n            <div className={\"flex h-full flex-col bg-white dark:bg-dark-bg1\"}>\n                <div className={\"h-0 grow overflow-y-auto\"}>\n                    <Conversation\n                        conversationInfo={conversationInfo}\n                        conversation={conversation}\n                        historyNotice={historyNotice}\n                        isVisible\n                    />\n                </div>\n            </div>\n        );\n    }\n};\n","import * as React from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faChevronRight } from \"@fortawesome/pro-light-svg-icons/faChevronRight\";\nimport { Button } from \"@/components/reusable/Button\";\nimport Link from \"@/components/reusable/Link\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport { AnvilCtaSpec, TableauCTASpec, getAppCta, isTableauCta, removeCta, validCtas } from \"@/controllers/app/cta\";\nimport { openOrFocusBottomTab } from \"@/controllers/bottom-tabs\";\nimport { ANVIL_X_LOGO } from \"@/data/imageUrls\";\nimport { AnvilDispatch } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\n\nconst TableauCtaContent = ({ description, sampleDashboardUrl }: TableauCTASpec) => {\n    return (\n        <div className={\"mx-40 flex items-start justify-center\"}>\n            <div className={\"flex-none\"}>\n                <img className={\"mr-8 h-60 p-4\"} src={ANVIL_X_LOGO} />\n            </div>\n            <div\n                className={\n                    \"max-w-360 min-w-120 flex-1 items-start rounded-lg border border-sectionborder bg-light-bg2 px-8 pt-4 dark:border-dark-sectionborder dark:bg-dark-bg3\"\n                }>\n                {description}\n                <hr />\n                <Text>\n                    To use this extension,{\" \"}\n                    <Link className={\"text-primary underline\"} target={\"_blank\"} to={sampleDashboardUrl}>\n                        download the sample Tableau dashboard\n                    </Link>{\" \"}\n                    it goes with. You can open this in Tableau Desktop, or upload it to Tableau Cloud or Tableau Server.\n                    Alternatively, you can use this extension with a dashboard you already have.\n                </Text>\n                <Text>\n                    Follow{\" \"}\n                    <Link className={\"text-primary underline\"} target={\"_blank\"} to={\"/docs/x/testing-in-tableau\"}>\n                        these instructions\n                    </Link>{\" \"}\n                    to download the <code>.trex</code> file for this extension, add it to your dashboard, and take it\n                    for a spin!\n                </Text>\n            </div>\n        </div>\n    );\n};\n\nconst AnvilCtaContent = ({ href, description, img }: AnvilCtaSpec) => {\n    return (\n        <div className={\"mx-40 flex items-center justify-center\"}>\n            <div className={\"flex flex-auto justify-center\"}>\n                {img && <img className={\"h-76 flex-none rounded-l-lg border border-light-bg4 bg-cover dark:border-dark-bg4 dark:border-dark-sectionborder\"} alt={\"Tutorial thumbnail\"} src={img}/>}\n                <div\n                    className={\n                        \"flex max-w-360 min-w-120 flex-1 flex-col items-start justify-between rounded-r-lg border border-l-0 border-sectionborder bg-light-bg2 px-8 pt-4 pb-8 dark:border-dark-sectionborder dark:bg-dark-bg3\"\n                    }>\n                    <Text>{description}</Text>\n                    {href && (\n                        <Button icon={faChevronRight} iconRight variant={\"primary\"} onClick={() => window.open(href)}>\n                            Open the tutorial\n                        </Button>\n                    )}\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport const BuildThis = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const appCta = useSelector(getAppCta);\n\n    const cta: AnvilCtaSpec | TableauCTASpec | null = appCta ? validCtas[appCta.preset] : null;\n\n    const closeTab = useEvent(() => {\n        dispatch(openOrFocusBottomTab({ type: \"versionHistory\" }));\n        dispatch(removeCta());\n    });\n\n    if (!cta) return null;\n\n    return (\n        <div className={\"h-full overflow-auto\"}>\n            <div className={\"flex items-center justify-between px-8 py-8\"}>\n                <Heading className={\"m-0!\"}>{\"headline\" in cta ? cta.headline : \"How to build this app\"}</Heading>\n                <Button size={\"small\"} variants={[\"danger\", \"outlined\"]} onClick={closeTab}>\n                    Remove these instructions from this app\n                </Button>\n            </div>\n            {isTableauCta(cta) ? <TableauCtaContent {...cta} /> : <AnvilCtaContent {...cta} />}\n        </div>\n    );\n};\n","import * as React from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { faCircle } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { createContextHook, useMemoiseObject } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback.ts\";\nimport { cx } from \"../../theme/styles\";\n\n// Stepper component-set. Similar idea to a carousel, there is a main body content section\n// that cycles through the content. There are control buttons to go forward/back thru the\n// steps, and also a progress/step indicator so let you know which step you're on out of\n// how many.\n// The content doesn't wrap so once you get to the last slide, that's it.\n// It's a component set and not just a component because each of the 4 parts can be placed\n// freely, anywhere on the layout.\n// The information about the steps will be made available in a context of some parent, and\n// then each component of the set will use that to stay in sync.\n// The components will be uncontrolled - but the step can be set by a parent\n\ninterface StepProps {\n    stepId: string;\n    content: React.ReactNode;\n}\ninterface StepperContextValue {\n    steps: StepProps[];\n    stepIndex: number;\n    stepCount: number;\n    canPrev: boolean;\n    canNext: boolean;\n    goToIndex: (ind: number) => void;\n    buttonClasses?: {\n        default?: string;\n        hoverClass?: string;\n        disabledClass?: string;\n        activeClass?: string;\n    };\n}\n\nconst StepperContext = React.createContext<StepperContextValue | null>(null);\n\nexport const useStepperContext = createContextHook(StepperContext, \"StepperComponentContext\");\n\ninterface StepperRootProps {\n    steps: StepProps[];\n    children: React.ReactNode;\n    buttonClasses?: {\n        default?: string;\n        hoverClass?: string;\n        disabledClass?: string;\n        activeClass?: string;\n    };\n    requestedStepIndex?: number;\n    onStepIndexChange?: (ind: number) => void;\n}\n\nexport const Stepper = ({ children, steps, buttonClasses, requestedStepIndex, onStepIndexChange }: StepperRootProps) => {\n    const stepCount = steps.length;\n    const [stepIndex, setStepIndex] = useState(requestedStepIndex ?? 0);\n\n    const canPrev = stepIndex != 0;\n    const canNext = stepIndex < steps.length - 1;\n\n    const goToIndex = useEvent((ind: number) => {\n        if (ind >= 0 && ind < steps.length) {\n            setStepIndex(ind);\n            onStepIndexChange?.(ind);\n        }\n    });\n\n    //stepper changes with requestedStepIndex, but arrow clicks still update internal state normally\n    useEffect(() => {\n        if (requestedStepIndex === undefined) return;\n        goToIndex(requestedStepIndex);\n    }, [requestedStepIndex, goToIndex]);\n\n    //for cases if the number of steps change\n    useEffect(() => {\n        //clamp incase shrinking\n        if (steps.length === 0) {\n            if (stepIndex !== 0) setStepIndex(0);\n            return;\n        }\n\n        const maxIndex = steps.length - 1;\n        if (stepIndex > maxIndex) goToIndex(maxIndex);\n    }, [steps.length, goToIndex]);\n\n    const value = useMemoiseObject<StepperContextValue>({\n        steps,\n        stepIndex,\n        stepCount,\n        canPrev,\n        canNext,\n        goToIndex,\n        buttonClasses,\n    });\n    return <StepperContext.Provider value={value}>{children}</StepperContext.Provider>;\n};\n\nexport type StepperBodyProps = {\n    className?: string;\n};\nexport const StepperBody = ({ className }: StepperBodyProps) => {\n    const { steps, stepIndex } = useStepperContext();\n    return (\n        <div className={className}>\n            {steps.map((step: StepProps, index: number) => {\n                return (\n                    <div\n                        key={step.stepId}\n                        className={cx(\"flex hidden h-full w-full gap-2\", { block: index === stepIndex })}>\n                        {step.content}\n                    </div>\n                );\n            })}\n        </div>\n    );\n};\n\ninterface StepperButtonProps {\n    children: React.ReactNode;\n}\n\nexport const StepperPrevButton = ({ children }: StepperButtonProps) => {\n    const { stepIndex, canPrev, goToIndex, buttonClasses } = useStepperContext();\n    const onClick = useEvent(() => {\n        if (canPrev) {\n            goToIndex(stepIndex - 1);\n        }\n    });\n    return (\n        <div\n            onClick={onClick}\n            className={cx(\n                buttonClasses?.default,\n                canPrev\n                    ? `cursor-pointer ${buttonClasses?.hoverClass} ${buttonClasses?.activeClass}`\n                    : `${buttonClasses?.disabledClass}`\n            )}>\n            {children}\n        </div>\n    );\n};\n\nexport const StepperForwardButton = ({ children }: StepperButtonProps) => {\n    const { stepIndex, canNext, goToIndex, buttonClasses } = useStepperContext();\n    const onClick = useEvent(() => {\n        if (canNext) {\n            goToIndex(stepIndex + 1);\n        }\n    });\n    return (\n        <div\n            onClick={onClick}\n            className={cx(\n                buttonClasses?.default,\n                canNext\n                    ? `cursor-pointer ${buttonClasses?.hoverClass} ${buttonClasses?.activeClass}`\n                    : `${buttonClasses?.disabledClass}`\n            )}>\n            {children}\n        </div>\n    );\n};\n\ninterface StepIndicatorProps {\n    className?: string;\n}\n\nexport const StepIndicator = ({ className }: StepIndicatorProps) => {\n    const { steps, stepIndex, goToIndex } = useStepperContext();\n\n    const jumpTo = useEvent((ind: number) => {\n        if (ind === stepIndex) return;\n        goToIndex(ind);\n    });\n    return (\n        <div className={cx(className, \"flex items-center justify-center gap-x-4\")}>\n            {steps.map((step, index) => (\n                <div\n                    key={step.stepId}\n                    onClick={() => jumpTo(index)}\n                    className={cx(\"cursor-pointer text-light-bg3\", {\n                        \"cursor-default text-primary\": stepIndex === index,\n                    })}>\n                    <FontAwesomeIcon icon={faCircle} size={\"2xs\"} />\n                </div>\n            ))}\n        </div>\n    );\n};\n","import * as React from \"react\";\nimport { ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faArrowRight, faChevronLeft, faChevronRight } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Button } from \"@/components/reusable/Button\";\nimport {\n    StepIndicator,\n    Stepper,\n    StepperBody,\n    StepperForwardButton,\n    StepperPrevButton,\n} from \"@/components/reusable/Stepper.tsx\";\nimport { missingFormClasses } from \"@/components/tabs/code/NewFormEditor\";\nimport { ideTutorialProgress } from \"@/controllers/ideTutorial\";\nimport { resetTutorial, setBottomPanelHeightForTutorial } from \"@/controllers/ideTutorial\";\nimport { cx } from \"@/theme/styles.ts\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useStoreState } from \"@/util/external-store\";\n\ninterface StepCardProps {\n    titleContent: ReactNode;\n    mainContent: ReactNode;\n    gif: string;\n}\n\nconst StepCard = ({ titleContent, mainContent, gif }: StepCardProps) => {\n    return (\n        <div className={cx(\"flex h-full w-full gap-4\")}>\n            <div className={\"flex flex-none items-center justify-center\"}>\n                <img\n                    src={gif}\n                    className={cx(\n                        \"mt-2 mr-8 h-[20rem] rounded-lg border\",\n                        \"border-sectionborder\",\n                        \"dark:border-dark-sectionborder\"\n                    )}\n                />\n            </div>\n            <div className={cx(\"flex min-w-[20rem] flex-col justify-center gap-4\")}>\n                <div className={cx(\"text-3xl font-semibold text-wrap text-black\", \"dark:text-dark-fg1\")}>\n                    {titleContent}\n                </div>\n                <div className={\"text-wrap\"}>{mainContent}</div>\n            </div>\n        </div>\n    );\n};\n\nconst tutorialSteps = [\n    {\n        stepId: \"add-component\",\n        content: (\n            <StepCard\n                titleContent={\n                    <>\n                        Step 1: Drag a <span className={\"font-mono font-normal\"}>Button</span> onto your page\n                    </>\n                }\n                mainContent={\n                    <>\n                        <div>\n                            In the{\" \"}\n                            <a\n                                href={\"/docs/editor/form-editor#design-view\"}\n                                target={\"_blank\"}\n                                className={\"text-primary hover:text-primary-300!\"}>\n                                Design View\n                            </a>{\" \"}\n                            above, drag a Button{\" \"}\n                            <img\n                                className={cx(\"mr-2 h-12\")}\n                                src={\"/docs/components/standard-components/img/basic/button-icon.png\"}\n                                alt={\"button-component\"}\n                            />\n                            from the{\" \"}\n                            <a\n                                href={\"/docs/editor/form-editor#toolbox\"}\n                                className={\"text-primary hover:text-primary-300!\"}\n                                target={\"_blank\"}>\n                                Toolbox\n                            </a>{\" \"}\n                            on the right (labelled <span className={\"font-semibold\"}>Add Components</span>) and drop it\n                            onto your page.{\" \"}\n                        </div>\n                        <div className={\"italic\"}>\n                            On smaller screens, click <span className={\"font-semibold\"}>+ Add Components</span> at the\n                            top to open the Toolbox.\n                        </div>\n                    </>\n                }\n                gif={\"/ide/img/ide-tutorial/step1.gif\"}\n            />\n        ),\n    },\n    {\n        stepId: \"add-event-handler\",\n        content: (\n            <StepCard\n                titleContent={\n                    <>\n                        Step 2: Add a <span className={\"font-mono font-normal\"}>click</span>{\" \"}\n                        <a\n                            href={\"/docs/client/events\"}\n                            className={\"text-primary hover:text-primary-300!\"}\n                            target={\"_blank\"}>\n                            event handler\n                        </a>{\" \"}\n                        to the button\n                    </>\n                }\n                mainContent={\n                    <>\n                        Click the button you just placed, then select{\" \"}\n                        <span className={\"font-mono font-semibold\"}>\n                            on click event <FontAwesomeIcon icon={faArrowRight} />\n                        </span>{\" \"}\n                        from the{\" \"}\n                        <a\n                            href={\"/docs/editor/form-editor#object-palette\"}\n                            className={\"text-primary hover:text-primary-300!\"}\n                            target={\"_blank\"}>\n                            Object Palette\n                        </a>{\" \"}\n                        to open{\" \"}\n                        <a\n                            href={\"/docs/editor/form-editor#code-view\"}\n                            className={\"text-primary hover:text-primary-300!\"}\n                            target={\"_blank\"}>\n                            Anvil's code editor\n                        </a>\n                        , where you’ll write your logic.\n                    </>\n                }\n                gif={\"/ide/img/ide-tutorial/step2.gif\"}\n            />\n        ),\n    },\n    {\n        stepId: \"change-text\",\n        content: (\n            <StepCard\n                titleContent={<>Step 3: Change the text of the button when it's clicked</>}\n                mainContent={\n                    <>\n                        <div>\n                            In the button's{\" \"}\n                            <a\n                                href={\"/docs/client/events\"}\n                                className={\"text-primary hover:text-primary-300!\"}\n                                target={\"_blank\"}>\n                                click handler\n                            </a>\n                            , replace <span className={\"font-mono\"}>pass</span> with:\n                        </div>\n                        <div>\n                            <span className={\"font-mono select-all\"}>self.button_1.text = \"Clicked!\"</span>\n                        </div>\n                    </>\n                }\n                gif={\"/ide/img/ide-tutorial/step3.gif\"}\n            />\n        ),\n    },\n    {\n        stepId: \"run-app\",\n        content: (\n            <StepCard\n                titleContent={<>Step 4: Run the app to try it out!</>}\n                mainContent={\n                    <>\n                        Click the Run Button{\" \"}\n                        <img\n                            className={cx(\"h-12\")}\n                            src={\"/docs/ui/components/img/basic/run-icon.png\"}\n                            alt={\"button-component\"}\n                        />{\" \"}\n                        in the top right to run the app, then click the button you added the event handler to.\n                    </>\n                }\n                gif={\"/ide/img/ide-tutorial/step4.gif\"}\n            />\n        ),\n    },\n];\n\nexport const IDETutorialPanel = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const missingClasses = useStoreState(missingFormClasses);\n    const anyMissingClasses = useMemo(() => Object.values(missingClasses).some(Boolean), [missingClasses]);\n\n    useEffect(() => {\n        dispatch(setBottomPanelHeightForTutorial());\n    }, [dispatch]);\n\n    const [requestedStepIndex, setRequestedStepIndex] = useState<number | undefined>(undefined);\n\n    const { lastCompletedStep, steps: completedSteps } = useStoreState(ideTutorialProgress);\n\n    useEffect(() => {\n        const lastCompletedIndex = tutorialSteps.findIndex((s) => s.stepId === lastCompletedStep);\n        const nextIndex = lastCompletedIndex < 0 ? 0 : Math.min(lastCompletedIndex + 1, tutorialSteps.length - 1);\n\n        setRequestedStepIndex(nextIndex);\n    }, [lastCompletedStep]);\n\n    return (\n        <>\n            {anyMissingClasses && (\n                <div className={cx(\"absolute top-[3.9rem] z-10 flex h-full w-full items-center justify-center\")}>\n                    <div className={\"h-full w-full bg-black opacity-10\"} />\n                    <div\n                        className={\n                            \"absolute z-30 flex w-3/4 flex-wrap justify-center gap-2 rounded-md border-2 border-sectionborder-darker bg-[#FFD]! p-12 text-[#333]!\"\n                        }>\n                        You have deleted your Form class, which Anvil needs. To continue,\n                        <Button\n                            small\n                            variant={\"secondary\"}\n                            className={\"ml-4\"}\n                            onClick={() => dispatch(resetTutorial())}>\n                            Reset the tutorial and try again.\n                        </Button>\n                    </div>\n                </div>\n            )}\n            <Stepper\n                steps={tutorialSteps}\n                requestedStepIndex={requestedStepIndex}\n                buttonClasses={{\n                    default:\n                        \"flex aspect-square w-[4rem] items-center justify-center rounded-full border border-sectionborder bg-light-bg2 dark:border-dark-sectionborder dark:bg-dark-bg3\",\n                    hoverClass: \"hover:bg-light-bg5 dark:hover:bg-dark-bg4\",\n                    disabledClass: \"opacity-60 cursor-not-allowed bg-light-bg1 dark:bg-black\",\n                    activeClass: \"active:bg-light-bg6 dark:active:bg-dark-bg6\",\n                }}>\n                <div className={\"h-full overflow-y-auto p-4\"}>\n                    <div\n                        className={cx(\n                            \"grid h-full grid-cols-[minmax(max-content,12rem)_minmax(30rem,1fr)_minmax(max-content,12rem)] items-center justify-items-center gap-4\"\n                        )}>\n                        <div>\n                            <StepperPrevButton>\n                                <FontAwesomeIcon size={\"lg\"} icon={faChevronLeft} />\n                            </StepperPrevButton>\n                        </div>\n                        <div className={\"flex h-full w-full items-center justify-center\"}>\n                            <div className={cx(\"relative h-full max-h-[33rem] w-full\")}>\n                                <StepIndicator className={\"absolute top-2 right-8\"} />\n                                <StepperBody\n                                    className={cx(\n                                        \"h-full w-full rounded-lg border px-8 py-4\",\n                                        \"border-sectionborder bg-light-bg2\",\n                                        \"dark:border-dark-sectionborder dark:bg-dark-bg1\"\n                                    )}\n                                />\n                            </div>\n                        </div>\n                        <div>\n                            <StepperForwardButton>\n                                <FontAwesomeIcon size={\"lg\"} icon={faChevronRight} />\n                            </StepperForwardButton>\n                        </div>\n                    </div>\n                </div>\n            </Stepper>\n        </>\n    );\n};\n","import React from \"react\";\nimport Link from \"../reusable/Link\";\n\nconst IntroVideoPanel = () => {\n    return (\n        <div className={\"h-full overflow-y-auto px-20\"}>\n            <h2 className={\"mt-8 mb-5 text-3xl font-medium dark:text-dark-fg1\"}>Watch our quick video tour</h2>\n            <Link\n                to=\"https://www.youtube.com/watch?v=6jcKjusc7wk\"\n                target={\"_blank\"}\n                className=\"mb-4 flex flex-wrap gap-10 rounded-md border-2 border-sectionborder bg-light-bg2 p-8 hover:bg-sidebar-highlight1 md:flex-nowrap dark:border-dark-bg4 dark:bg-dark-bg0 dark:hover:bg-dark-bg6\">\n                <div className=\"min-h-[200px] w-[360px] min-w-[270px] rounded-md border-2 border-sectionborder bg-[url('https://anvil-website-static.s3.eu-west-2.amazonaws.com/anvil-editor-introduction.png')] bg-cover bg-center dark:border-dark-bg4\"></div>\n                <div className=\"shrink\">\n                    <h3 className=\"text-[16px] font-semibold text-primary\">Video Tour</h3>\n                    <p className={\"dark:text-white\"}>\n                        This quick video will introduce you to the Anvil Editor so that you can get started building\n                        your first Anvil app. The video covers:\n                    </p>\n                    <ul className=\"list-inside list-disc marker:text-primary dark:text-white\">\n                        <li>Build your user interface</li>\n                        <li>Make it interactive</li>\n                        <li>Connect to a database</li>\n                        <li>Publish your app to the web</li>\n                    </ul>\n                </div>\n            </Link>\n        </div>\n    );\n};\n\nexport default IntroVideoPanel;\n","import * as React from \"react\";\nimport { useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport { faChevronLeft } from \"@fortawesome/pro-light-svg-icons/faChevronLeft\";\nimport { faChevronRight } from \"@fortawesome/pro-light-svg-icons/faChevronRight\";\nimport {\n    faArrowRight,\n    faArrowUpRightFromSquare,\n    faBookOpen,\n    faCircleCheck,\n    faCircleXmark,\n    faCloudArrowUp,\n    faComments,\n    faDatabase,\n    faGraduationCap,\n    faLaptop,\n    faPlay,\n    faRoad,\n    faServer,\n} from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { inRange } from \"lodash-es\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { CheckBox } from \"@/components/reusable/Forms\";\nimport Link from \"@/components/reusable/Link\";\nimport {\n    getUserRegistrationAgeDays,\n    getUserRoadmap,\n    markRoadmapStep,\n    setRoadmapStep,\n    useAbFlag,\n} from \"@/controllers/user\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useResizeObserver } from \"@/util/hooks\";\nimport { USER_AB_FLAGS } from \"@/util/hooks/ab-flags\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport ResizePanel from \"../sidebar/ResizePanel\";\n\nconst TILE_REM_SIZE = 27;\n\nconst useStyles = makeStyles()(() => ({\n    mapContainer: {\n        display: \"grid\",\n        gridTemplateColumns: `repeat(auto-fit, minmax(${TILE_REM_SIZE}rem, 1fr))`,\n        justifyContent: \"center\",\n        maxWidth: TILE_REM_SIZE * 5 + \"rem\",\n        minWidth: TILE_REM_SIZE + \"rem\",\n    },\n    mapTile: {\n        maxWidth: \"100%\",\n        minWidth: \"min-content\",\n\n        display: \"flex\",\n        position: \"relative\",\n    },\n    tileGrid: {\n        display: \"grid\",\n        width: \"100%\",\n        gridTemplateColumns: `repeat(2, 1fr)`,\n        gridTemplateRows: `repeat(2, minmax(3.65rem, 1fr))`,\n    },\n}));\n\ninterface StepProps {\n    stepId: string;\n    icon: IconDefinition;\n    title: string;\n    Content: React.FC;\n    buttons: { link: string; display: string; icon: IconDefinition }[];\n    variant?: string;\n    completeable?: boolean;\n}\n\nconst steps: StepProps[] = [\n    {\n        stepId: \"about\",\n        icon: faRoad,\n        title: \"About the roadmap\",\n        Content() {\n            const dispatch = useDispatch<AnvilDispatch>();\n            return (\n                <>\n                    <Text>\n                        Use this roadmap to guide your learning, track your progress, and measure your Anvil knowledge.\n                        It's flexible, allowing you to build what you want at each step. When you're ready, mark a step\n                        as complete.\n                    </Text>\n                    <Text>\n                        Do you want a more structured approach to learning Anvil? Are you stuck for what to build? Then\n                        complete the roadmap while following our{\" \"}\n                        <Link\n                            className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                            target={\"_blank\"}\n                            to={\"/learn/tutorials/feedback-form?utm_source=ide:roadmap\"}>\n                            feedback form tutorial\n                        </Link>\n                        .\n                    </Text>\n                    <Button\n                        className={\"mt-4\"}\n                        iconRight={true}\n                        icon={faChevronRight}\n                        onClick={() => dispatch(setRoadmapStep(\"addComponent\"))}>\n                        First Step\n                    </Button>\n                </>\n            );\n        },\n        buttons: [\n            {\n                link: \"/learn/tutorials/feedback-form?utm_source=ide:roadmap\",\n                display: \"Tutorial: Feedback Form\",\n                icon: faArrowUpRightFromSquare,\n            },\n        ],\n    },\n    {\n        stepId: \"addComponent\",\n        icon: faLaptop,\n        title: \"Add a component\",\n        Content: () => (\n            <>\n                <Text>\n                    Components are the things you add to your{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/ui/components/forms?utm_source=ide:roadmap\"}>\n                        Form\n                    </Link>{\" \"}\n                    to build your UI. These include{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/client/components/basic?utm_source=ide:roadmap#button\"}>\n                        Buttons\n                    </Link>\n                    ,{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/client/components/basic?utm_source=ide:roadmap#label\"}>\n                        Labels\n                    </Link>\n                    ,{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/client/components/basic?utm_source=ide:roadmap#textbox\"}>\n                        TextBoxes\n                    </Link>{\" \"}\n                    and other useful components.\n                </Text>\n                <Text>\n                    You can drag them from the{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/editor/form-editor?utm_source=ide:roadmap#toolbox\"}>\n                        Toolbox\n                    </Link>{\" \"}\n                    in the top right of the editor into the design view of your{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/ui/components/forms?utm_source=ide:roadmap\"}>\n                        Form\n                    </Link>\n                    .\n                </Text>\n            </>\n        ),\n        buttons: [\n            {\n                link: \"/learn/tutorials/feedback-form/chapter-1?utm_source=ide:roadmap#step-2\",\n                display: \"Tutorial: Feedback Form - Adding a component\",\n                icon: faArrowUpRightFromSquare,\n            },\n        ],\n        variant: \"primary\",\n        completeable: true,\n    },\n    {\n        stepId: \"styleComponent\",\n        icon: faLaptop,\n        title: \"Style a component\",\n        Content: () => (\n            <>\n                <Text>Click on a component to select it. You’ll see it outlined in the Form Editor.</Text>\n                <Text>\n                    Use the{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/editor/form-editor?utm_source=ide:roadmap#properties-panel\"}>\n                        Properties Panel\n                    </Link>{\" \"}\n                    on the right to change properties of the selected component. For example, changing a Button’s text\n                    property changes the text on the button.\n                </Text>\n            </>\n        ),\n        buttons: [\n            {\n                link: \"/learn/tutorials/feedback-form/chapter-1?utm_source=ide:roadmap#step-3\",\n                display: \"Tutorial: Feedback Form - Style a component\",\n                icon: faArrowUpRightFromSquare,\n            },\n        ],\n        variant: \"primary\",\n        completeable: true,\n    },\n    {\n        stepId: \"renameComponent\",\n        icon: faLaptop,\n        title: \"Rename a component\",\n        Content: () => (\n            <>\n                <Text>\n                    Select the component you want to rename. Then, use the{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/editor?utm_source=ide:roadmap#properties-panel\"}>\n                        Properties Panel\n                    </Link>{\" \"}\n                    on the right to change the components name. This will be the name you use to interact with the\n                    component in code.\n                </Text>\n            </>\n        ),\n        buttons: [\n            {\n                link: \"/learn/tutorials/feedback-form/chapter-1?utm_source=ide:roadmap#step-5\",\n                display: \"Tutorial: Feedback Form - Rename a component\",\n                icon: faArrowUpRightFromSquare,\n            },\n        ],\n        variant: \"primary\",\n        completeable: true,\n    },\n    {\n        stepId: \"clientSideCode\",\n        icon: faLaptop,\n        title: \"Write client-side code\",\n        Content: () => (\n            <>\n                <Text>\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/client?utm_source=ide:roadmap\"}>\n                        Client-side code\n                    </Link>{\" \"}\n                    interacts with your user interface by manipulating the Python objects that represent components.\n                </Text>\n                <pre className={\"m-4 select-all\"}>\n                    {`@handle(\"button_1\", \"click\")\ndef button_1_click(self, **event_args):\n    \"\"\"This method is called when the button is clicked\"\"\"\n    pass  # Write Code Here`}\n                </pre>\n                <Text>\n                    Why not start by using a{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/ui?utm_source=ide:roadmap#component-events\"}>\n                        component event\n                    </Link>{\" \"}\n                    to call a client-side function?\n                </Text>\n            </>\n        ),\n        buttons: [\n            {\n                link: \"/learn/tutorials/feedback-form/chapter-4?utm_source=ide:roadmap\",\n                display: \"Tutorial: Feedback Form - Write client-side Python\",\n                icon: faArrowUpRightFromSquare,\n            },\n        ],\n        variant: \"primary\",\n        completeable: true,\n    },\n    {\n        stepId: \"runApp\",\n        icon: faPlay,\n        title: \"Run an app\",\n        Content: () => (\n            <>\n                <Text>Time to Run your app and try it out! Click the ‘Run’ button at the top of the screen.</Text>\n                <Text>\n                    The Run Button runs the app in a development environment and brings up the{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/editor?utm_source=ide:roadmap#app-console\"}>\n                        App Console\n                    </Link>\n                    . Clicking the three dots menu gives you the option to run the app in split view or in a new window.\n                </Text>\n            </>\n        ),\n        buttons: [\n            {\n                link: \"/learn/tutorials/feedback-form/chapter-4?utm_source=ide:roadmap#step-6\",\n                display: \"Tutorial: Feedback Form - Run your app\",\n                icon: faArrowUpRightFromSquare,\n            },\n        ],\n        variant: \"highlight\",\n        completeable: true,\n    },\n    {\n        stepId: \"serverFunction\",\n        icon: faServer,\n        title: \"Define a server function\",\n        Content: () => (\n            <>\n                <Text>\n                    You can call functions in{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/server?utm_source=ide:roadmap#server-modules\"}>\n                        server modules\n                    </Link>{\" \"}\n                    from your client-side code. To make a server function available from your client code, decorate it\n                    as ‘@anvil.server.callable’.\n                </Text>\n                <pre className={\"m-4 select-all\"}>\n                    {`@anvil.server.call\ndef say_hello(name):\n    print(f”Hello from the server, {name}”)`}\n                </pre>\n                <Text>\n                    To understand why we run code in two different places, check out our guide on{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/articles/client-vs-server?utm_source=ide:roadmap\"}>\n                        Client vs Server Code\n                    </Link>\n                    .\n                </Text>\n            </>\n        ),\n        buttons: [\n            {\n                link: \"/learn/tutorials/feedback-form/chapter-3?utm_source=ide:roadmap\",\n                display: \"Tutorial: Feedback Form - Write server-side Python\",\n                icon: faArrowUpRightFromSquare,\n            },\n        ],\n        variant: \"secondary\",\n        completeable: true,\n    },\n    {\n        stepId: \"appLogs\",\n        icon: faServer,\n        title: \"Print to app logs\",\n        Content: () => (\n            <>\n                <Text>\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/editor/app-logs?utm_source=ide:roadmap#app-logs\"}>\n                        App logs\n                    </Link>{\" \"}\n                    are very useful for debugging, app optimisation and auditing. You can find your App Logs in the\n                    Sidebar Menu\n                </Text>\n                <Text>\n                    Every app session starts a new entry in the{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/editor/app-logs?utm_source=ide:roadmap#app-logs\"}>\n                        App logs\n                    </Link>\n                    , and{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/client/error-reporting?utm_source=ide:roadmap\"}>\n                        Exceptions\n                    </Link>{\" \"}\n                    are also recorded there.\n                </Text>\n            </>\n        ),\n        buttons: [\n            {\n                link: \"/docs/editor/app-logs?utm_source=ide:roadmap#app-logs\",\n                display: \"Documentation: App Logs\",\n                icon: faArrowUpRightFromSquare,\n            },\n        ],\n        variant: \"secondary\",\n        completeable: true,\n    },\n    {\n        stepId: \"addDataTable\",\n        icon: faDatabase,\n        title: \"Add a data table\",\n        Content: () => (\n            <>\n                <Text>\n                    Every Anvil app comes with a{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/data-tables?utm_source=ide:roadmap\"}>\n                        built-in database\n                    </Link>\n                    . If you’re not familiar with databases, it’s similar to a spreadsheet - data is stored in tables\n                    with rows and columns.\n                </Text>\n                <Text>\n                    Open the Data tab from the{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/editor?utm_source=ide:roadmap#sidebar-menu\"}>\n                        Sidebar Menu\n                    </Link>{\" \"}\n                    to begin adding data tables.\n                </Text>\n            </>\n        ),\n        buttons: [\n            {\n                link: \"/learn/tutorials/feedback-form/chapter-2?utm_source=ide:roadmap#step-2\",\n                display: \"Tutorial: Feedback Form - Set up your table\",\n                icon: faArrowUpRightFromSquare,\n            },\n        ],\n        variant: \"tertiary\",\n        completeable: true,\n    },\n    {\n        stepId: \"dataTableInCode\",\n        icon: faServer,\n        title: \"Use a data table in code\",\n        Content: () => (\n            <>\n                <Text>\n                    Now you have a data table, it’s time to start{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/data-tables/data-tables-in-code?utm_source=ide:roadmap\"}>\n                        using it in code\n                    </Link>\n                    . In a server module, start typing `app_tables.` and the autocompleter will show you the table names\n                    from your database. Pick a table and then see what functions are available.\n                </Text>\n                <pre className={\"m-4 select-all\"}>\n                    {`from anvil.works import app_tables\n\napp_tables.people.add_row(\n    name=\"Jane Smith\",\n    age=7, \n    employed=False\n)`}\n                </pre>\n            </>\n        ),\n        buttons: [\n            {\n                link: \"/learn/tutorials/feedback-form/chapter-3?utm_source=ide:roadmap#step-2\",\n                display: \"Tutorial: Feedback Form - Store data using a server function\",\n                icon: faArrowUpRightFromSquare,\n            },\n        ],\n        variant: \"secondary\",\n        completeable: true,\n    },\n    {\n        stepId: \"publish\",\n        icon: faCloudArrowUp,\n        title: \"Publish an app\",\n        Content: () => (\n            <>\n                <Text>\n                    You’ve covered the fundamentals of web apps with Anvil - UIs, client-side code, testing your app,\n                    server-side code and databases. All that’s left to do is use{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"/docs/deployment/environments?utm_source=ide:roadmap\"}>\n                        Anvil’s two click deployment\n                    </Link>{\" \"}\n                    to publish it on the internet for the world to see!\n                </Text>\n            </>\n        ),\n        buttons: [\n            {\n                link: \"/learn/tutorials/feedback-form/chapter-4?utm_source=ide:roadmap#step-4\",\n                display: \"Tutorial: Feedback Form - Publish your app\",\n                icon: faArrowUpRightFromSquare,\n            },\n        ],\n        variant: \"highlight\",\n        completeable: true,\n    },\n    {\n        stepId: \"whatNext\",\n        icon: faRoad,\n        title: \"What's Next\",\n        Content: () => (\n            <>\n                <Text>\n                    Congratulations on reaching this milestone! Now it's time to embark on the next phase of your Anvil\n                    journey. Here are some exciting ways to explore Anvil further:\n                </Text>\n                <ul className={\"list-decimal\"}>\n                    <li className={\"ml-12 pl-4\"}>\n                        <b>Build Something Cool:</b> Unleash your creativity and build remarkable apps with Anvil.\n                    </li>\n                    <li className={\"ml-12 pl-4\"}>\n                        <b>Explore Feature Tutorials:</b> Dive into our{\" \"}\n                        <Link\n                            className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                            target={\"_blank\"}\n                            to={\"/learn/tutorials?utm_source=ide:roadmap\"}>\n                            extensive tutorials\n                        </Link>{\" \"}\n                        to unlock Anvil's full potential.\n                    </li>\n                    <li className={\"ml-12 pl-4\"}>\n                        <b>Join Our Community:</b> Connect with like-minded developers in one of our{\" \"}\n                        <Link\n                            className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                            target={\"_blank\"}\n                            to={\"/community?utm_source=ide:roadmap\"}>\n                            community spaces\n                        </Link>\n                        .\n                    </li>\n                </ul>\n                <Text>\n                    If you have any questions, feel free to join our{\" \"}\n                    <Link\n                        className={\"text-primary underline hover:text-primary-300! dark:hover:text-primary-600!\"}\n                        target={\"_blank\"}\n                        to={\"https://anvil.works/forum\"}>\n                        community forum\n                    </Link>{\" \"}\n                    and ask away!\n                </Text>\n            </>\n        ),\n        buttons: [\n            { link: \"/learn/tutorials?utm_source=ide:roadmap\", display: \"Tutorials\", icon: faGraduationCap },\n            { link: \"/docs/overview?utm_source=ide:roadmap\", display: \"Documentation\", icon: faBookOpen },\n        ],\n    },\n];\n\nexport function useRoadmapAbFlag() {\n    const userRegisteredForDays = useSelector(getUserRegistrationAgeDays);\n    return useAbFlag(\n        USER_AB_FLAGS.getStartedRoadmap,\n        typeof userRegisteredForDays === \"number\" && userRegisteredForDays < 1 ? [false, true] : []\n    );\n}\n\nconst RoadmapPanel = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const roadmap = useSelector(getUserRoadmap);\n    const contentContainerRef = useRef<HTMLDivElement>(null!);\n    const [width, setWidth] = useState<number | null>(null);\n    useLayoutEffect(() => {\n        if (width === null) {\n            setWidth(contentContainerRef?.current?.offsetWidth / 2);\n        }\n    }, [contentContainerRef?.current?.offsetWidth]);\n\n    const [currentStep, stepNumber, hasNext, hasPrev] = useMemo(() => {\n        const currentStep = roadmap?.currentStep || \"about\";\n        const i = steps.findIndex((step) => step.stepId === currentStep);\n        const hasNext = i < steps.length - 1;\n        const hasPrev = i > 0;\n        return [currentStep, i, hasNext, hasPrev];\n    }, [roadmap?.currentStep]);\n\n    const updateStep = useEvent((newStep: string) => {\n        dispatch(setRoadmapStep(newStep));\n    });\n\n    const changeStep = useEvent((goBack = false) => {\n        const i = steps.findIndex((step) => step.stepId === currentStep);\n        const stepId = steps[goBack ? i - 1 : i + 1].stepId;\n        updateStep(stepId);\n    });\n\n    return (\n        <div className={\"flex h-full flex-col overflow-hidden\"}>\n            <div ref={contentContainerRef} className={cx(\"flex-auto\", \"flex overflow-hidden\")}>\n                <div\n                    className={cx(\n                        \"mx-auto my-0 w-full overflow-auto border-r border-sectionborder dark:border-dark-sectionborder\"\n                    )}>\n                    <div className={\"flex justify-center px-12 pt-4\"}>\n                        <Roadmap completedSteps={Object.keys(roadmap?.completed || {})} currentStep={currentStep} />\n                    </div>\n                </div>\n                <ResizePanel\n                    style={{ overflow: \"auto\" }}\n                    horizontal={true}\n                    panelSize={width || 200}\n                    handleAtStart={true}\n                    onFinishDrag={(s) => setWidth(s)}>\n                    <StepCard step={steps[stepNumber]} completedSteps={roadmap?.completed} />\n                </ResizePanel>\n            </div>\n            <div\n                className={cx(\n                    \"flex-none\",\n                    \"flex w-full items-center justify-between border-t border-t-sectionborder bg-light-bg2 p-2 dark:border-t-dark-sectionborder dark:bg-dark-bg1\"\n                )}>\n                <Button disabled={!hasPrev} icon={faChevronLeft} size={\"small\"} onClick={() => changeStep(true)}>\n                    Previous Step\n                </Button>\n                <div className={\"font-medium\"}>\n                    {stepNumber + 1}/{steps.length}\n                </div>\n                <Button\n                    disabled={!hasNext}\n                    iconRight={true}\n                    icon={faChevronRight}\n                    size={\"small\"}\n                    onClick={() => changeStep()}>\n                    Next Step\n                </Button>\n            </div>\n        </div>\n    );\n};\n\nexport default RoadmapPanel;\n\ninterface StepCardProps {\n    step: StepProps;\n    completedSteps?: { [key: string]: string };\n}\n\nconst StepCard = ({ step, completedSteps }: StepCardProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const toggleCompleted = useEvent(() => {\n        const alreadyMarked = completedSteps?.[step.stepId];\n        dispatch(markRoadmapStep(step.stepId, !alreadyMarked));\n    });\n\n    const StepContent = step.Content;\n\n    return (\n        <div className={\"flex h-full min-w-120 flex-col px-14 py-8\"}>\n            <div className={\"flex flex-none justify-between\"}>\n                <div className={\"flex items-center justify-center\"}>\n                    <FontAwesomeIcon className={cx(`text-${step.variant}`, \"mr-9 text-4xl\")} icon={step.icon} />\n                    <Heading className={\"m-0!\"} level={1}>\n                        {step.title}\n                    </Heading>\n                </div>\n                <div>\n                    {!!step.completeable && (\n                        <CheckBox checked={!!completedSteps?.[step.stepId]} onChange={toggleCompleted}>\n                            Completed\n                        </CheckBox>\n                    )}\n                </div>\n            </div>\n            <div className={\"flex-auto\"}>\n                <StepContent />\n            </div>\n            <div className={\"flex-none\"}>\n                {step.buttons.map(({ link, display, icon }, ind) => (\n                    <Button\n                        key={ind}\n                        className={\"mr-4\"}\n                        onClick={() => {\n                            window.open(link, \"_blank\");\n                        }}\n                        iconRight\n                        icon={icon}\n                        size={\"small\"}>\n                        {display}\n                    </Button>\n                ))}\n                <Button\n                    iconRight\n                    onClick={() => {\n                        window.open(\"https://anvil.works/forum\", \"_blank\");\n                    }}\n                    icon={faComments}\n                    size={\"small\"}>\n                    Ask for help\n                </Button>\n            </div>\n        </div>\n    );\n};\n\ninterface RoadmapProps {\n    completedSteps: string[];\n    currentStep: string;\n}\n\nconst Roadmap = ({ completedSteps, currentStep }: RoadmapProps) => {\n    const { classes } = useStyles();\n\n    const mapContainerRef = useRef<HTMLInputElement>(null!);\n\n    const [gridColCount, setGridColCount] = useState(3);\n    const [gridRowCount, setGridRowCount] = useState(1);\n\n    const setGridCounts = useEvent(() => {\n        const gridComputedStyle = getComputedStyle(mapContainerRef?.current);\n        setGridColCount(gridComputedStyle.getPropertyValue(\"grid-template-columns\").split(\" \").length);\n        setGridRowCount(gridComputedStyle.getPropertyValue(\"grid-template-rows\").split(\" \").length);\n    });\n\n    useResizeObserver(mapContainerRef, setGridCounts);\n\n    return (\n        <div ref={mapContainerRef} className={cx(\"w-full\", classes.mapContainer)}>\n            {steps.map((step, ind) => {\n                return (\n                    <RoadmapTile\n                        key={ind}\n                        stepInd={ind}\n                        step={step}\n                        isCurrentStep={currentStep === step.stepId}\n                        completed={completedSteps?.includes(step.stepId)}\n                        gridColCount={gridColCount}\n                        gridRowCount={gridRowCount}\n                    />\n                );\n            })}\n        </div>\n    );\n};\n\ninterface RoadmapTileProps {\n    stepInd: number;\n    step: StepProps;\n    completed: boolean;\n    isCurrentStep: boolean;\n    gridColCount: number;\n    gridRowCount: number;\n}\n\nconst RoadmapTile = ({ stepInd, step, completed, isCurrentStep, gridColCount, gridRowCount }: RoadmapTileProps) => {\n    const { classes } = useStyles();\n\n    const [first, last, singleColumn, firstCol, lastCol, firstRow, lastRow, middle] = useMemo(() => {\n        const singleColumn = gridColCount === 1;\n        const last = stepInd === steps.length - 1;\n        const firstCol = !singleColumn && stepInd % gridColCount === 0;\n        const lastCol = !singleColumn && stepInd % gridColCount === gridColCount - 1;\n        const firstRow = !singleColumn && inRange(stepInd, 0, gridColCount);\n        const lastRow =\n            !singleColumn && inRange(stepInd, (gridRowCount - 1) * gridColCount, gridRowCount * gridColCount);\n        return [\n            stepInd === 0,\n            last,\n            singleColumn,\n            firstCol,\n            lastCol,\n            firstRow,\n            lastRow,\n            !firstCol && !lastCol && !firstRow && !lastRow && !last && !singleColumn,\n        ];\n    }, [stepInd, gridColCount, gridRowCount]);\n\n    return (\n        <div className={cx(classes.mapTile)}>\n            <div className={cx(classes.tileGrid)}>\n                <div\n                    className={cx(\n                        { \"border-l-4 border-l-[#617A83] dark:border-l-dark-fg1\": firstCol && !first },\n                        { \"border-r-4 border-r-[#617A83] dark:border-r-dark-fg1\": singleColumn && !first },\n                        {\n                            \"border-b-4 border-b-[#617A83] dark:border-b-dark-fg1\":\n                                (firstCol && !first) || (!first && !singleColumn),\n                        }\n                    )}\n                />\n                <div\n                    className={cx({\n                        \"border-b-4 border-b-[#617A83] dark:border-b-dark-fg1\":\n                            (lastCol && !last) || firstCol || (!last && !singleColumn),\n                    })}\n                />\n                <div\n                    className={cx(\n                        { \"border-r-4 border-r-[#617A83] dark:border-r-dark-fg1\": singleColumn && !last },\n                        {\n                            \"border-b-4 border-b-[#617A83] dark:border-b-dark-fg1\":\n                                (lastCol && !last) ||\n                                middle ||\n                                (firstCol && !lastRow) ||\n                                (!lastRow && !last && !singleColumn),\n                        }\n                    )}\n                />\n                <div\n                    className={cx(\n                        { \"border-r-4 border-r-[#617A83] dark:border-r-dark-fg1\": lastCol && !last },\n                        {\n                            \"border-b-4 border-b-[#617A83] dark:border-b-dark-fg1\":\n                                (lastCol && !last) || middle || (!lastRow && !last && !singleColumn),\n                        }\n                    )}\n                />\n            </div>\n            <div className={cx(\"absolute flex w-full items-center justify-center self-center\")}>\n                <RoadmapCard\n                    step={step}\n                    completed={completed}\n                    singleColumn={singleColumn}\n                    isCurrentStep={isCurrentStep}\n                />\n            </div>\n        </div>\n    );\n};\n\ninterface RoadmapCardProps {\n    step: StepProps;\n    completed: boolean;\n    isCurrentStep: boolean;\n    singleColumn: boolean;\n}\nconst RoadmapCard = ({ step, completed, singleColumn, isCurrentStep }: RoadmapCardProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const statusIndicator = useMemo(() => {\n        return (\n            <div\n                className={cx(\n                    \"rounded-full ring-1 ring-[#617A83] ring-offset-1 ring-offset-transparent dark:ring-[#CFDBDC]\",\n                    \"mt-[0.1rem] mr-4 h-[2.2rem] w-[2.2rem] shrink-0 grow-0\",\n                    \"flex items-center justify-center\"\n                )}>\n                <FontAwesomeIcon\n                    className={completed ? \"text-highlight\" : \"text-secondary\"}\n                    icon={completed ? faCircleCheck : faCircleXmark}\n                />\n            </div>\n        );\n    }, [completed]);\n\n    const tileStyle = useMemo(() => {\n        if (!isCurrentStep) {\n            return \"hover:dark:border hover:dark:py-[0.6rem] hover:dark:border-dark-sectionborder! w-3/4 max-w-100\";\n        }\n        switch (step.variant) {\n            case \"primary\":\n                return \"h-[4.6rem] pt-2 text-2xl font-semibold border-primary hover:dark:border-primary-darkmap hover:dark:bg-[#4E4E4E]! w-11/12 max-w-md\";\n            case \"secondary\":\n                return \"h-[4.6rem] pt-2 text-2xl font-semibold border-secondary hover:dark:border-secondary-darkmap hover:dark:bg-[#4E4E4E]! w-11/12 max-w-md\";\n            case \"tertiary\":\n                return \"h-[4.6rem] pt-2 text-2xl font-semibold border-tertiary hover:dark:border-tertiary-darkmap hover:dark:bg-[#4E4E4E]! w-11/12 max-w-md\";\n            case \"highlight\":\n                return \"h-[4.6rem] pt-2 text-2xl font-semibold border-highlight hover:dark:border-highlight-darkmap hover:dark:bg-[#4E4E4E]! w-11/12 max-w-md\";\n            default:\n                return \"h-[4.6rem] pt-2 text-2xl font-semibold border-sectionborder hover:dark:border-dark-sectionborder! w-11/12 max-w-md\";\n        }\n    }, [isCurrentStep, step?.variant]);\n\n    switch (step.stepId) {\n        case \"about\": {\n            return (\n                <div\n                    className={cx(\n                        \"flex cursor-pointer items-center justify-center gap-3 rounded-lg bg-light-bg0 px-4 py-1 underline decoration-primary decoration-[0.2rem] underline-offset-[0.4rem] dark:bg-dark-bg2\",\n                        \"hover:text-[#627B84] hover:dark:text-[#999999]\"\n                    )}\n                    onClick={() => dispatch(setRoadmapStep(step.stepId))}>\n                    <span className={\"text-3xl font-semibold whitespace-nowrap\"}>Start here</span>\n                    {!singleColumn && <FontAwesomeIcon icon={faArrowRight} />}\n                </div>\n            );\n        }\n        case \"whatNext\": {\n            return (\n                <div\n                    className={cx(\n                        \"flex cursor-pointer items-center justify-center gap-3 rounded-lg bg-light-bg0 px-4 py-1 underline decoration-primary decoration-[0.2rem] underline-offset-[0.4rem] dark:bg-dark-bg2\",\n                        \"hover:text-[#627B84] hover:dark:text-[#999999]\"\n                    )}\n                    onClick={() => dispatch(setRoadmapStep(step.stepId))}>\n                    <span className={\"text-3xl font-semibold whitespace-nowrap\"}>What's next?</span>\n                </div>\n            );\n        }\n        default:\n            return (\n                <div\n                    className={cx(\n                        \"hover:dark:drop-shadow-unset hover:drop-shadow-md\",\n                        \"overflow-hidden border-y-[0.6rem] border-t-transparent border-b-transparent! bg-[#E1F2FA] font-semibold dark:bg-[#3D3D3D] dark:text-[#CFDBDC]\",\n                        \"flex cursor-pointer flex-nowrap items-center justify-between rounded-lg py-[0.15rem]\",\n                        tileStyle,\n                        \"active:bg-light-bg4 active:dark:bg-dark-bg3\"\n                    )}\n                    onClick={() => dispatch(setRoadmapStep(step.stepId))}>\n                    <div className={cx(\"flex min-w-0 grow flex-nowrap items-center justify-center px-4\")}>\n                        <FontAwesomeIcon icon={step?.icon} />\n                        <div className={\"ml-2 truncate\"}>{step.title}</div>\n                    </div>\n                    {(isCurrentStep || completed) && statusIndicator}\n                </div>\n            );\n    }\n};\n","import React, { useCallback, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faLevelDownAlt } from \"@fortawesome/free-solid-svg-icons/faLevelDownAlt\";\nimport { faPlay, faStop } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faTrashAlt } from \"@fortawesome/pro-regular-svg-icons/faTrashAlt\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { clearScriptOutput, getScriptRuns, killScript, runScript } from \"@/controllers/scripts\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { AnvilDispatch, ScriptRun } from \"@/types\";\nimport { LogEvent, compressEvent } from \"../tabs/sessions/SessionLogs\";\n\nconst useStyles = makeStyles()((theme) => ({\n    root: {\n        height: \"100%\",\n        display: \"flex\",\n        flexDirection: \"column\",\n    },\n    buttons: {\n        display: \"flex\",\n        justifyContent: \"flex-start\",\n        left: \"1.5rem\",\n    },\n    outputOuter: {\n        flex: \"1 0 auto\",\n        position: \"relative\",\n    },\n    outputInner: {\n        position: \"absolute\",\n        left: 0,\n        top: 0,\n        bottom: 0,\n        right: 0,\n    },\n}));\n\ninterface ScriptOutputTabProps {\n    scriptName: string;\n    classes?: any;\n}\n\nconst BLANK_SESSION = {};\n\n// This is an approximate copy of the py.space OutputScroller in Footer.tsx.\nconst OutputScroller = ({ scriptRuns, autoScroll }: { scriptRuns: ScriptRun[]; autoScroll: boolean }) => {\n    const outputScroller = useRef<HTMLDivElement>(null);\n\n    useLayoutEffect(() => {\n        if (outputScroller.current && autoScroll) {\n            outputScroller.current.scrollTop = outputScroller.current.scrollHeight;\n        }\n    }, [scriptRuns, autoScroll]);\n\n    let dropNextNewline = false; // Ick.\n\n    return (\n        <div ref={outputScroller} className={cx(\"h-full overflow-auto\")}>\n            <div className={\"p-2 font-mono text-[16px] whitespace-pre\"}>\n                {scriptRuns?.map((scriptRun, idx) => (\n                    <React.Fragment key={scriptRun.sessionId ?? idx}>\n                        {idx > 0 && <hr />}\n                        {scriptRun?.output?.map((event, idx) => {\n                            const evt = compressEvent(event);\n                            if (dropNextNewline && event.log_text === \"\\n\") {\n                                dropNextNewline = false;\n                                return null;\n                            }\n                            if (event.log_text !== \"\\n\") {\n                                dropNextNewline = true;\n                            }\n                            return (\n                                <React.Fragment key={idx}>\n                                    {idx === 0 && !scriptRun.outputCleared && (\n                                        <LogEvent\n                                            event={{ tp: \"session_started\", tm: event.timestamp }}\n                                            session={scriptRun.session || BLANK_SESSION}\n                                            isOpen\n                                        />\n                                    )}\n                                    <LogEvent\n                                        event={evt}\n                                        key={event.timestamp}\n                                        session={scriptRun.session || BLANK_SESSION}\n                                        isOpen\n                                    />\n                                </React.Fragment>\n                            );\n                        })}\n                    </React.Fragment>\n                ))}\n            </div>\n        </div>\n    );\n};\n\nconst ScriptOutputTab = ({ scriptName, classes }: ScriptOutputTabProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const scriptRuns = useSelector(getScriptRuns);\n    const runs = scriptRuns[scriptName];\n    ({ classes } = useStyles(undefined, { props: { classes } }));\n\n    const [autoScroll, setAutoScroll] = useState(true);\n\n    const isRunning = useMemo(() => runs?.some(({ state }) => state !== \"TERMINATED\"), [runs]);\n    const [launching, setLaunching] = useState<Record<string, boolean>>({});\n\n    const doRun = useCallback(async () => {\n        setLaunching((s) => ({ ...s, [scriptName]: true }));\n        await dispatch(runScript(scriptName));\n        setLaunching((s) => ({ ...s, [scriptName]: false }));\n    }, [scriptName]);\n\n    const doKill = useCallback(async () => {\n        await dispatch(killScript(scriptName));\n    }, [scriptName]);\n\n    const clearOutput = useCallback(async () => {\n        await dispatch(clearScriptOutput(scriptName));\n    }, [scriptName]);\n\n    const [autoScrollToolTip, autoScrollAnchorRef] = useTooltip(\"Toggle output auto-scroll\", \"top-right\");\n    const [runToolTip, runAnchorRef] = useTooltip(`Run ${scriptName}`, \"top-right\");\n    const [stopToolTip, stopAnchorRef] = useTooltip(`Stop ${scriptName}`, \"top-right\");\n    const [clearToolTip, clearAnchorRef] = useTooltip(`Clear output`, \"top-right\");\n\n    return (\n        <div className={classes.root}>\n            <div className=\"flex h-[38px] items-center justify-between border-b border-sectionborder px-4 py-2 dark:border-dark-sectionborder\">\n                <div className=\"flex h-full items-center gap-4 self-start\">\n                    {isRunning ? (\n                        <Button\n                            small\n                            variant={\"tertiary\"}\n                            ref={stopAnchorRef}\n                            // className=\"inline-flex w-8 justify-center hover:text-light-fg1/80 dark:hover:text-dark-fg1/80\"\n                            onClick={doKill}>\n                            {stopToolTip}\n                            <FontAwesomeIcon icon={faStop} />\n                        </Button>\n                    ) : (\n                        <Button\n                            small\n                            disabled={launching[scriptName]}\n                            variant={\"highlight1\"}\n                            ref={runAnchorRef}\n                            // className=\"inline-flex w-8 justify-center hover:text-light-fg1/80 dark:hover:text-dark-fg1/80\"\n                            onClick={doRun}>\n                            {runToolTip}\n                            <FontAwesomeIcon icon={faPlay} />\n                        </Button>\n                    )}\n                    <LinkInternal\n                        ref={autoScrollAnchorRef}\n                        className={cx(\n                            \"inline-flex w-8 justify-center hover:text-light-fg1/80 dark:hover:text-dark-fg1/80\",\n                            autoScroll && \"text-primary\"\n                        )}\n                        onClick={() => setAutoScroll(!autoScroll)}>\n                        {autoScrollToolTip}\n                        <FontAwesomeIcon icon={faLevelDownAlt} />\n                    </LinkInternal>\n                    <LinkInternal\n                        ref={clearAnchorRef}\n                        className={cx(\"inline-flex w-8 justify-center hover:text-tertiary dark:hover:text-tertiary\")}\n                        onClick={clearOutput}>\n                        {clearToolTip}\n                        <FontAwesomeIcon icon={faTrashAlt} />\n                    </LinkInternal>\n                </div>\n            </div>\n            <div className={classes.outputOuter}>\n                <div className={classes.outputInner}>\n                    <OutputScroller scriptRuns={runs} autoScroll={autoScroll} />\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport default ScriptOutputTab;\n","import React from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faTrashCan } from \"@fortawesome/pro-regular-svg-icons/faTrashCan\";\nimport { faXmark } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { closeBottomTab } from \"@/controllers/bottom-tabs\";\nimport { clearBreakpoints, getDebugEnvBreakpoints, setBreakpoints } from \"@/controllers/debugger\";\nimport { navigate } from \"@/router/navigation\";\nimport { AnvilDispatch, CodePath } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { Button } from \"../reusable/Button\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\n\ninterface BreakpointModuleProps {\n    codePath: string;\n    moduleBreaks: { breaks: { l: number }[]; module: string };\n}\n\nconst BreakpointModule = ({ codePath, moduleBreaks }: BreakpointModuleProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { breaks, module: moduleName } = moduleBreaks;\n\n    const handleBreakpointClick = (codePath: string, line: number) => {\n        dispatch(navigate({ type: \"CODE\", codePath: codePath as CodePath, view: { code: [`${line}`] } }));\n    };\n\n    const handleBreakpointDelete = (codePath: string, line: number) => {\n        dispatch(\n            setBreakpoints(\n                codePath,\n                moduleBreaks.breaks.filter((b) => b.l !== line).map((b) => b.l)\n            )\n        );\n    };\n\n    return (\n        <div className={\"border-b border-sectionborder p-4 dark:border-dark-sectionborder\"}>\n            <LinkInternal\n                className=\"font-semibold hover:text-light-fg1/80 dark:hover:text-dark-fg1/80\"\n                onClick={() => handleBreakpointClick(codePath, breaks[0]?.l ?? 1)}>\n                {moduleName}\n            </LinkInternal>\n            <ul className={\"mt-2\"}>\n                {breaks.map((b) => (\n                    <li key={b.l} className={\"flex items-center gap-2 py-1\"}>\n                        <Button small variant={\"hidden\"} onClick={() => handleBreakpointDelete(codePath, b.l)}>\n                            <FontAwesomeIcon icon={faXmark} />\n                        </Button>\n                        <LinkInternal\n                            className={\n                                \"flex grow items-center gap-2 rounded-md px-2 font-mono hover:bg-[#c0e0ff2e] hover:text-light-fg1/80 dark:hover:text-dark-fg1/80\"\n                            }\n                            onClick={() => handleBreakpointClick(codePath, b.l)}>\n                            <div className={\"h-4 w-4 rounded-full bg-[#E45765]\"}></div>\n                            Line {b.l}\n                        </LinkInternal>\n                    </li>\n                ))}\n            </ul>\n        </div>\n    );\n};\n\nconst BreakpointsToolbar = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const onClearAllBreakpoints = useEvent(() => {\n        dispatch(clearBreakpoints());\n    });\n\n    return (\n        <div className=\"flex items-center justify-between border-b border-sectionborder px-4 py-2 dark:border-dark-sectionborder\">\n            <div className=\"flex items-center gap-4 self-start\">\n                <Button\n                    title=\"Remove all breakpoints from this app\"\n                    small\n                    icon={faTrashCan}\n                    variant={\"highlight2\"}\n                    onClick={onClearAllBreakpoints}>\n                    Remove All\n                </Button>\n            </div>\n        </div>\n    );\n};\n\nexport const Breakpoints = () => {\n    const breakpoints = useSelector(getDebugEnvBreakpoints);\n\n    return (\n        <div className={\"flex h-full w-full flex-col\"}>\n            <BreakpointsToolbar />\n            <div className={\"grow overflow-auto\"}>\n                {breakpoints &&\n                    Object.entries(breakpoints).map(([codePath, moduleBreaks]) => (\n                        <BreakpointModule key={codePath} codePath={codePath} moduleBreaks={moduleBreaks} />\n                    ))}\n            </div>\n        </div>\n    );\n};\n","import React, { type ComponentProps, type ReactNode, useEffect, useState } from \"react\";\nimport { connect, useSelector } from \"react-redux\";\nimport { faChevronDown } from \"@fortawesome/free-solid-svg-icons/faChevronDown\";\nimport { faChevronRight } from \"@fortawesome/free-solid-svg-icons/faChevronRight\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { getEditableFileType } from \"@/code_mirror/editors/asset_editor\";\nimport { DiffComponentEdit } from \"@/components/reusable/CommitDetail\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { BottomPanelContentButton } from \"@/components/reusable/SharedComponents\";\nimport { StructuralValueDiff } from \"@/components/reusable/StructuralValueDiff\";\nimport { Heading } from \"@/components/reusable/Text\";\nimport { getAppIsEditable } from \"@/controllers/app\";\nimport { openCodeItem } from \"@/controllers/app/code\";\nimport { deleteExtraFile, getExtraFileContent } from \"@/controllers/app/extra-files\";\nimport {\n    getConflictsForConflictingItem,\n    listItemsWithConflicts,\n    resolveAllConflictsForFormComponent,\n    resolveAllItemConflicts,\n    resolveConfigConflict,\n} from \"@/controllers/app/history\";\nimport type { CodeNavTarget, ExtraFileNavTarget } from \"@/router/navTypes\";\nimport { navigate } from \"@/router/navigation\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, AppPath, CodePath, Conflicts, State } from \"@/types\";\nimport { getImageMimeType } from \"@/util/image-mime-type\";\n\nconst useStyles = makeStyles()((theme) => ({\n    root: {\n        width: \"100%\",\n        height: \"100%\",\n    },\n    flex: {\n        display: \"flex\",\n        alignItems: \"center\",\n        gap: \"1rem\",\n    },\n    item: {},\n    itemOpen: {\n        backgroundColor: theme.primaryNav.background.toString(),\n    },\n    itemHeader: {\n        fontWeight: theme.accordion.header.title.fontWeight,\n        color: theme.accordion.header.title.color.toString(),\n        background: theme.accordion.header.background.toString(),\n        borderBottom: \"1px solid \" + theme.sectionBorderColor.toString(),\n        height: \"4.5rem\",\n        alignItems: \"center\",\n        cursor: \"pointer\",\n        padding: \"0 1rem\",\n        \"&:hover\": {\n            background: theme.accordion.header.hoverBg.toString(),\n        },\n        \"&:active:focus\": {\n            background: theme.accordion.header.expandedBg.toString(),\n        },\n    },\n    itemType: {},\n    conflict: {\n        //cursor: \"pointer\",\n        padding: \"0.8rem 1rem 0.8rem 3.5rem\",\n        borderBottom: \"1px solid \" + theme.sectionBorderColor.toString(),\n        minHeight: \"4rem\",\n        \"& b\": {\n            fontFamily: theme.codeFont,\n        },\n    },\n    breadcrumbs: {\n        display: \"inline-block\",\n    },\n    pathElement: {\n        display: \"inline\",\n        fontWeight: 600,\n        padding: \"0 0.4rem\",\n        fontSize: \"90%\",\n        borderRadius: \"0.6rem\",\n        backgroundColor: theme.accordion.header.background.toString(),\n        marginRight: \"0.4rem\",\n    },\n    pathSep: {\n        fontSize: \"60%\",\n        marginRight: \"0.4rem\",\n    },\n    marginLeft: {\n        marginLeft: \"1rem\",\n    },\n    m0: {\n        margin: 0,\n    },\n    ml_auto: {\n        marginLeft: \"auto\",\n    },\n}));\n\nconst APP_PATH_RE = /^([^/]*)\\/(.*)/;\n\ntype ListedConflictingItem = NonNullable<ReturnType<typeof listItemsWithConflicts>>[number];\n\ntype ConfigEditConflict = {\n    path: string[];\n    type: [string, string];\n    a_value: unknown;\n    b_value: unknown;\n};\n\ntype FormComponentChange = {\n    type: [string, string];\n    a_change?: unknown;\n    b_change?: unknown;\n    property?: unknown;\n};\n\ntype FormComponentConflict = {\n    component: string;\n    conflicts: FormComponentChange[];\n};\n\ntype ConflictingItemOwnProps = {\n    whichItem: ListedConflictingItem;\n    index: number;\n};\n\nconst connector = connect((state: State, { whichItem }: ConflictingItemOwnProps) => ({\n    conflicts: getConflictsForConflictingItem(state, whichItem),\n}));\n\ntype ConflictingItemProps = AnvilConnectedProps<typeof connector> & ConflictingItemOwnProps;\n\nconst getCodeType = (appPath: AppPath | undefined) =>\n    appPath?.[0] === \"CODE\" ? APP_PATH_RE.exec(appPath[1])?.[1] : undefined;\n\nconst breadcrumbKey = (path: string[]) => path.join(\"/\");\ntype DiffComponentEditProps = ComponentProps<typeof DiffComponentEdit>;\n\nlet ConflictingItem = ({\n    whichItem: { appPath, conflictItem: conflictItemSpec },\n    index,\n    conflicts,\n    dispatch,\n}: ConflictingItemProps) => {\n    const [isOpen, setOpen] = useState(index === 0); // open the first conflict by default\n    const { classes } = useStyles();\n    const [itemType, itemId] = conflictItemSpec;\n    const editable = useSelector(getAppIsEditable);\n    const extraFileContent = useSelector((state: State) =>\n        itemType === \"extra_files\" && typeof itemId === \"string\" ? getExtraFileContent(state, itemId) : undefined\n    );\n    const canEditExtraFile =\n        typeof itemId === \"string\" &&\n        (itemId.toLowerCase().endsWith(\".py\") || !!getEditableFileType(itemId.toLowerCase()));\n    const wholeFileConflict =\n        itemType === \"extra_files\" &&\n        (!!conflicts?.binary ||\n            (extraFileContent !== undefined &&\n                typeof itemId === \"string\" &&\n                (!!getImageMimeType(itemId) || !canEditExtraFile)));\n\n    const nameA = \"Version A\",\n        nameB = \"Version B\"; // TODO be clever about these (name people or branches)\n\n    const codeType = getCodeType(appPath);\n    const codePath = appPath?.[0] === \"CODE\" ? appPath[1] : undefined;\n\n    const lineStart = conflicts?.text_chunks?.[0]?.start;\n\n    const linkTarget: CodeNavTarget | ExtraFileNavTarget | undefined =\n        appPath?.[0] === \"EXTRA_FILES\"\n            ? {\n                  type: \"EXTRA_FILE\",\n                  filePath: appPath.slice(1).join(\"/\"),\n                  view: wholeFileConflict\n                      ? undefined\n                      : { code: lineStart !== undefined ? [String(lineStart + 1), \"0\"] : true },\n              }\n            : codeType && codePath\n              ? {\n                    type: \"CODE\",\n                    codePath: codePath as CodePath,\n                    view: { code: lineStart !== undefined ? [String(lineStart + 1), \"0\"] : true },\n                }\n              : undefined;\n\n    const breadcrumb = (path: string[]): ReactNode =>\n        path.map((p, idx) => (\n            <div key={`${breadcrumbKey(path)}-${idx}`} className={classes.breadcrumbs}>\n                {idx !== 0 && <FontAwesomeIcon icon={faChevronRight} className={classes.pathSep} />}\n                <div className={classes.pathElement}>{p}</div>\n            </div>\n        ));\n\n    const renderConfigConflicts = (editConflicts: ConfigEditConflict[]) => {\n        //console.log(\"Edit conflicts:\", editConflicts);\n        const irregularPastTense: Record<string, string> = { remove: \"removed\" };\n        const pastTense = (op: string) => irregularPastTense[op] || `${op}ed`;\n\n        // TODO be able to sensibly render all types of conflict\n        return editConflicts.map(({ path, type, a_value, b_value }) => (\n            <div className={classes.conflict} key={JSON.stringify(path)}>\n                <div className={classes.flex}>\n                    {breadcrumb(path)}\n                    <BottomPanelContentButton\n                        small={true}\n                        className={classes.marginLeft}\n                        variant=\"tertiary\"\n                        onClick={() => dispatch(resolveConfigConflict(conflictItemSpec, path))}>\n                        Ignore\n                    </BottomPanelContentButton>\n                </div>\n                <div>{`${nameA} ${pastTense(type[0])}; ${nameB} ${pastTense(type[1])}`}</div>\n                <div className=\"mt-1 text-[1.1rem] font-semibold\">Target branch / version you're merging</div>\n                <StructuralValueDiff from={a_value} to={b_value} />\n            </div>\n        ));\n    };\n\n    const renderCodeConflicts = (textChunks: NonNullable<Conflicts[\"text_chunks\"]>) => (\n        <div className={cx(classes.flex, classes.conflict)}>\n            Code conflicts in {textChunks.length === 1 ? \"1 place\" : `${textChunks.length} places`}\n            {linkTarget && (\n                <BottomPanelContentButton\n                    small={true}\n                    onClick={() => dispatch(navigate({ ...linkTarget, refocusView: Math.random() }))}>\n                    Open code\n                </BottomPanelContentButton>\n            )}\n        </div>\n    );\n\n    const renderComponentConflicts = (components: FormComponentConflict[]) => {\n        // console.log(\"Component conflicts: \", components);\n        const hasValueChange = (change: unknown): change is DiffComponentEditProps[\"edit\"] & { to?: unknown } =>\n            typeof change === \"object\" && change !== null && \"to\" in change;\n\n        return components.map(({ component, conflicts }) => (\n            <div key={component} className={cx(classes.conflict)}>\n                <div className={classes.flex}>\n                    {breadcrumb([component || \"(form)\"])}\n                    <BottomPanelContentButton\n                        small={true}\n                        variant=\"tertiary\"\n                        className={classes.marginLeft}\n                        onClick={() => {\n                            if (typeof itemId === \"string\") {\n                                dispatch(resolveAllConflictsForFormComponent(itemId, component));\n                            }\n                        }}>\n                        Ignore\n                    </BottomPanelContentButton>\n                </div>\n                {conflicts.map(({ type, a_change, b_change }, idx) => {\n                    const [opA, opB] = type;\n                    // TODO: Be able to sensibly render all types of conflict\n                    //let isType = (t1,t2) => opA === t1 && opB === t2;\n                    const showDirectValueDiff = hasValueChange(a_change) && hasValueChange(b_change);\n                    return (\n                        <div key={idx} className=\"space-y-1\">\n                            <b>{opA}</b> / <b>{opB}</b> conflict. Conflicting change&nbsp;\n                            {showDirectValueDiff ? (\n                                <>\n                                    <span>(target branch / version you're merging):</span>\n                                    <StructuralValueDiff from={a_change.to} to={b_change.to} />\n                                </>\n                            ) : (\n                                <>\n                                    {a_change && (\n                                        <div>\n                                            <span className=\"font-semibold\">Target branch:</span>\n                                            <DiffComponentEdit\n                                                component={component}\n                                                edit={a_change as DiffComponentEditProps[\"edit\"]}\n                                            />\n                                        </div>\n                                    )}\n                                    {b_change && (\n                                        <div>\n                                            <span className=\"font-semibold\">Version you're merging:</span>\n                                            <DiffComponentEdit\n                                                component={component}\n                                                edit={b_change as DiffComponentEditProps[\"edit\"]}\n                                            />\n                                        </div>\n                                    )}\n                                </>\n                            )}\n                        </div>\n                    );\n                })}\n            </div>\n        ));\n    };\n\n    useEffect(() => {\n        if (isOpen && appPath?.[0] === \"CODE\") {\n            dispatch(openCodeItem(appPath[1]));\n        }\n    }, [dispatch, isOpen, appPath]);\n\n    const hasOpenConflicts = () =>\n        Boolean(\n            conflicts &&\n            ([conflicts.edits, conflicts.text_chunks, conflicts.components].find((l) => l && l.length !== 0) ||\n                (itemType === \"extra_files\" && (wholeFileConflict || conflicts.edit_delete)))\n        );\n\n    const renderContents = () => {\n        if (!conflicts || !hasOpenConflicts()) {\n            return (\n                <div>\n                    <div className={cx(classes.conflict, classes.flex)}>\n                        {`Have you resolved all conflicts here?`}\n                        <BottomPanelContentButton\n                            small={true}\n                            className={classes.marginLeft}\n                            variant={\"primary\"}\n                            disabled={!editable}\n                            onClick={() => dispatch(resolveAllItemConflicts(conflictItemSpec))}>\n                            Yes\n                        </BottomPanelContentButton>\n                    </div>\n                </div>\n            );\n        }\n\n        return (\n            <div>\n                {itemType === \"extra_files\" && (wholeFileConflict || conflicts.edit_delete) && (\n                    <div className={classes.conflict}>\n                        <p>\n                            {wholeFileConflict\n                                ? \"Open this file to compare the original versions and choose which one to keep.\"\n                                : `The ${conflicts.edit_delete!.deleted_by === \"A\" ? \"target branch\" : \"version you're merging\"} deleted this file, while the other version edited it. The edited file has been kept.`}\n                        </p>\n                        {!wholeFileConflict && (\n                            <BottomPanelContentButton\n                                small\n                                disabled={!editable}\n                                onClick={() => dispatch(resolveAllItemConflicts(conflictItemSpec))}>\n                                Keep file\n                            </BottomPanelContentButton>\n                        )}\n                        {!wholeFileConflict && conflicts.edit_delete && typeof itemId === \"string\" && (\n                            <BottomPanelContentButton\n                                small\n                                disabled={!editable}\n                                variant=\"tertiary\"\n                                onClick={() => {\n                                    dispatch(deleteExtraFile(itemId));\n                                    dispatch(resolveAllItemConflicts(conflictItemSpec));\n                                }}>\n                                Delete file\n                            </BottomPanelContentButton>\n                        )}\n                    </div>\n                )}\n                {(codeType === \"forms\" || itemType === \"config\") &&\n                    conflicts.edits &&\n                    renderConfigConflicts(conflicts.edits as ConfigEditConflict[])}\n                {(codeType || (itemType === \"extra_files\" && !wholeFileConflict)) &&\n                    conflicts.text_chunks &&\n                    renderCodeConflicts(conflicts.text_chunks)}\n                {codeType === \"forms\" &&\n                    conflicts.components &&\n                    renderComponentConflicts(conflicts.components as FormComponentConflict[])}\n            </div>\n        );\n    };\n\n    return (\n        <div className={cx(classes.item, isOpen && classes.itemOpen)}>\n            <div className={cx(classes.itemHeader, classes.flex)} onClick={() => setOpen(!isOpen)}>\n                <FontAwesomeIcon icon={isOpen ? faChevronDown : faChevronRight} fixedWidth />\n                {itemType !== \"extra_files\" && (\n                    <Heading level={3} className={cx(classes.itemType, classes.m0)}>\n                        {codeType === \"forms\"\n                            ? \"FORM\"\n                            : codeType === \"modules\"\n                              ? \"MODULE\"\n                              : codeType === \"server_modules\"\n                                ? \"SERVER\"\n                                : itemType.toUpperCase()}\n                    </Heading>\n                )}\n                <span>{typeof itemId === \"string\" ? itemId : breadcrumb(itemId)}</span>\n                {linkTarget && (\n                    <BottomPanelContentButton\n                        small={true}\n                        className={classes.ml_auto}\n                        variant={\"primary\"}\n                        onClick={() => {\n                            setOpen(true);\n                            dispatch(navigate({ ...linkTarget, refocusView: Math.random() }));\n                        }}>\n                        Open\n                    </BottomPanelContentButton>\n                )}\n            </div>\n            <Expander isOpen={isOpen}>{renderContents()}</Expander>\n        </div>\n    );\n};\n\nconst ConnectedConflictingItem = connector(ConflictingItem);\n\nconst Conflicts = () => {\n    const conflictingItems = useSelector(listItemsWithConflicts);\n    const { classes } = useStyles();\n\n    return (\n        <div className={cx(classes.root, \"offset-vscrollbar\")}>\n            {conflictingItems?.map((ci, idx) => {\n                console.log(\"Conflict for\", ci);\n                const key = ci.appPath?.join(\":\") ?? `${ci.conflictItem[0]}:${JSON.stringify(ci.conflictItem[1])}`;\n                return <ConnectedConflictingItem key={key} whichItem={ci} index={idx} />;\n            })}\n        </div>\n    );\n};\n\nexport default Conflicts;\n","import React, { useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faLevelDownAlt } from \"@fortawesome/free-solid-svg-icons/faLevelDownAlt\";\nimport { faTrash } from \"@fortawesome/free-solid-svg-icons/faTrash\";\nimport { faMagnifyingGlass } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { AnvilDispatch } from \"@/types\";\nimport { checkMeta } from \"@/util\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { clearDesignerOutput, getDesignerOutput } from \"../../controllers/designer\";\nimport { makeStyles } from \"../../theme/styles\";\nimport LiveOutput, { liveOutputSearchStore, useLiveOutputSearchStore } from \"../reusable/LiveOutput\";\nimport { BottomPanelToolbarButton } from \"../reusable/SharedComponents\";\n\nconst useStyles = makeStyles()((theme) => ({\n    root: {\n        height: \"100%\",\n        padding: \"1rem\",\n        display: \"flex\",\n        flexDirection: \"column\",\n    },\n    buttons: {\n        display: \"flex\",\n        justifyContent: \"flex-end\",\n        //position: 'absolute',\n        right: \"1.5rem\",\n    },\n    outputOuter: {\n        flex: \"1 0 auto\",\n        position: \"relative\",\n    },\n    outputInner: {\n        position: \"absolute\",\n        left: 0,\n        top: 0,\n        bottom: 0,\n        right: 0,\n    },\n}));\n\nconst DesignerOutputTab = ({ classes }: any) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const designerOutput = useSelector(getDesignerOutput);\n    ({ classes } = useStyles(undefined, { props: { classes } }));\n\n    const [autoScroll, setAutoScroll] = useState(true);\n\n    const onKeyDown = useEvent((e: React.KeyboardEvent<HTMLDivElement>) => {\n        if (e.key === \"f\" && checkMeta(e)) {\n            liveOutputSearchStore.open();\n        }\n    });\n\n    return (\n        <div className={classes.root} onKeyDown={onKeyDown}>\n            <div className={classes.buttons}>\n                <BottomPanelToolbarButton\n                    onClick={() => {\n                        dispatch(clearDesignerOutput());\n                    }}>\n                    <FontAwesomeIcon icon={faTrash} />\n                </BottomPanelToolbarButton>\n                <BottomPanelToolbarButton\n                    variant={autoScroll ? \"highlight2\" : \"\"}\n                    onClick={() => setAutoScroll(!autoScroll)}>\n                    <FontAwesomeIcon icon={faLevelDownAlt} />\n                </BottomPanelToolbarButton>\n                <BottomPanelToolbarButton onClick={() => liveOutputSearchStore.toggle()}>\n                    <FontAwesomeIcon icon={faMagnifyingGlass} />\n                </BottomPanelToolbarButton>\n            </div>\n            <div className={classes.outputOuter}>\n                <div className={classes.outputInner}>\n                    <LiveOutput messages={designerOutput} autoScroll={autoScroll} setAutoScroll={setAutoScroll} />\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport default DesignerOutputTab;\n","import React from \"react\";\nimport Link from \"../reusable/Link\";\n\nconst TutorialPanel = () => {\n    return (\n        <div className={\"h-full overflow-y-auto px-16\"}>\n            <h2 className={\"mt-8 mb-5 text-3xl font-medium dark:text-dark-fg1\"}>\n                Learn the basics of Anvil in just 10 minutes\n            </h2>\n            <Link\n                to=\"/learn/tutorials/feedback-form?utm_source=ide:bottom-panel-cta\"\n                target={\"_blank\"}\n                className=\"mb-4 flex flex-wrap gap-10 rounded-md border-2 border-sectionborder bg-light-bg2 p-8 hover:bg-sidebar-highlight1 md:flex-nowrap dark:border-dark-bg4 dark:bg-dark-bg0 dark:hover:bg-dark-bg6\">\n                <div className=\"min-h-[200px] w-[360px] min-w-[270px] rounded-md border-2 border-sectionborder bg-[url('https://anvil.works/learn/tutorials/img/feedback-form/feedback-form-thumbnail.png')] bg-cover dark:border-dark-bg4\"></div>\n                <div className=\"shrink\">\n                    <h3 className=\"text-[16px] font-semibold text-primary\">Get Started Tutorial</h3>\n                    <p className={\"dark:text-white\"}>\n                        Build a data-entry app, and learn the techniques fundamental to building any Anvil app. In this\n                        tutorial, you will:\n                    </p>\n                    <ul className=\"list-inside list-disc marker:text-primary dark:text-white\">\n                        <li>Build your user interface</li>\n                        <li>Write client-side Python</li>\n                        <li>Write server-side Python</li>\n                        <li>Store data in a database</li>\n                        <li>Deploy your app</li>\n                    </ul>\n                </div>\n            </Link>\n        </div>\n    );\n};\n\nexport default TutorialPanel;\n","import { useLayoutEffect, useMemo, useRef } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faChevronRight, faCircle, faCircleNotch } from \"@fortawesome/pro-light-svg-icons\";\nimport { faArrowLeft, faCircle as faFilledCircle } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport RuntimeBuildStatus from \"@/components/tabs/settings/python-version/RuntimeBuildStatus.tsx\";\nimport { getAppExtraFiles, getAppId, getAppRuntimeOptions } from \"@/controllers/app\";\nimport { getExtraFileContent } from \"@/controllers/app/extra-files.ts\";\nimport { ServerTestSessionLog, serverTestOutputText } from \"@/controllers/server-test-logs\";\nimport { OverlaidTestResult, TestOutcome, TestResult, TestRun, TestRunError } from \"@/controllers/server-test-runs\";\nimport { getServerTestRunLog, setSelectedServerTestId } from \"@/controllers/server-tests\";\nimport { navigate } from \"@/router/navigation\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch, type RuntimeOptions, State } from \"@/types\";\nimport { decodeAssetContent } from \"@/util/asset-content.ts\";\nimport { getTestRunStatusDisplay, getTestStatusDisplay } from \"./test-status-display\";\n\ninterface ResultHeadingProps {\n    text: string;\n    level?: undefined | 1 | 2 | 3;\n}\nexport const ResultHeading = ({ text, level = 2 }: ResultHeadingProps) => {\n    return (\n        <div\n            className={cx(\n                \"mb-2 font-semibold capitalize\",\n                { \"text-4xl\": level === 1 },\n                { \"pt-4 text-3xl\": level === 2 },\n                { \"pt-2 text-2xl\": level === 3 }\n            )}>\n            {text}\n        </div>\n    );\n};\n\nexport const TestRunStatusBadge = ({ run }: { run?: TestRun }) => {\n    const display = getTestRunStatusDisplay(run);\n\n    return (\n        <div\n            role=\"status\"\n            aria-live=\"polite\"\n            className={cx(\n                \"flex h-8 w-fit shrink-0 items-center gap-2 rounded-full\",\n                \"border border-sectionborder bg-light-bg2 px-4\",\n                \"text-[1.3rem] leading-none dark:border-dark-sectionborder dark:bg-dark-bg2\",\n                display.className\n            )}>\n            <FontAwesomeIcon className=\"shrink-0\" icon={display.icon} spin={display.spin} fixedWidth />\n\n            <span className=\"whitespace-nowrap\">{display.label}</span>\n        </div>\n    );\n};\n\nexport const TestStatusIcon = ({ result }: { result?: TestResult }) => {\n    const display = getTestStatusDisplay(result);\n\n    return (\n        <span className={cx(\"inline-flex shrink-0\", display.className)} title={display.label} aria-label={display.label}>\n            <FontAwesomeIcon icon={display.icon} spin={display.spin} fixedWidth />\n        </span>\n    );\n};\n\nconst TEST_OUTCOMES: TestOutcome[] = [\"passed\", \"failed\", \"error\", \"skipped\", \"xfailed\", \"xpassed\"];\n\ninterface TestRunOutputProps {\n    run: TestRun;\n    runLog?: ServerTestSessionLog;\n}\n\nconst TestRunOutput = ({ run, runLog }: TestRunOutputProps) => {\n    const text = useMemo(() => serverTestOutputText(runLog?.output ?? []), [runLog?.output]);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const sessionId = run.session_id;\n    if (!sessionId && !runLog?.output.length) {\n        return null;\n    }\n\n    return (\n        <div className=\"mr-5\">\n            <div className=\"mb-1 flex items-center gap-4\">\n                <ResultHeading text=\"Output\" />\n\n                {sessionId && (\n                    <Button\n                        className=\"ml-auto shrink-0\"\n                        small\n                        iconRight\n                        icon={faChevronRight}\n                        onClick={() => {\n                            dispatch(\n                                navigate({\n                                    type: \"SESSION\",\n                                    sessionId,\n                                    displayMode: \"LOGS\",\n                                })\n                            );\n                        }}>\n                        App Log\n                    </Button>\n                )}\n            </div>\n\n            {text ? (\n                <pre className=\"ml-6 overflow-x-auto rounded bg-light-bg2 p-3 font-mono text-[1.3rem] whitespace-pre select-text dark:bg-dark-bg1 dark:text-dark-fg3\">\n                    {text}\n                </pre>\n            ) : (\n                <div className=\"text-light-fg3 dark:text-dark-fg3\">\n                    {run.state.status !== \"complete\"\n                        ? \"Waiting for output...\"\n                        : runLog\n                          ? \"This run didn't print any output.\"\n                          : \"This run's output is in its App Log.\"}\n                </div>\n            )}\n        </div>\n    );\n};\n\ninterface RunDetailsRowProps {\n    title: string;\n    result: string;\n    resultClasses?: string;\n}\n\nconst RunDetailsRow = ({ title, result, resultClasses }: RunDetailsRowProps) => {\n    return (\n        <>\n            <div className=\"text-light-fg3 h-full items-center justify-center border-r border-sectionborder px-6 nth-last-[n+3]:border-b dark:border-dark-sectionborder dark:text-dark-fg3\">\n                {title}\n            </div>\n            <div\n                className={cx(\n                    \"border-sectionborder pr-2 pl-6 not-last:border-b dark:border-dark-sectionborder\",\n                    resultClasses\n                )}>\n                {result}\n            </div>\n        </>\n    );\n};\n\nconst TestError = ({ error }: { error: TestRunError }) => {\n    return (\n        <>\n            <div className=\"mb-2 ml-6 leading-none text-danger select-text\">\n                <span className=\"font-mono\">{error.message}</span>\n            </div>\n\n            {error.traceback && (\n                <pre className=\"ml-6 overflow-x-auto rounded bg-light-bg2 p-3 font-mono text-[1.3rem] whitespace-pre-wrap select-text dark:bg-dark-bg1 dark:text-dark-fg3\">\n                    {error.traceback}\n                </pre>\n            )}\n        </>\n    );\n};\n\nexport const TestRunSummary = ({ run }: { run?: TestRun }) => {\n    const runLog = useSelector((state: State) => getServerTestRunLog(run)(state));\n    const outputLength = runLog?.output.length ?? 0;\n    const isRunning = !!run && run.state.status !== \"complete\";\n    const appId = useSelector(getAppId)!;\n\n    const runtimeOptions = useSelector(getAppRuntimeOptions) as RuntimeOptions | undefined;\n    const testRequirementsBase64 = useSelector((state: State) =>\n        getExtraFileContent(state, \"tests/server_tests/requirements.txt\")\n    );\n    const testRequirements = useMemo(\n        () => (testRequirementsBase64 ? \"\\n\" + decodeAssetContent(testRequirementsBase64) : null),\n        [testRequirementsBase64]\n    );\n    const testRuntimeSpec = useMemo(\n        () => ({\n            ...(runtimeOptions?.server_spec ?? {}),\n            requirements: (runtimeOptions?.server_spec?.requirements || \"\") + testRequirements,\n        }),\n        [runtimeOptions?.server_spec, testRequirements]\n    );\n\n    // If we've seen the run going, follow its output unless the user has scrolled up. We keep following once it\n    // completes: the results appear above the output, and its last lines can arrive after the run's final update.\n    const scrollerRef = useRef<HTMLDivElement>(null);\n    const followOutputRef = useRef(true);\n    const sawRunningRef = useRef(false);\n    sawRunningRef.current ||= isRunning;\n    useLayoutEffect(() => {\n        const el = scrollerRef.current;\n        if (el && sawRunningRef.current && followOutputRef.current) {\n            el.scrollTop = el.scrollHeight;\n        }\n    }, [run, outputLength]);\n\n    if (!run) {\n        return <div className=\"text-light-fg3 p-4 dark:text-dark-fg3\">No test results available</div>;\n    }\n\n    const { state } = run;\n\n    return (\n        <div className=\"flex h-full min-w-0 flex-col\">\n            <div className=\"border-b border-sectionborder p-4 dark:border-dark-sectionborder\">\n                <ResultHeading text=\"Run summary\" level={1} />\n\n                <TestRunStatusBadge run={run} />\n            </div>\n\n            <div\n                ref={scrollerRef}\n                className=\"min-h-0 grow overflow-y-auto p-4\"\n                onScroll={(event) => {\n                    const el = event.currentTarget;\n                    followOutputRef.current = el.scrollTop + el.clientHeight >= el.scrollHeight - 8;\n                }}>\n                <div className=\"flex flex-col gap-5\">\n                    {state.counts && (\n                        <div>\n                            <ResultHeading text={\"Results\"} level={2} />\n\n                            <div className=\"mx-4 grid grid-cols-2 overflow-hidden rounded-md border border-sectionborder dark:border-dark-sectionborder\">\n                                {TEST_OUTCOMES.map((outcome) => (\n                                    <div\n                                        key={outcome}\n                                        className=\"flex h-full items-center justify-between gap-4 border-sectionborder bg-light-bg2 px-6 odd:border-r nth-last-[n+3]:border-b dark:border-dark-sectionborder dark:bg-dark-bg1\">\n                                        <div className=\"font-mono capitalize\">{outcome}</div>\n\n                                        <div className=\"font-mono font-semibold\">{state.counts?.[outcome] ?? 0}</div>\n                                    </div>\n                                ))}\n                            </div>\n                        </div>\n                    )}\n\n                    <div>\n                        <ResultHeading text={\"Run details\"} />\n\n                        <div className=\"mx-4 grid grid-cols-[max-content_minmax(0,1fr)] overflow-hidden rounded-md border border-sectionborder bg-light-bg2 dark:border-dark-sectionborder dark:bg-dark-bg1\">\n                            {state.duration !== undefined && state.duration !== null && (\n                                <RunDetailsRow title={\"Duration\"} result={`${state.duration.toFixed(3)}s`} />\n                            )}\n\n                            {state.exit_code !== undefined && state.exit_code !== null && (\n                                <RunDetailsRow title={\"Exit code\"} result={state.exit_code} resultClasses=\"font-mono\" />\n                            )}\n\n                            {state.pytest_version && <RunDetailsRow title={\"pytest\"} result={state.pytest_version} />}\n\n                            {state.args && state.args.length > 0 && (\n                                <RunDetailsRow\n                                    title={\"Arguments\"}\n                                    result={state.args.join(\" \")}\n                                    resultClasses={\"min-w-0 font-mono break-words select-text\"}\n                                />\n                            )}\n                        </div>\n                    </div>\n\n                    <div>\n                        <ResultHeading text={\"Test environment\"} />\n                        <div className=\"mx-4\">\n                            <RuntimeBuildStatus\n                                appId={appId}\n                                runtimeSpec={testRuntimeSpec}\n                                showBuildButton={false}\n                                showVulnerabilities={false}\n                            />\n                        </div>\n                        {state.launch_message && (\n                            <div className=\"pr-4 pl-6 font-mono text-[1.3rem] leading-8 select-text\">\n                                {state.launch_message}\n                            </div>\n                        )}\n                    </div>\n\n                    {state.error && (\n                        <div>\n                            <ResultHeading text=\"Run error\" level={2} />\n\n                            <TestError error={state.error} />\n                        </div>\n                    )}\n\n                    {state.collection_errors && state.collection_errors.length > 0 && (\n                        <div>\n                            <ResultHeading text=\"Collection errors\" level={2} />\n\n                            <div className=\"flex flex-col gap-4\">\n                                {state.collection_errors.map((error, index) => (\n                                    <div key={`${error.file_path}-${index}`} className=\"flex flex-col gap-1 px-4\">\n                                        <ResultHeading text={error.file_path} level={3} />\n\n                                        <TestError error={error} />\n                                    </div>\n                                ))}\n                            </div>\n                        </div>\n                    )}\n\n                    <TestRunOutput run={run} runLog={runLog} />\n                </div>\n            </div>\n        </div>\n    );\n};\n\ninterface TestOutputSectionProps {\n    title: string;\n    value?: string;\n}\n\nconst TestOutputSection = ({ title, value }: TestOutputSectionProps) => {\n    if (!value) {\n        return null;\n    }\n\n    return (\n        <div>\n            <ResultHeading text={title} level={2} />\n            <pre className=\"ml-6 overflow-x-auto rounded bg-light-bg2 p-3 font-mono text-[1.3rem] whitespace-pre-wrap select-text dark:bg-dark-bg1 dark:text-dark-fg3\">\n                {value}\n            </pre>\n        </div>\n    );\n};\n\nexport const SelectedTestDetails = ({ test }: { test: OverlaidTestResult | null }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const [tt, ttRef] = useTooltip(\"Return to run summary\", \"top\");\n\n    if (!test) {\n        return <div className=\"text-light-fg3 p-4 dark:text-dark-fg3\">Select a test to see its results.</div>;\n    }\n\n    const result = test.result;\n\n    return (\n        <div className=\"flex h-full min-w-0 flex-col\">\n            <div className=\"border-b border-sectionborder p-4 dark:border-dark-sectionborder\">\n                <div className=\"flex min-w-0 items-center gap-2\">\n                    <LinkInternal\n                        ref={ttRef}\n                        className={cx(\"flex items-center gap-4 hover:text-primary\")}\n                        onClick={() => dispatch(setSelectedServerTestId(null))}>\n                        {tt}\n                        <FontAwesomeIcon icon={faArrowLeft} />\n                        <span className={\"font-medium\"}>Run Summary</span>\n                    </LinkInternal>\n                    &nbsp;/&nbsp;\n                    <div className=\"min-w-0 truncate font-mono font-semibold\">{test.name}</div>\n                </div>\n\n                <div className=\"flex min-w-0 items-center gap-4\">\n                    <div className=\"flex shrink-0 items-center gap-2\">\n                        <TestStatusIcon result={result} />\n                        <span>{getTestStatusDisplay(result).label}</span>\n                    </div>\n\n                    <div className=\"text-light-fg3 ml-auto flex min-w-0 flex-col items-end gap-1 text-xs dark:text-dark-fg3\">\n                        <div className=\"max-w-full truncate select-text\" title={test.file_path}>\n                            {test.file_path}\n                            {test.line !== null && `:${test.line}`}\n                        </div>\n\n                        {result?.duration !== undefined && (\n                            <div>Duration: {result.duration.toFixed(3)}s</div>\n                        )}\n                    </div>\n                </div>\n            </div>\n\n            <div className=\"min-h-0 grow overflow-y-auto p-4\">\n                {!result ? (\n                    <div className=\"text-light-fg3 dark:text-dark-fg3\">\n                        This test has been discovered but has not been run.\n                    </div>\n                ) : result.status === \"pending\" ? (\n                    <div className=\"text-light-fg3 dark:text-dark-fg3\">This test is waiting to run.</div>\n                ) : result.status === \"running\" ? (\n                    <div className=\"text-light-fg3 dark:text-dark-fg3\">\n                        This test is running. Captured output will appear when it finishes.\n                    </div>\n                ) : result.status === \"not_run\" ? (\n                    <div className=\"text-light-fg3 dark:text-dark-fg3\">\n                        The run ended before this test started. See the run summary for details.\n                    </div>\n                ) : result.status === \"did_not_finish\" ? (\n                    <div className=\"text-light-fg3 dark:text-dark-fg3\">\n                        The run ended before this test finished. See the run summary for details.\n                    </div>\n                ) : (\n                    <div className=\"flex flex-col gap-5\">\n                        {result.reason && (\n                            <div>\n                                <ResultHeading text=\"Reason\" level={2} />\n                                <div className=\"pl-6 select-text\">{result.reason}</div>\n                            </div>\n                        )}\n\n                        {result.errors?.map((error, index) => (\n                            <div key={`${error.phase}-${index}`}>\n                                {/* <div className=\"mb-1 font-semibold text-danger\">{error.phase} error</div> */}\n                                <ResultHeading\n                                    text={error.phase === \"call\" ? \"Error\" : `${error.phase} error`}\n                                    level={2}\n                                />\n\n                                <TestError error={error} />\n                            </div>\n                        ))}\n\n                        <TestOutputSection title=\"Standard output\" value={result.stdout} />\n\n                        <TestOutputSection title=\"Standard error\" value={result.stderr} />\n\n                        <TestOutputSection title=\"Logs\" value={result.log} />\n\n                        {!result.reason &&\n                            !result.errors?.length &&\n                            !result.stdout &&\n                            !result.stderr &&\n                            !result.log && (\n                                <div className=\"text-light-fg3 dark:text-dark-fg3\">\n                                    This test did not produce any captured output.\n                                </div>\n                            )}\n                    </div>\n                )}\n            </div>\n        </div>\n    );\n};\n","import { useMemo } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faRotateForward } from \"@fortawesome/pro-light-svg-icons\";\nimport {\n    faAlignSlash,\n    faBug,\n    faFileCode,\n    faPlay,\n    faRotateExclamation,\n    faStop,\n} from \"@fortawesome/pro-regular-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { getServerTestSourceLine } from \"@/code_mirror/utils/server-test-locations\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { ButtonGroup } from \"@/components/reusable/ButtonGroup\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport ResizePanel from \"@/components/sidebar/ResizePanel\";\nimport { getAppId } from \"@/controllers/app\";\nimport { getExtraFileContent } from \"@/controllers/app/extra-files\";\nimport { OverlaidTestResult, TestRun } from \"@/controllers/server-test-runs\";\nimport {\n    cancelServerTestRuns,\n    clearDisplayedServerTestResults,\n    getAreServerTestsBusy,\n    getAreServerTestsRunning,\n    getBottomPanelServerTestListWidth,\n    getFailedServerTestIds,\n    getFilteredServerTests,\n    getLatestServerTestExecution,\n    getLatestServerTestRun,\n    getLatestVisibleServerTestExecution,\n    getLatestVisibleServerTestRun,\n    getServerTestListFilter,\n    getServerTestPanelState,\n    getServerTestResults,\n    getServerTestRunRequest,\n    rerunFailedServerTests,\n    rerunLastServerTests,\n    runServerTests,\n    setBottomPanelServerTestListWidth,\n    setSelectedServerTestId,\n    setServerTestKeywordExpression,\n    setServerTestListFilter,\n} from \"@/controllers/server-tests\";\nimport { navigate } from \"@/router/navigation\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { decodeAssetContent } from \"@/util/asset-content\";\nimport { SelectedTestDetails, TestRunStatusBadge, TestRunSummary, TestStatusIcon } from \"./ServerTestsResults\";\n\ninterface RunTestButtonProps {\n    latestRun?: TestRun;\n    testsAreRunning: boolean;\n    testsAreBusy: boolean;\n    onShowRunSummary: () => void;\n    hasTestResults: boolean;\n    failedTestCount: number;\n}\n\nconst RunTestsButtons = ({\n    latestRun,\n    testsAreRunning,\n    testsAreBusy,\n    onShowRunSummary,\n    hasTestResults,\n    failedTestCount,\n}: RunTestButtonProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const latestExecution = useSelector(getLatestServerTestExecution);\n\n    const onRunAllTests = () => {\n        onShowRunSummary();\n        dispatch(runServerTests());\n    };\n\n    const onCancelTests = () => {\n        dispatch(cancelServerTestRuns());\n    };\n\n    const onRerunLastRun = () => {\n        if (!latestExecution || testsAreBusy) {\n            return;\n        }\n\n        onShowRunSummary();\n        dispatch(rerunLastServerTests());\n    };\n\n    const onRerunFailedTests = () => {\n        if (testsAreBusy || failedTestCount === 0) {\n            return;\n        }\n\n        onShowRunSummary();\n        dispatch(rerunFailedServerTests());\n    };\n\n    const onClearResults = () => {\n        if (testsAreBusy || !hasTestResults) {\n            return;\n        }\n        dispatch(clearDisplayedServerTestResults());\n    };\n\n    return (\n        <div className=\"flex items-center gap-2\">\n            <Button\n                size=\"small\"\n                variant={testsAreRunning ? \"danger\" : \"highlight1\"}\n                title={\n                    testsAreRunning\n                        ? \"Cancel server tests\"\n                        : testsAreBusy\n                          ? \"Starting server tests\"\n                          : \"Run all server tests\"\n                }\n                titlePosition=\"top\"\n                disabled={testsAreBusy && !testsAreRunning}\n                onClick={testsAreRunning ? onCancelTests : onRunAllTests}>\n                <FontAwesomeIcon icon={testsAreRunning ? faStop : faPlay} fixedWidth />\n            </Button>\n\n            <Button\n                size=\"small\"\n                variant=\"secondary\"\n                title={testsAreRunning ? \"Server tests are already running\" : \"Rerun last server test run\"}\n                titlePosition=\"top\"\n                disabled={testsAreBusy || !latestExecution}\n                onClick={onRerunLastRun}>\n                <FontAwesomeIcon icon={faRotateForward} fixedWidth />\n            </Button>\n\n            <Button\n                size=\"small\"\n                variant=\"tertiary\"\n                title={\n                    testsAreRunning\n                        ? \"Server tests are already running\"\n                        : failedTestCount > 0\n                          ? `Rerun ${failedTestCount} failed ${failedTestCount === 1 ? \"test\" : \"tests\"}`\n                          : \"No failed server tests to rerun\"\n                }\n                titlePosition=\"top\"\n                disabled={testsAreBusy || failedTestCount === 0}\n                onClick={onRerunFailedTests}>\n                <FontAwesomeIcon icon={faRotateExclamation} fixedWidth />\n            </Button>\n\n            <Button\n                size=\"small\"\n                variant=\"highlight2\"\n                title={\n                    testsAreRunning\n                        ? \"Server tests are already running\"\n                        : hasTestResults\n                          ? \"Clear displayed server-test results\"\n                          : \"No server-test results to clear\"\n                }\n                titlePosition=\"top\"\n                disabled={testsAreBusy || !hasTestResults}\n                onClick={onClearResults}>\n                <FontAwesomeIcon icon={faAlignSlash} fixedWidth />\n            </Button>\n        </div>\n    );\n};\n\nconst TestRowButtons = ({ test }: { test: OverlaidTestResult }) => {\n    const testsAreBusy = useSelector(getAreServerTestsBusy);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const onJumpToCode = () => {\n        dispatch((_dispatch, getState) => {\n            const filePath = `tests/${test.file_path}`;\n            const encodedContent = getExtraFileContent(getState(), filePath);\n\n            const source = encodedContent === undefined ? undefined : decodeAssetContent(encodedContent);\n\n            const line = getServerTestSourceLine(source, test);\n\n            return _dispatch(\n                navigate({\n                    type: \"EXTRA_FILE\",\n                    filePath,\n                    view: {\n                        code: line === null ? true : [String(line), \"0\"],\n                        focus: \"code\",\n                    },\n                    refocusView: Math.random(),\n                })\n            );\n        });\n    };\n\n    const onRunTest = () => {\n        //todo: also decide if it makes sense to set this back to the run summary of the selected test\n        dispatch(setSelectedServerTestId(null));\n\n        dispatch(\n            runServerTests({\n                selection: {\n                    test_targets: [test.test_id],\n                },\n            })\n        );\n    };\n\n    return (\n        <>\n            <Button title={\"Jump to test\"} titlePosition=\"top\" size=\"small\" onClick={onJumpToCode} icon={faFileCode} />\n            <Button\n                title={testsAreBusy ? \"Server tests are busy\" : \"Run this test\"}\n                titlePosition=\"top\"\n                size=\"small\"\n                onClick={onRunTest}\n                icon={faPlay}\n                disabled={testsAreBusy}\n            />\n\n            {/* <Button\n            variant={\"hidden\"}\n            onClick={onRunDebug}>\n            <FontAwesomeIcon icon={faBug} /> */}\n        </>\n    );\n};\n\nconst useServerTestExecutionState = () => {\n    const appId = useSelector(getAppId);\n    const request = useSelector(getServerTestRunRequest);\n    const latestExecution = useSelector(getLatestVisibleServerTestExecution);\n\n    const startingExecution = !!request && request.appId === appId && !request.options.collect_only;\n\n    const executionActive = startingExecution || (!!latestExecution && latestExecution.state.status !== \"complete\");\n\n    return { latestExecution, executionActive };\n};\n\ninterface DiscoveredTestRowProps {\n    test: OverlaidTestResult;\n    isSelected: boolean;\n}\n\nconst DiscoveredTestRow = ({ test, isSelected }: DiscoveredTestRowProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    return (\n        <LinkInternal\n            key={test.test_id}\n            // type=\"button\"\n            aria-selected={isSelected}\n            onClick={() => {\n                dispatch(setSelectedServerTestId(test.test_id));\n            }}\n            className={cx(\n                \"flex w-full items-center gap-4 px-4 py-2 text-left\",\n                \"hover:bg-sidebar-highlight1 dark:hover:bg-dark-bg4\",\n                isSelected && \"bg-sidebar-highlight2 dark:bg-dark-bg3\",\n                \"group/test relative\"\n            )}>\n            <TestStatusIcon result={test.result} />\n\n            <div className=\"min-w-0 grow\">\n                <div className=\"truncate font-mono text-xl font-medium\">{test.name}</div>\n\n                <div className=\"text-light-fg3 truncate text-xs dark:text-dark-fg3\" title={test.file_path}>\n                    {test.file_path}\n                    {test.line !== null && `:${test.line}`}\n                </div>\n            </div>\n            <div\n                className={cx(\n                    \"pointer-events-none absolute right-4 flex gap-2 opacity-0\",\n                    \"group-hover/test:pointer-events-auto group-hover/test:opacity-100\",\n                    \"group-focus-within/test:pointer-events-auto group-focus-within/test:opacity-100\"\n                )}>\n                <TestRowButtons test={test} />\n            </div>\n        </LinkInternal>\n    );\n};\n\nconst DiscoveredTests = ({ selectedTest }: { selectedTest: OverlaidTestResult | null }) => {\n    const tests = useSelector(getFilteredServerTests);\n    const filter = useSelector(getServerTestListFilter);\n    const { latestExecution, executionActive } = useServerTestExecutionState();\n\n    if (tests.length === 0) {\n        let message = \"No server tests have been discovered.\";\n\n        if (filter === \"failed\") {\n            message = \"No failed tests.\";\n        } else if (filter === \"latest_run\") {\n            if (executionActive) {\n                message = \"Waiting for selected tests…\";\n            } else if (latestExecution) {\n                message = \"No discovered tests belong to this run.\";\n            } else {\n                message = \"No run results. Run tests to see them here.\";\n            }\n        }\n\n        return <div className=\"text-light-fg3 px-4 py-6 dark:text-dark-fg3\">{message}</div>;\n    }\n\n    return tests.map((test) => (\n        <DiscoveredTestRow key={test.test_id} test={test} isSelected={selectedTest?.test_id === test.test_id} />\n    ));\n};\n\nexport default function ServerTestsBottomPanel() {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const testsAreRunning = useSelector(getAreServerTestsRunning);\n    const testsAreBusy = useSelector(getAreServerTestsBusy);\n    const resultsPanelWidth = useSelector(getBottomPanelServerTestListWidth);\n    const latestRun = useSelector(getLatestServerTestRun);\n    const latestVisibleRun = useSelector(getLatestVisibleServerTestRun);\n    const failedTestCount = useSelector(getFailedServerTestIds).length;\n    const listFilter = useSelector(getServerTestListFilter);\n\n    const resultMap = useSelector(getServerTestResults);\n    const hasTestResults = Object.values(resultMap).some(({ result }) => result !== undefined);\n\n    const { selectedTestId, keywordExpression } = useSelector(getServerTestPanelState);\n\n    const selectedTest = selectedTestId === null ? null : (resultMap[selectedTestId] ?? null);\n\n    const showRunSummary = selectedTestId === null || selectedTest === null;\n\n    //just for testing -k options. will be removed.\n    const trimmedKeywordExpression = keywordExpression.trim();\n    const onRunWithKeywordExpression = () => {\n        if (testsAreBusy || !trimmedKeywordExpression) {\n            return;\n        }\n\n        dispatch(setSelectedServerTestId(null));\n\n        dispatch(\n            runServerTests({\n                selection: {\n                    keyword_expression: trimmedKeywordExpression,\n                },\n            })\n        );\n    };\n\n    return (\n        <div className={\"flex h-full w-full flex-col\"}>\n            <div className=\"grid h-16 w-full grid-cols-[1fr_auto_1fr] items-center border-b border-sectionborder px-4 dark:border-dark-sectionborder\">\n                <div className=\"justify-self-start\">\n                    <div className=\"flex items-center gap-4\">\n                        <RunTestsButtons\n                            latestRun={latestRun}\n                            testsAreRunning={testsAreRunning}\n                            testsAreBusy={testsAreBusy}\n                            hasTestResults={hasTestResults}\n                            failedTestCount={failedTestCount}\n                            onShowRunSummary={() => {\n                                dispatch(setSelectedServerTestId(null));\n                            }}\n                        />\n                        <TestRunStatusBadge run={latestVisibleRun} />\n                    </div>\n                </div>\n                <div className=\"justify-self-center\" role=\"group\" aria-label=\"Filter discovered tests\">\n                    <ButtonGroup\n                        className=\"shrink-0 whitespace-nowrap\"\n                        size=\"small\"\n                        // variant=\"primary\"\n                        selectedVariant=\"primary\"\n                        selectedOption={listFilter}\n                        options={\n                            [\n                                { value: \"all\", title: \"All tests\" },\n                                {\n                                    value: \"latest_run\",\n                                    title: \"Latest Run\",\n                                },\n                                { value: \"failed\", title: \"Failing\" },\n                            ] as const\n                        }\n                        onClick={(filter) => dispatch(setServerTestListFilter(filter))}\n                    />\n                </div>\n                <div className=\"flex items-center gap-2 justify-self-end pr-4\">\n                    <ContentTextInput\n                        small\n                        value={keywordExpression}\n                        disabled={testsAreBusy}\n                        placeholder=\"pytest -k expression\"\n                        aria-label=\"pytest keyword expression\"\n                        className=\"w-full min-w-0\"\n                        onChange={(event) => dispatch(setServerTestKeywordExpression(event.target.value))}\n                        onEnter={(event) => {\n                            event.preventDefault();\n                            onRunWithKeywordExpression();\n                        }}\n                    />\n                    <Button\n                        small\n                        icon={faPlay}\n                        title={\n                            testsAreRunning\n                                ? \"Server tests are already running\"\n                                : trimmedKeywordExpression\n                                  ? \"Run tests matching this expression\"\n                                  : \"Enter a pytest -k expression\"\n                        }\n                        titlePosition={\"top\"}\n                        disabled={testsAreBusy || !trimmedKeywordExpression}\n                        onClick={onRunWithKeywordExpression}\n                    />\n                </div>\n            </div>\n            <div className=\"relative flex min-h-0 w-full flex-1 overflow-hidden\">\n                <div className=\"h-full min-w-0 grow overflow-y-auto py-2\">\n                    <DiscoveredTests selectedTest={selectedTest} />\n                </div>\n                <ResizePanel\n                    className=\"h-full\"\n                    horizontal={true}\n                    panelSize={resultsPanelWidth}\n                    handleAtStart={true}\n                    onFinishDrag={(size) => dispatch(setBottomPanelServerTestListWidth(size))}>\n                    {showRunSummary ? (\n                        <TestRunSummary key={latestVisibleRun?.run_id} run={latestVisibleRun} />\n                    ) : (\n                        <SelectedTestDetails test={selectedTest} />\n                    )}\n                </ResizePanel>\n            </div>\n        </div>\n    );\n}\n","import React, { createContext, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { IconProp } from \"@fortawesome/fontawesome-svg-core\";\nimport { faBug } from \"@fortawesome/free-solid-svg-icons\";\nimport { faExclamationTriangle } from \"@fortawesome/free-solid-svg-icons/faExclamationTriangle\";\nimport { faSparkle, faBrain, faChevronDown, faCodeBranch, faLightbulb, faObjectGroup, faRoad, faTag, faTasksAlt, faTerminal, faTimes, faTools, faVideo, faFlask } from \"@fortawesome/pro-light-svg-icons\";\nimport { faChevronRight as faChevronRightHeavy, faTerminal as faTerminalHeavy } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faShieldHalved, faWindowRestore } from \"@fortawesome/pro-solid-svg-icons\";\nimport { faGift } from \"@fortawesome/pro-solid-svg-icons/faGift\";\nimport { faHammer } from \"@fortawesome/pro-solid-svg-icons/faHammer\";\nimport { faPlay } from \"@fortawesome/pro-solid-svg-icons/faPlay\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { AgentPanel } from \"@/agent/AgentBottomPanel.tsx\";\nimport { BuildThis } from \"@/components/bottom_panel/BuildThis\";\nimport { DebugInspector } from \"@/components/bottom_panel/DebugInspector\";\nimport { IDETutorialPanel } from \"@/components/bottom_panel/IDETutorialPanel\";\nimport IntroVideoPanel from \"@/components/bottom_panel/IntroVideoPanel\";\nimport RoadmapPanel, { useRoadmapAbFlag } from \"@/components/bottom_panel/RoadmapPanel\";\nimport ScriptOutputTab from \"@/components/bottom_panel/ScriptOutputTab\";\nimport DropdownMenu, { MenuItems } from \"@/components/reusable/DropdownMenu\";\nimport { TalkToUsOffer } from \"@/components/TalkToUsOffer\";\nimport { getApp, getAppEditState } from \"@/controllers/app\";\nimport { getAppCta, validCtas } from \"@/controllers/app/cta\";\nimport { getAppRefs } from \"@/controllers/app/history\";\nimport {\n    bottomTabsMatch,\n    closeBottomPanel,\n    closeBottomPanelConversation,\n    closeBottomTab,\n    closeTutorialTab,\n    dismissOnboardingCtaTab,\n    getBottomPanelCurrentTab,\n    getBottomPanelHeight,\n    getBottomPanelIsOpen,\n    getBottomPanelTabs,\n    openOrFocusBottomTab,\n    openOrFocusPrevBottomTab,\n} from \"@/controllers/bottom-tabs\";\nimport { getDebuggerHyperStacks } from \"@/controllers/debugger\";\nimport { closeDesignerOutput, getDesignerOutput } from \"@/controllers/designer\";\nimport { enableRoadmap } from \"@/controllers/ide\";\nimport { getInTutorialMode } from \"@/controllers/ideTutorial\";\nimport { alert } from \"@/controllers/modals\";\nimport { createRepl, destroyRepl, getRepls, getRunnerRepl } from \"@/controllers/repl\";\nimport { getRunnerOutput } from \"@/controllers/runner\";\nimport { getRunnerBgTaskOutputCount } from \"@/controllers/runner-bg-tasks\";\nimport { deleteScriptRuns, getScriptRuns } from \"@/controllers/scripts\";\nimport { useTalkToUsOffer } from \"@/controllers/talkToUsOffer\";\nimport { getShowRoadmap } from \"@/controllers/user\";\nimport { getWhereToStartTutorial } from \"@/controllers/whereToStartTutorials\";\nimport { navigate } from \"@/router/navigation\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { AnvilDispatch, BottomPanelTabHeader, BottomPanelTabTargetScriptRun } from \"@/types\";\nimport { createContextHook, useEffectWhen, useIsInView, useMemoiseObject } from \"@/util/hooks\";\nimport { faAnvilX } from \"@/util/icons\";\nimport useEffectEvent from \"@/util/useEffectEvent\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { Button } from \"../reusable/Button\";\nimport { ErrorBoundary } from \"../reusable/ErrorBoundary\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport BackgroundTasks from \"./BackgroundTasks\";\nimport { Breakpoints } from \"./Breakpoints\";\nimport Conflicts from \"./Conflicts\";\nimport DesignerOutput from \"./DesignerOutputTab\";\nimport WhereToStartTutorialPanel from \"./WhereToStartTutorialPanel\";\nimport History from \"./History\";\nimport REPL from \"./REPL\";\nimport TutorialPanel from \"./TutorialPanel\";\nimport ServerTestsBottomPanel from \"@/testing/ServerTestsBottomPanel\";\nimport { getTestingEnabled } from \"@/controllers/services\";\n\n// import SearchPanel from \"./SearchPanel\";\n\nconst useStyles = makeStyles<\n    void,\n    | \"tab\"\n    | \"tabIcon\"\n    | \"open\"\n    | \"selected\"\n    | \"server\"\n    | \"conflicts\"\n    | \"content\"\n    | \"tabCloseButton\"\n    | \"tabRightIcon\"\n    | \"branchIcon\"\n>()((theme, _props, classes) => ({\n    root: {\n        //height: '4rem',\n        width: \"100%\",\n        bottom: 0,\n        display: \"flex\",\n        flexDirection: \"column\",\n        color: theme.palette.fg1.hex(),\n        [`&.${classes.open}`]: {\n            height: \"100%\",\n        },\n        zIndex: 3,\n    },\n    open: {},\n    tabBar: {\n        height: \"4rem\",\n        display: \"flex\",\n        fontSize: \"1.2rem\",\n        fontWeight: 600,\n        background: theme.tabBar.background.toString(),\n        listStyleType: \"none\",\n        padding: 0,\n        margin: 0,\n        borderBottom: \"1px solid \" + theme.sectionBorderColor.toString(),\n        borderTop: \"1px solid \" + theme.sectionBorderColor.toString(),\n        [`& .${classes.tab}`]: {\n            background: theme.tabBar.bottom.closedBarTab.background.toString(),\n            \"&:hover\": {\n                background: theme.tabBar.bottom.closedBarTab.hoverBg.toString(),\n                [`& .${classes.tabIcon}`]: {\n                    color: theme.text.dark.toString(),\n                },\n            },\n            \"&:active\": {\n                background: theme.tabBar.bottom.closedBarTab.activeBg.toString(),\n            },\n\n            [`& .${classes.tabIcon}`]: {\n                color: theme.text.extraLight.toString(),\n            },\n        },\n        [`&.${classes.open} .${classes.tab}`]: {\n            borderTop: \"3px solid \" + theme.tabBar.bottom.openBarInactiveTab.background.toString(),\n            background: theme.tabBar.bottom.openBarInactiveTab.background.toString(),\n            color: theme.tabBar.bottom.openBarInactiveTab.color.toString(),\n            \"&:hover\": {\n                color: theme.tabBar.bottom.openBarInactiveTab.hoverColor.toString(),\n                borderTop: \"3px solid \" + theme.tabBar.bottom.openBarInactiveTab.hoverBg.toString(),\n                background: theme.tabBar.bottom.openBarInactiveTab.hoverBg.toString(),\n                [`& .${classes.tabIcon}`]: {\n                    color: theme.tabBar.bottom.openBarInactiveTab.iconHoverColor.toString(),\n                },\n            },\n            \"&:active\": {\n                background: theme.tabBar.bottom.openBarInactiveTab.activeBg.toString(),\n            },\n\n            [`& .${classes.tabIcon}`]: {\n                color: theme.tabBar.bottom.openBarInactiveTab.color.toString(),\n            },\n        },\n        [`&.${classes.open} .${classes.tab}.${classes.selected}`]: {\n            borderTop: \"3px solid \" + theme.palette.primary.toString(),\n            background: theme.tabBar.bottom.openBarActiveTab.background.toString(),\n            color: theme.tabBar.bottom.openBarActiveTab.color.toString(),\n            \"&:hover\": {\n                borderTop: \"3px solid \" + theme.palette.primary.toString(),\n                background: theme.tabBar.bottom.openBarActiveTab.background.toString(),\n                color: theme.tabBar.bottom.openBarActiveTab.color.toString(),\n            },\n            \"&:active\": {\n                background: theme.tabBar.bottom.openBarActiveTab.background.toString(),\n            },\n\n            [`& .${classes.tabIcon}`]: {\n                color: theme.palette.primary.toString(),\n            },\n        },\n        [`&.${classes.open} .${classes.tab}.${classes.selected}.${classes.server}`]: {\n            borderTop: \"3px solid \" + theme.palette.secondary.toString(),\n            \"&:hover\": {\n                borderTop: \"3px solid \" + theme.palette.secondary.toString(),\n            },\n            [`& .${classes.tabIcon}`]: {\n                color: theme.palette.secondary.toString(),\n            },\n        },\n    },\n    tab: {\n        flex: \"0 0 auto\",\n        display: \"inline-flex\",\n        alignItems: \"center\",\n        padding: \"0 2rem 0 1rem\",\n        borderRight: \"1px solid \" + theme.sectionBorderColor.toString(),\n        \"&:focus\": {\n            //border: '1px dotted white',\n        },\n        \"&:hover\": {\n            // borderTop: '2px solid ' + theme.hl1.hex(),\n            background: theme.isDark ? theme.palette.bg1.hex() : theme.palette.bg0.hex(),\n        },\n        [`&.${classes.selected}`]: {\n            // borderTop: '2px solid ' + theme.hl1.hex(),\n            background: theme.palette.bg0.hex(),\n        },\n    },\n    tabIcon: {\n        fontSize: \"1.8rem\",\n        marginRight: \"1rem\",\n    },\n    closed: {},\n    selected: {},\n    server: {},\n    conflicts: {\n        color: theme.tertiary.hex(),\n    },\n    content: {\n        flex: \"1 0 auto\",\n        height: 0,\n    },\n    tabCloseButton: {\n        alignSelf: \"stretch\",\n        display: \"flex\",\n        alignItems: \"center\",\n        fontSize: \"1.4rem\",\n        padding: \"0 1rem\",\n        marginRight: \"-2rem\",\n        opacity: 0.3,\n        \"&:hover\": {\n            opacity: 1,\n        },\n    },\n    tabRightIcon: {\n        width: \"2.9rem\",\n        marginRight: \"1rem\",\n    },\n    tabRightContainer: {\n        alignSelf: \"center\",\n        whiteSpace: \"nowrap\",\n    },\n    spring: {\n        flex: \"1 0 auto\",\n        minWidth: \"1rem\",\n    },\n    shrinkingTab: {\n        background: \"pink\",\n        whiteSpace: \"nowrap\",\n        flex: \"0 1 auto\",\n        minWidth: 0,\n        overflow: \"hidden\",\n    },\n    truncateTitle: {\n        flex: \"0 1 auto\",\n        minWidth: 0,\n        overflow: \"hidden\",\n        textOverflow: \"ellipsis\",\n        whiteSpace: \"nowrap\",\n    },\n    branch: {\n        fontSize: \"80%\",\n        marginLeft: \"0.4rem\",\n        color: theme.versionHistory.branch.color.toString(),\n        backgroundColor: theme.versionHistory.branch.background.toString(),\n        border: \"1px solid \" + theme.versionHistory.branch.border.toString(),\n        padding: \"0 0.4rem 0 0.6rem\",\n        borderRadius: \"0.4rem\",\n        overflow: \"hidden\",\n        textOverflow: \"ellipsis\",\n        maxWidth: \"6rem\",\n        whiteSpace: \"nowrap\",\n        display: \"flex\",\n        alignItems: \"center\",\n        gap: \"0.3rem\",\n    },\n    branchIcon: {\n        fontSize: \"0.9em\",\n    },\n}));\n\ninterface HeaderProps {\n    tab: BottomPanelTabHeader;\n    icon: IconProp;\n    children?: React.ReactNode;\n    onClose?: (e: React.MouseEvent) => void;\n    className?: string;\n    server?: boolean;\n    allowClose?: boolean;\n}\n\nconst Header: React.FC<HeaderProps> = ({ tab, icon, children, onClose, className, server, allowClose = false }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { classes } = useStyles();\n    const currentHeight = useSelector(getBottomPanelHeight);\n    const { onVisibilityChange } = useBottomPanelContext();\n    const currentTab = useSelector(getBottomPanelCurrentTab);\n    const selected = !!(currentTab && bottomTabsMatch(tab, currentTab));\n\n    const elementRef = useRef<HTMLLIElement>(null);\n\n    const scrollIntoView = useEffectEvent(() => {\n        if (currentTab && bottomTabsMatch(tab, currentTab)) {\n            elementRef.current?.scrollIntoView({ behavior: \"smooth\" });\n        }\n    });\n    useEffectWhen(selected, scrollIntoView, [currentTab]);\n    // was used incase the tab is already the selected tab\n    // useSubscribeToDispatchEvent(EVENTS.OPEN_OR_FOCUS_BOTTOM_TAB, scrollIntoView);\n\n    useIsInView(\n        elementRef,\n        (isInView) => {\n            onVisibilityChange(tab, isInView);\n        },\n        { threshold: 0.6 }\n    );\n\n    const onAuxClick: React.MouseEventHandler = useEvent((e) => {\n        if (allowClose) {\n            onClose?.(e);\n        }\n    });\n\n    const onClick: React.MouseEventHandler = useEvent((e) => {\n        if (currentHeight < 50) {\n            // Do we want this to be bigger? Height at which clicking on an active tab expands rather than closes.\n            // onOpen will make sure that we are atleast 150 - see openOrFocusBottomTab\n            dispatch(openOrFocusBottomTab(tab));\n        } else {\n            if (selected) {\n                dispatch(closeBottomPanel());\n            } else {\n                dispatch(openOrFocusBottomTab(tab));\n            }\n        }\n    });\n\n    return (\n        <li\n            ref={elementRef}\n            role=\"button\"\n            tabIndex={0}\n            className={cx(\n                classes.shrinkingTab,\n                classes.tab,\n                selected && classes.selected,\n                className,\n                server && classes.server\n            )}\n            onClick={onClick}\n            onAuxClick={onAuxClick}>\n            <FontAwesomeIcon className={classes.tabIcon} icon={icon} />\n            <div className={classes.truncateTitle}>{tab.title}</div>\n            {children}\n            {allowClose && (\n                <LinkInternal preventDefaultClick className={classes.tabCloseButton} onClick={(e) => onClose?.(e)}>\n                    <FontAwesomeIcon icon={faTimes} />\n                </LinkInternal>\n            )}\n        </li>\n    );\n};\n\ninterface BaseTabHeaderProps {\n    tab: BottomPanelTabHeader;\n}\nconst RunnerReplHeader: React.FC<BaseTabHeaderProps> = ({ tab }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { isOpen } = useBottomPanelContext();\n    const currentTab = useSelector(getBottomPanelCurrentTab);\n    const runnerOutput = useSelector(getRunnerOutput);\n    // Streamed BG-task output goes to state.runnerBgTasks (not debug.output), so count it\n    // explicitly or the badge would only tick for the task-launch markers.\n    const bgTaskOutputCount = useSelector(getRunnerBgTaskOutputCount);\n    const runnerRepl = useSelector(getRunnerRepl);\n    const [seenRunnerOutputLines, setSeenRunnerOutputLines] = useState(0);\n    const totalOutputLines = runnerOutput.length + bgTaskOutputCount;\n\n    if (seenRunnerOutputLines > totalOutputLines) {\n        setSeenRunnerOutputLines(totalOutputLines);\n    }\n\n    if (isOpen && currentTab?.type === \"runnerRepl\" && totalOutputLines > seenRunnerOutputLines) {\n        setSeenRunnerOutputLines(totalOutputLines);\n    }\n\n    let outputNotification = null;\n    if (seenRunnerOutputLines < totalOutputLines) {\n        outputNotification = <span style={{ color: \"red\" }}>&nbsp;({totalOutputLines - seenRunnerOutputLines})</span>;\n    }\n\n    if (!runnerRepl) {\n        return null;\n    }\n\n    return (\n        <Header\n            tab={tab}\n            icon={faTerminal}\n            onClose={() => dispatch(destroyRepl(runnerRepl))}\n            allowClose={runnerRepl.readOnly}>\n            {outputNotification}\n        </Header>\n    );\n};\n\nconst VersionHistoryHeader: React.FC<BaseTabHeaderProps> = ({ tab }) => {\n    const editState = useSelector(getAppEditState);\n    const { classes } = useStyles();\n    const refs = useSelector(getAppRefs);\n\n    const hasMultipleBranches = useMemo(() => Object.keys(refs?.branches ?? {}).length > 1, [refs?.branches]);\n\n    const currentTag = useMemo(() => {\n        if (!editState?.commitId || editState?.branch) return null;\n        return Object.entries(refs?.tags || {}).find(([name, { commitId }]) => commitId === editState.commitId)?.[0];\n    }, [editState?.commitId, editState?.branch, refs?.tags]);\n\n    const displayValue = currentTag || editState?.branch;\n    const refIcon = currentTag && faTag;\n\n    return (\n        <Header tab={tab} icon={faCodeBranch}>\n            {hasMultipleBranches && displayValue && (\n                <div className={classes.branch} title={displayValue}>\n                    {refIcon && <FontAwesomeIcon icon={refIcon} className={classes.branchIcon} />}\n                    <div>{displayValue}</div>\n                </div>\n            )}\n        </Header>\n    );\n};\n\nconst DesignerOutputHeader: React.FC<BaseTabHeaderProps> = ({ tab }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { isOpen } = useBottomPanelContext();\n    const currentTab = useSelector(getBottomPanelCurrentTab);\n    const designerOutput = useSelector(getDesignerOutput);\n    const [seenDesignerOutputLines, setSeenDesignerOutputLines] = useState(0);\n\n    if (seenDesignerOutputLines > designerOutput.length) {\n        setSeenDesignerOutputLines(designerOutput.length);\n    }\n\n    if (isOpen && currentTab?.type === \"designerOutput\" && (designerOutput?.length ?? 0) > seenDesignerOutputLines) {\n        setSeenDesignerOutputLines(designerOutput?.length ?? 0);\n    }\n\n    let designerNotification = null;\n    if (seenDesignerOutputLines < designerOutput.length) {\n        designerNotification = (\n            <span style={{ color: \"red\" }}>&nbsp;({designerOutput.length - seenDesignerOutputLines})</span>\n        );\n    }\n\n    return (\n        <Header tab={tab} icon={faObjectGroup} allowClose onClose={() => dispatch(closeDesignerOutput())}>\n            {designerNotification}\n        </Header>\n    );\n};\n\nconst ScriptRunHeader: React.FC<BaseTabHeaderProps> = ({ tab }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const scriptRuns = useSelector(getScriptRuns);\n    const scriptRunTab = tab as BottomPanelTabTargetScriptRun;\n    const runs = scriptRuns[scriptRunTab.scriptName] || [];\n    const isTerminated = runs.every((r) => r.state === \"TERMINATED\");\n\n    return (\n        <Header\n            tab={tab}\n            icon={faPlay}\n            allowClose={isTerminated}\n            onClose={() => dispatch(deleteScriptRuns(scriptRunTab.scriptName))}\n        />\n    );\n};\n\nconst OnboardingCtaHeader: React.FC<BaseTabHeaderProps> = ({ tab }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const tutorial = useSelector(getWhereToStartTutorial);\n\n    return (\n        <Header\n            tab={tab}\n            icon={tutorial === \"scriptsTutorial\" ? faTerminal : faObjectGroup}\n            allowClose\n            onClose={() => dispatch(dismissOnboardingCtaTab())}\n        />\n    );\n};\n\nconst BottomPanelHeader: React.FC<BaseTabHeaderProps> = ({ tab }) => {\n    const { classes } = useStyles();\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    switch (tab.type) {\n        case \"tutorial\":\n            return <Header tab={tab} icon={faLightbulb} allowClose onClose={() => dispatch(closeTutorialTab())} />;\n        case \"roadmap\":\n            return <Header tab={tab} icon={faRoad} allowClose onClose={() => dispatch(enableRoadmap(false))} />;\n        case \"versionHistory\":\n            return <VersionHistoryHeader tab={tab} />;\n        case \"backgroundTasks\":\n            return <Header tab={tab} icon={faTasksAlt} />;\n        case \"introVideo\":\n            return <Header tab={tab} icon={faVideo} />;\n        case \"onboardingCta\":\n            return <OnboardingCtaHeader tab={tab} />;\n        case \"talkToUs\":\n            return <Header tab={tab} icon={faGift} />;\n        case \"appCta\":\n            return <Header tab={tab} icon={faHammer} />;\n        case \"conflicts\":\n            return <Header tab={tab} icon={faExclamationTriangle} className={classes.conflicts} />;\n        case \"designerOutput\":\n            return <DesignerOutputHeader tab={tab} />;\n        case \"breakpoints\":\n            return <Header tab={tab} icon={faTools} />;\n        case \"runnerRepl\":\n            return <RunnerReplHeader tab={tab} />;\n        case \"serverRepl\":\n            return (\n                <Header tab={tab} icon={faTerminal} server onClose={() => dispatch(destroyRepl(tab.repl))} allowClose />\n            );\n        case \"tableauRepl\": {\n            return <Header tab={tab} icon={faAnvilX} onClose={() => dispatch(destroyRepl(tab.repl))} allowClose />;\n        }\n        case \"debugger\":\n            return (\n                <Header tab={tab} icon={faBug}>\n                    (<span style={{ textTransform: \"capitalize\" }}>{tab.subText}</span>)\n                </Header>\n            );\n        case \"ideTutorial\":\n            return <Header tab={tab} icon={faShieldHalved} />;\n        case \"scriptRun\":\n            return <ScriptRunHeader tab={tab} />;\n        case \"agent\":\n            return <Header tab={tab} icon={faSparkle} allowClose onClose={() => dispatch(closeBottomPanelConversation(tab.conversationPid))} />;\n        case \"serverTests\":\n            return <Header tab={tab} icon={faFlask} />;\n        default:\n            return null;\n    }\n};\n\nconst getTabKey = (tab: BottomPanelTabHeader) => {\n    return `${tab.type}-${\"replId\" in tab ? tab.replId\n        : \"scriptName\" in tab ? tab.scriptName\n            : \"hyperstackId\" in tab ? tab.hyperstackId\n                : \"conversationPid\" in tab ? tab.conversationPid\n                    : \"\"}`;\n};\n\ninterface BottomPanelContextType {\n    isOpen: boolean;\n    onVisibilityChange: (tab: BottomPanelTabHeader, isVisible: boolean) => void;\n}\n\nconst BottomPanelContext = createContext<BottomPanelContextType | null>(null);\nconst useBottomPanelContext = createContextHook(BottomPanelContext, \"bottomPanelOutputContext\");\n\nconst BottomPanel = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const app = useSelector(getApp);\n    const isOpen = useSelector(getBottomPanelIsOpen);\n    const currentTab = useSelector(getBottomPanelCurrentTab);\n    const debuggerHyperStacks = useSelector(getDebuggerHyperStacks);\n    const repls = useSelector(getRepls);\n    const appCta = useSelector(getAppCta);\n    const whereToStartTutorial = useSelector(getWhereToStartTutorial);\n    const showRoadmap = useSelector(getShowRoadmap);\n    const bottomPanelTabs = useSelector(getBottomPanelTabs);\n    const { classes } = useStyles();\n\n    const testingEnabled = useSelector(getTestingEnabled);\n\n    const [visibleTabs, setVisibleTabs] = useState(() => new Set());\n\n    const currentTabComponent = useMemo(() => {\n        if (!currentTab) return null;\n\n        switch (currentTab.type) {\n            case \"designerOutput\":\n                return <DesignerOutput />;\n            case \"appCta\":\n                return appCta?.preset && validCtas[appCta.preset] ? <BuildThis /> : null;\n            case \"versionHistory\":\n                return <History />;\n            case \"conflicts\":\n                return <Conflicts />;\n            case \"backgroundTasks\":\n                return <BackgroundTasks myActiveTasksOnly={true} />;\n            case \"tutorial\":\n                return <TutorialPanel />;\n            case \"roadmap\":\n                return <RoadmapPanel />;\n            case \"breakpoints\":\n                return <Breakpoints />;\n            case \"introVideo\":\n                return <IntroVideoPanel />;\n            case \"onboardingCta\":\n                return whereToStartTutorial ? <WhereToStartTutorialPanel tutorial={whereToStartTutorial} /> : null;\n            case \"talkToUs\":\n                return <TalkToUsOffer variant=\"bottomPanel\" />;\n            case \"runnerRepl\":\n            case \"serverRepl\":\n            case \"tableauRepl\":\n                return currentTab.replId && repls[currentTab.replId] ? (\n                    <REPL key={currentTab.replId} id={currentTab.replId} repl={repls[currentTab.replId]} />\n                ) : null;\n            case \"debugger\":\n                const dbg = debuggerHyperStacks[currentTab.hyperstackId];\n                return dbg ? (\n                    <DebugInspector\n                        key={currentTab.hyperstackId}\n                        hyperstackId={currentTab.hyperstackId}\n                        hyperstack={dbg}\n                    />\n                ) : null;\n            case \"ideTutorial\":\n                return <IDETutorialPanel />;\n            case \"scriptRun\":\n                return <ScriptOutputTab scriptName={currentTab.scriptName} />;\n            case \"agent\":\n                return <AgentPanel conversationPid={currentTab.conversationPid} />;\n            case \"serverTests\":\n                return testingEnabled ? <ServerTestsBottomPanel /> : null;\n            default:\n                return null;\n        }\n    }, [currentTab, appCta, repls, debuggerHyperStacks, classes, testingEnabled]);\n\n    const roadmapAbFlag = useRoadmapAbFlag();\n    const inTutorialMode = useSelector(getInTutorialMode);\n\n    // Assigns the AB arm, runs the countdown and opens the offer tab. Needed here as well as in\n    // TalkToUsOffer, because until the arm is assigned there is no tab to render the offer in.\n    useTalkToUsOffer();\n\n    useEffect(() => {\n        if (inTutorialMode && !currentTab) {\n            dispatch(openOrFocusBottomTab({ type: \"ideTutorial\" }));\n        } else if ((roadmapAbFlag && showRoadmap == null) || localStorage[\"forceShowAnvilRoadmap\"]) {\n            dispatch(enableRoadmap(true));\n        }\n    }, []);\n\n    const launchServerRepl = useCallback(async () => {\n        if (\n            !app?.config?.runtime_options?.server_spec &&\n            /sandbox/.test(app?.config?.runtime_options?.server_version || \"\")\n        ) {\n            await dispatch(\n                alert(\n                    \"Full Python server required\",\n                    \"Server REPLs are only supported on Full Python servers. Switch to a full Python server runtime to use this feature.\"\n                )\n            );\n            dispatch(navigate({ type: \"PYTHON_DEPENDENCIES\" }));\n        } else {\n            dispatch(createRepl(\"server\"));\n        }\n    }, [app?.config?.runtime_options?.server_version, app?.config?.runtime_options?.server_spec, dispatch]);\n\n    const onVisibilityChange = useEvent((tab: BottomPanelTabHeader, isVisible: boolean) => {\n        setVisibleTabs((prev) => {\n            const next = new Set(prev);\n            const key = getTabKey(tab);\n            if (isVisible) {\n                next.add(key);\n            } else {\n                next.delete(key);\n            }\n            return next;\n        });\n    });\n\n    const bottomTabsWithVisibility = useMemo(\n        () =>\n            bottomPanelTabs.map((tab) => ({\n                ...tab,\n                inView: visibleTabs.has(getTabKey(tab)),\n            })),\n        [bottomPanelTabs, visibleTabs]\n    );\n\n    const { ddItems, showDropdown } = useMemo(() => {\n        const items: MenuItems = [];\n        let needsBreak: boolean | null = null;\n        bottomTabsWithVisibility.forEach((tab) => {\n            if (tab.inView === false) {\n                if (needsBreak) {\n                    items.push(<hr />);\n                    needsBreak = false;\n                }\n                items.push([tab.title, () => dispatch(openOrFocusBottomTab(tab))]);\n            } else if (tab.inView === true && items.length && needsBreak === null) {\n                needsBreak = true;\n            }\n        });\n        return { ddItems: items, showDropdown: items.length > 0 };\n    }, [bottomTabsWithVisibility]);\n\n    const bottomPanelContext = useMemoiseObject({ isOpen, onVisibilityChange });\n\n    useEffect(() => {\n        // this mostly happens with Hot module reloading, but also a fail safe if we have an invalid tab\n        if (!currentTab) return;\n        if (!bottomPanelTabs.some((tab) => bottomTabsMatch(tab, currentTab))) {\n            // console.log(\"Invalid tab\", currentTab);\n            dispatch(closeBottomTab(currentTab));\n        }\n    }, [currentTab, bottomPanelTabs]);\n\n    return (\n        <BottomPanelContext.Provider value={bottomPanelContext}>\n            <div className={cx(classes.root, isOpen && classes.open)}>\n                <ul className={cx(classes.tabBar, isOpen && classes.open, \"flex w-full\")}>\n                    <div className=\"m-0 no-scrollbar flex h-[3.9rem] flex-none shrink grow list-none overflow-x-auto overflow-y-hidden border-b border-sectionborder bg-light-bg2 p-0 text-[1.2rem] text-light-fg1 dark:border-dark-sectionborder dark:bg-dark-bg2\">\n                        {bottomTabsWithVisibility.map((tab) => (\n                            <BottomPanelHeader key={getTabKey(tab)} tab={tab} />\n                        ))}\n                    </div>\n\n                    {showDropdown && (\n                        <div className=\"flex items-center justify-center px-2 py-1\">\n                            <DropdownMenu\n                                render={(showMenu, anchor) => (\n                                    <>\n                                        <Button size={\"small\"} onClick={(e) => showMenu(null, e.currentTarget)}>\n                                            <FontAwesomeIcon icon={faWindowRestore} className={\"mr-2\"} />\n                                            <FontAwesomeIcon icon={faChevronDown} />\n                                        </Button>\n                                        {anchor}\n                                    </>\n                                )}\n                                items={(selectItem, hideMenu) => ddItems}\n                                align={\"right\"}\n                            />\n                        </div>\n                    )}\n                    {!inTutorialMode && (\n                        <div className={classes.tabRightContainer}>\n                            <Button\n                                title={\"Launch server REPL\"}\n                                titlePosition={\"left\"}\n                                small\n                                className={classes.tabRightIcon}\n                                onClick={launchServerRepl}>\n                                <FontAwesomeIcon fixedWidth icon={faTerminalHeavy} />\n                            </Button>\n                            <Button\n                                small\n                                className={classes.tabRightIcon}\n                                onClick={() => {\n                                    if (isOpen) {\n                                        dispatch(closeBottomPanel());\n                                    } else {\n                                        dispatch(openOrFocusPrevBottomTab());\n                                    }\n                                }}>\n                                <FontAwesomeIcon fixedWidth rotation={isOpen ? 90 : 270} icon={faChevronRightHeavy} />\n                            </Button>\n                        </div>\n                    )}\n                </ul>\n\n                {isOpen && (\n                    <div className={classes.content}>\n                        <ErrorBoundary deps={[currentTabComponent]}>{currentTabComponent}</ErrorBoundary>\n                    </div>\n                )}\n            </div>\n        </BottomPanelContext.Provider>\n    );\n};\n\nexport default BottomPanel;\n","import { useEffect, useMemo, useRef } from \"react\";\nimport { connect, useDispatch, useSelector } from \"react-redux\";\nimport { faRocket } from \"@fortawesome/free-solid-svg-icons/faRocket\";\nimport { faTimes } from \"@fortawesome/pro-light-svg-icons/faTimes\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { isEmpty } from \"lodash-es\";\nimport AccountPage from \"@/components/AccountPage\";\nimport Link from \"@/components/reusable/Link\";\nimport { getApp } from \"@/controllers/app\";\nimport { getBottomPanelHeight, getBottomPanelIsOpen, setBottomPanelHeight } from \"@/controllers/bottom-tabs\";\nimport { closeNotice, getSubscription, getZenMode } from \"@/controllers/ide\";\nimport { getSplitRunnerWidth, getUser, setSplitRunnerWidth } from \"@/controllers/ide\";\nimport { getInTutorialMode } from \"@/controllers/ideTutorial\";\nimport { modal } from \"@/controllers/modals\";\nimport { startUpgrade } from \"@/controllers/payment\";\nimport { getRunMode, getRunnerViewMaximised } from \"@/controllers/runner\";\nimport { getIsSidebarVisible } from \"@/controllers/sidebar\";\nimport { getEligibleOffers, getUserHasClosedFeedbackPromoBanner, updateUserEditorPrefs } from \"@/controllers/user\";\nimport { useNavTargetSelector } from \"@/router/navigation-hooks\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { AnvilConnectedProps, AnvilDispatch, State } from \"@/types\";\nimport { useResizeObserver } from \"@/util/hooks\";\nimport { dateAndDaysAway } from \"@/util/time\";\nimport useEvent from \"@/util/useEventCallback\";\nimport Header from \"./Header\";\nimport { RunnerIframe } from \"./Runner\";\nimport StartPage from \"./StartPage\";\nimport BottomPanel from \"./bottom_panel/BottomPanel\";\nimport { Button } from \"./reusable/Button\";\nimport { ErrorBoundary } from \"./reusable/ErrorBoundary\";\nimport ResizePanel from \"./sidebar/ResizePanel\";\nimport Sidebar from \"./sidebar/Sidebar\";\nimport TabPanel from \"./tabs/TabPanel\";\n\nconst useStyles = makeStyles()((theme) => ({\n    root: {\n        width: \"100%\",\n        height: \"100%\",\n        margin: \"auto\",\n        fontSize: \"1.4rem\",\n    },\n    mainPanel: {\n        width: \"100%\",\n        height: \"100%\",\n        background: theme.palette.bg0.hex(),\n        flex: \"1 0 0\",\n        display: \"flex\",\n        flexDirection: \"column\",\n        overflow: \"hidden\",\n    },\n    app: {\n        flex: \"1 0 0\",\n        display: \"flex\",\n        overflow: \"hidden\",\n    },\n    appPanels: {\n        flex: \"1 1 auto\",\n        display: \"flex\",\n        flexDirection: \"column\",\n        overflow: \"hidden\",\n    },\n    splitRunner: {\n        height: 0,\n        flex: \"1 0 auto\",\n        display: \"flex\",\n    },\n    bottomResizePanel: {\n        flex: \"0 0 auto\",\n    },\n    notice: {\n        padding: \"2px 0.6rem\",\n        background: theme.notice.background.toString(),\n        borderBottom: \"1px solid \" + theme.notice.borderBottom.toString(),\n        fontSize: \"1.1rem\",\n        borderRadius: 2,\n        whiteSpace: \"nowrap\",\n        color: theme.notice.color.toString(),\n        \"& a[href]\": {\n            color: theme.notice.linkColor.toString(),\n        },\n        textAlign: \"center\",\n    },\n    closeNotice: {\n        float: \"right\",\n        fontSize: \"1.6rem\",\n        paddingTop: \"0.4rem\",\n        cursor: \"pointer\",\n    },\n    warningNotice: {\n        background: \"#fdd\",\n    },\n}));\n\ntype IDEClasses = ReturnType<typeof useStyles>[\"classes\"];\n\nconst INTENT_STATUS = [\"requires_action\", \"requires_payment_method\", \"past_due\", \"unpaid\"] as const;\n\nconst NewUserFeedbackFormTutorialPromoBanner = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const eligibleOffers = useSelector(getEligibleOffers);\n\n    const closedPromoBanner = useSelector(getUserHasClosedFeedbackPromoBanner);\n\n    return eligibleOffers?.[\"feedback-tutorial\"] && !closedPromoBanner ? (\n        <div className={cx(\"bg-secondary px-[0.6rem] py-[0.2rem]\")}>\n            <div className={\"relative flex h-full w-full items-center justify-center\"}>\n                <FontAwesomeIcon\n                    className={\"absolute right-0 cursor-pointer\"}\n                    icon={faTimes}\n                    onClick={() => dispatch(updateUserEditorPrefs(\"userHasClosedFeedbackPromoBanner\", true))}\n                />\n                <div className={\"flex w-full items-center justify-center\"}>\n                    <div className={\"flex-initial text-pretty\"}>\n                        Complete our get started tutorial and get <span className={\"font-bold\"}>20% off</span> the Hobby\n                        Plan - forever!\n                    </div>\n                    <div className={\"px-4\"}>-</div>\n                    <div className={\"flex-initial text-pretty\"}>\n                        <Link\n                            to={\"/docs/overview/milestone-discounts\"}\n                            target={\"_blank\"}\n                            className=\"text-grey-2! underline\">\n                            Find out more\n                        </Link>\n                    </div>\n                </div>\n            </div>\n        </div>\n    ) : null;\n};\n\nconst TRIAL_EXPIRED_NOTICE = \"trial-expired\";\n\nconst SubscriptionBanner = ({ classes }: { classes: IDEClasses }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const subscription = useSelector(getSubscription);\n    const user = useSelector(getUser);\n\n    const [trialExpiryDate, trialDaysRemaining] = useMemo(() => dateAndDaysAway(subscription?.expires), [subscription]);\n\n    const onClearExpiredTrialNotification = useEvent(() => {\n        dispatch(closeNotice(TRIAL_EXPIRED_NOTICE));\n    });\n\n    return useMemo(() => {\n        if (!subscription || !user) return null;\n        if (isEmpty(subscription)) {\n            // No subscription left, but a trial on record: it has lapsed.\n            if (!user.trialOrg || user.closedNotices?.[TRIAL_EXPIRED_NOTICE]) return null;\n            return (\n                <div className={classes.notice}>\n                    <span>\n                        Your trial has <strong>expired</strong>.{\" \"}\n                        <Button tiny icon={faRocket} onClick={() => dispatch(startUpgrade(true, false))}>\n                            Upgrade now{\" \"}\n                        </Button>{\" \"}\n                        <FontAwesomeIcon\n                            className={classes.closeNotice}\n                            icon={faTimes}\n                            onClick={onClearExpiredTrialNotification}\n                        />\n                    </span>\n                </div>\n            );\n        }\n        if (subscription.trial) {\n            // Every trial is a trial of the Business plan, whatever plan the org itself is on.\n            return (\n                <div className={classes.notice}>\n                    <span>\n                        Your <strong>Business</strong> trial will expire in <strong>{trialDaysRemaining} days</strong>.{\" \"}\n                        <Button tiny icon={faRocket} onClick={() => dispatch(startUpgrade(false, true))}>\n                            Upgrade now\n                        </Button>\n                    </span>\n                </div>\n            );\n        }\n        if (subscription.cancelled) {\n            return (\n                <div className={classes.notice}>\n                    <span>This subscription has been cancelled and will terminate at the end of the time period.</span>\n                </div>\n            );\n        }\n        if (subscription.isStripeCustomer) {\n            if (\n                (subscription.setupIntent && INTENT_STATUS.includes(subscription.setupIntent.status)) ||\n                subscription.charges?.map((c: any) => c.status)?.includes(\"open\")\n            ) {\n                return (\n                    <div className={classes.notice}>\n                        An issue occurred with processing your payment. To continue using the paid features, please\n                        complete your payment.{\" \"}\n                        <Button tiny onClick={() => dispatch(modal(\"account\", { section: \"BILLING\" }))}>\n                            View Billing\n                        </Button>\n                    </div>\n                );\n            }\n        } else if (subscription.expires <= Date.now() + 6 * 7 * 24 * 60 * 60 * 1000) {\n            return (\n                <div className={classes.notice}>\n                    <span>\n                        Your renewal date is approaching please contact{\" \"}\n                        <b className=\"select-all\">billing@anvil.works</b>.\n                    </span>\n                </div>\n            );\n        }\n        return null;\n    }, [subscription, user]);\n};\n\nconst InterventionBanner = ({ classes }: { classes: IDEClasses }) => {\n    const user = useSelector(getUser);\n    const banner = user?.activeBanner;\n    if (!banner) return null;\n    return (\n        <div className={cx(classes.notice, classes.warningNotice)}>\n            <span>{banner}</span>\n        </div>\n    );\n};\n\nconst ImpersonatorBanner = ({ classes }: { classes: IDEClasses }) => {\n    const user = useSelector(getUser);\n    return user?.impersonator ? (\n        <div className={cx(classes.notice, classes.warningNotice)}>\n            <span>\n                You are impersonating <span className={\"font-mono font-bold select-all\"}>{user.email}</span>\n                {user?.readOnlyMode && \" with read only permissions in the IDE\"}.{\" \"}\n                <a className={\"text-primary-darker!\"} href={`/impersonate/${user.impersonator}`}>\n                    Click here to return to being{\" \"}\n                    <span className={\"font-mono font-bold select-all\"}>{user.impersonator}</span>.\n                </a>\n            </span>\n        </div>\n    ) : null;\n};\n\nconst LicenseWarning = ({ classes }: { classes: IDEClasses }) => {\n    const user = useSelector(getUser);\n    return (\n        user?.licence_warning && (\n            <div className={classes.notice}>\n                <strong>{user.licence_warning}</strong>\n                {/*<FontAwesomeIcon className={classes.closeNotice} icon={faTimes} onClick={() => dispatch(hideBetaBanner())}/>*/}\n            </div>\n        )\n    );\n};\n\ntype IDEProps = AnvilConnectedProps<typeof connector>;\n\nconst DesktopIDE = ({\n    app,\n    bottomPanelHeight,\n    splitRunnerWidth,\n    debugRunMode,\n    runnerMaximised,\n    isSidebarVisible,\n    bottomPanelOpen,\n    user,\n    zenMode,\n    dispatch,\n}: IDEProps) => {\n    const { classes } = useStyles();\n    let showSidebar = app?.$loaded && isSidebarVisible;\n\n    if (debugRunMode === \"INLINE\" && runnerMaximised) {\n        showSidebar = false;\n    }\n\n    const runnerResizePanel = useMemo(() => {\n        return (\n            debugRunMode === \"INLINE\" && (\n                <ResizePanel\n                    closed={runnerMaximised}\n                    enabled={!runnerMaximised}\n                    horizontal={true}\n                    panelSize={splitRunnerWidth}\n                    handleAtStart={true}\n                    onFinishDrag={(size) => dispatch(setSplitRunnerWidth(size))}>\n                    <ErrorBoundary>\n                        <RunnerIframe />\n                    </ErrorBoundary>\n                </ResizePanel>\n            )\n        );\n    }, [debugRunMode, runnerMaximised, splitRunnerWidth]);\n\n    const bottomResizePanel = useMemo(() => {\n        const panel = <BottomPanel />;\n        return (\n            app?.$loaded &&\n            (bottomPanelOpen ? (\n                <ResizePanel\n                    classes={{ root: classes.bottomResizePanel }}\n                    closed={!bottomPanelOpen}\n                    enabled={bottomPanelOpen}\n                    horizontal={false}\n                    panelSize={bottomPanelHeight}\n                    handleAtStart={true}\n                    onFinishDrag={(size) => dispatch(setBottomPanelHeight(size))}>\n                    {panel}\n                </ResizePanel>\n            ) : (\n                panel\n            ))\n        );\n    }, [app?.$loaded, classes, bottomPanelOpen, bottomPanelHeight]);\n\n    const showAccountPage = useNavTargetSelector((t) => t?.type === \"ACCOUNT\");\n    const showStartPage = useNavTargetSelector((t) => t?.type === \"START_PAGE\");\n    const inTutorialMode = useSelector(getInTutorialMode);\n    const hasLicenceWarning = !!user?.licence_warning;\n\n    const contentRef = useRef<HTMLDivElement>(null);\n\n    const appPanelsRef = useRef<HTMLDivElement>(null);\n\n    const keepWidthReasonable = useEvent(() => {\n        const splitWidthInt = parseInt(splitRunnerWidth);\n        const entirePanelWidth = appPanelsRef.current?.clientWidth ?? 0;\n        const editorWidth = entirePanelWidth - splitWidthInt;\n\n        if (entirePanelWidth < 400) {\n            dispatch(setSplitRunnerWidth(entirePanelWidth / 2));\n        } else if (editorWidth <= 200) {\n            dispatch(setSplitRunnerWidth(entirePanelWidth - 200));\n        }\n    });\n\n    useEffect(() => keepWidthReasonable(), [keepWidthReasonable]);\n\n    useResizeObserver(appPanelsRef, (s) => {\n        keepWidthReasonable();\n    });\n\n    return (\n        <div className={classes.root} tabIndex={-1}>\n            <div className={classes.mainPanel}>\n                {hasLicenceWarning && <LicenseWarning classes={classes} />}\n                <InterventionBanner classes={classes} />\n                <ImpersonatorBanner classes={classes} />\n                {!hasLicenceWarning && <SubscriptionBanner classes={classes} />}\n                {!inTutorialMode && <NewUserFeedbackFormTutorialPromoBanner />}\n                {!zenMode && <Header />}\n                <AccountPage visible={showAccountPage} contentRef={contentRef} />\n                <div className={classes.app} ref={contentRef}>\n                    {showSidebar && !inTutorialMode && !zenMode && <Sidebar />}\n                    <div className={classes.appPanels} ref={appPanelsRef}>\n                        {app && !app.$loading && (\n                            <div className={classes.splitRunner}>\n                                {debugRunMode === \"INLINE\" && runnerMaximised ? null : <TabPanel />}\n                                {runnerResizePanel}\n                            </div>\n                        )}\n                        {/* Why isn't the StartPage outside all this app nonsense? */}\n                        {!app && (showStartPage || showAccountPage) && <StartPage />}\n                        {!zenMode && bottomResizePanel}\n                    </div>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nconst connector = connect((state: State) => ({\n    app: getApp(state),\n    bottomPanelHeight: getBottomPanelHeight(state),\n    splitRunnerWidth: getSplitRunnerWidth(state),\n    debugRunMode: getRunMode(state),\n    runnerMaximised: getRunnerViewMaximised(state),\n    isSidebarVisible: getIsSidebarVisible(state),\n    bottomPanelOpen: getBottomPanelIsOpen(state),\n    user: getUser(state),\n    zenMode: getZenMode(state),\n}));\n\nexport default connector(DesktopIDE);\n","import React, { useMemo, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport { MultiSelectDropDown, SingleSelectDropDown } from \"@/components/reusable/selectdropdown\";\nimport { SelectionItem } from \"@/components/reusable/selectdropdown/SelectDropDown\";\nimport { submitSurvey } from \"@/controllers/ide\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useStateWithCustomUpdate } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { QuestionProps, welcomeSurveys } from \"@/util/userSurveys\";\n\ninterface AnswerProps {\n    answer: string;\n    det: string | null;\n}\n\ninterface SurveyResponsesProps {\n    [key: string]: AnswerProps | AnswerProps[];\n}\n\ninterface parsedResponseProps {\n    answer: string;\n    otherOption?: string;\n}\n\ninterface SurveyQuestionProps {\n    surveyQuestion: QuestionProps;\n    surveyResponses: any;\n    recordResponses: (surveyResponses: SurveyResponsesProps) => void;\n}\n\nconst SurveyQuestion = ({\n    surveyQuestion: { id, type, question, reorderOptions, responses: possibleResponses, otherOption },\n    surveyResponses,\n    recordResponses,\n}: SurveyQuestionProps) => {\n    const reorderedResponses = useMemo(() => {\n        const reordered =\n            (reorderOptions ?? true)\n                ? possibleResponses\n                      .map((value) => ({ value, sort: Math.random() }))\n                      .sort((a, b) => a.sort - b.sort)\n                      .map(({ value }) => {\n                          return { value };\n                      })\n                : possibleResponses.map((value) => ({ value }));\n        if (otherOption) {\n            reordered.push({ value: \"Other\" });\n        }\n        return reordered;\n    }, [possibleResponses, otherOption]);\n\n    const [otherInput, setOtherInput] = useState<string | null>(\"\");\n    const [showOther, setShowOther] = useStateWithCustomUpdate<boolean>(false, (val: boolean) => {\n        if (!val) {\n            setOtherInput(null);\n        }\n        return val;\n    });\n\n    const updateSingleSelect = useEvent((answer: SelectionItem[\"value\"], dets: string | null = null) => {\n        setShowOther(answer === \"Other\");\n        const resp = { ...surveyResponses };\n        setOtherInput(dets);\n        resp[id] = { answer, det: answer === \"Other\" ? dets : null };\n        recordResponses(resp);\n    });\n\n    const updateMultiSelect = useEvent((answer: SelectionItem[\"value\"][], dets: string | null = null) => {\n        if (dets) setOtherInput(dets);\n        setShowOther(answer.includes(\"Other\"));\n\n        const updatedAnswers = answer.map((a) => {\n            return { answer: a, det: a === \"Other\" ? dets || otherInput : null };\n        });\n        const allResponses = { ...surveyResponses };\n\n        if (updatedAnswers.length > 0) {\n            allResponses[id] = updatedAnswers;\n        } else {\n            delete allResponses[id];\n        }\n\n        recordResponses(allResponses);\n    });\n\n    switch (type) {\n        case \"singleSelect\": {\n            return (\n                <>\n                    <Text level={1} className={\"font-semibold! dark:text-white!\"}>\n                        {\" \"}\n                        {question}\n                    </Text>\n                    <SingleSelectDropDown\n                        items={reorderedResponses}\n                        value={surveyResponses?.[id]?.answer}\n                        className={\"w-full!\"}\n                        placeholder={\"Make a selection\"}\n                        onChange={(r) => updateSingleSelect(r)}\n                    />\n                    {showOther && (\n                        <div className={\"mx-8 flex w-2/3 items-center justify-center gap-4\"}>\n                            <Text>Other:</Text>\n                            <ContentTextInput\n                                value={otherInput || \"\"}\n                                small\n                                onChange={(e) => updateSingleSelect(surveyResponses?.[id]?.answer, e.target.value)}\n                            />\n                        </div>\n                    )}\n                </>\n            );\n        }\n        case \"multiSelect\": {\n            const selectedResponses = (surveyResponses?.[id] ?? []).map(({ answer }: any) => answer);\n            return (\n                <>\n                    <Text level={1} className={\"font-semibold! dark:text-white!\"}>\n                        {\" \"}\n                        {question}\n                    </Text>\n                    <MultiSelectDropDown\n                        items={reorderedResponses}\n                        selected={selectedResponses}\n                        className={\"w-full!\"}\n                        placeholder={\"Select all that apply\"}\n                        onChange={(r) => updateMultiSelect(r)}\n                    />\n                    {showOther && (\n                        <div className={\"mx-8 flex w-2/3 items-center justify-center gap-4\"}>\n                            <Text>Other:</Text>\n                            <ContentTextInput\n                                value={otherInput || \"\"}\n                                small\n                                onChange={(e) => updateMultiSelect(selectedResponses, e.target.value)}\n                            />\n                        </div>\n                    )}\n                </>\n            );\n        }\n        default:\n            return <div>Not valid type</div>;\n    }\n};\n\nconst Survey = ({ survey }: { survey: string }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const [surveyResponses, setSurveyResponses] = useState<SurveyResponsesProps>({});\n\n    const handleSurveySubmit = useEvent(() => {\n        const parsedResponses: Record<string, any> = {};\n\n        Object.entries(surveyResponses || {}).forEach(([questionId, answer]) => {\n            if (Array.isArray(answer)) {\n                parsedResponses[questionId] = [];\n                answer.forEach((selection) => {\n                    const entry: parsedResponseProps = { answer: selection.answer };\n                    if (selection.answer === \"Other\") entry.otherOption = selection.det || \"\";\n                    parsedResponses[questionId].push(entry);\n                });\n            } else {\n                parsedResponses[questionId] = { answer: answer.answer };\n                if (answer.answer === \"Other\") {\n                    parsedResponses[questionId].otherOption = answer.det;\n                }\n            }\n        });\n\n        const surveyResponse = { id: survey, answers: parsedResponses };\n\n        dispatch(submitSurvey(surveyResponse));\n    });\n\n    const surveyData = welcomeSurveys[survey];\n    const disableSubmit = Object.keys(surveyResponses).length !== surveyData?.length;\n\n    return (\n        <>\n            <div className={\"absolute top-0 z-150 h-full w-full bg-black/30 backdrop-blur-sm backdrop-grayscale-0\"} />\n            <div className={\"absolute top-0 z-150 flex h-full w-full items-center justify-center\"}>\n                <div\n                    className={\n                        \"grid min-h-168 w-300 grid-cols-10 border border-sectionborder dark:border-dark-sectionborder\"\n                    }>\n                    <div\n                        className={cx(\n                            \"col-span-3 flex flex-col items-center justify-center border-r border-sectionborder bg-light-bg2 text-center! dark:border-dark-sectionborder dark:bg-dark-bg0\"\n                        )}>\n                        <Heading level={1} className={\"px-12 text-5xl! leading-16! dark:text-white!\"}>\n                            Welcome to Anvil\n                        </Heading>\n                        <Text level={2} className={\"px-12 leading-9!\"}>\n                            We're eager to hear more about you.\n                        </Text>\n                    </div>\n                    <div className={\"col-span-7 flex flex-col justify-center bg-white p-16 dark:bg-dark-bg3\"}>\n                        {surveyData.map((q, i) => (\n                            <SurveyQuestion\n                                key={i}\n                                surveyQuestion={q}\n                                surveyResponses={surveyResponses}\n                                recordResponses={setSurveyResponses}\n                            />\n                        ))}\n\n                        <div className={\"mt-12\"}>\n                            <Button disabled={disableSubmit} variant={\"primary\"} onClick={handleSurveySubmit}>\n                                Submit & Start Building\n                            </Button>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </>\n    );\n};\n\nexport default Survey;\n","import { useDispatch } from \"react-redux\";\nimport { faGift } from \"@fortawesome/pro-solid-svg-icons/faGift\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport { openTalkToUsScheduling, TalkToUsOfferPlacement, useTalkToUsOffer } from \"@/controllers/talkToUsOffer\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\n\nconst MEREDYDD_PHOTO = new URL(\"../../assets/img/meredydd.jpg\", import.meta.url).href;\n\n/**\n * The 2026-08 \"book a feedback call, get a gift card\" offer. Renders nothing unless the user is\n * eligible - see controllers/talkToUsOffer for the gating and the countdown.\n */\nexport const TalkToUsOffer = ({ variant }: { variant: TalkToUsOfferPlacement }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    // Also assigns the banner-test arm, and expires each arm on its own schedule\n    const { show, arm, countdown } = useTalkToUsOffer();\n\n    if (!show) return null;\n\n    const card = arm === \"original\" ? (\n        <div\n            className={cx(\n                \"flex items-start gap-8 p-8 pt-2 rounded-md border-2 border-primary bg-light-bg2 dark:border-primary dark:bg-dark-bg3\",\n                variant === \"startPage\" ? \"mb-14 max-w-436\" : \"max-w-436\"\n            )}>\n            <img src={MEREDYDD_PHOTO} alt=\"Meredydd Luff\" className=\"mt-8 size-36 lg:size-64 shrink-0 rounded-full object-cover\"/>\n            <div className=\"min-w-0\">\n                <Heading level={1} className=\"flex items-center gap-4 pb-2\">\n                    <FontAwesomeIcon className=\"text-primary\" icon={faGift}/>\n                    1:1 with our founder\n                </Heading>\n                <Text level={1} className=\"text-xl\">\n                    Book a call within {\" \"}\n                    <span className=\"font-bold whitespace-nowrap\">{countdown}</span> for a{\" \"}\n                    <span className=\"font-bold\">$75 Amazon gift card.</span>\n                </Text>\n                <div className=\"my-6\">\n                    <Button variant=\"primary\" onClick={() => dispatch(openTalkToUsScheduling(variant, arm))}>\n                        Pick a time\n                    </Button>\n                </div>\n                <Text level={1} className=\"text-xl\">\n                    We know you've only just signed up, but first impressions are important, and we need yours.\n                </Text>\n            </div>\n        </div>\n    ) : arm === \"personal\" ? (\n        <div\n            className={cx(\n                \"flex items-start gap-8 p-8 pt-2 rounded-md border-2 border-primary bg-light-bg2 dark:border-primary dark:bg-dark-bg3\",\n                variant === \"startPage\" ? \"mb-14 max-w-436\" : \"max-w-436\"\n            )}>\n            <img src={MEREDYDD_PHOTO} alt=\"Meredydd Luff\" className=\"mt-8 size-36 lg:size-64 shrink-0 rounded-full object-cover\"/>\n            <div className=\"min-w-0\">\n                <Heading level={1} className=\"flex items-center gap-4 pb-2\">\n                    <FontAwesomeIcon className=\"text-primary\" icon={faGift}/>\n                    1:1 with an Anvil founder\n                </Heading>\n                <Text level={1} className=\"text-xl\">\n                    Book a call within {\" \"}\n                    <span className=\"font-bold whitespace-nowrap\">{countdown}</span> for a free{\" \"}\n                    <span className=\"font-bold\">1:1 consultation with one of our founders.</span>\n                </Text>\n                <div className=\"my-6\">\n                    <Button variant=\"primary\" onClick={() => dispatch(openTalkToUsScheduling(variant, arm))}>\n                        Pick a time\n                    </Button>\n                </div>\n                <Text level={1} className=\"text-xl\">\n                    I want to know what you're building with Anvil! In exchange, I'll give you some free consulting and as many pointers as I can. Sound fair?\n                </Text>\n            </div>\n        </div>\n    ) : (\n        <div\n            className={cx(\n                \"flex items-start gap-8 p-8 pt-2 rounded-md border-2 border-primary bg-light-bg2 dark:border-primary dark:bg-dark-bg3\",\n                variant === \"startPage\" ? \"mb-14 max-w-436\" : \"max-w-436\"\n            )}>\n            <img src={MEREDYDD_PHOTO} alt=\"Meredydd Luff\" className=\"mt-8 size-36 lg:size-64 shrink-0 rounded-full object-cover\"/>\n            <div className=\"min-w-0\">\n                <Heading level={1} className=\"flex items-center gap-4 pb-2\">\n                    <FontAwesomeIcon className=\"text-primary\" icon={faGift}/>\n                    1:1 with an Anvil founder\n                </Heading>\n                <Text level={1} className=\"text-xl\">\n                    Get a free{\" \"}\n                    <span className=\"font-bold\">1:1 consultation with one of our founders.</span>\n                </Text>\n                <div className=\"my-6\">\n                    <Button variant=\"primary\" onClick={() => dispatch(openTalkToUsScheduling(variant, arm))}>\n                        Pick a time\n                    </Button>\n                </div>\n                <Text level={1} className=\"text-xl\">\n                    I want to know what you're building with Anvil! In exchange, I'll give you some free consulting and as many pointers as I can. Sound fair?\n                </Text>\n            </div>\n        </div>\n    );\n\n    // The bottom panel is short and user-resizable, so its content has to be able to scroll.\n    return variant === \"bottomPanel\" ? <div className=\"h-full overflow-y-auto p-8\">{card}</div> : card;\n};\n\nexport default TalkToUsOffer;\n","import React, { useMemo } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { useAgentsEnabled } from \"@/controllers/agents\";\nimport { submitSurvey } from \"@/controllers/ide\";\nimport { updateUserEditorPrefs } from \"@/controllers/user\";\nimport { WHERE_TO_START_ANSWER_PREF } from \"@/controllers/whereToStartTutorials\";\n\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\nimport {\n    WHERE_TO_START_OPTIONS,\n    WHERE_TO_START_QUESTION_ID,\n    WHERE_TO_START_SURVEY_ID,\n    WhereToStartOptionId,\n} from \"@/util/userSurveys\";\nimport { Heading } from \"./reusable/Text\";\n\nconst AI_AGENT_OPTION_ID: WhereToStartOptionId = \"prompt-ai-agent\";\n\n// Every answer leaves the user on the Start Page. Some answers get a tutorial advertised\n// there and in the bottom panel - see controllers/whereToStartTutorials.\nconst WhereToStartSurvey = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const agentsEnabled = useAgentsEnabled();\n\n    const options = useMemo(\n        () => WHERE_TO_START_OPTIONS.filter((option) => agentsEnabled || option.id !== AI_AGENT_OPTION_ID),\n        [agentsEnabled]\n    );\n\n    const chooseOption = useEvent((optionId: WhereToStartOptionId) => {\n        dispatch(\n            submitSurvey({\n                id: WHERE_TO_START_SURVEY_ID,\n                answers: {\n                    [WHERE_TO_START_QUESTION_ID]: { answer: optionId },\n                },\n            })\n        );\n        dispatch(updateUserEditorPrefs(WHERE_TO_START_ANSWER_PREF, optionId));\n    });\n\n    return (\n        <>\n            <div className=\"absolute top-0 z-150 h-full w-full bg-black/30 backdrop-blur-sm backdrop-grayscale-0\" />\n            <div className=\"absolute top-0 z-150 flex h-full w-full items-center justify-center\">\n                <div className=\"grid min-h-124 w-260 grid-cols-10 border border-sectionborder dark:border-dark-sectionborder\">\n                    <div\n                        className={cx(\n                            \"col-span-3 flex flex-col items-center justify-center border-r border-sectionborder bg-light-bg2 text-center! dark:border-dark-sectionborder dark:bg-dark-bg0\"\n                        )}>\n                        <Heading level={1} className=\"px-12 text-4xl! leading-14! dark:text-white!\">\n                            Welcome to Anvil\n                        </Heading>\n                    </div>\n                    <div className=\"col-span-7 flex min-w-0 flex-col justify-center bg-white px-16 py-18 dark:bg-dark-bg3\">\n                        <Heading level={1} className=\"mb-12 text-center font-medium! dark:text-white!\">\n                            Where do you want to start?\n                        </Heading>\n                        <div className=\"mx-auto flex w-full max-w-136 flex-col gap-6\">\n                            {options.map((option) => (\n                                <button\n                                    key={option.id}\n                                    type=\"button\"\n                                    className={cx(\n                                        \"min-h-17 w-full rounded-[0.4rem] border-2 border-sectionborder bg-transparent px-10 py-4 dark:border-dark-sectionborder\",\n                                        \"text-center text-xl/8 font-medium text-light-grey2 dark:text-white\",\n                                        \"hover:border-primary hover:bg-sidebar-highlight1 dark:hover:bg-dark-bg3/40\"\n                                    )}\n                                    onClick={() => chooseOption(option.id)}>\n                                    {option.label}\n                                </button>\n                            ))}\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </>\n    );\n};\n\nexport default WhereToStartSurvey;\n","import React, { useContext, useMemo, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faChevronDown } from \"@fortawesome/pro-light-svg-icons/faChevronDown\";\nimport { faChevronRight } from \"@fortawesome/pro-light-svg-icons/faChevronRight\";\nimport { faList } from \"@fortawesome/pro-light-svg-icons/faList\";\nimport { faEmptySet, faPlay, faToggleOff, faToggleOn } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faArrowDownToLine } from \"@fortawesome/pro-regular-svg-icons/faArrowDownToLine\";\nimport { faArrowLeftFromBracket } from \"@fortawesome/pro-regular-svg-icons/faArrowLeftFromBracket\";\nimport { faArrowRightToBracket } from \"@fortawesome/pro-regular-svg-icons/faArrowRightToBracket\";\nimport { faBinary } from \"@fortawesome/pro-regular-svg-icons/faBinary\";\nimport { faCubes } from \"@fortawesome/pro-regular-svg-icons/faCubes\";\nimport { faFunction } from \"@fortawesome/pro-regular-svg-icons/faFunction\";\nimport { faListOl } from \"@fortawesome/pro-regular-svg-icons/faListOl\";\nimport { faPlus } from \"@fortawesome/pro-regular-svg-icons/faPlus\";\nimport { faRedoAlt } from \"@fortawesome/pro-regular-svg-icons/faRedoAlt\";\nimport { faStop } from \"@fortawesome/pro-regular-svg-icons/faStop\";\nimport { faQuotes } from \"@fortawesome/pro-solid-svg-icons/faQuotes\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport {\n    Debugger,\n    DebuggerIdentity,\n    DebuggerUpdate,\n    DebuggerValue,\n    StackFrame,\n} from \"@platform-runner/shared-debugger-types\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { debuggerContinue, getDebuggerState, getItems, getValue } from \"@/controllers/debugger\";\nimport { restartApp, stopApp } from \"@/controllers/ide\";\nimport { getRunnerRepl } from \"@/controllers/repl\";\nimport { AnvilDispatch, CodePath, State } from \"@/types\";\nimport { DebuggerHyperStack } from \"@/types/debugger\";\nimport { ExternalState, useExternalState } from \"@/util/external-state\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { getAppPackageName } from \"../../controllers/app\";\nimport { navigate } from \"../../router/navigation\";\nimport { cx } from \"../../theme/styles\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport ResizePanel from \"../sidebar/ResizePanel\";\nimport REPL, { useIsRunning } from \"./REPL\";\n\nconst typeToTitle = (type: Debugger[\"type\"]) => {\n    switch (type) {\n        case \"browser\":\n            return \"Browser\";\n        case \"downlink\":\n            return \"Server\";\n        case \"uplink\":\n            return \"Uplink\";\n    }\n};\n\nconst classNameToIcon = (className: string, literal: any) => {\n    switch (className) {\n        case \"str\":\n            return faQuotes;\n        case \"int\":\n            return faBinary;\n        case \"float\":\n            return faBinary;\n        case \"bool\":\n            return literal ? faToggleOn : faToggleOff;\n        case \"NoneType\":\n            return faEmptySet;\n        case \"list\":\n            return faListOl;\n        case \"dict\":\n            return faList;\n        case \"tuple\":\n            return faList;\n        case \"function\":\n            return faFunction;\n        default:\n            return faCubes;\n    }\n};\n\nconst Literal = ({ value }: { value: DebuggerValue }) => {\n    switch (value.className) {\n        case \"bool\":\n            return <span className={\"font-mono\"}>{value.literal ? \"True\" : \"False\"}</span>;\n        case \"str\":\n            return (\n                <>\n                    <span>'</span>\n                    <span className={\"overflow-hidden font-mono text-ellipsis\"}>{`${value.literal}`}</span>\n                    <span>'</span>\n                </>\n            );\n        default:\n            return <span className={\"font-mono\"}>{value.literal?.toString() ?? \"None\"}</span>;\n    }\n};\n\nexport type StackFrameContextType = {\n    hyperstackId: string;\n    dbg?: DebuggerIdentity;\n    frame?: StackFrame;\n};\n\nexport const StackFrameContext = React.createContext<StackFrameContextType>({\n    hyperstackId: \"\",\n    dbg: undefined,\n    frame: undefined,\n});\n\ninterface ExpandableDebuggerValueProps {\n    name: string;\n    value: DebuggerValue;\n    global: boolean;\n    jsonPath: string;\n    initialExpand?: boolean;\n    showHeader?: boolean;\n}\n\nconst ExpandableDebuggerValue = React.memo((props: ExpandableDebuggerValueProps) => {\n    const { name, value, global, jsonPath, initialExpand = false, showHeader = true } = props;\n    const dispatch = useDispatch<AnvilDispatch>();\n    const frameContext = useContext(StackFrameContext);\n    const [expanded, _setExpanded] = useState(initialExpand);\n\n    const loaded = \"error\" in value || \"literal\" in value || \"items\" in value || \"attrs\" in value;\n    const path = JSON.parse(jsonPath);\n\n    const expandable =\n        !value.error &&\n        value.className !== \"function\" &&\n        !(\"literal\" in value) &&\n        (!loaded || (value.items || []).length > 0 || Object.keys(value.attrs || {}).length > 0);\n\n    const setExpanded = useEvent(async (e: boolean) => {\n        if (e) {\n            if (!loaded) {\n                await dispatch(getValue(frameContext, global, path));\n            }\n            _setExpanded(true);\n        } else {\n            _setExpanded(false);\n        }\n    });\n\n    const doLoadMoreItems = useEvent(async () => {\n        await dispatch(getItems(frameContext, global, path, value.items!.length));\n    });\n\n    const headerContent = (\n        <>\n            <FontAwesomeIcon\n                className={\"pr-2 text-[1.2rem] text-light-grey1\"}\n                icon={classNameToIcon(value.className, value.literal)}\n                fixedWidth\n            />\n            <span className={\"flex-none font-semibold\"}>{name}</span>\n            <span className={\"flex-none text-light-grey1\"}>\n                : {value.className}\n                {\"error\" in value && ` <ERROR: ${value.error}>`}\n                {\"totalItems\" in value && <>[{value[\"totalItems\"]}]</>}\n            </span>\n            {\"literal\" in value && (\n                <div className={\"flex w-0 grow basis-0 text-nowrap\"}>\n                    <div className={\"mx-2\"}>=</div>\n                    <Literal value={value} />\n                </div>\n            )}\n        </>\n    );\n\n    return (\n        <>\n            {showHeader && (\n                <div className={\"flex w-full items-center font-mono\"}>\n                    <LinkInternal\n                        onClick={() => expandable && setExpanded(!expanded)}\n                        className={cx({ invisible: !expandable })}>\n                        <FontAwesomeIcon\n                            className={\"text-[1.2rem]\"}\n                            icon={expanded ? faChevronDown : faChevronRight}\n                            fixedWidth\n                        />\n                        {expandable && headerContent}\n                    </LinkInternal>\n                    {!expandable && headerContent}\n                </div>\n            )}\n            {expanded && (\n                <ul className={\"pl-4\"}>\n                    {value.items && (\n                        <>\n                            {value.items.map(([k, v], idx) => (\n                                <li key={k.repr}>\n                                    <ExpandableDebuggerValue\n                                        name={`${k.literal || k.repr}`}\n                                        value={v}\n                                        global={global}\n                                        jsonPath={JSON.stringify([...path, [\"i\", idx]])}\n                                    />\n                                </li>\n                            ))}\n                            {value.totalItems! > value.items.length && (\n                                <li className={\"text-[1.2rem] text-gray-500\"}>\n                                    <LinkInternal className={\"\"} onClick={doLoadMoreItems}>\n                                        <FontAwesomeIcon className={\"pr-1\"} icon={faPlus} fixedWidth />\n                                        LOAD MORE\n                                    </LinkInternal>\n                                </li>\n                            )}\n                        </>\n                    )}\n\n                    {Object.entries(value.attrs || {})\n                        .slice()\n                        .sort()\n                        .map(([k, v], idx) => (\n                            <li key={k}>\n                                <ExpandableDebuggerValue\n                                    name={`${k}`}\n                                    value={v}\n                                    global={global}\n                                    jsonPath={JSON.stringify([...path, [\"a\", k]])}\n                                />\n                            </li>\n                        ))}\n                </ul>\n            )}\n        </>\n    );\n});\n\nExpandableDebuggerValue.displayName = \"ExpandableDebuggerValue\";\n\nconst EMPTY_PATH = JSON.stringify([]);\n\nconst StackFrameScope = () => {\n    const { frame } = useContext(StackFrameContext);\n\n    if (!frame) return null;\n\n    return (\n        <>\n            {frame.locals && (\n                <div className={\"border-b border-sectionborder\"}>\n                    <div\n                        className={\n                            \"flex h-16 flex-none items-center gap-2 border-b border-solid border-b-sectionborder px-4\"\n                        }>\n                        <h3 className={\"font-bold\"}>Local Variables</h3>\n                    </div>\n                    <ExpandableDebuggerValue\n                        name={\"Locals\"}\n                        value={frame.locals}\n                        global={false}\n                        jsonPath={EMPTY_PATH}\n                        initialExpand={true}\n                        showHeader={false}\n                    />\n                </div>\n            )}\n            {frame.globals && (\n                <div className={\"border-b border-sectionborder\"}>\n                    <div\n                        className={\n                            \"flex h-16 flex-none items-center gap-2 border-b border-solid border-b-sectionborder px-4\"\n                        }>\n                        <h3 className={\"font-bold\"}>Global Variables</h3>\n                    </div>\n                    <ExpandableDebuggerValue\n                        name={\"Globals\"}\n                        value={frame.globals}\n                        global={true}\n                        jsonPath={EMPTY_PATH}\n                        initialExpand={true}\n                        showHeader={false}\n                    />\n                </div>\n            )}\n            {/*<pre className={\"m-4\"}>{JSON.stringify(frame, null, 4)}</pre>*/}\n        </>\n    );\n};\n\nconst ReplSizeState = new ExternalState({ size: \"40rem\" as string | number });\n\ninterface DebuggerInspectorProps {\n    hyperstackId: string;\n    hyperstack: DebuggerHyperStack;\n}\n\nexport const DebugInspector = ({ hyperstackId, hyperstack }: DebuggerInspectorProps) => {\n    const packageName = useSelector(getAppPackageName);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const debuggers: DebuggerUpdate = useMemo(() => {\n        return hyperstack.debuggers\n            .slice()\n            .reverse()\n            .map((d) => {\n                const dbg = { ...d };\n                if (\"stack\" in dbg) {\n                    dbg.stack = dbg.stack\n                        .slice()\n                        .reverse()\n                        .filter(({ codePath }: any) => codePath);\n                }\n                return dbg;\n            });\n    }, [hyperstack]);\n\n    const [selectedStackFrameIds, setSelectedStackFrameIds] = useState<[string, number] | null>(() =>\n        debuggers[0] && \"stack\" in debuggers[0] && debuggers[0].stack.length > 0\n            ? [debuggers[0].debuggerId, debuggers[0].stack[0].id]\n            : null\n    );\n    const selectedDebuggerId = selectedStackFrameIds?.[0];\n    const selectedStackFrameId = selectedStackFrameIds?.[1];\n\n    const [selectedDebugger, selectedStackFrame] = useMemo(() => {\n        const dbg = debuggers.find((d) => d.debuggerId === selectedDebuggerId) as Debugger | undefined;\n        return [dbg, dbg?.stack?.find(({ id }) => id === selectedStackFrameId)];\n    }, [selectedDebuggerId, selectedStackFrameId, debuggers]);\n\n    const expandDebugger = useEvent((dbg: DebuggerIdentity) => {\n        dispatch(getDebuggerState(hyperstackId, dbg));\n    });\n\n    const selectStackFrame = useEvent(async (dbg: Debugger, frame: StackFrame) => {\n        setSelectedStackFrameIds([dbg.debuggerId, frame.id]);\n        if (!(\"locals\" in frame)) {\n            await dispatch(getValue({ hyperstackId, dbg, frame }, false, []));\n        }\n        if (!(\"globals\" in frame)) {\n            await dispatch(getValue({ hyperstackId, dbg, frame }, true, []));\n        }\n        if (frame.codePath) {\n            dispatch(\n                navigate({ type: \"CODE\", codePath: frame.codePath as CodePath, view: { code: [`${frame.line}`] } })\n            );\n        }\n    });\n\n    const frameContext = { hyperstackId, dbg: selectedDebugger, frame: selectedStackFrame };\n\n    const isRunner = hyperstackId === \"runner\";\n    const repl = useSelector((state: State) => (isRunner ? getRunnerRepl(state) : undefined));\n    const [{ size: panelSize }, setPanelSize] = useExternalState(ReplSizeState);\n    const isRunning = useIsRunning(repl, selectedDebugger);\n\n    return (\n        <StackFrameContext.Provider value={frameContext}>\n            <div className={\"flex h-full w-full\"}>\n                <ResizePanel horizontal>\n                    <div\n                        className={\n                            \"flex h-16 flex-none items-center gap-2 border-b border-solid border-b-sectionborder px-4\"\n                        }>\n                        <Button\n                            disabled={isRunning}\n                            small\n                            title={\"Resume\"}\n                            variant={\"highlight1\"}\n                            onClick={() => dispatch(debuggerContinue(hyperstackId))}>\n                            <FontAwesomeIcon icon={faPlay} fixedWidth />\n                        </Button>\n                        {isRunner && (\n                            <>\n                                <Button\n                                    small\n                                    title={\"Restart\"}\n                                    variant={\"secondary\"}\n                                    onClick={() => dispatch(restartApp())}>\n                                    <FontAwesomeIcon icon={faRedoAlt} fixedWidth />\n                                </Button>\n                                <Button small title={\"Stop\"} variant={\"danger\"} onClick={() => dispatch(stopApp())}>\n                                    <FontAwesomeIcon icon={faStop} fixedWidth />\n                                </Button>\n                            </>\n                        )}\n                        <Button\n                            disabled={isRunning}\n                            small\n                            title={\"Step Over\"}\n                            onClick={() => dispatch(debuggerContinue(hyperstackId, \"OVER\"))}>\n                            <FontAwesomeIcon icon={faArrowDownToLine} fixedWidth />\n                        </Button>\n                        <Button\n                            disabled={isRunning}\n                            small\n                            title={\"Step In\"}\n                            onClick={() => dispatch(debuggerContinue(hyperstackId, \"IN\"))}>\n                            <FontAwesomeIcon icon={faArrowRightToBracket} fixedWidth />\n                        </Button>\n                        <Button\n                            disabled={isRunning}\n                            small\n                            title={\"Step Out\"}\n                            onClick={() => dispatch(debuggerContinue(hyperstackId, \"OUT\"))}>\n                            <FontAwesomeIcon icon={faArrowLeftFromBracket} fixedWidth />\n                        </Button>\n                    </div>\n                    <div>\n                        <ul>\n                            {debuggers.map((d) => (\n                                <div key={d.debuggerId} className={\"border-b border-sectionborder\"}>\n                                    {\"stack\" in d ? (\n                                        <>\n                                            <div className={\"px-2 font-mono text-lg text-light-grey1\"}>\n                                                {typeToTitle(d.type).toUpperCase()}\n                                            </div>\n                                            {d.stack.map((frame) => {\n                                                const { moduleName, filename, line, id } = frame;\n                                                return (\n                                                    <li\n                                                        className={cx(\"font-mons px-4\", {\n                                                            \"bg-light-bg3 dark:bg-dark-bg3\":\n                                                                selectedStackFrameId === id &&\n                                                                selectedDebuggerId === d.debuggerId,\n                                                        })}\n                                                        key={`${id}-${moduleName}`}>\n                                                        <LinkInternal\n                                                            className={`block font-mono`}\n                                                            onClick={() => selectStackFrame(d, frame)}>\n                                                            {moduleName?.replace(\n                                                                new RegExp(`^${packageName}\\\\.`),\n                                                                \"\"\n                                                            ) || filename}\n                                                            :{line}\n                                                        </LinkInternal>\n                                                    </li>\n                                                );\n                                            })}\n                                        </>\n                                    ) : (\n                                        <LinkInternal onClick={() => expandDebugger(d)}>\n                                            Expand {typeToTitle(d.type)} Stack <FontAwesomeIcon icon={faChevronRight} />\n                                        </LinkInternal>\n                                    )}\n                                </div>\n                            ))}\n                        </ul>\n                    </div>\n                </ResizePanel>\n\n                <div className=\"grow overflow-auto\">{selectedStackFrame && <StackFrameScope />}</div>\n                {repl && (\n                    <ResizePanel\n                        handleAtStart\n                        horizontal\n                        panelSize={panelSize}\n                        onFinishDrag={(size) => setPanelSize({ size })}>\n                        <REPL debug id={repl.id} repl={repl} />\n                    </ResizePanel>\n                )}\n            </div>\n        </StackFrameContext.Provider>\n    );\n};\n","import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { faChevronDown } from \"@fortawesome/free-solid-svg-icons/faChevronDown\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { search } from \"fast-fuzzy\";\nimport { useStyles as useDdStyles } from \"@/components/reusable/DropdownMenu\";\nimport { useStyles as useInputStyles } from \"@/components/reusable/Forms\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { getAppRefs } from \"@/controllers/app/history\";\nimport { getUser } from \"@/controllers/ide\";\nimport { cx } from \"@/theme/styles\";\nimport { preventDefault } from \"@/util\";\nimport { useIntersectionObserver } from \"@/util/hooks/use-intersection-observer\";\nimport useEvent from \"@/util/useEventCallback\";\n\ninterface RefSelectorProps {\n    currentBranch?: string | null;\n    currentTag?: string | null;\n    currentCommitId?: string | null;\n    onSelectBranch?: (branch: string) => void;\n    onSelectTag?: (tag: string) => void;\n    onCreateBranch?: () => void;\n    onCreateTag?: () => void;\n    includePersonalBranch?: boolean;\n}\n\ntype TabType = \"branches\" | \"tags\";\n\nconst RefSelector: React.FC<RefSelectorProps> = ({\n    currentBranch,\n    currentTag,\n    currentCommitId,\n    onSelectBranch,\n    onSelectTag,\n    onCreateBranch,\n    onCreateTag,\n    includePersonalBranch = false,\n}) => {\n    const { classes: inputClasses } = useInputStyles();\n    const { classes: ddClasses } = useDdStyles();\n\n    const refs = useSelector(getAppRefs);\n    const user = useSelector(getUser);\n\n    const componentRef = useRef<HTMLDivElement>(null!);\n    const textBoxRef = useRef<HTMLInputElement>(null);\n    const ddRef = useRef<HTMLDivElement>(null!);\n    const listRef = useRef<HTMLDivElement>(null!);\n\n    const [dropdownVisible, setDropdownVisible] = useState(false);\n    const [activeTab, setActiveTab] = useState<TabType>(\"branches\");\n    const [searchTerm, setSearchTerm] = useState(\"\");\n    const [dropdownAbove, setDropdownAbove] = useState(false);\n    const [focusLocation, setFocusLocation] = useState<\"input\" | \"tabs\" | \"list\">(\"input\");\n    const [ringIndex, setRingIndex] = useState<number | null>(null);\n\n    const userBranch = `users/${user.email}`;\n\n    const checkPosition = useEvent(() => {\n        if (dropdownVisible && ddRef.current && componentRef.current) {\n            const buttonRect = componentRef.current.getBoundingClientRect();\n            const dropdownHeight = ddRef.current.offsetHeight;\n            const spaceBelow = window.innerHeight - buttonRect.bottom;\n            const spaceAbove = buttonRect.top;\n\n            if (spaceBelow < dropdownHeight && spaceAbove > spaceBelow) {\n                setDropdownAbove(true);\n            } else {\n                setDropdownAbove(false);\n            }\n        }\n    });\n\n    useIntersectionObserver(\n        ddRef,\n        (entries) => {\n            const entry = entries[0];\n            // Trigger repositioning when dropdown is starting to be cut off (intersectionRatio < 0.95)\n            console.log(entry.intersectionRatio);\n            if (entry && entry.intersectionRatio < 0.98 && dropdownVisible) {\n                checkPosition();\n            }\n        },\n        { threshold: [0, 0.5, 0.9, 0.95, 0.98, 1] }\n    );\n\n    useLayoutEffect(() => {\n        if (!ddRef.current || !componentRef.current) return;\n        const width = componentRef.current.offsetWidth;\n        ddRef.current.style.width = width + \"px\";\n        checkPosition();\n    }, [componentRef.current?.offsetWidth, dropdownVisible, checkPosition]);\n\n    useEffect(() => {\n        if (!dropdownVisible) return;\n\n        const handleClickOutside = (e: MouseEvent) => {\n            if (componentRef.current && !componentRef.current.contains(e.target as Node)) {\n                setDropdownVisible(false);\n                setSearchTerm(\"\");\n            }\n        };\n\n        document.addEventListener(\"mousedown\", handleClickOutside);\n        return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n    }, [dropdownVisible]);\n\n    const branches = useMemo(() => {\n        const branchList = Object.entries(refs?.nonCollaboratorBranches || {}).map(([name]) => name);\n        if (includePersonalBranch && !branchList.includes(userBranch)) {\n            branchList.push(userBranch);\n        }\n        return branchList;\n    }, [refs?.nonCollaboratorBranches, includePersonalBranch, userBranch]);\n\n    const tags = useMemo(() => {\n        // Tags are already sorted by semver in the selector\n        return Object.keys(refs?.tags || {}).filter((name) => !name.startsWith(\"anvil-preserved/\"));\n    }, [refs?.tags]);\n\n    const filteredBranches = useMemo(() => {\n        if (!searchTerm) return branches;\n        return search(searchTerm, branches, { threshold: 0.7 });\n    }, [branches, searchTerm]);\n\n    const filteredTags = useMemo(() => {\n        if (!searchTerm) return tags;\n        return search(searchTerm, tags, { threshold: 0.7 });\n    }, [tags, searchTerm]);\n\n    const displayValue = useMemo(() => {\n        if (currentTag) return currentTag;\n        if (currentBranch) return currentBranch;\n        if (currentCommitId) return currentCommitId.substring(0, 7);\n        return \"Select branch or tag\";\n    }, [currentBranch, currentTag, currentCommitId]);\n\n    const isViewingTag = !!currentTag && !currentBranch;\n    const isViewingCommit = !!currentCommitId && !currentBranch && !currentTag;\n\n    const onClickChevron = useEvent(() => {\n        const willOpen = !dropdownVisible;\n        setDropdownVisible(willOpen);\n\n        if (willOpen) {\n            // Set active tab based on current selection when opening\n            if (currentTag) {\n                setActiveTab(\"tags\");\n            } else {\n                setActiveTab(\"branches\");\n            }\n            setFocusLocation(\"input\");\n            setRingIndex(null);\n        } else {\n            setSearchTerm(\"\");\n            setFocusLocation(\"input\");\n            setRingIndex(null);\n        }\n    });\n\n    const handleSelectBranch = useEvent((branch: string) => {\n        onSelectBranch?.(branch);\n        setDropdownVisible(false);\n        setSearchTerm(\"\");\n        setFocusLocation(\"input\");\n        setRingIndex(null);\n    });\n\n    const handleSelectTag = useEvent((tag: string) => {\n        onSelectTag?.(tag);\n        setDropdownVisible(false);\n        setSearchTerm(\"\");\n        setFocusLocation(\"input\");\n        setRingIndex(null);\n    });\n\n    const handleCreateNew = useEvent(() => {\n        if (activeTab === \"branches\") {\n            onCreateBranch?.();\n        } else {\n            onCreateTag?.();\n        }\n        setDropdownVisible(false);\n        setSearchTerm(\"\");\n        setFocusLocation(\"input\");\n        setRingIndex(null);\n    });\n\n    const currentItems = activeTab === \"branches\" ? filteredBranches : filteredTags;\n    const currentValue = activeTab === \"branches\" ? currentBranch : currentTag;\n\n    const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useEvent((e) => {\n        const numItems = currentItems.length;\n\n        switch (e.key) {\n            case \"ArrowDown\": {\n                e.preventDefault();\n                if (focusLocation === \"input\") {\n                    // Move to tabs\n                    setFocusLocation(\"tabs\");\n                } else if (focusLocation === \"tabs\") {\n                    // Move to list\n                    if (numItems > 0) {\n                        setFocusLocation(\"list\");\n                        setRingIndex(0);\n                    }\n                } else if (focusLocation === \"list\" && numItems > 0) {\n                    // Navigate in list\n                    const nextIndex = ringIndex === null ? 0 : Math.min(ringIndex + 1, numItems - 1);\n                    setRingIndex(nextIndex);\n                }\n                break;\n            }\n            case \"ArrowUp\": {\n                e.preventDefault();\n                if (focusLocation === \"list\") {\n                    if (ringIndex === 0) {\n                        // Move back to tabs\n                        setFocusLocation(\"tabs\");\n                        setRingIndex(null);\n                    } else if (ringIndex !== null && ringIndex > 0) {\n                        // Navigate in list\n                        setRingIndex(ringIndex - 1);\n                    }\n                } else if (focusLocation === \"tabs\") {\n                    // Move back to input\n                    setFocusLocation(\"input\");\n                }\n                break;\n            }\n            case \"ArrowLeft\": {\n                if (focusLocation === \"tabs\") {\n                    e.preventDefault();\n                    setActiveTab(\"branches\");\n                    setRingIndex(null);\n                }\n                break;\n            }\n            case \"ArrowRight\": {\n                if (focusLocation === \"tabs\") {\n                    e.preventDefault();\n                    setActiveTab(\"tags\");\n                    setRingIndex(null);\n                }\n                break;\n            }\n            case \"Enter\": {\n                e.preventDefault();\n                if (focusLocation === \"tabs\") {\n                    // Already on the selected tab, move to list\n                    if (numItems > 0) {\n                        setFocusLocation(\"list\");\n                        setRingIndex(0);\n                    }\n                } else if (focusLocation === \"list\" && ringIndex !== null) {\n                    // Select the item\n                    const item = currentItems[ringIndex];\n                    if (activeTab === \"branches\") {\n                        handleSelectBranch(item);\n                    } else {\n                        handleSelectTag(item);\n                    }\n                }\n                break;\n            }\n            case \"Escape\": {\n                setDropdownVisible(false);\n                setSearchTerm(\"\");\n                setFocusLocation(\"input\");\n                setRingIndex(null);\n                break;\n            }\n        }\n    });\n\n    const virtualizer = useVirtualizer({\n        count: currentItems.length,\n        getScrollElement: () => listRef.current,\n        estimateSize: () => 40,\n    });\n\n    // Scroll to selected item when dropdown opens or tab changes\n    useLayoutEffect(() => {\n        if (!dropdownVisible || !currentValue || currentItems.length === 0) return;\n\n        const selectedIndex = currentItems.indexOf(currentValue);\n        if (selectedIndex !== -1) {\n            virtualizer.scrollToIndex(selectedIndex, { align: \"center\" });\n        }\n    }, [dropdownVisible, activeTab, virtualizer, currentValue, currentItems]);\n\n    // Scroll to hovered item when navigating with keyboard\n    useLayoutEffect(() => {\n        if (ringIndex !== null && focusLocation === \"list\") {\n            virtualizer.scrollToIndex(ringIndex, { align: \"auto\" });\n        }\n    }, [ringIndex, focusLocation, virtualizer]);\n\n    return (\n        <div\n            ref={componentRef}\n            className={cx(inputClasses.dropDownContainer, \"!h-[2.8rem] max-w-[250px] min-w-[150px]\")}>\n            <div\n                className={cx(\n                    inputClasses.inputShared,\n                    \"flex !h-[2.8rem] cursor-pointer items-center !p-0\",\n                    (isViewingTag || isViewingCommit) && \"!bg-amber-50 dark:!bg-amber-900/20\"\n                )}\n                onClick={onClickChevron}>\n                <div className=\"flex h-full flex-1 items-center overflow-hidden px-3 text-[1.2rem] dark:text-white\">\n                    <span className=\"truncate\">{displayValue}</span>\n                </div>\n                <div\n                    onMouseUp={preventDefault}\n                    onMouseDown={preventDefault}\n                    className=\"flex h-full items-center border-l border-light-bg4 px-3 dark:border-dark-bg3\">\n                    <FontAwesomeIcon icon={faChevronDown} className=\"text-[1rem]\" />\n                </div>\n            </div>\n            <div\n                ref={ddRef}\n                onMouseUp={preventDefault}\n                onMouseDown={preventDefault}\n                className={cx(\n                    \"offset-vscrollbar absolute min-w-[200px]\",\n                    dropdownAbove ? \"bottom-full\" : \"top-full\",\n                    ddClasses.menu,\n                    dropdownVisible && ddClasses.opened\n                )}>\n                {dropdownVisible && (\n                    <>\n                        <div className=\"border-b border-light-bg4 p-2 dark:border-dark-bg3\">\n                            <ContentTextInput\n                                ref={textBoxRef}\n                                className=\"h-[2.6rem]! pl-2! text-lg!\"\n                                placeholder={`Find a ${activeTab === \"branches\" ? \"branch\" : \"tag\"}...`}\n                                value={searchTerm}\n                                onChange={(e) => {\n                                    setSearchTerm(e.target.value);\n                                    setRingIndex(null);\n                                }}\n                                onKeyDown={onKeyDown}\n                                autoFocus\n                            />\n                        </div>\n                        <div className=\"flex border-b border-light-bg4 dark:border-dark-bg3\">\n                            <div\n                                className={cx(\n                                    \"flex-1 cursor-pointer border-b-2 py-3 text-center text-[1.2rem] hover:bg-light-bg2 dark:hover:bg-dark-bg2\",\n                                    activeTab === \"branches\"\n                                        ? \"border-primary text-primary\"\n                                        : \"border-transparent dark:text-white\",\n                                    focusLocation === \"tabs\" &&\n                                        activeTab === \"branches\" &&\n                                        \"rounded ring ring-primary ring-inset\"\n                                )}\n                                onClick={() => setActiveTab(\"branches\")}\n                                onMouseDown={preventDefault}>\n                                Branches\n                            </div>\n                            <div\n                                className={cx(\n                                    \"flex-1 cursor-pointer border-b-2 py-3 text-center text-[1.2rem] hover:bg-light-bg2 dark:hover:bg-dark-bg2\",\n                                    activeTab === \"tags\"\n                                        ? \"border-primary text-primary\"\n                                        : \"border-transparent dark:text-white\",\n                                    focusLocation === \"tabs\" &&\n                                        activeTab === \"tags\" &&\n                                        \"rounded ring ring-primary ring-inset\"\n                                )}\n                                onClick={() => setActiveTab(\"tags\")}\n                                onMouseDown={preventDefault}>\n                                Tags\n                            </div>\n                        </div>\n\n                        {currentItems.length > 0 ? (\n                            <div ref={listRef} className=\"max-h-[30vh] overflow-y-auto py-1\">\n                                <div\n                                    style={{\n                                        height: `${virtualizer.getTotalSize()}px`,\n                                        width: \"100%\",\n                                        position: \"relative\",\n                                    }}>\n                                    {virtualizer.getVirtualItems().map((virtualItem) => {\n                                        const item = currentItems[virtualItem.index];\n                                        const isHovered = ringIndex === virtualItem.index;\n                                        const isSelected = item === currentValue;\n                                        return (\n                                            <div\n                                                key={virtualItem.key}\n                                                data-index={virtualItem.index}\n                                                ref={virtualizer.measureElement}\n                                                className={cx(\n                                                    ddClasses.item,\n                                                    \"cursor-pointer\",\n                                                    isHovered && \"rounded! ring! ring-primary! ring-inset!\",\n                                                    isSelected\n                                                        ? \"bg-light-bg4! dark:bg-dark-bg7!\"\n                                                        : \"hover:bg-grey-0! dark:hover:bg-grey-2!\"\n                                                )}\n                                                style={{\n                                                    position: \"absolute\",\n                                                    top: 0,\n                                                    left: 0,\n                                                    width: \"100%\",\n                                                    transform: `translateY(${virtualItem.start}px)`,\n                                                }}\n                                                onClick={() =>\n                                                    activeTab === \"branches\"\n                                                        ? handleSelectBranch(item)\n                                                        : handleSelectTag(item)\n                                                }\n                                                onMouseDown={preventDefault}>\n                                                <div\n                                                    className=\"inline-block w-full truncate leading-loose\"\n                                                    title={item}>\n                                                    {item}\n                                                </div>\n                                            </div>\n                                        );\n                                    })}\n                                </div>\n                            </div>\n                        ) : (\n                            <div className=\"py-4 text-center text-light-bg6 dark:text-dark-bg7\">\n                                No {activeTab} found\n                            </div>\n                        )}\n\n                        {((activeTab === \"branches\" && onCreateBranch) || (activeTab === \"tags\" && onCreateTag)) && (\n                            <div\n                                className={cx(\n                                    ddClasses.item,\n                                    \"cursor-pointer border-t border-light-bg4 font-semibold hover:bg-light-bg2! dark:border-dark-bg3 dark:hover:bg-dark-bg2!\"\n                                )}\n                                onClick={handleCreateNew}\n                                onMouseDown={preventDefault}>\n                                <div className=\"flex w-full truncate leading-loose\">\n                                    + Create new {activeTab === \"branches\" ? \"branch\" : \"tag\"}\n                                </div>\n                            </div>\n                        )}\n                    </>\n                )}\n            </div>\n        </div>\n    );\n};\n\nexport default RefSelector;\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { connect, useDispatch, useSelector } from \"react-redux\";\nimport { faGithub } from \"@fortawesome/free-brands-svg-icons/faGithub\";\nimport { faEye } from \"@fortawesome/free-regular-svg-icons/faEye\";\nimport { faCodeBranch } from \"@fortawesome/free-solid-svg-icons/faCodeBranch\";\nimport { faLink } from \"@fortawesome/free-solid-svg-icons/faLink\";\nimport { faPencilAlt } from \"@fortawesome/free-solid-svg-icons/faPencilAlt\";\nimport { faRedo } from \"@fortawesome/free-solid-svg-icons/faRedo\";\nimport { faUser } from \"@fortawesome/free-solid-svg-icons/faUser\";\nimport { faCheck } from \"@fortawesome/pro-light-svg-icons/faCheck\";\nimport { faTrashAlt } from \"@fortawesome/pro-light-svg-icons/faTrashAlt\";\nimport { faArrowsSpin } from \"@fortawesome/pro-regular-svg-icons/faArrowsSpin\";\nimport { faCloudArrowUp } from \"@fortawesome/pro-regular-svg-icons/faCloudArrowUp\";\nimport { faCloudCheck } from \"@fortawesome/pro-regular-svg-icons/faCloudCheck\";\nimport { faCloudExclamation } from \"@fortawesome/pro-regular-svg-icons/faCloudExclamation\";\nimport { faCodeCompare } from \"@fortawesome/pro-regular-svg-icons/faCodeCompare\";\nimport { faColumns } from \"@fortawesome/pro-regular-svg-icons/faColumns\";\nimport { faTag } from \"@fortawesome/pro-regular-svg-icons/faTag\";\nimport { faExclamationTriangle } from \"@fortawesome/pro-solid-svg-icons/faExclamationTriangle\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport {\n    createNewBranch,\n    createNewTag,\n    getApp,\n    getAppEditState,\n    getAppId,\n    publishAppVersion,\n    removePublishedAppVersion,\n    resetBranch,\n} from \"@/controllers/app\";\nimport {\n    abandonMerge,\n    checkoutVersion,\n    completeMerge,\n    deleteBranch,\n    deleteCommits,\n    deleteTag,\n    editCommitMessage,\n    getAppCommitHistory,\n    getAppCommitId,\n    getAppHasConflicts,\n    getAppMalleableCommits,\n    getAppRefs,\n    loadCommitIntoHistory,\n    loadVersion,\n    mergeAppVersion,\n    updateAppCommitHistory,\n} from \"@/controllers/app/history\";\nimport { connectToNewGithubRepo, getGitRemotes, getGithubRemote, pullAllRemotes } from \"@/controllers/app/remotes\";\nimport { saveApp } from \"@/controllers/app/saving\";\nimport {\n    deleteEnvironment,\n    getCanPublishApp,\n    getCategorisedEnvironments,\n    getDefaultPublishedEnvironment,\n    publishApp,\n} from \"@/controllers/environments\";\nimport {\n    getCommitListDiffWidth,\n    getIsDiffVisible,\n    getUser,\n    setBottomPanelCommitListDiffWidth,\n    toggleDiffVisible,\n} from \"@/controllers/ide\";\nimport { getGitSyncTask } from \"@/controllers/ide_tasks\";\nimport { alert, confirm, modal } from \"@/controllers/modals\";\nimport { recordActivity } from \"@/controllers/util\";\nimport { cx, makeStyles, useTheme } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, AnvilDispatch, State } from \"@/types\";\nimport type { AppEnvironment } from \"@/types/app-environment\";\nimport type { BranchRefEntry, CommitVersion, MergeRefEntry, TagRefEntry } from \"@/types/app-history\";\nimport { USER_AB_FLAGS } from \"@/util/hooks/ab-flags\";\nimport useEffectEvent from \"@/util/useEffectEvent\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { useLongPress } from \"@/util/useLongPress\";\nimport { Button } from \"../reusable/Button\";\nimport { CommitDetails } from \"../reusable/CommitDetail\";\nimport type { DropDownMenuItems, MenuItems, ShowMenuCallback } from \"../reusable/DropdownMenu\";\nimport DropdownMenu from \"../reusable/DropdownMenu\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport RefSelector from \"../reusable/RefSelector\";\nimport { BottomPanelContentButton } from \"../reusable/SharedComponents\";\nimport { Text } from \"../reusable/Text\";\nimport ResizePanel from \"../sidebar/ResizePanel\";\n\nconst LINE_HEIGHT = 2,\n    COL_WIDTH = 1.4,\n    BLOB_SIZE = 0.45; // REM\n\nconst useStyles = makeStyles<void, \"selectedCommit\">()((theme, _props, classes) => ({\n    root: {\n        //width: \"100%\",\n        height: \"100%\",\n        display: \"flex\",\n        flexDirection: \"column\",\n    },\n    optionsPane: {\n        height: \"4rem\",\n        display: \"flex\",\n        alignItems: \"center\",\n        flex: \"0 0 auto\",\n        padding: \"0 1rem\",\n        backgroundColor: theme.palette.bg0.hex(),\n        borderBottom: \"1px solid \" + theme.palette.bg2.hex(),\n        fontSize: \"1.2rem\",\n    },\n    spring: {\n        flex: \"1 0 auto\",\n    },\n    branchSelector: {\n        marginLeft: \"0.5rem\",\n        backgroundColor: theme.palette.bg0.hex(),\n    },\n    commitsPane: {\n        padding: \"0.9rem 0\",\n        flex: \"1 1\",\n        textAlign: \"left\",\n    },\n    vis: {\n        position: \"absolute\",\n        left: \"0.9rem\",\n        pointerEvents: \"none\",\n    },\n    readWrite: {},\n    commit: {\n        lineHeight: `${LINE_HEIGHT}rem`,\n        height: `${LINE_HEIGHT}rem`,\n        fontSize: `calc(${LINE_HEIGHT}rem - 0.6rem)`,\n        display: \"flex\",\n        flexDirection: \"row\",\n        // '&$readWrite': {\n        cursor: \"pointer\",\n        [`&:not(${classes.selectedCommit}):hover`]: {\n            backgroundColor: theme.historyPanel.commit.hoverBg.toString(),\n        },\n        // },\n    },\n    selectedCommit: {\n        margin: \"-1px 0\",\n        height: `calc(${LINE_HEIGHT}rem + 2px)`,\n        padding: \"1px 0\",\n        backgroundColor: theme.historyPanel.selectedCommit.background.toString(),\n        \"&:hover\": {\n            backgroundColor: theme.historyPanel.selectedCommit.hoverBg.toString(),\n        },\n    },\n    headCommit: {\n        backgroundColor: theme.historyPanel.headCommit.background.alpha(0.15).toString(),\n        [`&:not(.${classes.selectedCommit}):hover, &${classes.selectedCommit}:hover`]: {\n            backgroundColor: theme.historyPanel.headCommit.background.alpha(0.1).toString(),\n        },\n    },\n    commitTime: {\n        width: \"15rem\",\n        marginLeft: \"5rem\",\n        fontSize: \"1.2rem\",\n        flex: \"0 0 auto\",\n    },\n    commitAuthor: {\n        fontSize: \"1.2rem\",\n        flex: \"0 0 auto\",\n        marginLeft: \"0.5rem\",\n    },\n    commitMessage: {\n        flex: \"1 0 0\",\n        whiteSpace: \"nowrap\",\n        overflow: \"hidden\",\n        width: 0, // this seems to be a bug in browsers, without width 0 causes the pane to go off screen when commit message is long\n        textOverflow: \"ellipsis\",\n    },\n    commitLabels: {\n        flex: \"0 0 auto\",\n    },\n    commitDescription: {\n        whiteSpace: \"nowrap\",\n        overflow: \"hidden\",\n        textOverflow: \"ellipsis\",\n        flex: \"1 1 auto\",\n        display: \"flex\",\n        justifyItems: \"space-between\",\n    },\n    commitButtons: {\n        marginTop: -2,\n        flex: \"0 1 auto\",\n        padding: \"0 0.4rem 0 2px\",\n    },\n    revertButton: {},\n    mergeButton: {\n        backgroundColor: theme.secondary.hex(),\n    },\n    publishButton: {\n        backgroundColor: theme.primary.hex(),\n    },\n    branch: {\n        float: \"left\",\n        fontWeight: \"bold\",\n        verticalAlign: \"middle\",\n        fontSize: \"70%\",\n        height: `calc(${LINE_HEIGHT}rem - 0.4rem)`,\n        lineHeight: `calc(${LINE_HEIGHT}rem - 0.4rem)`,\n        marginTop: 2,\n        marginRight: \"0.4rem\",\n        color: theme.versionHistory.branch.color.toString(),\n        backgroundColor: theme.versionHistory.branch.background.toString(),\n        border: \"1px solid \" + theme.versionHistory.branch.border.toString(),\n        padding: \"0 0.4rem 0 0.6rem\",\n        borderRadius: \"0.4rem\",\n        overflow: \"hidden\",\n        display: \"flex\",\n        alignItems: \"center\",\n    },\n    currentBranch: {\n        border: \"1px solid \" + theme.versionHistory.currentBranch.border.toString(),\n    },\n    branchEnvironment: {\n        color: theme.primary.darken(0.05).hex(),\n    },\n    branchEnvironmentAfterName: {\n        marginLeft: \"0.4rem\",\n        paddingLeft: \"0.4rem\",\n    },\n    branchIcon: {\n        marginRight: \"0.4rem\",\n    },\n    commits: {},\n    noodlePane: {\n        height: \"100%\",\n    },\n    diffDisplay: {\n        height: \"100%\",\n    },\n    alignCenter: {\n        textAlign: \"center\",\n    },\n    toggleDiff: {\n        float: \"right\",\n        paddingTop: \"0.6rem\",\n    },\n    toolbarButton: {\n        marginLeft: \"1rem\",\n    },\n    warningNotice: {\n        padding: \"2px 0.6rem\",\n        borderBottom: \"1px solid \" + theme.notice.borderBottom.toString(),\n        fontSize: \"1.1rem\",\n        borderRadius: 2,\n        whiteSpace: \"nowrap\",\n        textAlign: \"center\",\n        color: theme.notice.color.toString(),\n        background: \"#fdd\",\n    },\n}));\n\ntype HistoryClasses = ReturnType<typeof useStyles>[\"classes\"];\n\ntype HistoryEnvironmentGroups = ReturnType<typeof getCategorisedEnvironments>;\n\ninterface HistoryRemoteSync {\n    \"synced?\"?: boolean;\n    status?: string;\n    message?: string;\n}\n\ninterface BranchLabelProps {\n    type: \"BRANCH\" | \"TAG\" | \"HEAD\" | \"EDITING\" | \"VISITING\" | \"USER_BRANCH\" | \"MERGE\" | \"ENVIRONMENT\";\n    name?: string | null;\n    environment?: AppEnvironment;\n    isCurrent?: boolean;\n    commitId?: string;\n    onDoubleClick?: (e: React.MouseEvent<HTMLDivElement>) => void;\n    remoteSync?: Record<string, HistoryRemoteSync>;\n}\n\ninterface Noodle {\n    fromCol: number;\n    fromY: number;\n    lineCol?: number;\n}\n\ninterface ColumnAllocation {\n    v: string;\n    noodles: Noodle[];\n}\n\ntype LabelsByCommit = Record<string, React.ReactNode[]>;\n\nconst layoutVis = (\n    commits: CommitVersion[],\n    headCommitId: string | null | undefined,\n    malleableCommitIds: string[],\n    reserveFirstColumn: string | null | undefined,\n    classes: HistoryClasses,\n    theme: any\n) => {\n    const circleElements: React.ReactNode[] = [];\n    const noodleElements: React.ReactNode[] = [];\n    const REM_PX = parseFloat(getComputedStyle(document.documentElement).fontSize);\n    const LINE_HEIGHT_PX = LINE_HEIGHT * REM_PX;\n    const COL_WIDTH_PX = COL_WIDTH * REM_PX;\n    const BLOB_SIZE_PX = BLOB_SIZE * REM_PX;\n    let y = LINE_HEIGHT_PX / 2;\n    const colx = (n: number) => COL_WIDTH_PX / 2 + n * COL_WIDTH_PX;\n    const colcol = (n: number) => [theme.primary, theme.secondary, theme.tertiary][n % 3];\n    const colcolFade = (n: number) => colcol(n).lighten(0.9).toString();\n\n    const columnAllocations: Array<ColumnAllocation | null> = [];\n    if (reserveFirstColumn) {\n        columnAllocations.push({ v: reserveFirstColumn, noodles: [] });\n    }\n\n    const findColumnAllocations = (v: string, noodle?: Noodle | null) => {\n        const cols: number[] = [];\n        for (let i = 0; i < columnAllocations.length; i++) {\n            const allocation = columnAllocations[i];\n            if (allocation && allocation.v === v) {\n                cols.push(i);\n            }\n        }\n        if (cols.length !== 0) {\n            if (noodle) {\n                // merge the noodle into an existing column\n                let mergeCol: number | undefined,\n                    minDist = columnAllocations.length + 1;\n                for (const c of cols) {\n                    const dist = Math.abs(c - noodle.fromCol);\n                    if (dist < minDist) {\n                        mergeCol = c;\n                        minDist = dist;\n                    }\n                }\n                noodle.lineCol = mergeCol;\n                if (mergeCol != null) {\n                    columnAllocations[mergeCol]?.noodles.push(noodle);\n                }\n            }\n            return cols;\n        }\n        let i = 0;\n        while (columnAllocations[i]) {\n            i++;\n        }\n        columnAllocations[i] = { v: v, noodles: [] };\n        if (noodle) {\n            noodle.lineCol = i;\n            columnAllocations[i]!.noodles.push(noodle);\n        }\n        return [i];\n    };\n\n    const drawNoodles = (noodles: Noodle[], finishCol: number) => {\n        for (let { fromCol, fromY, lineCol } of noodles) {\n            lineCol ??= fromCol;\n            if (lineCol !== fromCol && lineCol !== finishCol && fromY + LINE_HEIGHT_PX > y - LINE_HEIGHT_PX) {\n                // No distance to travel in lineCol - go straight to the finish\n                lineCol = finishCol;\n            }\n            const fromX = colx(fromCol),\n                lineX = colx(lineCol),\n                toX = colx(finishCol);\n            const lineY = finishCol === lineCol ? y : y - LINE_HEIGHT_PX;\n            const K = 2 / 3;\n            noodleElements.push(\n                <path\n                    key={`${fromCol},${fromY},${lineCol}`}\n                    d={\n                        `M ${fromX},${fromY} ` +\n                        (lineCol === fromCol\n                            ? `L ${lineX},${lineY} `\n                            : `C ${fromX},${fromY + LINE_HEIGHT_PX * K}\n                           ${lineX},${fromY + LINE_HEIGHT_PX * (1 - K)}\n                           ${lineX},${fromY + LINE_HEIGHT_PX}\n                         L ${lineX},${lineY} `) +\n                        (finishCol !== lineCol\n                            ? `C ${lineX},${lineY + LINE_HEIGHT_PX * K}\n                           ${toX},${lineY + LINE_HEIGHT_PX * (1 - K)}\n                           ${toX},${y}`\n                            : \"\")\n                    }\n                    fill=\"none\"\n                    stroke={colcol(lineCol)}\n                />\n            );\n        }\n    };\n\n    for (const commit of commits) {\n        const cols = findColumnAllocations(commit.v),\n            col = cols[0];\n        const head = commit.v === headCommitId;\n        const malleable = malleableCommitIds.indexOf(commit.v) > -1;\n        circleElements.push(\n            <circle\n                key={commit.v}\n                cx={colx(col)}\n                cy={y}\n                strokeWidth={head ? 2 : malleable ? 2 : 0}\n                fill={!malleable ? colcol(col) : colcolFade(col)}\n                stroke={head ? \"#555\" : colcol(col)}\n                r={BLOB_SIZE_PX + (head ? 1 : 0)}\n            />\n        );\n\n        // Finish all the noodles intended for this commit...\n        for (const c of cols) {\n            drawNoodles(columnAllocations[c]?.noodles || [], col);\n            columnAllocations[c] = null;\n        }\n\n        // Our parents determine the next row's column allocations\n        if (commit.p && commit.p.length !== 0) {\n            // Force the direct parent into the same column as us\n            columnAllocations[col] = { v: commit.p[0], noodles: [{ fromCol: col, fromY: y, lineCol: col }] };\n            for (let i = 1; i < commit.p.length; i++) {\n                findColumnAllocations(commit.p[i], { fromCol: col, fromY: y });\n            }\n        }\n\n        y += LINE_HEIGHT_PX;\n    }\n\n    // Parents outside the loaded history still need a line continuing off the bottom.\n    columnAllocations.forEach((allocation, col) => {\n        if (allocation) drawNoodles(allocation.noodles, col);\n    });\n\n    const width = columnAllocations.length * COL_WIDTH_PX + COL_WIDTH_PX / 2;\n\n    // Match the rendered rows, whose scaled heights can round individually.\n    const visLayout = (\n        <svg\n            className={classes.vis}\n            version=\"1.1\"\n            baseProfile=\"full\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            width={width}\n            style={{ height: \"100%\" }}\n            viewBox={`0 0 ${width} ${LINE_HEIGHT_PX * commits.length}`}\n            preserveAspectRatio=\"none\">\n            {noodleElements}\n            {circleElements}\n        </svg>\n    );\n\n    return [visLayout, width] as const;\n};\n\ninterface NoodleCommitProps {\n    activeCommitRef?: React.RefObject<HTMLDivElement | null>;\n    commit: CommitVersion;\n    classes: HistoryClasses;\n    headCommitId?: string | null;\n    onSelectCommit: (commit: CommitVersion) => void;\n    showMenu: ShowMenuCallback;\n    onDoubleClickCommit?: (commit: CommitVersion) => void;\n    labels: LabelsByCommit;\n    selectedCommit: CommitVersion | null;\n    readOnly?: boolean;\n    visWidth: number;\n}\n\nconst NoodleCommit = ({\n    activeCommitRef,\n    commit,\n    classes,\n    headCommitId,\n    onSelectCommit,\n    showMenu,\n    onDoubleClickCommit,\n    labels,\n    selectedCommit,\n    readOnly,\n    visWidth,\n}: NoodleCommitProps) => {\n    const longPressProps = useLongPress(showMenu);\n    const commitRef = commit.v === headCommitId ? activeCommitRef : null;\n    const summary = commit?.m?.split(/\\r?\\n/)[0]?.trim() || commit?.m?.trim() || \"\";\n\n    return (\n        <div\n            key={commit.v}\n            ref={commitRef}\n            className={cx(\n                classes.commit,\n                !readOnly && classes.readWrite,\n                commit.v === headCommitId && classes.headCommit,\n                commit.v === selectedCommit?.v && classes.selectedCommit\n            )}\n            style={{ paddingLeft: `calc(${visWidth}px + ${COL_WIDTH}rem)` }}\n            onClick={() => onSelectCommit(commit)}\n            onContextMenu={(e) => showMenu(e, e.currentTarget)}\n            {...longPressProps}\n            onDoubleClick={() => onDoubleClickCommit?.(commit)}>\n            <div className={classes.commitDescription}>\n                <div className={classes.commitLabels}>{labels[commit.v]}</div>\n                <div className={classes.commitMessage}>{summary}</div>\n                <div className={classes.commitAuthor}>{commit.e}</div>\n                <div className={classes.commitTime}>{new Date(commit.t * 1000).toLocaleString()}</div>\n            </div>\n        </div>\n    );\n};\n\ninterface NoodlePaneProps {\n    activeCommitRef?: React.RefObject<HTMLDivElement | null>;\n    className?: string;\n    headCommitId?: string | null;\n    commits?: CommitVersion[] | null;\n    malleableCommitIds?: string[];\n    reserveFirstLane?: string | null;\n    initialSelectedCommit?: CommitVersion | null;\n    onSelectCommit?: (commit: CommitVersion) => void;\n    onDoubleClickCommit?: (commit: CommitVersion) => void;\n    onDoubleClickBranch?: (commitId: string, branch?: string | null, forceVisiting?: boolean) => void;\n    generateCommitContextMenuItems?: (\n        commit: CommitVersion,\n        selectItem: (item: any) => void,\n        hideMenu: () => void\n    ) => MenuItems;\n    readOnly?: boolean;\n    onLoadMore?: () => Promise<void>;\n    classes?: Partial<Record<\"commit\" | \"commitsPane\" | \"alignCenter\" | \"selectedCommit\", string>>;\n}\n\nexport const NoodlePane = ({ activeCommitRef, ...props }: NoodlePaneProps) => {\n    const {\n        className,\n        headCommitId,\n        commits: givenCommits = null,\n        malleableCommitIds = [],\n        reserveFirstLane,\n        initialSelectedCommit = null,\n        onSelectCommit,\n        onDoubleClickCommit,\n        onDoubleClickBranch,\n        generateCommitContextMenuItems,\n        readOnly = false,\n        onLoadMore,\n        classes: givenClasses,\n    } = props;\n\n    const headCommit = useSelector(getAppCommitId);\n    const editState = useSelector(getAppEditState);\n    const refs = useSelector(getAppRefs);\n    const malleableCommits = useSelector(getAppMalleableCommits);\n    const commitHistory = useSelector(getAppCommitHistory);\n    const environments = useSelector(getCategorisedEnvironments);\n\n    const theme = useTheme();\n    const { classes: internalClasses } = useStyles();\n    const commits = givenCommits || commitHistory?.versions || [];\n\n    const classes: HistoryClasses = {\n        ...internalClasses,\n        selectedCommit: cx(internalClasses.selectedCommit, givenClasses?.selectedCommit),\n        commit: cx(internalClasses.commit, givenClasses?.commit),\n    };\n\n    const [visLayout, visWidth] = useMemo(\n        () => layoutVis(commits, headCommitId, malleableCommitIds, reserveFirstLane, classes, theme),\n        [commits, headCommitId, reserveFirstLane, /*publishedCommit, */ classes, malleableCommitIds]\n    );\n\n    const [selectedCommit, setSelectedCommit] = useState(initialSelectedCommit);\n\n    useEffect(() => {\n        setSelectedCommit(initialSelectedCommit);\n    }, [initialSelectedCommit?.v]);\n\n    const _onSelectCommit = useCallback(\n        async (c: CommitVersion) => {\n            if (onSelectCommit) {\n                setSelectedCommit(c);\n                onSelectCommit(c);\n            }\n        },\n        [onSelectCommit]\n    );\n\n    const lastLoadCount = useRef<number | null>(null);\n    const [loadingMore, setLoadingMore] = useState(false);\n    const onScroll = useCallback(\n        async (e: React.UIEvent<HTMLDivElement>) => {\n            const target = e.currentTarget;\n            if (target.scrollTop + target.clientHeight > target.scrollHeight - 10) {\n                if (lastLoadCount.current !== commits.length && commits?.[commits.length - 1].p?.length > 0) {\n                    setLoadingMore(true);\n                    await onLoadMore?.();\n                    setLoadingMore(false);\n                    lastLoadCount.current = commits.length;\n                }\n            }\n        },\n        [commits, onLoadMore]\n    );\n\n    const labels = useMemo(() => {\n        const labels: LabelsByCommit = {};\n        for (const [mergeId, { oid }] of Object.entries(refs.resolvingMerges || {})) {\n            (labels[oid] = labels[oid] || []).push(\n                <BranchLabel\n                    key={`merge-${mergeId}`}\n                    type=\"MERGE\"\n                    name={\"Resolving Conflicts\"}\n                    isCurrent={`${editState?.merge}` === mergeId}\n                />\n            );\n        }\n        for (const [branch, { commitId, remoteSync }] of Object.entries(refs.branches || {})) {\n            const ref = `refs/heads/${branch}`;\n            const env = environments.named.find((e) => e.version?.ref === ref);\n            const onDoubleClick = (e: React.MouseEvent<HTMLDivElement>) => {\n                e.preventDefault();\n                e.stopPropagation();\n                onDoubleClickBranch?.(commitId, branch);\n            };\n            (labels[commitId] = labels[commitId] || []).push(\n                <BranchLabel\n                    key={branch}\n                    type=\"BRANCH\"\n                    name={branch}\n                    environment={env}\n                    isCurrent={branch === editState?.branch}\n                    commitId={commitId}\n                    onDoubleClick={onDoubleClick}\n                    remoteSync={remoteSync}\n                />\n            );\n            if (ref in (malleableCommits || {}) && commitId === headCommit) {\n                labels[commitId].unshift(<BranchLabel key={\"EDITING\"} type={\"EDITING\"} name={\"EDITING\"} />);\n            }\n        }\n\n        for (const [branch, { commitId, inSync }] of Object.entries(refs.remotes || {})) {\n            // Only show remotes that are not in sync.\n            if (!inSync) {\n                (labels[commitId] = labels[commitId] || []).push(\n                    <BranchLabel key={branch} type=\"BRANCH\" name={branch} commitId={commitId} />\n                );\n            }\n        }\n\n        for (const tag of Object.keys(refs.tags)) {\n            if (tag.startsWith(\"anvil-preserved/\")) {\n                continue;\n            }\n            const ref = `refs/tags/${tag}`;\n            const commitId = refs.refs[ref]?.oid;\n            const env = environments.named.find((e) => e.version?.ref === ref);\n            const isCurrentTag = editState?.commitId === commitId && !editState?.branch;\n            const onDoubleClick = (e: React.MouseEvent<HTMLDivElement>) => {\n                e.preventDefault();\n                e.stopPropagation();\n                onDoubleClickBranch?.(commitId, null, true); // Pass forceVisiting=true for tags\n            };\n            (labels[commitId] = labels[commitId] || []).push(\n                <BranchLabel\n                    key={tag}\n                    type=\"TAG\"\n                    name={tag}\n                    environment={env}\n                    commitId={commitId}\n                    isCurrent={isCurrentTag}\n                    onDoubleClick={onDoubleClick}\n                />\n            );\n        }\n        if (editState?.commitId) {\n            (labels[editState.commitId] = labels[editState.commitId] || []).unshift(\n                <BranchLabel key={\"VISITING\"} type={\"VISITING\"} name={\"VISITING\"} />\n            );\n        }\n        for (const environment of environments.named) {\n            // Give environments that point to specific commits their own labels\n            const commitId = environment.version?.[\"commit-id\"];\n            if (commitId) {\n                (labels[commitId] = labels[commitId] || []).unshift(\n                    <BranchLabel key={environment.env_id} type={\"ENVIRONMENT\"} environment={environment} />\n                );\n            }\n        }\n        return labels;\n    }, [\n        headCommit,\n        refs.branches,\n        refs.tags,\n        environments.named,\n        malleableCommits,\n        editState?.branch,\n        editState?.commitId,\n    ]);\n\n    const commitProps = {\n        activeCommitRef,\n        classes,\n        headCommitId,\n        onSelectCommit: _onSelectCommit,\n        onDoubleClickCommit,\n        labels,\n        selectedCommit,\n        readOnly,\n        visWidth,\n    };\n\n    return (\n        <div className={cx(className, classes.commitsPane, \"offset-vscrollbar\")} onScroll={onScroll}>\n            <div style={{ paddingTop: 1 }}>\n                {/* Include selected rows' negative margins in the graph's sizing box. */}\n                <div className={cx(classes.commits, \"relative flow-root\")}>\n                    {visLayout}\n                    {commits.map((commit) => (\n                        <DropdownMenu\n                            key={commit.v}\n                            render={(showMenu) => <NoodleCommit showMenu={showMenu} commit={commit} {...commitProps} />}\n                            items={(selectItem, hideMenu) =>\n                                generateCommitContextMenuItems?.(commit, selectItem, hideMenu) ?? []\n                            }\n                        />\n                    ))}\n                </div>\n            </div>\n            {onLoadMore && commits?.[commits.length - 1]?.p?.length > 0 && !loadingMore && (\n                <div className={classes.alignCenter}>\n                    <br />\n                    <BottomPanelContentButton variant={\"primary\"} onClick={onLoadMore}>\n                        <FontAwesomeIcon icon={faRedo} /> Load more commits\n                    </BottomPanelContentButton>\n                </div>\n            )}\n        </div>\n    );\n};\n\nconst branchLabelConnector = connect((state: State) => ({ userEmail: getUser(state).email }));\n\ntype BranchLabelConnectedProps = AnvilConnectedProps<typeof branchLabelConnector> & BranchLabelProps;\n\nexport const BranchLabel = branchLabelConnector(\n    ({ type, userEmail, name, environment, isCurrent, onDoubleClick, remoteSync }: BranchLabelConnectedProps) => {\n        const { classes } = useStyles();\n\n        const isUser = type === \"BRANCH\" && name?.match(/^users\\/(.*)@(.*)$/);\n        if (isUser) {\n            const [_, username, userDomain] = isUser;\n            const [__, myDomain] = userEmail.match(/^.*@(.*)$/) || [];\n            type = \"USER_BRANCH\";\n            name = userDomain === myDomain ? username : username + \"@\" + userDomain;\n        }\n\n        const icon = {\n            BRANCH: faCodeBranch,\n            TAG: faTag,\n            HEAD: faCodeBranch,\n            EDITING: faPencilAlt,\n            VISITING: faEye,\n            USER_BRANCH: faUser,\n            MERGE: faExclamationTriangle,\n            ENVIRONMENT: null,\n        }[type];\n\n        const remotes = useMemo(() => {\n            const remotes: React.ReactNode[] = [];\n            for (const [remoteName, sync] of Object.entries(remoteSync || {})) {\n                const inSync = sync[\"synced?\"];\n                remotes.push(\n                    <div\n                        key={remoteName}\n                        title={`${inSync ? \"In\" : \"Out of\"} sync with '${remoteName}'`}\n                        className={\"ml-2 border-l border-l-black pl-1.5\"}>\n                        <FontAwesomeIcon\n                            size={\"lg\"}\n                            className={cx(!inSync && \"text-danger\")}\n                            icon={inSync ? faCloudCheck : faCloudExclamation}\n                            fixedWidth\n                        />\n                    </div>\n                );\n            }\n            return remotes;\n        }, [remoteSync]);\n\n        return (\n            <div\n                className={cx(classes.branch, isCurrent && classes.currentBranch)}\n                key={`${type}/${name}`}\n                onDoubleClick={(e) => onDoubleClick?.(e)}>\n                {icon && <FontAwesomeIcon icon={icon} className={classes.branchIcon} />}\n                <div>{name}</div>\n                {environment && (\n                    <LinkInternal className={cx(classes.branchEnvironment, name && classes.branchEnvironmentAfterName)}>\n                        <FontAwesomeIcon icon={faLink} className={classes.branchIcon} /> {environment.name}\n                    </LinkInternal>\n                )}\n                {remotes}\n            </div>\n        );\n    }\n);\n\nconst getCommitsReachableFromBranches = (fromCommits: string[], allCommits: CommitVersion[], except?: Set<string>) => {\n    const findableCommitIds = new Set(fromCommits);\n    for (const { v, p } of allCommits) {\n        if (findableCommitIds.has(v)) {\n            for (const pid of p || []) {\n                if (!except?.has(pid)) {\n                    findableCommitIds.add(pid);\n                }\n            }\n        }\n    }\n    return findableCommitIds;\n};\n\nconst GitSyncButton = ({ menuItems, classes }: { menuItems: DropDownMenuItems; classes: HistoryClasses }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const gitSyncTask = useSelector(getGitSyncTask);\n    const prevGitSyncTaskRef = useRef(gitSyncTask);\n    const refs = useSelector(getAppRefs);\n    const { branch } = useSelector(getAppEditState) ?? {};\n    const [showModal, setShowModal] = useState(false);\n\n    const allBranchesInSync = useMemo(() => {\n        for (const { remoteSync } of Object.values(refs.branches || {})) {\n            for (const info of Object.values(remoteSync || {})) {\n                if (!info[\"synced?\"]) {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }, [refs.branches]);\n\n    const gitSyncButtonIcon = gitSyncTask ? faArrowsSpin : allBranchesInSync ? faCloudCheck : faCodeCompare;\n\n    const onCheckWhichBranchesAreInSync = useEffectEvent(async () => {\n        const currentBranchSync = branch ? (refs.branches[branch]?.remoteSync ?? {}) : {};\n        for (const [remote, sync] of Object.entries(currentBranchSync)) {\n            if (!branch) {\n                return;\n            }\n            if (!sync[\"synced?\"]) {\n                dispatch(modal(\"gitDesync\", { branch, remote, sync }));\n                return;\n            }\n        }\n\n        const c = await dispatch(\n            confirm(\n                <>\n                    <code>{branch}</code> branch synced\n                </>,\n                \"This branched is synced with the Git remote. However some other branches are out of sync. View/Manage Git remotes?\",\n                \"View out of sync branches\",\n                \"No\"\n            )\n        );\n\n        if (c) {\n            dispatch(modal(\"gitRemotes\", {}));\n        }\n    });\n\n    useEffect(() => {\n        const prevGitSyncTask = prevGitSyncTaskRef.current;\n        prevGitSyncTaskRef.current = gitSyncTask;\n\n        if (!prevGitSyncTask || gitSyncTask || !showModal) {\n            return;\n        }\n\n        setShowModal(false);\n\n        if (allBranchesInSync) {\n            dispatch(alert(\"Git Sync\", \"All branches are in sync with their Git remotes.\"));\n        } else {\n            onCheckWhichBranchesAreInSync();\n        }\n    }, [gitSyncTask, allBranchesInSync, showModal]);\n\n    const onHandleSyncClick = useEvent(() => {\n        setShowModal(true);\n        dispatch(pullAllRemotes());\n    });\n\n    return (\n        <Button\n            menuItems={menuItems}\n            size={\"small\"}\n            className={classes.toolbarButton}\n            onClick={onHandleSyncClick}\n            icon={gitSyncButtonIcon}\n            iconSpin={!!gitSyncTask}>\n            Sync Git Remotes\n        </Button>\n    );\n};\n\ntype HistoryOwnProps = {\n    classes?: HistoryClasses;\n    className?: string;\n};\n\nconst historyConnector = connect((state: State) => ({\n    app: getApp(state)!,\n    appId: getAppId(state)!,\n    commitHistory: getAppCommitHistory(state)!,\n    refs: getAppRefs(state),\n    malleableCommits: getAppMalleableCommits(state),\n    publishedCommit: getAppCommitHistory(state)?.published_version,\n    publishedEnv: getDefaultPublishedEnvironment(state),\n    headCommit: getAppCommitId(state)!,\n    editState: getAppEditState(state)!,\n    user: getUser(state),\n    environments: getCategorisedEnvironments(state),\n    commitListDiffWidth: getCommitListDiffWidth(state),\n    isDiffVisible: getIsDiffVisible(state),\n    hasConflicts: getAppHasConflicts(state),\n    canPublish: getCanPublishApp(state),\n    remotes: getGitRemotes(state),\n    githubRemote: getGithubRemote(state),\n}));\n\ntype HistoryProps = AnvilConnectedProps<typeof historyConnector> & HistoryOwnProps;\n\nconst History = ({\n    app,\n    commitHistory,\n    refs,\n    malleableCommits,\n    environments,\n    publishedEnv,\n    publishedCommit,\n    headCommit,\n    editState,\n    appId,\n    user,\n    remotes,\n    githubRemote,\n    classes,\n    className,\n    commitListDiffWidth,\n    isDiffVisible,\n    hasConflicts,\n    canPublish,\n    dispatch,\n}: HistoryProps) => {\n    ({ classes } = useStyles(undefined, { props: { classes } }));\n\n    const legacy = environments.named.length === 1 && environments.named[0].legacy;\n\n    const reserveFirstLane =\n        refs.branches.master\n            ?.commitId; /*(editState.branch === \"master\" || editState.branch?.startsWith?.(\"users/\") || !editState.branch) ?\n        commitHistory.branches.master : null;*/\n\n    const publishLegacy = useCallback(\n        async (commit: CommitVersion | null) => {\n            if (!commit) return;\n            if (\n                await dispatch(\n                    confirm(\"Publish this version of your app?\", \"This version is what visitors to your app will see.\")\n                )\n            ) {\n                dispatch(publishAppVersion(appId, commit.v));\n            }\n        },\n        [appId]\n    );\n\n    const unpublishLegacy = useCallback(async () => {\n        if (\n            await dispatch(\n                confirm(\"Unpublish your app?\", \"Your app will no longer be accessible via its current public URL\")\n            )\n        ) {\n            await dispatch(removePublishedAppVersion());\n        }\n    }, []);\n\n    const publish = useCallback(\n        async (version: { ref?: string; \"commit-id\"?: string }) => {\n            const confirmed = await dispatch(publishApp(version));\n            // TODO: We could display a nice \"Here is the link to your app, click [here] to see the full environment\" modal here\n            // For now, just open the Publish modal if the app wasn't already published.\n            if (confirmed && !publishedEnv) {\n                dispatch(modal(\"environments\", {}));\n            }\n        },\n        [publishedEnv]\n    );\n\n    const unpublish = useCallback(async () => {\n        const publishedEnv = environments.named.find((e) => e.tags?.indexOf(\"default_published\") > -1);\n        if (\n            await dispatch(\n                confirm(\"Unpublish your app?\", \"Your app will no longer be accessible via its current public URL\")\n            )\n        ) {\n            if (!publishedEnv) return;\n            await dispatch(deleteEnvironment(publishedEnv));\n            dispatch(recordActivity(\"unpublishApp\"));\n        }\n    }, [environments]);\n\n    const malleableCommitIds = useMemo(() => {\n        const ids: string[] = [];\n        for (const [ref, commitInfo] of Object.entries(malleableCommits || {})) {\n            if (commitInfo) {\n                ids.push(commitInfo.oid);\n            }\n        }\n        return ids;\n    }, [malleableCommits]);\n\n    const doCommit = useCallback(\n        async (commit: CommitVersion | null) => {\n            commit = commit || commitHistory?.versions?.find((v) => v.v === headCommit) || null;\n            if (!commit) return;\n            const msg = await dispatch(\n                modal(\"precommit\", {\n                    title: \"Enter a commit message\",\n                    text: \"Enter a description of this version to help you find it later\",\n                    initialValue: commit?.m || \"Saved app\",\n                    commit,\n                })\n            );\n            if (msg) {\n                // TODO: Cope with updating commit message on an old commit.\n                dispatch(saveApp(true, msg));\n            }\n        },\n        [headCommit, commitHistory]\n    );\n\n    // Hack for inline diffs\n    const [selectedCommit, setSelectedCommit] = useState<CommitVersion | null>(\n        () => commitHistory.versions.find((c) => c.v === headCommit) || null\n    );\n    const onSelectedCommit = (c: CommitVersion) => {\n        console.log(\"Selected commit\", c);\n        setSelectedCommit(c);\n        c?.p?.[0] && dispatch(toggleDiffVisible(true));\n    };\n\n    useEffect(() => {\n        // If the selected commit is no longer in the history (probably because it was a malleable commit that was replaced), deselect.\n        if (!commitHistory?.versions?.find((v) => v.v === selectedCommit?.v)) {\n            setSelectedCommit(null);\n        }\n    }, [commitHistory]);\n\n    const ref = useRef<HTMLDivElement | null>(null);\n\n    useEffect(() => {\n        const loadAndScroll = async () => {\n            await dispatch(loadCommitIntoHistory(app.commitSha));\n            ref.current?.scrollIntoView();\n        };\n        loadAndScroll();\n    }, []);\n\n    const onSelectBranch = useEvent(async (branch: string) => {\n        const commitId = refs.branches[branch]?.commitId || refs.nonCollaboratorBranches?.[branch]?.commitId;\n        if (commitId) {\n            await dispatch(checkoutVersion(commitId, branch));\n        } else {\n            // Fallback if we can't find the commitId\n            await dispatch(loadVersion({ branch }));\n        }\n        ref.current?.scrollIntoView();\n    });\n\n    const onSelectTag = useEvent(async (tag: string) => {\n        const commitId = refs.tags[tag]?.commitId;\n        if (commitId) {\n            await dispatch(checkoutVersion(commitId, \"master\", true));\n            ref.current?.scrollIntoView();\n        }\n    });\n\n    const diffPanel = useMemo(() => {\n        return (\n            isDiffVisible &&\n            selectedCommit && (\n                <ResizePanel\n                    className=\"max-w-full\"\n                    style={{ height: \"100%\" }}\n                    horizontal={true}\n                    panelSize={commitListDiffWidth}\n                    handleAtStart={true}\n                    onFinishDrag={(size) => dispatch(setBottomPanelCommitListDiffWidth(size))}>\n                    <CommitDetails\n                        className={classes.diffDisplay}\n                        commitIdB={selectedCommit.v}\n                        commitIdA={selectedCommit.p?.[0]}\n                    />\n                </ResizePanel>\n            )\n        );\n    }, [isDiffVisible, selectedCommit, commitListDiffWidth, classes, appId]);\n\n    const hasRemotes = useMemo(() => Object.keys(remotes).length > 0, [remotes]);\n\n    const remotesMenuItems: DropDownMenuItems = useMemo(() => {\n        const items: MenuItems = [\n            [\"Manage Git Remotes\", () => dispatch(modal(\"gitRemotes\", {})), faCloudArrowUp],\n            [\"Clone with Git\", () => dispatch(modal(\"gitclone\", {})), faCodeBranch],\n        ];\n        if (githubRemote) {\n            items.push([\"View on Github\", () => window.open(githubRemote.url.replace(/.git$/, \"\")), faGithub]);\n        }\n        return (_selectItem, _hideMenu) => items;\n    }, [remotes, githubRemote]);\n\n    const [commitsReachableFromOtherBranches, commitsReachableFromThisBranchOnly] = useMemo(() => {\n        const otherBranchCommitIds = Object.entries(refs.branches)\n            .filter(([branch, _]) => branch !== editState.branch)\n            .map(([_, { commitId }]) => commitId);\n        const reachableFromOtherBranches = getCommitsReachableFromBranches(\n            otherBranchCommitIds,\n            commitHistory.versions\n        );\n        const reachableFromThisBranchOnly =\n            editState.branch && refs.branches[editState.branch]?.commitId\n                ? getCommitsReachableFromBranches(\n                      [refs.branches[editState.branch].commitId],\n                      commitHistory.versions,\n                      reachableFromOtherBranches\n                  )\n                : new Set();\n        return [reachableFromOtherBranches, reachableFromThisBranchOnly];\n    }, [refs.branches, editState.branch, commitHistory.versions]);\n\n    const currentTag = useMemo(() => {\n        if (!editState.commitId || editState.branch) return null;\n        return Object.entries(refs?.tags || {}).find(([name, { commitId }]) => commitId === editState.commitId)?.[0];\n    }, [editState.commitId, editState.branch, refs?.tags]);\n\n    //console.log(\"Reachable commits are\", commitsReachableFromOtherBranches);\n\n    return (\n        <div className={cx(classes.root, className)}>\n            {user?.impersonator && (\n                <div className={cx(classes.warningNotice)}>\n                    <span>\n                        <b>WARNING</b> When you change branch or visit a commit this will persist for the user.\n                    </span>{\" \"}\n                </div>\n            )}\n            <div className={cx(classes.optionsPane)}>\n                <Text level={3} style={{ margin: 0, marginRight: 10 }}>\n                    {currentTag ? \"Viewing tag:\" : editState.branch ? \"Editing branch:\" : \"Viewing commit:\"}\n                </Text>\n                <RefSelector\n                    currentBranch={editState.branch}\n                    currentTag={currentTag}\n                    currentCommitId={!editState.branch && !currentTag ? editState.commitId : null}\n                    onSelectBranch={onSelectBranch}\n                    onSelectTag={onSelectTag}\n                    onCreateBranch={() => dispatch(createNewBranch(headCommit))}\n                    onCreateTag={() => dispatch(createNewTag(headCommit))}\n                    includePersonalBranch={false}\n                />\n                {editState.branch && editState.branch !== \"master\" && (\n                    <Button\n                        size={\"small\"}\n                        className={classes.toolbarButton}\n                        onClick={() => dispatch(mergeAppVersion(headCommit, editState.branch, \"master\"))}>\n                        Merge changes into master\n                    </Button>\n                )}\n                {\"merge\" in editState && (\n                    <Button\n                        size={\"small\"}\n                        className={classes.toolbarButton}\n                        onClick={() => dispatch(abandonMerge(editState.merge!))}\n                        icon={faTrashAlt}>\n                        Abandon Merge\n                    </Button>\n                )}\n                {\"merge\" in editState && !hasConflicts && (\n                    <Button\n                        size={\"small\"}\n                        className={classes.toolbarButton}\n                        onClick={() => dispatch(completeMerge(editState.merge!))}\n                        icon={faCheck}>\n                        Complete Merge\n                    </Button>\n                )}\n                {/*{editState.branch && editState.branch === \"master\" && <ContentButton onClick={() => dispatch(resetAppAndBranchToVersion(`users/${user.email}`, headCommit))}>Switch to my development branch</ContentButton>}*/}\n                {!legacy &&\n                    canPublish &&\n                    editState.branch &&\n                    publishedEnv?.version?.[\"ref\"] !== `refs/heads/${editState.branch}` && (\n                        <Button\n                            size={\"small\"}\n                            className={classes.toolbarButton}\n                            onClick={() => publish({ ref: `refs/heads/${editState.branch}` })}>\n                            Publish '{editState.branch}' branch\n                        </Button>\n                    )}\n                {!legacy &&\n                    canPublish &&\n                    editState.branch &&\n                    publishedEnv?.version?.[\"ref\"] === `refs/heads/${editState.branch}` && (\n                        <Button size={\"small\"} className={classes.toolbarButton} onClick={() => unpublish()}>\n                            Unpublish '{editState.branch}' branch\n                        </Button>\n                    )}\n                {!legacy && !canPublish && editState.branch && (\n                    <Button\n                        size={\"small\"}\n                        className={classes.toolbarButton}\n                        onClick={() => dispatch(modal(\"environments\", {}))}>\n                        Publish app...\n                    </Button>\n                )}\n                {\"branch\" in editState && (\n                    <Button\n                        size={\"small\"}\n                        className={classes.toolbarButton}\n                        onClick={() => doCommit(null)}\n                        variant={malleableCommitIds.indexOf(headCommit) > -1 ? undefined : \"disabled\"}\n                        disabled={malleableCommitIds.indexOf(headCommit) === -1}>\n                        Commit\n                    </Button>\n                )}\n                <div className={classes.spring} />\n                {hasRemotes ? (\n                    <GitSyncButton menuItems={remotesMenuItems} classes={classes} />\n                ) : (\n                    <Button\n                        menuItems={remotesMenuItems}\n                        size={\"small\"}\n                        className={classes.toolbarButton}\n                        onClick={() => dispatch(connectToNewGithubRepo())}\n                        icon={faGithub}>\n                        Save app to GitHub\n                    </Button>\n                )}\n                <Button\n                    small\n                    className={classes.toolbarButton}\n                    variant={!isDiffVisible ? \"outlined\" : undefined}\n                    onClick={() => dispatch(toggleDiffVisible(!isDiffVisible))}>\n                    <FontAwesomeIcon icon={faColumns} />\n                </Button>\n            </div>\n            <div style={{ display: \"flex\", position: \"relative\", height: \"100%\", overflow: \"hidden\" }}>\n                <NoodlePane\n                    className={classes.noodlePane}\n                    classes={classes}\n                    commits={commitHistory.versions}\n                    headCommitId={headCommit}\n                    malleableCommitIds={malleableCommitIds}\n                    reserveFirstLane={reserveFirstLane}\n                    onDoubleClickCommit={(commit: CommitVersion) => {\n                        if (commit.v !== headCommit) {\n                            dispatch(checkoutVersion(commit.v));\n                        }\n                    }}\n                    onDoubleClickBranch={(commitId: string, branch?: string | null, forceVisiting?: boolean) => {\n                        dispatch(checkoutVersion(commitId, branch ?? undefined, forceVisiting));\n                    }}\n                    onSelectCommit={onSelectedCommit}\n                    onLoadMore={async () => await dispatch(updateAppCommitHistory(commitHistory.versions.length + 50))}\n                    generateCommitContextMenuItems={(commit: CommitVersion, _selectItem: any, _hideMenu: any) => {\n                        const items: any[] = [];\n                        if (commit.v !== headCommit) {\n                            items.push([`Checkout this commit`, () => dispatch(checkoutVersion(commit.v))]);\n                            if (editState.branch) {\n                                items.push([\n                                    `Reset '${editState.branch}' branch to here`,\n                                    () => dispatch(resetBranch(editState.branch as string, commit.v)),\n                                ]);\n                            }\n                            items.push([`Merge into '${editState.branch}'`, () => dispatch(mergeAppVersion(commit.v))]);\n                            items.push(<hr />);\n                        }\n                        const merges = Object.entries(refs.resolvingMerges || {}).filter(\n                            ([mergeId, { oid }]: [string, MergeRefEntry]) => oid === commit.v\n                        );\n                        if (merges.length > 0) {\n                            items.push([\"Abandon merge\", () => dispatch(abandonMerge(merges[0][0]))]);\n                        }\n\n                        const allBranches = Object.entries(refs.branches || {}).sort((a, b) =>\n                            a[0].localeCompare(b[0])\n                        );\n                        const otherBranches = allBranches.filter(\n                            ([branch, { commitId }]: [string, BranchRefEntry]) =>\n                                commitId === commit.v && branch !== editState.branch\n                        );\n\n                        if (legacy) {\n                            // Legacy \"publish\" interface\n                            if (commit.v !== publishedCommit) {\n                                items.push([\"Publish\", () => publishLegacy(commit)]);\n                            } else {\n                                items.push([\"Unpublish\", unpublishLegacy]);\n                            }\n                            items.push(<hr />);\n                        } else if (canPublish) {\n                            if (publishedEnv?.version?.[\"commit-id\"] !== commit.v) {\n                                items.push([\"Publish this commit\", () => publish({ \"commit-id\": commit.v })]);\n                            }\n\n                            if (publishedEnv?.version?.[\"commit-id\"] === commit.v) {\n                                items.push([\"Unpublish this commit\", () => unpublish()]);\n                            }\n\n                            for (const [branch, { commitId }] of allBranches) {\n                                if (commitId === commit.v && publishedEnv?.version?.ref !== `refs/heads/${branch}`) {\n                                    items.push([\n                                        `Publish '${branch}' branch`,\n                                        () => publish({ ref: `refs/heads/${branch}` }),\n                                    ]);\n                                } else if (\n                                    commitId === commit.v &&\n                                    publishedEnv?.version?.ref === `refs/heads/${branch}`\n                                ) {\n                                    items.push([`Unpublish '${branch}' branch`, () => unpublish()]);\n                                }\n                            }\n\n                            items.push(<hr />);\n                        }\n                        items.push([\"Create branch here...\", () => dispatch(createNewBranch(commit.v))]);\n                        items.push([\"Tag this commit\", () => dispatch(createNewTag(commit.v))]);\n\n                        if (otherBranches.length) {\n                            items.push(<hr />);\n                            items.push(\n                                ...otherBranches.map(([branch, { commitId }]) => [\n                                    `Checkout branch '${branch}'`,\n                                    () => dispatch(checkoutVersion(commitId, branch)),\n                                ])\n                            );\n                            items.push(<hr />);\n                            items.push(\n                                ...otherBranches.map(([branch]) => [\n                                    `Delete branch '${branch}'`,\n                                    () => dispatch(deleteBranch(branch)),\n                                ])\n                            );\n                        }\n\n                        if (user?.ab?.[USER_AB_FLAGS.editHistory] && !commitsReachableFromOtherBranches.has(commit.v)) {\n                            items.push(<hr />);\n                            items.push([\"Edit commit message...\", () => dispatch(editCommitMessage(commit))]);\n                            if (\n                                commit.v !== (editState.branch ? refs.branches[editState.branch]?.commitId : undefined)\n                            ) {\n                                const permanent = !commitsReachableFromThisBranchOnly.has(commit.v);\n                                items.push([\n                                    permanent ? \"Delete commit\" : \"Remove from history (squash)\",\n                                    () => dispatch(deleteCommits([commit.v], permanent)),\n                                ]);\n                            }\n                        }\n\n                        const allTags = Object.entries(refs.tags || {});\n                        const tagsOnCommit = allTags.filter(\n                            ([tag, { commitId }]: [string, TagRefEntry]) =>\n                                commitId === commit.v && tag.indexOf(\"anvil-preserved/\") !== 0\n                        );\n\n                        if (tagsOnCommit.length) {\n                            items.push(<hr />);\n                            items.push(\n                                ...tagsOnCommit.map(([tag]) => [`Delete tag '${tag}'`, () => dispatch(deleteTag(tag))])\n                            );\n                        }\n\n                        return items;\n                    }}\n                    activeCommitRef={ref}\n                />\n                {diffPanel}\n            </div>\n        </div>\n    );\n};\n\nexport default historyConnector(History);\n","import React from \"react\";\nimport type { WhereToStartTutorial } from \"@/controllers/whereToStartTutorials\";\nimport Link from \"../reusable/Link\";\n\n// Tutorials we advertise based on the user's where-to-start survey answer (see\n// controllers/whereToStartTutorials). Each one shows as a start page CTA and as a bottom panel\n// tab that is open by default until the user closes it.\n\ninterface WhereToStartTutorialCta {\n    path: string;\n    /** Distinguishes clicks from each surface in `utm_source`, eg \"ide-start-page:where-to-start-guis\". */\n    utmSlug: string;\n    imageURL: string;\n    imageAlign?: \"top-left\" | \"top-center\";\n    title: string;\n    /** Heading above the card in the bottom panel tab. */\n    panelHeading: string;\n    body: React.ReactNode;\n}\n\nexport const WHERE_TO_START_TUTORIAL_CTAS: Record<WhereToStartTutorial, WhereToStartTutorialCta> = {\n    guisAreDifferent: {\n        path: \"/docs/get-started/coming-from-scripting\",\n        utmSlug: \"where-to-start-guis\",\n        imageURL: \"https://anvil-website-static.s3.eu-west-2.amazonaws.com/misc-assets/2026-08-guis-are-different.png\",\n        imageAlign: \"top-center\",\n        title: \"Intro to GUI and Server Programming\",\n        panelHeading: \"If you've written Python scripts before, here's how GUIs are different.\",\n        body: (\n            <>\n                <p className={\"mb-2\"}>\n                    Interactive apps are different from Python scripts. Instead of running all your code at once, everything is driven by events from the components on your page.\n                </p>\n\n                <p className={\"mb-2\"}>\n                    This quick guide covers:\n                </p>\n\n                <ul className=\"list-inside list-disc marker:text-primary\">\n                    <li>How to code with GUIs</li>\n                    <li>The difference between \"client\" and \"server\" code</li>\n                    <li>How to store your data</li>\n                </ul>\n            </>\n        ),\n    },\n    scriptsTutorial: {\n        path: \"/learn/tutorials/scripts\",\n        utmSlug: \"where-to-start-scripts\",\n        imageURL: \"/learn/tutorials/img/scripts/scripts-tutorial-thumbnail.png\",\n        imageAlign: \"top-center\",\n        // TODO: Placeholder copy\n        title: \"Turn a Python script into a web app\",\n        panelHeading: \"Already have a Python script or notebook? Here's how to give it a web UI.\",\n        body: (\n            <>\n                <p className={\"mb-2\"}>\n                    Follow this step-by-step guide to take an existing script and build a web user interface around it so anyone can use it from their browser.\n                </p>\n\n                <p className={\"mb-2\"}>\n                    You'll learn how to:\n                </p>\n\n                <ul className=\"list-inside list-disc marker:text-primary\">\n                    <li>Run a script in Anvil</li>\n                    <li>Create a UI to capture inputs and display outputs</li>\n                    <li>Publish your app for other people to use</li>\n                </ul>\n            </>\n        ),\n    },\n};\n\nexport const whereToStartTutorialLink = (tutorial: WhereToStartTutorial, surface: \"ide-start-page\" | \"ide-bottom-panel\") => {\n    const { path, utmSlug } = WHERE_TO_START_TUTORIAL_CTAS[tutorial];\n    return `${path}?utm_source=${surface}:${utmSlug}&l=${surface}`;\n};\n\nconst WhereToStartTutorialPanel = ({ tutorial }: { tutorial: WhereToStartTutorial }) => {\n    const { imageURL, title, panelHeading, body } = WHERE_TO_START_TUTORIAL_CTAS[tutorial];\n    return (\n        <div className={\"h-full overflow-y-auto px-20\"}>\n            <h2 className={\"mb-5 mt-8 text-3xl font-medium dark:text-dark-fg1\"}>\n                {panelHeading}\n            </h2>\n            <Link\n                to={whereToStartTutorialLink(tutorial, \"ide-bottom-panel\")}\n                target={\"_blank\"}\n                className=\"mb-4 flex flex-wrap gap-10 rounded-md  border-2 border-sectionborder bg-light-bg2 p-8 hover:bg-sidebar-highlight1 dark:border-dark-bg4 dark:bg-dark-bg0 dark:hover:bg-dark-bg6 md:flex-nowrap\">\n                <div\n                    style={{ backgroundImage: `url(${imageURL})` }}\n                    className=\"min-h-[200px] w-[360px] min-w-[270px] rounded-md border-2 border-sectionborder bg-cover bg-center dark:border-dark-bg4\"></div>\n                <div className=\"shrink dark:text-white\">\n                    <h3 className=\"text-[16px] font-semibold text-primary\">{title}</h3>\n                    {body}\n                </div>\n            </Link>\n        </div>\n    );\n};\n\nexport default WhereToStartTutorialPanel;\n","import { useEffect, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { getUserHasLoaded } from \"@/controllers/ide\";\nimport { navigate } from \"@/router/navigation\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useAppsInfiniteQuery } from \"@/util/hooks\";\nimport { Button } from \"../reusable/Button\";\nimport { ButtonGroup } from \"../reusable/ButtonGroup\";\nimport { ContentTextInput } from \"../reusable/SharedComponents\";\nimport styles from \"./mobile.module.css\";\n\nconst ownerOptions = [\n    { value: \"All\", title: \"All\" },\n    { value: \"Mine\", title: \"Mine\" },\n    { value: \"Shared\", title: \"Shared\" },\n] as const;\n\nconst AppPicker = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const userHasLoaded = useSelector(getUserHasLoaded);\n    const [owner, setOwner] = useState<(typeof ownerOptions)[number][\"value\"]>(\"All\");\n    const { apps, isFetched, isFetching, isError, isPlaceholderData, hasNextPage, fetchNextPage, setQuery } =\n        useAppsInfiniteQuery({ enabled: userHasLoaded, owner });\n    const loadMoreRef = useRef<HTMLDivElement>(null);\n    useEffect(() => {\n        const sentinel = loadMoreRef.current;\n        if (!sentinel || !hasNextPage || isFetching || isPlaceholderData || isError) return;\n        // Observe after each page renders, so the initial empty list cannot trigger a premature fetch.\n        const observer = new IntersectionObserver(\n            ([entry]) => {\n                if (entry.isIntersecting) {\n                    observer.disconnect();\n                    void fetchNextPage();\n                }\n            },\n            { rootMargin: \"200px\" }\n        );\n        observer.observe(sentinel);\n        return () => observer.disconnect();\n    }, [hasNextPage, isFetching, isPlaceholderData, isError, fetchNextPage]);\n    return (\n        <div className=\"mx-auto w-full max-w-[480px] px-[16px] pt-[calc(28px+env(safe-area-inset-top))] pb-[28px]\">\n            <p className={styles.eyebrow}>YOUR APPS</p>\n            <div className=\"mt-[6px] mb-[16px] flex flex-wrap items-center justify-between gap-[8px]\">\n                <h2 id=\"mobile-app-picker-title\" className=\"m-0 text-[22px] tracking-[-0.7px]\">Choose an app</h2>\n                <ButtonGroup\n                    className=\"ml-auto shrink-0 whitespace-nowrap\"\n                    small\n                    linkClassName=\"h-[32px]! px-[10px]!\"\n                    options={ownerOptions}\n                    selectedOption={owner}\n                    selectedVariant=\"primary\"\n                    onClick={setOwner}\n                />\n            </div>\n            <ContentTextInput\n                type=\"search\"\n                aria-label=\"Search apps or tags\"\n                placeholder=\"Search apps or tags\"\n                className=\"mb-[16px] h-[44px]! w-full text-[16px]!\"\n                onChange={(event) => setQuery(event.target.value)}\n            />\n            {!isFetched && <p>Loading your apps…</p>}\n            {isError && <p>Unable to load your apps. Please try again.</p>}\n            {isFetched && !isFetching && !isError && apps.length === 0 && <p>No matching apps.</p>}\n            {apps.map((app) => (\n                <button\n                    className=\"flex w-full items-center gap-[10px] border-0 border-b border-[#e2e8ec] bg-transparent px-[6px] py-[14px] text-left text-[#263d49]\"\n                    key={app.id}\n                    onClick={() => dispatch(navigate({ type: \"APP_ROOT\", appId: app.id }))}>\n                    <span className=\"text-[#84a6b6]\" aria-hidden=\"true\">\n                        ◇\n                    </span>\n                    {app.name}\n                </button>\n            ))}\n            <div ref={loadMoreRef} className=\"min-h-px\">\n                {hasNextPage && (\n                    <Button disabled={isFetching || isPlaceholderData} onClick={() => void fetchNextPage()}>\n                        {isFetching ? \"Loading more apps…\" : \"Load more apps\"}\n                    </Button>\n                )}\n            </div>\n        </div>\n    );\n};\n\nexport default AppPicker;\n","// The App section lists the real app's code; the other sections are still sample-only.\nexport const sections = [\n    { label: \"App\", icon: \"◇\", items: [] as string[] },\n    { label: \"Data\", icon: \"▤\", items: [\"Data Tables\", \"Users\"] },\n    { label: \"Services\", icon: \"↗\", items: [\"Email\", \"Scheduled Tasks\", \"Uplink\"] },\n    { label: \"Search\", icon: \"⌕\", items: [] },\n    {\n        label: \"Tools\",\n        icon: \"⌘\",\n        items: [\"App Console\", \"Server Console\", \"App logs\", \"Background Tasks\", \"Version History\"],\n    },\n    { label: \"Settings\", icon: \"⚙\", items: [\"Settings\", \"Environments\", \"Dependencies\"] },\n];\nexport const sampleChats = [\n    { title: \"Build the booking form\", preview: \"Add a date picker and save reservations.\", date: \"Today\" },\n    { title: \"Style the home page\", preview: \"A calmer colour palette for Fieldnotes.\", date: \"Today\" },\n    { title: \"Connect the bookings table\", preview: \"Store workshop bookings in Data Tables.\", date: \"Yesterday\" },\n    { title: \"Send confirmation emails\", preview: \"Let guests know their place is reserved.\", date: \"Yesterday\" },\n    { title: \"Debug the server module\", preview: \"Track down the missing argument.\", date: \"10 Nov\" },\n    { title: \"Plan the workshop app\", preview: \"Forms, services and the first version.\", date: \"9 Nov\" },\n];\n","import { useRef, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { faChevronDown } from \"@fortawesome/free-solid-svg-icons/faChevronDown\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { getApp } from \"@/controllers/app\";\nimport styles from \"./mobile.module.css\";\nimport { sampleChats } from \"./sample-content\";\n\ninterface ChatPickerProps {\n    visible: boolean;\n    selectedChat: string;\n    onSelectChat: (title: string) => void;\n}\nexport default function ChatPicker({ visible, selectedChat, onSelectChat }: ChatPickerProps) {\n    const app = useSelector(getApp);\n    const [chatQuery, setChatQuery] = useState(\"\");\n    const chatPicker = useRef<HTMLDialogElement>(null);\n    const chatSelector = useRef<HTMLButtonElement>(null);\n    return (\n        <>\n            {visible && (\n                <nav className={styles.secondaryBar} aria-label=\"AI chat tools\">\n                    <button\n                        ref={chatSelector}\n                        className={`${styles.modeSelector} min-w-0 flex-1! gap-[12px]! border-r-0!`}\n                        aria-label={`Choose chat: ${selectedChat}`}\n                        aria-haspopup=\"dialog\"\n                        onClick={() => chatPicker.current?.showModal()}>\n                        <span className=\"truncate\">{selectedChat}</span>\n                        <FontAwesomeIcon icon={faChevronDown} className={styles.chevron} aria-hidden=\"true\" />\n                    </button>\n                    <span className=\"flex items-center px-[16px] text-[10px] text-[#90a2ac]\">\n                        {sampleChats.length} chats\n                    </span>\n                </nav>\n            )}\n\n            <dialog\n                ref={chatPicker}\n                className=\"fixed inset-0 m-0 h-dvh max-h-none w-full max-w-none border-0 bg-white p-0 text-[#263d49] backdrop:bg-white\"\n                aria-label=\"Your chats\"\n                onClose={() => {\n                    setChatQuery(\"\");\n                    chatSelector.current?.focus();\n                }}>\n                <div className=\"flex h-full flex-col pt-[env(safe-area-inset-top)] pb-[env(safe-area-inset-bottom)]\">\n                    <header className={styles.panelHeader}>\n                        <button\n                            className={styles.iconButton}\n                            aria-label=\"Back to chat\"\n                            onClick={() => chatPicker.current?.close()}>\n                            ←\n                        </button>\n                        <div>\n                            <strong>Your chats</strong>\n                            <span>\n                                {app?.name ?? \"Fieldnotes\"} · {sampleChats.length} conversations\n                            </span>\n                        </div>\n                        <button\n                            className={styles.iconButton}\n                            aria-label=\"Close chat list\"\n                            onClick={() => chatPicker.current?.close()}>\n                            ×\n                        </button>\n                    </header>\n                    <label className=\"mx-[18px] mt-[18px] mb-[12px] flex items-center gap-[10px] rounded-[8px] border border-[#e5ecef] bg-[#f4f7f9] px-[14px] py-[11px] text-[#8a9fa9] focus-within:border-primary\">\n                        <span aria-hidden=\"true\">⌕</span>\n                        <input\n                            className=\"min-w-0 flex-1 border-0 bg-transparent text-[13px] text-[#263d49] outline-0\"\n                            autoFocus\n                            aria-label=\"Search chats\"\n                            placeholder=\"Search your chats…\"\n                            value={chatQuery}\n                            onChange={(event) => setChatQuery(event.target.value)}\n                        />\n                    </label>\n                    <div className=\"flex-1 overflow-y-auto px-[10px] pb-[20px]\">\n                        {sampleChats\n                            .filter((chat) =>\n                                `${chat.title} ${chat.preview}`.toLowerCase().includes(chatQuery.toLowerCase())\n                            )\n                            .map((chat) => (\n                                <button\n                                    key={chat.title}\n                                    className=\"flex w-full items-start gap-[12px] rounded-[6px] border-0 border-b border-[#edf1f3] bg-transparent px-[12px] py-[18px] text-left text-[#526f7d] aria-pressed:border-b-transparent aria-pressed:bg-[#eef8fc]\"\n                                    aria-pressed={selectedChat === chat.title}\n                                    onClick={() => {\n                                        onSelectChat(chat.title);\n                                        chatPicker.current?.close();\n                                    }}>\n                                    <span className=\"text-[22px] leading-[1.3] text-[#7cabbf]\" aria-hidden=\"true\">\n                                        ✧\n                                    </span>\n                                    <span className=\"min-w-0 flex-1\">\n                                        <strong className=\"mb-[5px] block text-[13px] font-semibold text-[#344e5c]\">\n                                            {chat.title}\n                                        </strong>\n                                        <span className=\"block text-[11px] leading-[1.6] text-[#8c9ea8]\">\n                                            {chat.preview}\n                                        </span>\n                                    </span>\n                                    <span className=\"shrink-0 pt-[3px] text-right text-[9px] text-[#96a8b2]\">\n                                        {chat.date}\n                                        <span className=\"mt-[12px] block text-[14px] text-primary-600\">\n                                            {selectedChat === chat.title ? \"✓\" : \"\"}\n                                        </span>\n                                    </span>\n                                </button>\n                            ))}\n                        {!sampleChats.some((chat) =>\n                            `${chat.title} ${chat.preview}`.toLowerCase().includes(chatQuery.toLowerCase())\n                        ) && <p className={styles.noResults}>No chats found. Try another search.</p>}\n                    </div>\n                </div>\n            </dialog>\n        </>\n    );\n}\n","import { Tab } from \"@/types\";\n\nexport const sampleIcon = (name: string) => (name.includes(\"Console\") ? \"›_\" : \"◇\");\nexport const tabIcon = (tab: Tab) => (tab.navTarget.type === \"CODE\" ? \"▧\" : \"⌘\");\nexport const tabTitle = (tab: Tab) => tab.title || tab.navTarget.type.toLowerCase().replace(/_/g, \" \");\n","import React from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faChevronDown } from \"@fortawesome/free-solid-svg-icons/faChevronDown\";\nimport { faComment } from \"@fortawesome/pro-light-svg-icons/faComment\";\nimport { faSparkle } from \"@fortawesome/pro-regular-svg-icons/faSparkle\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { getApp } from \"@/controllers/app\";\nimport { getIsAllSaved, runApp, stopApp } from \"@/controllers/ide\";\nimport { closeTab } from \"@/controllers/tabs\";\nimport { AnvilDispatch, Tab } from \"@/types\";\nimport { Button } from \"../reusable/Button\";\nimport DropdownMenu from \"../reusable/DropdownMenu\";\nimport styles from \"./mobile.module.css\";\nimport { sampleIcon, tabIcon, tabTitle } from \"./tabs\";\n\ninterface MobileHeaderProps {\n    running: boolean;\n    realTabs: Tab[];\n    activeRealTab: Tab | undefined;\n    activeTitle: string;\n    sampleTabs: string[];\n    activeSample: string | null;\n    menuButton: React.Ref<HTMLButtonElement>;\n    onOpenNavigation: () => void;\n    onOpenSample: (name: string) => void;\n    onCloseSample: (name: string) => void;\n    onSelectSample: (name: string) => void;\n    onFocusRealTab: (tab: Tab) => void;\n}\nexport default function MobileHeader({\n    running,\n    realTabs,\n    activeRealTab,\n    activeTitle,\n    sampleTabs,\n    activeSample,\n    menuButton,\n    onOpenNavigation,\n    onOpenSample,\n    onCloseSample,\n    onSelectSample,\n    onFocusRealTab,\n}: MobileHeaderProps) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const app = useSelector(getApp);\n    const allSaved = useSelector(getIsAllSaved);\n    const activeIcon = activeRealTab ? tabIcon(activeRealTab) : activeTitle ? sampleIcon(activeTitle) : \"◇\";\n    return (\n        <header className=\"relative flex h-[calc(52px+env(safe-area-inset-top))] shrink-0 items-center gap-[10px] border-b border-[#e2e8ec] bg-white pt-[env(safe-area-inset-top)] pr-[12px] pl-[4px]\">\n            {running ? (\n                <button className={styles.iconButton} aria-label=\"Back to editor\" onClick={() => dispatch(stopApp())}>\n                    ←\n                </button>\n            ) : (\n                <button\n                    ref={menuButton}\n                    className={styles.iconButton}\n                    aria-label=\"Open navigation\"\n                    onClick={onOpenNavigation}>\n                    ☰\n                    {allSaved && (\n                        <span\n                            className=\"absolute top-[8px] right-[7px] size-[8px] rounded-full bg-[#239f89] shadow-[0_0_0_2px_white]\"\n                            role=\"status\"\n                            aria-label=\"All changes saved\"\n                        />\n                    )}\n                </button>\n            )}\n            {running ? (\n                <div className=\"flex min-w-0 flex-1 flex-col leading-[1.35]\">\n                    <strong className=\"truncate text-[14px]\">{app?.name ?? \"Fieldnotes\"}</strong>\n                    <span className=\"text-[9px] tracking-[1px] text-[#7e9099]\">APP PREVIEW</span>\n                </div>\n            ) : (\n                <DropdownMenu\n                    menuClassName=\"box-border w-screen max-h-[60dvh]! rounded-none! border-0! p-[6px]! [font:12px/1.5_system-ui,sans-serif]! [&>div]:min-h-[44px] [&>div]:cursor-pointer [&>div]:rounded-[4px]\"\n                    items={(_selectItem, hideMenu) => [\n                        ...[\n                            ...realTabs.map((tab) => ({\n                                key: `tab-${tab.id}`,\n                                label: tabTitle(tab),\n                                icon: tabIcon(tab),\n                                isActive: tab.id === activeRealTab?.id,\n                                focus: () => onFocusRealTab(tab),\n                                close: () => dispatch(closeTab(tab.id)),\n                            })),\n                            ...sampleTabs.map((name) => ({\n                                key: `sample-${name}`,\n                                label: name,\n                                icon: sampleIcon(name),\n                                isActive: activeSample === name,\n                                focus: () => onSelectSample(name),\n                                close: () => onCloseSample(name),\n                            })),\n                        ].map(({ key, label, icon, isActive, focus, close }) => (\n                            <div key={key} className=\"flex items-stretch hover:bg-[#edf7fc]\">\n                                <button\n                                    className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-[12px] border-0 bg-transparent p-[10px] text-left text-inherit [font:inherit] focus-visible:outline-2 focus-visible:outline-primary focus-visible:-outline-offset-2\"\n                                    aria-label={`Switch to ${label}`}\n                                    onClick={() => {\n                                        focus();\n                                        hideMenu();\n                                    }}>\n                                    <span className=\"w-[18px] text-[#5d9ba9]\" aria-hidden=\"true\">\n                                        {icon}\n                                    </span>\n                                    <span>{label}</span>\n                                    <span className=\"ml-auto text-primary-600\" aria-hidden=\"true\">\n                                        {isActive ? \"✓\" : \"\"}\n                                    </span>\n                                </button>\n                                <button\n                                    className=\"w-[44px] shrink-0 cursor-pointer border-0 bg-transparent text-[20px]! text-[#71838e] [font:inherit] focus-visible:outline-2 focus-visible:outline-primary focus-visible:-outline-offset-2\"\n                                    aria-label={`Close ${label}`}\n                                    onClick={() => {\n                                        close();\n                                        hideMenu();\n                                    }}>\n                                    ×\n                                </button>\n                            </div>\n                        )),\n                        <hr key=\"separator\" />,\n                        [\"＋ Open another tab\", () => onOpenNavigation()],\n                    ]}\n                    render={(showMenu, anchor) => (\n                        <>\n                            <button\n                                id=\"mobile-tab-selector\"\n                                className=\"flex h-[36px] min-w-0 flex-1 items-center gap-[9px] rounded-[5px] border-0 bg-[#f1f5f7] px-[10px] text-left text-[12px]! text-[#263d49]\"\n                                aria-label={`Switch tab: ${activeTitle || \"No open tabs\"}`}\n                                aria-haspopup=\"menu\"\n                                onClick={(event) => showMenu(null, event.currentTarget)}>\n                                <span className=\"text-[#5d9ba9]\">{activeIcon}</span>\n                                <span className=\"truncate\">{activeTitle || \"No open tabs\"}</span>\n                                <span className=\"ml-auto shrink-0 text-[10px] text-[#8197a3]\">\n                                    {realTabs.length + sampleTabs.length} open\n                                </span>\n                                <FontAwesomeIcon icon={faChevronDown} className={styles.chevron} aria-hidden=\"true\" />\n                            </button>\n                            <div className=\"absolute inset-x-0 -bottom-px\">{anchor}</div>\n                        </>\n                    )}\n                />\n            )}\n            {running ? (\n                <Button small onClick={() => dispatch(stopApp())}>\n                    ■ Stop\n                </Button>\n            ) : (\n                <>\n                    <Button\n                        small\n                        isIconButton\n                        variant=\"hidden\"\n                        aria-label=\"AI chat\"\n                        onClick={() => onOpenSample(\"AI chat\")}>\n                        <span className=\"relative inline-flex leading-none\" aria-hidden=\"true\">\n                            <FontAwesomeIcon icon={faComment} className=\"text-[20px]\" />\n                            <span className=\"absolute -top-[3px] -right-[4px] flex rounded-full bg-white p-px\">\n                                <FontAwesomeIcon icon={faSparkle} className=\"text-[10px]\" />\n                            </span>\n                        </span>\n                    </Button>\n                    <Button\n                        small\n                        isIconButton\n                        aria-label=\"Run app\"\n                        variant=\"primary\"\n                        disabled={!app}\n                        onClick={() => dispatch(runApp(\"INLINE\", true))}>\n                        ▶\n                    </Button>\n                </>\n            )}\n        </header>\n    );\n}\n","import React, { useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faChevronDown } from \"@fortawesome/free-solid-svg-icons/faChevronDown\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { getApp } from \"@/controllers/app\";\nimport { getCodeStructure } from \"@/controllers/app/code\";\nimport { getUser } from \"@/controllers/ide\";\nimport { navigate } from \"@/router/navigation\";\nimport { AnvilDispatch, CodePath, StructureItem, Tab } from \"@/types\";\nimport { Button } from \"../reusable/Button\";\nimport styles from \"./mobile.module.css\";\nimport { sections } from \"./sample-content\";\nimport { sampleIcon } from \"./tabs\";\n\ninterface NavItem {\n    key: string;\n    label: string;\n    icon: string;\n    open: () => void;\n    isOpen: boolean;\n    isActive: boolean;\n}\n\nconst codeIcons: Partial<Record<StructureItem[\"type\"], string>> = {\n    form: \"▧\",\n    module: \"◇\",\n    server_module: \"⌘\",\n};\n\nconst listCodeItems = (items: StructureItem[] | undefined): StructureItem[] =>\n    (items ?? []).flatMap((item) => [...(codeIcons[item.type] ? [item] : []), ...listCodeItems(item.children)]);\n\ninterface NavigationDrawerProps {\n    drawer: React.RefObject<HTMLDialogElement | null>;\n    menuButton: React.RefObject<HTMLButtonElement | null>;\n    realTabs: Tab[];\n    currentRealTab: Tab | undefined;\n    showingRealTab: boolean;\n    sampleTabs: string[];\n    activeSample: string | null;\n    onOpenSample: (name: string) => void;\n    onOpenCode: (codePath: CodePath) => void;\n}\nexport default function NavigationDrawer({\n    drawer,\n    menuButton,\n    realTabs,\n    currentRealTab,\n    showingRealTab,\n    sampleTabs,\n    activeSample,\n    onOpenSample,\n    onOpenCode,\n}: NavigationDrawerProps) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const app = useSelector(getApp);\n    const user = useSelector(getUser);\n    const codeStructure = useSelector(getCodeStructure);\n    const [section, setSection] = useState(\"App\");\n    const [query, setQuery] = useState(\"\");\n    const [searchVisible, setSearchVisible] = useState(false);\n    const codeNavItems: NavItem[] = [\n        ...listCodeItems(codeStructure.clientCode.children),\n        ...listCodeItems(codeStructure.serverCode.children),\n    ].map((item) => ({\n        key: item.codePath,\n        label: item.name,\n        icon: codeIcons[item.type]!,\n        open: () => onOpenCode(item.codePath),\n        isOpen: realTabs.some(({ navTarget }) => navTarget.type === \"CODE\" && navTarget.codePath === item.codePath),\n        isActive:\n            showingRealTab &&\n            currentRealTab?.navTarget.type === \"CODE\" &&\n            currentRealTab.navTarget.codePath === item.codePath,\n    }));\n    const sampleNavItem = (name: string): NavItem => ({\n        key: name,\n        label: name,\n        icon: sampleIcon(name),\n        open: () => onOpenSample(name),\n        isOpen: sampleTabs.includes(name),\n        isActive: activeSample === name,\n    });\n    const navItems = (label: string) =>\n        label === \"App\" ? codeNavItems : sections.find((group) => group.label === label)!.items.map(sampleNavItem);\n    const searchResults = sections\n        .flatMap((group) => navItems(group.label))\n        .filter((item) => item.label.toLowerCase().includes(query.toLowerCase()));\n\n    return (\n        <dialog\n            ref={drawer}\n            className=\"fixed inset-y-0 right-auto left-0 m-0 h-dvh max-h-none w-[min(360px,calc(100%_-_24px))] max-w-none border-0 bg-white p-0 text-[#263d49] shadow-[10px_0_50px_#18374930] backdrop:bg-[#17374666] backdrop:backdrop-blur-[2px]\"\n            onClose={() => {\n                setQuery(\"\");\n                setSearchVisible(false);\n                menuButton.current?.focus();\n            }}\n            onClick={(event) => {\n                if (event.target === event.currentTarget) drawer.current?.close();\n            }}>\n            <div className=\"flex h-full flex-col pt-[env(safe-area-inset-top)]\">\n                <div className=\"flex items-center gap-[10px] py-[15px] pr-[8px] pl-[18px]\">\n                    <span className=\"grid size-[32px] place-items-center rounded-[9px] bg-primary text-white [font:bold_26px_Georgia,serif]\">\n                        a\n                    </span>\n                    <strong className=\"flex-1 text-[14px]\">\n                        {app?.name ?? \"No app open\"}\n                        <span className=\"mt-[2px] block text-[10px] font-normal text-[#8b9ba4]\">Development · main</span>\n                    </strong>\n                    <Button small variant=\"primary\" onClick={() => onOpenSample(\"Publish\")}>\n                        Publish\n                    </Button>\n                    <button\n                        className={styles.iconButton}\n                        aria-label=\"Close navigation\"\n                        onClick={() => drawer.current?.close()}>\n                        ×\n                    </button>\n                </div>\n                <div className=\"flex min-h-0 flex-1 border-t border-[#edf1f3]\">\n                    <nav\n                        className=\"flex w-[74px] shrink-0 flex-col overflow-y-auto border-r border-[#edf1f3] bg-[#f8fafb] px-[7px] py-[10px]\"\n                        aria-label=\"Workspace sections\">\n                        {sections.map((group) => (\n                            <button\n                                key={group.label}\n                                className={`mb-[6px] flex w-full shrink-0 flex-col items-center gap-[5px] rounded-[6px] border-0 bg-transparent px-0 py-[12px] text-[10px] text-[#8b9da6] last:mb-0 aria-pressed:bg-[#e3f4fb] aria-pressed:text-primary-700 ${group.label === \"Tools\" ? \"mt-auto\" : \"\"}`}\n                                aria-pressed={section === group.label}\n                                onClick={() => {\n                                    setSection(group.label);\n                                    setQuery(\"\");\n                                    setSearchVisible(group.label === \"Search\");\n                                }}>\n                                <span className=\"text-[23px] leading-[1.2]\">{group.icon}</span>\n                                {group.label}\n                            </button>\n                        ))}\n                    </nav>\n                    <nav className=\"min-w-0 flex-1 overflow-auto px-[10px] py-[23px]\" aria-label=\"Files and tools\">\n                        {searchVisible && (\n                            <label\n                                id=\"mobile-navigation-search\"\n                                className=\"mb-[20px] flex items-center gap-[10px] rounded-[6px] border border-[#e2e9ed] bg-[#f7f9fa] p-[9px] text-[#89a1ab]\">\n                                ⌕\n                                <input\n                                    className=\"min-w-0 w-full border-0 bg-transparent text-[12px] outline-0\"\n                                    autoFocus\n                                    aria-label=\"Find a file or tool\"\n                                    placeholder=\"Find a file or tool…\"\n                                    value={query}\n                                    onChange={(event) => setQuery(event.target.value)}\n                                />\n                            </label>\n                        )}\n\n                        <p className={`${styles.eyebrow} pl-[10px]`}>\n                            {searchVisible\n                                ? \"SEARCH RESULTS\"\n                                : section === \"App\"\n                                  ? \"APP CONTENT\"\n                                  : section.toUpperCase()}\n                        </p>\n                        {(searchVisible ? searchResults : navItems(section)).map((item) => (\n                            <button\n                                key={item.key}\n                                className={`flex w-full items-center gap-[10px] rounded-[5px] border-0 px-[10px] py-[13px] text-left text-[12px] ${item.isActive ? \"bg-[#edf7fc] text-[#147da8]\" : \"bg-transparent text-[#526f7d]\"}`}\n                                onClick={item.open}>\n                                <span className=\"text-[#84a6b6]\">{item.icon}</span>\n                                {item.label}\n                                <span className=\"ml-auto text-primary\">{item.isOpen ? \"•\" : \"\"}</span>\n                            </button>\n                        ))}\n                        {query && searchResults.length === 0 && (\n                            <p className={styles.noResults}>No matching files or tools.</p>\n                        )}\n                        {!searchVisible && section === \"App\" && (\n                            <p className={styles.noResults}>\n                                Forms and modules.\n                                <br />\n                                Tap an item to open a tab.\n                            </p>\n                        )}\n                    </nav>\n                </div>\n                <div className=\"flex shrink-0 items-center justify-between gap-[12px] border-t border-[#e8eef1] bg-white px-[12px] pt-[8px] pb-[calc(8px+env(safe-area-inset-bottom))]\">\n                    <a\n                        className=\"inline-flex min-h-[44px] items-center gap-[8px] rounded-[6px] px-[8px] text-[12px] font-medium text-[#718590] no-underline hover:bg-[#f4f7f9] hover:text-[#263d49] focus-visible:outline-2 focus-visible:outline-primary focus-visible:-outline-offset-2\"\n                        href=\"/build\"\n                        onClick={(event) => {\n                            event.preventDefault();\n                            drawer.current?.close();\n                            dispatch(navigate({ type: \"START_PAGE\" }));\n                        }}>\n                        <span aria-hidden=\"true\">←</span> Apps\n                    </a>\n                    <Button\n                        variant=\"hidden\"\n                        className=\"ml-auto h-[44px]! text-left [&_svg]:ml-[10px] [&_svg]:text-[#96a6af]!\"\n                        aria-label=\"Open account\"\n                        onClick={() => onOpenSample(\"Account\")}>\n                        <span className=\"mr-[8px] inline-flex size-[28px] shrink-0 items-center justify-center rounded-full bg-[#eaf0ec] text-[9px] font-semibold tracking-[0.3px] text-[#65816f]\">\n                            {user?.email?.slice(0, 2).toUpperCase() ?? \"AT\"}\n                        </span>\n                        <span className=\"text-[12px] font-medium text-[#526a77]\">{user?.email ?? \"Alex Taylor\"}</span>\n                        <FontAwesomeIcon icon={faChevronDown} className={styles.chevron} aria-hidden=\"true\" />\n                    </Button>\n                </div>\n            </div>\n        </dialog>\n    );\n}\n","import { Button } from \"../reusable/Button\";\nimport styles from \"./mobile.module.css\";\nimport { sampleChats, sections } from \"./sample-content\";\n\ninterface SampleContentProps {\n    active: string;\n    selectedChat: string;\n    onOpenNavigation: () => void;\n}\nexport default function SampleContent({ active, selectedChat, onOpenNavigation }: SampleContentProps) {\n    return !active ? (\n        <div className={styles.empty}>\n            <h2>Your workspace, one tab at a time.</h2>\n            <p>Open a form, file or tool from the menu.</p>\n            <Button onClick={onOpenNavigation}>Open navigation</Button>\n        </div>\n    ) : active === \"AI chat\" ? (\n        <div className=\"flex-1 bg-[#fbfcfd] px-[20px] py-[28px]\">\n            <p className={styles.eyebrow}>ANVIL ASSISTANT · SAMPLE CHAT</p>\n            <h2 className=\"mt-0 mb-[28px] text-[20px] font-semibold tracking-[-0.4px]\">{selectedChat}</h2>\n            <p className=\"ml-[24px] rounded-[12px_12px_2px_12px] bg-[#eaf4f9] p-[16px] text-[13px] text-[#526f7d]\">\n                {sampleChats.find((chat) => chat.title === selectedChat)?.preview}\n            </p>\n            <div className=\"flex gap-[12px] py-[18px] text-[13px] leading-[1.8] text-[#526f7d]\">\n                <span className=\"text-[24px] text-[#28a5cd]\">✧</span>\n                <p>Let’s work on this together. I can help with your forms, Python code and app design.</p>\n            </div>\n            <p className=\"mt-[40px] text-center text-[11px] text-[#95a5ae]\">\n                Choose a conversation from the toolbar above.\n            </p>\n        </div>\n    ) : active.includes(\"Console\") ? (\n        <div className=\"flex-1 bg-[#fbfcfd] px-[16px] py-[20px] [font:11px/1.8_monospace]\">\n            <p className=\"mt-0 mb-[6px]\">\n                <span className=\"mr-[10px] text-[#9babb4]\">12:04:32</span> Connected to development session\n            </p>\n            <p className=\"mt-0 mb-[6px]\">\n                <span className=\"mr-[10px] text-[#9babb4]\">12:04:32</span> Running app…\n            </p>\n            <p className=\"mt-0 mb-[6px] text-[#249b80]\">✓ App ready</p>\n            <p className=\"mt-[32px] mb-[6px] text-[#9baab2]\">\n                Your app output appears here.\n                <br />\n                This tool has the whole screen, just like a file.\n            </p>\n            <label className=\"mt-[28px] flex gap-[10px] text-[#379dc0]\">\n                ›{\" \"}\n                <input\n                    className=\"w-full border-0 bg-transparent outline-0 [font:inherit]\"\n                    aria-label=\"Console command\"\n                    placeholder=\"Enter a Python expression…\"\n                    onKeyDown={(event) => {\n                        if (event.key === \"Enter\") event.currentTarget.value = \"\";\n                    }}\n                />\n            </label>\n        </div>\n    ) : (\n        <div className={styles.empty}>\n            <div className=\"mb-[20px] text-[40px] text-[#50adc8]\">\n                {sections.find((group) => group.items.includes(active))?.icon ?? \"◇\"}\n            </div>\n            <p className={styles.eyebrow}>YOUR WORKSPACE</p>\n            <h2>{active}</h2>\n            <p>\n                A full-page space for {active.toLowerCase()}.<br />\n                Use the dropdown above to return to your work.\n            </p>\n            <span className=\"mt-[15px] inline-block rounded-[20px] border border-[#d9e4e9] px-[10px] py-[5px] text-[10px] text-[#8b9ca5]\">\n                Navigation prototype · sample content\n            </span>\n        </div>\n    );\n}\n","import { useMemo, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { RunnerIframe } from \"@/components/Runner\";\nimport { WrappedTabContent } from \"@/components/tabs/TabPanel\";\nimport { getApp } from \"@/controllers/app\";\nimport { getRunMode } from \"@/controllers/runner\";\nimport { getCurrentTabId, getTabs } from \"@/controllers/tabs\";\nimport { navigate } from \"@/router/navigation\";\nimport { AnvilDispatch, CodePath, Tab } from \"@/types\";\nimport { useTabPanelRef } from \"@/util/TabPanelRefContext\";\nimport useEvent from \"@/util/useEventCallback\";\nimport AppPicker from \"./AppPicker\";\nimport ChatPicker from \"./ChatPicker\";\nimport MobileHeader from \"./MobileHeader\";\nimport NavigationDrawer from \"./NavigationDrawer\";\nimport SampleContent from \"./SampleContent\";\nimport styles from \"./mobile.module.css\";\nimport { sampleChats } from \"./sample-content\";\nimport { tabTitle } from \"./tabs\";\n\n// Sample shell around the real app's tabs: forms and modules open real editors, everything else is placeholder.\nexport default function MobileIDE() {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const app = useSelector(getApp);\n    const allRealTabs = useSelector(getTabs);\n    const currentTabId = useSelector(getCurrentTabId);\n    const tabPanelRef = useTabPanelRef();\n\n    const [sampleTabs, setSampleTabs] = useState([\"App Console\"]);\n    // null shows the current real tab\n    const [activeSample, setActiveSample] = useState<string | null>(null);\n    const running = useSelector(getRunMode) === \"INLINE\";\n    const [selectedChat, setSelectedChat] = useState(sampleChats[0].title);\n    const drawer = useRef<HTMLDialogElement>(null);\n    const menuButton = useRef<HTMLButtonElement>(null);\n\n    const realTabs = useMemo(() => allRealTabs.filter((tab) => !tab.hidden), [allRealTabs]);\n    // Render in id order so reordering tabs doesn't remount designer iframes (as in TabPanel)\n    const orderedRealTabs = useMemo(() => [...realTabs].sort((a, b) => a.id - b.id), [realTabs]);\n    const currentRealTab = realTabs.find((tab) => tab.id === currentTabId);\n    const showingRealTab = activeSample === null && !!currentRealTab;\n    const active = activeSample ?? (currentRealTab ? tabTitle(currentRealTab) : \"\");\n\n    const onOpenSample = useEvent((name: string) => {\n        setSampleTabs((current) => (current.includes(name) ? current : [...current, name]));\n        setActiveSample(name);\n        drawer.current?.close();\n    });\n    const onCloseSample = useEvent((name: string) => {\n        setSampleTabs((current) => current.filter((tab) => tab !== name));\n        if (activeSample === name) setActiveSample(null);\n    });\n    const onFocusRealTab = useEvent((tab: Tab) => {\n        setActiveSample(null);\n        dispatch(navigate(tab.navTarget));\n    });\n    const onOpenCode = useEvent((codePath: CodePath) => {\n        setActiveSample(null);\n        dispatch(navigate({ type: \"CODE\", codePath }));\n        drawer.current?.close();\n    });\n\n    return (\n        <div className=\"fixed inset-0 isolate flex flex-col bg-[#f2f5f7] text-[#263d49] [font:14px/1.5_system-ui,sans-serif] [-webkit-tap-highlight-color:transparent] [&_*]:box-border [:where(&_button)]:[font:inherit] [:where(&_input)]:[font:inherit] [:where(&_button)]:cursor-pointer [&_button:focus-visible]:outline-2 [&_button:focus-visible]:outline-primary [&_button:focus-visible]:-outline-offset-2 [&_input:focus-visible]:outline-2 [&_input:focus-visible]:outline-primary [&_input:focus-visible]:-outline-offset-2\">\n            {app && (\n                <MobileHeader\n                    running={running}\n                    realTabs={realTabs}\n                    activeRealTab={showingRealTab ? currentRealTab : undefined}\n                    activeTitle={active}\n                    sampleTabs={sampleTabs}\n                    activeSample={activeSample}\n                    menuButton={menuButton}\n                    onOpenNavigation={() => drawer.current?.showModal()}\n                    onOpenSample={onOpenSample}\n                    onCloseSample={onCloseSample}\n                    onSelectSample={setActiveSample}\n                    onFocusRealTab={onFocusRealTab}\n                />\n            )}\n            <ChatPicker\n                visible={!!app && !running && activeSample === \"AI chat\"}\n                selectedChat={selectedChat}\n                onSelectChat={setSelectedChat}\n            />\n            <main\n                id=\"mobile-content\"\n                role={running ? undefined : \"region\"}\n                aria-labelledby={!app ? \"mobile-app-picker-title\" : !running ? \"mobile-tab-selector\" : undefined}\n                className={`relative flex min-h-0 flex-1 flex-col overflow-auto pb-[env(safe-area-inset-bottom)] ${running ? \"bg-white\" : \"\"}`}>\n                {/* Real tabs stay mounted underneath so designer iframes survive tab switches */}\n                {/* Like the desktop IDE, only mount tabs once the app has loaded */}\n                {app && !app.$loading && (\n                    <div\n                        ref={tabPanelRef}\n                        className={`absolute inset-0 bg-white pb-[env(safe-area-inset-bottom)] ${!running && showingRealTab ? \"\" : \"invisible pointer-events-none\"}`}>\n                        {orderedRealTabs.map((tab) => (\n                            <WrappedTabContent\n                                key={`${tab.id}-${tab.forceReload}`}\n                                tab={tab}\n                                selected={tab.id === currentTabId}\n                            />\n                        ))}\n                    </div>\n                )}\n                {running ? (\n                    <div className=\"relative min-h-0 min-w-0 flex-1\">\n                        <RunnerIframe allowSplitView={false} />\n                    </div>\n                ) : !app ? (\n                    <AppPicker />\n                ) : app.$loading ? (\n                    <div className={styles.empty}>\n                        <h2>Opening {app.name ?? \"your app\"}…</h2>\n                    </div>\n                ) : showingRealTab ? null : (\n                    <SampleContent\n                        active={active}\n                        selectedChat={selectedChat}\n                        onOpenNavigation={() => drawer.current?.showModal()}\n                    />\n                )}\n            </main>\n\n            <NavigationDrawer\n                drawer={drawer}\n                menuButton={menuButton}\n                realTabs={realTabs}\n                currentRealTab={currentRealTab}\n                showingRealTab={showingRealTab}\n                sampleTabs={sampleTabs}\n                activeSample={activeSample}\n                onOpenSample={onOpenSample}\n                onOpenCode={onOpenCode}\n            />\n        </div>\n    );\n}\n","import React from \"react\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { ModalComponent } from \".\";\nimport Modal, { ModalButtons } from \"./Modal\";\n\ninterface AlertSpec {\n    title: React.ReactNode;\n    text: React.ReactNode;\n    buttons?: ModalButtons;\n}\n\nconst Alert: ModalComponent<AlertSpec, undefined> = ({ modalId, spec: { title, text, buttons } }) => (\n    <Modal\n        size={\"small\"}\n        className={\"select-text\"}\n        modalId={modalId}\n        allowDismiss={true}\n        title={title}\n        buttons={buttons || [{ text: \"OK\", clickActionCreator: () => modalReturn(true), defaultButton: true }]}>\n        {text}\n    </Modal>\n);\n\nexport default Alert;\n","import React from \"react\";\nimport { ModalComponent } from \".\";\nimport { modalReturn } from \"../../controllers/modals\";\nimport Modal, { ModalButtonProps } from \"./Modal\";\n\ninterface ConfirmSpec {\n    title: React.ReactNode;\n    text: React.ReactNode;\n    ok?: string | Partial<ModalButtonProps>;\n    cancel?: string | Partial<ModalButtonProps>;\n}\n\nconst applyButtonOverrides = (props: ModalButtonProps, overrides?: string | Partial<ModalButtonProps>) => {\n    if (typeof overrides === \"undefined\") {\n        // pass\n    } else if (typeof overrides === \"string\") {\n        props.text = overrides;\n    } else {\n        Object.assign(props, overrides);\n    }\n    return props;\n};\n\nconst Confirm: ModalComponent<ConfirmSpec, boolean> = ({ modalId, spec: { title, text, ok, cancel } }) => {\n    const ButtonConfirm = { text: \"Yes\", clickActionCreator: () => modalReturn(true), defaultButton: true };\n    applyButtonOverrides(ButtonConfirm, ok);\n    const ButtonCancel = { text: \"No\", clickActionCreator: () => modalReturn(false) };\n    applyButtonOverrides(ButtonCancel, cancel);\n\n    return (\n        <Modal modalId={modalId} allowDismiss={false} title={title} buttons={[ButtonConfirm, ButtonCancel]}>\n            {text}\n        </Modal>\n    );\n};\n\nexport default Confirm;\n","import React, { useCallback, useState } from \"react\";\nimport { CheckBox } from \"@/components/reusable/SharedComponents\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { ModalComponent } from \".\";\nimport Modal from \"./Modal\";\n\ninterface ConfirmSpec {\n    title: React.ReactNode;\n    text: React.ReactNode;\n    confirmMessage: React.ReactNode;\n    ok?: string;\n    cancel?: string;\n}\n\nconst ConfirmWithCheckBox: ModalComponent<ConfirmSpec, boolean> = ({\n    modalId,\n    spec: { title, confirmMessage, text, ok = \"Yes\", cancel = \"No\" },\n}) => {\n    const [enabled, setEnabled] = useState(false);\n\n    return (\n        <Modal\n            title={title}\n            modalId={modalId}\n            autoFocus={false}\n            buttons={[\n                {\n                    text: ok,\n                    clickActionCreator: () => modalReturn(true),\n                    variant: \"danger\",\n                    enabled,\n                    defaultButton: true,\n                },\n                { text: cancel, clickActionCreator: () => modalReturn(false) },\n            ]}>\n            <div className=\"flex flex-col gap-4\">\n                {text}\n                <CheckBox autoFocus checked={enabled} onChange={() => setEnabled(!enabled)} text={confirmMessage} />\n            </div>\n        </Modal>\n    );\n};\n\nexport default ConfirmWithCheckBox;\n","import { createContext, useMemo, useRef } from \"react\";\nimport { ModalId } from \"@/components/modals\";\nimport useEvent from \"@/util/useEventCallback\";\n\nexport const ModalHeightContext = createContext({\n    registerModalHeight: (modalId: ModalId, height: number) => {},\n    unregisterModalHeight: (modalId: ModalId) => {},\n});\n\nexport const useModalHeightsContextValue = (ref: React.RefObject<HTMLElement>) => {\n    const modalHeights = useRef<{ [modalId: number]: number }>({});\n\n    const updateMaxHeight = useEvent(() => {\n        let maxSize = 0;\n        for (const s of Object.values(modalHeights.current)) {\n            maxSize = Math.max(s, maxSize);\n        }\n        if (ref.current) {\n            ref.current.style.minHeight = `${maxSize}px`;\n        }\n    });\n\n    const registerModalHeight = useEvent((modalId: ModalId, height: number) => {\n        console.log(\"Registering modal height\", modalId, height);\n        modalHeights.current[modalId] = height;\n        updateMaxHeight();\n    });\n\n    const unregisterModalHeight = useEvent((modalId: ModalId) => {\n        console.log(\"Unregistering modal height\", modalId);\n        delete modalHeights.current[modalId];\n        updateMaxHeight();\n    });\n\n    return useMemo(\n        () => ({ registerModalHeight, unregisterModalHeight }),\n        [registerModalHeight, unregisterModalHeight]\n    );\n};\n","// extracted by css-extract-rspack-plugin\nexport default {\"backdrop\":\"backdrop__src-components-modals-mobile-modal-module\",\"dialog\":\"dialog__src-components-modals-mobile-modal-module\",\"spacer\":\"spacer__src-components-modals-mobile-modal-module\",\"header\":\"header__src-components-modals-mobile-modal-module\",\"footer\":\"footer__src-components-modals-mobile-modal-module\",\"body\":\"body__src-components-modals-mobile-modal-module\"};","import React, {\n    useCallback,\n    useContext,\n    useImperativeHandle,\n    useInsertionEffect,\n    useMemo,\n    useRef,\n    useState,\n} from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport type { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport { faTimes } from \"@fortawesome/pro-light-svg-icons/faTimes\";\nimport { faTimes as faTimesBold } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { ensureModalCancelled, modalCancel, modalRemove, modalReturn } from \"@/controllers/modals\";\nimport { cx, useIsPySpace } from \"@/theme/styles\";\nimport { AnvilAction, AnvilDispatch } from \"@/types\";\nimport { delayAction, stopPropagation } from \"@/util\";\nimport { useResizeObserver, useTimeout } from \"@/util/hooks\";\nimport { useIsMobileIde } from \"@/util/hooks/use-mobile-ide\";\nimport { ModalHeightContext } from \"@/util/modalHeightContext\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { Button, ButtonVariant } from \"../reusable/Button\";\nimport { ErrorSuspenseBoundary } from \"../reusable/ErrorBoundary\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { LoadingSpinner } from \"../reusable/LoadingSpinner\";\nimport mobileStyles from \"./mobile-modal.module.css\";\nimport useStyles from \"./modalstyles\";\n\nconst MODAL_DELAY = 150; // Slightly more than theme.appearTime\n\ntype Falsy = false | 0 | \"\" | null | undefined | 0n;\n\nexport type ModalButtonProps = {\n    text: string;\n    icon?: IconDefinition;\n    tooltip?: string;\n    clickActionCreator?: () => AnvilAction | Promise<AnvilAction> | void | Promise<void>;\n    /** returns: true is equivalent to clickActionCreator: () => modalReturn(true) */\n    returns?: any;\n    defaultButton?: boolean;\n    variant?: ButtonVariant;\n    close?: boolean;\n    enabled?: boolean;\n    shrinkable?: boolean;\n    elevated?: boolean;\n    round?: boolean;\n};\n\nexport interface ModalRef {\n    returnValue: (value?: any) => Promise<void>;\n    cancel: (cancelMethod: string) => Promise<void>;\n}\n\nexport type ModalButtons = (ModalButtonProps | Falsy)[];\n\ninterface ModalProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n    modalId: number;\n    title?: string | React.ReactNode;\n    icon?: IconDefinition;\n    /** autoFocus is false then it is the responsibility of the children to set focus */\n    autoFocus?: boolean;\n    className?: string;\n    classes?: Record<string, string>;\n    /** Whether the modal has a close button, and whether it can be dismissed by clicking on the background. */\n    allowDismiss?: boolean;\n    size?: \"small\" | \"medium\" | \"large\" | \"huge\";\n    buttons?: ModalButtons;\n    /** Buttons (or other things) to display on the left hand side of the modal footer. */\n    leftButtons?: React.ReactNode;\n    /** Modal content */\n    children?: React.ReactNode;\n    /** Called before the built-in dismiss triggers. If it returns false, the modal is not dismissed. */\n    beforeClose?: () => any;\n    closeIcon?: IconDefinition;\n    ref?: React.Ref<ModalRef>;\n}\n\ntype DispatchAndMaybeClose = (action?: void | AnvilAction | undefined, close?: boolean) => Promise<void>;\n\ninterface ButtonsProps {\n    buttons: ModalButtonProps[];\n    dispatchAndMaybeClose: DispatchAndMaybeClose;\n}\n\nconst Buttons = ({ buttons, dispatchAndMaybeClose }: ButtonsProps) => {\n    const [processing, setProcessing] = useState(false);\n    return (\n        <>\n            {buttons.map(\n                (\n                    {\n                        text,\n                        icon,\n                        tooltip,\n                        clickActionCreator,\n                        defaultButton = false,\n                        variant,\n                        close = true,\n                        enabled = true,\n                        shrinkable,\n                        round,\n                        elevated,\n                    },\n                    i\n                ) => (\n                    <Button\n                        key={i}\n                        style={{ marginLeft: \"1rem\" }}\n                        title={tooltip}\n                        disabled={!enabled || processing}\n                        variant={variant || (defaultButton && \"primary\") || undefined}\n                        icon={icon}\n                        onClick={async () => {\n                            setProcessing(true);\n                            await dispatchAndMaybeClose(await clickActionCreator?.(), close);\n                            setTimeout(() => setProcessing(false), MODAL_DELAY);\n                        }}\n                        shrinkable={shrinkable}\n                        round={round}\n                        elevated={elevated}>\n                        {text}\n                    </Button>\n                )\n            )}\n        </>\n    );\n};\n\nconst WrappedSpinner = () => (\n    <div className=\"h-[30vh]\">\n        <LoadingSpinner />\n    </div>\n);\n\n/**\n *\n * @description\n * In order for your custom modal implementation to be loaded when called, it must be listed in the modalTypes in components/modals/index.jsx\n *\n * Note on button placement: General rules for button Consistency\n *   Main actions buttons should be on the left\n *   Use Variant type on Actions and Confirmations (such as variant={\"primary\"}. variant={\"secondary\"}, variant={\"tertiary\"}, variant={\"danger\"}, ...)\n *   Use \"Close\" for information Modals and \"Cancel\" for action Modals\n *\n *\n * @example\n * // Await the result of a modal\n * let modalResult = await dispatch(modal(\"my-modal-type\"));\n *\n *\n * @example\n * // Confirm something from a button *inside* another modal.\n * <button\n *     onClick={async () =>\n *         modalRef.current.returnValue(\n *             await dispatch(modal(\"confirm\", { title: \"Really?\", text: \"Are you sure?\" }))\n *         )\n *     }>\n *     Dismiss this modal\n * </button>;\n *\n * @example\n * // Custom modal implementation\n *\n * const modal = useRef();\n *\n * <Modal\n *     allowDismiss={false}\n *     ref={modal}\n *     buttons={[{text: \"OK\", clickActionCreator: () => modalReturn(\"OKAY\"), variant: 'primary', defaultButton: true, close: false, enabled: false}]}\n *     >\n *     ... MODAL BODY EXAMPLE ...\n *     <button onClick={() => modal.current.cancel(\"CUSTOM_BUTTON\")}>Dismiss the modal</button>\n *     ... END BODY ...\n * </Modal>\n *\n *\n *\n */\nconst Modal = ({ ref, ...modalProps }: ModalProps) => {\n    const {\n        className,\n        modalId,\n        title,\n        icon,\n        allowDismiss = true,\n        size = \"medium\",\n        buttons,\n        leftButtons,\n        closeIcon,\n        children,\n        autoFocus = true,\n        beforeClose,\n        onMouseDown,\n        onKeyDown,\n        ...props\n    } = modalProps;\n\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { classes } = useStyles(undefined, { props });\n    const isPySpace = useIsPySpace();\n    const mobile = useIsMobileIde();\n\n    if (modalId == null) {\n        throw new Error(`Modal created without modalId: '${title}'`);\n    }\n\n    const [hidden, setHidden] = useState(true);\n\n    // Filter out falsey buttons. It's handy to be able to pass buttons like [someCondition && {text: ... }]\n    const actualButtons = useMemo(() => {\n        const rv = buttons?.filter(Boolean) || [];\n        return rv.map((b) => {\n            if (\"returns\" in b) {\n                return {\n                    ...b,\n                    clickActionCreator: () => modalReturn(b.returns),\n                };\n            }\n            return b;\n        });\n    }, [buttons]);\n\n    const dispatchAndMaybeClose = async (action?: AnvilAction | void, close = true) => {\n        // Do this asynchronously, so any onBlur event handlers have a chance to fire.\n        setTimeout(async () => {\n            if ((await beforeClose?.()) === false) {\n                return; // This close request was intercepted and cancelled.\n            }\n\n            if (action && typeof action === \"function\") {\n                await dispatch(action);\n            }\n            if (close) {\n                dispatch(ensureModalCancelled(modalId, \"CLOSE\"));\n                setHidden(true);\n                dispatch(delayAction(modalRemove(modalId), MODAL_DELAY));\n                prevFocusRef.current?.focus?.();\n            }\n        });\n    };\n\n    // Need to do this asynchronously, otherwise the CSS changes before the element has ever rendered, preventing the animation from firing.\n    useTimeout(() => setHidden(false), 0);\n\n    useImperativeHandle(ref, () => ({\n        returnValue: (value: any) => dispatchAndMaybeClose(modalReturn(value)),\n        cancel: (cancelMethod: string) => dispatchAndMaybeClose(modalCancel(cancelMethod)),\n    }));\n\n    const onModalKeyDown = useEvent(async (e: React.KeyboardEvent<HTMLDivElement>) => {\n        switch (e.key) {\n            case \"Escape\":\n                allowDismiss && dispatchAndMaybeClose(modalCancel(\"BG_CLICK\"));\n                e.stopPropagation();\n                e.preventDefault();\n                break;\n            case \"Enter\":\n                const dButton = actualButtons.find((btn) => btn.defaultButton);\n                const enabled = dButton?.enabled ?? true;\n                if (dButton && enabled) {\n                    dispatchAndMaybeClose(await dButton?.clickActionCreator?.(), dButton?.close);\n                    e.stopPropagation();\n                    e.preventDefault();\n                }\n        }\n        onKeyDown?.(e);\n    });\n\n    const onModalMouseDown: React.MouseEventHandler<HTMLDivElement> = useEvent((e) => {\n        allowDismiss && !hidden && dispatchAndMaybeClose(modalCancel(\"BG_CLICK\"));\n        onMouseDown?.(e);\n    });\n\n    const prevFocusRef = useRef<HTMLElement | null>(null);\n    useInsertionEffect(() => {\n        prevFocusRef.current = document.activeElement as HTMLElement | null;\n    }, []);\n\n    const modalRef = useCallback((node: HTMLDivElement | null) => {\n        autoFocus && node?.focus();\n    }, []);\n\n    const innerRef = useRef<HTMLDivElement>(null);\n    const { registerModalHeight, unregisterModalHeight } = useContext(ModalHeightContext);\n\n    useResizeObserver(\n        innerRef,\n        () => {\n            registerModalHeight(modalId, innerRef.current!.offsetHeight + 160);\n        },\n        () => unregisterModalHeight(modalId)\n    );\n\n    return (\n        <div\n            className={cx(classes.root, hidden && classes.hidden, \"@container px-4\", mobile && mobileStyles.backdrop)}\n            ref={modalRef}\n            onKeyDown={onModalKeyDown}\n            onMouseDown={onModalMouseDown}\n            {...props}\n            tabIndex={-1}>\n            <div className={cx(classes.spacerTop, mobile && mobileStyles.spacer)} />\n            <div\n                ref={innerRef}\n                data-modal-presentation={mobile ? \"mobile\" : undefined}\n                data-modal-hidden={hidden}\n                className={cx(\n                    className,\n                    classes.modal,\n                    { \"w-full @[60rem]:w-240\": size === \"small\" },\n                    { \"w-full @[70rem]:w-280\": size === \"medium\" },\n                    { \"w-full @[100rem]:w-400\": size === \"large\" },\n                    { \"w-full max-w-800 @[125rem]:w-[80vw]\": size === \"huge\" },\n                    { \"w-full max-w-220\": size === \"small\" && isPySpace },\n                    { \"w-full max-w-272\": size === \"medium\" && isPySpace },\n                    // classes[size],\n                    hidden && classes.hidden,\n                    mobile && mobileStyles.dialog\n                )}\n                onMouseDown={stopPropagation}\n                onClick={stopPropagation}>\n                <ErrorSuspenseBoundary fallback={<WrappedSpinner />}>\n                    <div className={cx(classes.modalHeaderBar, mobile && mobileStyles.header)}>\n                        {icon && (\n                            <div className={classes.modalIcon}>\n                                <FontAwesomeIcon icon={icon} />\n                            </div>\n                        )}\n                        <div className={cx(classes.modalHeader)}>{title}</div>\n                        {allowDismiss && (\n                            <LinkInternal\n                                className={cx(classes.modalCloseButton)}\n                                onClick={() => dispatchAndMaybeClose(modalCancel(\"CLOSE_BUTTON\"))}>\n                                <FontAwesomeIcon icon={(closeIcon ?? isPySpace) ? faTimesBold : faTimes} />\n                            </LinkInternal>\n                        )}\n                    </div>\n                    <div className={cx(\"whitespace-pre-line\", mobile && mobileStyles.body)}>{children}</div>\n                </ErrorSuspenseBoundary>\n                {actualButtons.length > 0 && <hr />}\n                <div className={cx(classes.modalFooter, mobile && mobileStyles.footer)}>\n                    {leftButtons}\n                    <div style={{ flexGrow: 1 }} />\n                    <Buttons buttons={actualButtons} dispatchAndMaybeClose={dispatchAndMaybeClose} />\n                </div>\n            </div>\n\n            <div className={cx(classes.spacerBottom, mobile && mobileStyles.spacer)} />\n        </div>\n    );\n};\n\nexport default Modal;\n","import React, { useCallback, useState } from \"react\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { ModalComponent } from \".\";\nimport { ContentTextInput } from \"../reusable/SharedComponents\";\nimport Modal from \"./Modal\";\nimport useStyles from \"./modalstyles\";\n\ninterface PromptSpec {\n    title: React.ReactNode;\n    text?: React.ReactNode;\n    afterInput?: React.ReactNode;\n    initialValue?: string;\n    ok?: string;\n    cancel?: string;\n}\n\nconst Prompt: ModalComponent<PromptSpec, string | null> = ({\n    modalId,\n    spec: { title, text, afterInput, initialValue, ok = \"OK\", cancel = \"Cancel\" },\n}) => {\n    const { classes } = useStyles();\n\n    const [value, setValue] = useState(initialValue || \"\");\n\n    const inputRef = useCallback((node: HTMLInputElement | null) => {\n        node?.focus();\n        node?.select();\n    }, []);\n\n    return (\n        <Modal\n            autoFocus={false}\n            modalId={modalId}\n            allowDismiss={true}\n            title={title}\n            buttons={[\n                { text: ok, clickActionCreator: () => modalReturn(value), defaultButton: true },\n                { text: cancel, clickActionCreator: () => modalReturn(null) },\n            ]}>\n            {text}\n            <br />\n            <ContentTextInput\n                ref={inputRef}\n                className={classes.fullWidth}\n                value={value}\n                onChange={(e) => setValue(e.target.value)}\n                disableEsc={true}\n            />\n            {afterInput}\n        </Modal>\n    );\n};\n\nexport default Prompt;\n","import React, { useCallback, useMemo, useReducer, useRef } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faClose } from \"@fortawesome/pro-regular-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { capitalize, sortBy } from \"lodash-es\";\nimport { openConversation } from \"@/controllers/agents\";\nimport { getAppExtraFiles, getTableMappings } from \"@/controllers/app\";\nimport { getCodeNames } from \"@/controllers/app/code\";\nimport { getExtraFileEntry } from \"@/controllers/app/extra-files\";\nimport { getZenMode } from \"@/controllers/ide\";\nimport { modal } from \"@/controllers/modals\";\nimport { getScheduledTasks } from \"@/controllers/scheduledtasks\";\nimport { getTestingEnabled } from \"@/controllers/services\";\nimport { getRecentlyOpened, getTabStack, removeRecentlyOpened, tabMatchesNavTarget } from \"@/controllers/tabs\";\nimport type {\n    AppDependenciesNavTarget,\n    BackgroundTasksNavTarget,\n    DBTableNavTarget,\n    ExtraFileNavTarget,\n    ImportMapTarget,\n    JavaScriptDependenciesNavTarget,\n    NavTarget,\n    PythonDependenciesNavTarget,\n    ScheduledTasksNavTarget,\n    ServiceNavTarget,\n    SessionsNavTarget,\n    SettingsNavTarget,\n    ThemeNavTarget,\n} from \"@/router/navTypes\";\nimport { dependencyTargetFromLegacyNavTarget } from \"@/router/navTypes\";\nimport { navigate } from \"@/router/navigation\";\nimport { useRemToPixels } from \"@/theme/ThemeProvider\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { type AnvilDispatch, type ExtraFiles, State, type StructureItem, type Tab } from \"@/types\";\nimport { blockEvent, checkMeta, getServiceType, preventDefault } from \"@/util\";\nimport { useUpdateEffect, useUpdateLayoutEffect } from \"@/util/hooks\";\nimport useEffectEvent from \"@/util/useEffectEvent\";\nimport useEvent from \"@/util/useEventCallback\";\nimport type { ModalComponent } from \".\";\nimport { Button } from \"../reusable/Button\";\nimport { TextBox } from \"../reusable/Forms\";\nimport { getExtraFileIcon, getIconFromFile, icons, serviceIcons, useFileIconClassGetter } from \"../reusable/IconHooks\";\nimport Link from \"../reusable/Link\";\nimport { Text } from \"../reusable/Text\";\nimport Modal, { ModalRef } from \"./Modal\";\n\ntype TabWithTitle = Tab & { title: string };\ntype SIWithId = StructureItem & { id: string | number };\ntype CommonNavTargetsWithTitle = (\n    | DBTableNavTarget\n    | ExtraFileNavTarget\n    | SessionsNavTarget\n    | BackgroundTasksNavTarget\n    | AppDependenciesNavTarget\n    | PythonDependenciesNavTarget\n    | JavaScriptDependenciesNavTarget\n    | ServiceNavTarget\n    | ScheduledTasksNavTarget\n    | SettingsNavTarget\n    | ThemeNavTarget\n    | ImportMapTarget\n) & { title: string };\ntype SwitcherItem = TabWithTitle | SIWithId | CommonNavTargetsWithTitle;\n\nconst COMMON_TARGET_TYPES = [\n    \"EXTRA_FILE\",\n    \"DB_TABLE\",\n    \"SESSIONS\",\n    \"SERVICE\",\n    \"SCHEDULED_TASKS\",\n    \"BACKGROUND_TASKS\",\n    \"APP_DEPENDENCIES\",\n    \"PYTHON_DEPENDENCIES\",\n    \"JAVASCRIPT_DEPENDENCIES\",\n    \"IMPORT_MAP\",\n    \"SETTINGS\",\n    \"THEME\",\n];\n\nconst hasNavTarget = (t: any): t is Tab => \"navTarget\" in t;\nconst isValidTab = (t: Tab): t is TabWithTitle => !!t.title;\nconst isValidSI = (s: StructureItem): s is SIWithId => !!s.id && s.type !== \"folder\" && !s.name.endsWith(\".gitkeep\");\nconst isCommonNavTarget = (s: any): s is CommonNavTargetsWithTitle => COMMON_TARGET_TYPES.includes(s.type);\nconst isFileIconItem = (item: SwitcherItem): item is SIWithId => !hasNavTarget(item) && !isCommonNavTarget(item);\n\nconst getItemTitle = (item: SwitcherItem) => {\n    if (hasNavTarget(item)) {\n        if (item.navTarget.type === \"EXTRA_FILE\") return item.navTarget.filePath;\n        return item.title;\n    }\n    if (isCommonNavTarget(item)) return item.title;\n    return item.fullName;\n};\n\nconst FIXED_TARGETS: CommonNavTargetsWithTitle[] = [\n    { title: \"Settings\", type: \"SETTINGS\", section: \"ROOT\" },\n    { title: \"App Sessions\", type: \"SESSIONS\" },\n    { title: \"Background Tasks\", type: \"BACKGROUND_TASKS\" },\n    { title: \"App Dependencies\", type: \"APP_DEPENDENCIES\" },\n    { title: \"Python Dependencies\", type: \"PYTHON_DEPENDENCIES\" },\n    { title: \"JavaScript Dependencies\", type: \"JAVASCRIPT_DEPENDENCIES\" },\n    // { title: \"Import Map\", type: \"IMPORT_MAP\" },\n    { title: \"Roles\", type: \"THEME\", section: \"ROLES\" },\n    { title: \"Colour Scheme\", type: \"THEME\", section: \"COLOUR_SCHEME\" },\n];\n\nconst SCHEDULED_TASK_TARGET = { title: \"Scheduled Tasks\", type: \"SCHEDULED_TASKS\" } as const;\n\nconst useIconStyles = makeStyles()((theme) => ({\n    formIcon: {\n        background: theme.secondaryNav.icon1.background.toString(),\n        color: theme.secondaryNav.icon1.color.toString(),\n    },\n    otherClientIcon: {\n        background: theme.secondaryNav.icon3.background.toString(),\n        color: theme.secondaryNav.icon3.color.toString(),\n    },\n    serverIcon: {\n        background: theme.secondaryNav.icon2.background.toString(),\n        color: theme.secondaryNav.icon2.color.toString(),\n    },\n    assetIcon: {\n        background: theme.secondaryNav.icon1.background.toString(),\n        color: theme.secondaryNav.icon1.color.toString(),\n    },\n    testingIcon: {\n        background: theme.secondaryNav.icon4.background.toString(),\n        color: theme.secondaryNav.icon4.color.toString(),\n    },\n    extraFileIcon: {\n        background: theme.palette.fg3.alpha(0.2).toString(),\n        color: theme.palette.fg3.toString(),\n    },\n    agentIcon: {\n        background: \"#A844FF\",\n        color: theme.secondaryNav.icon1.color.alpha(0.6).toString(),\n    },\n}));\n\nexport const useOpenQuickSwitcherInZenModeIfNoTabs = () => {\n    const tabStack = useSelector(getTabStack);\n    const dispatch = useDispatch<AnvilDispatch>();\n    const zenMode = useSelector(getZenMode);\n    useUpdateEffect(() => {\n        if (!tabStack.length && zenMode) {\n            dispatch(modal(\"quickSwitcher\", {}));\n        }\n    }, [tabStack]);\n};\n\ninterface ItemProps extends React.HTMLAttributes<HTMLDivElement> {\n    item: SwitcherItem;\n    selected?: boolean;\n    onConfirm: (index: number) => void;\n    index: number;\n    onRemoveRecent: (tab: Tab) => void;\n}\n\nconst Item = ({ style, item, selected, index, onConfirm, onRemoveRecent }: ItemProps) => {\n    const { classes } = useIconStyles();\n    const navTarget = useMemo(() => getNavTarget(item), [item]);\n\n    const onClick = useEvent((e: React.MouseEvent) => {\n        if (checkMeta(e) || e.shiftKey) {\n            onConfirm(-1);\n        } else {\n            onConfirm(index);\n        }\n    });\n    const isTab = hasNavTarget(item);\n    const isConversation = navTarget.type === \"CONVERSATION\";\n    const getFileIconClass = useFileIconClassGetter(classes);\n    const { icon, iconClass } = useMemo(() => {\n        if (navTarget.type === \"PYTHON_SOURCE\") {\n            return { icon: icons.PYTHON_SOURCE, iconClass: classes.extraFileIcon };\n        }\n        if (navTarget.type === \"EXTRA_FILE\") {\n            const extraFileIcon = getExtraFileIcon(navTarget.filePath);\n            return { icon: extraFileIcon.icon, iconClass: classes[extraFileIcon.iconClass] };\n        }\n        if (isFileIconItem(item)) {\n            return {\n                icon: getIconFromFile(item.type, item),\n                iconClass: getFileIconClass(item.type) ?? classes.otherClientIcon,\n            };\n        }\n        const tabIcon = hasNavTarget(item) ? item.icon : undefined;\n        const tabIconClass =\n            hasNavTarget(item) && typeof item.itemType === \"string\"\n                ? getFileIconClass(item.itemType as StructureItem[\"type\"])\n                : null;\n        const icon = navTarget.type === \"SERVICE\" ? serviceIcons[navTarget.service] : tabIcon;\n        return {\n            icon: icon || icons[navTarget.type],\n            iconClass: isConversation ? classes.agentIcon : (tabIconClass ?? classes.otherClientIcon),\n        };\n    }, [item, navTarget, classes, getFileIconClass, isConversation]);\n    const onRemoveClick = useEvent(() => {\n        isTab && onRemoveRecent(item);\n    });\n    const display = getItemTitle(item);\n\n    return (\n        <Link\n            className=\"absolute inset-0 w-full no-underline!\"\n            style={style}\n            to={isConversation ? null : navTarget}\n            onClick={onClick}>\n            <div\n                className={cx(\"flex h-full items-center gap-4 px-4 hover:bg-grey-0 dark:hover:bg-grey-2\", {\n                    \"bg-light-bg4! dark:bg-dark-bg4!\": selected,\n                })}>\n                <div\n                    className={cx(\n                        \"flex h-7 w-7 shrink-0 items-center justify-center rounded-full p-3 text-base\",\n                        iconClass\n                    )}>\n                    <FontAwesomeIcon fixedWidth icon={icon} />\n                </div>\n                <span\n                    title={display}\n                    className=\"min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap text-light-bg6 dark:text-dark-fg1\">\n                    {display}\n                </span>\n                {isTab && (\n                    <div className=\"ml-auto flex h-full shrink-0 items-center gap-4\">\n                        <Text level={3} className={\"whitespace-nowrap\"}>\n                            recently opened\n                        </Text>\n                        <Button onMouseDown={preventDefault} onClick={onRemoveClick} tiny variant=\"hidden\">\n                            <FontAwesomeIcon fixedWidth icon={faClose} />\n                        </Button>\n                    </div>\n                )}\n            </div>\n        </Link>\n    );\n};\n\ninterface SwitcherState {\n    searchTerm?: string;\n    selectedIndex: number;\n    filteredItems: SwitcherItem[];\n    recentlyOpenedEndsAt: number;\n}\n\nconst SEARCH = \"search\";\nconst NEXT = \"next\";\nconst PREV = \"prev\";\nconst RERENDER = \"rerender\";\n\ntype SwitcherAction = { type: typeof SEARCH; payload: string } | { type: typeof NEXT | typeof PREV | typeof RERENDER };\n\nconst useItemState = () => {\n    const testingEnabled = useSelector(getTestingEnabled);\n\n    const codeNames = useSelector(getCodeNames);\n    const extraFiles = useSelector(getAppExtraFiles);\n    const tableMappings = useSelector(getTableMappings);\n\n    const currentServices = useSelector((state: State) => state.app?.config?.services);\n    const scheduledTasks = useSelector(getScheduledTasks);\n\n    const CommonNavTargets = useMemo(() => {\n        const navTargets: CommonNavTargetsWithTitle[] = [...FIXED_TARGETS];\n\n        if (scheduledTasks) {\n            navTargets.push(SCHEDULED_TASK_TARGET);\n        }\n\n        currentServices?.forEach((s) => {\n            const service = getServiceType(s.source as any);\n            if (service) {\n                if (service !== \"TESTS\") navTargets.push({ title: capitalize(service), type: \"SERVICE\", service });\n            }\n        });\n\n        tableMappings?.forEach((m) => {\n            const tables = sortBy(m?.tables ?? [], [\"name\"]);\n            navTargets.push(\n                ...tables.map((t) => {\n                    let title = t.name ?? \"Database\";\n                    if ((tableMappings?.length ?? 0) > 1) {\n                        title = `${m?.name}: ${title}`;\n                    }\n                    return {\n                        type: \"DB_TABLE\",\n                        tableId: t.id,\n                        tableMappingId: m.table_mapping_id,\n                        title,\n                    } as const;\n                })\n            );\n        });\n\n        // The switcher needs paths only; opening the chosen file handles its content.\n        const addExtraFiles = (files: ExtraFiles, prefix = \"\") => {\n            for (const [name, content] of Object.entries(files)) {\n                if (name === \".gitkeep\") continue;\n                const filePath = `${prefix}${name}`;\n\n                if (!testingEnabled && (filePath === \"tests\" || filePath.startsWith(\"tests/\"))) continue;\n\n                if (typeof content === \"string\") {\n                    navTargets.push({ type: \"EXTRA_FILE\", filePath, title: filePath });\n                } else {\n                    addExtraFiles(content, `${filePath}/`);\n                }\n            }\n        };\n        addExtraFiles(extraFiles);\n        return navTargets;\n    }, [scheduledTasks, currentServices, tableMappings, extraFiles, testingEnabled]);\n\n    const recent = useSelector(getRecentlyOpened);\n    const numTabs = useSelector(getTabStack).length;\n    const validRecent = useMemo(\n        () =>\n            recent\n                .toReversed()\n                .filter(isValidTab)\n                .filter((tab) => {\n                    if (tab.navTarget.type === \"CODE\") {\n                        return tab.title in codeNames;\n                    }\n                    if (tab.navTarget.type === \"EXTRA_FILE\") {\n                        if (!testingEnabled && tab.navTarget.filePath.startsWith(\"tests/\")) {\n                            return false;\n                        }\n\n                        return typeof getExtraFileEntry(extraFiles, tab.navTarget.filePath) === \"string\";\n                    }\n                    // The fixed targets replace stale dependency entries.\n                    return !dependencyTargetFromLegacyNavTarget(tab.navTarget);\n                }),\n        [recent, codeNames, testingEnabled, extraFiles]\n    );\n    const validCodeItems = useMemo(() => Object.values(codeNames).filter(isValidSI), [codeNames]);\n\n    const items = useMemo(() => {\n        const rv: SwitcherItem[] = [...validRecent];\n        for (const si of validCodeItems) {\n            if (!validRecent.find((r) => r.title === si.fullName)) {\n                rv.push(si);\n            }\n        }\n        for (const navTarget of CommonNavTargets) {\n            if (!validRecent.find((r) => tabMatchesNavTarget(r, navTarget))) {\n                rv.push(navTarget);\n            }\n        }\n        return rv;\n    }, [validCodeItems, validRecent, CommonNavTargets]);\n\n    const reducer = (state: SwitcherState, action: SwitcherAction): SwitcherState => {\n        let { filteredItems, selectedIndex, searchTerm, recentlyOpenedEndsAt: recentlyOpenEndsAt } = state;\n        let numFiltered = filteredItems.length;\n\n        const applyFilter = () => {\n            recentlyOpenEndsAt = validRecent.length;\n            if (searchTerm) {\n                filteredItems = items.filter((item) => getItemTitle(item).toLowerCase().includes(searchTerm!));\n                recentlyOpenEndsAt = filteredItems.findIndex((item) => !validRecent.includes(item as any));\n            } else {\n                filteredItems = items;\n            }\n            numFiltered = filteredItems.length;\n        };\n\n        switch (action.type) {\n            case \"next\":\n                selectedIndex = (selectedIndex + 1) % filteredItems.length;\n                break;\n            case \"prev\":\n                selectedIndex = (selectedIndex + numFiltered - 1) % numFiltered;\n                break;\n            case \"search\":\n                searchTerm = action.payload.toLowerCase();\n                applyFilter();\n                selectedIndex = 0;\n                break;\n            case \"rerender\":\n                applyFilter();\n                selectedIndex = Math.max(0, Math.min(selectedIndex, numFiltered - 1));\n                break;\n        }\n        return { filteredItems, selectedIndex, searchTerm, recentlyOpenedEndsAt: recentlyOpenEndsAt };\n    };\n\n    return useReducer(reducer, {\n        selectedIndex: numTabs && items.length > 1 ? 1 : 0,\n        filteredItems: items,\n        recentlyOpenedEndsAt: validRecent.length,\n    });\n};\n\nconst RecentFilesDivider = ({ y }: { y: number }) => {\n    return (\n        <div key={\"file-divider\"} className=\"pointer-events-none -z-1\" style={{ transform: `translateY(${y}px)` }}>\n            <div className=\"relative w-full\">\n                <div className=\"absolute inset-0 flex w-full translate-y-1/2 items-center\">\n                    <div className=\"grow border-t border-sectionborder dark:border-dark-sectionborder\"></div>\n                    <span className=\"mx-2 px-2 text-base text-grey-1\">Remaining Files, Data Tables and Services</span>\n                    <div className=\"grow border-t border-sectionborder dark:border-dark-sectionborder\"></div>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nconst getNavTarget = (item: SwitcherItem) => {\n    let navTarget: NavTarget;\n    if (hasNavTarget(item)) {\n        navTarget = item.navTarget;\n        if (navTarget.temp) {\n            navTarget = { ...navTarget, temp: undefined };\n        }\n    } else if (isCommonNavTarget(item)) {\n        ({ ...navTarget } = item);\n    } else {\n        navTarget = { type: \"CODE\", codePath: item.codePath };\n    }\n    return navTarget;\n};\n\nconst QuickSwitcher: ModalComponent = ({ modalId }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const modalRef = useRef<ModalRef>(null);\n    const [{ filteredItems, selectedIndex, recentlyOpenedEndsAt: recentlyOpenEndsAt }, updateState] = useItemState();\n\n    const inputRefCallback = useCallback((node: HTMLInputElement) => {\n        node?.focus();\n    }, []);\n\n    const onConfirm = useEvent((index?: number) => {\n        const selectedItem = filteredItems[index ?? selectedIndex];\n        modalRef.current?.returnValue(null);\n        if (selectedItem) {\n            const navTarget = getNavTarget(selectedItem);\n            if (navTarget.type === \"CONVERSATION\") {\n                setTimeout(() => dispatch(openConversation(navTarget.conversationPid)));\n            } else {\n                setTimeout(() => dispatch(navigate(navTarget)));\n            }\n        }\n    });\n\n    const onRemoveRecent = (tab: Tab) => {\n        dispatch(removeRecentlyOpened(tab));\n        updateState({ type: RERENDER });\n    };\n\n    const onKeyDown: React.KeyboardEventHandler = useEvent((e) => {\n        switch (e.code) {\n            case \"ArrowUp\":\n                blockEvent(e);\n                updateState({ type: PREV });\n                break;\n            case \"ArrowDown\":\n                blockEvent(e);\n                updateState({ type: NEXT });\n                break;\n            case \"Enter\":\n                blockEvent(e);\n                onConfirm();\n                break;\n            case \"KeyP\":\n                if (checkMeta(e)) {\n                    blockEvent(e);\n                    if (e.shiftKey) {\n                        updateState({ type: PREV });\n                    } else {\n                        updateState({ type: NEXT });\n                    }\n                }\n                break;\n        }\n    });\n\n    // note - we're using an uncontrolled input here\n    const timeoutRef = useRef<number | undefined>(undefined);\n    const onChange: React.ChangeEventHandler<HTMLInputElement> = useEvent((e) => {\n        const searchTerm = e.target.value;\n        clearTimeout(timeoutRef.current);\n        timeoutRef.current = setTimeout(() => {\n            updateState({ type: SEARCH, payload: searchTerm });\n        }, 50);\n    });\n\n    const size = useRemToPixels(4);\n    const containerRef = useRef<HTMLDivElement>(null);\n\n    const rowVirtualizer = useVirtualizer({\n        count: filteredItems.length,\n        overscan: 10,\n        getScrollElement: () => containerRef.current,\n        estimateSize: () => size,\n        // getItemKey: (i) => filteredItems[i].id,\n    });\n\n    const scrollToIndex = useEffectEvent(() => {\n        if (!filteredItems.length) return;\n        rowVirtualizer.scrollToIndex(selectedIndex);\n    });\n\n    useUpdateLayoutEffect(() => {\n        scrollToIndex();\n    }, [rowVirtualizer, selectedIndex]);\n\n    const virtualItems = rowVirtualizer.getVirtualItems();\n    const dividerItem = !!recentlyOpenEndsAt && virtualItems.find(({ index }) => index === recentlyOpenEndsAt);\n\n    return (\n        <Modal autoFocus={false} ref={modalRef} modalId={modalId} title=\"Jump To\">\n            <div className=\"flex h-[30vh] flex-col\" onKeyDown={onKeyDown}>\n                <TextBox type=\"search\" ref={inputRefCallback} onChange={onChange} />\n                <div ref={containerRef} className=\"h-full overflow-x-hidden overflow-y-auto\">\n                    <div className=\"relative w-full\" style={{ height: `${rowVirtualizer.getTotalSize()}px` }}>\n                        {virtualItems.map(({ size, start, key, index }) => (\n                            <Item\n                                style={{ height: `${size}px`, transform: `translateY(${start}px)` }}\n                                key={key}\n                                index={index}\n                                item={filteredItems[index]}\n                                selected={index === selectedIndex}\n                                onConfirm={onConfirm}\n                                onRemoveRecent={onRemoveRecent}\n                            />\n                        ))}\n                        {dividerItem && <RecentFilesDivider y={dividerItem.start - 0.5} />}\n                    </div>\n                </div>\n            </div>\n        </Modal>\n    );\n};\n\nexport default QuickSwitcher;\n","import React, { useMemo } from \"react\";\nimport { ModalComponent } from \".\";\nimport Modal, { ModalButtonProps } from \"./Modal\";\n\ninterface SimpleModalSpec {\n    title: React.ReactNode;\n    text: React.ReactNode;\n    buttons: ModalButtonProps[];\n}\n\nconst SimpleModal: ModalComponent<SimpleModalSpec, any> = ({ modalId, spec: { title, text, buttons } }) => {\n    const modalButtons = useMemo(() => {\n        const hasDefaultButton = buttons.some((btnProps) => btnProps.defaultButton);\n        if (hasDefaultButton) {\n            return buttons;\n        }\n        const rv = [...buttons];\n        rv[0] = { ...rv[0], defaultButton: true };\n        return rv;\n    }, [buttons]);\n\n    return (\n        <Modal modalId={modalId} allowDismiss={false} title={title} buttons={modalButtons}>\n            {text}\n        </Modal>\n    );\n};\n\nexport default SimpleModal;\n","import React, { useMemo } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faTrashAlt } from \"@fortawesome/pro-regular-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { format, parseISO } from \"date-fns\";\nimport * as api from \"@/api\";\nimport { useScrollToHash } from \"@/components/modals/account/Authentication\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { alert, confirm } from \"@/controllers/modals\";\nimport { AnvilDispatch } from \"@/types\";\n\ninterface OAuthToken {\n    device_label: string;\n    family_id: string;\n    client_id: string;\n    client_name: string;\n    created_at: string;\n}\n\n// TODO: Use idx to alternate row background colours. Needs subgrid.\nexport const OAuthTokenRow = ({ idx, token }: { idx: number; token: OAuthToken }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const queryClient = useQueryClient();\n\n    const [tooltip, anchorRef] = useTooltip(`Revoke token for ${token?.client_name || token?.client_id}.`, \"left\");\n\n    const revokeTokenMutation = useMutation({\n        mutationFn: async (token: OAuthToken) => {\n            return api.revokeOAuthToken(token.family_id);\n        },\n\n        onMutate: async (token: OAuthToken) => {\n            await queryClient.cancelQueries({ queryKey: [\"oauth-tokens\"] });\n\n            const previousTokens = queryClient.getQueryData<Array<{ id: string }>>([\"oauth-tokens\"]);\n\n            // Optimistically update UI\n            queryClient.setQueryData([\"oauth-tokens\"], (old: any[]) =>\n                old.filter((t) => t.family_id !== token.family_id)\n            );\n\n            return { previousTokens, token };\n        },\n\n        onError: (_err, _id, context) => {\n            // Rollback if delete failed\n            if (context?.previousTokens) {\n                queryClient.setQueryData([\"oauth-tokens\"], context.previousTokens);\n            }\n            dispatch(\n                alert(\n                    \"OAuth Token Revokation Failed\",\n                    `Could not revoke token for ${context?.token.client_name}. \n                    Please contact support@anvil.works for assistance.`\n                )\n            );\n        },\n\n        onSettled: () => {\n            // Refetch to ensure server state is correct\n            queryClient.invalidateQueries({ queryKey: [\"oauth-tokens\"] });\n        },\n    });\n\n    const revokeDeviceToken = async () => {\n        {\n            const revoke = await dispatch(\n                confirm(\n                    `Revoke token for ${token.client_name || token.client_id}?`,\n                    `You are about to revoke the OAuth token for ${token.client_name || token.client_id}`,\n                    \"Revoke\",\n                    \"Cancel\"\n                )\n            );\n            if (revoke) {\n                revokeTokenMutation.mutate(token);\n            }\n        }\n    };\n\n    const createdAt = useMemo(() => {\n        return format(parseISO(token.created_at), `dd MMM yyyy, HH:mm:ss`) + \" UTC\"; // TODO: Local timezone!\n    }, [token.created_at]);\n\n    return (\n        <>\n            <div className={\"truncate\"}>{token?.client_name}</div>\n            <div className={\"truncate\"}>{createdAt}</div>\n\n            <Button ref={anchorRef} size={\"small\"} onClick={revokeDeviceToken}>\n                <FontAwesomeIcon icon={faTrashAlt} />\n                {tooltip}\n            </Button>\n        </>\n    );\n};\n\nexport const OAuthTokens = ({ scrollIntoView }: { scrollIntoView: boolean }) => {\n    const { isLoading, error, data } = useQuery({\n        queryKey: [\"oauth-tokens\"],\n        queryFn: () => {\n            return api.getOAuthTokens();\n        },\n    });\n\n    const { ref } = useScrollToHash(scrollIntoView);\n\n    // TODO: Uncomment HelpLink below when anvil-cli is released\n    return (\n        <div className={\"flex flex-col dark:text-grey-0\"} ref={ref}>\n            <h3 className={\"mt-10 mb-5 text-4xl font-medium\"}>\n                OAuth Tokens {/*<HelpLink*/}\n                {/*    inline*/}\n                {/*    iconRight*/}\n                {/*    url={\"/docs/version-control/local-development/installation#authentication\"}*/}\n                {/*/>*/}\n            </h3>\n            <div className={\"px-10\"}>\n                {isLoading ? (\n                    <div className=\"relative min-h-[12rem]\">\n                        <LoadingSpinner />\n                    </div>\n                ) : !data || data.length === 0 ? (\n                    <Text level={2}>No OAuth Tokens issued</Text>\n                ) : (\n                    <div className=\"grid grid-cols-[1fr_1fr_40px] gap-y-2\">\n                        <div className=\"border-b border-b-sectionborder font-semibold\">Client</div>\n                        <div className=\"border-b border-b-sectionborder font-semibold\">Created</div>\n                        <div className=\"border-b border-b-sectionborder font-semibold\"></div>\n                        {data.map((token: OAuthToken, idx: number) => (\n                            <OAuthTokenRow key={token.family_id} idx={idx} token={token} />\n                        ))}\n                    </div>\n                )}\n            </div>\n        </div>\n    );\n};\n\nexport default OAuthTokens;\n","import React, { useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { useScrollToHash } from \"@/components/modals/account/Authentication.tsx\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport { useSaveIndicator } from \"@/components/reusable/SaveIndicator\";\nimport { ContentTextAreaInput } from \"@/components/reusable/SharedComponents\";\nimport { markUnsaved } from \"@/controllers/app\";\nimport { getSshKeys, updateSshKeys } from \"@/controllers/user\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useStateWithReset } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\n\nconst SSHKeys = ({ scrollIntoView }: { scrollIntoView: boolean }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const keys = useSelector(getSshKeys);\n\n    const [sshKeys, setSshKeys] = useStateWithReset(keys);\n    const [saveTimeout, setSaveTimeout] = useState<number | undefined>(undefined);\n    const [saveIndicator, setSaved] = useSaveIndicator();\n\n    const onChange: React.ChangeEventHandler<HTMLTextAreaElement> = useEvent(async (e) => {\n        const keys = e.target.value;\n        setSshKeys(keys);\n        dispatch(markUnsaved(\"ssh-keys\"));\n        setSaved(false);\n        setSaveTimeout((h) => {\n            clearTimeout(h);\n            return setTimeout(async () => {\n                await dispatch(updateSshKeys(keys));\n                setSaved(true);\n            }, 500);\n        });\n    });\n\n    const { ref } = useScrollToHash(scrollIntoView);\n\n    return (\n        <div className={\"flex flex-col dark:text-grey-0\"} ref={ref}>\n            <h3 className={\"mt-10 mb-5 text-4xl font-medium\"}>\n                SSH Keys <HelpLink inline iconRight url={\"/docs/how-to/app-server/linux-ssh-key-setup\"} />\n            </h3>\n            <div className={\"px-10\"}>\n                <p>\n                    Use your Anvil account email and password to authenticate to git, or paste your SSH public key into\n                    this box:\n                </p>\n                <ContentTextAreaInput\n                    style={{ height: \"150px\" }}\n                    className={\"my-2 h-full max-w-full\"}\n                    value={sshKeys || \"\"}\n                    onChange={onChange}\n                    disableEsc={true}\n                />\n                <div className={\"text-base\"}>\n                    <b>Enter one SSH public key per line.</b>\n                </div>\n                {saveIndicator}\n            </div>\n        </div>\n    );\n};\n\nexport default SSHKeys;\n","import React, { PropsWithChildren, useCallback, useMemo } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { format, parseISO } from \"date-fns\";\nimport * as api from \"@/api\";\nimport { useScrollToHash } from \"@/components/modals/account/Authentication\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { alert, confirm, modal } from \"@/controllers/modals\";\nimport { AnvilDispatch } from \"@/types\";\nimport { cx } from \"@/theme/styles\";\nimport { faChevronRight, faLinkSlash, faSignOut } from \"@fortawesome/pro-solid-svg-icons\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { doDisconnectAgent, refreshAgentAuth, useAgentAuth } from \"@/agent/hooks\";\nimport { AgentAuthMap, AgentTypeId } from \"@/agent/types\";\nimport { getEnabledAgentTypes } from \"@/controllers/user-agent-types\";\n\n\nconst ConnectionRow = ({ children }: PropsWithChildren) => {\n    return <div className={cx(\"items-center grid grid-cols-[1fr_auto] gap-4 py-4 px-6 rounded border w-full\", \"border-sectionborder\", \"dark:border-dark-sectionborder\")}>\n        {children}\n    </div>;\n};\n\nexport const AIConnections = ({ scrollIntoView = false }: { scrollIntoView?: boolean }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const queryClient = useQueryClient();\n    const { ref } = useScrollToHash(scrollIntoView);\n    const { isLoading, data: agentAuth } = useAgentAuth();\n    const enabledAgentTypes = useSelector(getEnabledAgentTypes);\n    const disconnectAgent = useEvent(async (agentType: AgentTypeId) => {\n        const agentName = agentType[0].toUpperCase() + agentType.slice(1);\n        if (\n            await dispatch(\n                confirm(\n                    \"Disconnect Agent\",\n                    `You are about to disconnect the connection to ${agentName}. Any active conversations currently using this agent will be interrupted. Are you sure you'd like to continue?`\n                )\n            )\n        ) {\n            disconnectAgentMutation.mutate(agentType);\n        }\n    });\n    const disconnectAgentMutation = useMutation({\n        mutationFn: async (agentType: AgentTypeId) => {\n            await doDisconnectAgent(agentType);\n        },\n        onSettled: () => refreshAgentAuth(queryClient),\n    });\n\n    const disconnectButton = useCallback((agentType: AgentTypeId) => {\n        return <Button className={\"min-w-84\"} icon={faSignOut} onClick={() => disconnectAgent(agentType)}>Remove connection</Button>;\n    }, [disconnectAgent]);\n\n\n    return (\n        !isLoading ? <div ref={ref} className={\"flex w-full flex-col dark:text-grey-0\"} >\n            <h3 className={\"mt-10 mb-5 text-4xl font-medium\"}>\n                AI Connections <HelpLink inline iconRight url={\"/docs/ai/connecting-your-account\"} />\n            </h3>\n            <div className={\"px-10 flex flex-col gap-4\"}>\n                <>\n                    {enabledAgentTypes.includes(\"codex-anvil\") && (\n                        <ConnectionRow>\n                            <div>Codex (included)</div>\n                            {/* Anvil-managed: no credential to connect or remove. */}\n                            <div className=\"text-center\">Included with your Anvil account</div>\n                        </ConnectionRow>\n                    )}\n\n                    {enabledAgentTypes.includes(\"codex\") && (\n                        <ConnectionRow >\n                            <div>OpenAI</div>\n                            {agentAuth?.[\"codex\"]?.overridden ? <>\n                                <div className=\"text-center\">Managed by your organization</div>\n                            </> : agentAuth?.[\"codex\"] ? <>\n                                {/* todo: agentAuth['codex'] has which type it is. Make use the correct wording. */}\n                                {disconnectButton('codex')}\n                            </> : <>\n                                <div className=\"text-center\">To connect, start a chat and choose Codex/ChatGPT</div>\n                                {/* <Button variant={\"primary\"}>Log in with ChatGPT <FontAwesomeIcon className=\"ml-4\" icon={faChevronRight} /></Button>\n                                <Button variant={\"primary\"}>Connect with API key<FontAwesomeIcon className=\"ml-4\" icon={faChevronRight} /></Button> */}\n                            </>}\n                        </ConnectionRow>\n                    )}\n\n                    {enabledAgentTypes.includes(\"claude\") && (\n                        <ConnectionRow >\n                            <div>Claude</div>\n                            {agentAuth?.[\"claude\"]?.overridden ? <>\n                                <div className=\"text-center\">Managed by your organization</div>\n                            </> : agentAuth?.[\"claude\"] ? <>\n                                {/* todo: agentAuth['claude'] has which type it is. Make use the correct wording. */}\n                                {disconnectButton('claude')}\n                            </> : <>\n                                <div className=\"text-center\">To connect, start a chat and choose Claude</div>\n                                {/* <Button variant={\"primary\"}>Connect with Claude Code key<FontAwesomeIcon className=\"ml-4\" icon={faChevronRight} /></Button>\n                                <Button variant={\"primary\"}>Connect with Anthropic key<FontAwesomeIcon className=\"ml-4\" icon={faChevronRight} /></Button> */}\n                            </>}\n\n                        </ConnectionRow>\n                    )}\n\n                    {enabledAgentTypes.includes(\"zai\") && (\n                        <ConnectionRow>\n                            <div>Z.ai</div>\n                            {agentAuth?.[\"zai\"]?.overridden ? <>\n                                <div className=\"text-center\">Managed by your organization</div>\n                            </> : agentAuth?.[\"zai\"] ? <>\n                                {disconnectButton(\"zai\")}\n                            </> : <>\n                                <div className=\"text-center\">To connect, start a chat and choose Z.ai</div>\n                            </>}\n                        </ConnectionRow>\n                    )}\n\n                    <ConnectionRow >\n                        <div className=\"flex gap-4 items-center\">\n                            <div>Custom Model Provider</div>\n                            <div className=\"px-2 py-1 text-lg font-semibold shrink-0 rounded bg-light-bg5 text-white\">Enterprise Only</div>\n                        </div>\n                        <Button className={\"min-w-84\"} variant={\"primary\"} onClick={() => dispatch(modal(\"agentCustomModelProvider\", {}))}>Contact Sales</Button>\n                    </ConnectionRow>\n                </>\n            </div>\n        </div > : <LoadingSpinner inline />\n    );\n};\n\nexport default AIConnections;\n","import React from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faGithub } from \"@fortawesome/free-brands-svg-icons/faGithub\";\nimport { faLinkSlash } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useScrollToHash } from \"@/components/modals/account/Authentication.tsx\";\nimport { Button } from \"@/components/reusable/Button.tsx\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal.tsx\";\nimport {\n    ensureGithubConnection,\n    getGithubConnection,\n    promptAndMaybeDisconnectGitHubAccount,\n} from \"@/controllers/app/remotes.ts\";\nimport { alert } from \"@/controllers/modals.ts\";\nimport { AuthHash } from \"@/router/navTypes.ts\";\nimport { AnvilDispatch } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback.ts\";\nimport OAuthTokens from \"./OAuthTokens.tsx\";\nimport SSHKeys from \"./SSHKeys\";\nimport AIConnections from \"./AIConnections.tsx\";\n\nexport const KeysAndTokens = ({ hash }: { hash?: AuthHash | null }) => {\n    const conn = useSelector(getGithubConnection);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const onHandleDisconnectClick = useEvent(async () => {\n        // @ts-ignore\n        const { error } = await dispatch(promptAndMaybeDisconnectGitHubAccount());\n        if (error) {\n            dispatch(alert(\"Failed to disconnect GitHub account\", `${error}   \\nPlease contact support@anvil.works`));\n        }\n    });\n\n    const { ref } = useScrollToHash(hash === \"GH\");\n\n    return (\n        <div>\n            <SSHKeys scrollIntoView={hash === \"SSH\"} />\n            <div className=\"flex max-w-250 flex-col\">\n                <OAuthTokens scrollIntoView={hash === \"OAUTH\"} />\n            </div>\n            <div className=\"flex w-full flex-col\">\n                <AIConnections scrollIntoView={hash === \"AI\"} />\n            </div>\n            <div className=\"flex max-w-250 flex-col\" ref={ref}>\n                <h3 className={\"mt-10 mb-5 text-4xl font-medium dark:text-grey-0\"}>Github Connection</h3>\n                <div className={\"px-10\"}>\n                    {conn ? (\n                        <div>\n                            <div>\n                                You are logged in to Github as{\" \"}\n                                <span className={\"font-mono font-semibold\"}>{conn.user.login}</span>\n                                {conn?.user?.name && ` (${conn.user.name})`}.\n                            </div>\n                            <LinkInternal className={\"text-danger\"} onClick={onHandleDisconnectClick}>\n                                <FontAwesomeIcon icon={faLinkSlash} className={\"mr-2\"} />\n                                Disconnect GitHub Account\n                            </LinkInternal>\n                        </div>\n                    ) : (\n                        <div>\n                            <Button\n                                variant={\"secondary\"}\n                                icon={faGithub}\n                                onClick={() => dispatch(ensureGithubConnection())}>\n                                Connect to GitHub\n                            </Button>\n                        </div>\n                    )}\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport default KeysAndTokens;\n","import React, { RefObject, useCallback, useLayoutEffect, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport KeysAndTokens from \"@/components/modals/account/keys_and_tokens/KeysAndTokens\";\nimport { AuthHash } from \"@/router/navTypes\";\nimport { AnvilDispatch } from \"@/types\";\nimport useEffectEvent from \"@/util/useEffectEvent\";\nimport { confirm2fa, confirmPassword, update2fa, updatePassword } from \"../../../api\";\nimport { getUser } from \"../../../controllers/ide\";\nimport { alert, confirm } from \"../../../controllers/modals\";\nimport { getPasswordExpires, updatePasswordExpires, updateUser2faEnabled } from \"../../../controllers/user\";\nimport { InputLabel } from \"../../reusable/Forms\";\nimport { ContentTextInput, ModalButton } from \"../../reusable/SharedComponents\";\nimport { Heading } from \"../../reusable/Text\";\nimport useStyles from \"../modalstyles\";\n\nexport const useScrollToHash = (scrollIntoView: boolean) => {\n    const ref = useRef<HTMLDivElement>(null);\n\n    useLayoutEffect(() => {\n        if (!scrollIntoView) return;\n\n        const timeoutId = setTimeout(() => {\n            ref.current?.scrollIntoView({ behavior: \"smooth\" });\n        }, 150); //150 is the delay time it takes to open the modal\n\n        return () => clearTimeout(timeoutId);\n    }, [scrollIntoView]);\n\n    return { ref };\n};\n\nexport const Authentication = ({ hash }: { hash?: AuthHash | null }) => {\n    const user = useSelector(getUser);\n    const passwordExpires = useSelector(getPasswordExpires);\n\n    return (\n        <div>\n            <div className={\"dark:text-grey-0\"}>\n                {user[\"2fa\"]?.available && (\n                    <>\n                        <h3 className={\"mt-10 mb-5 text-4xl font-medium\"}>Authentication</h3>\n                        <div className={\"px-10\"}>\n                            <div>\n                                <Heading>Change Password</Heading>\n                                <ChangePassword />\n                                <hr />\n                                <Heading>Two-factor authentication</Heading>\n                                {passwordExpires - Date.now() > 0 ? <ConfigureMFA /> : <ConfirmPassword />}\n                            </div>\n                        </div>\n                    </>\n                )}\n            </div>\n            <KeysAndTokens hash={hash} />\n        </div>\n    );\n};\n\nconst ChangePassword = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { classes } = useStyles();\n\n    const [currPassword, setCurrPassword] = useState(\"\");\n    const [newPassword, setNewPassword] = useState(\"\");\n    const [confirmPassword, setConfirmPassword] = useState(\"\");\n    const [errorMsg, setErrorMsg] = useState<string | null>(null);\n\n    const onChangePassword = useCallback(async () => {\n        if (newPassword !== confirmPassword) {\n            setErrorMsg(\"The passwords do not match\");\n            return;\n        }\n        try {\n            const res = await updatePassword(currPassword, newPassword);\n            if (res[\"success\"]) {\n                setCurrPassword(\"\");\n                setNewPassword(\"\");\n                setConfirmPassword(\"\");\n                setErrorMsg(null);\n                await dispatch(alert(\"Success\", \"Your password has been successfully updated\"));\n            } else {\n                setErrorMsg(res.error ?? \"There was a problem updating your password\");\n            }\n        } catch (e) {\n            setErrorMsg(`There was a problem updating your password: ${e}`);\n        }\n    }, [newPassword, confirmPassword, currPassword]);\n\n    return (\n        <>\n            <InputLabel title=\"Current password\" className={classes.marginTop10}>\n                <ContentTextInput\n                    type={\"password\"}\n                    placeholder={\"Current password\"}\n                    value={currPassword}\n                    // onEnter={() => {}}\n                    onChange={(e) => {\n                        setErrorMsg(null);\n                        setCurrPassword(e.target.value);\n                    }}\n                />\n            </InputLabel>\n            <InputLabel title={\"New password\"} className={classes.marginTop10}>\n                <ContentTextInput\n                    type={\"password\"}\n                    placeholder={\"New password\"}\n                    value={newPassword}\n                    // onEnter={() => {}}\n                    onChange={(e) => {\n                        setErrorMsg(null);\n                        setNewPassword(e.target.value);\n                    }}\n                />\n            </InputLabel>\n            <InputLabel title={\"Confirm new password\"} className={classes.marginTop10}>\n                <ContentTextInput\n                    type={\"password\"}\n                    placeholder={\"Confirm new password\"}\n                    value={confirmPassword}\n                    onEnter={onChangePassword}\n                    onChange={(e) => {\n                        setErrorMsg(null);\n                        setConfirmPassword(e.target.value);\n                    }}\n                />\n            </InputLabel>\n            <ModalButton\n                enabled={!!(newPassword && currPassword && confirmPassword)}\n                className={classes.marginTop10}\n                variant=\"primary\"\n                onClick={onChangePassword}>\n                Update password\n            </ModalButton>\n            <p className={classes.errorLabel}>{errorMsg ? errorMsg : \"\\u00A0\"}</p>\n        </>\n    );\n};\n\nconst ConfirmPassword = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { classes } = useStyles();\n    const [passwordError, setPasswordError] = useState<string | null>(null);\n    const [password, setPassword] = useState(\"\");\n\n    const onConfirmPassword = useCallback(async () => {\n        setPassword(\"\");\n        const res = await confirmPassword(password);\n        // const res = { \"remaining-ms\": 100000 };\n        if (res.error) {\n            setPasswordError(res.error);\n        } else {\n            dispatch(updatePasswordExpires(Date.now() + (res[\"remaining-ms\"] ?? 0)));\n        }\n    }, [password]);\n\n    return (\n        <div>\n            <p>Confirm password to edit settings</p>\n            <ContentTextInput\n                style={{ marginLeft: 0 }}\n                type={\"password\"}\n                placeholder={\"Current password\"}\n                value={password}\n                onEnter={onConfirmPassword}\n                onChange={(e) => {\n                    setPasswordError(null);\n                    setPassword(e.target.value);\n                }}\n            />\n            <ModalButton\n                enabled={!!password}\n                variant=\"primary\"\n                onClick={onConfirmPassword}\n                className={classes.marginTop10}>\n                Confirm\n            </ModalButton>\n            <p className={classes.errorLabel}>{passwordError ? passwordError : \"\\u00A0\"}</p>\n        </div>\n    );\n};\n\nconst ConfigureMFA = () => {\n    const user = useSelector(getUser);\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { classes } = useStyles();\n\n    const isEnabled = user[\"2fa\"].enabled;\n\n    const [qrCode, setQrCode] = useState<string | null>(null);\n    const [authCode, setAuthCode] = useState(\"\");\n    const [authCodeError, setAuthCodeError] = useState<string | null>(null);\n\n    const enable2fa = useCallback(async () => {\n        const qr = await update2fa(true);\n        setQrCode(typeof qr === \"string\" ? qr : null);\n    }, []);\n\n    const disable2fa = useCallback(async () => {\n        if (\n            await dispatch(\n                confirm(\n                    \"Disable two-factor authentication?\",\n                    \"Are you sure you would like to disable two-factor authentication?\"\n                )\n            )\n        ) {\n            const response = await update2fa(false);\n            const error = typeof response === \"string\" ? undefined : response.error;\n            if (error) {\n                dispatch(alert(\"Error disabling two-factor authentication\", error));\n            } else {\n                await dispatch(updateUser2faEnabled(false));\n            }\n        }\n    }, []);\n\n    const cancel2fa = useCallback(() => {\n        setQrCode(null);\n        setAuthCodeError(null);\n        setAuthCode(\"\");\n    }, []);\n\n    const confirmAuthCode = useCallback(async () => {\n        const res = await confirm2fa(authCode);\n        if (res[\"success\"]) {\n            setQrCode(null);\n            setAuthCodeError(null);\n            setAuthCode(\"\");\n            dispatch(updateUser2faEnabled(true));\n        } else {\n            setAuthCodeError(res[\"error\"] || \"Invalid code\");\n        }\n    }, [authCode]);\n\n    return isEnabled ? (\n        <div>\n            <ModalButton variant=\"danger\" onClick={disable2fa}>\n                Disable\n            </ModalButton>\n            <p>\n                <i>Two-factor authentication is currently enabled</i>\n            </p>\n        </div>\n    ) : qrCode ? (\n        <div>\n            Scan the QR code to set up two-factor authentication in an app such as Google Authenticator.\n            <br />\n            <div style={{ textAlign: \"center\" }}>\n                <img src={`data:image/png;base64,${qrCode}`} />\n            </div>\n            <ContentTextInput\n                style={{ marginLeft: 0 }}\n                value={authCode}\n                placeholder={\"Code\"}\n                onEnter={confirmAuthCode}\n                onChange={(e) => {\n                    setAuthCodeError(null);\n                    setAuthCode(e.target.value);\n                }}\n            />\n            <div className={classes.marginTop10}>\n                <ModalButton variant=\"danger\" onClick={cancel2fa}>\n                    Cancel\n                </ModalButton>\n                <ModalButton variant=\"primary\" onClick={confirmAuthCode} style={{ marginLeft: \"1em\" }}>\n                    Confirm\n                </ModalButton>\n            </div>\n            <p className={classes.errorLabel}>{authCodeError ? authCodeError : \"\\u00A0\"}</p>\n        </div>\n    ) : (\n        <div>\n            <ModalButton variant=\"primary\" onClick={enable2fa}>\n                Enable\n            </ModalButton>\n            <p>\n                <i>Two-factor authentication is currently disabled</i>\n            </p>\n        </div>\n    );\n};\n","import React, { useCallback, useMemo } from \"react\";\nimport { connect } from \"react-redux\";\nimport { ButtonGroup } from \"@/components/reusable/ButtonGroup\";\nimport { useSaveIndicator } from \"@/components/reusable/SaveIndicator\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { getUser } from \"@/controllers/ide\";\nimport { updateSubscriptionToMailingList } from \"@/controllers/user\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\n\nconst useStyles = makeStyles()((theme) => ({\n    dropdown: {\n        margin: 0,\n        display: \"block\",\n    },\n    dropdownContainer: {\n        display: \"flex\",\n        alignItems: \"center\",\n    },\n    paddingTop20: {\n        paddingTop: \"2rem\",\n    },\n    form: {\n        rowGap: \"1rem\",\n        paddingTop: \"2rem\",\n        width: \"90%\",\n        maxWidth: \"100rem\",\n        display: \"grid\",\n        gridTemplateColumns: \"1fr max-content\",\n    },\n    selectionBox: {\n        display: \"flex\",\n        flexWrap: \"nowrap\",\n        justifyContent: \"center\",\n        alignItems: \"center\",\n    },\n}));\n\ninterface MailingPreference {\n    optIn?: boolean;\n    title: string;\n    callbackFn: (selection: boolean) => void;\n}\n\ninterface PrefPromptAndSelectProps {\n    pref: MailingPreference;\n}\n\nconst PrefPromptAndSelect = ({ pref: { optIn, title, callbackFn } }: PrefPromptAndSelectProps) => {\n    const { classes } = useStyles();\n\n    const options = [\n        { title: \"Opt In\", value: true },\n        { title: \"Opt Out\", value: false },\n    ];\n    const [savePrefIndicator, setPrefSaved] = useSaveIndicator();\n\n    const updateSelection = useCallback(\n        (selection: boolean) => {\n            setPrefSaved(false);\n            callbackFn(selection);\n            setPrefSaved(true);\n        },\n        [callbackFn]\n    );\n\n    return (\n        <>\n            <Text className={\"self-center\"}>{title}</Text>\n            <div className={cx(classes.selectionBox)}>\n                <ButtonGroup\n                    options={options}\n                    selectedVariant={\"primary\"}\n                    selectedOption={optIn ?? false}\n                    onClick={(selection) => updateSelection(selection)}\n                />\n                {savePrefIndicator}\n            </div>\n        </>\n    );\n};\n\nconst connector = connect((state: State) => ({\n    user: getUser(state),\n}));\n\ntype CommunicationsProps = AnvilConnectedProps<typeof connector>;\n\nconst Communications = ({ user, dispatch }: CommunicationsProps) => {\n    const { classes } = useStyles();\n\n    const mailing = useMemo<MailingPreference[]>(() => {\n        const subscriptions = user?.mailingListSubscriptions as { newsletter?: boolean } | null | undefined;\n        return [\n            {\n                title: \"Monthly Newsletter\",\n                optIn: subscriptions?.newsletter,\n                callbackFn: (option) => {\n                    dispatch(updateSubscriptionToMailingList(option, \"newsletter\"));\n                },\n            },\n        ];\n    }, [dispatch, user?.mailingListSubscriptions]);\n\n    return (\n        <div className={\"dark:text-grey-0\"}>\n            <h3 className={\"mt-10 mb-5 text-4xl font-medium\"}>Communication preferences</h3>\n\n            <div className={cx(classes.form)}>\n                {mailing.map((pref, ind) => (\n                    <PrefPromptAndSelect pref={pref} key={ind} />\n                ))}\n            </div>\n        </div>\n    );\n};\n\nexport default connector(Communications);\n","import React, { useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faQuestionCircle } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { useSaveIndicator } from \"@/components/reusable/SaveIndicator\";\nimport { ContentDropdownMenuItem } from \"@/components/reusable/SharedComponents\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport {\n    getUserAutoImport,\n    getUserCodeTemplates,\n    getUserEslintPref,\n    getUserKeyBindings,\n    getUserMinimapPref,\n    getUserPythonInlayHints,\n    getUserTabSize,\n    getUserTheme,\n    getUserUiPrefs,\n    getUserUiScale,\n    updateUserEditorPrefs,\n} from \"@/controllers/user\";\nimport { exportStore } from \"@/store\";\nimport { AnvilAsyncAction, AnvilDispatch } from \"@/types\";\nimport { User } from \"@/types/user\";\nimport { getAbTyAnalysis } from \"@/util/hooks/ab-flags\";\n\nconst LookAndFeel = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const userMinimap = useSelector(getUserMinimapPref);\n    const pythonInlayHints = useSelector(getUserPythonInlayHints);\n    const pythonAnalysis = useSelector(getAbTyAnalysis);\n    const userTheme = useSelector(getUserTheme);\n    const userKeyBindings = useSelector(getUserKeyBindings);\n    const userTabSize = useSelector(getUserTabSize);\n    const userFormatOnSave = useSelector(getUserUiPrefs)?.formatOnSave;\n    const uiScale = useSelector(getUserUiScale);\n    const autoImport = useSelector(getUserAutoImport);\n    const eslint = useSelector(getUserEslintPref);\n    const userCodeTemplates = useSelector(getUserCodeTemplates);\n\n    return (\n        <div className={\"dark:text-grey-0\"}>\n            <h3 className={\"mt-10 mb-5 text-4xl font-medium\"}>Look & Feel</h3>\n            <LookAndFeelDropDown\n                title={\"Theme\"}\n                configOption={\"theme\"}\n                value={userTheme || \"system\"}\n                options={[\n                    { display: \"System\", value: \"system\" },\n                    { display: \"Light\", value: \"light\" },\n                    { display: \"Dark\", value: \"dark\" },\n                ]}\n            />\n            <LookAndFeelDropDown<number | string>\n                title={\"Tab Size\"}\n                configOption={\"tabSize\"}\n                value={userTabSize || \"2\"}\n                options={[\n                    { display: \"2\", value: \"2\" },\n                    { display: \"4\", value: \"4\" },\n                ]}\n            />\n            <LookAndFeelDropDown\n                title={\"UI Scale\"}\n                configOption={\"scale\"}\n                value={uiScale || \"medium\"}\n                options={[\n                    { display: \"Tiny\", value: \"tiny\" },\n                    { display: \"Small\", value: \"small\" },\n                    { display: \"Medium\", value: \"medium\" },\n                    { display: \"Large\", value: \"large\" },\n                    { display: \"Huge\", value: \"huge\" },\n                ]}\n            />\n            <LookAndFeelDropDown\n                title={\"Minimap\"}\n                configOption={\"minimap\"}\n                description={\n                    \"Displays a condensed overview of your code on the right side of the editor for easier navigation.\"\n                }\n                value={String(userMinimap ?? true)}\n                getValue={(x) => x === \"true\"}\n                options={[\n                    { display: \"Yes\", value: true },\n                    { display: \"No\", value: false },\n                ]}\n            />\n            {pythonAnalysis && (\n                <LookAndFeelDropDown\n                    title=\"Python Inlay Hints\"\n                    configOption=\"pythonInlayHints\"\n                    description=\"Show inferred types and parameter names alongside Python code.\"\n                    value={String(pythonInlayHints)}\n                    getValue={(value) => value === \"true\"}\n                    options={[\n                        { display: \"Yes\", value: true },\n                        { display: \"No\", value: false },\n                    ]}\n                />\n            )}\n            <LookAndFeelDropDown\n                title={\"Auto Import Services\"}\n                configOption={\"autoImport\"}\n                description={\n                    \"Automatically manages service imports when creating new forms/modules or adding new services.\"\n                }\n                value={autoImport ?? 1}\n                options={[\n                    { display: \"Yes\", value: 1 },\n                    { display: \"No\", value: 0 },\n                ]}\n            />\n            <LookAndFeelDropDown\n                title={\"Code Templates\"}\n                description={\n                    \"Choose your preferred code structure: Standard templates include helpful comments and starred imports, while Minimal templates provide code without comments and starred imports (not recommended for new developers).\"\n                }\n                configOption={\"codeTemplates\"}\n                value={userCodeTemplates || \"standard\"}\n                options={[\n                    { display: \"Standard (Beginner-friendly)\", value: \"standard\" },\n                    { display: \"Minimal\", value: \"minimal\" },\n                ]}\n            />\n            <LookAndFeelDropDown\n                title={\"Format on save\"}\n                description={\n                    <>\n                        Automatically format code when using <code>Ctrl/Cmd+S</code> keyboard shortcut.\n                    </>\n                }\n                configOption={\"formatOnSave\"}\n                value={userFormatOnSave ?? false}\n                getValue={(x) => x === \"true\"}\n                options={[\n                    { display: \"Yes\", value: true },\n                    { display: \"No\", value: false },\n                ]}\n            />\n\n            <LookAndFeelDropDown<boolean>\n                title={\"ESLint JavaScript\"}\n                configOption={\"eslint\"}\n                description={\"Javascript files will be linted using ESLint.\"}\n                value={String(eslint ?? true)}\n                getValue={(x) => x === \"true\"}\n                options={[\n                    { display: \"Yes\", value: true },\n                    { display: \"No\", value: false },\n                ]}\n            />\n            <LookAndFeelDropDown\n                title={\"Key Bindings\"}\n                configOption={\"keyBindings\"}\n                value={userKeyBindings || \"default\"}\n                options={[\n                    { display: \"Default\", value: \"default\" },\n                    { display: \"Vim\", value: \"vim\" },\n                    { display: \"Emacs\", value: \"emacs\" },\n                ]}\n            />\n            <Text level={3} style={{ marginTop: \"2rem\" }}>\n                <LinkInternal style={{ textDecoration: \"underline\" }} onClick={() => dispatch(exportStore())}>\n                    Export local debugging data\n                </LinkInternal>\n            </Text>\n        </div>\n    );\n};\n\ninterface LookAndFeelDropDownProps<T> {\n    title: string;\n    description?: React.ReactNode;\n    configOption: keyof User[\"uiPrefs\"];\n    value: string | T;\n    options: { value: T; display: string }[];\n    getValue?: (x: string) => T;\n}\n\nconst LookAndFeelDropDown = <T,>({\n    title,\n    description,\n    configOption,\n    value,\n    options,\n    getValue = (x: string) => x as T,\n}: LookAndFeelDropDownProps<T>) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const [selectedLookAndFeel, setSelectedLookAndFeel] = useState(value);\n    const [saveIndicator, setSaved] = useSaveIndicator();\n    const [tooltip, tooltipAnchorRef] = useTooltip(\n        description && <div className=\"w-max max-w-sm whitespace-break-spaces\">{description}</div>,\n        \"right\"\n    );\n\n    const updateUserPrefs = async (newOption: string) => {\n        setSelectedLookAndFeel(newOption);\n        setSaved(false);\n        const value = getValue(newOption);\n        await dispatch(updateUserEditorPrefs(configOption, value));\n        setSaved(true);\n    };\n\n    return (\n        <div className=\"flex flex-col gap-2 pt-5\">\n            <div className=\"flex items-center gap-4\">\n                <span>{title}: </span>\n                {description && (\n                    <div ref={tooltipAnchorRef} className=\"cursor-help text-primary\">\n                        <FontAwesomeIcon icon={faQuestionCircle} />\n                        {tooltip}\n                    </div>\n                )}\n            </div>\n            <div className={\"flex items-center gap-2\"}>\n                <ContentDropdownMenuItem\n                    className={\"m-0! min-w-106\"}\n                    value={String(selectedLookAndFeel)}\n                    onChange={(e: React.ChangeEvent<HTMLSelectElement>) => updateUserPrefs(e.target.value)}>\n                    {options.map(({ value, display }) => (\n                        <option key={display} value={value as string}>\n                            {display}\n                        </option>\n                    ))}\n                </ContentDropdownMenuItem>\n                <div className=\"min-w-14\">{saveIndicator}</div>\n            </div>\n        </div>\n    );\n};\n\nexport default LookAndFeel;\n","import React from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { Heading } from \"@/components/reusable/Text\";\nimport { getSubscription, getUser } from \"@/controllers/ide\";\nimport { modal } from \"@/controllers/modals\";\nimport Developer from \"@/manager/components/Developers\";\nimport Managers from \"@/manager/components/Managers\";\nimport { AnvilDispatch } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\n\nconst ManageDevelopers = () => {\n    const user = useSelector(getUser);\n    const subscription = useSelector(getSubscription);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const onClickViewApps = useEvent(() => {\n        dispatch(modal(\"orgApps\", {}));\n    });\n\n    return (\n        <div className={\"max-w-400 dark:text-grey-0\"}>\n            <Developer user={user} />\n            {subscription?.isManager && (\n                <div className={\"mt-10\"}>\n                    <Heading level={1}>Apps</Heading>\n                    <LinkInternal className={\"underline\"} onClick={onClickViewApps}>\n                        View all Apps in this plan\n                    </LinkInternal>\n                </div>\n            )}\n            {subscription?.plan && (\n                <div className={\"mt-10\"}>\n                    <Managers />\n                </div>\n            )}\n        </div>\n    );\n};\n\nexport default ManageDevelopers;\n","import { useMemo, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport moment from \"moment-timezone\";\nimport { type AppWithScheduledTasks, getAllScheduledTasks } from \"@/api\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { useFormatTimeSpec } from \"@/controllers/scheduledtasks\";\nimport { navigate } from \"@/router/navigation\";\nimport type { AnvilDispatch } from \"@/types\";\nimport type { AppId } from \"@/types/app\";\nimport type { TimeSpec } from \"@/types/app-scheduled-tasks\";\nimport { useEffectAsync } from \"@/util/hooks\";\n\ntype SortKey =\n    | \"last-updated-desc\"\n    | \"last-updated-asc\"\n    | \"name-asc\"\n    | \"name-desc\"\n    | \"task-count-desc\"\n    | \"task-count-asc\";\n\nconst SORT_OPTIONS: { value: SortKey; label: string }[] = [\n    { value: \"last-updated-desc\", label: \"Last updated: newest first\" },\n    { value: \"last-updated-asc\", label: \"Last updated: oldest first\" },\n    { value: \"name-asc\", label: \"App name: A–Z\" },\n    { value: \"name-desc\", label: \"App name: Z–A\" },\n    { value: \"task-count-desc\", label: \"Most tasks first\" },\n    { value: \"task-count-asc\", label: \"Fewest tasks first\" },\n];\n\nfunction sortApps(apps: AppWithScheduledTasks[], sort: SortKey): AppWithScheduledTasks[] {\n    return [...apps].sort((a, b) => {\n        switch (sort) {\n            case \"last-updated-desc\":\n                return (b.last_updated ?? \"\").localeCompare(a.last_updated ?? \"\");\n            case \"last-updated-asc\":\n                return (a.last_updated ?? \"\").localeCompare(b.last_updated ?? \"\");\n            case \"name-asc\":\n                return (a.app_name ?? \"\").localeCompare(b.app_name ?? \"\");\n            case \"name-desc\":\n                return (b.app_name ?? \"\").localeCompare(a.app_name ?? \"\");\n            case \"task-count-desc\":\n                return b.tasks.length - a.tasks.length;\n            case \"task-count-asc\":\n                return a.tasks.length - b.tasks.length;\n        }\n    });\n}\n\nconst TaskRow = ({\n    task_name,\n    time_spec,\n    suspended_at,\n}: {\n    task_name: string;\n    time_spec: TimeSpec;\n    suspended_at: string | null;\n}) => {\n    const formatted = useFormatTimeSpec(time_spec);\n    return (\n        <div className=\"flex items-baseline gap-3 py-1\">\n            <span className=\"font-mono text-xl\">{task_name}</span>\n            <span className=\"text-grey-2\">{formatted}</span>\n            {suspended_at && (\n                <span className=\"rounded bg-danger/10 px-1.5 py-0.5 text-sm font-medium text-danger\">suspended</span>\n            )}\n        </div>\n    );\n};\n\nconst AppRow = ({ app }: { app: AppWithScheduledTasks }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const formattedDate = app.last_updated ? moment(app.last_updated).format(\"D MMM YYYY\") : null;\n    const suspendedCount = app.tasks.filter((t) => t.suspended_at).length;\n\n    const goToApp = () => {\n        dispatch(navigate({ type: \"SCHEDULED_TASKS\", appId: app.app_id as AppId }));\n        dispatch(modalReturn(true));\n    };\n\n    return (\n        <div className=\"border-b border-gray-200 py-4 last:border-0 dark:border-gray-700\">\n            <div className=\"flex items-baseline justify-between gap-4\">\n                <h4 className=\"text-2xl font-medium\">\n                    <LinkInternal className=\"underline\" onClick={goToApp}>\n                        {app.app_name || app.app_id}\n                    </LinkInternal>\n                </h4>\n                <span className=\"shrink-0 text-base text-grey-2\">\n                    {formattedDate ? `last updated ${formattedDate}` : \"\"}\n                    {suspendedCount > 0 && <span className=\"ml-3 text-danger\">{suspendedCount} suspended</span>}\n                </span>\n            </div>\n            <div className=\"mt-2 pl-3\">\n                {app.tasks.map((task) => (\n                    <TaskRow key={task.job_id} {...task} />\n                ))}\n            </div>\n        </div>\n    );\n};\n\nconst AccountScheduledTasks = () => {\n    const [apps, setApps] = useState<AppWithScheduledTasks[] | null>(null);\n    const [sort, setSort] = useState<SortKey>(\"last-updated-desc\");\n\n    useEffectAsync(async () => {\n        const result = await getAllScheduledTasks();\n        setApps(result);\n    }, []);\n\n    const sorted = useMemo(() => (apps ? sortApps(apps, sort) : []), [apps, sort]);\n\n    return (\n        <div className=\"dark:text-grey-0\">\n            <h3 className=\"mt-10 mb-5 text-4xl font-medium\">Scheduled Tasks</h3>\n            <p className=\"mb-6 text-lg\">All apps with scheduled tasks enabled across your account.</p>\n\n            {apps === null ? (\n                <p>Loading…</p>\n            ) : apps.length === 0 ? (\n                <p>You don't have any scheduled tasks enabled on any of your apps.</p>\n            ) : (\n                <>\n                    <div className=\"mb-6 flex items-center gap-3\">\n                        <label className=\"text-base\" htmlFor=\"st-sort\">\n                            Sort by\n                        </label>\n                        <select\n                            id=\"st-sort\"\n                            className=\"rounded border border-gray-300 bg-white px-2 py-1 text-base dark:border-gray-600 dark:bg-gray-800\"\n                            value={sort}\n                            onChange={(e) => setSort(e.target.value as SortKey)}>\n                            {SORT_OPTIONS.map((o) => (\n                                <option key={o.value} value={o.value}>\n                                    {o.label}\n                                </option>\n                            ))}\n                        </select>\n                        <span className=\"text-base text-grey-2\">\n                            {apps.length} app{apps.length !== 1 ? \"s\" : \"\"}\n                        </span>\n                    </div>\n                    <div>\n                        {sorted.map((app) => (\n                            <AppRow key={app.app_id} app={app} />\n                        ))}\n                    </div>\n                </>\n            )}\n        </div>\n    );\n};\n\nexport default AccountScheduledTasks;\n","import * as React from \"react\";\nimport { useMemo, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport type { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport { faComments } from \"@fortawesome/free-solid-svg-icons/faComments\";\nimport { faFileInvoiceDollar } from \"@fortawesome/free-solid-svg-icons/faFileInvoiceDollar\";\nimport { faKey } from \"@fortawesome/free-solid-svg-icons/faKey\";\nimport { faMoneyCheck } from \"@fortawesome/free-solid-svg-icons/faMoneyCheck\";\nimport { faPalette } from \"@fortawesome/free-solid-svg-icons/faPalette\";\nimport { faChartArea } from \"@fortawesome/pro-solid-svg-icons/faChartArea\";\nimport { faClock } from \"@fortawesome/pro-solid-svg-icons/faClock\";\nimport { faUsers } from \"@fortawesome/pro-solid-svg-icons/faUsers\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport * as api from \"@/api\";\nimport { Authentication } from \"@/components/modals/account/Authentication\";\nimport Link from \"@/components/reusable/Link\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { getSubscription, getSubscriptionLoading, getUser } from \"@/controllers/ide\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport type { AuthHash } from \"@/router/navTypes\";\nimport { navigate } from \"@/router/navigation\";\nimport { cx } from \"@/theme/styles\";\nimport type { AnvilDispatch } from \"@/types\";\nimport { useFeatureSupported } from \"@/util/features\";\nimport { useEffectAsync, useStateWithReset } from \"@/util/hooks\";\nimport type { ModalComponent } from \"..\";\nimport type { ModalRef } from \"../Modal\";\nimport Modal from \"../Modal\";\nimport useStyles from \"../modalstyles\";\nimport Billing from \"./Billing\";\nimport Communications from \"./Communications\";\nimport LookAndFeel from \"./LookAndFeel\";\nimport ManageDevelopers from \"./ManageDevelopers\";\nimport type { AccountQuotas } from \"./Quotas\";\nimport { Quotas } from \"./Quotas\";\nimport AccountScheduledTasks from \"./ScheduledTasksDashboard\";\nimport Subscription from \"./Subscription\";\n\ntype AccountSection =\n    | \"SUBSCRIPTION\"\n    | \"USERS\"\n    | \"AUTHENTICATION\"\n    | \"LOOK-FEEL\"\n    | \"COMMUNICATIONS\"\n    | \"BILLING\"\n    | \"QUOTAS\"\n    | \"SCHEDULED-TASKS\";\n\ninterface AccountItem {\n    description: string;\n    icon: IconDefinition;\n    id: AccountSection;\n    title: string;\n}\n\ninterface AccountModalSpec {\n    action?: \"updatePayment\" | null;\n    hash?: AuthHash | null;\n    section?: AccountSection | null;\n}\n\nexport const AccountModalContent = ({\n    section,\n    action = null,\n    newAccountPage = false,\n    hash = null,\n}: AccountModalSpec & { newAccountPage?: boolean }) => {\n    const { classes } = useStyles();\n\n    const user = useSelector(getUser);\n    const subscription = useSelector(getSubscription);\n    const dispatch = useDispatch<AnvilDispatch>();\n    const isSubscriptionLoading = useSelector(getSubscriptionLoading);\n    const supportsScheduledTasks = useFeatureSupported(\"scheduled-tasks\");\n\n    const isEnterprise = useMemo(() => {\n        return subscription?.plan === \"enterprise\";\n    }, [subscription]);\n\n    const accountItems = useMemo(() => {\n        return [\n            {\n                id: \"SUBSCRIPTION\",\n                title: \"Subscription\",\n                description: \"Plan and payment details\",\n                icon: faFileInvoiceDollar,\n            },\n            { id: \"USERS\", title: \"Account Users\", description: \"Add and remove developers\", icon: faUsers },\n            {\n                id: \"AUTHENTICATION\",\n                title: \"Authentication & Keys\",\n                description: \"Account security settings, SSH and OAuth access\",\n                icon: faKey,\n            },\n            { id: \"LOOK-FEEL\", title: \"Look & Feel\", description: \"Themes, fonts etc.\", icon: faPalette },\n            { id: \"COMMUNICATIONS\", title: \"Communications\", description: \"Upgrade your account\", icon: faComments },\n            ...(!isEnterprise\n                ? [{ id: \"BILLING\", title: \"Billing\", description: \"Billing history\", icon: faMoneyCheck } as const]\n                : []),\n            ...(user?.ideConfig?.enableAccounting\n                ? [\n                      {\n                          id: \"QUOTAS\",\n                          title: \"Quotas & Usage\",\n                          description: \"Account usage and quotas\",\n                          icon: faChartArea,\n                      } as const,\n                  ]\n                : []),\n            ...(supportsScheduledTasks\n                ? [\n                      {\n                          id: \"SCHEDULED-TASKS\",\n                          title: \"Scheduled Tasks\",\n                          description: \"Tasks running across your apps\",\n                          icon: faClock,\n                      } as const,\n                  ]\n                : []),\n        ] satisfies AccountItem[];\n    }, [isEnterprise, subscription, user, supportsScheduledTasks]);\n\n    const [selectedItem, _setSelectedItem] = useStateWithReset<AccountItem | undefined>(\n        accountItems.find((a) => a.id === section) || accountItems[0]\n    );\n    const setSelectedItem = (item: AccountItem) => {\n        if (newAccountPage) {\n            dispatch(navigate({ type: \"ACCOUNT\", section: item.id }));\n            _setSelectedItem(item);\n        } else {\n            _setSelectedItem(item);\n        }\n    };\n\n    let content: React.ReactNode = null;\n\n    const [bucketQuotas, setBucketQuotas] = useState<AccountQuotas | null>(null);\n\n    useEffectAsync(async () => {\n        const results = await api.getQuota([\"db-rows\", \"db-bytes\", \"email\", \"server-time\", \"ai-credits\"]);\n        setBucketQuotas(results);\n    }, []);\n\n    const quotasAndLimits = {\n        quotas: bucketQuotas,\n        limits: user?.dynamicDownlinkBuildLimits,\n    };\n\n    switch (selectedItem?.id) {\n        case \"SUBSCRIPTION\":\n            content = (\n                <Subscription\n                    subscription={subscription}\n                    user={user}\n                    dispatch={dispatch}\n                    goToBilling={() => {\n                        const billingItem = accountItems.find(({ id }) => id === \"BILLING\");\n                        if (billingItem) {\n                            setSelectedItem(billingItem);\n                        }\n                    }}\n                />\n            );\n            break;\n        case \"USERS\":\n            content = <ManageDevelopers />;\n            break;\n        case \"QUOTAS\":\n            content = <Quotas quotasAndLimits={quotasAndLimits} />;\n            break;\n        case \"AUTHENTICATION\":\n            content = <Authentication hash={hash} />;\n            break;\n        case \"LOOK-FEEL\":\n            content = <LookAndFeel />;\n            break;\n        case \"BILLING\":\n            content = <Billing action={action} />;\n            break;\n        case \"COMMUNICATIONS\":\n            content = <Communications />;\n            break;\n        case \"SCHEDULED-TASKS\":\n            content = <AccountScheduledTasks />;\n            break;\n    }\n\n    if (!selectedItem) return null;\n\n    // Without this, the wrong information will show up for a couple of seconds on Subscription and Billing\n    if (isSubscriptionLoading) {\n        return <LoadingSpinner />;\n    }\n\n    return (\n        <>\n            {user?.impersonator && (\n                <div className={cx(classes.warningNotice)}>\n                    <span>\n                        <b>WARNING</b> Changes you make to this account will affect the user.\n                    </span>{\" \"}\n                </div>\n            )}\n            <div className={classes.flex}>\n                <ul className={cx(classes.listStyleNone, classes.noMargin, classes.modalSidebarOptions)}>\n                    {accountItems.map((accItem, idx) => (\n                        <li\n                            key={idx}\n                            className={cx(\n                                classes.sidebarNavItem,\n                                classes.fullWidth,\n                                accItem.id === selectedItem.id && cx(classes.activeLink)\n                            )}>\n                            <LinkInternal key={idx} onClick={() => setSelectedItem(accItem)}>\n                                <div className={classes.sidebarNavIcon}>\n                                    <FontAwesomeIcon className={classes.icon} icon={accItem.icon} />\n                                    {accItem.title}\n                                </div>\n                            </LinkInternal>\n                        </li>\n                    ))}\n                </ul>\n                <div className={cx(classes.horizPadding, classes.fullWidth)}>\n                    {accountItems\n                        .filter((accItem) => accItem.id === selectedItem.id)\n                        .map((accItem, idx) => (\n                            <div key={idx}>{content}</div>\n                        ))}\n                </div>\n            </div>\n        </>\n    );\n};\n\nconst AccountModal: ModalComponent<AccountModalSpec, boolean> = ({ modalId, spec: { section, action, hash } }) => {\n    const user = useSelector(getUser);\n    const modalRef = useRef<ModalRef>(null);\n    const leftButtons = (\n        <small>\n            {\" \"}\n            We take your privacy seriously.{\" \"}\n            <Link to={\"https://anvil.works/privacy\"} target={\"_blank\"}>\n                {\" \"}\n                Click here to view our Privacy Policy\n            </Link>\n        </small>\n    );\n\n    return (\n        <Modal\n            modalId={modalId}\n            ref={modalRef}\n            title={`My Account: ${user.email}`}\n            leftButtons={leftButtons}\n            buttons={[{ text: \"Close\", clickActionCreator: () => modalReturn(true) }]}>\n            <AccountModalContent section={section} action={action} hash={hash} />\n        </Modal>\n    );\n};\n\nexport default AccountModal;\n","import * as React from \"react\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faCheck } from \"@fortawesome/free-solid-svg-icons/faCheck\";\nimport { faExclamationTriangle } from \"@fortawesome/pro-regular-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport UpgradeBadge from \"@/components/reusable/UpgradeBadge\";\nimport { getSubscription, getUser } from \"@/controllers/ide\";\nimport { alert, prompt, updatePayment } from \"@/controllers/modals\";\nimport { modal } from \"@/controllers/modals\";\nimport { authorisePayment, authoriseSetup, retryPayment } from \"@/controllers/payment\";\nimport { getInvoices, updateInvoiceEmail } from \"@/controllers/user\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { ignoreSsrWarning } from \"@/theme/utils\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport type { SubscriptionCharge } from \"@/types/subscription\";\nimport { CURRENCY_SYMBOLS, formatDiscountLabel } from \"@/util/discounts\";\nimport { getFeatureSupport } from \"@/util/features\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { dateAndDaysAway } from \"../../../util/time\";\nimport { Button } from \"../../reusable/Button\";\nimport Link from \"../../reusable/Link\";\nimport { Heading, Text } from \"../../reusable/Text\";\nimport useStyles from \"../../tabs/settings/styles\";\nimport { DirectToManagerPortal } from \"./Subscription\";\n\nconst billingTabStyles = makeStyles()((theme) => ({\n    cardBrand: {\n        textTransform: \"capitalize\",\n    },\n    billingHistoryTable: {\n        borderBottom: \"none\",\n        tableLayout: \"fixed\",\n        [`& tr th:first-child${ignoreSsrWarning}, & tr td:first-child${ignoreSsrWarning}`]: {\n            width: \"20%\",\n            paddingLeft: \"1rem\",\n        },\n\n        \"& tr th:nth-child(2), & tr td:nth-child(2)\": {\n            width: \"25%\",\n            textAlign: \"center\",\n        },\n        \"& tr th:nth-child(3), & tr td:nth-child(3)\": {\n            width: \"20%\",\n            textAlign: \"center\",\n        },\n        \"& tr th:last-child, & tr td:last-child\": {\n            width: \"auto\",\n            textAlign: \"right\",\n            paddingRight: \"1rem\",\n        },\n    },\n    paidStatusIcon: {\n        color: theme.palette.highlight.toString(),\n    },\n    openStatusIcon: {\n        color: theme.palette.danger.toString(),\n    },\n}));\n\nconst connector = connect((state: State) => ({\n    subscription: getSubscription(state),\n    user: getUser(state),\n    supportsInvoiceEmail: getFeatureSupport(state, \"invoice-email\"),\n    invoices: getInvoices(state),\n}));\n\ntype BillingProps = AnvilConnectedProps<typeof connector> & {\n    action?: \"updatePayment\" | null;\n};\n\nconst Billing = ({ subscription, user, supportsInvoiceEmail, invoices, action = null, dispatch }: BillingProps) => {\n    const { classes } = useStyles();\n    const { classes: modalClasses } = billingTabStyles();\n\n    const [disabledButton, setDisabledButton] = useState(false);\n\n    const realCharges = useMemo(() => {\n        return subscription?.charges?.filter((charge) => !charge[\"line-description\"].includes(\"Trial period for \"));\n    }, [subscription?.charges]);\n\n    const currency = useMemo(() => {\n        if (realCharges) {\n            return CURRENCY_SYMBOLS[realCharges[0]?.currency?.toUpperCase()] || \"$\";\n        }\n    }, [realCharges]);\n\n    const [showMoreHistory, setShowAllHistory] = useState(realCharges ? realCharges.length <= 5 : false);\n\n    const firstElems = useMemo(() => {\n        const elems: SubscriptionCharge[] = [];\n        if (realCharges) {\n            for (let i = 0; i < 5; i++) {\n                if (!realCharges[i]) break;\n                elems.push(realCharges[i]);\n            }\n        }\n        return elems;\n    }, [realCharges]);\n\n    const onAuthorizeButtonClick = useCallback(\n        async (charge: SubscriptionCharge) => {\n            setDisabledButton(true);\n            await dispatch(authorisePayment(charge));\n            setDisabledButton(false);\n        },\n        [disabledButton]\n    );\n\n    const onRetryButtonClick = useCallback(\n        async (charge: SubscriptionCharge) => {\n            setDisabledButton(true);\n            await dispatch(retryPayment(charge));\n            setDisabledButton(false);\n        },\n        [disabledButton]\n    );\n\n    const paymentButton = useCallback(\n        (charge: SubscriptionCharge) => {\n            return charge.paymentStatus === \"requires_action\" ? (\n                <Button disabled={disabledButton} onClick={() => onAuthorizeButtonClick(charge)} small>\n                    Authorise Payment\n                </Button>\n            ) : (\n                <Button disabled={disabledButton} onClick={() => onRetryButtonClick(charge)} small>\n                    Retry Payment\n                </Button>\n            );\n        },\n        [disabledButton, onAuthorizeButtonClick, onRetryButtonClick]\n    );\n\n    const historyElement = useCallback(\n        (charge: SubscriptionCharge, index: number) => {\n            const dateTime = new Date(charge.date * 1000);\n            const date = dateTime.toISOString().substring(0, 10);\n            return (\n                <tr key={index}>\n                    <td>{date}</td>\n                    <td>\n                        {currency}\n                        {(charge.amount * 0.01).toFixed(2)}\n                    </td>\n                    <td>\n                        {charge.status === \"paid\" ? (\n                            <FontAwesomeIcon className={modalClasses.paidStatusIcon} icon={faCheck} />\n                        ) : (\n                            <FontAwesomeIcon className={modalClasses.openStatusIcon} icon={faExclamationTriangle} />\n                        )}\n                    </td>\n                    <td>\n                        {charge.status === \"open\" ? (\n                            paymentButton(charge)\n                        ) : invoices?.[charge.id] ? (\n                            <Link\n                                to={`/manage/_/organisation/${subscription!.licenceKey}/invoices/${invoices[charge.id]}`}\n                                target={\"_blank\"}>\n                                {\" \"}\n                                View Invoice\n                            </Link>\n                        ) : (\n                            \"Invoice Available Soon\"\n                        )}\n                    </td>\n                </tr>\n            );\n        },\n        [invoices, currency, paymentButton]\n    );\n\n    const visibleHistory = useMemo(() => {\n        return showMoreHistory\n            ? realCharges?.map((charge, index) => historyElement(charge, index))\n            : firstElems.map((charge, index) => historyElement(charge, index));\n    }, [showMoreHistory, firstElems, realCharges, historyElement]);\n\n    const openUpdatePaymentFlow = useCallback(\n        async (errMsg: string | null = null) => {\n            const cardUpdate = await dispatch(updatePayment(errMsg, subscription));\n            if (cardUpdate && \"setupIntent\" in cardUpdate && cardUpdate.setupIntent) {\n                dispatch(\n                    alert(\"Payment Details Updated\", \"Your payment details have been successfully updated. Thank you!\")\n                );\n            } else if (cardUpdate && \"e\" in cardUpdate && cardUpdate.e) {\n                console.log(cardUpdate.e, cardUpdate.error);\n                await openUpdatePaymentFlow(cardUpdate.error.message);\n            }\n        },\n        [subscription]\n    );\n\n    const updateInvoiceAddress = useCallback(async () => {\n        const initVal = subscription?.invoiceEmail || user.email;\n        const invoiceEmailAddress = await dispatch(\n            prompt(\"Email Invoices\", \"Enter the email address to send your invoice to\", initVal)\n        );\n        if (invoiceEmailAddress) dispatch(updateInvoiceEmail(invoiceEmailAddress));\n    }, [subscription?.invoiceEmail, user?.email]);\n\n    useEffect(() => {\n        switch (action) {\n            case \"updatePayment\":\n                openUpdatePaymentFlow();\n                break;\n            default:\n                break;\n        }\n    }, [action]);\n\n    {\n        /* TODO: Invoices should be available even if you're manually invoiced */\n    }\n    const [authorisingFirstPayment, setAuthorisingFirstPayment] = useState(false);\n\n    const authoriseFirstPayment = useEvent(async () => {\n        setAuthorisingFirstPayment(true);\n        await dispatch(authoriseSetup(subscription?.setupIntent?.clientSecret!));\n        setAuthorisingFirstPayment(false);\n    });\n\n    const tabBody = useMemo(() => {\n        const [nextInvoiceDate, daysRemaining] = dateAndDaysAway(subscription?.nextInvoice || subscription?.expires);\n        let requiresPaymentAction = <></>;\n        if (\n            subscription?.setupIntent &&\n            [\"requires_action\", \"requires_payment_method\"].includes(subscription.setupIntent.status)\n        ) {\n            requiresPaymentAction = (\n                <>\n                    <hr />\n                    <div>\n                        {\n                            <>\n                                <div className={classes.notification}>\n                                    <Heading level={2} className={\"mt-2!\"}>\n                                        Authorise Payment\n                                    </Heading>\n                                    <Text level={3} className={\"mt-10\"}>\n                                        We were unable to take payment. Please authorise the card to complete the\n                                        transaction and continue your paid plan.\n                                    </Text>\n                                    <Button\n                                        onClick={authoriseFirstPayment}\n                                        icon={faExclamationTriangle}\n                                        variant={\"tertiary\"}\n                                        disabled={authorisingFirstPayment}>\n                                        Authorise Payment\n                                    </Button>\n                                </div>\n                            </>\n                        }\n                    </div>\n                </>\n            );\n        } else if (\n            realCharges &&\n            realCharges.length < 0 &&\n            !realCharges.map((charge: SubscriptionCharge) => charge.status).find((status) => status !== \"open\")\n        ) {\n            requiresPaymentAction = (\n                <>\n                    <hr />\n                    <div>\n                        {\n                            <>\n                                <div className={classes.notification}>\n                                    <Heading level={2} className={\"mt-2!\"}>\n                                        Authorise Payment\n                                    </Heading>\n                                    <Text level={3} className={\"mt-10\"}>\n                                        We were unable to take payment. Please retry the payment below. If you'd like to\n                                        use a different payment method, please change the payment card above and then\n                                        retry the payment.\n                                    </Text>\n                                </div>\n                            </>\n                        }\n                    </div>\n                </>\n            );\n        }\n\n        switch (true) {\n            case !subscription?.plan:\n                return (\n                    <div>\n                        You are currently on the <b>Free Plan</b>. No billing information is available.\n                    </div>\n                );\n            case !subscription?.isManager:\n                return (\n                    <Text level={2}>\n                        Only account managers can view and update billing information for this subscription.\n                    </Text>\n                );\n            case !subscription?.isStripeCustomer:\n                return (\n                    <div>\n                        Billing information is only available to customers paying by card. Please contact{\" \"}\n                        <b>billing@anvil.works</b> with any questions.\n                    </div>\n                );\n            default:\n                return (\n                    <>\n                        <div>\n                            <Heading level={1}>Payment Details</Heading>\n                            <p>\n                                Contact:{\" \"}\n                                <strong>\n                                    {subscription?.name} - {subscription?.email}\n                                </strong>\n                                <br />\n                                Payment Card: ••• <b className={modalClasses.cardBrand}>\n                                    {subscription?.card?.last4}\n                                </b>{\" \"}\n                                (<b>{subscription?.card?.brand}</b>)\n                            </p>\n                            <Button variant={\"primary\"} size={\"small\"} onClick={() => openUpdatePaymentFlow()}>\n                                Change payment card\n                            </Button>\n                        </div>\n                        {(!!subscription?.balance && subscription.balance < 0 || subscription?.discount) && (\n                            <>\n                                <hr />\n                                <div>\n                                    <Heading level={1}>Account Credit &amp; Discounts</Heading>\n                                    {!!subscription?.balance && subscription.balance < 0 && (\n                                        <p>\n                                            Account credit: <b>{currency}{(-subscription.balance / 100).toFixed(2)}</b> — will\n                                            be applied to your next invoice.\n                                        </p>\n                                    )}\n                                    {subscription?.discount && (\n                                        <p>\n                                            Discount applied: <b>{formatDiscountLabel(subscription.discount)}</b>\n                                        </p>\n                                    )}\n                                </div>\n                            </>\n                        )}\n                        <hr />\n                        <div>\n                            <Heading level={1}>Invoicing</Heading>\n                            {subscription?.cancelled ? (\n                                <></>\n                            ) : (\n                                <>\n                                    <p>\n                                        Next Invoice Date:{\" \"}\n                                        <strong>{`${nextInvoiceDate} (${daysRemaining.toLocaleString()} days from now)`}</strong>\n                                    </p>\n                                </>\n                            )}\n                            {subscription.invoiceEmail ? (\n                                <>\n                                    <div>\n                                        New invoices will be sent to <b>{subscription.invoiceEmail}</b>\n                                    </div>\n                                    <Button size={\"small\"} variant={\"primary\"} onClick={updateInvoiceAddress}>\n                                        Update email address\n                                    </Button>\n                                    <Button\n                                        style={{ marginLeft: \"0.5rem\" }}\n                                        size={\"small\"}\n                                        variant={\"secondary\"}\n                                        onClick={() => dispatch(updateInvoiceEmail())}>\n                                        Stop receiving invoices by email\n                                    </Button>\n                                </>\n                            ) : (\n                                <>\n                                    <div>You do not currently receive invoices by email.</div>\n                                    <Button\n                                        onClick={() =>\n                                            supportsInvoiceEmail\n                                                ? updateInvoiceAddress()\n                                                : dispatch(modal(\"upgradePrompt\", { featureId: \"invoice-email\" }))\n                                        }\n                                        variant={\"primary\"}\n                                        size={\"small\"}>\n                                        Receive invoices by email\n                                        <UpgradeBadge feature={\"invoice-email\"} />\n                                    </Button>\n                                </>\n                            )}\n                        </div>\n                        {requiresPaymentAction}\n                        <hr />\n                        <div>\n                            <Heading level={1}>Billing History</Heading>\n                            {realCharges && realCharges.length > 0 ? (\n                                <>\n                                    <table className={cx(\"table\", classes.table, modalClasses.billingHistoryTable)}>\n                                        <thead>\n                                            <tr>\n                                                <th>Date</th>\n                                                <th>Amount</th>\n                                                <th>Status</th>\n                                                <th></th>\n                                            </tr>\n                                        </thead>\n                                        <tbody>{visibleHistory}</tbody>\n                                    </table>\n\n                                    {realCharges.length > 5 && !showMoreHistory && (\n                                        <Button\n                                            className={\"relative -top-10 left-4\"}\n                                            onClick={() => setShowAllHistory(true)}\n                                            size={\"small\"}>\n                                            Show All...\n                                        </Button>\n                                    )}\n                                    <hr className={\"relative -top-10 border-4! border-light-bg5!\"} />\n                                </>\n                            ) : (\n                                <div>No billing history available</div>\n                            )}\n                        </div>\n                    </>\n                );\n        }\n    }, [user, subscription, supportsInvoiceEmail, showMoreHistory, modalClasses, classes]);\n\n    return (\n        <div className={\"dark:text-grey-0\"}>\n            <DirectToManagerPortal />\n            <h3 className={\"mt-10 mb-5 text-4xl font-medium\"}>Billing</h3>\n            {tabBody}\n        </div>\n    );\n};\n\nexport default connector(Billing);\n","import React, { ChangeEvent, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { ModalComponent } from \"@/components/modals\";\nimport Modal from \"@/components/modals/Modal\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { useSaveIndicator } from \"@/components/reusable/SaveIndicator\";\nimport { ContentDropdownMenuItem } from \"@/components/reusable/SharedComponents\";\nimport { loadOrgApps } from \"@/manager/api\";\nimport { getCurrentOrganisationLicenceKey, updateAppOwner } from \"@/manager/controller\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useDeveloperQuery } from \"@/util/hooks/use-developer-query.ts\";\nimport { queryClient } from \"@/util/queryClient\";\nimport useEvent from \"@/util/useEventCallback\";\n\nexport const useUpdateAppOwnership = (initialOwner: string, appId: string) => {\n    const { developers } = useDeveloperQuery();\n    const [appOwner, setAppOwner] = useState(initialOwner);\n    const [updateOwnershipSaveIndicator, setOwnershipSaved] = useSaveIndicator();\n    const dispatch = useDispatch<AnvilDispatch>();\n    const licenceKey = useSelector(getCurrentOrganisationLicenceKey);\n\n    const chooseAppOwner = useEvent(async (owner: string) => {\n        setAppOwner(owner);\n        setOwnershipSaved(false);\n        await dispatch(updateAppOwner(appId, owner, initialOwner));\n        setOwnershipSaved(true);\n        await queryClient.invalidateQueries({ queryKey: [\"all-subscription-apps\", licenceKey] });\n    });\n\n    return { updateOwnershipSaveIndicator, appOwner, chooseAppOwner, developers };\n};\ninterface ChangeAppOwnershipRowProps {\n    app: {\n        name: string;\n        id: string;\n        email: string;\n        num_shared: number;\n    };\n    index: number;\n}\n\nconst UpdateOwnerRow = ({ app, index }: ChangeAppOwnershipRowProps) => {\n    const { name, id, email, num_shared } = app;\n    const { updateOwnershipSaveIndicator, appOwner, chooseAppOwner, developers } = useUpdateAppOwnership(email, id);\n\n    const alternatingRowStyle = { \"bg-light-bg2 dark:bg-dark-bg2\": index % 2 === 0 };\n    return (\n        <>\n            <div\n                className={cx(\n                    \"h-full py-2 pl-4\",\n                    alternatingRowStyle,\n                    \"border-l border-sectionborder dark:border-dark-sectionborder\"\n                )}>\n                <div title={name} className={\"truncate font-semibold\"}>\n                    {name}\n                </div>\n                <div className={\"font-mono leading-none\"}>{id}</div>\n            </div>\n            <div className={cx(\"flex items-center justify-center px-4\", alternatingRowStyle)}>\n                {updateOwnershipSaveIndicator}\n            </div>\n            <div className={cx(\"flex items-center justify-center pr-4\", alternatingRowStyle)}>\n                <ContentDropdownMenuItem\n                    variant={\"small\"}\n                    value={appOwner}\n                    onChange={(e: ChangeEvent<HTMLSelectElement>) => chooseAppOwner(e.target.value)}>\n                    {developers?.map(({ email }: { email: string }, index: number) => (\n                        <option value={email} key={index}>\n                            {email}\n                        </option>\n                    ))}\n                </ContentDropdownMenuItem>\n            </div>\n            <div\n                className={cx(\n                    \"flex items-center justify-center\",\n                    alternatingRowStyle,\n                    \"border-r border-sectionborder dark:border-dark-sectionborder\"\n                )}>\n                {num_shared}\n            </div>\n        </>\n    );\n};\n\nexport const orgAppsModal: ModalComponent = ({ modalId, spec }) => {\n    return (\n        <Modal title=\"Organisation Apps\" modalId={modalId} buttons={[{ text: \"Close\" }]}>\n            <OrgApps />\n        </Modal>\n    );\n};\n\nexport const OrgApps = () => {\n    const licenceKey = useSelector(getCurrentOrganisationLicenceKey);\n    const { data: apps, isLoading } = useQuery({\n        queryKey: [\"all-subscription-apps\", licenceKey],\n        queryFn: () => {\n            return loadOrgApps(licenceKey);\n        },\n    });\n\n    if (isLoading) {\n        return <LoadingSpinner />;\n    }\n    const capColors = \"bg-light-bg4 dark:border-dark-sectionborder dark:bg-dark-bg6 border-sectionborder\";\n    const sharedHeaderStyle = \"text-3xl border-t border-sectionborder py-4 \" + capColors;\n    return (\n        <div>\n            <p>All apps belonging to this organisation. You can change the ownership of individual apps below.</p>\n\n            <div className={\"mt-8 grid grid-cols-[minmax(0,1fr)_min-content_max-content_max-content]\"}>\n                {/*Table Headers*/}\n                <div className={cx(\"col-span-2 rounded-tl-xl border-l pl-4\", sharedHeaderStyle)}>App</div>\n                <div className={cx(sharedHeaderStyle)}>Owner</div>\n                <div className={cx(\"rounded-tr-xl border-r pr-4\", sharedHeaderStyle)}>Collaborators</div>\n                {apps?.map((app, index) => (\n                    <UpdateOwnerRow key={index} app={app} index={index} />\n                ))}\n                <div className={cx(\"col-span-4 h-4 rounded-b-xl border-r border-b border-l\", capColors)}></div>\n            </div>\n        </div>\n    );\n};\n","import React, { useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport moment from \"moment\";\nimport type { Figure } from \"react-plotly.js\";\nimport { ButtonGroup } from \"@/components/reusable/ButtonGroup\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport type { UsageData } from \"@/components/reusable/LineGraph\";\nimport { UsageGraph } from \"@/components/reusable/LineGraph\";\nimport { Heading } from \"@/components/reusable/Text\";\nimport { getIsIDE, getSubscription } from \"@/controllers/ide\";\nimport { getOrgUsage } from \"@/manager/api\";\nimport { getCurrentOrganisationLicenceKey } from \"@/manager/controller\";\nimport type { FullNavTarget } from \"@/router/navTypes\";\nimport { getUrlForNavTarget } from \"@/router/navigation\";\nimport type { AppId } from \"@/types\";\nimport { getUsage } from \"@/api\";\nimport { useRefreshValue, useUpdateEffect } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { AccountQuotas } from \"../Quotas\";\n\ninterface LegendTrace {\n    id?: string | number;\n    name?: string;\n}\n\ntype LegendClickFigure = Figure & {\n    curveNumber: number;\n    data: LegendTrace[];\n};\n\nexport const ComputeUsage = ({ quotas }: { quotas?: AccountQuotas | null }) => {\n    const subscription = useSelector(getSubscription);\n    const orgLicenceKey: string = useSelector(getCurrentOrganisationLicenceKey);\n    const [refresh, incrementRefreshValue] = useRefreshValue();\n    const [twoMonthsAgo] = useState(moment().subtract(2, \"months\"));\n    const [oneWeekAgo] = useState(moment().subtract(1, \"week\"));\n    const [oneDayAgo] = useState(moment().subtract(1, \"day\"));\n    const [startTime, setStartTime] = useState(twoMonthsAgo);\n    const [endTime] = useState(moment());\n\n    const inIde = useSelector(getIsIDE);\n\n    const onRefresh = useEvent(() => {\n        incrementRefreshValue();\n    });\n\n    const { isLoading, error, data } = useQuery({\n        queryKey: [\"usage-data\", orgLicenceKey, startTime, endTime],\n        queryFn: () => {\n            if (inIde) {\n                return getUsage(startTime, endTime, null);\n            } else {\n                return getOrgUsage(orgLicenceKey, startTime, endTime, null);\n            }\n        },\n    });\n\n    const queryClient = useQueryClient();\n    useUpdateEffect(() => {\n        queryClient.invalidateQueries({ queryKey: [\"usage-data\"] });\n    }, [refresh]);\n\n    const onStartChange = useEvent((m: moment.Moment) => {\n        setStartTime(m);\n        onRefresh();\n    });\n\n    let sharedUsageChart = <></>;\n\n    if (error) {\n        sharedUsageChart = <> We are unable to display usage data at this time</>;\n    } else {\n        let limit;\n        let limitHistoryHighlights: unknown[] = [];\n        let onLegendEntryClick: ((e: Figure) => void) | undefined;\n        let plotWidth = 650;\n\n        // TODO - onLegendEntryClick being IDE can change  when we have navigation in Manager Portal\n        //        But be aware we'll need to handle the case were a manager is not an IDE User somehow.\n        if (inIde) {\n            onLegendEntryClick = (e: Figure) => {\n                const figure = e as LegendClickFigure;\n                const name = figure.data[figure.curveNumber]?.name;\n                // Do nothing for deleted/unnamed traces or apps user doens't have access to\n                if (!name || (typeof name === \"string\" && name.startsWith(\"Deleted App\")) || name === \"Other Apps\") {\n                    return;\n                }\n                const appId = figure.data[figure.curveNumber]?.id;\n                if (typeof appId !== \"string\") return;\n                const navTarget = { type: \"CPU_USAGE\", appId: appId as AppId } as FullNavTarget;\n                const href = getUrlForNavTarget(navTarget);\n                window.open(href, \"_blank\");\n            };\n            plotWidth = 800;\n        }\n\n        // Ensure unnamed traces get unique labels like \"Deleted App 1\", \"Deleted App 2\", ...\n        let usageData = data?.shared?.app_traces ?? [];\n        let deletedAppCounter = 1;\n        usageData = usageData?.map((d: UsageData & { _deletedApp?: boolean }) => {\n            if (!d.name) {\n                d.name = `Deleted App ${deletedAppCounter++}`;\n                d._deletedApp = true;\n            }\n            return d;\n        });\n\n        if (localStorage.displayBoostLimit === \"true\") {\n            limit = data?.shared?.[\"limit\"];\n            limitHistoryHighlights = data?.shared?.limitedPeriods ?? [];\n        }\n        if (subscription?.plan === \"enterprise\") {\n            sharedUsageChart = (\n                <div className={\"flex w-full\"}>\n                    <UsageGraph\n                        yLabel={\"CPU time (seconds per second)\"}\n                        usageData={usageData}\n                        totalData={data?.total_trace}\n                        xMin={data?.shared?.xmin || startTime.utc().format(\"YYYY-MM-DDTHH:mm:ss[Z]\")}\n                        xMax={data?.shared?.xmax || endTime.utc().format(\"YYYY-MM-DDTHH:mm:ss[Z]\")}\n                        yMax={data?.shared?.ymax}\n                        startTime={startTime}\n                        alwaysShowLegend={true}\n                        onLegendEntryClick={onLegendEntryClick}\n                        onStartChange={onStartChange}\n                        legendPosition={\"right\"}\n                        plotWidth={plotWidth}\n                        isLoading={isLoading}\n                    />\n                </div>\n            );\n        } else {\n            sharedUsageChart = (\n                <div className={\"flex w-full\"}>\n                    <UsageGraph\n                        yLabel={\"Compute Units per Second\"}\n                        usageData={usageData}\n                        totalData={data?.shared?.total_trace}\n                        limit={limit}\n                        xMin={data?.shared?.xmin ?? startTime.utc().format(\"YYYY-MM-DDTHH:mm:ss[Z]\")}\n                        xMax={data?.shared?.xmax ?? endTime.utc().format(\"YYYY-MM-DDTHH:mm:ss[Z]\")}\n                        yMax={data?.shared?.ymax}\n                        startTime={startTime}\n                        alwaysShowLegend={true}\n                        onLegendEntryClick={onLegendEntryClick}\n                        // limitedPeriods={limitHistoryHighlights}\n                        // durationOptions={[\n                        //     { title: \"24 Hours\", value: oneDayAgo },\n                        //     { title: \"1 Week\", value: oneWeekAgo },\n                        //     { title: \"2 Months\", value: twoMonthsAgo },\n                        // ]}\n                        onStartChange={onStartChange}\n                        legendPosition={\"right\"}\n                        plotWidth={plotWidth}\n                        isLoading={isLoading}\n                    />\n                </div>\n            );\n        }\n    }\n\n    let downlinkUsageChart = <></>;\n\n    if (subscription?.plan === \"enterprise\" || subscription?.plan === \"dedicated\") {\n        if (error) {\n            downlinkUsageChart = <> We are unable to display downlink data at this time</>;\n        } else {\n            let onLegendEntryClick: ((e: Figure) => void) | undefined;\n            let plotWidth = 650;\n\n            let downlinks = data?.downlinks?.app_traces ?? [];\n            let deletedAppCounter = 1;\n            downlinks = downlinks?.map((d: UsageData & { _deletedApp?: boolean }) => {\n                if (!d.name) {\n                    d.name = `Deleted App ${deletedAppCounter++}`;\n                    d._deletedApp = true;\n                }\n                return d;\n            });\n\n            // TODO - onLegendEntryClick being IDE can change  when we have navigation in Manager Portal\n            //        But be aware we'll need to handle the case were a manager is not an IDE User somehow.\n            if (inIde) {\n                onLegendEntryClick = (e: Figure) => {\n                    const figure = e as LegendClickFigure;\n                    const name = figure.data[figure.curveNumber]?.name;\n                    // Do nothing for deleted/unnamed traces or apps user doens't have access to\n                    if (\n                        !name ||\n                        (typeof name === \"string\" && name.startsWith(\"Deleted App\")) ||\n                        name === \"Other Apps\"\n                    ) {\n                        return;\n                    }\n\n                    const appId = figure.data[figure.curveNumber]?.id;\n                    if (typeof appId !== \"string\") return;\n                    const navTarget = { type: \"CPU_USAGE\", appId: appId as AppId } as const;\n                    const href = getUrlForNavTarget(navTarget);\n                    window.open(href, \"_blank\");\n                };\n                plotWidth = 800;\n            }\n\n            downlinkUsageChart = (\n                <div className={\"flex w-full\"}>\n                    <UsageGraph\n                        yLabel={\"CPU time (seconds per second)\"}\n                        usageData={downlinks}\n                        totalData={data?.downlinks?.total_trace}\n                        xMin={data?.downlinks?.xmin || startTime.toDate()}\n                        xMax={data?.downlinks?.xmax || endTime.toDate()}\n                        yMax={data?.downlinks?.ymax}\n                        startTime={startTime}\n                        alwaysShowLegend={true}\n                        onLegendEntryClick={onLegendEntryClick}\n                        onStartChange={onStartChange}\n                        legendPosition={\"right\"}\n                        plotWidth={plotWidth}\n                        isLoading={isLoading}\n                    />\n                </div>\n            );\n        }\n    }\n\n    let body = <></>;\n    switch (subscription?.plan) {\n        case \"enterprise\":\n            body = (\n                <>\n                    <h3 className={\"mt-10 mb-5 text-4xl font-medium\"}>Dedicated CPU Time</h3>\n                    <ButtonGroup\n                        options={[\n                            { title: \"24 Hours\", value: oneDayAgo },\n                            { title: \"1 Week\", value: oneWeekAgo },\n                            { title: \"2 Months\", value: twoMonthsAgo },\n                        ]}\n                        selectedVariant={\"primary\"}\n                        selectedOption={startTime}\n                        onClick={(selection) => onStartChange(selection)}\n                    />\n                    <div>\n                        <Heading className={\"!mt-0\"} level={2}>\n                            History\n                        </Heading>\n                        {downlinkUsageChart}\n                    </div>\n                </>\n            );\n            break;\n        case \"dedicated\":\n            body = (\n                <>\n                    <h1 className={\"mt-10 mb-8 text-4xl font-medium\"}>Usage History</h1>\n                    <ButtonGroup\n                        className={\"my-5\"}\n                        options={[\n                            { title: \"24 Hours\", value: oneDayAgo },\n                            { title: \"1 Week\", value: oneWeekAgo },\n                            { title: \"2 Months\", value: twoMonthsAgo },\n                        ]}\n                        selectedVariant={\"primary\"}\n                        selectedOption={startTime}\n                        onClick={(selection) => onStartChange(selection)}\n                    />\n                    <div className={\"flex flex-col gap-12 big-account-charts:flex-row\"}>\n                        <div>\n                            <Heading className={\"!mt-12 !mb-0\"} level={2}>\n                                Dedicated CPU Time\n                            </Heading>\n                            {downlinkUsageChart}\n                        </div>\n                        <div>\n                            <Heading className={\"!mt-12 !mb-0\"} level={2}>\n                                Shared CPU Time\n                            </Heading>\n                            {sharedUsageChart}\n                        </div>\n                    </div>\n                </>\n            );\n            break;\n\n        default:\n            body = (\n                <>\n                    {quotas && (\n                        <>\n                            <Heading level={1}>\n                                Compute Usage{\" \"}\n                                <HelpLink\n                                    iconRight\n                                    inline\n                                    url={\"/docs/plans-and-accounts/account-management#compute-usage\"}></HelpLink>\n                            </Heading>\n                            <ButtonGroup\n                                className={\"my-5\"}\n                                options={[\n                                    { title: \"24 Hours\", value: oneDayAgo },\n                                    { title: \"1 Week\", value: oneWeekAgo },\n                                    { title: \"2 Months\", value: twoMonthsAgo },\n                                ]}\n                                selectedVariant={\"primary\"}\n                                selectedOption={startTime}\n                                onClick={(selection) => onStartChange(selection)}\n                            />\n                            <div>\n                                <Heading className={\"!mt-0\"} level={2}>\n                                    History\n                                </Heading>\n                                {sharedUsageChart}\n                            </div>\n                        </>\n                    )}\n                </>\n            );\n    }\n    return body;\n};\n\nexport default ComputeUsage;\n","import React from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { getUserUiScale } from \"@/controllers/user.ts\";\nimport { remToPixelMultiplier } from \"@/theme/ThemeProvider.tsx\";\nimport { useIsDark } from \"@/theme/styles\";\nimport LazyPlot from \"@/util/lazy/plotly\";\n\nexport interface DBQuotaUseBarChartProps {\n    title: string;\n    data: any;\n    limit?: number;\n}\n\nexport const DBQuotaUseBarChart = ({ title, data, limit }: DBQuotaUseBarChartProps) => {\n    const uiScale = useSelector(getUserUiScale);\n    const traces = [];\n    const traceMetadata = { type: \"bar\", orientation: \"h\", hoverinfo: \"x+name\", opacity: 0.6 };\n    for (const d of data) {\n        traces.push({ ...d, ...traceMetadata });\n    }\n    return (\n        <div className=\"flex h-fit items-center py-4\">\n            <LazyPlot\n                data={traces}\n                layout={{\n                    colorway: [\n                        \"#1BB0EE\",\n                        \"#8DD5EF\",\n                        \"#F5D470\",\n                        \"#FFB347\",\n                        \"#FF8C00\",\n                        \"#FF763F\",\n                        \"#FF3F46\",\n                        \"#AF3859\",\n                        \"#EA4FB1\",\n                        \"#312F6F\",\n                    ],\n                    title: {\n                        text: title,\n                        x: 0,\n                        font: {\n                            size: remToPixelMultiplier(1.2, uiScale),\n                            weight: \"600\",\n                        },\n                        pad: { b: remToPixelMultiplier(0.3, uiScale) },\n                    },\n                    font: {\n                        family: \"Poppins, sans-serif\",\n                        size: remToPixelMultiplier(1, uiScale),\n                        color: useIsDark() ? \"#dddddd\" : \"#515151\",\n                    },\n                    plot_bgcolor: \"transparent\",\n                    paper_bgcolor: \"rgba(0, 0, 0, 0)\",\n                    bargap: 0,\n                    showlegend: false,\n                    margin: { t: 30, r: 20, b: 20, l: 10 },\n                    barmode: \"stack\",\n                    height: 70,\n                    width: 865,\n                    hoverlabel: { namelength: 50 },\n                    xaxis: {\n                        zeroline: false,\n                        fixedrange: true,\n                        range: [0, limit],\n                        linecolor: \"rgba(0, 0, 0, 0)\",\n                        gridcolor: \"#b4b4b4\",\n                    },\n                    yaxis: {\n                        visible: false,\n                        fixedrange: true,\n                    },\n                    barcornerradius: 4,\n                }}\n                config={{\n                    displayModeBar: false,\n                }}\n            />\n        </div>\n    );\n};\n\nexport interface BoostBarChartProps {\n    boostMaxValue: number;\n    boostCurrentValue: number;\n    limitedState: boolean;\n}\n\nexport const BoostBarChart = ({ boostMaxValue, boostCurrentValue, limitedState }: BoostBarChartProps) => {\n    let patternShape;\n    let hoverInfo;\n    let title = `Boost`;\n    let backgroundColour = \"rgba(184, 184, 184, 0.3)\";\n    if (limitedState) {\n        patternShape = \"/\";\n        title = \"Boost <br> Recharging\";\n        backgroundColour = \"rgba(252, 000, 000,  0.3)\";\n    } else {\n        hoverInfo = \"y\";\n    }\n    return (\n        <LazyPlot\n            data={[\n                {\n                    y: [boostMaxValue - boostCurrentValue],\n                    type: \"bar\",\n                    hoverinfo: hoverInfo,\n                    opacity: 0.6,\n                    marker: {\n                        pattern: {\n                            shape: patternShape,\n                        },\n                    },\n                },\n            ]}\n            layout={{\n                title: {\n                    text: title,\n                    x: 0.5,\n                    y: 0.1,\n                    font: { size: 12 },\n                    pad: { b: 3 },\n                },\n                plot_bgcolor: backgroundColour,\n                paper_bgcolor: \"rgba(0, 0, 0, 0)\",\n                bargap: 0,\n                width: 70,\n                showlegend: false,\n                margin: { t: 50, r: 15, b: 80, l: 15 },\n                xaxis: {\n                    visible: false,\n                    fixedrange: true,\n                },\n                yaxis: {\n                    range: [0, boostMaxValue],\n                    visible: false,\n                    fixedrange: true,\n                },\n            }}\n            config={{\n                displayModeBar: false,\n            }}\n        />\n    );\n};\n","import type ReactTabulator from \"react-tabulator\";\nimport { lazyComponent } from \".\";\n\nconst LazyReactTabulator = lazyComponent<typeof ReactTabulator>(async () => {\n    // use tabulator-tables css because the css for react-tabulator doesn't match the version of react tabulator they are using\n    // @ts-ignore\n    import(\"tabulator-tables/dist/css/tabulator.min.css\");\n    // @ts-ignore\n    // import(\"react-tabulator/lib/styles.css\");\n\n    const ReactTabulator = (await import(\"react-tabulator\")).ReactTabulator;\n    return { default: ReactTabulator };\n});\n\nexport default LazyReactTabulator;\n","import React from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { DBQuotaUseBarChart } from \"@/components/reusable/BarChart\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport { getIsIDE, getSubscription } from \"@/controllers/ide\";\nimport { getOrgDBQuotaUsageData } from \"@/manager/api\";\nimport { getCurrentOrganisationLicenceKey } from \"@/manager/controller\";\nimport { cx, useIsDark } from \"@/theme/styles\";\nimport { getQuotasUseBreakdown } from \"@/api\";\nimport LazyReactTabulator from \"@/util/lazy/react-tabulator\";\n\nconst bytesToMb = (bytes: number) => {\n    return Math.round(bytes / 100_000) / 10;\n};\n\nexport interface DBQuotaUseTableProps {\n    data: any;\n    parameter: string;\n}\n\nexport const DBQuotaUseTable = ({ data, parameter }: DBQuotaUseTableProps) => {\n    const sortedData = [...data].sort((a, b) => b.x - a.x);\n\n    const columns = [\n        { title: \"Name\", field: \"tableName\", widthGrow: 3 },\n        {\n            title: \"Apps\",\n            field: \"apps\",\n            widthGrow: 8,\n            formatter: (cell: any) => {\n                const apps = cell.getValue() ?? [];\n                return (\n                    apps\n                        .map((a: any) => {\n                            const mappingNames = (a.mappings ?? []).map((m: any) => m.name).join(\", \");\n                            return mappingNames ? `${a.name} (${mappingNames})` : a.name;\n                        })\n                        .join(\", \") || \"-\"\n                );\n            },\n        },\n    ];\n\n    if (parameter === \"Rows\") {\n        columns.push({ title: \"Rows\", field: \"x\", widthGrow: 2 });\n    } else {\n        columns.push({ title: \"Storage (MB)\", field: \"x\", widthGrow: 2 });\n    }\n\n    const options = {\n        pagination: true,\n        paginationSize: 5,\n    };\n\n    return (\n        <LazyReactTabulator\n            columns={columns}\n            data={sortedData}\n            options={options}\n            className={cx(\"tabulator\", useIsDark() ? \"dark\" : \"\")}\n        />\n    );\n};\n\nexport const DatabaseUsageBreakdown = ({ quotas }: { quotas: any }) => {\n    const orgLicenceKey: string = useSelector(getCurrentOrganisationLicenceKey);\n    const subscription = useSelector(getSubscription);\n    // TODO: We're not sure whether or not to show database usage to enterprise users.\n    //       There's currently no concept of an org or managers in enterprise.\n    //       So for now we're not showing it to enterprise users at all.\n    const allowedToView = subscription?.isManager || typeof subscription?.plan === \"undefined\"; //  || subscription?.plan === \"enterprise\"\n    const inIDE = useSelector(getIsIDE);\n\n    const { isLoading, error, data } = useQuery({\n        queryKey: [\"database-usage\", orgLicenceKey],\n        queryFn: () => {\n            if (inIDE) {\n                return getQuotasUseBreakdown();\n            } else {\n                return getOrgDBQuotaUsageData(orgLicenceKey);\n            }\n        },\n    });\n\n    let body = (\n        <div>\n            <div className={\"flex flex-col gap-8 big-account:max-w-fit big-account:flex-row\"}>\n                <div className={\"flex-1\"}>\n                    <Heading className={\"!m-0\"} level={2}>\n                        Rows\n                    </Heading>\n                    {subscription?.plan === \"enterprise\" || subscription?.plan === \"dedicated\" ? (\n                        <DBQuotaUseBarChart title={\"Rows\"} data={data?.rowData?.traces ?? []}></DBQuotaUseBarChart>\n                    ) : (\n                        <>\n                            <p>\n                                {quotas[\"db-rows\"] === \"infinite\"\n                                    ? \"Unlimited\"\n                                    : quotas[\"db-rows\"]?.current_token_count != null\n                                      ? `${quotas[\"db-rows\"].current_token_count} rows remaining`\n                                      : \"Unknown\"}\n                            </p>\n                            <DBQuotaUseBarChart\n                                title={\"Rows\"}\n                                data={data?.rowData?.traces ?? []}\n                                limit={quotas[\"db-rows\"]?.[\"bucket-size\"] ?? 50_000}></DBQuotaUseBarChart>\n                        </>\n                    )}\n                    <DBQuotaUseTable data={data?.rowData?.traces ?? []} parameter=\"Rows\"></DBQuotaUseTable>\n                </div>\n                <div className={\"flex-1\"}>\n                    <Heading className={\"!m-0\"} level={2}>\n                        Data Storage\n                    </Heading>\n                    {subscription?.plan === \"enterprise\" || subscription?.plan === \"dedicated\" ? (\n                        <DBQuotaUseBarChart\n                            title={\"Storage (MB)\"}\n                            data={data?.bytesData?.traces ?? []}></DBQuotaUseBarChart>\n                    ) : (\n                        <>\n                            <p>\n                                {quotas[\"db-bytes\"] === \"infinite\"\n                                    ? \"Unlimited\"\n                                    : quotas[\"db-bytes\"]?.current_token_count != null\n                                      ? `${bytesToMb(quotas[\"db-bytes\"].current_token_count)} MB remaining`\n                                      : \"Unknown\"}\n                            </p>\n                            <DBQuotaUseBarChart\n                                title={\"Storage (MB)\"}\n                                data={data?.bytesData?.traces ?? []}\n                                limit={\n                                    quotas[\"db-bytes\"]?.[\"bucket-size\"]\n                                        ? quotas[\"db-bytes\"]?.[\"bucket-size\"] / 1_000_000\n                                        : 100\n                                }></DBQuotaUseBarChart>\n                        </>\n                    )}\n                    <DBQuotaUseTable data={data?.bytesData?.traces ?? []} parameter=\"Storage (MB)\"></DBQuotaUseTable>\n                </div>\n            </div>\n            {data?.time_stamp && (\n                <Text className={\"pt-4 italic\"} level={3}>\n                    This database data was collected at {data?.time_stamp}\n                </Text>\n            )}\n        </div>\n    );\n\n    return (\n        <div className=\"m-0 list-none\">\n            <Heading level={1}>\n                Database{\" \"}\n                <HelpLink iconRight inline url={\"/docs/plans-and-accounts/account-management#database\"}></HelpLink>\n            </Heading>\n            {!allowedToView ? (\n                <>Database Usage is currently only available for managers.</>\n            ) : isLoading ? (\n                <LoadingSpinner />\n            ) : error ? (\n                <p>We are unable to display data at this time</p>\n            ) : data ? (\n                body\n            ) : null}\n        </div>\n    );\n};\n\nexport default DatabaseUsageBreakdown;\n","import React from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport { getSubscription, getUser } from \"@/controllers/ide\";\nimport { getEnabledAgentTypes } from \"@/controllers/user-agent-types\";\nimport { AiCreditBar } from \"./usage/AiCreditBar\";\nimport ComputeUsage from \"./usage/ComputeUsage\";\nimport DatabaseUsageBreakdown from \"./usage/DatabaseUsage\";\n\nexport interface QuotaProps {\n    current_token_count: number;\n    \"bucket-size\": number;\n}\n\nexport interface AiCreditQuota {\n    current_token_count?: number | null;\n    \"bucket-size\"?: number;\n    \"refill-rate\"?: number;\n    \"infinite?\"?: boolean;\n    // The org's subscription has lapsed: the proxy refuses every request (no personal\n    // fallback), and the server reports a zero bucket alongside this flag.\n    lapsed?: boolean;\n}\n\nexport interface AccountQuotas {\n    email: \"infinite\" | QuotaProps;\n    \"db-rows\": \"infinite\" | QuotaProps;\n    \"db-bytes\": \"infinite\" | QuotaProps;\n    // NB \"AI credit\" is an arbitrary unit; it is deliberately never a dollar figure.\n    \"ai-credits\"?: AiCreditQuota;\n}\n\nexport interface AccountLimits {\n    \"image-size\": number;\n    \"build-time\": number;\n}\n\nexport interface QuotasAndLimitsProps {\n    quotas?: AccountQuotas | null;\n    limits?: AccountLimits | null;\n}\n\n\nexport const Quotas = ({ quotasAndLimits }: { quotasAndLimits?: QuotasAndLimitsProps }) => {\n    const subscription = useSelector(getSubscription);\n    const user = useSelector(getUser);\n    const enabledAgentTypes = useSelector(getEnabledAgentTypes);\n    const aiCredits = quotasAndLimits?.quotas?.[\"ai-credits\"];\n\n    const emailQuota = (\n        <div>\n            <Heading level={1}>Email Quota</Heading>{\" \"}\n            {quotasAndLimits?.quotas?.email === \"infinite\" ? (\n                <p>Unlimited</p>\n            ) : (\n                <>\n                    {quotasAndLimits?.quotas?.email ? (\n                        <div>\n                            <p>{quotasAndLimits.quotas.email.current_token_count} emails remaining</p>\n                            <p>\n                                Your email quota will reset to {quotasAndLimits.quotas.email[\"bucket-size\"]} on the 1st\n                                of each month\n                            </p>\n                        </div>\n                    ) : (\n                        <p>Unknown</p>\n                    )}\n                </>\n            )}\n        </div>\n    );\n\n    const customPackageLimits = (\n        <div>\n            <Heading level={1}>\n                Custom Package Limits <HelpLink iconRight inline url={\"/docs/server/custom-packages\"}></HelpLink>\n            </Heading>\n            <p>\n                Size:{\" \"}\n                {quotasAndLimits?.limits?.[\"image-size\"] != null\n                    ? (quotasAndLimits.limits[\"image-size\"] / 1_000_000).toFixed(0)\n                    : \"Unknown\"}{\" \"}\n                MB\n            </p>\n            <p>\n                Install time:{\" \"}\n                {quotasAndLimits?.limits?.[\"build-time\"] != null\n                    ? (quotasAndLimits.limits[\"build-time\"] / 60_000).toFixed(0)\n                    : \"Unknown\"}{\" \"}\n                minutes\n            </p>\n        </div>\n    );\n\n    const quotas = (\n        <>\n            <h3 className={\"mt-10 mb-5 text-4xl font-medium\"}>Quotas</h3>\n            {enabledAgentTypes.includes(\"codex-anvil\") && aiCredits && <AiCreditBar quota={aiCredits} />}\n            {emailQuota}\n            {subscription?.plan !== \"dedicated\" && customPackageLimits}\n        </>\n    );\n\n    return quotasAndLimits && user?.ideConfig?.enableAccounting ? (\n        <div className={\"@container dark:text-grey-0\"}>\n            <div>\n                {subscription?.plan !== \"enterprise\" && quotas}\n                <ComputeUsage quotas={quotasAndLimits.quotas} />\n                <DatabaseUsageBreakdown quotas={quotasAndLimits.quotas} />\n            </div>\n\n            <Text className={\"pt-12\"} level={3}>\n                These numbers are approximate, and updates may be delayed. If something doesn't look right, please\n                contact support@anvil.works.\n            </Text>\n        </div>\n    ) : (\n        <></>\n    );\n};\n\nexport default Quotas;\n","import { Heading } from \"@/components/reusable/Text\";\nimport { cx } from \"@/theme/styles\";\nimport type { AiCreditQuota } from \"../Quotas\";\n\n// The credit count is an arbitrary unit, so a progress bar (not a number with a unit)\n// is the whole story: how much of your allowance is left.\nexport const AiCreditBar = ({ quota }: { quota: AiCreditQuota }) => {\n    const max = quota[\"bucket-size\"] ?? 0;\n    const current = Math.max(0, Math.min(max, quota.current_token_count ?? 0));\n    const fraction = max > 0 ? (1 - current / max) : 1;\n    return (\n        <div>\n            <Heading level={1}>AI Credit</Heading>\n            {quota[\"infinite?\"] ? (\n                <p>Unlimited</p>\n            ) : quota.lapsed ? (\n                <p>Your organisation's subscription has lapsed, so included AI credit is paused.</p>\n            ) : (\n                <>\n                    <div\n                        aria-label={\"AI credits used\"}\n                        aria-valuemax={100}\n                        aria-valuemin={0}\n                        aria-valuenow={Math.round(fraction * 100)}\n                        className={cx(\"mt-2 h-4 w-full max-w-140 overflow-hidden rounded-full bg-light-bg3\", \"dark:bg-dark-bg3\")}\n                        role=\"progressbar\">\n                        <div\n                            className={\"h-full rounded-full bg-primary transition-[width]\"}\n                            style={{ width: `${Math.round(fraction * 100)}%` }} />\n                    </div>\n                    <p className={\"mt-1\"}>\n                        You have used {Math.round(fraction * 100)}% of your included AI credit.\n                        {(quota[\"refill-rate\"] ?? 0) > 0 ? \" Credit refills continuously.\" : \"\"}\n                    </p>\n                </>\n            )}\n        </div>\n    );\n};\n","import React, { useMemo, useRef } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { faGripLines, faTimes } from \"@fortawesome/pro-light-svg-icons\";\nimport { faPlus } from \"@fortawesome/pro-regular-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { sortBy } from \"lodash-es\";\nimport { Button } from \"@/components/reusable/Button\";\nimport DropdownMenu, { MenuItems } from \"@/components/reusable/DropdownMenu\";\nimport { CheckBox } from \"@/components/reusable/Forms\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { TTable } from \"@/components/tabs/database/types\";\nimport { SortArray, canSort, getSort } from \"@/controllers/db_new\";\nimport { State } from \"@/types\";\nimport { CurrentTable } from \"@/types/database\";\nimport { useDrag, useDrop } from \"@/util/dnd\";\nimport { useMergeRefs, useStateWithReset } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \"..\";\nimport Modal from \"../Modal\";\n\ninterface SortModalSpec {\n    table: TTable;\n}\n\nconst useSortArrayWithColSpec = (currentTable: CurrentTable) => {\n    const { id: tableId, columns } = currentTable;\n    const sortArray = useSelector((state: State) => getSort(state, tableId));\n    return useMemo(() => {\n        return sortArray\n            .map(({ colId, ascending }, i) => {\n                const colSpec = columns[colId];\n                if (!colSpec) return false; // stale\n                const { name, type } = columns[colId];\n                if (!canSort(type)) return false; // also stale\n                return { colId, ascending, name, type };\n            })\n            .filter(Boolean);\n    }, [sortArray, currentTable]);\n};\n\ninterface DragItem {\n    index: number;\n    id: string;\n    type: string;\n}\n\nconst SortRow = ({\n    name,\n    colId,\n    ascending,\n    table,\n    index,\n    localColumnSorting,\n    moveSort,\n}: ReturnType<typeof useSortArrayWithColSpec>[number] & {\n    table: TTable;\n    index: number;\n    localColumnSorting: SortArray;\n    moveSort: (dragIndex: number, hoverIndex: number) => void;\n}) => {\n    const { updateColumnSorting, removeColumnSorting, setColumnSorting } = table.options.meta!;\n    const onAscendingChange = useEvent(() => {\n        updateColumnSorting(colId, !ascending);\n    });\n\n    const ref = useRef<HTMLDivElement>(null);\n\n    const [, drop] = useDrop({\n        accept: \"sort\",\n        onHover(item: DragItem, event) {\n            if (!ref.current) {\n                return;\n            }\n            const dragIndex = item.index;\n            const hoverIndex = index;\n\n            // Don't replace items with themselves\n            if (dragIndex === hoverIndex) {\n                return;\n            }\n\n            // Determine rectangle on screen\n            const hoverBoundingRect = ref.current?.getBoundingClientRect();\n\n            // Get vertical middle\n            const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;\n\n            // Determine mouse position\n            const clientY = event.clientY;\n\n            // Get pixels to the top\n            const hoverClientY = clientY - hoverBoundingRect.top;\n\n            // Only perform the move when the mouse has crossed half of the items height\n            // When dragging downwards, only move when the cursor is below 50%\n            // When dragging upwards, only move when the cursor is above 50%\n\n            // Dragging downwards\n            if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {\n                return;\n            }\n\n            // Dragging upwards\n            if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {\n                return;\n            }\n\n            // Time to actually perform the action\n            moveSort(dragIndex, hoverIndex);\n\n            // Note: we're mutating the monitor item here!\n            // Generally it's better to avoid mutations,\n            // but it's good here for the sake of performance\n            // to avoid expensive index searches.\n            item.index = hoverIndex;\n        },\n        onDrop() {\n            setColumnSorting(localColumnSorting.map(({ colId, ascending }) => ({ colId, ascending })));\n        },\n        dropEffect: \"move\",\n    });\n\n    const [{ isDragging }, drag, previewRef] = useDrag({\n        type: \"sort\",\n        item: { id: colId, index },\n    });\n\n    const opacity = isDragging ? 0 : 1;\n\n    const mergedRefs = useMergeRefs(drop, previewRef, ref);\n\n    return (\n        <div ref={mergedRefs} className=\"relative rounded-sm p-4\">\n            <div className=\"flex items-center gap-6\" style={{ opacity }}>\n                <Button ref={drag} small linkClassName=\"cursor-move!\">\n                    <FontAwesomeIcon icon={faGripLines} fixedWidth />\n                </Button>\n                <span className=\"w-1/3 grow truncate text-lg\">\n                    sort by <strong>{name}</strong>\n                </span>\n                <CheckBox\n                    className=\"flex items-center justify-center text-lg! font-normal\"\n                    checked={ascending}\n                    onChange={onAscendingChange}>\n                    ascending\n                </CheckBox>\n                <Button small onClick={() => removeColumnSorting(colId)} variant=\"hidden\">\n                    <FontAwesomeIcon icon={faTimes} fixedWidth />\n                </Button>\n            </div>\n        </div>\n    );\n};\n\nexport const SortModalContent = ({ table }: { table: TTable }) => {\n    const { currentTable, columnSorting, updateColumnSorting } = table.options.meta!;\n    const { columns } = currentTable;\n    const namedSortArray = useSortArrayWithColSpec(currentTable);\n\n    const remainingCols = useMemo(() => {\n        const alreadySorted = columnSorting.map(({ colId }) => colId);\n        const rv: MenuItems = [];\n        for (const [colId, { type, name }] of Object.entries(columns)) {\n            if (!canSort(type)) continue;\n            if (alreadySorted.includes(colId)) continue;\n            rv.push([name, () => onAddSort(colId)]);\n        }\n        if (rv.length) return sortBy(rv, [0]);\n        return null;\n    }, [columnSorting]);\n\n    const onAddSort = useEvent((colId: string) => {\n        updateColumnSorting(colId, true);\n    });\n\n    const [localColumnSorting, setLocalColumnSorting] = useStateWithReset(namedSortArray);\n    const moveSort = useEvent((dragIndex: number, hoverIndex: number) => {\n        setLocalColumnSorting((prevColumnSorting) => {\n            const [dragItem, hoverItem] = [prevColumnSorting[dragIndex], prevColumnSorting[hoverIndex]];\n            const newColumnSorting = [...prevColumnSorting];\n            newColumnSorting[dragIndex] = hoverItem;\n            newColumnSorting[hoverIndex] = dragItem;\n            return newColumnSorting;\n        });\n    });\n\n    return (\n        <div className=\"flex w-160 min-w-96 flex-col gap-4\">\n            {localColumnSorting.length ? (\n                <div className=\"flex flex-col\">\n                    {localColumnSorting.map((props, i) => (\n                        <SortRow\n                            key={props.colId}\n                            table={table}\n                            index={i}\n                            localColumnSorting={localColumnSorting}\n                            moveSort={moveSort}\n                            {...props}\n                        />\n                    ))}\n                </div>\n            ) : null}\n            {remainingCols ? (\n                <DropdownMenu\n                    align=\"left\"\n                    render={(showMenu, anchor) => (\n                        <div className=\"\">\n                            <Button small onClick={(e) => showMenu(null, e.currentTarget)} icon={faPlus}>\n                                Add Sort Field\n                            </Button>\n                            {anchor}\n                        </div>\n                    )}\n                    items={() => remainingCols}\n                />\n            ) : (\n                <Text>All columns have been sorted</Text>\n            )}\n        </div>\n    );\n};\n\nconst SortModal: ModalComponent<SortModalSpec> = ({ modalId, spec: { table } }) => (\n    <Modal size={\"small\"} modalId={modalId} title={\"Sorted Fields\"}>\n        <SortModalContent table={table} />\n    </Modal>\n);\n\nexport default SortModal;\n","import React from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faBug, faCaretDown, faCaretRight, faCodeBranch, faPlus } from \"@fortawesome/free-solid-svg-icons\";\nimport { faCloudUpload } from \"@fortawesome/pro-regular-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { isEmpty } from \"lodash-es\";\nimport { NoodlePane } from \"@/components/bottom_panel/History\";\nimport { useOrgType } from \"@/components/modals/account/Subscription\";\nimport { Accordion } from \"@/components/reusable/Accordion\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { PublishCTA } from \"@/components/reusable/CollapsibleCTA\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { ModalButton } from \"@/components/reusable/SharedComponents\";\nimport { Text } from \"@/components/reusable/Text\";\nimport UpgradeBadge from \"@/components/reusable/UpgradeBadge\";\nimport { getAppId } from \"@/controllers/app\";\nimport { getAppCommitId } from \"@/controllers/app/history\";\nimport {\n    allEnvironmentSavesComplete,\n    checkForStagingEnvironments,\n    confirmLeaveUnsavedEnvironment,\n    createEnvironment,\n    deleteEnvironment,\n    getCategorisedEnvironments,\n    getNewEnvironmentURL,\n    getSelectedEnvironmentId,\n    hasServerKeys,\n    hasUplinkKeys,\n    loadEnvironments,\n    publishApp,\n    saveEnvironment,\n    setSelectedEnvironmentId,\n} from \"@/controllers/environments\";\nimport { confirm, modal, modalReturn } from \"@/controllers/modals\";\nimport { claimAchievement } from \"@/controllers/user.ts\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { AnvilDispatch, AppEnvironment, State } from \"@/types\";\nimport type { CommitHistory } from \"@/types/app-history\";\nimport { waitFor } from \"@/util\";\nimport { useFeatureSupported } from \"@/util/features\";\nimport { useEffectAsync } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \"..\";\nimport Modal from \"../Modal\";\nimport { EnvironmentBody } from \"./EnvironmentBody\";\nimport { EnvironmentHeader } from \"./EnvironmentHeader\";\n\ntype EnvClasses = \"expandable\";\n\nexport const useStyles = makeStyles<void, EnvClasses>()((theme, _props, classes) => ({\n    expandable: {},\n    settingRow: {\n        display: \"flex\",\n        padding: \"1rem 0\",\n        \"&:not(:last-child)\": {\n            borderBottom: \"1px solid \" + theme.palette.bg2.toString(),\n        },\n        [`&.${classes.expandable}`]: {\n            cursor: \"pointer\",\n        },\n        [`&.${classes.expandable}:hover`]: {\n            background: theme.palette.bg0.darken(0.02).toString(),\n        },\n    },\n    settingName: {\n        fontWeight: \"bold\",\n        width: \"18rem\",\n        textAlign: \"right\",\n        paddingRight: \"2rem\",\n        flex: \"0 0 auto\",\n        //paddingTop: 3,\n    },\n    settingBody: {\n        width: 0,\n        flex: \"1 0 auto\",\n    },\n    settingDescription: {\n        padding: \"1rem 0\",\n        color: theme.palette.fg1.alpha(0.2).toString(),\n    },\n}));\n\nexport const environmentStyles = useStyles;\n\nexport const migrationConfirmContent = (\n    <div>\n        To make this change, you must{\" \"}\n        <a href=\"https://anvil.works/docs/deployment/environments#migrating-apps-from-the-classic-editor\">\n            migrate your app to use Environments\n        </a>\n        . Once you have done this, you will only be able to publish your app using the new Anvil Editor. You will still\n        be able to edit your app in the classic Editor. Do you wish to continue?\n    </div>\n);\n\nconst isBlank = (env: AppEnvironment) => {\n    return !env.url && !hasServerKeys(env) && !env.run_scheduled_tasks;\n};\n\nconst getEnvironmentHeadCommitId = (commitHistory: CommitHistory | undefined, env: AppEnvironment) =>\n    (env.version?.ref && commitHistory?.refs[env.version.ref]?.oid) || env.version?.[\"commit-id\"];\n\nexport const useSelectVersion = (commitHistory: CommitHistory | undefined) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    return useEvent(async (env: AppEnvironment) => {\n        const initialCommitId = getEnvironmentHeadCommitId(commitHistory, env);\n        const selection = await dispatch(modal(\"appHistory\", { initialCommitId }));\n        if (selection) {\n            let version;\n            if (selection.branch) {\n                version = { ref: \"refs/heads/\" + selection.branch };\n            } else if (selection.tag) {\n                version = { ref: \"refs/tags/\" + selection.tag };\n            } else {\n                version = { \"commit-id\": selection.commitId };\n            }\n            await dispatch(saveEnvironment(env, { version }));\n            await dispatch(claimAchievement(\"publishedSpecificAppVersion\"));\n            await dispatch(checkForStagingEnvironments());\n        }\n    });\n};\n\ninterface AppVersionRowProps {\n    env: AppEnvironment;\n    labels: unknown[];\n    setExpansions: React.Dispatch<React.SetStateAction<Record<string, boolean>>>;\n    expansions: Record<string, boolean>;\n    classes: Record<string, string>;\n    selectVersion: (env: AppEnvironment) => Promise<void>;\n    commitHistory?: CommitHistory;\n}\n\nexport const AppVersionRow = ({\n    setExpansions,\n    expansions,\n    classes,\n    selectVersion,\n    commitHistory,\n    env,\n}: AppVersionRowProps) => {\n    const version = env.version;\n    const versionCommitId = version?.[\"commit-id\"];\n    const branchRef = version?.ref;\n    const headCommitId = getEnvironmentHeadCommitId(commitHistory, env);\n    const isMaster = branchRef === \"refs/heads/master\";\n    const branchExists = !!(branchRef && commitHistory?.refs[branchRef]);\n    return (\n        <div\n            className={cx(classes.settingRow, classes.expandable)}\n            onClick={() => setExpansions((e) => ({ appVersion: !e[\"appVersion\"] }))}>\n            <div className={classes.settingName} style={{ paddingTop: \"1rem\" }}>\n                App version:\n            </div>\n            <div className={classes.settingBody}>\n                <div className={classes.settingDescription}>\n                    <FontAwesomeIcon fixedWidth={true} icon={expansions[\"appVersion\"] ? faCaretDown : faCaretRight} />{\" \"}\n                    This link will load{\" \"}\n                    {isMaster ? (\n                        <>\n                            the latest version (<code>master</code> branch)\n                        </>\n                    ) : branchExists && branchRef ? (\n                        <>\n                            the <code>{branchRef.replace(/^refs\\/heads\\//, \"\")}</code> branch\n                        </>\n                    ) : (\n                        \"a specific version\"\n                    )}{\" \"}\n                    of your app\n                </div>\n                {expansions[\"appVersion\"] && (\n                    <>\n                        <div>\n                            <NoodlePane\n                                className=\"overflow-y-hidden pt-0!\"\n                                commits={(commitHistory?.versions ?? []).filter(\n                                    (v) => v.v === headCommitId || v.v === versionCommitId\n                                )}\n                                headCommitId={headCommitId}\n                                readOnly={true}\n                            />\n                        </div>\n                        <div>\n                            <ModalButton onClick={() => selectVersion(env)}>\n                                <FontAwesomeIcon icon={faCodeBranch} /> Link to a different version...\n                            </ModalButton>\n                        </div>\n                    </>\n                )}\n            </div>\n        </div>\n    );\n};\n\nconst EnvironmentsModal: ModalComponent = ({ modalId }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const appId = useSelector(getAppId);\n    if (!appId) {\n        throw new Error(\"App not loaded\");\n    }\n    const environments = useSelector(getCategorisedEnvironments);\n    const allowRestrictedEnvironmentUpdates = useSelector(\n        (state: State) => !!state.app?.allow_restricted_environment_updates\n    );\n    const selectedEnvironmentId = useSelector(getSelectedEnvironmentId);\n    const supportsMultipleEnvironments = useFeatureSupported(\"multiple-environments\");\n    const headCommit = useSelector(getAppCommitId);\n\n    // Every time this modal is opened, reload the environments.\n    useEffectAsync(async () => {\n        await dispatch(loadEnvironments());\n    }, []);\n\n    const sortedEnvironments = environments.sorted;\n    const isEnvironmentReadOnly = (env?: AppEnvironment) => !!env?.restricted && !allowRestrictedEnvironmentUpdates;\n\n    const onCreateEnvironment = useEvent(async () => {\n        if (environments?.real.length === 0 || supportsMultipleEnvironments) {\n            // For now, create new environments with a URL\n            const newEnv = {\n                app_id: appId,\n                version: { ref: \"refs/heads/master\" },\n                url: await dispatch(getNewEnvironmentURL(\"private\")),\n                run_scheduled_tasks: true,\n            };\n            const createdEnv = await dispatch(createEnvironment(newEnv));\n            if (createdEnv) {\n                dispatch(setSelectedEnvironmentId(createdEnv.env_id));\n            }\n        } else {\n            dispatch(modal(\"upgradePrompt\", { featureId: \"multiple-environments\" }));\n        }\n    });\n\n    const onDeleteEnvironment = useEvent(async (env: AppEnvironment) => {\n        if (\n            isBlank(env) ||\n            (await dispatch(\n                confirm(\"Delete environment?\", \"Are you sure you want to remove this environment from your app?\")\n            ))\n        ) {\n            // TODO: Better confirmation if there are scheduled tasks or uplink keys in this environment\n            await dispatch(deleteEnvironment(env));\n        }\n    });\n\n    // ***********\n    // Shared\n    // ***********\n    const onAddDebug = useEvent(async () => {\n        const url = await dispatch(getNewEnvironmentURL(\"private\"));\n        dispatch(saveEnvironment(environments.debug!, { url })); // TODO: Get from server\n        dispatch(setSelectedEnvironmentId(environments.debug?.env_id));\n    });\n\n    const onRemoveDebug = useEvent(async () => {\n        if (\n            !hasUplinkKeys(environments.debug) ||\n            (await dispatch(\n                confirm(\n                    \"Remove Uplink Access?\",\n                    \"Removing your development environment will also remove its Uplink keys. Do you want to continue?\"\n                )\n            ))\n        ) {\n            await dispatch(\n                saveEnvironment(environments.debug!, {\n                    name: null,\n                    table_mapping_id: null,\n                    url: null,\n                    server_keys: null,\n                    digest: null,\n                    run_scheduled_tasks: null,\n                })\n            );\n        }\n    });\n\n    const leftButtons = !environments.debug?.url &&\n        isEmpty(environments.debug?.server_keys) && [\n            <LinkInternal\n                key={\"getDebug\"}\n                className={isEnvironmentReadOnly(environments.debug) ? \"cursor-not-allowed opacity-50\" : undefined}\n                onClick={isEnvironmentReadOnly(environments.debug) ? undefined : onAddDebug}\n                aria-disabled={isEnvironmentReadOnly(environments.debug)}\n                tabIndex={isEnvironmentReadOnly(environments.debug) ? -1 : 0}>\n                <FontAwesomeIcon icon={faBug} /> Get a link to my development environment\n            </LinkInternal>,\n        ];\n\n    const beforeClose = useEvent(async () => {\n        // Wait for any in-progress saves to complete\n        try {\n            await dispatch(waitFor(allEnvironmentSavesComplete));\n        } catch {\n            /* We don't care if it timed out */\n        }\n        // Allow closing the modal if there were no save errors.\n        return await dispatch(confirmLeaveUnsavedEnvironment());\n    });\n\n    const onSelectEnvironment = useEvent((env: AppEnvironment) => {\n        if (selectedEnvironmentId === env.env_id) {\n            dispatch(setSelectedEnvironmentId(null));\n        } else {\n            dispatch(setSelectedEnvironmentId(env.env_id));\n        }\n    });\n\n    const expandedKeys =\n        sortedEnvironments.length === 1\n            ? { [sortedEnvironments[0].env_id]: true }\n            : selectedEnvironmentId\n              ? { [selectedEnvironmentId]: true }\n              : {};\n\n    const { freeOrgNoTrial } = useOrgType();\n\n    return (\n        <Modal\n            modalId={modalId}\n            beforeClose={beforeClose}\n            size=\"large\"\n            icon={faCloudUpload}\n            title={\"Publish this app\"}\n            leftButtons={leftButtons}\n            buttons={[{ text: \"Close\", clickActionCreator: () => modalReturn(true) }]}>\n            <PublishCTA />\n            <Accordion\n                items={sortedEnvironments}\n                expandedKeys={expandedKeys}\n                onToggle={onSelectEnvironment}\n                keyName={\"env_id\"}\n                renderHeader={(env: AppEnvironment, idx: number, isExpanded: boolean) => (\n                    <EnvironmentHeader\n                        env={env}\n                        isSelected={isExpanded}\n                        readOnly={isEnvironmentReadOnly(env)}\n                        onDelete={() => (env === environments.debug ? onRemoveDebug() : onDeleteEnvironment(env))}\n                    />\n                )}\n                renderBody={(env: AppEnvironment) => (\n                    <EnvironmentBody\n                        env={env}\n                        isDebug={env === environments.debug}\n                        readOnly={isEnvironmentReadOnly(env)}\n                        allowRestrictedEnvironmentUpdates={allowRestrictedEnvironmentUpdates}\n                    />\n                )}\n            />\n\n            {sortedEnvironments.length === 0 && (\n                <div className=\"text-center\" style={{ marginTop: 45 }}>\n                    <Button\n                        large\n                        variant={\"primary\"}\n                        onClick={() => dispatch(publishApp({ ref: `refs/heads/master` }, true))}\n                        icon={faCloudUpload}>\n                        Publish this app\n                    </Button>\n                    {!freeOrgNoTrial && (\n                        <>\n                            <hr />\n                            <Button small onClick={onCreateEnvironment} icon={faPlus}>\n                                Add a custom environment (advanced)\n                            </Button>\n                        </>\n                    )}\n                </div>\n            )}\n            {sortedEnvironments.length > 0 && (\n                <div className=\"text-center\" style={{ marginTop: 45 }}>\n                    <Text level={2}>\n                        To publish your app to a{sortedEnvironments.length === 0 ? \"\" : \"nother\"} URL you can share, add\n                        an{sortedEnvironments.length === 0 ? \"\" : \"other\"} environment:{\" \"}\n                        {environments.real.length > 0 && <UpgradeBadge feature={\"multiple-environments\"} />}\n                    </Text>\n                    <Button variant={\"primary\"} onClick={onCreateEnvironment} icon={faPlus}>\n                        Add{sortedEnvironments.length === 0 ? \"\" : \" another\"} environment\n                    </Button>\n                </div>\n            )}\n            <HelpLink url={`${window.location.origin}/docs/deployment`}>More info</HelpLink>\n            <br />\n        </Modal>\n    );\n};\n\nexport default EnvironmentsModal;\n","import React, { useMemo } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { useUpdateAppOwnership } from \"@/components/modals/account/OrgApps\";\nimport { ModalComponent } from \"@/components/modals/index\";\nimport { ContentDropdownMenuItem } from \"@/components/reusable/SharedComponents\";\nimport { getSubscription } from \"@/controllers/ide\";\nimport { PermissionPreset } from \"@/types\";\nimport { getPlanName } from \"@/util/features\";\nimport { modalReturn } from \"../../controllers/modals\";\nimport Modal from \"./Modal\";\n\ninterface UserPermissionsProps {\n    id: string;\n    name: string;\n    user_id: number; //todo: are we going to do sqid this?\n    permission: { preset: PermissionPreset };\n}\n\ninterface RemoveSelfFromSubscriptionSpec {\n    sharedApps: UserPermissionsProps[];\n}\n\ninterface OwnAppPermissionsProps {\n    name: string;\n    numCollaborators: number;\n}\n\ninterface RemoveUserFromSubscriptionSpecs {\n    email: string;\n    permissionsOfAppsOfUser: UserPermissionsProps[];\n}\n\ninterface ChangeAppOwnershipRowProps {\n    app: { name: string; appId: string };\n    initialOwner: string;\n}\n\nexport const RemoveSelfFromSubscription: ModalComponent<RemoveSelfFromSubscriptionSpec, boolean> = ({\n    modalId,\n    spec,\n}) => {\n    const { sharedApps } = spec;\n    const subscription = useSelector(getSubscription);\n    const appsAndNumberOfCollaborators = useMemo(() => {\n        const a: Record<string, OwnAppPermissionsProps> = {};\n        sharedApps.forEach((app) => {\n            if (a[app.id]) {\n                a[app.id].numCollaborators += 1;\n            } else {\n                a[app.id] = { name: app.name, numCollaborators: 1 };\n            }\n        });\n        return a;\n    }, [sharedApps]);\n\n    return (\n        <Modal\n            title=\"Remove yourself from this subscription\"\n            modalId={modalId}\n            buttons={[\n                { text: \"Cancel\" },\n                {\n                    text: sharedApps.length ? \"Revoke Access and Leave Subscription\" : \"Leave Subscription\",\n                    defaultButton: true,\n                    clickActionCreator: () => modalReturn(true),\n                },\n            ]}>\n            {sharedApps.length ? (\n                <>\n                    <div className={\"mb-4\"}>\n                        You're about to leave the{\" \"}\n                        <span className={\"font-semibold\"}>{getPlanName(subscription?.plan)}</span> of{\" \"}\n                        <span className={\"font-semibold\"}>{subscription?.name}</span>.\n                    </div>\n                    <div className={\"my-4\"}>\n                        The following are apps <span className={\"font-semibold\"}>owned by you</span> that have been\n                        shared with other users within your current subscription.\n                    </div>\n                    <div\n                        className={\n                            \"my-4 rounded-lg border border-sectionborder bg-light-bg2 p-4 dark:border-dark-sectionborder dark:bg-dark-bg6\"\n                        }>\n                        {Object.keys(appsAndNumberOfCollaborators).map((appId, ind) => (\n                            <div key={ind} className={\"mx-2\"}>\n                                <span className={\"font-semibold\"}>{appsAndNumberOfCollaborators[appId].name}</span> (\n                                <span className={\"font-mono\"}>{appId}</span>) -{\" \"}\n                                <span>{appsAndNumberOfCollaborators[appId].numCollaborators}</span> collaborator(s)\n                            </div>\n                        ))}\n                    </div>\n                    <div className={\"my-4\"}>\n                        <span className={\"text-danger\"}>\n                            Leaving the subscription will revoke access to these apps from all collaborators.\n                        </span>\n                        <br />\n                        If you'd like to change the ownership of any of these apps, contact a manager of your\n                        subscription.\n                    </div>\n                </>\n            ) : (\n                <>\n                    You're about to leave the <span className={\"font-semibold\"}>{getPlanName(subscription?.plan)}</span>{\" \"}\n                    of <span className={\"font-semibold\"}>{subscription?.name}</span>. Are you sure?\n                </>\n            )}\n        </Modal>\n    );\n};\n\nconst ChangeAppOwnershipRow = ({ app: { name, appId }, initialOwner }: ChangeAppOwnershipRowProps) => {\n    const { updateOwnershipSaveIndicator, appOwner, chooseAppOwner, developers } = useUpdateAppOwnership(\n        initialOwner,\n        appId\n    );\n    return (\n        <div className={\"grid w-full grid-cols-[1fr_max-content]\"}>\n            <div>\n                <span className={\"font-semibold\"}>{name}</span> (<span className={\"font-mono\"}>{appId}</span>)\n            </div>\n            <div>\n                {updateOwnershipSaveIndicator}\n                <ContentDropdownMenuItem\n                    variant={\"small\"}\n                    value={appOwner}\n                    onChange={(e) => chooseAppOwner(e.target.value)}>\n                    {developers?.map(({ email }: { email: string }, index: number) => (\n                        <option value={email} key={index}>\n                            {email}\n                        </option>\n                    ))}\n                </ContentDropdownMenuItem>\n            </div>\n        </div>\n    );\n};\n\nexport const RemoveUserFromSubscription: ModalComponent<RemoveUserFromSubscriptionSpecs, boolean> = ({\n    modalId,\n    spec,\n}) => {\n    const { email, permissionsOfAppsOfUser } = spec;\n\n    const apps = useMemo(() => {\n        const set = new Set(\n            permissionsOfAppsOfUser.map(({ id, name }) =>\n                JSON.stringify({\n                    name,\n                    appId: id,\n                })\n            )\n        );\n        return [...set].map((str) => JSON.parse(str));\n    }, [permissionsOfAppsOfUser]);\n\n    return (\n        <Modal\n            title=\"Remove developer?\"\n            modalId={modalId}\n            buttons={[\n                { text: \"Cancel\" },\n                {\n                    text: \"Remove developer from subscription\",\n                    defaultButton: true,\n                    variant: \"danger\",\n                    clickActionCreator: () => modalReturn(true),\n                },\n            ]}>\n            {permissionsOfAppsOfUser.length > 0 ? (\n                <>\n                    <div className={\"mb-4\"}>\n                        You are about to remove <span className={\"font-semibold\"}>{email}</span>.\n                    </div>\n                    <div className={\"my-4\"}>\n                        The following are apps owned by <span className={\"\"}>{email}</span> that have{\" \"}\n                        <span className={\"italic\"}>collaboration permissions</span>. Removing <span>{email}</span> will\n                        revoke access to all of these apps from users within the subscription.\n                    </div>\n                    <div className={\"my-4\"}>\n                        If you need to maintain access to any of the apps, update the app owner below. If you don't\n                        change the owner of an app, then the app will continue to be owned by <span>{email}</span> and\n                        will not be accessible to anyone in your subscription.\n                    </div>\n                    <div\n                        className={\n                            \"my-4 w-full rounded-lg border border-sectionborder bg-light-bg2 p-4 dark:border-dark-sectionborder dark:bg-dark-bg6\"\n                        }>\n                        {apps.map((app, index) => (\n                            <ChangeAppOwnershipRow key={index} app={app} initialOwner={email} />\n                        ))}\n                    </div>\n                </>\n            ) : (\n                <>Are you sure you want to remove {email} from this organisation?</>\n            )}\n        </Modal>\n    );\n};\n","import * as React from \"react\";\nimport { useCallback, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { alert, modalReturn } from \"@/controllers/modals\";\nimport { cancelSubscription } from \"@/controllers/user\";\nimport type { AnvilDispatch, Subscription } from \"@/types\";\nimport { getPlanName } from \"@/util/features\";\nimport { ModalComponent } from \".\";\nimport { TextArea } from \"../reusable/Forms\";\nimport { CheckBox } from \"../reusable/SharedComponents\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport Modal from \"./Modal\";\n\ninterface TerminateSubscriptionSpec {\n    subscription: Subscription;\n}\n\nconst TerminateSubscription: ModalComponent<TerminateSubscriptionSpec, boolean | null> = ({\n    modalId,\n    spec: { subscription },\n}) => {\n    const [confirmed, setConfirmed] = useState(false);\n    const [submitted, setSubmitted] = useState(false);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const dateOptions: Intl.DateTimeFormatOptions = { year: \"numeric\", month: \"long\", day: \"numeric\" };\n    const expiryDate = new Date(subscription?.expires).toLocaleString(\"en-GB\", dateOptions);\n    const [feedback, setFeedback] = useState(\"\");\n\n    const terminatePlan = useCallback(async () => {\n        setSubmitted(true);\n        const response = await dispatch(cancelSubscription(feedback));\n\n        if (response && typeof response === \"object\" && \"error\" in response && response.error) {\n            dispatch(\n                alert(\n                    \"Unable to Terminate Subscription\",\n                    \"Sorry, an error occurred and we are unable to cancel your subscription at this time. We have been notified of this and will be in contact with you shortly to verify cancellation.\"\n                )\n            );\n        } else {\n            let text = \"Your subscription has been successfully cancelled.\";\n            text = feedback ? \"Thank you for your feedback! \" + text : text;\n            dispatch(alert(\"Termination Request Confirmed\", text));\n        }\n    }, [feedback]);\n\n    return (\n        <Modal\n            modalId={modalId}\n            allowDismiss={true}\n            title={`Terminate Subscription`}\n            buttons={[\n                {\n                    text: \"Terminate Subscription\",\n                    clickActionCreator: () => terminatePlan(),\n                    variant: \"danger\",\n                    enabled: confirmed && !submitted,\n                },\n                { text: \"Cancel\", clickActionCreator: () => modalReturn(false) },\n            ]}>\n            <Heading level={2}>\n                Termination of your subscription will take effect on <strong>{expiryDate}</strong>\n            </Heading>\n            <Text level={3}>\n                On that date, you will no longer be billed and your account will revert to a Free plan. All your apps\n                will continue to exist - however services that are not available on the free tier will cease to\n                function.\n            </Text>\n            <CheckBox\n                checked={confirmed}\n                onChange={() => setConfirmed(!confirmed)}\n                text={`I confirm that I want to cancel my ${getPlanName(subscription?.plan)} plan`}\n            />\n\n            <Heading level={3}>Please let us know why you've decided to cancel your subscription.</Heading>\n            <Text level={3}>Any feedback is greatly appreciated as we continue to improve Anvil for everyone.</Text>\n            <TextArea\n                style={{ resize: \"none\" }}\n                value={feedback}\n                onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => setFeedback(e.target.value)}\n                placeholder={\"Optional: Please tell us why you're leaving\"}\n            />\n\n            <Text level={3}>\n                <i>\n                    For questions regarding canceling your subscription, please email{\" \"}\n                    <a tabIndex={-1} href=\"mailto:sales@anvil.works\">\n                        {\" \"}\n                        contact@anvil.works\n                    </a>\n                    .\n                </i>\n            </Text>\n        </Modal>\n    );\n};\n\nexport default TerminateSubscription;\n","import * as React from \"react\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { uncancelSubscription } from \"@/controllers/user\";\nimport { ModalComponent } from \".\";\nimport { Text } from \"../reusable/Text\";\nimport Modal from \"./Modal\";\n\nconst UnTerminateSubscription: ModalComponent = ({ modalId }) => (\n    <Modal\n        modalId={modalId}\n        allowDismiss={true}\n        title=\"Un-cancel Subscription\"\n        buttons={[\n            {\n                text: \"Un-cancel Subscription\",\n                clickActionCreator: uncancelSubscription,\n                variant: \"danger\",\n            },\n            { text: \"Back\", clickActionCreator: () => modalReturn(false) },\n        ]}>\n        <Text level={2}>\n            <i>\n                For questions regarding your subscription, please email{\" \"}\n                <a tabIndex={-1} href=\"mailto:contact@anvil.works\">\n                    contact@anvil.works\n                </a>\n                .\n            </i>\n        </Text>\n    </Modal>\n);\n\nexport default UnTerminateSubscription;\n","import React, { useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { CardElement, useElements } from \"@stripe/react-stripe-js\";\nimport { ModalComponent } from \"@/components/modals\";\nimport { useStyles } from \"@/components/reusable/Forms\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { confirmUpdateCard, stripeElementOptions } from \"@/controllers/payment\";\nimport { getUserUiScale } from \"@/controllers/user\";\nimport { cx, makeStyles, useIsDark } from \"@/theme/styles\";\nimport type { AnvilDispatch, Subscription } from \"@/types\";\nimport Modal from \"./Modal\";\nimport type { ModalRef } from \"./Modal\";\n\nexport type UpdatePaymentCardResult =\n    | {\n          setupIntent: unknown;\n      }\n    | {\n          e: unknown;\n          error: { message: string };\n      };\n\nconst updateCardModalStyles = makeStyles()((theme) => ({\n    stripeContainer: {\n        display: \"flex\",\n        justifyContent: \"center\",\n        width: \"70%\",\n        alignItems: \"center\",\n        \"& > *\": {\n            width: \"100%\",\n        },\n    },\n    inputContainer: {\n        marginTop: \"1.5rem\",\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"space-between\",\n        width: \"100%\",\n    },\n    cardLabel: {\n        width: \"min-content\",\n        whiteSpace: \"nowrap\",\n    },\n}));\n\ninterface UpdatePaymentCardSpec {\n    errMsg?: string | false | null;\n    subscription?: Subscription & {\n        card?: {\n            brand: string;\n            last4: string;\n        } | null;\n    };\n}\n\nconst UpdatePaymentCard: ModalComponent<UpdatePaymentCardSpec, UpdatePaymentCardResult | null> = ({\n    modalId,\n    spec: { errMsg, subscription },\n}) => {\n    const { classes } = useStyles();\n    const { classes: modalClasses } = updateCardModalStyles();\n\n    //todo: decide if should get rid of this cuz stripeElementOptions has defaults\n    const isDarkMode = useIsDark();\n    const uiScale = useSelector(getUserUiScale) || \"medium\";\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const [showCardElement, setShowCardElement] = useState(true);\n    const modalRef = useRef<ModalRef>(null);\n    const [enabled, setEnabled] = useState(false);\n    const [buttonText, setButtonText] = useState(\"Update\");\n    const [errorMessage, setErrorMessage] = useState<string | false | null | undefined>(errMsg);\n\n    const elements = useElements();\n\n    const handleButton = async () => {\n        setButtonText(\"Processing\");\n        setEnabled(false);\n        setErrorMessage(false);\n        const response = await dispatch(confirmUpdateCard(elements!.getElement(CardElement)));\n        setShowCardElement(false); //hack for stripe, so we can pop up modal again if there are any errors\n        return modalReturn(response);\n    };\n\n    return (\n        <Modal\n            modalId={modalId}\n            ref={modalRef}\n            size=\"small\"\n            title=\"Update Payment Details\"\n            buttons={[\n                { text: buttonText, variant: \"primary\", clickActionCreator: () => handleButton(), enabled },\n                { text: \"Cancel\", clickActionCreator: () => modalReturn(null) },\n            ]}>\n            <div>\n                {subscription?.card && (\n                    <>\n                        Your current card on file is a <b>{subscription.card.brand}</b> ending in •••{\" \"}\n                        <b>{subscription.card.last4}</b>\n                    </>\n                )}\n                <br />\n                <div className={modalClasses.inputContainer}>\n                    <div className={modalClasses.cardLabel}>New Payment Details</div>\n                    <div className={cx(classes.inputShared, classes.textBoxRoot, modalClasses.stripeContainer)}>\n                        {showCardElement && (\n                            <CardElement\n                                options={stripeElementOptions(isDarkMode, uiScale)}\n                                onChange={(e: { complete: boolean }) => setEnabled(e.complete)}\n                            />\n                        )}\n                    </div>\n                </div>\n                {errorMessage && (\n                    <Text level={3} className={\"text-danger!\"}>\n                        {errorMessage} <br />\n                        For more assistance, please contact billing@anvil.works\n                    </Text>\n                )}\n            </div>\n        </Modal>\n    );\n};\n\nexport default UpdatePaymentCard;\n","import { default as React, useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faCheck, faCircleExclamation, faRepeat, faTags } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { CardElement } from \"@stripe/react-stripe-js\";\nimport { countries } from \"country-data\";\nimport useStyles from \"@/components/modals/modalstyles\";\nimport ComboBox from \"@/components/reusable/ComboBox.tsx\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { alert, updatePayment } from \"@/controllers/modals\";\nimport { stripeElementOptions } from \"@/controllers/payment\";\nimport { getActiveOffers } from \"@/controllers/user\";\nimport { cx } from \"@/theme/styles\";\nimport { makeStyles } from \"@/theme/styles\";\nimport { CURRENCY_SYMBOLS, getDiscountedPrice, mergeTierOffers } from \"@/util/discounts\";\nimport { getPlanName } from \"@/util/features\";\nimport { dateAndDaysAway } from \"@/util/time\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ButtonGroup } from \"../reusable/ButtonGroup\";\nimport { TextArea, TextBox } from \"../reusable/Forms\";\nimport Link from \"../reusable/Link\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport { IncrementingNumericTextInput } from \"../reusable/TextInput\";\n\nconst rawCountries = Object.values(countries).slice(1);\nconst allCountries = rawCountries.reduce(\n    (o, country) => ({\n        ...o,\n        [country.alpha2]: {\n            name: country.name,\n            currency: country.currencies,\n            callingCodes: country.countryCallingCodes,\n            flag: country.emoji,\n            code: country.alpha2,\n        },\n    }),\n    {}\n);\ndelete allCountries[\"UK\"];\n\nconst countryValues = Object.values(allCountries).sort((a, b) => {\n    return a.name.localeCompare(b.name);\n});\nconst countryItems = countryValues.map((c) => ({ value: c.code, display: c.name }));\n\nconst paymentFormStyles = makeStyles()((theme, _props, classes) => ({\n    inputShared: {\n        height: theme.formInput.height,\n        padding: \"0 \" + theme.formInput.padding,\n        border: \"2px solid \" + theme.formInput.border.toString(),\n        borderRadius: \"0.4rem\",\n        color: theme.formInput.color.toString(),\n        fontSize: \"1.4rem\",\n        fontWeight: 400,\n        width: \"100%\",\n        background: theme.formInput.background.toString(),\n        [`&.${classes.small}`]: {\n            height: theme.formInput.smallHeight,\n            background: theme.formInput.smallBackground.toString(),\n            borderColor: theme.formInput.smallBorder.toString(),\n            fontSize: theme.formInput.smallFontSize,\n            padding: \"0 \" + theme.formInput.smallPadding,\n        },\n    },\n    textBoxRoot: {\n        \"&::placeholder\": {\n            color: theme.formInput.placeholderColor.toString(),\n        },\n    },\n    stripeContainer: {\n        display: \"flex\",\n        justifyContent: \"center\",\n        alignItems: \"center\",\n        \"& > *\": {\n            width: \"100%\",\n        },\n    },\n}));\n\nconst PERSONAL_PLANS = [\"hobby\", \"personal\", \"individual\"];\n\nconst isEUMember = (countryCode) => {\n    return [\n        \"BE\",\n        \"BG\",\n        \"CZ\",\n        \"DK\",\n        \"DE\",\n        \"EE\",\n        \"IE\",\n        \"GR\",\n        \"ES\",\n        \"FR\",\n        \"HR\",\n        \"IT\",\n        \"CY\",\n        \"LV\",\n        \"LT\",\n        \"LU\",\n        \"HU\",\n        \"MT\",\n        \"NL\",\n        \"AT\",\n        \"PL\",\n        \"PT\",\n        \"RO\",\n        \"SI\",\n        \"SK\",\n        \"FI\",\n        \"SE\",\n    ].includes(countryCode);\n};\n\nconst PersonalOrBusinessDetails = ({\n    accountType,\n    plan,\n    paymentRegion,\n    useVRN,\n    setUseVRN,\n    vrn,\n    setVRN,\n    crn,\n    setCRN,\n    companyName,\n    setCompanyName,\n    subscription,\n}) => {\n    let taxId = <></>;\n\n    if (accountType === \"business\" && plan.id !== \"hobby\") {\n        switch (paymentRegion.currencyRegionCode) {\n            case \"EU\":\n                if (useVRN) {\n                    taxId = (\n                        <div className={\"mt-4 flex flex-col\"}>\n                            <label htmlFor={\"companyNumber\"} className=\"\">\n                                VAT Registration Number\n                            </label>\n                            {!subscription?.vrn ? (\n                                <div className={\"grid\"}>\n                                    <TextBox\n                                        value={vrn}\n                                        placeholder={\"VRN\"}\n                                        onChange={(e) => setVRN(e.target.value)}\n                                        className={\"!border-1\"}\n                                        id={\"companyNumber\"}\n                                    />\n                                    <LinkInternal\n                                        className={\"whitespace-nowrap underline\"}\n                                        onClick={() => setUseVRN(false)}>\n                                        I don't have a VRN\n                                    </LinkInternal>\n                                </div>\n                            ) : (\n                                <text>{subscription?.vrn}</text>\n                            )}\n                        </div>\n                    );\n                } else {\n                    taxId = (\n                        <div className={\"mt-4 flex flex-col\"}>\n                            <label htmlFor={\"companyNumber\"} className=\"\">\n                                Company Registration Number\n                            </label>\n                            {!subscription?.crn ? (\n                                <div>\n                                    <TextBox\n                                        value={crn}\n                                        placeholder={\"CRN\"}\n                                        onChange={(e) => setCRN(e.target.value)}\n                                        className={\"!border-1\"}\n                                        id={\"companyNumber\"}\n                                    />\n                                    <LinkInternal\n                                        className={\"whitespace-nowrap underline\"}\n                                        onClick={() => setUseVRN(true)}>\n                                        Use VRN instead\n                                    </LinkInternal>\n                                </div>\n                            ) : (\n                                <text>{subscription?.crn}</text>\n                            )}\n                        </div>\n                    );\n                }\n\n                break;\n            case \"GB\":\n                taxId = (\n                    <div className={\"mt-4 flex flex-col\"}>\n                        <label htmlFor={\"companyNumber\"} className=\"\">\n                            VAT Registration Number\n                        </label>\n                        {!subscription?.vrn ? (\n                            <TextBox\n                                value={vrn}\n                                placeholder={\"VRN (Optional)\"}\n                                onChange={(e) => setVRN(e.target.value)}\n                                className={\"!border-1\"}\n                                id={\"companyNumber\"}\n                            />\n                        ) : (\n                            <text>{subscription?.vrn}</text>\n                        )}\n                    </div>\n                );\n                break;\n        }\n    }\n\n    return (\n        accountType === \"business\" &&\n        plan.id !== \"hobby\" && (\n            <div className={\"flex flex-col\"}>\n                <label htmlFor=\"companyName\" className=\"\">\n                    Company Name\n                </label>\n\n                <TextBox\n                    id=\"companyName\"\n                    className={\"!border-1\"}\n                    placeholder={\"Company Name (Optional)\"}\n                    value={companyName}\n                    onChange={(e) => setCompanyName(e.target.value)}\n                />\n                {taxId}\n            </div>\n        )\n    );\n};\n\nexport const PaymentForm = ({\n    userName,\n    countryFromIP,\n    isDarkMode,\n    uiScale,\n    pricing,\n    getPaymentAmount,\n    plan,\n    serverUpgrade,\n    supportUpgrade,\n    displaySupportUpgrade,\n    setFormComplete,\n    setFormEntries,\n    newOrganisation,\n    trialUpgrade,\n    subscription,\n    currentActiveDevs,\n    forceShowAdditionalTableauViewers,\n    errMsg,\n    formErrors,\n    planSelectMarker,\n    setInitialEntries,\n    subscriptionFreq,\n    switchToBusinessPlan,\n    seats,\n    setSeats,\n    accountType,\n    setAccountType,\n    billingFrequency,\n    setBillingFrequency,\n}) => {\n    const dispatch = useDispatch();\n    const { classes } = paymentFormStyles();\n    let { classes: modalClasses } = useStyles();\n\n    const capability = subscription?.planUpdateCapability;\n\n    const activeOffers = useSelector(getActiveOffers);\n\n    const collectAllInfo = newOrganisation || trialUpgrade;\n    const [name, setName] = useState(userName || \"\");\n    const [address, setAddress] = useState(\"\");\n    const [selectedCountry, setSelectedCountry] = useState(\n        collectAllInfo ? countryFromIP : subscription?.country || countryFromIP\n    );\n    const [countryPhoneCode, setCountryPhoneCode] = useState(\"\");\n    const [phoneNumber, setPhoneNumber] = useState(\"\");\n    const [useVRN, setUseVRN] = useState(!subscription?.crn);\n    const [vrn, setVRN] = useState(subscription?.vrn || \"\");\n    const [crn, setCRN] = useState(subscription?.crn || \"\");\n    const [companyName, setCompanyName] = useState(\n        subscription?.accountType === \"consumer\" || subscription?.name === userName ? \"\" : subscription?.name\n    );\n    const [additionalTableauViewers, setAdditionalTableauViewers] = useState(\n        subscription?.trial ? 0 : subscription?.additionalTableauViewers || 0\n    );\n    const [showAdditionalTableauViewers, setShowAdditionalTableauViewers] = useState(\n        forceShowAdditionalTableauViewers || additionalTableauViewers > 0\n    );\n\n    const minSeats = Math.max(currentActiveDevs, subscription?.planUpdateCapability?.minSeats || 1);\n\n    const [cardComplete, setCardComplete] = useState(false);\n\n    const [expiryDate, daysRemaining] = useMemo(() => dateAndDaysAway(subscription?.expires), [subscription]);\n\n    const anvilXInfo = {\n        id: \"anvilX\",\n        className: \"anvil-x\",\n        name: \"Anvil X\",\n        summary: \"Free Add On\",\n        features: [\"Build Tableau Extensions\", \"10 Free Tableau Viewers\"],\n    };\n\n    const dedicatedUpgradeInfo = {\n        id: \"dedicated\",\n        className: \"dedicated-upgrade\",\n        name: \"Extra Server Resources\",\n        summary: \"Your Custom Plan\",\n        features: [\"Private server\", \"Isolated database\", \"Custom CPU/RAM capacity\"],\n    };\n\n    const hasServerUpgrade = !!subscription?.dedicatedUpgrade;\n    const hasAwsOnlyUpgrade = !hasServerUpgrade && !!subscription?.aws;\n    const planWithSidebarExtras = hasAwsOnlyUpgrade\n        ? { ...plan, features: [...plan.features, \"Custom CPU/RAM capacity\"] }\n        : plan;\n\n    const paymentRegion = useMemo(() => {\n        if (selectedCountry === \"GB\")\n            return {\n                currencyRegionCode: \"GB\",\n                currency: \"GBP\",\n                vat: pricing?.vat_rates[\"GB\"],\n                countryCode: selectedCountry,\n                callingCodes: allCountries[selectedCountry]?.callingCodes,\n            };\n        if (isEUMember(selectedCountry))\n            return {\n                currencyRegionCode: \"EU\",\n                currency: \"EUR\",\n                vat: pricing?.vat_rates[selectedCountry],\n                countryCode: selectedCountry,\n                callingCodes: allCountries[selectedCountry]?.callingCodes,\n            };\n        return {\n            currencyRegionCode: \"US\",\n            currency: \"USD\",\n            countryCode: selectedCountry,\n            callingCodes: allCountries[selectedCountry]?.callingCodes,\n        };\n    }, [pricing, selectedCountry, isEUMember]);\n\n    // Fixed-amount offers are denominated in a single currency, so drop them if the payment\n    // currency doesn't match - otherwise the discount amount would be subtracted as if it were\n    // in the payment currency (e.g. a £60 offer knocking $60 off a USD total).\n    const { tierOffers, currencyMismatchedAmountOffer } = useMemo(() => {\n        const merged = mergeTierOffers(activeOffers?.[plan.id], activeOffers?.any);\n        if (merged.amountOffer && merged.amountOffer.discountCurrency !== paymentRegion?.currency) {\n            return { tierOffers: { ...merged, amountOffer: undefined }, currencyMismatchedAmountOffer: merged.amountOffer };\n        }\n        return { tierOffers: merged, currencyMismatchedAmountOffer: null };\n    }, [activeOffers, plan.id, paymentRegion?.currency]);\n\n    const countryMatchesIP = useMemo(() => countryFromIP === selectedCountry, [countryFromIP, selectedCountry]);\n    const needsVAT = useMemo(() => {\n        switch (paymentRegion?.currencyRegionCode) {\n            case \"US\":\n                return false;\n            case \"EU\":\n                return accountType !== \"business\";\n            default:\n                return true;\n        }\n    }, [paymentRegion, accountType]);\n\n    const price = useMemo(() => {\n        return getPaymentAmount(\n            plan.id,\n            billingFrequency,\n            seats,\n            subscription?.dedicatedUpgrade?.upgradeCost && subscription?.dedicatedUpgrade?.upgradeCost / 100,\n            subscription?.aws?.cost && subscription?.aws?.cost / 100,\n            displaySupportUpgrade ? subscription?.support?.upgradeCost / 100 : 0,\n            additionalTableauViewers,\n            paymentRegion?.countryCode,\n            paymentRegion?.currency\n        );\n    }, [subscription, pricing, billingFrequency, paymentRegion, additionalTableauViewers, seats]);\n\n\n    const validString = useCallback((str) => !!str && str.trim() !== \"\", []);\n\n    const consolidatedCollectedInfo = useEvent((force = null) => {\n        let info = {\n            name,\n            address,\n            accountType,\n            billingFrequency,\n            paymentRegion,\n            countryFromIP,\n            seats,\n            additionalTableauViewers,\n            offerCode: tierOffers?.percentOffer?.code,\n            amountOfferCode: tierOffers?.amountOffer?.code,\n        };\n        if (!countryMatchesIP) {\n            info = {\n                ...info,\n                tel: `${countryPhoneCode} ${phoneNumber}`,\n                countryPhoneCode,\n            };\n        }\n\n        if (!countryMatchesIP) {\n            info = {\n                ...info,\n                tel: `${countryPhoneCode} ${phoneNumber}`,\n                countryPhoneCode,\n            };\n        }\n        if (accountType === \"business\") {\n            if (useVRN) {\n                info = { ...info, companyName, vrn };\n            } else {\n                info = { ...info, companyName, crn };\n            }\n        }\n        if (force) {\n            info = { ...info, ...force };\n        }\n\n        return info;\n    });\n\n    useEffect(() => {\n        if (planSelectMarker === 1)\n            setInitialEntries(consolidatedCollectedInfo({ billingFrequency: subscriptionFreq }));\n    }, [planSelectMarker]);\n\n    useEffect(() => {\n        const baseRequirements = validString(name) && validString(address) && cardComplete;\n        const locationInfoEntered =\n            countryMatchesIP || (!countryMatchesIP && validString(phoneNumber) && validString(countryPhoneCode)); //checks that all the info is there but doesn't do validation\n\n        const business =\n            accountType === \"business\" && paymentRegion.currencyRegionCode === \"EU\"\n                ? useVRN\n                    ? validString(vrn)\n                    : validString(crn)\n                : true;\n        const consumer = accountType === \"consumer\";\n\n        let info = consolidatedCollectedInfo();\n\n        let enable =\n            ((collectAllInfo && baseRequirements && locationInfoEntered) || (!collectAllInfo && subscription?.card)) &&\n            (business || consumer);\n        setFormComplete(enable);\n        setFormEntries(enable ? info : {});\n    }, [\n        subscription?.card,\n        billingFrequency,\n        paymentRegion,\n        companyName,\n        countryFromIP,\n        setFormEntries,\n        setFormComplete,\n        name,\n        address,\n        cardComplete,\n        countryMatchesIP,\n        phoneNumber,\n        countryPhoneCode,\n        accountType,\n        seats,\n        additionalTableauViewers,\n        useVRN,\n        vrn,\n        crn,\n    ]);\n\n    const updateCardLinkClicked = useCallback(\n        async (errMsg = null) => {\n            const cardUpdate = await dispatch(updatePayment(errMsg, subscription));\n            if (cardUpdate?.setupIntent) {\n                dispatch(\n                    alert(\"Payment Details Updated\", \"Your payment details have been successfully updated. Thank you!\")\n                );\n            } else if (cardUpdate?.e) {\n                console.log(cardUpdate.e, cardUpdate.error);\n                await updateCardLinkClicked(cardUpdate.error.message);\n            }\n        },\n        [subscription]\n    );\n\n    const dropdownChanged = useCallback(\n        (country) => {\n            setSelectedCountry(country);\n            setPhoneNumber(\"\");\n            setCountryPhoneCode(allCountries[country].callingCodes[0]);\n        },\n        [allCountries]\n    );\n\n    const planSideBar = useCallback((plan) => {\n        return (\n            <>\n                <div className={\"text-center\"}>\n                    <Link className={\"group !no-underline\"} target={\"_blank\"} to={\"https://anvil.works/pricing\"}>\n                        <Heading level={2} className={\"!m-0 ps-0 pb-0 !text-primary group-hover:!text-primary-darker\"}>\n                            {plan?.name}\n                        </Heading>\n                    </Link>\n                    <Heading level={2} className={\"!mt-0 !mb-4 !text-[1.3rem]\"}>\n                        {plan.summary}\n                    </Heading>\n                </div>\n                <ul className={cx(modalClasses.planFeatures)}>\n                    {plan.features.map((f, idx) => (\n                        <li className=\"flex items-center gap-4 dark:text-dark-fg1\" key={idx}>\n                            <FontAwesomeIcon icon={faCheck} className=\"text-primary\" />\n                            <p>{f}</p>\n                        </li>\n                    ))}\n                </ul>\n            </>\n        );\n    }, []);\n\n    const { paymentTotalDisplay, standardMonthlyDisplay, percentDiscountedAmount, amountDiscountedAmount, remainingCredit } = useMemo(() => {\n        const basePrice = parseFloat(needsVAT ? price?.priceIncVAT : price?.priceExecVAT);\n        const afterPercent = getDiscountedPrice(basePrice, tierOffers?.percentOffer);\n        const afterAmount = getDiscountedPrice(afterPercent, tierOffers?.amountOffer);\n\n        let paymentTotalDisplay;\n        let standardMonthlyDisplay = null;\n        if (billingFrequency === \"annual\") {\n            paymentTotalDisplay = `${price?.symbol}${afterAmount?.toFixed(2)} / year`;\n            if (tierOffers?.amountOffer) {\n                paymentTotalDisplay += ` (this payment)`;\n                standardMonthlyDisplay = `then ${price?.symbol}${afterPercent.toFixed(2)} / year`;\n            }\n        } else if (tierOffers?.amountOffer) {\n            paymentTotalDisplay = `${price?.symbol}${afterAmount.toFixed(2)} (this payment)`;\n            standardMonthlyDisplay = `then ${price?.symbol}${afterPercent.toFixed(2)} / month`;\n        } else {\n            paymentTotalDisplay = `${price?.symbol}${afterAmount.toFixed(2)} / month (${price?.symbol}${(\n                afterAmount * 12\n            ).toFixed(2)} / year)`;\n        }\n\n        const remainingCredit = tierOffers?.amountOffer\n            ? Math.max(0, tierOffers.amountOffer.discountAmount / 100 - afterPercent)\n            : 0;\n\n        return {\n            paymentTotalDisplay,\n            standardMonthlyDisplay,\n            percentDiscountedAmount: (basePrice - afterPercent).toFixed(2),\n            amountDiscountedAmount: (afterPercent - afterAmount).toFixed(2),\n            remainingCredit: remainingCredit.toFixed(2),\n        };\n    }, [billingFrequency, needsVAT, price, tierOffers]);\n\n    const [discountAppliedTT, discountAppliedTTAnchorRef] = useTooltip(\n        <div className={\"w-[16rem] text-center text-balance\"}>\n            You’ve saved 20% by completing our introductory tutorial.\n        </div>\n    );\n\n    const exclVatUnitPrice = (unit, productId) => {\n        const vatRate = pricing?.vat_rates?.[paymentRegion.countryCode] ?? 0;\n        const vatIsInclusive = pricing?.products?.[productId]?.vat === \"inc\";\n\n        return vatIsInclusive && vatRate ? unit / (1 + vatRate / 100) : unit;\n    };\n\n    const seatUnitPriceDisplay = () => {\n        const unit = pricing?.products?.[plan.id]?.[paymentRegion.currency]?.[billingFrequency];\n\n        return Number(exclVatUnitPrice(unit, plan.id) * seats).toFixed(2);\n    };\n\n    const planBasePriceDisplay = () => {\n        const unit = pricing?.products?.[plan.id]?.[paymentRegion.currency]?.base_price?.[billingFrequency];\n        if (!unit) return null;\n\n        return Number(exclVatUnitPrice(unit, plan.id)).toFixed(2);\n    };\n\n    return (\n        <div className=\"grid grid-cols-[1fr_auto] grid-rows-[auto_auto] gap-4\">\n            <div className={\"row-span-2 min-w-[37rem] rounded-lg border-2 border-light-bg5 p-6 dark:border-dark-bg6\"}>\n                <Heading level={1}>\n                    {newOrganisation || trialUpgrade\n                        ? `Billing Details`\n                        : subscription?.plan === plan.id || !capability?.canChangePlanLevel\n                          ? `Update Plan`\n                          : `Switch Plan`}\n                </Heading>\n                <div className=\"grid gap-4\">\n                    {subscription?.trial && (\n                        <div className={cx(\"col-span-2\", modalClasses.notification)}>\n                            <Text className={\"text-center\"}>\n                                You are on a trial that terminates in <b>{daysRemaining}</b> days. You'll be able to\n                                finish out the rest of your trial period before your subscription starts and will be\n                                charged on <b>{expiryDate}</b>.\n                            </Text>\n                        </div>\n                    )}\n\n                    {!collectAllInfo && (\n                        <>\n                            <div className={\"\"}>\n                                {subscription?.plan === plan.id ? (\n                                    <Text>\n                                        You are updating the <b>{getPlanName(subscription?.plan)} plan</b> of\n                                        <b> {subscription?.name} </b>\n                                    </Text>\n                                ) : hasServerUpgrade || hasAwsOnlyUpgrade ? (\n                                    <Text>\n                                        You are updating the{\" \"}\n                                        <b>{getPlanName(subscription?.plan)} plan with extra server resources </b> of\n                                        <b> {subscription?.name}</b>\n                                    </Text>\n                                ) : (\n                                    <Text>\n                                        You are switching from the <b>{getPlanName(subscription?.plan)} plan</b> of\n                                        <b> {subscription?.name}</b>\n                                    </Text>\n                                )}\n                            </div>\n                        </>\n                    )}\n\n                    <PersonalOrBusinessDetails\n                        plan={plan}\n                        subscription={subscription}\n                        accountType={accountType}\n                        useVRN={useVRN}\n                        setUseVRN={setUseVRN}\n                        vrn={vrn}\n                        setVRN={setVRN}\n                        crn={crn}\n                        setCRN={setCRN}\n                        companyName={companyName}\n                        setCompanyName={setCompanyName}\n                        paymentRegion={paymentRegion}\n                    />\n\n                    {collectAllInfo ? (\n                        <>\n                            <div className={\"grid\"}>\n                                <label htmlFor=\"name\" className=\"\">\n                                    Your Name\n                                </label>\n                                <TextBox\n                                    id=\"name\"\n                                    className={\"!border-1\"}\n                                    placeholder={\"Your Name\"}\n                                    value={name}\n                                    onChange={(e) => setName(e.target.value)}\n                                />\n                            </div>\n\n                            <div className={\"flex flex-col\"}>\n                                <label htmlFor=\"address\" className=\"\">\n                                    Billing Address\n                                </label>\n                                <TextArea\n                                    id=\"address\"\n                                    className={cx(\"!h-48 resize-none !border-1\")}\n                                    placeholder={\"Street Address\"}\n                                    value={address}\n                                    onChange={(e) => setAddress(e.target.value)}\n                                />\n                            </div>\n\n                            <div className={\"flex flex-col\"}>\n                                <label className=\"\">Country</label>\n                                <ComboBox\n                                    value={selectedCountry ?? countryFromIP}\n                                    items={countryItems}\n                                    onChange={(v) => setSelectedCountry(v)}\n                                    onSelectValue={(code) => dropdownChanged(code)}\n                                    className={\"[&>div]:!border-[1px]\"}\n                                />\n                            </div>\n                        </>\n                    ) : userName ? (\n                        <div className={\"flex flex-col\"}>\n                            <label htmlFor=\"name\" className=\"\">\n                                Your Name\n                            </label>\n                            <label htmlFor=\"name\" className={\"font-bold\"}>\n                                {userName}\n                            </label>\n                        </div>\n                    ) : (\n                        <div className={\"flex flex-col\"}>\n                            <label htmlFor=\"name\" className=\"\">\n                                Your Name\n                            </label>\n                            <TextBox\n                                id=\"name\"\n                                placeholder={\"Your Name\"}\n                                value={name}\n                                onChange={(e) => setName(e.target.value)}\n                            />\n                        </div>\n                    )}\n                    {selectedCountry && (\n                        <>\n                            {accountType && (\n                                <>\n                                    {!countryMatchesIP && collectAllInfo && (\n                                        <div className={\"flex flex-col\"}>\n                                            <label htmlFor={\"countryPhoneCode\"}>Phone Number</label>\n                                            <div className={\"flex items-center\"}>\n                                                <TextBox\n                                                    maxLength=\"6\"\n                                                    value={countryPhoneCode}\n                                                    onChange={(e) => setCountryPhoneCode(e.target.value)}\n                                                    className={\"mr-4 !w-[20%] !border-1\"}\n                                                    id={\"countryPhoneCode\"}\n                                                />\n                                                <TextBox\n                                                    value={phoneNumber}\n                                                    onChange={(e) => setPhoneNumber(e.target.value)}\n                                                    className={\"!border-1\"}\n                                                    id={\"phoneNumber\"}\n                                                    placeholder={\"Phone number\"}\n                                                />\n                                            </div>\n                                        </div>\n                                    )}\n                                </>\n                            )}\n\n                            {\n                                <>\n                                    <div className={\"flex flex-col\"}>\n                                        <label htmlFor=\"paymentDetails\" className=\"\">\n                                            Payment Card Details\n                                        </label>\n                                        {collectAllInfo ? (\n                                            <div className=\"\">\n                                                <div\n                                                    className={cx(\n                                                        \"!border-1\",\n                                                        classes.inputShared,\n                                                        classes.textBoxRoot,\n                                                        classes.stripeContainer\n                                                    )}>\n                                                    <CardElement\n                                                        options={stripeElementOptions(isDarkMode, uiScale)}\n                                                        onChange={(e) => setCardComplete(e.complete)}\n                                                    />\n                                                </div>\n                                            </div>\n                                        ) : subscription?.card ? (\n                                            <div>\n                                                <b>{subscription?.card?.brand}</b> ••• {subscription?.card?.last4}{\" \"}\n                                                <LinkInternal\n                                                    className={\"ml-4 whitespace-nowrap underline\"}\n                                                    onClick={() => updateCardLinkClicked()}>\n                                                    Change payment method here\n                                                </LinkInternal>\n                                            </div>\n                                        ) : (\n                                            <div>\n                                                <b>No card provided</b>\n                                                <LinkInternal\n                                                    className={\"ml-4 whitespace-nowrap underline\"}\n                                                    onClick={() => updateCardLinkClicked()}>\n                                                    Add payment method here\n                                                </LinkInternal>\n                                            </div>\n                                        )}\n                                    </div>\n\n                                    {errMsg && (\n                                        <Text level={3} className={cx(\"text-danger!\")}>\n                                            {errMsg} Please check and try again. For more assistance, please contact\n                                            billing@anvil.works\n                                        </Text>\n                                    )}\n                                </>\n                            }\n                        </>\n                    )}\n                </div>\n            </div>\n\n            <div className=\"flex items-start gap-4 rounded-lg border-2 border-light-bg5 p-6 dark:border-dark-bg6\">\n                <div className=\"grid gap-4\">\n                    <Heading level={1} className={\"!m-0\"}>\n                        Plan Details\n                    </Heading>\n                    {/* This defaults to allowing the user to change the billing frequency, so behavior is correct for free users, as we don't have a subscription check wrapping this. */}\n                    {capability?.canChangeFrequency === false ? (\n                        <div className=\"grid\">\n                            <label className=\"\">Billing Frequency</label>\n                            <Text className={\"!m-0 !font-bold\"}>\n                                {billingFrequency === \"monthly\" ? \"Monthly\" : \"Annual\"}\n                            </Text>\n                        </div>\n                    ) : (\n                        <div className=\"grid\">\n                            <label className=\"\">Billing Frequency</label>\n                            <ButtonGroup\n                                options={[\n                                    { title: \"Annual\", value: \"annual\" },\n                                    { title: \"Monthly\", value: \"monthly\" },\n                                ]}\n                                selectedVariant={\"primary\"}\n                                selectedOption={billingFrequency}\n                                onClick={(selection) => setBillingFrequency(selection)}\n                            />\n                        </div>\n                    )}\n\n                    <div className=\"grid\">\n                        <label className=\"\">How will you use this plan?</label>\n                        <ButtonGroup\n                            className=\"\"\n                            options={[\n                                { title: \"Personal Use\", value: \"consumer\" },\n                                { title: \"Business Use\", value: \"business\" },\n                            ]}\n                            selectedVariant={\"primary\"}\n                            selectedOption={accountType}\n                            onClick={(selection) => setAccountType(selection)}\n                        />\n                    </div>\n\n                    <div className={\"grid\"}>\n                        <label className=\"\">How many developers will use this plan?</label>\n\n                        <div className={\"inline-flex items-center\"}>\n                            <IncrementingNumericTextInput\n                                value={seats}\n                                small={true}\n                                changeValueFn={setSeats}\n                                lowerBound={minSeats}\n                                className={\"inline-flex\"}\n                            />\n                        </div>\n                    </div>\n\n                    {showAdditionalTableauViewers && (\n                        <div className={\"grid\"}>\n                            <label className=\"\">Anvil X: Tableau Viewers</label>\n                            <div>\n                                <IncrementingNumericTextInput\n                                    lowerBound={10}\n                                    small={true}\n                                    value={10 + additionalTableauViewers}\n                                    changeValueFn={(x) => {\n                                        setAdditionalTableauViewers(x - 10);\n                                    }}\n                                    className={\"inline-flex\"}\n                                />\n                            </div>\n                        </div>\n                    )}\n                </div>\n\n                <div\n                    className={cx(\n                        \"grid h-full max-w-[252.7px] grid-rows-[auto_auto_1fr] rounded-md border border-sectionborder bg-light-bg2 p-4 text-light-bg7 dark:border-dark-bg4 dark:bg-dark-bg3\"\n                    )}>\n                    {planSideBar(planWithSidebarExtras)}\n\n                    {hasServerUpgrade && (\n                        <>\n                            <Heading level={1} className={\"!m-0 text-center\"}>\n                                +\n                            </Heading>\n                            {planSideBar(dedicatedUpgradeInfo)}\n                        </>\n                    )}\n                    {supportUpgrade && (\n                        <div className={\"text-center\"}>\n                            <Heading level={1} className={\"!m-0\"}>\n                                +\n                            </Heading>\n                            <Heading level={2} className={\"!m-0 ps-0 pb-0\"}>\n                                Support Plan\n                            </Heading>\n                        </div>\n                    )}\n                    <div className=\"mt-4\">\n                        <p className=\"font-semibold dark:text-dark-fg1\">+ Anvil X</p>\n                        <>\n                            <Text level={2} className=\"!m-0\">\n                                {\" \"}\n                                10 Free Tableau Viewers!\n                            </Text>\n\n                            {!showAdditionalTableauViewers && (\n                                <>\n                                    {pricing?.products?.tableau?.supported_plans?.includes(plan?.id) ? (\n                                        <LinkInternal\n                                            className={\n                                                \"inline-flex font-semibold text-primary underline hover:text-primary-darker\"\n                                            }\n                                            onClick={() => setShowAdditionalTableauViewers(true)}>\n                                            Add more\n                                        </LinkInternal>\n                                    ) : (\n                                        <Text level={3}>Choose the Business Plan to add more</Text>\n                                    )}\n                                </>\n                            )}\n                        </>\n                    </div>\n                </div>\n            </div>\n\n            <div\n                className={\n                    \"flex min-h-[216px] flex-col gap-4 rounded-md border-2 border-light-bg5 p-6 dark:border-dark-bg6\"\n                }>\n                {formErrors.hobbyTooManySeats ? (\n                    <div\n                        className={\n                            \"m-4 flex h-full flex-col items-center justify-center gap-6 rounded-md border border-sectionborder bg-light-bg2 p-8 dark:border-dark-bg4 dark:bg-dark-bg3\"\n                        }>\n                        <div className={\"flex items-center gap-6\"}>\n                            <FontAwesomeIcon icon={faCircleExclamation} className={\"text-7xl text-light-bg6\"} />\n                            <p>\n                                The Hobby plan is licensed for one developer only. To proceed with multiple developers,\n                                switch to Business.\n                            </p>\n                        </div>\n                        <button\n                            onClick={switchToBusinessPlan}\n                            className={\n                                \"flex w-full items-center justify-center gap-4 rounded-md border-0 bg-light-bg4 font-semibold text-light-bg7 hover:bg-light-bg5\"\n                            }>\n                            <FontAwesomeIcon icon={faRepeat} />\n                            Switch to Business\n                        </button>\n                    </div>\n                ) : formErrors.hobbyBusinessUse ? (\n                    <div\n                        className={\n                            \"m-4 flex h-full flex-col items-center justify-center gap-6 rounded-md border border-sectionborder bg-light-bg2 p-8 dark:border-dark-bg4 dark:bg-dark-bg3\"\n                        }>\n                        <div className={\"flex items-center gap-6\"}>\n                            <FontAwesomeIcon icon={faCircleExclamation} className={\"text-7xl text-light-bg6\"} />\n                            <p>\n                                The Hobby plan is licensed for personal use only. To proceed with business use, switch\n                                to Business.\n                            </p>\n                        </div>\n                        <button\n                            onClick={switchToBusinessPlan}\n                            className={\n                                \"flex w-full items-center justify-center gap-4 rounded-md border-0 bg-light-bg4 font-semibold text-light-bg7 hover:bg-light-bg5\"\n                            }>\n                            <FontAwesomeIcon icon={faRepeat} />\n                            Switch to Business\n                        </button>\n                    </div>\n                ) : (\n                    <>\n                        <Heading level={1} className={\"!m-0\"}>\n                            Order Summary\n                        </Heading>\n\n                        {serverUpgrade && (\n                            <>\n                                {parseFloat(price?.serverExtraResourcesUpgradeCost) > 0 && (\n                                    <div className={\"flex items-center justify-between\"}>\n                                        <label>Extra Server Resources Upgrade</label>\n                                        <p className={\"inline-flex\"}>\n                                            {price?.symbol} {price?.serverExtraResourcesUpgradeCost}\n                                            {subscription?.dedicatedUpgrade?.legacy && \"*\"}\n                                        </p>\n                                    </div>\n                                )}\n                                {parseFloat(price?.serverExtraResourcesAWSCost) > 0 && (\n                                    <div className={\"flex items-center justify-between\"}>\n                                        <label>AWS Costs</label>\n                                        <p className={\"inline-flex\"}>\n                                            {price?.symbol} {price?.serverExtraResourcesAWSCost}\n                                        </p>\n                                    </div>\n                                )}\n                            </>\n                        )}\n\n                        {planBasePriceDisplay() && (\n                            <div className={\"flex justify-between\"}>\n                                <label>{getPlanName(plan.id)} Base</label>\n                                <div>\n                                    {price?.symbol}\n                                    {planBasePriceDisplay()}\n                                </div>\n                            </div>\n                        )}\n\n                        {supportUpgrade && displaySupportUpgrade && (\n                            <div className={\"flex items-center justify-between\"}>\n                                <label>Support Upgrade</label>\n                                <div>\n                                    <Text level={1} className={\"inline-flex\"}>\n                                        {price?.symbol} {price?.supportCost}\n                                    </Text>\n                                </div>\n                            </div>\n                        )}\n\n                        <div className={\"flex justify-between\"}>\n                            <label>{seats}x Developer Seats</label>\n                            <div>\n                                {price?.symbol}\n                                {seatUnitPriceDisplay()}\n                            </div>\n                        </div>\n\n                        {showAdditionalTableauViewers && additionalTableauViewers > 0 && (\n                            <div className={\"flex justify-between\"}>\n                                <label>{additionalTableauViewers}x Additional Tableau Viewers</label>\n                                <div>\n                                    {price?.symbol}\n                                    {price?.tableauPriceExecVAT}\n                                </div>\n                            </div>\n                        )}\n\n                        {needsVAT && (\n                            <div className={\"flex justify-between\"}>\n                                <label>VAT</label>\n                                <div>\n                                    {price?.symbol}\n                                    {price?.vat}\n                                </div>\n                            </div>\n                        )}\n\n                        {tierOffers?.percentOffer && (\n                            <div className={\"flex justify-between\"}>\n                                {tierOffers.percentOffer.code === \"feedback-tutorial\" ? (\n                                    <label className={cx(\"underline\")} ref={discountAppliedTTAnchorRef}>\n                                        <FontAwesomeIcon icon={faTags} /> Discount Applied {discountAppliedTT}\n                                    </label>\n                                ) : (\n                                    <label>\n                                        <FontAwesomeIcon icon={faTags} /> Discount Applied\n                                    </label>\n                                )}\n                                <div>\n                                    -{price?.symbol}\n                                    {percentDiscountedAmount}\n                                </div>\n                            </div>\n                        )}\n\n                        {tierOffers?.amountOffer && (\n                            <div className={\"flex justify-between\"}>\n                                <label>\n                                    <FontAwesomeIcon icon={faTags} /> Discount Applied\n                                </label>\n                                <div>\n                                    -{price?.symbol}\n                                    {amountDiscountedAmount}\n                                </div>\n                            </div>\n                        )}\n\n                        {currencyMismatchedAmountOffer && (\n                            <div className={cx(modalClasses.notification, \"text-[1.3rem]\")}>\n                                <FontAwesomeIcon icon={faTags} className={\"mr-2\"} />\n                                Your {CURRENCY_SYMBOLS[currencyMismatchedAmountOffer.discountCurrency]}\n                                {(currencyMismatchedAmountOffer.discountAmount / 100).toFixed(0)} credit offer is only\n                                valid in {currencyMismatchedAmountOffer.discountCurrency} and can't be applied to this\n                                payment. Contact support@anvil.works to get it updated for your currency.\n                            </div>\n                        )}\n\n                        <div className={\"flex justify-between border-t-1 border-light-bg5 pt-4\"}>\n                            <label>Total</label>\n\n                            <div className={\"justify-items-end\"}>\n                                <div className={\"font-bold\"}>{paymentTotalDisplay}</div>\n                                {standardMonthlyDisplay && (\n                                    <div>\n                                        <small>{standardMonthlyDisplay}</small>\n                                    </div>\n                                )}\n                                {needsVAT && (\n                                    <div>\n                                        <small>Including {paymentRegion.vat}% VAT</small>\n                                    </div>\n                                )}\n                                {isEUMember(selectedCountry) && accountType === \"business\" && (\n                                    <div>\n                                        <small>VAT not charged under reverse charge mechanism</small>\n                                    </div>\n                                )}\n                            </div>\n                        </div>\n\n                        {parseFloat(remainingCredit) > 0 && (\n                            <div className={cx(modalClasses.notification, \"text-[1.3rem]\")}>\n                                <FontAwesomeIcon icon={faTags} className={\"mr-2\"} />\n                                {price?.symbol}\n                                {remainingCredit} of your discount isn't used by this payment - it'll be kept as\n                                account credit and applied to future invoices instead.\n                            </div>\n                        )}\n\n                        {subscription?.dedicatedUpgrade?.legacy && (\n                            <div className={\"text-[1.2rem] text-grey-1\"}>\n                                * You were automatically moved from a Dedicated Plan to an equivalent Business Plan with\n                                additional server resources. The overall cost of your Anvil subscription didn't change.\n                                This legacy plan requires a minimum of 3 developer seats. To move to a plan with fewer\n                                seats please contact support@anvil.works.\n                            </div>\n                        )}\n\n                        {supportUpgrade && !displaySupportUpgrade && (\n                            <Text level={3} className={\"inline-flex\"}>\n                                Your total is displayed without support upgrade cost. Please check your lastest invoice\n                                for your support cost.\n                            </Text>\n                        )}\n                    </>\n                )}\n            </div>\n        </div>\n    );\n};\n//TODO: Will probably be useful to pass trialUpgrade into here and under the payment amount have some info on when you'll get charged and make it clear you'll get to finish off your tiral period\n","import { default as React, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faRocket } from \"@fortawesome/free-solid-svg-icons/faRocket\";\nimport { faArrowRight } from \"@fortawesome/pro-light-svg-icons/faArrowRight\";\nimport { faCheck, faCircleExclamation } from \"@fortawesome/pro-solid-svg-icons\";\nimport { faCircleQuestion } from \"@fortawesome/pro-solid-svg-icons/faCircleQuestion\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { CardElement, useElements } from \"@stripe/react-stripe-js\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { isEqual } from \"lodash-es\";\nimport { IncrementingNumericTextInput } from \"@/components/reusable/TextInput.js\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { getSubscription, getUser } from \"@/controllers/ide\";\nimport { confirm, modalReturn } from \"@/controllers/modals\";\nimport { modal } from \"@/controllers/modals\";\nimport { changePlan, upgradeFromFree, upgradeFromTrial } from \"@/controllers/payment\";\nimport { getEligibleOffers, getUserUiScale } from \"@/controllers/user\";\nimport { CURRENCY_SYMBOLS, formatDiscountLabel, getDiscountedPrice, mergeTierOffers } from \"@/util/discounts\";\nimport { useDeveloperQuery } from \"@/util/hooks/use-developer-query.js\";\nimport { getManagerUser } from \"../../manager/controller\";\nimport { cx, useIsDark } from \"../../theme/styles\";\nimport { getPricing } from \"../../api/index\";\nimport { getPlanName } from \"../../util/features\";\nimport { dateAndDaysAway } from \"../../util/time\";\nimport { Button } from \"../reusable/Button\";\nimport { ButtonGroup } from \"../reusable/ButtonGroup\";\nimport { HelpLink } from \"../reusable/HelpLink\";\nimport Link from \"../reusable/Link\";\nimport { ModalButton } from \"../reusable/SharedComponents\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport Modal from \"./Modal\";\nimport { PaymentForm } from \"./UpgradePaymentForm\";\nimport { planInfo } from \"./UpgradePrompts\";\nimport useStyles from \"./modalstyles\";\n\n\nconst PERSONAL_PLANS = [\"personal\", \"hobby\"];\nconst LEGACY_PLANS = [\"personal\", \"individual\"];\n\n// newOrganisation: Are we changing the plan for an existing org, or creating a new one from scratch?\n// trialUpgrade: Are we upgrading from a trial to a paid plan? In that case, the org already exists, but for all\n//               other purposes this is like creating a new one from scratch.\n/**\n * @typedef {{initialPlanId: string, initialFreq: any, managerAction?:boolean, newOrganisation?:boolean,trialUpgrade?: boolean,forceShowAdditionalTableauViewers?: boolean}} UpgradeSpec\n * @type {import(\".\").ModalComponent<UpgradeSpec>} */\nlet Upgrade = ({\n    modalId,\n    spec: {\n        initialPlanId,\n        initialFreq,\n        managerAction = false,\n        newOrganisation = false,\n        trialUpgrade = false,\n        forceShowAdditionalTableauViewers = false,\n    },\n}) => {\n    const dispatch = useDispatch();\n    const user = useSelector(managerAction ? getManagerUser : getUser);\n    const subscription = useSelector(getSubscription);\n    const capability = subscription?.planUpdateCapability;\n    const fixedPlan = subscription?.plan\n        ? capability?.canChangePlanLevel\n            ? initialPlanId\n            : capability?.canChangeSeatCount\n              ? (capability?.seatBillingTier ?? subscription.plan)\n              : \"business\" // locked (e.g. education) - no self-serve entry point reaches this today, kept as a safe fallback\n        : null;\n\n    const { developers, requeryDevelopers } = useDeveloperQuery();\n\n    const currentActiveDevs = developers?.length || 1;\n\n    const isDark = useIsDark();\n    const isDarkMode = managerAction ? false : isDark;\n    const uiScale = useSelector(managerAction ? () => \"medium\" : getUserUiScale);\n    const { classes } = useStyles();\n\n    const location = useMemo(() => subscription?.country || user?.ipLocation?.country.code, [subscription, user]);\n    const locationOrPlanCurrency = useMemo(\n        () => user?.currency || subscription?.currency || user.ipLocation?.currency,\n        [user, subscription]\n    );\n\n    const modalRef = useRef();\n    const elements = useElements();\n\n    const subscribeText = managerAction ? \"Subscribe\" : \"Upgrade\";\n    const [buttonText, setButtonText] = useState(newOrganisation || trialUpgrade ? subscribeText : \"Update\");\n    const [paymentProcessing, setPaymentProcessing] = useState(false);\n    const [formComplete, setFormComplete] = useState(false);\n    const [formEntries, setFormEntries] = useState({});\n    const [errorMessage, setErrorMessage] = useState(null);\n\n    const eligibleOffers = useSelector(getEligibleOffers);\n\n    const filterFreqOptions = [\n        { title: \"Pay annually\", value: \"annual\" },\n        { title: \"Pay monthly\", value: \"monthly\" },\n    ];\n\n    const { data: pricing } = useQuery({\n        queryKey: [\"pricing\"],\n        queryFn: () => {\n            return getPricing();\n        },\n        staleTime: Number.POSITIVE_INFINITY,\n    });\n\n    const seatPlans = useMemo(() => {\n        return [\n            {\n                id: \"hobby\",\n                name: \"Hobby\",\n                className: \"hobby-plan\",\n                summary: \"Get Started\",\n                features: [\"1 Developer\", \"Remove Anvil banner\", \"One custom domain\", \"Light traffic\"],\n                vat: pricing?.products.hobby.vat,\n            },\n            {\n                id: \"business\",\n                name: \"Business\",\n                className: \"business-plan\",\n                summary: \"For Professional Use\",\n                features: [\n                    \"Multiple developers\",\n                    \"Collaborate on private repositories\",\n                    \"SSO for apps\",\n                    \"Community support\",\n                ],\n                multiDevPlan: true,\n                vat: pricing?.products.business.vat,\n            },\n            {\n                id: \"production\",\n                name: \"Production\",\n                className: \"business-plan\",\n                summary: \"Support and Power\",\n                features: [\n                    \"Priority email support\",\n                    \"High-performance server\",\n                    \"Direct SQL access\"\n                ],\n                multiDevPlan: true,\n                moreInfoUrl: \"https://anvil.works/docs/plans-and-accounts/free-vs-paid#production-plan\",\n                vat: pricing?.products[\"production\"]?.vat,\n            },\n            {\n                id: \"enterprise\",\n                className: \"enterprise-plan\",\n                name: \"Enterprise\",\n                summary: \"A Tailored Solution\",\n                features: [\"Enterprise SSO\", \"Enterprise integrations\", \"On-site or private cloud deployment\"],\n                learnMore: \"https://anvil.works/docs/overview/enterprise\",\n                contactUs: \"Get in touch\",\n                subText: \"for a quote\\n\",\n            },\n        ];\n    }, [pricing]);\n\n    const [selectedPlan, setSelectedPlan] = useState(() =>\n        fixedPlan ? seatPlans.find((p) => p.id === fixedPlan) : null\n    );\n\n    const [browsingPlans, setBrowsingPlans] = useState(!selectedPlan);\n\n    const [planSelectMarker, setPlanSelectMarker] = useState(0);\n    const [initialEntries, setInitialEntries] = useState({});\n\n    const formChanged = useMemo(() => {\n        return !isEqual(initialEntries, formEntries) || subscription?.plan !== selectedPlan?.id;\n    }, [initialEntries, formEntries, subscription?.plan, selectedPlan?.id]);\n\n    const selectPlan = useCallback(\n        async (plan) => {\n            setPlanSelectMarker((m) => m + 1);\n\n            if (subscription?.isPaid) {\n                if (!managerAction && !subscription.isManager) {\n                    if (\n                        await dispatch(\n                            confirm(\n                                \"Switch to new plan\",\n                                `You are on a ${getPlanName(subscription?.plan)} plan managed by ${\n                                    subscription?.email\n                                }. Switching plans will remove you from your current plan and put you on a new ${getPlanName(\n                                    selectedPlan?.plan\n                                )} plan. Would you like to continue?`\n                            )\n                        )\n                    ) {\n                        setSelectedPlan(plan);\n                        setBrowsingPlans(false);\n                    } else {\n                        modalRef.current.returnValue();\n                    }\n                } else {\n                    setBrowsingPlans(false);\n                    setSelectedPlan(plan);\n                }\n            } else {\n                setBrowsingPlans(false);\n                setSelectedPlan(plan);\n            }\n        },\n        [subscription, user, selectedPlan]\n    );\n\n    useEffect(() => {\n        if (initialPlanId) {\n            const p = plans.find(({ id }) => id === initialPlanId);\n            p && selectPlan(p);\n        }\n    }, [initialPlanId]);\n\n    const deselectPlan = () => {\n        setBrowsingPlans(true);\n        setSelectedPlan();\n    };\n\n    const [seats, setSeats] = useState(subscription?.totalDevCount || 1);\n    const [accountType, setAccountType] = useState(\n        PERSONAL_PLANS.includes(selectedPlan?.id) ? \"consumer\" : subscription?.accountType || \"business\"\n    );\n    const [billingFrequency, setBillingFrequency] = useState(\n        initialFreq || subscription?.recurringInterval || \"annual\"\n    );\n\n    const getPaymentAmount = useCallback(\n        (\n            planId,\n            billingFrequency,\n            nDevs,\n            serverExtraResourcesUpgradeCost = 0,\n            serverExtraResourcesAWSCost = 0,\n            supportCost = 0,\n            additionalTableauViewers = 0,\n            country = null,\n            paymentCurrency = null\n        ) => {\n            const tierPlan = planId;\n            if (!user || !location || !pricing || !pricing.products[tierPlan]) {\n                return undefined;\n            }\n            const userLocation = country || location;\n            const currency = paymentCurrency || locationOrPlanCurrency;\n            const tierPricing = pricing.products[tierPlan][currency];\n            const tableauPricePerUser = pricing.products.tableau[currency];\n            const symbol = CURRENCY_SYMBOLS[currency];\n\n            const planBasePrice = tierPricing[\"base_price\"]?.[billingFrequency] || 0;\n            const planPrice = planBasePrice + tierPricing[billingFrequency] * nDevs;\n            const planPriceIncludesVAT = pricing.products[tierPlan][\"vat\"] === \"inc\";\n            const seatsPriceExecVAT =\n                planPriceIncludesVAT &&\n                pricing.vat_rates[userLocation] &&\n                pricing.vat_rates[userLocation] !== 0\n                    ? planPrice / (1 + pricing.vat_rates[userLocation] / 100)\n                    : planPrice;\n\n            const tableauPrice = additionalTableauViewers * tableauPricePerUser[billingFrequency];\n\n            const basePrice =\n                planPrice +\n                additionalTableauViewers * tableauPricePerUser[billingFrequency] +\n                serverExtraResourcesUpgradeCost +\n                serverExtraResourcesAWSCost +\n                supportCost;\n\n            const vat =\n                planPriceIncludesVAT\n                    ? (basePrice * (pricing.vat_rates[userLocation] / 100)) /\n                      (1 + pricing.vat_rates[userLocation] / 100)\n                    : basePrice * (pricing.vat_rates[userLocation] / 100);\n\n            const supportCostExcVAT =\n                planPriceIncludesVAT\n                    ? supportCost / (1 + pricing.vat_rates[userLocation] / 100)\n                    : supportCost;\n\n            const priceIncVAT = planPriceIncludesVAT ? basePrice : basePrice + vat;\n\n            return {\n                symbol: symbol,\n                planPrice: planPrice,\n                seatsPriceExecVAT: seatsPriceExecVAT.toFixed(2),\n                priceExecVAT: basePrice.toFixed(2),\n                priceIncVAT: priceIncVAT.toFixed(2),\n                vat: vat.toFixed(2),\n                tableauPriceExecVAT: tableauPrice.toFixed(2),\n                serverExtraResourcesUpgradeCost: serverExtraResourcesUpgradeCost.toFixed(2),\n                serverExtraResourcesAWSCost: serverExtraResourcesAWSCost.toFixed(2),\n                supportCost: supportCostExcVAT.toFixed(2),\n            };\n        },\n        [pricing, billingFrequency, location, locationOrPlanCurrency]\n    );\n\n    const plansWithOffer = useMemo(() => {\n        return seatPlans.map((p) => {\n            const tierOffers = mergeTierOffers(user?.currentOffers?.active?.[p.id], user?.currentOffers?.active?.any);\n            return {\n                ...p,\n                offers: tierOffers,\n            };\n        });\n    }, [seatPlans, user]);\n\n    const plans = useMemo(() => {\n        if (!selectedPlan) return plansWithOffer;\n        // Re-resolve selectedPlan from plansWithOffer (by id) so its .offers is populated too.\n        return [plansWithOffer.find((p) => p.id === selectedPlan.id) || selectedPlan];\n    }, [plansWithOffer, selectedPlan]);\n\n    const makeUpgradeObj = (entries) => {\n        // offerCode/amountOfferCode come from entries: PaymentForm resolves them itself, since it\n        // knows the payment currency the user actually selected and drops offers that don't match it.\n        const obj = {\n            ...entries,\n            tier: selectedPlan?.id,\n        };\n\n        if (PERSONAL_PLANS.includes(selectedPlan?.id)) {\n            obj.additionalTableauViewers = 0;\n            obj.seats = 1;\n        }\n\n        return obj;\n    };\n\n    const handleUpgradeButton = () => async (dispatch, getState, updateState) => {\n        let response;\n        setErrorMessage(null);\n        const upgradeObj = makeUpgradeObj(formEntries);\n\n        setPaymentProcessing(true);\n        setButtonText(\"Processing\");\n\n        if (trialUpgrade || newOrganisation) {\n            response = await dispatch(\n                trialUpgrade\n                    ? upgradeFromTrial(upgradeObj, elements.getElement(CardElement))\n                    : upgradeFromFree(upgradeObj, elements.getElement(CardElement), !managerAction)\n            );\n            if (response.error) {\n                setErrorMessage(response.error);\n                setPaymentProcessing(false);\n                setButtonText(subscribeText);\n                setFormComplete(false);\n            } else {\n                return modalRef.current.returnValue({ id: selectedPlan?.id, failed: response?.upgradeError });\n            }\n        } else {\n            response = await dispatch(changePlan(upgradeObj, elements.getElement(CardElement)));\n            if (response.error) {\n                return modalRef.current.returnValue({ failed: true, errorMessage: response.error.error });\n            } else {\n                return modalRef.current.returnValue({ id: selectedPlan?.id, ...response });\n            }\n        }\n    };\n\n    const backButton = fixedPlan ? null : <ModalButton onClick={() => deselectPlan()}>Back</ModalButton>;\n    const [discountTT, discountTTAnchorRef] = useTooltip(\n        <div className={\"flex w-[16rem] flex-col items-center justify-center\"}>\n            <div className={\"text-center text-balance\"}>\n                Complete our 10-minute introductory Feedback Form tutorial and get a 20% discount on the Hobby Plan -\n                forever!\n            </div>\n            <Link\n                to={\"/docs/overview/milestone-discounts\"}\n                target={\"_blank\"}\n                className=\"mt-2 font-semibold text-grey-0 underline dark:text-grey-2\">\n                Find out more <FontAwesomeIcon icon={faArrowRight} />\n            </Link>\n        </div>,\n        \"right\",\n        { sticky: true }\n    );\n    const planPrice = useCallback(\n        (plan, tierOffers) => {\n            if (plan.contactUs) {\n                return (\n                    <Link\n                        level={2}\n                        to={\"mailto:contact@anvil.works\"}\n                        target=\"_blank\"\n                        className={cx(classes.alignBaseline, classes.flex, classes.justifyCenter, \"mt-8 mb-14 text-[1.6rem] font-semibold\")}>\n                        Contact us for a quote.\n                    </Link>\n                );\n            } else {\n                const nDevs = plan.multiDevPlan ? seats : 1;\n                const priceData = getPaymentAmount(plan?.id, billingFrequency, nDevs, 0);\n                let vatSubtext = \"\";\n                if (plan.vat === \"inc\") {\n                    vatSubtext = <Text level={3} className={\"my-0!\"}>including {pricing.vat_rates[location]}% VAT</Text>;\n                } else if (plan.vat === \"exc\") {\n                    vatSubtext = <Text level={3} className={\"my-0!\"}>excluding {pricing.vat_rates[location]}% VAT</Text>;\n                }\n\n                const displayPrice = tierOffers?.percentOffer ? (\n                    <>\n                        <span\n                            className={\"mr-2 line-through\"}\n                            style={{ \"text-decoration-color\": \"rgba(255, 101, 65, 0.8)\" }}>\n                            {priceData?.symbol}\n                            {(priceData?.planPrice / (billingFrequency === \"annual\" ? 12 : 1)).toFixed(0)}\n                        </span>\n                        <span>\n                            {priceData?.symbol}\n                            {(\n                                getDiscountedPrice(priceData?.planPrice, tierOffers.percentOffer) /\n                                (billingFrequency === \"annual\" ? 12 : 1)\n                            ).toFixed(0)}\n                        </span>\n                    </>\n                ) : (\n                    <>\n                        {priceData?.symbol}\n                        {(priceData?.planPrice / (billingFrequency === \"annual\" ? 12 : 1)).toFixed(0)}\n                    </>\n                );\n\n                return (\n                    <>\n                        <div className={cx(\"mt-5\", classes.flex, classes.alignBaseline, classes.justifyCenter)}>\n                            <h3 className={\"mt-10 mb-5 text-4xl font-medium\"}>{displayPrice}</h3>\n                            <small>/ month</small>\n                        </div>\n                        {/* Every priced card keeps both subtext lines (blank where they don't apply), so\n                            that the prices themselves line up across the columns. */}\n                        <div className={cx(classes.alignCenter, \"pt-2 pb-4 leading-snug\")}>\n                            <Text level={3} className={cx(\"mt-0! mb-1!\", !plan.multiDevPlan && \"invisible\")}>\n                                for {nDevs} developer{nDevs === 1 ? \"\" : \"s\"}\n                            </Text>\n                            {pricing?.products[plan.id] && pricing.vat_rates[location] > 0 && vatSubtext}\n                        </div>\n                    </>\n                );\n            }\n        },\n        [classes, getPaymentAmount, billingFrequency, pricing?.products, pricing?.vat_rates, location, seats]\n    );\n\n    const planCard = useCallback(\n        (plan) => {\n            const eligibleOfferForTier =\n                eligibleOffers?.[\"feedback-tutorial\"] && eligibleOffers?.[\"feedback-tutorial\"].tier === plan.id;\n            const tierOffers = plan.offers;\n\n            return (\n                <div className={\"h-full grid grid-rows-[repeat(2,_auto)_1fr_repeat(3,_auto)] py-8 px-6 justify-items-center\"}>\n                    <Link\n                        className={cx(\"group !no-underline\")}\n                        target={\"_blank\"}\n                        to={plan.moreInfoUrl || \"https://anvil.works/pricing\"}>\n                        <Heading level={1}\n                                 className={\"leading-normal !m-0 !text-primary group-hover:!text-primary-darker transition-colors\"}>\n                            {plan.name}\n                        </Heading>\n                    </Link>\n                    <Heading level={2} className={\"!mt-0 !mb-6\"}>{plan.summary}</Heading>\n\n                    <ul className={cx(\"w-full\")}>\n                        {plan.features.map((f, idx) => (\n                            <li className={cx(classes.planFeature, \"!bg-light-bg0 dark:!bg-dark-bg6\")} key={idx}>\n                                {f}\n                            </li>\n                        ))}\n                    </ul>\n\n                    {plan.id === \"hobby\" && seats > 1 ? (\n                        <div\n                            className={\"leading-normal p-4 m-4 text-center rounded-md flex items-center gap-4 bg-light-grey0 text-dark-bg4 dark:bg-dark-bg4 dark:text-dark-fg1\"}>\n                            <FontAwesomeIcon icon={faCircleExclamation} className={\"text-4xl\"} />\n                            <p>The Hobby plan is licensed for one developer only</p>\n                        </div>\n                    ) : (plan.id === \"hobby\" && accountType === \"business\") ? (\n                        <div\n                            className={\"leading-normal p-4 m-4 text-center rounded-md flex items-center gap-4 bg-light-grey0 text-dark-bg4 dark:bg-dark-bg4 dark:text-dark-fg1\"}>\n                            <FontAwesomeIcon icon={faCircleExclamation} className={\"text-4xl\"} />\n                            <p>The Hobby plan is licensed for personal use only</p>\n                        </div>\n                    ) : (\n                        planPrice(plan, tierOffers)\n                    )}\n\n                    <div className={cx(\"text-center\")}>\n                        {subscription?.plan === plan?.id && !subscription?.trial && !subscription?.expired ? (\n                            plan?.multiDevPlan ||\n                            billingFrequency !== (initialFreq || subscription?.recurringInterval) ? (\n                                <ModalButton variant={\"primary\"} onClick={() => selectPlan(plan)}>\n                                    Update Plan\n                                </ModalButton>\n                            ) : (\n                                <ModalButton variant={\"outlined\"}> Current Plan </ModalButton>\n                            )\n                        ) : (\n                            <>\n                                {plan.learnMore ? (\n                                    <ModalButton\n                                        onClick={() => {\n                                            const newWindow = window.open(\n                                                plan.learnMore,\n                                                \"_blank\",\n                                                \"noopener,noreferrer\"\n                                            );\n                                            if (newWindow) {\n                                                newWindow.opener = null;\n                                            }\n                                        }}\n                                        variant={\"primary\"}>\n                                        Learn More\n                                    </ModalButton>\n                                ) : PERSONAL_PLANS.includes(plan.id) && currentActiveDevs > 1 ? (\n                                    <ModalButton variant={\"outlined\"}> Remove users to downgrade</ModalButton>\n                                ) : (\n                                    <>\n                                        {eligibleOfferForTier ? (\n                                            <div className={\"m-2 flex items-center justify-center dark:text-grey-2\"}>\n                                                <div\n                                                    ref={discountTTAnchorRef}\n                                                    className={\n                                                        \"bg-secondary-300 text-secondary-900 rounded-full px-4 py-2 text-[11px]\"\n                                                    }>\n                                                    Get a lifetime{\" \"}\n                                                    {eligibleOffers?.[\"feedback-tutorial\"].discountPercent}% discount\n                                                    <FontAwesomeIcon className={\"pl-2\"} icon={faCircleQuestion} />\n                                                </div>\n                                                {discountTT}\n                                            </div>\n                                        ) : tierOffers?.percentOffer || tierOffers?.amountOffer ? (\n                                            <div className={\"m-2 flex flex-col items-center justify-center gap-2 dark:text-grey-2!\"}>\n                                                {[tierOffers.percentOffer, tierOffers.amountOffer]\n                                                    .filter(Boolean)\n                                                    .map((offer) => (\n                                                        <div\n                                                            key={offer.code}\n                                                            className={\n                                                                \"bg-secondary-300 text-secondary-900 rounded-full px-4 py-2 text-[1rem] font-bold\"\n                                                            }>\n                                                            <Link\n                                                                to={\"/docs/overview/milestone-discounts\"}\n                                                                target={\"_blank\"}\n                                                                className=\"mt-2 text-grey-0 underline dark:text-grey-2!\">\n                                                                {formatDiscountLabel(offer)} available at checkout\n                                                            </Link>\n                                                            <FontAwesomeIcon className={\"pl-2\"} icon={faCheck} />\n                                                        </div>\n                                                    ))}\n                                            </div>\n                                        ) : null}\n                                        {(plan.id === \"hobby\" && seats > 1 || plan.id === \"hobby\" && accountType === \"business\") ? (\n                                            <ModalButton variant={\"primary\"} enabled={false}>\n                                                Choose Plan\n                                            </ModalButton>) : (\n                                            <ModalButton variant={\"primary\"} onClick={() => selectPlan(plan)}>\n                                                Choose Plan\n                                            </ModalButton>)}\n                                    </>\n                                )}\n                            </>\n                        )}\n                        {subscription?.plan === plan?.id && subscription?.trial && !subscription?.expired && (\n                            <div className={\"mt-4 font-bold\"}>Current trial</div>\n                        )}\n                    </div>\n                </div>\n            );\n        },\n        [\n            eligibleOffers,\n            classes.planFeature,\n            planPrice,\n            subscription?.plan,\n            subscription?.trial,\n            subscription?.expired,\n            subscription?.recurringInterval,\n            billingFrequency,\n            initialFreq,\n            currentActiveDevs,\n            discountTTAnchorRef,\n            discountTT,\n            selectPlan,\n            seats,\n            accountType,\n        ]\n    );\n\n    const LegacyBanner = useMemo(() => {\n        return (\n            LEGACY_PLANS.includes(subscription?.plan) && (\n                <div className={\"flex gap-8 items-center justify-center my-8 p-2 bg-secondary-100 text-center border border-secondary-300 rounded\"}>\n                    <FontAwesomeIcon className={\"text-6xl text-secondary-400\"} icon={faCircleExclamation} />\n                    <div className={\"text-secondary-900\"}>\n                        You are on a legacy Anvil plan. You may stay on your current plan indefinitely. <br />\n                        If you change your subscription, you won’t be able to go back to your current plan.\n                    </div>\n                </div>\n            )\n        );\n    }, [subscription?.plan]);\n\n\n    const hobbyTooManySeats = selectedPlan?.id === \"hobby\" && seats > 1;\n    const hobbyBusinessUse = selectedPlan?.id === \"hobby\" && accountType === \"business\";\n\n    const formErrors = { hobbyTooManySeats, hobbyBusinessUse };\n\n    return (\n        <>\n            {subscription?.cancelled ? (\n                <Modal\n                    modalId={modalId}\n                    ref={modalRef}\n                    title={`${newOrganisation || trialUpgrade ? \"Upgrade\" : \"Update\"} your subscription`}\n                    size=\"large\">\n                    <Text level={2} className={cx(classes.alignCenter)}>\n                        Plan changes cannot be made while your subscription is cancelled. <></>\n                        {!subscription.isManager ? (\n                            ` If you'd like to rescind this cancellation contact the subscription administrator. `\n                        ) : (\n                            <Button small onClick={() => dispatch(modal(\"unterminateSubscription\", { subscription }))}>\n                                Un-cancel your subscription\n                            </Button>\n                        )}\n                    </Text>\n                </Modal>\n            ) : browsingPlans ? (\n                <Modal\n                    modalId={modalId}\n                    ref={modalRef}\n                    title={`${newOrganisation || trialUpgrade ? \"Upgrade\" : \"Update\"} your subscription`}\n                    size=\"large\"\n                    buttons={[{ text: \"Cancel\", clickActionCreator: () => modalReturn(false) }]}>\n                    {LegacyBanner}\n\n                    <div className={\"flex gap-4 items-center justify-between\"}>\n                        <div className={\"flex min-w-max\"}>\n                            {/* This defaults to allowing the user to change the billing frequency, so behavior is correct for free users, as we don't have a subscription check wrapping this. */}\n                            {capability?.canChangeFrequency === false ? (\n                                <Text className={\"!m-0 !font-bold\"}>\n                                    {billingFrequency === \"monthly\" ? \"Pay monthly\" : \"Pay annually\"}\n                                </Text>\n                            ) : (\n                                <ButtonGroup\n                                    options={filterFreqOptions}\n                                    selectedVariant={\"primary\"}\n                                    selectedOption={billingFrequency}\n                                    onClick={(selection) => setBillingFrequency(selection)}\n                                />\n                            )}\n                        </div>\n                        <div className={\"w-full h-[1px] bg-sectionborder dark:bg-dark-bg4\"}></div>\n                        <div className={\"flex gap-2 items-center min-w-max\"}>\n                            <label>Developer seats</label>\n                            <div className={\"inline-flex items-center\"}>\n                                <IncrementingNumericTextInput\n                                    value={seats}\n                                    small={true}\n                                    changeValueFn={setSeats}\n                                    lowerBound={1}\n                                />\n                            </div>\n                        </div>\n                        <div className=\"flex min-w-max\">\n                            <ButtonGroup\n                                className=\"\"\n                                options={[\n                                    { title: \"Personal Use\", value: \"consumer\" },\n                                    { title: \"Business Use\", value: \"business\" },\n                                ]}\n                                selectedVariant={\"primary\"}\n                                selectedOption={accountType}\n                                onClick={(selection) => setAccountType(selection)}\n                            />\n                        </div>\n                    </div>\n\n                    <div className={cx(\"mt-8 grid grid-cols-4 gap-6\")}>\n                        {plans?.map((plan, idx) => (\n                            <div\n                                key={idx}\n                                className={cx(\"bg-light-bg2 border border-sectionborder rounded-md dark:bg-dark-bg3 dark:border-dark-bg4\")}>\n                                {planCard(plan)}\n                            </div>\n                        ))}\n                    </div>\n\n                </Modal>\n            ) : (\n                <Modal\n                    modalId={modalId}\n                    ref={modalRef}\n                    title={\n                        subscription?.plan === selectedPlan.id || !capability?.canChangePlanLevel\n                            ? `Update your Anvil plan`\n                            : `${newOrganisation || trialUpgrade ? \"Upgrade\" : `Switch`} to the ${getPlanName(\n                                  selectedPlan?.name\n                              )} plan`\n                    }\n                    size=\"large\"\n                    leftButtons={backButton}\n                    buttons={[\n                        {\n                            text: buttonText,\n                            variant: \"primary\",\n                            tooltip:\n                                !formComplete &&\n                                !paymentProcessing &&\n                                \"Complete all required entries to submit the form\",\n                            clickActionCreator: () => handleUpgradeButton(),\n                            icon: faRocket,\n                            enabled: (formChanged || subscription?.trial) && formComplete && !paymentProcessing && Object.values(formErrors).every((error) => !error),\n                            close: false,\n                        },\n                        { text: \"Cancel\", enabled: !paymentProcessing, clickActionCreator: () => modalReturn(false) },\n                    ]}>\n\n                    {/* TODO: Change this to upgrade the payment form design*/}\n\n                    <PaymentForm\n                        userName={user?.name}\n                        countryFromIP={user.ipLocation.country.code}\n                        uiScale={uiScale}\n                        isDarkMode={isDarkMode}\n                        pricing={pricing}\n                        getPaymentAmount={getPaymentAmount}\n                        plan={selectedPlan}\n                        serverUpgrade={subscription?.dedicatedUpgrade || subscription?.aws}\n                        supportUpgrade={subscription?.support}\n                        offers={user?.currentOffers?.active}\n                        displaySupportUpgrade={subscription?.support?.defaultTaxRate}\n                        setFormComplete={setFormComplete}\n                        setFormEntries={setFormEntries}\n                        newOrganisation={newOrganisation}\n                        trialUpgrade={trialUpgrade}\n                        subscription={subscription}\n                        currentActiveDevs={currentActiveDevs}\n                        forceShowAdditionalTableauViewers={forceShowAdditionalTableauViewers}\n                        errMsg={errorMessage}\n                        formErrors={formErrors}\n                        planSelectMarker={planSelectMarker}\n                        setInitialEntries={setInitialEntries}\n                        subscriptionFreq={subscription?.recurringInterval}\n                        switchToBusinessPlan={() => {\n                            const businessPlan = plansWithOffer.find((p) => p.id === \"business\");\n                            if (businessPlan) {\n                                selectPlan(businessPlan);\n                            }\n                        }}\n                        seats={seats}\n                        setSeats={setSeats}\n                        accountType={accountType}\n                        setAccountType={setAccountType}\n                        billingFrequency={billingFrequency}\n                        setBillingFrequency={setBillingFrequency}\n                    />\n                </Modal>\n            )}\n        </>\n    );\n};\n\nexport default Upgrade;\n\nconst lowerTier = {\n    hobby: \"free\",\n    business: \"hobby\",\n    production: \"business\",\n    dedicated: \"business\",\n    enterprise: \"dedicated\",\n};\n\n/** @type {import(\".\").ModalComponent<{subscription?: any, trialUpgrade?: boolean}>} */\nexport const UpgradeSuccessful = ({ modalId, spec: { subscription, trialUpgrade = false } }) => {\n    const [expiryDate, daysRemaining] = useMemo(() => dateAndDaysAway(subscription?.expires), [subscription]);\n    const { classes } = useStyles();\n    return (\n        <Modal\n            modalId={modalId}\n            allowDismiss={true}\n            title={`Plan update successful! 🎉`}\n            buttons={[{ text: \"OK\", clickActionCreator: () => modalReturn(true), defaultButton: true }]}>\n            <Heading level={1}>\n                You're now on {subscription?.trial && \"a trial of\"} the {getPlanName(subscription?.plan)} plan\n                {(subscription?.totalDevCount > 1 || subscription?.additionalTableauViewers > 0) && `,`}\n                {subscription?.totalDevCount > 1 && ` with ${subscription.totalDevCount} seats`}\n                {subscription?.totalDevCount > 1 && subscription?.additionalTableauViewers > 0 && ` and`}\n                {subscription?.additionalTableauViewers > 0 &&\n                    ` with ${subscription.additionalTableauViewers + 10} Tableau Viewers`}\n                !\n            </Heading>\n\n            {trialUpgrade && (\n                <div className={cx(classes.notification)}>\n                    <Text className={\"text-center\"}>\n                        You've upgraded from a trial that terminates in <b>{daysRemaining}</b> days. You'll be able to\n                        finish out the rest of your trial period before your subscription starts and will be charged on{\" \"}\n                        <b>{expiryDate}</b>.\n                    </Text>\n                </div>\n            )}\n\n            <Text>\n                You are able to access everything on the {getPlanName(lowerTier[subscription?.plan])} plan plus the\n                following features:\n            </Text>\n\n            <ul className=\"ml-12\">\n                {planInfo[subscription?.plan].map((pi, idx) => (\n                    <li className={\"list-disc\"} key={idx}>\n                        {pi}\n                    </li>\n                ))}\n            </ul>\n\n            {subscription?.trial && (\n                <div className={cx(\"my-4 text-center\", classes.notification)}>\n                    <Text>\n                        Your trial will expire in <b>{daysRemaining}</b> days, on <b>{expiryDate}</b>.\n                    </Text>\n                </div>\n            )}\n\n            <HelpLink url={\"/pricing#compare\"}>More Info</HelpLink>\n        </Modal>\n    );\n};\n","import {\n    RemoveSelfFromSubscription,\n    RemoveUserFromSubscription,\n} from \"@/components/modals/RemoveUsersFromSubscription\";\nimport TerminateSubscription from \"@/components/modals/TerminateSubscription\";\nimport UnTerminateSubscription from \"@/components/modals/UnTerminateSubscription\";\nimport UpdatePaymentCard from \"@/components/modals/UpdatePaymentCard\";\nimport Upgrade, { UpgradeSuccessful } from \"@/components/modals/Upgrade\";\nimport { UpgradePrompt } from \"@/components/modals/UpgradePrompts\";\nimport { orgAppsModal } from \"@/components/modals/account/OrgApps\";\nimport { ModalTypes } from \"..\";\n\nexport const getAccountModals = () =>\n    ({\n        upgrade: Upgrade,\n        updatePaymentCard: UpdatePaymentCard,\n        upgradePrompt: UpgradePrompt,\n        upgradeSuccessful: UpgradeSuccessful,\n        terminateSubscription: TerminateSubscription,\n        unterminateSubscription: UnTerminateSubscription,\n        removeSelfFromSubscription: RemoveSelfFromSubscription,\n        removeUserFromSubscription: RemoveUserFromSubscription,\n        orgApps: orgAppsModal,\n    }) as const satisfies ModalTypes;\n\nexport type AccountModalTypes = ReturnType<typeof getAccountModals>;\nexport type AccountModalType = keyof AccountModalTypes;\n","import ApiKeyLoginModal from \"@/agent/components/ApiKeyLoginModal\";\nimport CodeLocationsModal from \"@/analysis/CodeLocationsModal\";\nimport AddAssetModal from \"@/components/modals/AddAssetModal\";\nimport { AddExistingTable, AddExistingTableMapping } from \"@/components/modals/AddTableAndMappings\";\nimport AppCta from \"@/components/modals/AppCta\";\nimport AppHistoryModal from \"@/components/modals/AppHistoryModal\";\nimport { BetaWelcomeModal } from \"@/components/modals/BetaWelcome\";\nimport ChooseAppTheme from \"@/components/modals/ChooseAppTheme\";\nimport ChooseFormTypeModal from \"@/components/modals/ChooseFormTypeModal\";\nimport ClaimedAchievement from \"@/components/modals/ClaimedAchievement\";\nimport ConfigureDependency from \"@/components/modals/ConfigureDependency\";\nimport { ConfigureRunner } from \"@/components/modals/ConfigureRunner\";\nimport CreateTag from \"@/components/modals/CreateTag\";\nimport DeleteApp from \"@/components/modals/DeleteApp\";\nimport DirectSQLAccessModal from \"@/components/modals/DirectSQLAccessModal\";\nimport DockerExportModal from \"@/components/modals/DockerExport\";\nimport Git from \"@/components/modals/Git\";\nimport HawthornDeployModal from \"@/components/modals/HawthornDeployModal\";\nimport HtmlLayoutModal from \"@/components/modals/HtmlLayout\";\nimport IdeTutorialIntro from \"@/components/modals/IdeTutorialIntro\";\nimport IntroVideoModal from \"@/components/modals/IntroVideoModal\";\nimport MergeCompletionConflict from \"@/components/modals/MergeCompletionConflict\";\nimport NewServiceModal from \"@/components/modals/NewServiceModal\";\nimport { PipAudit } from \"@/components/modals/PipAudit\";\nimport PreCommitModal from \"@/components/modals/PreCommitModal\";\nimport PreMergeModal from \"@/components/modals/PreMergeModal\";\nimport PreviewV3Designer from \"@/components/modals/PreviewV3Designer\";\nimport RemapDependency from \"@/components/modals/RemapDependency\";\nimport SaveConflict from \"@/components/modals/SaveConflict\";\nimport ScheduledTaskModal from \"@/components/modals/ScheduledTaskModal\";\nimport SchemaMismatchModal from \"@/components/modals/SchemaMismatch\";\nimport { TableauDebugModal, TableauPublishModal } from \"@/components/modals/Tableau\";\nimport TableauCTA from \"@/components/modals/TableauCTA\";\nimport {\n    ConfigureOrUpgradePromptOnRuntimeFeatureRequired,\n    UpgradePromptOnOpenApp,\n} from \"@/components/modals/UpgradePrompts\";\nimport UplinkModal from \"@/components/modals/UplinkModal\";\nimport UploadAppYaml from \"@/components/modals/UploadAppYaml\";\nimport UriUploader from \"@/components/modals/UriUploader\";\nimport WelcomeModal from \"@/components/modals/WelcomeModal\";\nimport AccountModal from \"@/components/modals/account/Account\";\nimport CustomComponent from \"@/components/modals/customcomponent/CustomComponent\";\nimport AddColumn from \"@/components/modals/database/AddColumn\";\nimport AddLinkedRow from \"@/components/modals/database/AddLinkedRow\";\nimport {\n    CloneDatabase,\n    CreateNewDatabaseInPool,\n    RestoreDatabase,\n} from \"@/components/modals/database/DatabasesForDeploymentPools\";\nimport DeleteAllRows from \"@/components/modals/database/DeleteAllRows\";\nimport { EditColumn } from \"@/components/modals/database/EditColumn.tsx\";\nimport SortModal from \"@/components/modals/database/SortModal\";\nimport TableIndexes from \"@/components/modals/database/TableIndexes.tsx\";\nimport TextEditor from \"@/components/modals/database/TextEditor\";\nimport { DNSRequiredNotification, EnvUrlCustom, EnvUrlPublic } from \"@/components/modals/environments/EnvUrlEditModal\";\nimport EnvironmentsModal from \"@/components/modals/environments/EnvironmentsModal\";\nimport AddHTTPRemote from \"@/components/modals/git_remotes/AddHTTPRemote\";\nimport GitCloneApp from \"@/components/modals/git_remotes/GitCloneApp\";\nimport GitDesync from \"@/components/modals/git_remotes/GitDesync\";\nimport GitRemotes from \"@/components/modals/git_remotes/GitRemotes\";\nimport GithubAccountChooser from \"@/components/modals/git_remotes/GithubAccountChooser\";\nimport GithubChooseVisibilityAndLicence from \"@/components/modals/git_remotes/GithubChooseVisibilityAndLicence\";\nimport { GoogleServiceModal } from \"@/components/tabs/GoogleServiceTab\";\nimport { DeleteSecretModal, SecretConfiguredModal, ViewSecretModal } from \"@/components/tabs/SecretsTab\";\nimport ConfirmRemoveTesting from \"@/testing/RemoveTestingService\";\nimport { ModalTypes } from \"..\";\nimport QuickSwitcher from \"../QuickSwitcherModal\";\nimport SizedImageModal from \"../SizedImageModal\";\nimport TemplatesModal from \"../TemplatesModal\";\nimport UpdateFormItemType from \"../UpdateFormItemType\";\nimport AgentClaudeLogin from \"../agent/AgentClaudeLogin\";\nimport AgentCodexLogin from \"../agent/AgentCodexLogin\";\nimport AgentCustomModelProvider from \"../agent/AgentCustomModelProvider\";\nimport AgentUsage from \"../agent/AgentUsage\";\nimport AgentZaiLogin from \"../agent/AgentZaiLogin\";\nimport LazyJsonEditorModal from \"../database/LazyJsonEditor\";\nimport { getAccountModals } from \"./account-modals\";\nimport { commonModalTypes } from \"./common-modals\";\n\nlet ideModalTypes: IDEModalTypes;\n\n// because of circular imports\nconst createIdeModals = () =>\n    ({\n        ...commonModalTypes,\n        ...getAccountModals(),\n        account: AccountModal,\n        uplink: UplinkModal,\n        addservice: NewServiceModal,\n        addExistingTable: AddExistingTable,\n        addExistingDB: AddExistingTableMapping,\n        appHistory: AppHistoryModal,\n        environments: EnvironmentsModal,\n        hawthornDeploy: HawthornDeployModal,\n        envURLpublic: EnvUrlPublic,\n        envURLcustom: EnvUrlCustom,\n        chooseFormType: ChooseFormTypeModal,\n        addasset: AddAssetModal,\n        sizedImageUpload: SizedImageModal,\n        directSQLAccess: DirectSQLAccessModal,\n        deleteSecret: DeleteSecretModal,\n        configuredSecret: SecretConfiguredModal,\n        chooseapptheme: ChooseAppTheme,\n        createTag: CreateTag,\n        saveconflict: SaveConflict,\n        deleteapp: DeleteApp,\n        upgradePromptOnOpenApp: UpgradePromptOnOpenApp,\n        configureOrUpgradePromptOnRuntimeFeatureRequired: ConfigureOrUpgradePromptOnRuntimeFeatureRequired,\n        customcomponent: CustomComponent,\n        gitclone: Git,\n        gitRemotes: GitRemotes,\n        addHTTPRemote: AddHTTPRemote,\n        gitDesync: GitDesync,\n        githubAccountChooser: GithubAccountChooser,\n        gitCloneApp: GitCloneApp,\n        githubChooseVisibilityAndLicence: GithubChooseVisibilityAndLicence,\n        premerge: PreMergeModal,\n        precommit: PreCommitModal,\n        schemaMismatch: SchemaMismatchModal,\n        scheduledTask: ScheduledTaskModal,\n        mergeCompletionConflict: MergeCompletionConflict,\n        betaWelcome: BetaWelcomeModal,\n        tableauDebug: TableauDebugModal,\n        tableauPublish: TableauPublishModal,\n        pipAudit: PipAudit,\n        dnsRequired: DNSRequiredNotification,\n        viewSecret: ViewSecretModal,\n        googleService: GoogleServiceModal,\n        uriChanger: UriUploader,\n        appCta: AppCta,\n        tableauCta: TableauCTA,\n        tableIndexes: TableIndexes,\n        dockerExport: DockerExportModal,\n        deleteAllRows: DeleteAllRows,\n        dbSort: SortModal,\n        dbAddCol: AddColumn,\n        dbEditCol: EditColumn,\n        dbAddLinkedRow: AddLinkedRow,\n        dbJsonEditor: LazyJsonEditorModal,\n        dbTextEditor: TextEditor,\n        remapDependency: RemapDependency,\n        configureDependency: ConfigureDependency,\n        previewV3Designer: PreviewV3Designer,\n        claimedAchievement: ClaimedAchievement,\n        ideTutorialIntro: IdeTutorialIntro,\n        uploadAppYaml: UploadAppYaml,\n        templates: TemplatesModal,\n        welcome: WelcomeModal,\n        quickSwitcher: QuickSwitcher,\n        pythonEditorToolsResults: CodeLocationsModal,\n        htmlLayout: HtmlLayoutModal,\n        updateFormItemType: UpdateFormItemType,\n        configureRunner: ConfigureRunner,\n        cloneDatabase: CloneDatabase,\n        createNewDatabaseInPool: CreateNewDatabaseInPool,\n        introVideo: IntroVideoModal,\n        restoreDatabase: RestoreDatabase,\n        agentApiKeyLogin: ApiKeyLoginModal,\n        agentCodexLogin: AgentCodexLogin,\n        agentClaudeLogin: AgentClaudeLogin,\n        agentZaiLogin: AgentZaiLogin,\n        agentCustomModelProvider: AgentCustomModelProvider,\n        agentUsage: AgentUsage,\n        confirmRemoveTesting: ConfirmRemoveTesting,\n    }) satisfies ModalTypes;\n\nexport const getIdeModals = () => {\n    return (ideModalTypes ??= createIdeModals());\n};\n\nexport type IDEModalTypes = ReturnType<typeof createIdeModals>;\nexport type IDEModalType = keyof IDEModalTypes;\n","import React, { useCallback, useRef, useState } from \"react\";\nimport { ModalComponent } from \"@/components/modals\";\nimport Modal, { ModalRef } from \"@/components/modals/Modal\";\nimport { TextBox } from \"@/components/reusable/Forms.tsx\";\nimport { modalReturn } from \"@/controllers/modals.ts\";\n\nconst ApiKeyLoginModal: ModalComponent<Record<string, never>, string | null> = ({ modalId }) => {\n    const [apiKey, setApiKey] = useState(\"\");\n    const modalRef = useRef<ModalRef>(null);\n\n    const inputRef = useCallback((node: HTMLInputElement | null) => {\n        node?.focus();\n    }, []);\n\n    return (\n        <Modal\n            autoFocus={false}\n            ref={modalRef}\n            modalId={modalId}\n            allowDismiss={true}\n            title={\"Log in with API key\"}\n            buttons={[{\n                text: \"Login\",\n                clickActionCreator: () => modalReturn(apiKey.trim()),\n                defaultButton: true,\n                enabled: apiKey.trim().length > 0,\n            }]}>\n            <div className={\"min-w-96\"}>\n                <TextBox\n                    ref={inputRef}\n                    className={\"w-full\"}\n                    type={\"password\"}\n                    value={apiKey}\n                    placeholder={\"API key\"}\n                    onChange={(e) => setApiKey(e.target.value)}\n                    onKeyDown={(e) => {\n                        if (e.key === \"Enter\" && apiKey.trim()) {\n                            e.preventDefault();\n                            modalRef.current?.returnValue(apiKey.trim());\n                        }\n                    }}\n                />\n            </div>\n        </Modal>\n    );\n};\n\nexport default ApiKeyLoginModal;\n","import { useEffect, useRef, useState } from \"react\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport type { ModalComponent } from \"@/components/modals\";\nimport Modal, { type ModalRef } from \"@/components/modals/Modal\";\nimport { TextBox } from \"@/components/reusable/Forms\";\nimport { useRemToPixels } from \"@/theme/ThemeProvider\";\nimport { cx } from \"@/theme/styles\";\nimport useEvent from \"@/util/useEventCallback\";\nimport type { CodeTarget } from \"./ide-analysis\";\n\nconst CodeLocationsModal: ModalComponent<{ title: string; targets: CodeTarget[] }, CodeTarget> = ({\n    modalId,\n    spec: { title, targets },\n}) => {\n    const modal = useRef<ModalRef>(null);\n    const list = useRef<HTMLDivElement>(null);\n    const searchInput = useRef<HTMLInputElement>(null);\n    useEffect(() => searchInput.current?.focus(), []);\n    const [search, setSearch] = useState(\"\");\n    const [selected, setSelected] = useState(0);\n    const filtered = targets.filter((target) =>\n        `${target.symbol ?? \"\"} ${target.label}`.toLowerCase().includes(search.toLowerCase())\n    );\n    const rowHeight = useRemToPixels(5.6);\n    const rows = useVirtualizer({\n        count: filtered.length,\n        getScrollElement: () => list.current,\n        estimateSize: () => rowHeight,\n        overscan: 5,\n    });\n    useEffect(() => {\n        if (filtered.length) rows.scrollToIndex(selected);\n    }, [selected, filtered.length]);\n    const onChoose = useEvent((index: number) => {\n        if (filtered[index]) void modal.current?.returnValue(filtered[index]);\n    });\n    const onKeyDown = useEvent((event: React.KeyboardEvent) => {\n        if (event.key === \"Enter\") {\n            event.preventDefault();\n            onChoose(selected);\n        }\n        if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n            event.preventDefault();\n            setSelected(Math.max(0, Math.min(filtered.length - 1, selected + (event.key === \"ArrowDown\" ? 1 : -1))));\n            searchInput.current?.focus();\n        }\n    });\n    const onSearchChange = useEvent((event: React.ChangeEvent<HTMLInputElement>) => {\n        setSearch(event.target.value);\n        setSelected(0);\n    });\n\n    return (\n        <Modal ref={modal} modalId={modalId} title={title} autoFocus={false}>\n            <div className=\"flex h-[30vh] flex-col gap-2\" onKeyDown={onKeyDown}>\n                <TextBox\n                    type=\"search\"\n                    aria-label=\"Filter symbols and files\"\n                    ref={searchInput}\n                    value={search}\n                    onChange={onSearchChange}\n                />\n                <div ref={list} className=\"min-h-0 grow overflow-x-hidden overflow-y-auto\">\n                    <div className=\"relative w-full\" style={{ height: rows.getTotalSize() }}>\n                        {rows.getVirtualItems().map((row) => {\n                            const target = filtered[row.index];\n                            return (\n                                <button\n                                    type=\"button\"\n                                    key={row.key}\n                                    className={cx(\n                                        \"absolute top-0 left-0 flex w-full flex-col justify-center border-0 bg-transparent px-4 text-left hover:bg-grey-0 focus-visible:outline-2 focus-visible:outline-primary dark:hover:bg-grey-2\",\n                                        {\n                                            \"bg-light-bg4! dark:bg-dark-bg4!\": row.index === selected,\n                                        }\n                                    )}\n                                    style={{ height: row.size, transform: `translateY(${row.start}px)` }}\n                                    onFocus={() => setSelected(row.index)}\n                                    onClick={() => onChoose(row.index)}>\n                                    <span className=\"w-full truncate text-light-fg1 dark:text-dark-fg1\">\n                                        {target.symbol || target.label}\n                                    </span>\n                                    <span className=\"w-full truncate text-[1.2rem] text-grey-1\">\n                                        {target.label}:{target.line}\n                                        {target.dependencyId ? \" (dependency)\" : \"\"}\n                                    </span>\n                                </button>\n                            );\n                        })}\n                    </div>\n                    {!filtered.length && <p className=\"px-4 py-3 text-grey-1\">No results.</p>}\n                </div>\n            </div>\n        </Modal>\n    );\n};\n\nexport default CodeLocationsModal;\n","import React, { useRef, useState } from \"react\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { Button, ButtonProps } from \"./Button\";\n\nexport interface FileUploadButtonProps extends ButtonProps {\n    onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n    accept?: string;\n    multiple?: boolean;\n    directory?: boolean;\n    children: React.ReactNode;\n    // Add more file input props as needed\n}\n\nconst FileUploadButton: React.FC<FileUploadButtonProps> = ({\n    onChange,\n    children,\n    accept,\n    multiple,\n    directory,\n    ...buttonProps\n}) => {\n    const inputRef = useRef<HTMLInputElement>(null);\n    const [selectedFiles, setSelectedFiles] = useState<FileList | null>(null);\n\n    const handleClick = useEvent(() => {\n        inputRef.current?.click();\n    });\n\n    const onInputChange = useEvent((e: React.ChangeEvent<HTMLInputElement>) => {\n        setSelectedFiles(e.target.files);\n        onChange(e);\n    });\n\n    let buttonText: React.ReactNode = children;\n    if (selectedFiles && selectedFiles.length > 0) {\n        if (selectedFiles.length === 1) {\n            buttonText = `Selected: ${selectedFiles[0].name}`;\n        } else {\n            buttonText = `${selectedFiles.length} files selected`;\n        }\n    }\n\n    return (\n        <>\n            <Button {...buttonProps} onClick={handleClick}>\n                {buttonText}\n            </Button>\n            <input\n                ref={inputRef}\n                type=\"file\"\n                tabIndex={-1}\n                style={{ display: \"none\" }}\n                onChange={onInputChange}\n                accept={accept}\n                multiple={multiple}\n                {...(directory ? { webkitdirectory: \"\" } : {})}\n            />\n        </>\n    );\n};\n\nexport default FileUploadButton;\n","import * as React from \"react\";\nimport { useRef, useState } from \"react\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { cx } from \"@/theme/styles\";\nimport { AssetUpload, droppedAssetFiles, selectedAssetFiles } from \"@/util/assetUploads\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \".\";\nimport FileUploadButton from \"../reusable/FileUploadButton\";\nimport { ContentButton } from \"../reusable/SharedComponents\";\nimport { Heading } from \"../reusable/Text\";\nimport Modal, { ModalRef } from \"./Modal\";\n\nconst assetTypes = [\n    { name: \"HTML File\", ext: \"html\" },\n    { name: \"CSS Stylesheet\", ext: \"css\" },\n    { name: \"JavaScript File\", ext: \"js\" },\n];\n\nfunction isFileEvent(e: React.DragEvent<HTMLDivElement>) {\n    return e.dataTransfer && e.dataTransfer.types.includes(\"Files\");\n}\n\nconst AddAssetModal: ModalComponent<never, AssetUpload[] | string | null> = ({ modalId }) => {\n    const modalRef = useRef<ModalRef>(null);\n    const closing = useRef(false);\n    const [dragActive, setDragActive] = useState(false);\n    const [reading, setReading] = useState(false);\n    const [error, setError] = useState<string | null>(null);\n\n    // Local drop zone events for accessibility/UX\n\n    const onDragOver = useEvent((e: React.DragEvent<HTMLDivElement>) => {\n        if (isFileEvent(e)) {\n            e.preventDefault();\n            e.stopPropagation();\n            setDragActive(true);\n        }\n    });\n    const onDragLeave = useEvent((e: React.DragEvent<HTMLDivElement>) => {\n        e.preventDefault();\n        e.stopPropagation();\n        setDragActive(false);\n    });\n    const onDrop = useEvent(async (e: React.DragEvent<HTMLDivElement>) => {\n        e.preventDefault();\n        e.stopPropagation();\n        setDragActive(false);\n        if (!isFileEvent(e) || reading || closing.current) return;\n        setReading(true);\n        setError(null);\n        try {\n            const files = await droppedAssetFiles(e.dataTransfer);\n            if (closing.current) return;\n            if (files.length) modalRef.current?.returnValue(files);\n            else setError(\"No files found. Empty folders cannot be uploaded.\");\n        } catch {\n            setError(\"Could not read the dropped files. Try selecting them again.\");\n        } finally {\n            setReading(false);\n        }\n    });\n    const onFilesSelected = (e: React.ChangeEvent<HTMLInputElement>) => {\n        if (e.target.files?.length) {\n            modalRef.current?.returnValue(selectedAssetFiles(e.target.files));\n        }\n    };\n\n    return (\n        <Modal\n            ref={modalRef}\n            title=\"Add Asset\"\n            modalId={modalId}\n            beforeClose={() => {\n                // A cancelled read can finish while the modal is still fading out.\n                if (closing.current) return false;\n                closing.current = true;\n            }}\n            buttons={[{ text: \"Cancel\", clickActionCreator: () => modalReturn(null) }]}>\n            <div className=\"text-center\">\n                <Heading level={2}>What type of file would you like to create?</Heading>\n                <div className=\"flex justify-center gap-10\">\n                    {assetTypes.map((t, idx) => (\n                        <ContentButton\n                            key={idx}\n                            variant={\"primary\"}\n                            disabled={reading}\n                            onClick={() => modalRef.current?.returnValue(t.ext)}>\n                            {t.name}\n                        </ContentButton>\n                    ))}\n                </div>\n                <div className=\"mt-20 flex w-full flex-col items-center justify-center gap-10\">\n                    <div\n                        onDragOver={onDragOver}\n                        onDragLeave={onDragLeave}\n                        onDrop={onDrop}\n                        className={cx(\n                            \"mb-4 w-80 rounded-lg border-2 border-dashed p-6 text-center transition-colors\",\n                            dragActive\n                                ? \"border-primary bg-primary-50\"\n                                : \"border-sectionborder dark:border-dark-sectionborder\"\n                        )}>\n                        {reading\n                            ? \"Reading files...\"\n                            : dragActive\n                              ? \"Drop your files and folders here...\"\n                              : \"Drag & drop files and folders here\"}\n                    </div>\n                    <div className=\"flex gap-10\">\n                        <FileUploadButton multiple disabled={reading} onChange={onFilesSelected}>\n                            Upload files\n                        </FileUploadButton>\n                        <FileUploadButton multiple directory disabled={reading} onChange={onFilesSelected}>\n                            Upload folder\n                        </FileUploadButton>\n                    </div>\n                    {error && <p role=\"alert\">{error}</p>}\n                </div>\n            </div>\n        </Modal>\n    );\n};\n\nexport default AddAssetModal;\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faSearch } from \"@fortawesome/pro-light-svg-icons/faSearch\";\nimport { faTimes } from \"@fortawesome/pro-light-svg-icons/faTimes\";\nimport { faPlus } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faUserFriends } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { sortBy } from \"lodash-es\";\nimport { Accordion } from \"@/components/reusable/Accordion\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport { getAppId } from \"@/controllers/app\";\nimport {\n    getAppAccessibleTableMappings,\n    getSharedTableCounts,\n    linkExistingMapping,\n    linkExistingTableToMapping,\n} from \"@/controllers/db\";\nimport { alert, modalReturn } from \"@/controllers/modals\";\nimport { navigate } from \"@/router/navigation\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport type { AccessibleTableMapping, Table, TableMapping } from \"@/types/database\";\nimport { useDebounceFn } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport type { ModalComponent } from \".\";\nimport Modal from \"./Modal\";\nimport type { ModalButtons, ModalRef } from \"./Modal\";\n\ntype AddTableAndMappingsClasses = \"selected\";\n\ntype AddExistingTableSpec = {\n    tableMapping: TableMapping;\n    addNewTable: () => void;\n    addNewTableLabel?: string;\n};\n\ntype AddExistingTableMappingSpec = {\n    createNewDatabase: () => void;\n};\n\ntype AccessibleTable = AccessibleTableMapping[\"tables\"][number] & {\n    alreadyInMapping?: boolean;\n    mappingsNames?: string[];\n    split?: Table[\"split\"];\n};\n\ntype AccessibleMappingWithKey = Omit<AccessibleTableMapping, \"tables\"> & {\n    tables: AccessibleTable[];\n    uniqueKey: string;\n};\n\ntype SelectedTable = {\n    id: string;\n    table: AccessibleTable;\n};\n\ntype SearchResults = {\n    tableMappings: AccessibleMappingWithKey[];\n    tables: AccessibleTable[];\n};\n\nconst useStyles = makeStyles<void, AddTableAndMappingsClasses>()((theme, _props, classes) => ({\n    root: {},\n    dbContainer: {\n        maxHeight: \"50rem\",\n        overflowY: \"auto\",\n        border: \"1px solid \" + theme.sectionBorderColor.toString(),\n        // overflowX: \"hidden\",\n        maxWidth: \"100%\",\n        width: \"100%\",\n    },\n    sharedIcon: {\n        position: \"absolute\",\n        left: \"3rem\",\n    },\n    selected: {\n        background: theme.accordion.children.selectedBg.toString(),\n    },\n    tableRow: {\n        position: \"relative\",\n        display: \"flex\",\n        minWidth: 0,\n        color: theme.accordion.children.color.toString(),\n        background: theme.accordion.children.background.toString(),\n        padding: \"0.7rem 2rem\",\n\n        [`&${classes.selected}`]: {\n            background: theme.accordion.children.selectedBg.toString(),\n        },\n\n        \"&:hover\": {\n            cursor: \"pointer\",\n            background: theme.accordion.children.hoverBackground.toString(),\n            [`&.${classes.selected}`]: {\n                background: theme.accordion.children.selectedBg.toString(),\n            },\n        },\n    },\n    dbSelector: {\n        padding: \"0.7rem 3rem\",\n\n        \"&:hover\": {\n            cursor: \"pointer\",\n            background: theme.accordion.children.hoverBackground.toString(),\n            [`&.${classes.selected}`]: {\n                background: theme.accordion.children.selectedBg.toString(),\n            },\n        },\n    },\n    defaultDBHeader: {\n        flex: 1,\n        minWidth: 0,\n    },\n    mappingHeader: {\n        fontWeight: \"normal\",\n        width: \"100%\",\n    },\n    accordionRoot: {},\n    searchBox: {\n        height: \"4rem\",\n        border: \"1px solid \" + theme.sectionBorderColor.toString(),\n        borderRadius: 0,\n        paddingLeft: \"4rem\",\n    },\n    searchIcon: {\n        position: \"absolute\",\n        top: \"1rem\",\n        left: \"1.2rem\",\n        fontSize: \"2rem\",\n        color: theme.formInput.placeholderColor.toString(),\n    },\n    clearSearchIconLink: {\n        position: \"absolute\",\n        top: 0,\n        right: 0,\n        padding: \"2px 1.2rem\",\n        fontSize: \"2rem\",\n        color: theme.formInput.placeholderColor.toString(),\n        \"&:hover\": {\n            color: theme.formInput.color.toString(),\n        },\n    },\n    searchBoxContainer: {\n        position: \"relative\",\n        margin: \"3rem 0\",\n    },\n    noResults: {\n        background: theme.modal.addMappingOrTable.noResults.background.toString(),\n        color: theme.modal.addMappingOrTable.noResults.color.toString(),\n        textAlign: \"center\",\n        padding: \"1rem 0\",\n    },\n    disabledAdd: {\n        background: theme.modal.addMappingOrTable.noResults.background.toString(),\n        color: theme.modal.addMappingOrTable.noResults.color.toString(),\n        cursor: \"default !important\",\n        \"&:hover\": {\n            cursor: \"default !important\",\n            background: theme.modal.addMappingOrTable.noResults.background.toString(),\n            color: theme.modal.addMappingOrTable.noResults.color.toString(),\n        },\n    },\n}));\n\ninterface MappingHeaderProps {\n    name: string;\n    apps: AccessibleTableMapping[\"apps\"];\n    table_mapping_id: AccessibleTableMapping[\"table_mapping_id\"];\n}\n\nconst MappingHeader = ({ name, apps, table_mapping_id }: MappingHeaderProps) => {\n    const { classes } = useStyles();\n\n    const appIds = useMemo(() => Object.keys(apps || {}), [apps]);\n    const appList = useMemo(() => Object.values(apps)?.join(\", \"), [apps]);\n\n    return (\n        <>\n            {table_mapping_id ? (\n                <div className={cx(\"flex w-full\")}>\n                    <div title={name} className={cx(\"w-1/2 overflow-hidden pr-4 text-ellipsis whitespace-nowrap\")}>\n                        {name}\n                    </div>\n                    <div className={\"flex w-1/2\"}>\n                        <div className={cx(\"w-16\")}>\n                            {appIds.length > 1 && <FontAwesomeIcon icon={faUserFriends} />}\n                        </div>\n                        <div\n                            title={appList}\n                            className={cx(\"w-full overflow-hidden pr-4 text-ellipsis whitespace-nowrap\")}>\n                            {appList}\n                        </div>\n                    </div>\n                </div>\n            ) : (\n                <div className={cx(classes.defaultDBHeader)}>\n                    <div\n                        title={`${name} of ${appList}`}\n                        className={\"overflow-hidden pr-4 text-ellipsis whitespace-nowrap\"}>\n                        {name} of '<span className={\"font-semibold\"}>{appList}</span>'\n                    </div>\n\n                    {/* <div alt={table.name} title={table.name} className={cx(\"w-full text-ellipsis overflow-hidden whitespace-nowrap pr-4\")}>{table.name} ( <span className={\"font-mono\"}>{table.python_name}</span> )</div>\n                     */}\n                </div>\n            )}\n        </>\n    );\n};\n\ninterface MappingTablesProps {\n    sharedTables: Record<Table[\"id\"], number>;\n    tables: AccessibleTable[];\n    mappingIdentifier?: string | null;\n    selectedTable: SelectedTable | null;\n    setSelectedTable: React.Dispatch<React.SetStateAction<SelectedTable | null>>;\n}\n\nconst MappingTables = ({\n    sharedTables,\n    tables,\n    mappingIdentifier = null,\n    selectedTable,\n    setSelectedTable,\n}: MappingTablesProps) => {\n    const { classes } = useStyles();\n\n    const tableRow = useCallback(\n        (table: AccessibleTable, idx: number) => {\n            const appList = table?.mappingsNames?.join(\", \");\n            const uniqueTableId = `${mappingIdentifier}_${table.id}`;\n            return (\n                <div\n                    key={idx}\n                    className={cx(\n                        classes.tableRow,\n                        uniqueTableId === selectedTable?.id && classes.selected,\n                        table.alreadyInMapping && classes.disabledAdd\n                    )}\n                    onClick={() => {\n                        !table.alreadyInMapping && setSelectedTable({ id: uniqueTableId, table });\n                    }}>\n                    <div className={cx(table?.mappingsNames && \"w-1/2\", \"flex min-w-0 items-center\")}>\n                        {sharedTables[table.id] > 1 && (\n                            <FontAwesomeIcon className={cx(classes.sharedIcon)} icon={faUserFriends} />\n                        )}\n                        <div\n                            className={\"overflow-hidden pr-4 pl-20 text-ellipsis whitespace-nowrap\"}\n                            title={table.python_name}>\n                            {table.name} ( <span className={\"font-mono\"}>{table.python_name}</span> )\n                        </div>\n                    </div>\n                    {table?.mappingsNames && (\n                        <div\n                            title={appList}\n                            className={cx(\"w-1/2 overflow-hidden pl-12 text-ellipsis whitespace-nowrap\")}>\n                            {appList}\n                        </div>\n                    )}\n                </div>\n            );\n        },\n        [selectedTable, mappingIdentifier, classes]\n    );\n\n    return <>{tables?.map((table, idx) => tableRow(table, idx))}</>;\n};\n\nconst addExistingTableConnector = connect((state: State) => ({\n    appId: getAppId(state),\n    accessibleTableMappings: getAppAccessibleTableMappings(state),\n    sharedTables: getSharedTableCounts(state),\n}));\n\ntype AddExistingTableProps = AnvilConnectedProps<typeof addExistingTableConnector>;\n\nconst AddExistingTableComponent: ModalComponent<AddExistingTableSpec, boolean | null, AddExistingTableProps> = ({\n    modalId,\n    appId,\n    accessibleTableMappings,\n    sharedTables,\n    dispatch,\n    spec: { tableMapping, addNewTable, addNewTableLabel = \"Add New Table\" },\n}) => {\n    const { classes } = useStyles();\n    const modalRef = useRef<ModalRef>(null);\n\n    const [selectedTable, setSelectedTable] = useState<SelectedTable | null>(null);\n    const [selectedMapping, setSelectedMapping] = useState<string | null>(null);\n    const [search, setSearch] = useState(\"\");\n    const [searching, setSearching] = useState(false);\n\n    const addNewTableInstead = useCallback(() => {\n        addNewTable();\n        return modalRef.current!.returnValue(false);\n    }, [modalRef, addNewTable]);\n\n    const addExistingTable = useCallback(\n        async (mapping: TableMapping, table: AccessibleTable) => {\n            const linkedTable = await dispatch(linkExistingTableToMapping(mapping, table as Table));\n            if (\"error\" in linkedTable && linkedTable.error) {\n                dispatch(\n                    alert(\n                        \"An error has occurred\",\n                        \"Sorry, we were unable to add the table. Please contact support@anvil.works for more help.\"\n                    )\n                );\n                return;\n            }\n            dispatch(navigate({ type: \"DB_TABLE\", tableMappingId: mapping.table_mapping_id, tableId: table.id }));\n        },\n        [appId]\n    );\n\n    const [defaultDBs, setDefaultDBs] = useState<AccessibleMappingWithKey[]>([]);\n    const [tableMappings, setTableMappings] = useState<AccessibleMappingWithKey[]>([]);\n\n    useEffect(() => {\n        const idsInMap = tableMapping?.tables.map((table) => table.id);\n        const restrictedTableIds = new Set(\n            accessibleTableMappings?.filter((mapping) => mapping.restricted).flatMap(({ tables }) => tables.map(({ id }) => id))\n        );\n\n        const mappingsWithSharedOrNotIndicator: Array<\n            Omit<AccessibleTableMapping, \"tables\"> & { tables: AccessibleTable[] }\n        > = [];\n\n        accessibleTableMappings?.forEach((mapping) => {\n            if (\n                !(\n                    mapping.tables?.length < 1 ||\n                    (mapping.table_mapping_id === tableMapping.table_mapping_id &&\n                        Object.keys(mapping.apps).includes(appId!))\n                )\n            ) {\n                const tables = mapping.tables.filter((table) => tableMapping.restricted || !restrictedTableIds.has(table.id)).map((table) => {\n                    if (idsInMap.includes(table.id)) {\n                        return { ...table, alreadyInMapping: true };\n                    }\n                    return table;\n                });\n                if (tables.length) mappingsWithSharedOrNotIndicator.push({ ...mapping, tables });\n            }\n        });\n\n        const defaults: AccessibleMappingWithKey[] = [],\n            nonDefaults: AccessibleMappingWithKey[] = [];\n\n        //todo: figure how to do prioritized sort so can just iterate thru once\n        mappingsWithSharedOrNotIndicator?.forEach((mapping) => {\n            const m = { ...mapping, uniqueKey: `${mapping.table_mapping_id}-${Object.keys(mapping.apps)?.[0]}` };\n            m.tables?.sort((a, b) => a.name.localeCompare(b.name));\n\n            if (mapping.table_mapping_id === null) {\n                defaults.push(m);\n            } else {\n                nonDefaults.push(m);\n            }\n        });\n\n        defaults?.sort((a, b) => Object.values(a.apps)[0].localeCompare(Object.values(b.apps)[0]));\n        nonDefaults?.sort((a, b) => a.name.localeCompare(b.name));\n\n        setDefaultDBs(defaults);\n        setTableMappings(nonDefaults);\n    }, [accessibleTableMappings, tableMapping?.tables, tableMapping.restricted, appId]);\n\n    const sortedMappingsWithKey = useMemo(() => {\n        return [...defaultDBs, ...tableMappings];\n    }, [tableMappings, defaultDBs]);\n\n    const selectDB = useCallback(\n        (m: AccessibleMappingWithKey) => {\n            setSelectedTable(null);\n            setSelectedMapping(m.uniqueKey === selectedMapping ? null : m.uniqueKey);\n        },\n        [selectedMapping]\n    );\n\n    const modalButtons = useMemo<ModalButtons>(() => {\n        const buttons: ModalButtons = [];\n        if (selectedTable) {\n            buttons.push({\n                text: `Add '${selectedTable.table.name}'`,\n                variant: \"primary\",\n                clickActionCreator: () => addExistingTable(tableMapping, selectedTable.table),\n                shrinkable: true,\n            });\n        }\n        buttons.push({ text: \"Cancel\", clickActionCreator: () => modalReturn(null) });\n        return buttons;\n    }, [tableMapping, selectedTable]);\n\n    const [searchResults, setSearchResults] = useState<SearchResults>({ tableMappings: [], tables: [] });\n\n    const applySearchToMappings = useEvent((searchTerm: string) => {\n        const mappingsWithMatchNames: AccessibleMappingWithKey[] = [];\n        const tablesWithMatchNames: AccessibleTable[] = [];\n        if (searchTerm)\n            sortedMappingsWithKey.forEach((mapping) =>\n                searchMappingAndAppNames(searchTerm, mapping, mappingsWithMatchNames, tablesWithMatchNames)\n            );\n        setSearchResults({ tableMappings: mappingsWithMatchNames, tables: tablesWithMatchNames });\n    });\n\n    const runSearch = useEvent((useOverride?: string | React.SyntheticEvent) => {\n        const searchTerm = typeof useOverride === \"string\" ? useOverride : search;\n        const s = searchTerm.toLowerCase();\n        applySearchToMappings(s);\n        setSelectedTable(null);\n        setSelectedMapping(null);\n    });\n    const debouncedSearch = useDebounceFn(runSearch, 250);\n    const delayedShowSearching = useDebounceFn(() => setSearching(true), 250);\n    const doSearch = useEvent((useOverride?: string | React.SyntheticEvent) => {\n        debouncedSearch.cancel();\n        runSearch(useOverride);\n    });\n\n    useEffect(() => {\n        delayedShowSearching.cancel();\n        if (search) {\n            delayedShowSearching();\n        } else {\n            setSearching(false);\n        }\n    }, [search]);\n\n    useEffect(() => {\n        debouncedSearch(search);\n    }, [search, sortedMappingsWithKey]);\n\n    return (\n        <Modal\n            modalId={modalId}\n            ref={modalRef}\n            allowDismiss={true}\n            title={`Add an existing table to '${tableMapping?.name}'`}\n            size={\"large\"}\n            className={cx()}\n            buttons={modalButtons}>\n            {sortedMappingsWithKey.length > 0 ? (\n                <div>\n                    <div>\n                        <Text level={1}>\n                            Adding an existing table will connect that table to your database - not make a copy of it.\n                            Any changes made to a shared table will be visible in all databases that contain that table.\n                        </Text>\n                        <div className={classes.searchBoxContainer}>\n                            <ContentTextInput\n                                className={classes.searchBox}\n                                placeholder=\"Search for a table using the name, app, or database\"\n                                value={search}\n                                onChange={(e) => setSearch(e.target.value)}\n                                onEnter={() => doSearch()}\n                            />\n                            <FontAwesomeIcon icon={faSearch} className={classes.searchIcon} />\n                            {search && (\n                                <LinkInternal\n                                    className={classes.clearSearchIconLink}\n                                    onClick={() => {\n                                        setSearch(\"\");\n                                        doSearch(\"\");\n                                    }}>\n                                    <FontAwesomeIcon icon={faTimes} />\n                                </LinkInternal>\n                            )}\n                        </div>\n                    </div>\n                    {searching && <Heading level={1}>Search Results</Heading>}\n                    <Heading level={2}>Databases</Heading>\n                    <div className={cx(classes.dbContainer)}>\n                        <Accordion\n                            items={searching ? searchResults.tableMappings : sortedMappingsWithKey}\n                            expandedKeys={\n                                (search ? searchResults.tableMappings : sortedMappingsWithKey)?.length === 1\n                                    ? {\n                                          [(search ? searchResults.tableMappings : sortedMappingsWithKey)[0].uniqueKey]:\n                                              true,\n                                      }\n                                    : { [String(selectedMapping)]: true }\n                            }\n                            keyName={\"uniqueKey\"}\n                            onToggle={selectDB}\n                            headerStyle={{ height: \"4rem\" }}\n                            headerClass={classes.mappingHeader}\n                            rootClass={classes.accordionRoot}\n                            renderHeader={({ name, apps, table_mapping_id }, idx, isExpanded) => (\n                                <MappingHeader table_mapping_id={table_mapping_id} name={name} apps={apps} />\n                            )}\n                            renderBody={({ tables, uniqueKey }, idx) => (\n                                <MappingTables\n                                    sharedTables={sharedTables}\n                                    key={idx}\n                                    mappingIdentifier={uniqueKey}\n                                    tables={tables}\n                                    selectedTable={selectedTable}\n                                    setSelectedTable={setSelectedTable}\n                                />\n                            )}\n                        />\n                        {searching && searchResults.tableMappings.length < 1 && (\n                            <div className={cx(classes.noResults)}>\n                                No databases or apps with tables found for '{search}'\n                            </div>\n                        )}\n                    </div>\n\n                    {searching && (\n                        <div className={\"mt-12\"}>\n                            <Heading level={2}>Tables</Heading>\n                            <div className={cx(classes.dbContainer)}>\n                                <MappingTables\n                                    sharedTables={sharedTables}\n                                    tables={searchResults?.tables}\n                                    selectedTable={selectedTable}\n                                    setSelectedTable={setSelectedTable}\n                                />\n                                {search && searchResults?.tables.length < 1 && (\n                                    <div className={cx(classes.noResults)}>No tables found for '{search}'</div>\n                                )}\n                            </div>\n                        </div>\n                    )}\n                </div>\n            ) : (\n                <div className={cx(classes.noResults)}>\n                    No existing tables available\n                    <div className={\"m-12\"}>\n                        <Button onClick={addNewTableInstead} variant={\"primary\"} icon={faPlus}>\n                            {addNewTableLabel}\n                        </Button>\n                    </div>\n                </div>\n            )}\n        </Modal>\n    );\n};\n\nexport const AddExistingTable = addExistingTableConnector(\n    AddExistingTableComponent\n) as typeof AddExistingTableComponent;\n\ninterface AddableMappingsProps {\n    mapping: AccessibleMappingWithKey;\n    selectedMapping: AccessibleMappingWithKey | null;\n    setSelectedMapping: React.Dispatch<React.SetStateAction<AccessibleMappingWithKey | null>>;\n}\n\nconst AddableMappings = ({ mapping, selectedMapping, setSelectedMapping }: AddableMappingsProps) => {\n    const { classes } = useStyles();\n    return (\n        <div\n            className={cx(classes.dbSelector, selectedMapping === mapping && classes.selected)}\n            onClick={() => setSelectedMapping(mapping)}>\n            <MappingHeader name={mapping.name} apps={mapping.apps} table_mapping_id={mapping.table_mapping_id} />\n        </div>\n    );\n};\n\nconst addExistingTableMappingConnector = connect((state: State) => ({\n    appId: getAppId(state),\n    accessibleTableMappings: getAppAccessibleTableMappings(state),\n}));\n\ntype AddExistingTableMappingProps = AnvilConnectedProps<typeof addExistingTableMappingConnector>;\n\nconst AddExistingTableMappingComponent: ModalComponent<\n    AddExistingTableMappingSpec,\n    boolean | null,\n    AddExistingTableMappingProps\n> = ({ modalId, appId, accessibleTableMappings, dispatch, spec: { createNewDatabase } }) => {\n    const { classes } = useStyles();\n    const modalRef = useRef<ModalRef>(null);\n    const [search, setSearch] = useState(\"\");\n    const [searching, setSearching] = useState(false);\n    const [selectedMapping, setSelectedMapping] = useState<AccessibleMappingWithKey | null>(null);\n\n    const addNewMappingInstead = useCallback(() => {\n        createNewDatabase();\n        return modalRef.current!.returnValue(false);\n    }, [modalRef, createNewDatabase]);\n\n    const sortedMappingsWithKey = useMemo(() => {\n        const mappings = accessibleTableMappings?.filter((m) => {\n            const appIds = Object.keys(m.apps);\n            return !appIds.includes(appId!) && m.table_mapping_id;\n        });\n\n        //todo: sort the tables\n        return sortBy(mappings, [(mapping) => mapping.table_mapping_id !== null, (mapping) => mapping.name]).map(\n            (itm) => {\n                return { ...itm, uniqueKey: `${itm.table_mapping_id}-${Object.keys(itm.apps)?.[0]}` };\n            }\n        );\n    }, [accessibleTableMappings, appId]);\n\n    const addExistingMapping = useCallback(async () => {\n        const linkedMapping = await dispatch(linkExistingMapping(selectedMapping!.table_mapping_id));\n\n        if (\"error\" in linkedMapping && linkedMapping.error) {\n            dispatch(\n                alert(\n                    \"An error has occurred\",\n                    \"Sorry, we were unable to link this database. Please contact support@anvil.works for more help.\"\n                )\n            );\n        }\n    }, [selectedMapping]);\n\n    const modalButtons = useMemo<ModalButtons>(() => {\n        const buttons: ModalButtons = [];\n        if (selectedMapping) {\n            buttons.push({\n                text: `Add '${selectedMapping.name}'`,\n                variant: \"primary\",\n                clickActionCreator: addExistingMapping,\n                shrinkable: true,\n            });\n        }\n        buttons.push({ text: \"Cancel\", clickActionCreator: () => modalReturn(null) });\n        return buttons;\n    }, [selectedMapping]);\n\n    const [searchResults, setSearchResults] = useState<AccessibleMappingWithKey[]>([]);\n\n    const applySearchToMappings = useEvent((searchTerm: string) => {\n        const mappingsWithMatchNames: AccessibleMappingWithKey[] = [];\n        if (searchTerm)\n            sortedMappingsWithKey.forEach((mapping) =>\n                searchMappingAndAppNames(searchTerm, mapping, mappingsWithMatchNames)\n            );\n        setSearchResults(mappingsWithMatchNames);\n    });\n\n    const runSearch = useEvent((useOverride?: string | React.SyntheticEvent) => {\n        const searchTerm = typeof useOverride === \"string\" ? useOverride : search;\n        const s = searchTerm.toLowerCase();\n        applySearchToMappings(s);\n        setSelectedMapping(null);\n    });\n    const debouncedSearch = useDebounceFn(runSearch, 250);\n    const delayedShowSearching = useDebounceFn(() => setSearching(true), 250);\n    const doSearch = useEvent((useOverride?: string | React.SyntheticEvent) => {\n        debouncedSearch.cancel();\n        runSearch(useOverride);\n    });\n\n    useEffect(() => {\n        delayedShowSearching.cancel();\n        if (search) {\n            delayedShowSearching();\n        } else {\n            setSearching(false);\n        }\n    }, [search]);\n\n    useEffect(() => {\n        debouncedSearch(search);\n    }, [search, sortedMappingsWithKey]);\n\n    return (\n        <Modal\n            ref={modalRef}\n            modalId={modalId}\n            allowDismiss={true}\n            title={`Add an existing database to the app`}\n            size={\"large\"}\n            className={cx()}\n            buttons={modalButtons}>\n            {sortedMappingsWithKey.length > 0 ? (\n                <div>\n                    <div>\n                        <Text level={1}>\n                            Adding an existing database will connect the database to your app. The data will not be\n                            copied, and any changes you make will be visible in all apps connected to this database.\n                        </Text>\n                        <div className={classes.searchBoxContainer}>\n                            <ContentTextInput\n                                className={classes.searchBox}\n                                placeholder=\"Search for a database using the name or app\"\n                                value={search}\n                                onChange={(e) => setSearch(e.target.value)}\n                                onEnter={() => doSearch()}\n                            />\n                            <FontAwesomeIcon icon={faSearch} className={classes.searchIcon} />\n                            {search && (\n                                <LinkInternal\n                                    className={classes.clearSearchIconLink}\n                                    onClick={() => {\n                                        setSearch(\"\");\n                                        doSearch(\"\");\n                                    }}>\n                                    <FontAwesomeIcon icon={faTimes} />\n                                </LinkInternal>\n                            )}\n                        </div>\n                    </div>\n                    {searching && <Heading level={1}>Search Results</Heading>}\n                    <Heading level={2}>Databases</Heading>\n                    <div className={cx(classes.dbContainer)}>\n                        {(searching ? searchResults : sortedMappingsWithKey)?.map((m) => (\n                            <AddableMappings\n                                key={m.table_mapping_id}\n                                mapping={m}\n                                selectedMapping={selectedMapping}\n                                setSelectedMapping={setSelectedMapping}\n                            />\n                        ))}\n                        {searching && searchResults.length < 1 && (\n                            <div className={cx(classes.noResults)}>\n                                No databases or apps with tables found for '{search}'\n                            </div>\n                        )}\n                    </div>\n                </div>\n            ) : (\n                <div className={cx(classes.noResults)}>\n                    No databases available for sharing. Default databases cannot be shared between apps, but you can\n                    share their tables individually.\n                    <div className={\"m-12\"}>\n                        <Button onClick={addNewMappingInstead} variant={\"primary\"} icon={faPlus}>\n                            Add New Database\n                        </Button>\n                    </div>\n                </div>\n            )}\n        </Modal>\n    );\n};\n\nexport const AddExistingTableMapping = addExistingTableMappingConnector(\n    AddExistingTableMappingComponent\n) as typeof AddExistingTableMappingComponent;\n\nconst searchMappingAndAppNames = (\n    searchTerm: string,\n    mapping: AccessibleMappingWithKey,\n    matchedMappings: AccessibleMappingWithKey[],\n    matchedTables: AccessibleTable[] | null = null\n) => {\n    if (mapping.name.toLowerCase().indexOf(searchTerm) > -1) {\n        //searching name of mapping\n        if (!(\"default database\".indexOf(searchTerm) > -1 && !mapping.table_mapping_id)) {\n            matchedMappings.push(mapping);\n        }\n    }\n\n    const appIds = Object.keys(mapping.apps);\n\n    appIds.forEach((id) => {\n        if (!matchedMappings.includes(mapping)) {\n            if (mapping.apps[id].toLowerCase().indexOf(searchTerm) > -1) {\n                //searching name of an app\n                matchedMappings.push(mapping);\n            } else if (id.toLowerCase() === searchTerm) {\n                //matching with ID of app\n                matchedMappings.push(mapping);\n            }\n        }\n    });\n    if (matchedTables) {\n        const mappingName = mapping.table_mapping_id\n            ? mapping.name\n            : mapping.name + \" of \" + Object.values(mapping.apps)[0];\n        mapping.tables.forEach((table) => {\n            const alreadyAdded = matchedTables.find((t) => t.id === table.id);\n            if (alreadyAdded) {\n                alreadyAdded.mappingsNames!.push(mappingName);\n            } else {\n                if (\n                    table.name.toLowerCase().indexOf(searchTerm) > -1 ||\n                    table.python_name.toLowerCase().indexOf(searchTerm) > -1\n                ) {\n                    matchedTables.push({ ...table, mappingsNames: [mappingName] });\n                }\n            }\n        });\n    }\n};\n","import React from \"react\";\nimport { faChevronRight } from \"@fortawesome/pro-light-svg-icons/faChevronRight\";\nimport { AnvilCtaSpec } from \"@/controllers/app/cta\";\nimport { ModalComponent } from \".\";\nimport { modalReturn } from \"../../controllers/modals\";\nimport { Button } from \"../reusable/Button\";\nimport { Text } from \"../reusable/Text\";\nimport Modal from \"./Modal\";\n\nconst AppCta: ModalComponent<AnvilCtaSpec> = ({ modalId, spec: { description, href, headline } }) => {\n    return (\n        <Modal\n            title={headline ?? \"How to build this app\"}\n            modalId={modalId}\n            buttons={[\n                { text: \"Close\" },\n                {\n                    text: \"Got it! Don't show this again.\",\n                    defaultButton: true,\n                    clickActionCreator: () => modalReturn(true),\n                },\n            ]}>\n            <Text>{description}</Text>\n            {href && (\n                <div className={\"mt-4\"}>\n                    <Button icon={faChevronRight} iconRight variant={\"secondary\"} onClick={() => window.open(href)}>\n                        View the tutorial\n                    </Button>\n                </div>\n            )}\n        </Modal>\n    );\n};\n\nexport default AppCta;\n","import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { connect, useDispatch } from \"react-redux\";\nimport { faChevronDown } from \"@fortawesome/free-solid-svg-icons\";\nimport { NoodlePane } from \"@/components/bottom_panel/History\";\nimport { Button } from \"@/components/reusable/Button\";\nimport DropdownMenu from \"@/components/reusable/DropdownMenu\";\nimport { ModalButton } from \"@/components/reusable/SharedComponents\";\nimport {\n    getAppCommitHistory,\n    getAppMalleableCommits,\n    getAppRefs,\n    updateAppCommitHistory,\n} from \"@/controllers/app/history\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { type AnvilConnectedProps, AnvilDispatch, type State } from \"@/types\";\nimport type { CommitVersion } from \"@/types/app-history\";\nimport type { ModalComponent } from \".\";\nimport type { ModalRef } from \"./Modal\";\nimport Modal from \"./Modal\";\n\nconst useStyles = makeStyles<void, \"selectedCommit\">()((theme, _props, classes) => ({\n    root: {},\n    selectedCommit: {},\n    //TODO: these colors need to be better and match the theme\n    commit: {\n        [`&.${classes.selectedCommit}`]: {\n            // background: theme.primary.lighten(0.5).hex(),\n            background: theme.isDark ? theme.hl1.alpha(0.5).toString() : theme.primary.lighten(0.5).hex(),\n            \"&:hover\": {\n                backgroundColor: theme.isDark ? theme.hl1.alpha(0.5).toString() : theme.primary.lighten(0.5).hex(), //theme.palette.bg1.hex(),\n            },\n        },\n        [`&:not(.${classes.selectedCommit}):hover`]: {\n            backgroundColor: theme.isDark ? theme.palette.bg2.hex() : theme.palette.bg1.hex(),\n        },\n    },\n    h60: {\n        maxHeight: \"60vh\", // prevent pane going off screen in environment modal branch selection #2983\n    },\n    lowerButtons: {\n        marginTop: \"2rem\",\n        display: \"flex\",\n        justifyContent: \"flex-end\",\n        gap: \"1rem\",\n    },\n    selectBranchAnchor: {\n        position: \"absolute\",\n        left: -2,\n        bottom: -2,\n    },\n}));\n\nconst connector = connect((state: State) => ({\n    commitHistory: getAppCommitHistory(state)!,\n    refs: getAppRefs(state),\n    malleableCommits: getAppMalleableCommits(state),\n}));\n\ntype AppHistoryModalProps = AnvilConnectedProps<typeof connector>;\n\ninterface AppHistorySelection {\n    branch?: string;\n    commitId?: string;\n    tag?: string;\n}\n\ntype AppHistoryModalComponent = ModalComponent<\n    { initialCommitId?: string | null },\n    AppHistorySelection,\n    AppHistoryModalProps\n>;\n\nconst AppHistoryModal: AppHistoryModalComponent = ({\n    modalId,\n    commitHistory,\n    refs,\n    malleableCommits,\n    spec: { initialCommitId },\n}) => {\n    const { classes } = useStyles();\n\n    const modalRef = useRef<ModalRef>(null);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const malleableCommitIds = useMemo(() => {\n        const ids: string[] = [];\n        for (const [ref, x] of Object.entries(malleableCommits || {})) {\n            if (x) {\n                ids.push(x.oid);\n            }\n        }\n        return ids;\n    }, [malleableCommits]);\n\n    const [selectedCommit, setSelectedCommit] = useState<CommitVersion | undefined>(() =>\n        commitHistory.versions.find((v) => v.v === initialCommitId)\n    );\n\n    useEffect(() => {\n        if (!selectedCommit && initialCommitId) {\n            const commit = commitHistory.versions.find((v) => v.v === initialCommitId);\n            if (commit) {\n                setSelectedCommit(commit);\n            }\n        }\n    }, [commitHistory.versions, initialCommitId, selectedCommit]);\n\n    const selectVersionButton = useMemo(() => {\n        let tagButtons;\n        const tagsOnCommit: string[] = [];\n        for (const [tag, { commitId }] of Object.entries(refs.tags || {})) {\n            if (commitId === selectedCommit?.v && !tag.startsWith(\"anvil-preserved/\")) tagsOnCommit.push(tag);\n        }\n        console.log(\"tags\", tagsOnCommit);\n        switch (tagsOnCommit.length) {\n            case 0:\n                tagButtons = <></>;\n                break;\n            case 1:\n                tagButtons = (\n                    <ModalButton\n                        variant={\"secondary\"}\n                        onClick={() => modalRef.current!.returnValue({ tag: tagsOnCommit[0] })}>\n                        Select {tagsOnCommit[0]}\n                    </ModalButton>\n                );\n                break;\n            default:\n                tagButtons = (\n                    <>\n                        <DropdownMenu\n                            onSelectItem={(tag) => {\n                                tag && modalRef.current!.returnValue({ tag });\n                            }}\n                            render={(showMenu, anchor) => (\n                                <>\n                                    <Button\n                                        variant={\"secondary\"}\n                                        onClick={(e) => showMenu(null, e.currentTarget)}\n                                        icon={faChevronDown}\n                                        iconRight>\n                                        Select tag\n                                        <div className={classes.selectBranchAnchor}>{anchor}</div>\n                                    </Button>\n                                </>\n                            )}\n                            items={() => tagsOnCommit}\n                            align={\"left\"}\n                        />\n                    </>\n                );\n                break;\n        }\n        return tagButtons;\n    }, [refs.tags, selectedCommit?.v, classes.selectBranchAnchor]);\n\n    const selectBranchButton = useMemo(() => {\n        let branchButtons;\n        const branchesOnCommit: string[] = [];\n        for (const [branch, { commitId }] of Object.entries(refs.branches || {})) {\n            if (commitId === selectedCommit?.v) branchesOnCommit.push(branch);\n        }\n\n        switch (branchesOnCommit.length) {\n            case 0:\n                branchButtons = <></>;\n                break;\n            case 1:\n                branchButtons = (\n                    <ModalButton\n                        variant={\"primary\"}\n                        onClick={() => modalRef.current!.returnValue({ branch: branchesOnCommit[0] })}>\n                        Select branch '{branchesOnCommit[0]}'\n                    </ModalButton>\n                );\n                break;\n            default:\n                branchButtons = (\n                    <DropdownMenu\n                        onSelectItem={(branch) => {\n                            branch && modalRef.current!.returnValue({ branch });\n                        }}\n                        render={(showMenu, anchor) => (\n                            <>\n                                <Button\n                                    variant={\"primary\"}\n                                    onClick={(e) => showMenu(null, e.currentTarget)}\n                                    icon={faChevronDown}\n                                    iconRight>\n                                    Select branch\n                                    <div className={cx(classes.selectBranchAnchor)}>{anchor}</div>\n                                </Button>\n                            </>\n                        )}\n                        items={() => branchesOnCommit}\n                        align={\"left\"}\n                    />\n                );\n                break;\n        }\n\n        return branchButtons;\n    }, [refs.branches, selectedCommit?.v, classes.selectBranchAnchor]);\n\n    const selectionButtons = useMemo(() => {\n        return (\n            <>\n                {selectedCommit && (\n                    <>\n                        {selectBranchButton}\n                        {selectVersionButton}\n                        <ModalButton onClick={() => modalRef.current!.returnValue({ commitId: selectedCommit.v })}>\n                            Select commit\n                        </ModalButton>\n                    </>\n                )}\n                <ModalButton onClick={() => modalRef.current!.returnValue(false)}>Cancel</ModalButton>\n            </>\n        );\n    }, [selectBranchButton, selectVersionButton, selectedCommit]);\n\n    return (\n        <Modal modalId={modalId} title=\"Choose a version\" ref={modalRef}>\n            <NoodlePane\n                commits={commitHistory.versions}\n                classes={classes}\n                className={classes.h60}\n                initialSelectedCommit={selectedCommit}\n                malleableCommitIds={malleableCommitIds}\n                onSelectCommit={setSelectedCommit}\n                onLoadMore={async () => await dispatch(updateAppCommitHistory(commitHistory.versions.length + 50))}\n            />\n            <div className={classes.lowerButtons}>{selectionButtons}</div>\n        </Modal>\n    );\n};\n\nexport default connector(AppHistoryModal) as typeof AppHistoryModal;\n","import * as React from \"react\";\nimport { faFlagCheckered } from \"@fortawesome/pro-light-svg-icons\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { ModalComponent } from \".\";\nimport Link from \"../reusable/Link\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport Modal from \"./Modal\";\n\nexport const BetaWelcomeModal: ModalComponent = ({ modalId }) => {\n    return (\n        <Modal\n            modalId={modalId}\n            title={\"Announcing: The New Anvil Editor\"}\n            icon={faFlagCheckered}\n            buttons={[{ text: \"Close\", close: true, clickActionCreator: () => modalReturn(true) }]}>\n            <div style={{ textAlign: \"center\" }}>\n                <Heading>Welcome to Anvil's new App Editor</Heading>\n            </div>\n\n            <Text>\n                Anvil's Classic Editor has now been retired. Using the modern Anvil Editor gives you access to version\n                control, tabbed editing, more powerful UIs, and more. Take a look around!\n            </Text>\n            <Text>\n                To learn more,{\" \"}\n                <Link to={\"https://anvil.works/docs/editor\"} target={\"_blank\"}>\n                    see the documentation.\n                </Link>\n            </Text>\n        </Modal>\n    );\n};\n","import React, { useMemo, useRef } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { isEqual } from \"lodash-es\";\nimport { LEGACY_CUSTOM_COMPONENT_SPEC } from \"@runtime/runner/component-spec-constants\";\nimport { ComponentYaml, FormLayoutYaml, FormYaml } from \"@runtime/runner/data\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { getApp, getAppRuntimeVersion } from \"@/controllers/app\";\nimport { getDependencyCode } from \"@/controllers/app/code\";\nimport { componentYamlTypesReferToSameForm } from \"@/controllers/app/form-spec-readers\";\nimport { makeLegacyCustomComponentSpec } from \"@/controllers/app/form-spec-writers\";\nimport { LayoutSpec, getAllCustomLayouts } from \"@/controllers/designer\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { blankFormTemplate, defaultStandardFormCode, htmlComponent } from \"@/controllers/util\";\nimport { BLANK_PANEL, CUSTOM_HTML, LAYOUT } from \"@/data/imageUrls\";\nimport { cx } from \"@/theme/styles\";\nimport { FormItemYaml, FormTemplate, FullView } from \"@/types\";\nimport { ImageWithRetry, useMaybeRemoveAssetPrefix } from \"@/util/hooks/assets\";\nimport { useIsMobileIde } from \"@/util/hooks/use-mobile-ide\";\nimport { ModalComponent } from \".\";\nimport Modal, { ModalRef } from \"./Modal\";\n\n// Form templates are stored in the app that defines them. When a dependency\n// template is inserted into this app, legacy local customComponentSpecs inside\n// the template must become legacy dependency customComponentSpecs so they still\n// resolve against the dependency app.\nconst qualifyFormTemplateFromDependency = (form: FormYaml, logicalDepId: string | null | undefined) => {\n    const qualifyDep = (customComponentSpec: string) => {\n        const match = customComponentSpec.match(LEGACY_CUSTOM_COMPONENT_SPEC);\n        if (!match) {\n            return customComponentSpec;\n        }\n\n        const [, existingLogicalDepId, appLocalFormName] = match;\n        return existingLogicalDepId\n            ? customComponentSpec\n            : makeLegacyCustomComponentSpec(appLocalFormName, logicalDepId);\n    };\n\n    const qualifyComponents = (components: ComponentYaml[] = []): ComponentYaml[] =>\n        components?.map(({ type, components, ...component }) => ({\n            type: qualifyDep(type),\n            // Child components are also authored in the dependency template's\n            // app context, so recurse through the whole component tree.\n            ...(components ? { components: qualifyComponents(components) } : {}),\n            ...component,\n        }));\n\n    form = { ...form };\n    if (form.layout) {\n        form.layout = { ...form.layout, type: qualifyDep(form.layout.type) };\n        form.components_by_slot = Object.fromEntries(\n            Object.entries(form.components_by_slot || {}).map(([slotName, components]) => [\n                slotName,\n                qualifyComponents(components),\n            ])\n        );\n    } else if (form.container) {\n        form.container = { ...form.container, type: qualifyDep(form.container.type) };\n        form.components = qualifyComponents(form.components);\n    }\n\n    return form;\n};\n\ninterface ChooseFormButtonProps {\n    title: React.ReactNode;\n    description: React.ReactNode;\n    img: string;\n    current?: boolean;\n    onClick: () => void;\n}\n\nconst ChooseFormButton = ({ title, description, img, current, onClick }: ChooseFormButtonProps) => {\n    const src = useMaybeRemoveAssetPrefix(img);\n    return (\n        <LinkInternal\n            className={cx(\n                \"flex h-100 w-100 max-w-full flex-[0_0_auto] flex-col overflow-hidden rounded-[0.4rem] border-2 border-solid border-sectionborder bg-light-bg2 text-center dark:border-dark-sectionborder dark:bg-dark-bg3\",\n                current\n                    ? \"border-primary!\"\n                    : \"hover:border-primary! hover:bg-sidebar-highlight1 active:bg-light-bg4 dark:hover:bg-[#484d5866] dark:active:bg-dark-bg3!\"\n            )}\n            onClick={onClick}>\n            <ImageWithRetry\n                className=\"h-52 flex-none border-b-2 border-light-bg4 bg-contain bg-center dark:border-dark-bg4\"\n                src={src}\n            />\n\n            <div className=\"mx-5 mt-6 flex-none text-2xl font-semibold text-light-grey2 dark:text-white\">{title}</div>\n            <div className=\"flex-1\" />\n            <div className=\"max-h-21 flex-none overflow-hidden px-4 pb-4 text-xl leading-[1.4] font-medium text-light-bg6 dark:text-dark-fg1\">\n                {description}\n            </div>\n            <div className=\"flex-1\" />\n        </LinkInternal>\n    );\n};\n\ninterface ChooseFormSpec {\n    layoutForFormClassName?: string;\n    currentLayoutType?: string;\n    currentLayout?: FormLayoutYaml;\n}\n\nexport type ChooseFormTypeResult = { form: Omit<FormItemYaml, \"id\">; initialView?: FullView } | null;\n\nconst ChooseFormTypeModal: ModalComponent<ChooseFormSpec, ChooseFormTypeResult> = ({ spec, modalId }) => {\n    const mobile = useIsMobileIde();\n    const app = useSelector(getApp);\n    if (!app) {\n        throw new Error(\"app is not loaded\");\n    }\n    const runtimeVersion = useSelector(getAppRuntimeVersion);\n    const dependencyCode = useSelector(getDependencyCode);\n    const customLayouts = useSelector(getAllCustomLayouts);\n\n    const { layoutForFormClassName, currentLayout, currentLayoutType } = spec;\n    const modalRef = useRef<ModalRef>(null!);\n\n    const initialTemplates = app.initialCode.theme?.templates;\n\n    const chooseFormButtons = useMemo(() => {\n        type Template = [FormTemplate, string | null | undefined];\n\n        const templates: FormTemplate[] = initialTemplates ?? [];\n\n        const onAddCustomLayoutForm = (layout: FormLayoutYaml) => {\n            modalRef.current.returnValue({\n                form: {\n                    class_name: \"Form\",\n                    layout,\n                    code: defaultStandardFormCode,\n                    is_package: true,\n                },\n            });\n        };\n\n        // for (const [depId, { form_templates, runtime_options, error }] of Object.entries(dependencyCode)) {\n        //     if (!error && form_templates && runtime_options.version >= 3) {\n        //         const logicalDepId = findLogicalDepIdForDepAppId(depId, app.config);\n        //         templates.push(...form_templates.map((template) => [template, logicalDepId] as Template));\n        //     }\n        // }\n\n        const btns = [];\n\n        const btnPropsFromLayout = ({ name, layout, metadata }: LayoutSpec) => ({\n            title: metadata.title || name,\n            description: metadata?.description || \"\",\n            img: metadata.thumbnail || LAYOUT,\n            onClick: () => onAddCustomLayoutForm(layout),\n            current:\n                componentYamlTypesReferToSameForm(currentLayoutType, layout.type, {\n                    appPackageName: app.config.package_name,\n                    dependencies: app.config.dependencies,\n                    dependencyIds: app.config.dependency_ids,\n                    dependencyCode,\n                }) ||\n                currentLayoutType === makeLegacyCustomComponentSpec(name) ||\n                (currentLayoutType === \"HtmlTemplate\" && isEqual(currentLayout, layout)),\n        });\n\n        const btnPropsFromTemplate = ([template, logicalDepId]: Template) => ({\n            title:\n                template.name +\n                (logicalDepId ? ` (from ${dependencyCode[app.config.dependency_ids[logicalDepId]].name})` : \"\"),\n            description: template.description,\n            img: template.img ? \"ide/\" + template.img : LAYOUT,\n            onClick: () => {\n                modalRef.current.returnValue({ form: qualifyFormTemplateFromDependency(template.form, logicalDepId) });\n            },\n        });\n\n        if (runtimeVersion >= 3) {\n            btns.push(...customLayouts.filter((cl) => !cl.fromDependency).map(btnPropsFromLayout));\n        }\n\n        if (!layoutForFormClassName) {\n            btns.push(...templates.map((t) => btnPropsFromTemplate([t, null])));\n        }\n\n        if (runtimeVersion >= 3) {\n            btns.push(\n                ...customLayouts.filter((cl) => cl.fromDependency && !cl.metadata.internal).map(btnPropsFromLayout)\n            );\n        }\n\n        if (!layoutForFormClassName) {\n            btns.push({\n                title: \"Blank Panel\",\n                description: \"Start with an empty drag-and-drop layout.\",\n                img: BLANK_PANEL,\n                onClick: () => {\n                    modalRef.current.returnValue({ form: blankFormTemplate });\n                },\n            });\n\n            btns.push({\n                title: \"Custom HTML\",\n                description: \"Build a page, component, or layout with HTML.\",\n                img: CUSTOM_HTML,\n                onClick: () => {\n                    modalRef.current.returnValue({\n                        form: htmlComponent,\n                        initialView: { design: true, html: true, focus: \"html\" },\n                    });\n                },\n            });\n        }\n\n        return btns.map((props, idx) => <ChooseFormButton key={idx} {...props} />);\n    }, [\n        layoutForFormClassName,\n        runtimeVersion,\n        customLayouts,\n        dependencyCode,\n        app.config,\n        currentLayout,\n        currentLayoutType,\n        initialTemplates,\n    ]);\n\n    return (\n        <Modal\n            ref={modalRef}\n            title={layoutForFormClassName ? \"Choose Layout\" : \"New Form\"}\n            size={\"large\"}\n            modalId={modalId}\n            buttons={[{ text: \"Cancel\", clickActionCreator: () => modalReturn(null) }]}>\n            {!layoutForFormClassName && (\n                <h4 className={\"my-12 text-3xl font-bold\"}>What will your new page look like?</h4>\n            )}\n\n            <div className={\"text-center\"}>\n                <div\n                    className={cx(\n                        \"justify-items-center gap-12\",\n                        mobile\n                            ? \"grid w-full grid-cols-[repeat(auto-fit,minmax(min(100%,25rem),1fr))]\"\n                            : \"inline-grid grid-cols-3\"\n                    )}>\n                    {chooseFormButtons}\n                </div>\n            </div>\n        </Modal>\n    );\n};\n\nexport default ChooseFormTypeModal;\n","import React from \"react\";\nimport { faClock } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faArrowTrendUp, faTrophy } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport Modal from \"@/components/modals/Modal\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal.tsx\";\nimport { Heading } from \"@/components/reusable/Text\";\nimport useEvent from \"@/util/useEventCallback.ts\";\nimport { ModalComponent } from \".\";\n\nconst openInNewTab = (url: string) => {\n    const newWindow = window.open(url, \"_blank\", \"noopener\");\n    if (newWindow) {\n        newWindow.opener = null;\n    }\n};\n\n// This will (hopefully) eventually cover multiple achievements, but for now it's only for completing the IDE tutorial\n\ninterface TutorialSuggestionProps {\n    title: string;\n    timeEst: number;\n    level: string;\n    url: string;\n}\nconst tutorials: TutorialSuggestionProps[] = [\n    {\n        title: \"Build a Simple Feedback Form\",\n        timeEst: 10,\n        level: \"Beginner\",\n        url: \"/learn/tutorials/feedback-form\",\n    },\n    {\n        title: \"Build Database-Backed Apps\",\n        timeEst: 20,\n        level: \"Beginner\",\n        url: \"/learn/tutorials/database-backed-apps\",\n    },\n    {\n        title: \"Building multi-user Applications\",\n        timeEst: 10,\n        level: \"Intermediate\",\n        url: \"/learn/tutorials/multi-user-apps\",\n    },\n];\n\nconst TutorialPanel = ({ tutorial }: { tutorial: TutorialSuggestionProps }) => {\n    const { title, timeEst, level, url } = tutorial;\n    const onClick = useEvent(() => {\n        openInNewTab(url);\n    });\n    return (\n        <LinkInternal\n            onClick={onClick}\n            role=\"button\"\n            className=\"block w-full rounded border-1 border-sectionborder bg-light-bg2 px-12 pt-4 pb-8 hover:bg-light-bg3 dark:border-dark-sectionborder dark:bg-dark-bg2 hover:dark:bg-dark-bg1\">\n            <Heading level={1}>{title}</Heading>\n            <div className={\"flex gap-x-6\"}>\n                <div className={\"flex items-center gap-2 text-xl text-light-grey1\"}>\n                    <FontAwesomeIcon icon={faClock} />\n                    <span>~{timeEst}m</span>\n                </div>\n                <div className={\"flex items-center gap-2 text-xl text-light-grey1\"}>\n                    <FontAwesomeIcon icon={faArrowTrendUp} />\n                    <span>{level}</span>\n                </div>\n            </div>\n        </LinkInternal>\n    );\n};\n\nconst ClaimedAchievement: ModalComponent = ({ modalId }) => {\n    return (\n        <Modal\n            icon={faTrophy}\n            title={\"Achievement Unlocked\"}\n            modalId={modalId}\n            buttons={[{ text: \"Close\", close: true }]}>\n            <div>\n                {/*<div className={\"flex-none\"}>*/}\n                {/*    <img src={\"/ide/img/trophy.jpeg\"} className={\"mt-2 mr-8 w-[200px]\"} />*/}\n                {/*</div>*/}\n                Congratulations! You've completed the intro tutorial and now you can explore all the features of Anvil.\n                <Heading level={1}>What's next?</Heading>\n                Now that you've got the basics down, why not try some more in-depth tutorials?\n                <div className={\"mx-2 mt-6 grid grid-cols-2 gap-4\"}>\n                    {tutorials.map((tutorial) => (\n                        <TutorialPanel key={tutorial.title} tutorial={tutorial} />\n                    ))}\n                </div>\n            </div>\n        </Modal>\n    );\n};\n\nexport default ClaimedAchievement;\n","import React, { useCallback } from \"react\";\nimport { faPlus, faTrashAlt } from \"@fortawesome/pro-light-svg-icons\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { Text } from \"@/components/reusable/Text\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { cleanPythonName, useResetState } from \"./helpers\";\nimport { TEvent, TEventUpdater, TParamUpdater, TParameter } from \"./types\";\n\ninterface ParametersProps {\n    event: TEvent;\n    doUpdate: TEventUpdater;\n}\nexport const Parameters = ({ event, doUpdate }: ParametersProps) => {\n    const parameters = event.parameters || [];\n\n    const addOrUpdateParameter: TParamUpdater = useCallback(\n        (param, updatedParam) => {\n            param ??= {} as TParameter;\n            const name = cleanPythonName(updatedParam.name || param.name, param, parameters);\n            const newParams = [...parameters];\n            let idx = parameters.indexOf(param);\n            idx = idx === -1 ? parameters.length : idx;\n            const newParam = { ...param, ...updatedParam, name };\n            if (!newParam.description) {\n                // don't include empty description in the yaml\n                delete newParam.description;\n            }\n            newParams[idx] = newParam;\n            doUpdate(event, { parameters: newParams });\n        },\n        [event, doUpdate]\n    );\n\n    const deleteParameter = useCallback(\n        (param: TParameter) => doUpdate(event, { parameters: parameters.filter((p) => p !== param) }),\n        [event]\n    );\n\n    return (\n        <>\n            <div className=\"flex flex-col gap-4\">\n                {parameters.map((param, i) => {\n                    const doUpdate = (newParam: Partial<TParameter>) => addOrUpdateParameter(param, newParam);\n                    const onDelete = () => deleteParameter(param);\n                    return (\n                        <ParameterRow\n                            key={`${i}-${parameters.length}`}\n                            parameter={param}\n                            onDelete={onDelete}\n                            doUpdate={doUpdate}\n                        />\n                    );\n                })}\n                <Button\n                    onClick={() => addOrUpdateParameter(null, { name: \"param\" })}\n                    small={true}\n                    icon={faPlus}\n                    className=\"w-fit\"\n                    variant=\"primary\">\n                    Add parameter\n                </Button>\n                <Text level={3} className=\"m-0 flex-1 text-lg!\">\n                    Event parameters must be passed as keyword arguments to <code>raise_event</code>, and will be made\n                    available as named parameters in auto-generated event handlers.\n                </Text>\n            </div>\n        </>\n    );\n};\n\ninterface ParamRowProps {\n    parameter: TParameter;\n    onDelete: () => void;\n    doUpdate: (update: Partial<TEvent>) => void;\n}\n\nexport const ParameterRow = ({ parameter, onDelete, doUpdate }: ParamRowProps) => {\n    const [name, setName] = useResetState(parameter.name, \"\", parameter);\n    const [description, setDescription] = useResetState(parameter.description, \"\", parameter);\n    const onBlur = useEvent(() => doUpdate({ name, description }));\n\n    return (\n        <div className=\"flex gap-4\">\n            <ContentTextInput\n                disableEsc\n                className=\"flex-0.5 dark:placeholder:text-gray-400!\"\n                small={true}\n                value={name}\n                onChange={(e) => setName(e.target.value)}\n                onBlur={onBlur}\n                onEnter={onBlur}\n                placeholder={\"name\"}></ContentTextInput>\n            <ContentTextInput\n                disableEsc\n                className=\"flex-1 dark:placeholder:text-gray-400!\"\n                placeholder={\"description\"}\n                small={true}\n                value={description}\n                onChange={(e) => setDescription(e.target.value)}\n                onBlur={onBlur}\n                onEnter={onBlur}\n            />\n            <LinkInternal tabIndex={-1} icon={faTrashAlt} onClick={onDelete} />\n        </div>\n    );\n};\n","import React from \"react\";\nimport { RadioButton } from \"@/components/reusable/Forms\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { Parameters } from \"./Parameters\";\nimport { AdvancedExpander, DescriptionInput, PropSection } from \"./SubComponents\";\nimport type { TEvent, TEventUpdater } from \"./types\";\n\ninterface EventBodyProps {\n    event: TEvent;\n    doUpdate: TEventUpdater;\n}\n\nexport const EventBody = ({ event, doUpdate }: EventBodyProps) => {\n    const { default_event: isDefault } = event;\n    return (\n        <div className=\"p-4\">\n            <PropSection title=\"Description\">\n                <DescriptionInput placeholder={\"when the component is...\"} item={event} doUpdate={doUpdate} />\n            </PropSection>\n\n            <AdvancedExpander type=\"event\">\n                <PropSection title=\"Default Event\">\n                    <div className=\"flex flex-1 flex-col gap-4\">\n                        <RadioButton\n                            className=\"m-0 flex text-lg font-normal\"\n                            checked={isDefault || false}\n                            onChange={() => doUpdate(event, { default_event: !isDefault })}>\n                            Make this the default event\n                        </RadioButton>\n                        <Text level={3} className=\"m-0 text-lg!\">\n                            Auto-create an event handler for this event easily from the Anvil Designer.\n                        </Text>\n                    </div>\n                </PropSection>\n                <PropSection title=\"Parameters\">\n                    <div className=\"flex-1\">\n                        <Parameters event={event} doUpdate={doUpdate}></Parameters>\n                    </div>\n                </PropSection>\n            </AdvancedExpander>\n        </div>\n    );\n};\n","import { CustomComponentToolboxItem, EnumPropertyDescription } from \"@runtime/components/Component\";\nimport { LayoutMetadata } from \"@runtime/runner/data\";\nimport { FormItemYaml } from \"@/types\";\n\nexport const ID_KEY = Symbol(\"id\");\nexport const IS_NEW = Symbol(\"new\");\n\nexport type TProperty = Required<FormItemYaml>[\"properties\"][number] & {\n    [ID_KEY]?: string;\n    [IS_NEW]?: boolean;\n};\nexport type TEnumProperty = TProperty & EnumPropertyDescription;\nexport type TProperties = TProperty[];\n\nexport type TEvent = Required<FormItemYaml>[\"events\"][number] & { [ID_KEY]?: string; [IS_NEW]?: boolean };\nexport type TEvents = TEvent[];\n\nexport type TParameter = Required<TEvent>[\"parameters\"][number];\n\nexport interface CustomFormItem extends Partial<FormItemYaml> {\n    properties?: TProperties;\n    events?: TEvents;\n    custom_component?: boolean;\n    custom_component_container?: boolean;\n    toolbox_item?: CustomComponentToolboxItem;\n    layout_metadata?: LayoutMetadata;\n}\n\nexport type TUpdater<T> = (v: T | null, u: Partial<T>) => void;\n\nexport type TPropUpdater = TUpdater<TProperty>;\nexport type TEventUpdater = TUpdater<TEvent>;\nexport type TParamUpdater = TUpdater<TParameter>;\n","import React, { useCallback, useLayoutEffect, useRef, useState } from \"react\";\nimport { faGripLines, faPencilAlt, faTrashAlt } from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { cx } from \"@/theme/styles\";\nimport { blockEvent, stopPropagation } from \"@/util\";\nimport { useDrag, useDrop } from \"@/util/dnd\";\nimport { useResetState, useSwapPropEvent } from \"./helpers\";\nimport { IS_NEW, TEvent, TProperty, TUpdater } from \"./types\";\n\n/**\n * extracted logic for a textbox input that should focus when editing starts\n */\nfunction useNameBuffer<T extends TEvent | TProperty>(name: string, item: T) {\n    const [editingName, setEditingName] = useState(false);\n    const [nameBuffer, setNameBuffer] = useResetState(name, \"\", item);\n\n    const nameEditBox = useRef<HTMLInputElement>(null);\n\n    useLayoutEffect(() => {\n        if (editingName && nameEditBox.current) {\n            nameEditBox.current.focus();\n            nameEditBox.current.select();\n        }\n    }, [editingName]);\n\n    return { nameEditBox, nameBuffer, setNameBuffer, editingName, setEditingName } as const;\n}\n\ninterface PropHeaderProps<T extends TEvent | TProperty> {\n    name: string;\n    subtitle?: string;\n    onDelete: () => void;\n    item: T;\n    updateName: (name: string) => void;\n    onSwap: ReturnType<typeof useSwapPropEvent>;\n    index: number;\n    type: T extends TProperty ? \"properties\" : \"events\";\n    doUpdate: TUpdater<T>;\n    updateDragState: (state: { [index: number]: boolean }) => void;\n}\n\nexport const PropEventHeader = <T extends TEvent | TProperty>({\n    name,\n    subtitle,\n    onDelete,\n    updateName,\n    doUpdate,\n    item,\n    onSwap,\n    index,\n    type,\n    updateDragState,\n}: PropHeaderProps<T>) => {\n    const { nameEditBox, nameBuffer, setNameBuffer, editingName, setEditingName } = useNameBuffer(name, item);\n\n    // DIRTY HACK TO MAKE RENAMING WORK FOR A NEW ITEM\n    if (item[IS_NEW]) {\n        delete item[IS_NEW];\n        setEditingName(true);\n    }\n\n    const finishEditingName = useCallback(() => {\n        setEditingName(false);\n        if (nameBuffer !== name) {\n            updateName(nameBuffer);\n        }\n    }, [updateName, name, nameBuffer]);\n\n    const toggleEditingName = useCallback(() => {\n        setEditingName(!editingName);\n        if (editingName) {\n            finishEditingName();\n        }\n    }, [editingName, finishEditingName]);\n\n    const [renameTooltip, renameTooltipRef] = useTooltip(\"Rename\", \"top\", { delay: true });\n    const [deleteTooltip, deleteTooltipRef] = useTooltip(\"Delete\", \"top\", { delay: true });\n\n    const [_, dropRef] = useDrop({\n        accept: type,\n        onDrop: ({ index: fromIndex }) => {\n            onSwap(fromIndex, index);\n        },\n        onOverChange: ({ isOver, canDrop }) => {\n            // we need to tell the parent about the drop state\n            updateDragState({ [index]: isOver && canDrop });\n        },\n    });\n\n    const [, dragRef] = useDrag({ type, item: { name: item.name, index } });\n\n    return (\n        <div ref={dropRef} className=\"flex items-center gap-4 px-2\">\n            <div className=\"flex-auto\">\n                {editingName ? (\n                    <ContentTextInput\n                        className=\"h-auto! bg-light-bg2! py-1! font-mono text-xl! font-semibold! text-grey-2 dark:bg-dark-bg2! dark:text-dark-fg3\"\n                        small\n                        ref={nameEditBox}\n                        value={nameBuffer}\n                        onChange={(e) => setNameBuffer(e.target.value)}\n                        onMouseDown={stopPropagation}\n                        onMouseUp={stopPropagation}\n                        onClick={stopPropagation}\n                        onBlur={(e) => {\n                            finishEditingName();\n                        }}\n                        disableEsc\n                        onEnter={() => finishEditingName()}\n                    />\n                ) : (\n                    <>\n                        <div className=\"font-mono text-xl font-semibold text-grey-2 dark:text-dark-fg3\">{name}</div>\n                        {subtitle && (\n                            <div className=\"text-base font-medium text-light-bg6 dark:text-dark-fg3\">{subtitle}</div>\n                        )}\n                    </>\n                )}\n            </div>\n            <div className=\"flex flex-initial items-center gap-1\">\n                <Button\n                    ref={renameTooltipRef}\n                    variant=\"hidden\"\n                    onClick={toggleEditingName}\n                    // @ts-ignore\n                    onMouseDown={(e) => {\n                        if (editingName) {\n                            blockEvent(e);\n                        }\n                        // stops the race condition with the onBlur of the TextBox\n                    }}>\n                    <FontAwesomeIcon icon={faPencilAlt} />\n                    {renameTooltip}\n                </Button>\n                <Button ref={deleteTooltipRef} variant=\"hidden\" onClick={onDelete}>\n                    {deleteTooltip}\n                    <FontAwesomeIcon icon={faTrashAlt} />\n                </Button>\n                <Button linkClassName=\"cursor-move!\" ref={dragRef} preventDefaultClick={false} variant=\"hidden\">\n                    <FontAwesomeIcon icon={faGripLines} />\n                </Button>\n            </div>\n        </div>\n    );\n};\n","import React from \"react\";\nimport { startCase } from \"lodash-es\";\nimport { DesignerHint } from \"@runtime/components/Component\";\nimport { CheckBox } from \"@/components/reusable/Forms\";\nimport { ContentDropdownMenuItem, ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport { useResetState } from \"./helpers\";\nimport { TPropUpdater, TProperty } from \"./types\";\n\ninterface PropertyBodyProps {\n    property: TProperty;\n    doUpdate: TPropUpdater;\n}\n\nconst DESIGNER_HINTS: Partial<Record<TProperty[\"type\"], DesignerHint[]>> = {\n    boolean: [\"enabled\", \"font-bold\", \"font-italic\", \"font-underline\", \"toggle\", \"visible\", \"disabled\"],\n    enum: [\"align-horizontal\"],\n    // string: [\"border\"],\n    // color: [\"background-color\", \"foreground-color\"],\n    uri: [\"asset-upload\"],\n};\n\nconst DesignSection = ({ title, body, info }: { title: string; body: React.ReactNode; info: string }) => (\n    <>\n        <div className=\"flex items-center gap-4\">\n            <Heading level={3} className=\"m-0! flex-0.5\">\n                {startCase(title)}:\n            </Heading>\n            {body}\n        </div>\n        <Text level={3} className=\"m-0! text-sm\">\n            {info}\n        </Text>\n    </>\n);\n\nexport const PropertyDesigner = ({ property, doUpdate }: PropertyBodyProps) => {\n    const { priority, important = false } = property;\n    const [group, setGroup] = useResetState(property.group, \"\", property);\n    const [priorityAsString, setPriorityAsString] = useResetState(priority ? String(priority) : null, \"\", property);\n\n    const updateGroup = () => {\n        if (group !== (property.group ?? \"\")) {\n            doUpdate(property, { group });\n        }\n    };\n\n    const updatePriority = () => {\n        const asNumber = priorityAsString ? parseFloat(priorityAsString) : undefined;\n        if (asNumber != property.priority) {\n            doUpdate(property, { priority: asNumber });\n        }\n    };\n\n    const updateDesignerHint: React.ChangeEventHandler<HTMLSelectElement> = (e) => {\n        const designer_hint = (e.target.value || undefined) as DesignerHint | undefined;\n        if (designer_hint !== property.designer_hint) {\n            doUpdate(property, { designer_hint: designer_hint });\n        }\n    };\n\n    const designerHints = DESIGNER_HINTS[property.type] ?? [];\n\n    const Sections = [\n        {\n            title: \"group\",\n            info: \"Properties with the same group name will appear together in the designer.\",\n            body: (\n                <ContentTextInput\n                    className=\"w-96!\"\n                    placeholder={\"Property group\"}\n                    small={true}\n                    value={group}\n                    onChange={(e) => setGroup(e.target.value)}\n                    onBlur={updateGroup}\n                    onEnter={updateGroup}\n                    disableEsc\n                />\n            ),\n        },\n        {\n            title: \"important\",\n            info: \"Important properties will always be visible (and bold) in the designer.\",\n            body: (\n                <div className=\"w-96\">\n                    <CheckBox\n                        className=\"m-0! flex\"\n                        checked={important}\n                        onChange={() => doUpdate(property, { important: !important })}\n                    />\n                </div>\n            ),\n        },\n        {\n            title: \"priority\",\n            info: \"Properties with a higher priority will appear higher in the designer.\",\n            body: (\n                <ContentTextInput\n                    small={true}\n                    className=\"w-96!\"\n                    type={\"number\"}\n                    value={priorityAsString}\n                    placeholder={\"Priority\"}\n                    onChange={(e: React.ChangeEvent<HTMLInputElement>) => setPriorityAsString(e.target.value)}\n                    onBlur={updatePriority}\n                    onEnter={updatePriority}\n                    disableEsc\n                />\n            ),\n        },\n        {\n            title: \"designer hint\",\n            info: \"Properties with designer hints will show up in the Designer palette\",\n            body: (\n                <ContentDropdownMenuItem\n                    className=\"w-96!\"\n                    small\n                    value={property.designer_hint ?? \"\"}\n                    onChange={updateDesignerHint}>\n                    <option key={\"\"} value={\"\"}>\n                        {designerHints.length ? \"Select a designer hint\" : \"No designer hints available for this type\"}\n                    </option>\n                    {designerHints.map((value) => (\n                        <option key={value} value={value}>\n                            {value}\n                        </option>\n                    ))}\n                </ContentDropdownMenuItem>\n            ),\n        },\n    ] as const;\n\n    return (\n        <div>\n            <div className=\"flex flex-col gap-4\">\n                {Sections.map((sectionProps) => (\n                    <DesignSection key={sectionProps.title} {...sectionProps} />\n                ))}\n            </div>\n        </div>\n    );\n};\n","import React from \"react\";\nimport { faUpload } from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { StylePropertyEditor } from \"@/code_mirror/editors\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { CheckBox } from \"@/components/reusable/Forms\";\nimport {\n    ColourInput,\n    ContentDropdownMenuItem,\n    ContentTextAreaInput,\n    ContentTextInput,\n} from \"@/components/reusable/SharedComponents\";\nimport { Text } from \"@/components/reusable/Text\";\nimport {\n    AvailableFormsDropdown,\n    IconComboBox,\n    MarginProperty,\n    PaddingProperty,\n    SpacingProperty,\n    useChangeUriPropertyWithModal,\n} from \"@/components/tabs/code/designer/PropertyEditors\";\nimport { useActionOnTimeout, useStateWithReset } from \"@/util/hooks\";\nimport { DEFAULT_ICON_SETS } from \"@/util/iconsets\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { useCustomComponentContext } from \"./CustomComponent\";\nimport { PropSection } from \"./SubComponents\";\nimport { useResetState } from \"./helpers\";\nimport { TEnumProperty, TProperty } from \"./types\";\n\nconst NULL_VALUE = \"____$NULL_VALUE$\";\nconst PLACE_HOLDER = \"___$PLACE_HOLDER$\";\n\ninterface PropertyEditorProps {\n    property: TProperty;\n    doUpdate: (p: TProperty, u: Partial<TProperty>) => void;\n}\n\ninterface ValueProps<T> {\n    defaultValue: T;\n    setDefaultValue(v: T): void;\n    onBlur: () => void;\n}\n\nconst EMPTY_OPTIONS: string[] = [];\n\ninterface PropertyProps {\n    property: TProperty;\n    onSave: (p: TProperty, u: Partial<TProperty>) => void;\n}\n\nconst EnumDropDown = ({ property, onSave }: PropertyProps) => {\n    const { default_value, options, include_none_option, none_option_label } = property;\n\n    const onDropDownChange = useEvent((e: React.ChangeEvent<HTMLSelectElement>) => {\n        const value = e.target.value;\n        const newValue = value === NULL_VALUE ? null : value;\n        if (newValue !== default_value) {\n            onSave(property, { ...property, default_value: newValue });\n        }\n    });\n\n    return (\n        <ContentDropdownMenuItem\n            className=\"w-96!\"\n            small\n            value={default_value ?? NULL_VALUE}\n            onChange={onDropDownChange}>\n            <option key={PLACE_HOLDER} value={PLACE_HOLDER} disabled>\n                Select a default option\n            </option>\n            {include_none_option && (\n                <option key={NULL_VALUE} value={NULL_VALUE}>\n                    {none_option_label} (None)\n                </option>\n            )}\n            {(options ?? []).map((value, idx) => (\n                <option key={`${value}-${idx}`} value={value}>\n                    {value}\n                </option>\n            ))}\n        </ContentDropdownMenuItem>\n    );\n};\n\nconst EnumOptions = ({ property, onSave }: PropertyProps) => {\n    const { default_value, include_none_option } = property;\n    const [enumOptions, setEnumOptions] = useStateWithReset(property.options ?? EMPTY_OPTIONS);\n\n    const onSave_ = useEvent(() => {\n        if (\n            !property.options ||\n            property.options.length !== enumOptions.length ||\n            property.options.some((x, i) => x !== enumOptions[i])\n        ) {\n            const updated = { ...property, options: enumOptions };\n            if (default_value == null && include_none_option) {\n                // pass\n            } else if (!enumOptions.includes(default_value)) {\n                const prevIdex = property.options?.indexOf(default_value) ?? -1;\n                if (prevIdex >= 0 && prevIdex < enumOptions.length) {\n                    updated.default_value = enumOptions[prevIdex];\n                } else {\n                    updated.default_value = enumOptions[0] ?? null;\n                }\n            }\n            onSave(property, updated);\n        }\n    });\n\n    const [delaySave, doSave] = useActionOnTimeout(onSave_, 300);\n\n    const onChange: React.ChangeEventHandler<HTMLTextAreaElement> = useEvent((e) => {\n        setEnumOptions(e.target.value ? e.target.value.split(\"\\n\") : []);\n        delaySave();\n    });\n\n    return (\n        <ContentTextAreaInput\n            small\n            value={enumOptions.join(\"\\n\")}\n            placeholder={\"Add options - 1 option per line\"}\n            className=\"w-96! dark:placeholder:text-gray-400!\"\n            onChange={onChange}\n            onBlur={doSave}\n            disableEsc={true}\n        />\n    );\n};\n\nconst NoneOption = ({ property, onSave }: PropertyProps) => {\n    const { options, default_value, include_none_option: showNoneOption } = property;\n    const [noneLabel, setNoneLabel] = useResetState(property.none_option_label, undefined, property);\n\n    const onDeleteNoneOption = useEvent(() => {\n        const update: Partial<TEnumProperty> = { include_none_option: undefined, none_option_label: undefined };\n        if (default_value == null) {\n            update.default_value = options?.[0];\n        }\n        onSave(property, update);\n    });\n\n    const onAddNoneOption = useEvent(() => {\n        onSave(property, { include_none_option: true, none_option_label: undefined });\n    });\n\n    const onBlurNoneLabel = useEvent(() => {\n        onSave(property, { none_option_label: noneLabel || undefined });\n    });\n    const onChange: React.ChangeEventHandler<HTMLInputElement> = useEvent((e) => {\n        if (e.target.checked) {\n            onAddNoneOption();\n        } else {\n            onDeleteNoneOption();\n        }\n    });\n\n    return (\n        <div className=\"flex w-96 gap-2\">\n            <CheckBox checked={!!showNoneOption} onChange={onChange} />\n            {showNoneOption && (\n                <ContentTextInput\n                    type={\"text\"}\n                    value={noneLabel ?? \"\"}\n                    placeholder=\"None option label\"\n                    onChange={(e) => setNoneLabel(e.target.value)}\n                    onBlur={onBlurNoneLabel}\n                    onEnter={onBlurNoneLabel}\n                    small\n                    disableEsc={true}\n                    className=\"w-96!\"\n                />\n            )}\n        </div>\n    );\n};\n\nconst IconProperty = ({\n    defaultValue,\n    onBlur,\n    setDefaultValue,\n    iconsets,\n}: ValueProps<string> & { iconsets?: string[] }) => {\n    // TODO support multiple iconsets here\n    return (\n        <div className=\"w-96!\">\n            <IconComboBox\n                iconsets={iconsets || DEFAULT_ICON_SETS}\n                value={defaultValue}\n                onChange={setDefaultValue}\n                onBlur={onBlur}\n            />\n        </div>\n    );\n};\n\nexport const PropertyEditor = ({ property, doUpdate: onSave }: PropertyEditorProps) => {\n    const { type, default_value, iconsets } = property;\n    const [defaultValue, setDefaultValue] = useStateWithReset(default_value);\n\n    const saveValue = (newVal: any) => {\n        if (newVal !== default_value) onSave(property, { ...property, default_value: newVal });\n    };\n\n    const onBlur = useEvent(() => saveValue(defaultValue));\n\n    const onChangeDefaultUriValue = useChangeUriPropertyWithModal(\n        { value: defaultValue, accept: property.accept },\n        (value) => {\n            onSave(property, { ...property, default_value: value });\n        }\n    );\n    const { formName } = useCustomComponentContext();\n\n    switch (type) {\n        case \"string\":\n            return (\n                <ContentTextInput\n                    type={\"text\"}\n                    value={defaultValue}\n                    placeholder={\"Default value\"}\n                    onChange={(e) => setDefaultValue(e.target.value)}\n                    onBlur={onBlur}\n                    onEnter={onBlur}\n                    small\n                    disableEsc={true}\n                    className=\"w-96!\"\n                />\n            );\n        case \"style\":\n            return (\n                <div className=\"w-96!\">\n                    <StylePropertyEditor\n                        value={defaultValue}\n                        placeholder=\"Default value\"\n                        onChange={setDefaultValue}\n                        onBlur={onBlur}\n                    />\n                </div>\n            );\n        case \"number\":\n            return (\n                <ContentTextInput\n                    type={\"number\"}\n                    small\n                    value={String(defaultValue ?? \"\")}\n                    placeholder={\"Default value\"}\n                    onChange={(e) => setDefaultValue(e.target.value ? e.target.valueAsNumber : null)}\n                    onBlur={onBlur}\n                    onEnter={onBlur}\n                    disableEsc={true}\n                    className=\"w-96!\"\n                />\n            );\n        case \"color\":\n            /** @todo: also give theme colours as a dropdown (appColors)*/\n            return (\n                <ColourInput\n                    small\n                    value={defaultValue}\n                    onChange={(e: React.ChangeEvent<HTMLInputElement>) => setDefaultValue(e.target.value)}\n                    onBlur={onBlur}\n                    className=\"w-96!\"\n                    onEnter={onBlur}\n                />\n            );\n        case \"boolean\":\n            return (\n                <CheckBox\n                    checked={defaultValue}\n                    className=\"-my-0.5\"\n                    onChange={(e: React.ChangeEvent<HTMLInputElement>) => saveValue(e.target.checked)}\n                    onBlur={onBlur}\n                />\n            );\n        case \"text[]\":\n        case \"classes\":\n            return (\n                <ContentTextAreaInput\n                    small\n                    value={typeof defaultValue === \"string\" ? defaultValue : (defaultValue?.join?.(\"\\n\") ?? \"\")}\n                    placeholder={\"Default value\"}\n                    className=\"w-96! dark:placeholder:text-gray-400!\"\n                    onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>\n                        setDefaultValue(e.target.value ? e.target.value.split(\"\\n\") : [])\n                    }\n                    onBlur={onBlur}\n                    disableEsc={true}\n                />\n            );\n        case \"icon\":\n            return (\n                <IconProperty\n                    defaultValue={defaultValue}\n                    setDefaultValue={setDefaultValue}\n                    onBlur={onBlur}\n                    iconsets={iconsets}\n                />\n            );\n        case \"form\":\n            return <AvailableFormsDropdown formName={formName} value={defaultValue} onChange={saveValue} />;\n        case \"object\":\n            return (\n                <Text className=\"m-0! italic\" level={3}>\n                    Set at runtime\n                </Text>\n            );\n        case \"enum\":\n            return <EnumDropDown property={property} onSave={onSave} />;\n        case \"uri\":\n            return (\n                <div className=\"flex gap-4\">\n                    <ContentTextInput\n                        type={\"text\"}\n                        value={defaultValue || \"\"}\n                        placeholder={\"Default value\"}\n                        onChange={(e) => setDefaultValue(e.target.value || null)}\n                        onBlur={onBlur}\n                        onEnter={onBlur}\n                        small\n                        disableEsc={true}\n                        className=\"w-96!\"\n                    />\n                    <Button className=\"h-full!\" tiny onClick={() => onChangeDefaultUriValue()}>\n                        <FontAwesomeIcon icon={faUpload} />\n                    </Button>\n                </div>\n            );\n        case \"margin\":\n            return <MarginProperty value={defaultValue} onChange={saveValue} />;\n        case \"padding\":\n            return <PaddingProperty value={defaultValue} onChange={saveValue} />;\n        case \"spacing\":\n            return <SpacingProperty value={defaultValue} onChange={saveValue} />;\n        default:\n            return null;\n    }\n};\n\nexport function PropertyEditorSections({ property, doUpdate }: PropertyEditorProps) {\n    const { type } = property;\n    const [accept, setAccept] = useResetState(property.accept, undefined, property);\n\n    return (\n        <>\n            <PropSection title=\"Default Value\">\n                <PropertyEditor property={property} doUpdate={doUpdate} />\n            </PropSection>\n            {type === \"enum\" && (\n                <>\n                    <PropSection title=\"Options\">\n                        <EnumOptions property={property as TEnumProperty} onSave={doUpdate} />\n                    </PropSection>\n                    <PropSection title=\"None Option\">\n                        <NoneOption property={property as TEnumProperty} onSave={doUpdate} />\n                    </PropSection>\n                </>\n            )}\n            {type === \"string\" && (\n                <PropSection title=\"Multiline\">\n                    <CheckBox\n                        checked={property.multiline ?? false}\n                        onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n                            doUpdate(property, { multiline: e.target.checked })\n                        }\n                    />\n                </PropSection>\n            )}\n            {type === \"uri\" && (\n                <PropSection title=\"Accept\">\n                    <ContentTextInput\n                        type={\"string\"}\n                        small\n                        value={accept || \"\"}\n                        placeholder={\"Default value\"}\n                        onChange={(e) => setAccept(e.target.value || undefined)}\n                        onBlur={() => doUpdate(property, { accept })}\n                        onEnter={() => doUpdate(property, { accept })}\n                        disableEsc={true}\n                        className=\"w-96!\"\n                    />\n                </PropSection>\n            )}\n        </>\n    );\n}\n","import React, { useCallback, useMemo } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faTimes } from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { difference, union } from \"lodash-es\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { CheckBox } from \"@/components/reusable/Forms\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { ContentDropdownMenuItem } from \"@/components/reusable/SharedComponents\";\nimport { Heading } from \"@/components/reusable/Text\";\nimport { alert, prompt } from \"@/controllers/modals\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useCustomComponentContext } from \"./CustomComponent\";\nimport { TPropUpdater, TProperty } from \"./types\";\n\ninterface PropertyWritebackProps {\n    property: TProperty;\n    doUpdate: TPropUpdater;\n}\n\nexport function PropertyWriteback({ property, doUpdate }: PropertyWritebackProps) {\n    const { allow_binding_writeback = false, binding_writeback_events } = property;\n    return (\n        <div>\n            <CheckBox\n                className=\"m-0! flex text-lg font-normal\"\n                checked={!!allow_binding_writeback}\n                onChange={() => doUpdate(property, { allow_binding_writeback: !allow_binding_writeback })}>\n                Allow data binding write-back\n            </CheckBox>\n            <Expander isOpen={allow_binding_writeback}>\n                <WriteBackEvents doUpdate={doUpdate} property={property} />\n            </Expander>\n        </div>\n    );\n}\n\nconst WritebackPills = ({ events, onDelete }: { events?: string[]; onDelete: (event: string) => void }) => {\n    if (!events) return null;\n    return (\n        <div className=\"my-4 flex flex-wrap gap-2\">\n            {events.map((eventName) => (\n                <div className=\"flex items-center gap-2 rounded-lg border border-light-bg4 bg-white px-2 py-1 font-mono text-base text-black dark:border-dark-bg3\">\n                    {eventName}\n                    <LinkInternal onClick={() => onDelete(eventName)}>\n                        <FontAwesomeIcon icon={faTimes} />\n                    </LinkInternal>\n                </div>\n            ))}\n        </div>\n    );\n};\n\ninterface WriteBackEventsProps {\n    property: TProperty;\n    doUpdate: TPropUpdater;\n}\n\nconst CUSTOM_EVENT = \"Custom event...\";\n\nconst WriteBackEvents = ({ doUpdate, property }: WriteBackEventsProps) => {\n    const { binding_writeback_events } = property;\n    const { eventNames } = useCustomComponentContext();\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const addWritebackEvent = useCallback(\n        async (newValue: string) => {\n            if (newValue === CUSTOM_EVENT) {\n                const customEvent = await dispatch(\n                    prompt(\"Enter custom event name\", \"Custom event names must begin 'x-'\")\n                );\n                if (customEvent && customEvent.substr(0, 2) === \"x-\") {\n                    doUpdate(property, {\n                        binding_writeback_events: union(binding_writeback_events || [], [customEvent]),\n                    });\n                } else if (customEvent !== null) {\n                    dispatch(alert(\"Error setting custom writeback event\", \"Custom event names must begin 'x-'\"));\n                }\n            } else {\n                doUpdate(property, { binding_writeback_events: union(binding_writeback_events || [], [newValue]) });\n            }\n        },\n        [doUpdate, property, binding_writeback_events]\n    );\n\n    const bindingEvents = useMemo(\n        () => difference(eventNames, binding_writeback_events || []),\n        [eventNames, binding_writeback_events]\n    );\n\n    const onDeleteWritebackEvent = (eventName: string) =>\n        doUpdate(property, {\n            binding_writeback_events: (binding_writeback_events ?? []).filter((e) => e !== eventName),\n        });\n\n    return (\n        <div className=\"mt-4\">\n            <Heading level={3} className=\"mt-4\">\n                Trigger write-back on the following events:\n            </Heading>\n            <div>\n                <WritebackPills events={binding_writeback_events} onDelete={onDeleteWritebackEvent} />\n                <ContentDropdownMenuItem\n                    small\n                    value={\"choose-events\"}\n                    className=\"flex\"\n                    onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {\n                        addWritebackEvent(e.target.value);\n                    }}>\n                    <option key={\"placeholder\"} value={\"choose-events\"} disabled>\n                        Add event:\n                    </option>\n                    {bindingEvents.map((evt) => (\n                        <option key={evt} value={evt}>\n                            {evt}\n                        </option>\n                    ))}\n                    <option value={CUSTOM_EVENT}>{CUSTOM_EVENT}</option>\n                </ContentDropdownMenuItem>\n            </div>\n        </div>\n    );\n};\n","import React from \"react\";\nimport { PropertyType } from \"@designer/shared-types\";\nimport { useCustomComponentContext } from \"@/components/modals/customcomponent/CustomComponent\";\nimport { RadioButton } from \"@/components/reusable/Forms\";\nimport { ContentDropdownMenuItem } from \"@/components/reusable/SharedComponents\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { PropertyDesigner } from \"./PropertyDesigner\";\nimport { PropertyEditorSections } from \"./PropertyEditors\";\nimport { PropertyWriteback } from \"./PropertyWriteback\";\nimport { AdvancedExpander, DescriptionInput, ExpandableDesignerPropSection, PropSection } from \"./SubComponents\";\nimport { getDefaultFromType } from \"./helpers\";\nimport { TPropUpdater, TProperty } from \"./types\";\n\ninterface PropertyBodyProps {\n    property: TProperty;\n    doUpdate: TPropUpdater;\n}\n\nexport const PropertyBody = ({ property, doUpdate }: PropertyBodyProps) => {\n    const { type, default_binding_prop: isDefault } = property;\n\n    const onTypeChange: React.ChangeEventHandler<HTMLSelectElement> = useEvent((e) => {\n        const type = e.target.value as PropertyType;\n        const default_value = getDefaultFromType(type);\n        const options = type === \"enum\" ? [] : undefined;\n        const accept = type === \"uri\" ? \"image/*\" : undefined;\n        doUpdate(property, { multiline: undefined, type, default_value, options, designer_hint: undefined, accept });\n    });\n\n    const { propTypes } = useCustomComponentContext();\n\n    return (\n        <div className=\"p-4\">\n            <PropSection title=\"Type\">\n                <ContentDropdownMenuItem\n                    className=\"flex w-96!\"\n                    small\n                    value={type || \"select-type\"}\n                    onChange={onTypeChange}>\n                    <option key={\"placeholder\"} value={\"select-type\"} disabled>\n                        Select property type\n                    </option>\n                    {propTypes.map((prop, idx) => (\n                        <option key={idx} value={prop.val}>\n                            {prop.name}\n                        </option>\n                    ))}\n                </ContentDropdownMenuItem>\n            </PropSection>\n\n            <PropertyEditorSections property={property} doUpdate={doUpdate} />\n\n            <PropSection title=\"Description\">\n                <DescriptionInput item={property} doUpdate={doUpdate} />\n            </PropSection>\n            <AdvancedExpander type={\"property\"}>\n                <PropSection title=\"Data Binding\">\n                    <RadioButton\n                        className=\"m-0! flex text-lg font-normal\"\n                        checked={isDefault || false}\n                        onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n                            doUpdate(property, { default_binding_prop: !isDefault });\n                        }}>\n                        Make this the default data binding property\n                    </RadioButton>\n                </PropSection>\n                <PropSection title=\"Writeback\">\n                    <PropertyWriteback property={property} doUpdate={doUpdate} />\n                </PropSection>\n                <ExpandableDesignerPropSection\n                    title=\"Designer\"\n                    description={\"These options affect how the property appears in the designer\"}>\n                    <PropertyDesigner property={property} doUpdate={doUpdate} />\n                </ExpandableDesignerPropSection>\n            </AdvancedExpander>\n        </div>\n    );\n};\n","import React from \"react\";\nimport { faChevronUp } from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Accordion } from \"@/components/reusable/Accordion\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport { ContentTextAreaInput } from \"@/components/reusable/SharedComponents\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport { ExternalState, useExternalState } from \"@/util/external-state\";\nimport { usePartialReducer } from \"@/util/hooks\";\nimport { EventBody } from \"./EventBody\";\nimport { PropEventHeader } from \"./PropEventHeader\";\nimport { PropertyBody } from \"./PropertyBody\";\nimport { useExpandedItems, useResetState, useSwapPropEvent } from \"./helpers\";\nimport { TEvent, TEventUpdater, TPropUpdater, TProperty, TUpdater } from \"./types\";\n\ninterface PropSectionProps extends React.PropsWithChildren {\n    title: string;\n}\nexport const PropSection = ({ title, children }: PropSectionProps) => {\n    return (\n        <div className=\"hover:bg-palette-bg2 flex items-center border-b border-sectionborder p-4 dark:border-dark-sectionborder\">\n            <Heading level={3} className=\"relative m-0! ml-8! w-48 self-start pt-2\">\n                {title}:\n            </Heading>\n            {children}\n        </div>\n    );\n};\n\ninterface ExpandableSectionProps extends PropSectionProps {\n    description: string;\n}\n\nconst designerSectionExpanded = new ExternalState(false);\n\nexport const ExpandableDesignerPropSection = ({ title, children, description }: ExpandableSectionProps) => {\n    const [isOpen, setIsOpen] = useExternalState(designerSectionExpanded);\n    return (\n        <div\n            className=\"hover:bg-palette-bg2 flex cursor-pointer items-center border-b border-sectionborder p-4 hover:bg-light-bg2 dark:border-dark-sectionborder dark:hover:bg-dark-bg2\"\n            onClick={() => setIsOpen(!isOpen)}>\n            <Heading level={3} className=\"m-0! ml-8! flex w-48 items-center gap-4\">\n                <FontAwesomeIcon className=\"ml-[-4px]\" rotation={isOpen ? 180 : 90} icon={faChevronUp} fixedWidth />\n                {title}:\n            </Heading>\n            <div className=\"flex flex-col\">\n                <Text level={3} className=\"m-0\" hidden={isOpen}>\n                    {description}\n                </Text>\n                <div onClick={(e) => e.stopPropagation()} className=\"cursor-auto\">\n                    <Expander isOpen={isOpen}>{children}</Expander>\n                </div>\n            </div>\n        </div>\n    );\n};\n\ninterface DescriptionInputProps<T extends TProperty | TEvent> {\n    item: T;\n    doUpdate: TUpdater<T>;\n    placeholder?: string;\n}\n\nexport const DescriptionInput = <T extends TProperty | TEvent>({\n    item,\n    doUpdate,\n    placeholder,\n}: DescriptionInputProps<T>) => {\n    const [description, setDescription] = useResetState(item.description, \"\");\n\n    const onBlur = () => description !== item.description && doUpdate(item, { description } as Partial<T>);\n    const onChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => setDescription(e.target.value);\n\n    return (\n        <ContentTextAreaInput\n            className=\"flex-1 dark:placeholder:text-gray-400!\"\n            placeholder={placeholder || \"Description\"}\n            small={true}\n            autoExpand\n            value={description}\n            onChange={onChange}\n            onBlur={onBlur}\n        />\n    );\n};\n\ninterface HeaderProps {\n    title: React.ReactNode;\n    description: React.ReactNode;\n    helplink?: string;\n}\nexport const Header = ({ title, description, helplink }: HeaderProps) => {\n    return (\n        <div className=\"border-t border-sectionborder pl-5 dark:border-dark-sectionborder\">\n            <Heading level={2}>{title}</Heading>\n            <div className=\"flex items-center gap-4\">\n                <Text level={2}>{description}</Text>\n                {helplink && (\n                    <HelpLink inline url={`${window.location.origin}/docs/client/custom-components#${helplink}`} />\n                )}\n            </div>\n        </div>\n    );\n};\n\nconst advancedExpanderAtom = new ExternalState({ event: false, property: false });\n\ntype TPropEvent = \"property\" | \"event\";\n\nexport const AdvancedExpander = ({ children, type }: React.PropsWithChildren<{ type: TPropEvent }>) => {\n    const [openState, setOpenState] = useExternalState(advancedExpanderAtom);\n    const open = openState[type];\n    const setOpen = (v: boolean) => setOpenState({ ...openState, [type]: v });\n    return (\n        <>\n            <Expander isOpen={open}>{children}</Expander>\n            <div className=\"m-5\">\n                <Button small variant={\"highlight2\"} onClick={() => setOpen(!open)}>\n                    {`${open ? \"Hide\" : \"Show\"} advanced settings`}\n                </Button>\n            </div>\n        </>\n    );\n};\n\ninterface ComponentAccordionProps<T extends TProperty | TEvent> extends ReturnType<typeof useExpandedItems<T>> {\n    type: T extends TProperty ? \"properties\" : \"events\";\n    doUpdate: TUpdater<T>;\n    onDelete: (item: T) => void;\n    subtitle?: (item: T) => string;\n}\n\ninterface DragState {\n    [index: number]: boolean;\n}\n\nexport const ComponentAccordion = <T extends TEvent | TProperty>({\n    items,\n    type,\n    doUpdate,\n    onDelete,\n    subtitle,\n    onToggle,\n    expandedKeys,\n}: ComponentAccordionProps<T>) => {\n    const onSwap = useSwapPropEvent(type);\n    const [dragState, updateDragState] = usePartialReducer<DragState>({});\n\n    let renderBody: ({ item }: { item: T }) => React.ReactNode;\n    if (type === \"properties\") {\n        renderBody = ({ item }) => <PropertyBody property={item as TProperty} doUpdate={doUpdate as TPropUpdater} />;\n    } else {\n        renderBody = ({ item }) => <EventBody event={item as TEvent} doUpdate={doUpdate as TEventUpdater} />;\n    }\n\n    return (\n        <Accordion\n            items={items}\n            onToggle={onToggle}\n            keyName=\"propKey\"\n            expandedKeys={expandedKeys}\n            headerClassFn={(item, idx) => {\n                return dragState[idx]\n                    ? \"bg-light-bg4/70 dark:bg-dark-bg3/70\" //\"bg-light-bg4/70 dark:bg-dark-bg3/70 border border-light-bg6 dark:border-dark-bg5\"\n                    : \"\";\n            }}\n            renderHeader={({ item }, idx: number) => (\n                <PropEventHeader\n                    index={idx}\n                    type={type}\n                    doUpdate={doUpdate}\n                    onSwap={onSwap}\n                    item={item}\n                    name={item.name}\n                    subtitle={subtitle?.(item)}\n                    updateName={(name: string) => doUpdate(item, { name } as Partial<T>)}\n                    onDelete={() => onDelete(item)}\n                    updateDragState={updateDragState}\n                />\n            )}\n            renderBody={renderBody}\n        />\n    );\n};\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { confirm } from \"@/controllers/modals\";\nimport { AnvilDispatch } from \"@/types\";\nimport { getRandomString } from \"@/util\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { useCustomComponentContext } from \"./CustomComponent\";\nimport { ID_KEY, TEvent, TProperty } from \"./types\";\n\n/**\n * Constants and functions\n */\n\nexport const PROP_TYPES = [\n    { name: \"String\", val: \"string\" },\n    { name: \"Number\", val: \"number\" },\n    { name: \"Color\", val: \"color\" },\n    { name: \"Boolean\", val: \"boolean\" },\n    { name: \"String list\", val: \"text[]\" },\n    { name: \"Classes\", val: \"classes\" },\n    { name: \"Style\", val: \"style\" },\n    { name: \"Enum\", val: \"enum\" },\n    { name: \"Icon\", val: \"icon\" },\n    { name: \"Form\", val: \"form\" },\n    { name: \"Object\", val: \"object\" },\n    { name: \"Uri\", val: \"uri\" },\n];\n\nexport const PROP_TYPES_V3 = [\n    { name: \"Margin\", val: \"margin\" },\n    { name: \"Padding\", val: \"padding\" },\n    { name: \"Spacing\", val: \"spacing\" },\n];\n\nexport const PROP_TYPES_TO_DISPLAY = {\n    string: \"string\",\n    number: \"number\",\n    color: \"color\",\n    boolean: \"boolean\",\n    \"text[]\": \"string list\",\n    classes: \"classes\",\n    style: \"style\",\n    enum: \"enum\",\n    icon: \"icon\",\n    form: \"form\",\n    object: \"object\",\n    uri: \"uri\",\n    margin: \"margin\",\n    padding: \"padding\",\n    spacing: \"spacing\",\n};\n\nexport function cleanPythonName(name: string, itemItem: { name: string }, items: { name: string }[]) {\n    if (name === itemItem.name) return name;\n    name = name\n        .replace(/[^A-z0-9]/g, \"_\")\n        .replace(/^[0-9]/, \"_$&\")\n        .toLowerCase();\n    let i = 2;\n    let propReturnName = name;\n    while (items.some((item) => item !== itemItem && propReturnName === item.name)) {\n        propReturnName = `${name}_${i++}`;\n    }\n    return propReturnName;\n}\n\nexport function cleanPriority({ priority }: TProperty) {\n    let rv;\n    if (typeof priority === \"string\") {\n        rv = parseFloat(priority);\n    } else if (typeof priority === \"number\") {\n        rv = priority;\n    } else if (priority == null) {\n        return undefined;\n    }\n    return Number.isNaN(rv) ? undefined : rv;\n}\n\nexport const getDefaultFromType = (type: string) => {\n    switch (type) {\n        case \"color\":\n        case \"string\":\n        case \"style\":\n        case \"icon\":\n            return \"\";\n        case \"boolean\":\n            return false;\n        case \"text[]\":\n        case \"classes\":\n            return [];\n        case \"form\":\n        case \"object\":\n        case \"enum\":\n        case \"number\":\n        case \"uri\":\n        default:\n            return;\n    }\n};\n\n/**\n * Hooks\n */\nexport const useResetState = <T,>(prop: T | null | undefined, nullVal: T, item?: any) => {\n    const [state, setState] = useState(prop ?? nullVal);\n    const [prevState, setPrevState] = useState(prop);\n    const itemRef = useRef(item);\n\n    if (prevState !== prop) {\n        setState(prop ?? nullVal);\n        setPrevState(prop);\n    }\n    if (itemRef.current !== item) {\n        itemRef.current = item;\n        setState(prop ?? nullVal);\n    }\n\n    return [state, setState] as const;\n};\n\nexport function addExpandKey<T extends TProperty | TEvent>(item: T) {\n    return (item[ID_KEY] ??= getRandomString());\n}\n\nexport function useExpandedItems<T extends TProperty | TEvent>(propEventItems: T[]) {\n    const items = useMemo(\n        () =>\n            propEventItems.map((item: T) => {\n                // This is a bit of a hack - but Symbols won't get sent to the server\n                // and item is mutable\n                const propKey = addExpandKey(item);\n                return { item, propKey };\n            }),\n        [propEventItems]\n    );\n    const [expandedKeys, setExpandedKeys] = useState({} as Record<string, boolean>);\n    const onToggle = useCallback(\n        ({ propKey }: { item: T; propKey: string }) => {\n            setExpandedKeys({ [propKey]: !expandedKeys[propKey] });\n        },\n        [expandedKeys]\n    );\n    return { items, expandedKeys, setExpandedKeys, onToggle } as const;\n}\n\nexport function useDeletePropEvent<T extends TEvent | TProperty>(getNewItem: (item: T) => any) {\n    const { updateCustomComponent } = useCustomComponentContext();\n    const dispatch = useDispatch<AnvilDispatch>();\n    return useEvent(async (item: T) => {\n        const title = `Delete '${item.name}'`;\n        const msg = `Are you sure you want to delete '${item.name}'?`;\n        if (await dispatch(confirm(title, msg))) {\n            updateCustomComponent(getNewItem(item));\n        }\n    });\n}\n\nexport function useSwapPropEvent(key: \"events\" | \"properties\") {\n    const { updateCustomComponent, [key]: list } = useCustomComponentContext();\n\n    return useEvent((fromIdx: number, toIdx: number) => {\n        if (fromIdx === toIdx) return;\n        const [element] = list.splice(fromIdx, 1);\n        list.splice(toIdx, 0, element);\n        updateCustomComponent({ [key]: [...list] });\n    });\n}\n","import React, { ChangeEvent, ChangeEventHandler, createContext, useId, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faUpload } from \"@fortawesome/free-solid-svg-icons/faUpload\";\nimport { faChevronDown } from \"@fortawesome/pro-solid-svg-icons/faChevronDown\";\nimport { faChevronRight } from \"@fortawesome/pro-solid-svg-icons/faChevronRight\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { LayoutMetadata } from \"@runtime/runner/data\";\nimport {\n    CustomComponentContextValue,\n    useCustomComponentContext,\n} from \"@/components/modals/customcomponent/CustomComponent\";\nimport { Header } from \"@/components/modals/customcomponent/SubComponents\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { CheckBox } from \"@/components/reusable/Forms\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { modal } from \"@/controllers/modals\";\nimport { LAYOUT } from \"@/data/imageUrls\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { createContextHook, useStateWithReset } from \"@/util/hooks\";\nimport { ImageWithRetry, useMaybeRemoveAssetPrefix } from \"@/util/hooks/assets\";\nimport useEvent from \"@/util/useEventCallback\";\n\nconst useUpdateLayoutMetadata = (\n    key: keyof CustomComponentContextValue[\"layoutMetadata\"],\n    oldValue: LayoutMetadata,\n    value: string\n) => {\n    const { updateCustomComponent } = useLayoutMetaContext();\n    return useEvent(() => {\n        const newValue = value || undefined;\n        if (newValue === oldValue[key]) return;\n        const newMetadata = { ...oldValue, [key]: newValue };\n        updateCustomComponent({ layout_metadata: newMetadata });\n    });\n};\n\nconst layoutThumbnailSpec = {\n    title: \"Change Thumbnail\",\n    text: \"Choose a thumbnail to help users find this Layout\",\n    suffix: \"thumbnail\",\n    defaultValue: LAYOUT,\n    uploadInfo: \"Thumbnails should be 246×130 pixels or smaller\",\n    maxSize: 246,\n    errorMsg: \"Thumbnails should be 246×130 pixels.\",\n    pkgPrefix: \"designer_icons\",\n};\n\ninterface TextPropProps {\n    title: string;\n    placeholder: string;\n    fieldName: \"title\" | \"description\";\n}\n\nconst TextProp = ({ title, placeholder, fieldName }: TextPropProps) => {\n    const { layoutMetadata } = useLayoutMetaContext();\n    const id = useId();\n    const [value, setValue] = useStateWithReset(layoutMetadata[fieldName] ?? \"\");\n    const onSave = useUpdateLayoutMetadata(fieldName, layoutMetadata, value);\n    const onChange: React.ChangeEventHandler<HTMLInputElement> = useEvent((e) => {\n        setValue(e.target.value);\n    });\n    return (\n        <>\n            <label htmlFor={id} className=\"text-xl font-semibold\">\n                {title}:\n            </label>\n            <ContentTextInput\n                id={id}\n                small\n                value={value}\n                placeholder={placeholder}\n                onBlur={onSave}\n                onEnter={onSave}\n                onChange={onChange}\n            />\n        </>\n    );\n};\n\nconst ThumbnailUploader = () => {\n    const { updateCustomComponent, layoutMetadata } = useLayoutMetaContext();\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { thumbnail } = layoutMetadata;\n    const onSave = useEvent((value: string | null) => {\n        updateCustomComponent({ layout_metadata: { ...layoutMetadata, thumbnail: value || undefined } });\n    });\n\n    const onChangeImage = useEvent(async () => {\n        const newValue = await dispatch(modal(\"sizedImageUpload\", { value: thumbnail, ...layoutThumbnailSpec }));\n        if (newValue !== undefined) {\n            onSave(newValue);\n        }\n    });\n\n    const src = useMaybeRemoveAssetPrefix(thumbnail ?? LAYOUT);\n\n    return (\n        <div className=\"flex flex-col items-center gap-4 pr-4\">\n            <div className=\"flex flex-col items-center gap-4\">\n                <div className={cx(\"rounded-lg p-2\", \"bg-sidebar\")}>\n                    <div className=\"h-40 w-76\">\n                        <ImageWithRetry src={src} />\n                    </div>\n                </div>\n                <div className=\"flex items-center gap-4\">\n                    <span className=\"text-center text-xl\">{}</span>\n                    <Button onClick={() => onChangeImage()} small icon={faUpload}>\n                        Choose Thumbnail\n                    </Button>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport type LayoutMetaContextValue = Pick<\n    CustomComponentContextValue,\n    \"formName\" | \"updateCustomComponent\" | \"layoutMetadata\"\n>;\n\nexport const LayoutMetaContext = createContext<LayoutMetaContextValue | null>(null);\nconst useLayoutMetaContext = createContextHook(LayoutMetaContext, \"layout meta context\");\n\n// also used by HtmlLayout modal\nexport const LayoutMetadataConfig = () => {\n    const { formName, layoutMetadata, updateCustomComponent } = useLayoutMetaContext();\n    const [expandAdvanced, setExpandAdvanced] = useState(false);\n    const onChange = useEvent((e: ChangeEvent<HTMLInputElement>) => {\n        updateCustomComponent({ layout_metadata: { ...layoutMetadata, internal: !e.target.checked } });\n    });\n    return (\n        <>\n            <Header title={\"Layout Metadata\"} description={\"Help users find this Layout when adding a new Form\"} />\n            <div className=\"mt-4 flex items-start gap-4 p-4\">\n                <div className=\"grid flex-1 grid-cols-[0.1fr_0.9fr] items-center gap-8\">\n                    <TextProp title={\"Title\"} placeholder={formName} fieldName={\"title\"} />\n                    <TextProp title={\"Description\"} placeholder={\"\"} fieldName={\"description\"} />\n                    <LinkInternal\n                        className={\"col-span-2 text-xl font-semibold\"}\n                        onClick={() => setExpandAdvanced((e) => !e)}>\n                        Advanced{\" \"}\n                        <FontAwesomeIcon className={\"pl-4\"} icon={expandAdvanced ? faChevronDown : faChevronRight} />\n                    </LinkInternal>\n                    <Expander className={\"col-span-2\"} isOpen={expandAdvanced}>\n                        <CheckBox\n                            checked={!layoutMetadata.internal}\n                            onChange={onChange}\n                            className={\"pl-8 text-xl font-semibold\"}>\n                            Make available to apps that depend on this app\n                        </CheckBox>\n                    </Expander>\n                </div>\n                <ThumbnailUploader />\n            </div>\n        </>\n    );\n};\n\nexport const LayoutMetadataCustomComponentConfig = () => {\n    const value = useCustomComponentContext();\n    return (\n        <LayoutMetaContext.Provider value={value}>\n            <LayoutMetadataConfig />\n        </LayoutMetaContext.Provider>\n    );\n};\n","import React from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faUpload } from \"@fortawesome/free-solid-svg-icons/faUpload\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { modal } from \"@/controllers/modals\";\nimport { darkIcons, icons } from \"@/data/componentIcons\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { ImageWithRetry, useMaybeRemoveAssetPrefix } from \"@/util/hooks/assets\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { useCustomComponentContext } from \"./CustomComponent\";\n\nconst defaultLight = icons.CustomComponent;\nconst defaultDark = darkIcons.CustomComponent;\n\nconst MAX_ICON_SIZE = 48;\n\nconst iconSpec = {\n    title: \"Change Icon\",\n    text: \"Choose an image to display in the designer toolbox\",\n    errorMsg: `Icons should be ${MAX_ICON_SIZE}x${MAX_ICON_SIZE} pixels or smaller.`,\n    suffix: \"icon\",\n    uploadInfo: `Icons should be ${MAX_ICON_SIZE}x${MAX_ICON_SIZE} pixels or smaller`,\n    maxSize: MAX_ICON_SIZE,\n    pkgPrefix: \"designer_icons\",\n};\n\nconst ImageUploader = ({ theme }: { theme: \"light\" | \"dark\" }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { toolbox_item = {}, updateCustomComponent } = useCustomComponentContext();\n    const { icon: toolboxIcon = {} } = toolbox_item;\n    const value = toolboxIcon[theme];\n    const isDark = theme === \"dark\";\n    const onSave = useEvent((value: string | null) => {\n        const newToolboxIcon = { ...toolboxIcon };\n        if (value) {\n            newToolboxIcon[theme] = value;\n        } else {\n            delete newToolboxIcon[theme];\n        }\n        updateCustomComponent({ toolbox_item: { ...toolbox_item, icon: newToolboxIcon } });\n    });\n\n    const defaultValue = isDark ? defaultDark : defaultLight;\n    const onChangeImage = useEvent(async () => {\n        const newValue = await dispatch(modal(\"sizedImageUpload\", { value, defaultValue, ...iconSpec }));\n        if (newValue !== undefined) {\n            onSave(newValue);\n        }\n    });\n\n    const src = useMaybeRemoveAssetPrefix(value ?? defaultValue);\n\n    return (\n        <div className=\"flex flex-col items-center gap-4\">\n            <div className=\"flex flex-col items-center gap-4\">\n                <div className={cx(\"rounded-lg p-2\", isDark ? \"bg-dark-sidebar\" : \"bg-sidebar\")}>\n                    <div className=\"h-[28px] w-[28px]\">\n                        <ImageWithRetry src={src} dark={isDark} />\n                    </div>\n                </div>\n                <div className=\"flex items-center gap-4\">\n                    <span className=\"text-center text-xl\">{}</span>\n                    <Button onClick={() => onChangeImage()} small icon={faUpload}>\n                        {isDark ? \"Dark\" : \"Light\"} Icon\n                    </Button>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport function IconUploader() {\n    return (\n        <div className=\"flex gap-4 pr-4\">\n            <ImageUploader key=\"light\" theme=\"light\" />\n            <ImageUploader key=\"dark\" theme=\"dark\" />\n        </div>\n    );\n}\n","import React, { ChangeEvent, useId } from \"react\";\nimport ComboBox from \"@/components/reusable/ComboBox\";\nimport { CheckBox } from \"@/components/reusable/Forms\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { useStateWithReset } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { CustomComponentContextValue, useCustomComponentContext } from \"./CustomComponent\";\nimport { IconUploader } from \"./IconUploader\";\nimport { Header } from \"./SubComponents\";\n\nconst useUpdateToolboxItem = (key: keyof CustomComponentContextValue[\"toolbox_item\"], value: string) => {\n    const { toolbox_item, updateCustomComponent } = useCustomComponentContext();\n    return useEvent(() => {\n        const newValue = value || undefined;\n        if (newValue === toolbox_item[key]) return;\n        const newItem = { ...toolbox_item, [key]: newValue };\n        if (newValue === undefined) {\n            delete newItem.title;\n        }\n        updateCustomComponent({ toolbox_item: newItem });\n    });\n};\n\nconst Title = () => {\n    const { formName: placeholder, toolbox_item } = useCustomComponentContext();\n    const id = useId();\n    const [value, setValue] = useStateWithReset(toolbox_item.title ?? \"\");\n    const onSave = useUpdateToolboxItem(\"title\", value);\n    const onChange: React.ChangeEventHandler<HTMLInputElement> = useEvent((e) => {\n        setValue(e.target.value);\n    });\n    return (\n        <>\n            <label htmlFor={id} className=\"text-xl font-semibold\">\n                Title:\n            </label>\n            <ContentTextInput\n                id={id}\n                small\n                value={value}\n                placeholder={placeholder}\n                onBlur={onSave}\n                onEnter={onSave}\n                onChange={onChange}\n            />\n        </>\n    );\n};\n\nconst Group = () => {\n    const { toolbox_item, groups } = useCustomComponentContext();\n    const [value, setValue] = useStateWithReset(toolbox_item.group ?? \"\");\n    const onSave = useUpdateToolboxItem(\"group\", value);\n    const onChange = useEvent((v: string) => {\n        setValue(v);\n    });\n    return (\n        <>\n            <label className=\"text-xl font-semibold\">Group:</label>\n            <ComboBox\n                inputClassName=\"w-full\"\n                small\n                value={value}\n                items={groups}\n                placeholder={\"Custom Components\"}\n                onBlur={onSave}\n                onEnter={onSave}\n                onChange={onChange}\n            />\n        </>\n    );\n};\n\nexport const ToolboxSettings = () => {\n    const { toolbox_item, updateCustomComponent, custom_component } = useCustomComponentContext();\n    const showInToolbox = !toolbox_item?.hidden;\n\n    const onChange = useEvent((e: ChangeEvent<HTMLInputElement>) => {\n        updateCustomComponent({ toolbox_item: { ...toolbox_item, hidden: !e.target.checked } });\n    });\n\n    return (\n        <>\n            <Header\n                title={\"Designer Display Settings\"}\n                description={\"Help users find and understand your component in the drag-and-drop designer\"}\n            />\n            <div className=\"mb-4 flex flex-col gap-8 p-4\">\n                <CheckBox onChange={onChange} checked={showInToolbox}>\n                    Make component available in toolbox\n                </CheckBox>\n\n                {showInToolbox && (\n                    <div className=\"flex items-end gap-8\">\n                        <div className=\"grid flex-1 grid-cols-[0.2fr_0.8fr] items-center gap-8\">\n                            <Title />\n                            <Group />\n                        </div>\n                        <div className=\"flex-[0.6]\">\n                            <IconUploader />\n                        </div>\n                    </div>\n                )}\n            </div>\n        </>\n    );\n};\n","import React, { useCallback } from \"react\";\nimport { faPlus } from \"@fortawesome/pro-light-svg-icons\";\nimport { ModalButton } from \"@/components/reusable/SharedComponents\";\nimport { useCustomComponentContext } from \"./CustomComponent\";\nimport { ComponentAccordion, Header } from \"./SubComponents\";\nimport { addExpandKey, cleanPythonName, useDeletePropEvent, useExpandedItems } from \"./helpers\";\nimport { IS_NEW, TEvent, TEventUpdater, TEvents, TProperties } from \"./types\";\n\n/**\n * Events\n */\n\nfunction getNewProperties(properties: TProperties, eventName: string, name: string | null) {\n    if (!eventName || name === eventName) {\n        return properties;\n    } else if (name === null) {\n        return properties.map((prop) =>\n            prop.binding_writeback_events\n                ? {\n                      ...prop,\n                      binding_writeback_events: prop.binding_writeback_events.filter((x) => x !== eventName),\n                  }\n                : prop\n        );\n    } else {\n        return properties.map((prop) =>\n            prop.binding_writeback_events\n                ? {\n                      ...prop,\n                      binding_writeback_events: prop.binding_writeback_events.map((x) => (x === eventName ? name : x)),\n                  }\n                : prop\n        );\n    }\n}\n\nfunction getNewEvents(events: TEvents, event: TEvent, updatedEvent: Partial<TEvent>) {\n    if (updatedEvent.default_event && !event.default_event) {\n        // remove all default events\n        return events.map((ev) => {\n            delete ev.default_event;\n            return ev;\n        });\n    }\n    return [...events];\n}\n\nexport const Events = () => {\n    const { properties, events, updateCustomComponent, custom_component } = useCustomComponentContext();\n    const expandFeature = useExpandedItems(events);\n    const { setExpandedKeys } = expandFeature;\n\n    const addOrUpdateEvent: TEventUpdater = useCallback(\n        async (event, updatedEvent) => {\n            const isNewEvent = event === null;\n            event ??= {} as TEvent;\n            const name = cleanPythonName(updatedEvent.name || event.name, event, events);\n            const newProperties = getNewProperties(properties, event.name, name);\n            const newEvents = getNewEvents(events, event, updatedEvent);\n            let idx = events.indexOf(event);\n            idx = idx === -1 ? events.length : idx;\n            const newEvent = { ...event, ...updatedEvent, name };\n            if (!newEvent.description) {\n                delete newEvent.description;\n            }\n            newEvents[idx] = newEvent;\n            if (isNewEvent) {\n                const propKey = addExpandKey(newEvent);\n                setExpandedKeys({ [propKey]: true });\n                newEvent[IS_NEW] = true;\n            }\n            updateCustomComponent({ properties: newProperties, events: newEvents });\n        },\n        [updateCustomComponent, events, properties]\n    );\n\n    const deleteEvent = useDeletePropEvent((event: TEvent) => {\n        const newProperties = getNewProperties(properties, event.name, null);\n        const newEvents = events.filter((ev: TEvent) => ev !== event);\n        return { properties: newProperties, events: newEvents };\n    });\n\n    return (\n        <>\n            <Header\n                title={\"Events\"}\n                description={`Configure events of your ${custom_component ? \"custom component\" : \"layout\"}`}\n                helplink=\"custom-events\"\n            />\n            <div className=\"p-4\">\n                <ComponentAccordion\n                    onDelete={deleteEvent}\n                    doUpdate={addOrUpdateEvent}\n                    type=\"events\"\n                    {...expandFeature}\n                />\n                <div className=\"my-4 flex gap-4\">\n                    <ModalButton\n                        onClick={() => {\n                            const event = { name: \"event\" } as TEvent;\n                            if (!events.length) {\n                                event.default_event = true;\n                            }\n                            addOrUpdateEvent(null, event);\n                        }}\n                        icon={faPlus}\n                        small\n                        variant=\"primary\">\n                        Add Event\n                    </ModalButton>\n                </div>\n            </div>\n        </>\n    );\n};\n","import React from \"react\";\nimport { ContentTextAreaInput } from \"@/components/reusable/SharedComponents\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { useCustomComponentContext } from \"./CustomComponent\";\nimport { Header } from \"./SubComponents\";\nimport { useResetState } from \"./helpers\";\n\n/**\n * Custom Component or Layout Help text\n */\n\nexport const HelpText = () => {\n    const { helpText, updateCustomComponent, custom_component } = useCustomComponentContext();\n\n    const [newHelpText, setNewHelpText] = useResetState(helpText, \"\");\n\n    const updateHelpText = useEvent(() => updateCustomComponent({ help_text: newHelpText }, \"Update help text\"));\n\n    const onBlur = () => helpText !== newHelpText && updateHelpText();\n    const onChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => setNewHelpText(e.target.value);\n\n    return (\n        <>\n            <Header\n                title={\"Help Text\"}\n                description={`Explain what this ${custom_component ? \"custom component does\" : \"layout provides\"} and how to use it`}\n            />\n            <div className=\"p-4\">\n                <div className=\"my-4 flex gap-4\">\n                    <ContentTextAreaInput\n                        className=\"flex-1 dark:placeholder:text-gray-400!\"\n                        placeholder={\"Add usage guidance or examples…\"}\n                        small={true}\n                        autoExpand\n                        value={newHelpText}\n                        onChange={onChange}\n                        onBlur={onBlur}\n                    />\n                </div>\n            </div>\n        </>\n    );\n};\n","import React, { useCallback } from \"react\";\nimport { faPlus } from \"@fortawesome/pro-light-svg-icons\";\nimport { ModalButton } from \"@/components/reusable/SharedComponents\";\nimport { useCustomComponentContext } from \"./CustomComponent\";\nimport { ComponentAccordion, Header } from \"./SubComponents\";\nimport { PROP_TYPES_TO_DISPLAY, addExpandKey, cleanPythonName, useDeletePropEvent, useExpandedItems } from \"./helpers\";\nimport { IS_NEW, TPropUpdater, TProperties, TProperty } from \"./types\";\n\n/**\n * Properties\n */\n\nfunction getNewProperties(properties: TProperties, property: TProperty, updatedProperty: Partial<TProperty>) {\n    if (updatedProperty.default_binding_prop && !property.default_binding_prop) {\n        return properties.map((prop, i) => {\n            if (prop.default_binding_prop) {\n                delete prop.default_binding_prop;\n            }\n            return prop;\n        });\n    }\n    return [...properties];\n}\n\nconst DELETE_IF_FALSE = [\n    \"description\",\n    \"allow_binding_writeback\",\n    \"group\",\n    \"priority\",\n    \"default_binding_prop\",\n    \"multiline\",\n    \"designer_hint\",\n    \"accept\",\n] as const;\n\nconst NEW_PROPERTY = {\n    name: \"prop\",\n    type: \"string\",\n    default_value: \"\",\n    important: true,\n} satisfies Partial<TProperty>;\n\nexport const Properties = () => {\n    const { properties, updateCustomComponent, custom_component } = useCustomComponentContext();\n\n    const expandFeature = useExpandedItems(properties);\n    const { setExpandedKeys } = expandFeature;\n\n    const addOrUpdateProperty: TPropUpdater = useCallback(\n        (property, updatedProperty) => {\n            const isNew = property === null;\n            property ??= {} as TProperty;\n            const name = cleanPythonName(updatedProperty.name || property.name, property, properties);\n            const newProperties = getNewProperties(properties, property, updatedProperty);\n            let idx = properties.indexOf(property);\n            idx = idx === -1 ? properties.length : idx;\n            const newProp = { ...property, ...updatedProperty, name } as TProperty;\n            for (const propName in newProp) {\n                if (newProp[propName as keyof TProperty] === undefined) {\n                    delete newProp[propName as keyof TProperty];\n                }\n            }\n            for (const propName of DELETE_IF_FALSE) {\n                // don't include these properties in the yaml\n                if (!newProp[propName as keyof TProperty]) {\n                    delete newProp[propName as keyof TProperty];\n                }\n            }\n            newProperties[idx] = newProp;\n            if (isNew) {\n                const propKey = addExpandKey(newProp);\n                setExpandedKeys({ [propKey]: true });\n                newProp[IS_NEW] = true;\n            }\n            updateCustomComponent({ properties: newProperties });\n        },\n        [updateCustomComponent, properties]\n    );\n\n    const deleteProperty = useDeletePropEvent((prop: TProperty) => ({\n        properties: properties.filter((p) => p !== prop),\n    }));\n\n    return (\n        <>\n            <Header\n                title={\"Properties\"}\n                description={`Configure properties of your ${custom_component ? \"custom component\" : \"layout\"}`}\n                helplink=\"custom-properties\"\n            />\n            {/* <Button onClick={useSortProperties()}>SORT PROPERITES</Button> */}\n            <div className=\"p-4\">\n                <ComponentAccordion\n                    onDelete={deleteProperty}\n                    doUpdate={addOrUpdateProperty}\n                    type=\"properties\"\n                    subtitle={(item) => PROP_TYPES_TO_DISPLAY[item.type as keyof typeof PROP_TYPES_TO_DISPLAY]}\n                    {...expandFeature}\n                />\n                <div className=\"my-4 flex gap-4\">\n                    <ModalButton\n                        onClick={() =>\n                            addOrUpdateProperty(null, {\n                                ...NEW_PROPERTY,\n                                default_binding_prop: !properties.length,\n                            })\n                        }\n                        small\n                        icon={faPlus}\n                        variant=\"primary\">\n                        Add property\n                    </ModalButton>\n                    {/**\n                     * @todo pass-through properties will allow the custom component to include parent class properties\n                     * in the same way that item is a pass-through property. e.g. visible, role, spacing_above...\n                     */}\n                    {/* <ModalButton small className={classes.p10} variant={\"highlight2\"}>\n                    Show pass-through properties\n                </ModalButton> */}\n                </div>\n            </div>\n        </>\n    );\n};\n","import React, { createContext, useMemo } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { LayoutMetadataCustomComponentConfig } from \"@/components/modals/customcomponent/LayoutMetadataConfig\";\nimport { ToolboxSettings } from \"@/components/modals/customcomponent/ToolboxSettings\";\nimport { PROP_TYPES, PROP_TYPES_V3 } from \"@/components/modals/customcomponent/helpers\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { CheckBox } from \"@/components/reusable/Forms\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport { getAppRuntimeOptions } from \"@/controllers/app\";\nimport {\n    getCachedCodeItem,\n    getCustomComponentForms,\n    openCodeItem,\n    toggleIsLayout,\n    useUpdateCustomComponent,\n} from \"@/controllers/app/code\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { AnvilDispatch, CodePath, FormItem, FormItemYaml, State } from \"@/types\";\nimport { createContextHook, useMemoiseObject, useRerender } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \"..\";\nimport Modal from \"../Modal\";\nimport { Events } from \"./Events\";\nimport { HelpText } from \"./HelpText\";\nimport { Properties } from \"./Properties\";\nimport { CustomFormItem } from \"./types\";\n\nexport interface CustomComponentContextValue {\n    updateCustomComponent: ReturnType<typeof useUpdateCustomComponent>;\n    formName: string;\n    eventNames: string[];\n    groups: string[];\n    properties: Required<CustomFormItem>[\"properties\"];\n    events: Required<CustomFormItem>[\"events\"];\n    toolbox_item: Required<CustomFormItem>[\"toolbox_item\"];\n    propTypes: typeof PROP_TYPES;\n    custom_component: Required<CustomFormItem>[\"custom_component\"];\n    layoutMetadata: Required<CustomFormItem>[\"layout_metadata\"];\n    helpText?: Required<CustomFormItem>[\"help_text\"];\n}\n\nconst CustomComponentContext = createContext<CustomComponentContextValue | null>(null);\nexport const useCustomComponentContext = createContextHook(CustomComponentContext, \"CustomComponent\");\n\ninterface CustomBodyProps {\n    codePath: CodePath;\n}\n\nconst CustomComponentBody = ({ codePath }: CustomBodyProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const runtimeOptions = useSelector(getAppRuntimeOptions);\n    const canUseClassic = (runtimeOptions?.version ?? 0) < 3;\n    const { item, conflicts } = useSelector((state: State) => getCachedCodeItem(codePath, state)) as Partial<FormItem>;\n    const customComponents = useSelector(getCustomComponentForms);\n    const groups = useMemo(() => {\n        return Array.from(new Set(customComponents.map((f) => f.toolboxItem?.group).filter(Boolean)));\n    }, [customComponents]);\n\n    const updateCustomComponent = useUpdateCustomComponent(codePath, item, conflicts);\n    const {\n        properties = [],\n        custom_component = false,\n        custom_component_container = false,\n        events = [],\n        toolbox_item = {},\n        slots,\n        layout_metadata = {},\n        help_text,\n    } = (item || {}) as FormItemYaml;\n\n    const toggleCustomComponent = useEvent(() =>\n        updateCustomComponent({ custom_component: !custom_component }, \"Set custom component\")\n    );\n\n    const toggleContainer = useEvent(() =>\n        updateCustomComponent({ custom_component_container: !custom_component_container })\n    );\n\n    const showCustomContainerToggle =\n        (item?.container?.type === \"HtmlTemplate\" || item?.container?.type === \"HtmlComponent\") && custom_component;\n\n    const eventNames = useMemo(() => events.map((event) => event.name), [events]);\n\n    if (!item) {\n        // load the item and create a suspense boundary\n        throw Promise.resolve(dispatch(openCodeItem(codePath)));\n    }\n\n    const runtimeVersion = useSelector(getAppRuntimeOptions)?.version ?? 0;\n    const propTypes = useMemo(() => [...PROP_TYPES, ...(runtimeVersion >= 3 ? PROP_TYPES_V3 : [])], [runtimeVersion]);\n\n    const value = useMemoiseObject<CustomComponentContextValue>({\n        properties,\n        events,\n        updateCustomComponent,\n        formName: item.class_name,\n        eventNames,\n        toolbox_item,\n        groups,\n        propTypes,\n        custom_component,\n        layoutMetadata: layout_metadata,\n        helpText: help_text,\n    });\n\n    const rerender = useRerender();\n\n    const onToggleLayout = useEvent(async () => {\n        if (item) {\n            await dispatch(toggleIsLayout(codePath, item, !item.slots));\n            // the above doesn't trigger a re-render but we need it to\n            rerender();\n            // TODO: Reload editing form if slots have actually been deleted.\n        }\n    });\n\n    const hasSlots = Boolean(slots);\n\n    return (\n        <CustomComponentContext.Provider value={value}>\n            <div className=\"m-8 flex flex-col gap-4\">\n                {!canUseClassic && (\n                    <CheckBox checked={hasSlots} onChange={onToggleLayout}>\n                        <div className={\"flex gap-4\"}>\n                            <span>Make this Form available as a layout</span>\n                            <HelpLink inline url={\"/docs/ui/layouts#creating-a-layout-from-an-anvil-form\"} />\n                        </div>\n                    </CheckBox>\n                )}\n                <CheckBox checked={custom_component || false} onChange={toggleCustomComponent}>\n                    <div className={\"flex gap-4\"}>\n                        <span>Make this Form available as a custom component</span>\n                        <HelpLink inline url={\"/docs/client/custom-components\"} />\n                    </div>\n                </CheckBox>\n                <Expander isOpen={showCustomContainerToggle}>\n                    <div className=\"ml-16 flex justify-between\">\n                        <CheckBox\n                            checked={custom_component_container}\n                            onChange={toggleContainer}\n                            className={\"font-normal\"}>\n                            Make this Form available as a container\n                        </CheckBox>\n                    </div>\n                </Expander>\n            </div>\n\n            <Expander isOpen={custom_component || hasSlots}>\n                <Properties />\n                <Events />\n            </Expander>\n\n            <Expander isOpen={custom_component || hasSlots}>\n                <HelpText />\n            </Expander>\n\n            <Expander isOpen={custom_component}>\n                <ToolboxSettings />\n            </Expander>\n\n            <Expander isOpen={hasSlots}>\n                <LayoutMetadataCustomComponentConfig />\n            </Expander>\n        </CustomComponentContext.Provider>\n    );\n};\n\ninterface CustomComponentSpec {\n    codePath: CodePath;\n}\n\nconst CustomComponent: ModalComponent<CustomComponentSpec> = ({ modalId, spec: { codePath } }) => (\n    <Modal\n        modalId={modalId}\n        allowDismiss={true}\n        title=\"Configuration\"\n        buttons={[{ text: \"Close\", clickActionCreator: () => modalReturn(true) }]}>\n        <CustomComponentBody codePath={codePath} />\n    </Modal>\n);\nexport default CustomComponent;\n","import React, { useId, useMemo, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faSliders } from \"@fortawesome/pro-regular-svg-icons/faSliders\";\nimport { faChevronDown, faChevronRight, faTrash } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { DepConfigKeys, DepConfigSchemaDef, DependencyConfigType, DependencyPropConfig } from \"@runtime/runner/data\";\nimport { PROP_TYPES_TO_DISPLAY } from \"@/components/modals/customcomponent/helpers\";\nimport { ModalComponent } from \"@/components/modals/index\";\nimport { Accordion } from \"@/components/reusable/Accordion\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { CheckBox, DropDown } from \"@/components/reusable/Forms\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { useSaveIndicator } from \"@/components/reusable/SaveIndicator\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport TextInput from \"@/components/reusable/TextInput\";\nimport { getAppConfig } from \"@/controllers/app\";\nimport { getDependencyCode } from \"@/controllers/app/code\";\nimport {\n    dependencyAndIdentifier,\n    removeDependencyConfig,\n    removeStaleConfig,\n    saveIfDependencyConfigHasChanged,\n    updateDependencyConfig,\n} from \"@/controllers/dependencies\";\nimport { AnvilDispatch, AppConfig, DependencyConfig, DependencyConfigSchemaConfig, SchemaConfigProp } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\nimport Modal from \"./Modal\";\n\n/*\n * Supported types:\n * - String\n * - Number\n * - Boolean\n * - String list\n * - Enum\n *\n * Not (yet?) supported types:\n * - Color\n * - Icon\n * - Form\n * - Object\n * - Uri\n * - Margin\n * - Padding\n * - Spacing\n *\n * Definitely not supported types:\n * - TBD\n * */\n\nconst SUPPORTED_PROP_TYPE = [\"string\", \"number\", \"boolean\", \"text[]\", \"enum\"]; // this should match with DependencyConfigType\n\ninterface StringConfigPropProps {\n    value?: null | string;\n    defaultValue: string;\n    onChange: (v: string) => void;\n    propName: string;\n}\n\nconst StringConfigProp = ({ value, defaultValue, onChange, propName }: StringConfigPropProps) => {\n    return (\n        <TextInput\n            small\n            className={\"mb-0!\"}\n            placeholder={defaultValue as string}\n            saveKey={propName}\n            initialValue={value ?? \"\"}\n            onSave={onChange}\n            title={\"\"}\n        />\n    );\n};\n\ninterface NumberConfigPropProps {\n    value?: null | number;\n    defaultValue: number;\n    onChange: (v: number | null) => void;\n    propName: string;\n}\n\nconst NumberConfigProp = ({ value, defaultValue, onChange, propName }: NumberConfigPropProps) => {\n    const _onChange = (v: string) => {\n        onChange(v === \"\" ? null : Number(v));\n    };\n\n    return (\n        <TextInput\n            type={\"number\"}\n            small\n            className={\"mb-0!\"}\n            placeholder={`${defaultValue}`}\n            saveKey={propName}\n            initialValue={`${value}`}\n            onSave={_onChange}\n            title={\"\"}\n        />\n    );\n};\n\ninterface BooleanConfigPropProps {\n    value?: null | boolean;\n    defaultValue: boolean;\n    onChange: (v: boolean) => void;\n}\n\nconst BooleanConfigProp = ({ value, defaultValue, onChange }: BooleanConfigPropProps) => {\n    const [checked, setChecked] = useState(value ?? defaultValue ?? false);\n    const [saveIndicator, setSaved] = useSaveIndicator();\n\n    const _onChange = useEvent((e: React.ChangeEvent<HTMLInputElement>) => {\n        const newValue = e.target.checked; // Get the checked state\n        setChecked(newValue);\n        onChange(newValue); // Call the onChange handler with the new value\n        setSaved(true);\n    });\n\n    return (\n        <div className={\"flex items-center gap-2\"}>\n            <CheckBox checked={checked} onChange={_onChange} />\n            {saveIndicator}\n        </div>\n    );\n};\n\ninterface StringListConfigPropProps {\n    value: string[] | string;\n    defaultValue: string[] | string;\n    onChange: (v: string) => void;\n    propName: string;\n}\n\nconst StringListConfigProp = ({ value, defaultValue, onChange, propName }: StringListConfigPropProps) => {\n    const placeholderText = typeof defaultValue === \"string\" ? defaultValue : (defaultValue?.join?.(\"\\n\") ?? \"\");\n    return (\n        <TextInput\n            small={true}\n            className={\"mb-0!\"}\n            placeholder={placeholderText}\n            saveKey={propName}\n            initialValue={typeof value === \"string\" ? value : (value?.join?.(\"\\n\") ?? \"\")}\n            onSave={onChange}\n            title={\"\"}\n            textarea={true}\n            textBoxClassName={\"min-h-32\"}\n        />\n    );\n};\n\ninterface StaleComponentProps {\n    type: DepConfigKeys;\n    propName: string;\n    value: string | string[];\n    dependency: DependencyConfig;\n}\n\nconst StaleComponent = ({ type, propName, value, dependency }: StaleComponentProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    return (\n        <div className={\"flex w-full flex-nowrap items-center gap-4 rounded-md border border-sectionborder p-4\"}>\n            <div className={\"grow\"}>\n                <div className={\"font-mono leading-none font-semibold\"}>{propName}</div>\n                <Text level={3} className={\"m-0!\"}>\n                    {type.charAt(0).toUpperCase() + type.slice(1)} Configuration\n                </Text>\n                <div className={\"pl-4 font-mono leading-none\"}>{`${value}`}</div>\n            </div>\n            <div className={\"flex-none pr-4\"}>\n                <Button\n                    icon={faTrash}\n                    variants={[\"danger\", \"outlined\"]}\n                    small\n                    onClick={() => dispatch(removeStaleConfig(dependency, type, propName))}>\n                    Remove\n                </Button>\n            </div>\n        </div>\n    );\n};\n\ninterface EnumConfigPropProps {\n    value: string;\n    options: string[];\n    onChange: (v: string) => void;\n    onClear: () => void;\n}\n\nconst EnumConfigProp = ({ value, options, onChange, onClear }: EnumConfigPropProps) => {\n    const [saveIndicator, setSaved] = useSaveIndicator();\n    const id = useId();\n    const [ddValue, setValue] = useState(value ?? `${id}-null`);\n\n    const _onChange = useEvent(async (e: React.ChangeEvent<HTMLSelectElement>) => {\n        const newValue = e.target.value;\n        setValue(newValue);\n        if (newValue === `${id}-null`) {\n            onClear();\n        } else {\n            onChange(newValue);\n        }\n        setSaved(true);\n    });\n\n    return (\n        <div className={\"flex items-center gap-2\"}>\n            <DropDown variant={\"small\"} value={ddValue} onChange={_onChange}>\n                <option value={`${id}-null`}></option>\n                <hr />\n                {options.map((optionValue, ind: number) => (\n                    <option key={`${id}-${ind}-${optionValue}`} value={optionValue}>\n                        {optionValue}\n                    </option>\n                ))}\n            </DropDown>\n\n            {saveIndicator}\n        </div>\n    );\n};\n\ninterface DependencyPropProps {\n    type: DepConfigKeys;\n    schemaItem: DependencyPropItem;\n    yamlValues: SchemaConfigProp;\n    dependency: DependencyConfig;\n}\n\nconst DependencyProp = ({\n    type,\n    schemaItem: { propName, value: schemaProp },\n    yamlValues,\n    dependency,\n}: DependencyPropProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const onChangeBooleanProperty = useEvent(async (v: boolean) =>\n        dispatch(updateDependencyConfig(dependency, type, propName, v))\n    );\n\n    const onChangeTextProp = useEvent((saveValue: string, list = false) => {\n        if (yamlValues?.value === saveValue) return;\n        if (saveValue === \"\") {\n            dispatch(removeDependencyConfig(dependency, type, propName));\n        } else {\n            dispatch(updateDependencyConfig(dependency, type, propName, list ? saveValue.split(\"\\n\") : saveValue));\n        }\n    });\n\n    const onChangeNumberProp = useEvent((saveValue: number | null) => {\n        if (yamlValues?.value === saveValue) return;\n        if (saveValue === null) {\n            dispatch(removeDependencyConfig(dependency, type, propName));\n        } else {\n            dispatch(updateDependencyConfig(dependency, type, propName, saveValue));\n        }\n    });\n\n    const propEditor = () => {\n        switch (schemaProp.type) {\n            case \"string\":\n                return (\n                    <StringConfigProp\n                        value={yamlValues?.value as string | null}\n                        defaultValue={schemaProp.default_value as string}\n                        onChange={onChangeTextProp}\n                        propName={propName}\n                    />\n                );\n            case \"number\":\n                return (\n                    <NumberConfigProp\n                        value={yamlValues?.value || schemaProp.default_value}\n                        defaultValue={schemaProp.default_value as number}\n                        onChange={onChangeNumberProp}\n                        propName={propName}\n                    />\n                );\n            case \"boolean\":\n                return (\n                    <BooleanConfigProp\n                        value={yamlValues?.value as boolean | null}\n                        defaultValue={schemaProp.default_value as boolean}\n                        onChange={onChangeBooleanProperty}\n                    />\n                );\n            case \"text[]\":\n                return (\n                    <StringListConfigProp\n                        value={(yamlValues?.value ?? \"\") as string | string[]}\n                        defaultValue={schemaProp.default_value as string[]}\n                        onChange={onChangeTextProp}\n                        propName={propName}\n                    />\n                );\n            case \"enum\":\n                return (\n                    <EnumConfigProp\n                        value={(yamlValues?.value ?? \"\") as string}\n                        options={schemaProp.options || []}\n                        onChange={async (v: string) => dispatch(updateDependencyConfig(dependency, type, propName, v))}\n                        onClear={async () => dispatch(removeDependencyConfig(dependency, type, propName))}\n                    />\n                );\n            default:\n                return <>Configure this value in the yaml</>;\n        }\n    };\n\n    //todo: swap these if we do want to show things that need to be directly changed from the yaml. Will have to change copy in propEditor()\n    // return schemaProp.hidden ? null : (\n    return schemaProp.hidden || !SUPPORTED_PROP_TYPE.includes(schemaProp.type as DependencyConfigType) ? null : (\n        <>\n            <div className={\"flex flex-col pt-8\"}>\n                {schemaProp.title ? (\n                    <div className={\"font-semibold\"}>{schemaProp.title}</div>\n                ) : (\n                    <div className={\"font-mono font-semibold\"}>{propName}</div>\n                )}\n\n                <Text className={\"m-0! font-semibold!\"} level={3}>\n                    {schemaProp.type ? (PROP_TYPES_TO_DISPLAY[schemaProp.type] ?? schemaProp.type) : null}\n                </Text>\n            </div>\n            <div className={\"pt-8\"}>\n                {propEditor()}\n                {schemaProp.description && (\n                    <Text className={\"m-0!\"} level={3}>\n                        {schemaProp.description}\n                    </Text>\n                )}\n            </div>\n        </>\n    );\n};\n\ninterface DependencyConfigBodyProps {\n    dependency: DependencyConfig;\n    schema: ConfigItemProps;\n}\n\ninterface DependencyPropItem {\n    propName: string;\n    value: DependencyPropConfig;\n}\n\nconst DependencyConfigBody = ({ schema: { content, id: type }, dependency }: DependencyConfigBodyProps) => {\n    const yaml = dependency.config?.[type];\n    const propItems = useMemo(() => {\n        const items: DependencyPropItem[] = [];\n        Object.entries(content || {}).forEach(([key, value]) => {\n            if (!value.hidden) items.push({ propName: key, value: value });\n        });\n        return items;\n    }, [content]);\n\n    return (\n        <div className={\"grid grid-cols-[max-content_1fr] gap-x-8 px-8 py-4\"}>\n            {propItems.map((item, ind) => (\n                <DependencyProp\n                    key={ind}\n                    type={type}\n                    schemaItem={item}\n                    yamlValues={yaml?.[item.propName] as SchemaConfigProp}\n                    dependency={dependency}\n                />\n            ))}\n        </div>\n    );\n};\n\ntype ConfigItemProps = { id: DepConfigKeys; content: DepConfigSchemaDef };\n\ntype staleItem = {\n    type: DepConfigKeys;\n    propName: string;\n    value: any;\n};\n\nconst ConfigureDependency: ModalComponent<{ refDep: DependencyConfig }> = ({ modalId, spec: { refDep } }) => {\n    const appConfig = useSelector(getAppConfig);\n    const dispatch = useDispatch<AnvilDispatch>();\n    const depCode = useSelector(getDependencyCode);\n    const { dep: dependency, activeDepAppId } = useMemo(\n        () => dependencyAndIdentifier(refDep, appConfig as AppConfig),\n        [refDep, appConfig]\n    );\n\n    const config_schema = useMemo(() => {\n        return depCode ? depCode?.[activeDepAppId]?.config_schema : {};\n    }, [depCode, activeDepAppId]);\n\n    const configItems = useMemo(() => {\n        const types: ConfigItemProps[] = [];\n        const entries = Object.entries(config_schema || {});\n        entries.forEach(([key, specs]) => {\n            const hidden = Object.keys(specs).find((key) => !specs[key].hidden);\n            if (hidden) types.push({ id: key as DepConfigKeys, content: specs as DepConfigSchemaDef });\n        });\n        return types;\n    }, [config_schema]);\n\n    const [expandedKeys, setExpandedKeys] = useState<Record<string, boolean>>({});\n\n    const toggleItem = (item: { id: string }) => {\n        setExpandedKeys((prev) => ({\n            ...prev,\n            [item.id]: !prev[item.id],\n        }));\n    };\n\n    const staleComponents = useMemo(() => {\n        const components: staleItem[] = [];\n        if (!dependency?.config) return components;\n\n        type IterDepConfig = Array<[DepConfigKeys, DependencyConfigSchemaConfig[DepConfigKeys]]>;\n\n        (Object.entries(dependency.config) as IterDepConfig).forEach(([type, content]) => {\n            Object.entries(content || {}).forEach(([propName, { value }]) => {\n                if (!config_schema?.[type]?.[propName]) {\n                    components.push({ type, propName, value });\n                }\n            });\n        });\n\n        return components;\n    }, [config_schema, dependency?.config]);\n    const [sOpen, setSOpen] = useState(false);\n\n    if (!dependency) return null;\n\n    return (\n        <Modal\n            modalId={modalId}\n            title=\"Configure Dependency\"\n            icon={faSliders}\n            size=\"medium\"\n            buttons={[{ text: \"Done\", variant: \"primary\", close: true }]}\n            beforeClose={() => {\n                // Field edits autosave; reload dependencies on close if configuration changed.\n                dispatch(saveIfDependencyConfigHasChanged(refDep));\n            }}>\n            <Text level={3}>Changes are saved automatically for this app.</Text>\n            {config_schema && (\n                <div>\n                    <Heading>Edit Dependency Configuration</Heading>\n                    <Accordion\n                        items={configItems}\n                        keyName=\"id\"\n                        expandedKeys={expandedKeys}\n                        onToggle={toggleItem}\n                        renderHeader={(config_schema) => (\n                            <div>\n                                {config_schema.id.charAt(0).toUpperCase() + config_schema.id.slice(1)} Configuration\n                            </div>\n                        )}\n                        renderBody={(config_schema) => (\n                            <DependencyConfigBody schema={config_schema} dependency={dependency as DependencyConfig} />\n                        )}\n                    />\n                </div>\n            )}\n            {staleComponents.length > 0 && (\n                <>\n                    <LinkInternal onClick={() => setSOpen((o) => !o)}>\n                        <Heading>\n                            Stale Properties <FontAwesomeIcon icon={sOpen ? faChevronDown : faChevronRight} />\n                        </Heading>\n                    </LinkInternal>\n\n                    <Expander isOpen={sOpen} duration={300}>\n                        <Text level={3} className={\"leading-[1.2]\"}>\n                            Stale Properties are configuration in the yaml that aren't found in the dependency. This\n                            could be a result of an error in the yaml, or changes in the dependency rending the saved\n                            value as obsolete.\n                        </Text>\n                        <div className={\"my-4 flex flex-col gap-8\"}>\n                            {staleComponents.map(({ type, propName, value }, ind) => (\n                                <StaleComponent\n                                    key={ind}\n                                    type={type}\n                                    value={value}\n                                    propName={propName}\n                                    dependency={dependency as DependencyConfig}\n                                />\n                            ))}\n                        </div>\n                    </Expander>\n                </>\n            )}\n        </Modal>\n    );\n};\n\nexport default ConfigureDependency;\n","import React, { useCallback } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { ModalComponent } from \"@/components/modals/index\";\nimport TextInput from \"@/components/reusable/TextInput\";\nimport { getAppId } from \"@/controllers/app\";\nimport { getUserUiPrefs, updateUserEditorPrefs } from \"@/controllers/user\";\nimport { AnvilDispatch } from \"@/types\";\nimport Modal from \"./Modal\";\n\nexport const ConfigureRunner: ModalComponent = ({ modalId, spec }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const appId = useSelector(getAppId)!;\n    const userUiPrefs = useSelector(getUserUiPrefs);\n\n    const setStartupUrl = useCallback(\n        async (startupUrl: string) => {\n            dispatch(updateUserEditorPrefs(\"appRunPaths\", { ...(userUiPrefs.appRunPaths || {}), [appId]: startupUrl }));\n        },\n        [userUiPrefs]\n    );\n\n    return (\n        <Modal title={\"Configure runner\"} modalId={modalId} buttons={[{ text: \"Close\" }]}>\n            <TextInput\n                initialValue={userUiPrefs.appRunPaths?.[appId] || \"\"}\n                title={\"Startup URL\"}\n                description={\"The path to load when running the app\"}\n                placeholder={\"/\"}\n                onSave={setStartupUrl}\n            />\n        </Modal>\n    );\n};\n","import React, { useCallback, useMemo, useState } from \"react\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { ModalComponent } from \".\";\nimport { ContentTextInput } from \"../reusable/SharedComponents\";\nimport Modal from \"./Modal\";\nimport useStyles from \"./modalstyles\";\n\nconst CreateTag: ModalComponent<never, string | null> = ({ modalId }) => {\n    let { classes } = useStyles();\n\n    let [value, setValue] = useState(\"\");\n\n    const inputRef = useCallback((node: HTMLInputElement | null) => {\n        node?.focus();\n    }, []);\n\n    const buttonText = useMemo(() => (value ? `Tag commit as '${value}'` : \"Enter a Name\"), [value]);\n    const enabled = useMemo(() => !!value, [value]);\n\n    return (\n        <Modal\n            autoFocus={false}\n            modalId={modalId}\n            allowDismiss={true}\n            title=\"Enter tag name\"\n            buttons={[\n                { text: buttonText, clickActionCreator: () => modalReturn(value), defaultButton: true, enabled },\n                { text: \"Cancel\", clickActionCreator: () => modalReturn(null) },\n            ]}>\n            Tags beginning with <code>v</code> (e.g. <code>v1.2</code>) will be made available as pinned versions when\n            adding this app as a dependency.\n            <br />\n            <ContentTextInput\n                ref={inputRef}\n                className={classes.fullWidth}\n                value={value}\n                onChange={(e: React.ChangeEvent<HTMLInputElement>) => setValue(e.target.value)}\n                disableEsc={true}\n            />\n        </Modal>\n    );\n};\n\nexport default CreateTag;\n","import React, { useCallback, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { ModalComponent } from \".\";\nimport { getApp } from \"../../controllers/app\";\nimport { ContentTextInput } from \"../reusable/SharedComponents\";\nimport { Text } from \"../reusable/Text\";\nimport Modal from \"./Modal\";\n\nconst DeleteApp: ModalComponent<{ appName: string | null }, boolean> = ({ modalId, spec: { appName } }) => {\n    const app = useSelector(getApp);\n    const name = appName || app?.name;\n    const [input, setInput] = useState(\"\");\n    const enabled = name === input;\n\n    const inputRef = useCallback((node: HTMLInputElement) => {\n        node?.focus();\n    }, []);\n\n    return (\n        <Modal\n            autoFocus={false}\n            title={`Delete ${name}?`}\n            modalId={modalId}\n            buttons={[\n                { text: \"Delete\", returns: true, variant: \"danger\", enabled, defaultButton: true },\n                { text: \"Cancel\", returns: false },\n            ]}>\n            <Text>\n                This action cannot be undone. This will permanently delete the{\" \"}\n                <span className={\"font-mono font-semibold text-primary select-text\"}>{name}</span> app.\n            </Text>\n            <Text>\n                Please type <span className={\"font-mono font-semibold text-primary select-text\"}>{name}</span> to\n                confirm.\n            </Text>\n\n            <ContentTextInput\n                ref={inputRef}\n                className={\"w-full\"}\n                value={input}\n                onChange={(e) => setInput(e.target.value)}\n            />\n        </Modal>\n    );\n};\n\nexport default DeleteApp;\n","import * as React from \"react\";\nimport { useRef } from \"react\";\nimport { connect } from \"react-redux\";\nimport { getAppId } from \"@/controllers/app\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport type { TableMapping } from \"@/types/database\";\nimport type { ModalComponent } from \".\";\nimport { HelpLink } from \"../reusable/HelpLink\";\nimport Modal, { ModalRef } from \"./Modal\";\nimport useStyles from \"./modalstyles\";\n\ninterface DirectSQLAccessModalSpec {\n    mapping: TableMapping;\n}\n\nconst connector = connect((state: State) => ({\n    appId: getAppId(state),\n}));\n\ntype DirectSQLAccessModalProps = AnvilConnectedProps<typeof connector>;\n\nconst DirectSQLAccessModal: ModalComponent<DirectSQLAccessModalSpec, null, DirectSQLAccessModalProps> = ({\n    appId,\n    modalId,\n    spec: { mapping },\n}) => {\n    const { classes } = useStyles();\n    const modalRef = useRef<ModalRef>(null);\n    const schemaName = `app_schema_${mapping?.table_mapping_id ? `_${mapping.table_mapping_id}` : `${appId}_tables`}`;\n\n    return (\n        <Modal\n            ref={modalRef}\n            title=\"Direct SQL Access\"\n            modalId={modalId}\n            buttons={[{ text: \"Close\", clickActionCreator: () => modalReturn(null) }]}>\n            <div style={{ marginBottom: \"2rem\" }}>\n                Import <code className={classes.selectable}>psycopg2</code> and{\" \"}\n                <code className={classes.selectable}>anvil.tables</code> into the top of your Server Module and call{\" \"}\n                <code className={classes.selectable}>anvil.tables.get_connection_string()</code>. This connection string\n                is linked to the schema of the environment that your code is running in.\n                <br />\n            </div>\n            <div style={{ marginBottom: \"2rem\" }}>\n                For example, if your app has a Data Table called <strong className={classes.selectable}>users</strong>:\n                <pre className={classes.selectable}>\n                    import psycopg2\n                    <br />\n                    import anvil.tables\n                    <br />\n                    <br />\n                    conn = psycopg2.connect(anvil.tables.get_connection_string())\n                    <br />\n                    with conn.cursor() as cur:\n                    <br />\n                    &nbsp;&nbsp;&nbsp;&nbsp;cur.execute(\"SELECT * FROM <strong>users</strong>\")\n                    <br />\n                    &nbsp;&nbsp;&nbsp;&nbsp;all_entries = list(cur)\n                    <br />\n                </pre>\n            </div>\n            <hr />{\" \"}\n            {/*todo: these are impossible to see in light theme and pretty hard to see in dark. Are we married with 3 young children to this or can we look into changing it*/}\n            <div style={{ marginBottom: \"2rem\" }}>\n                For external access to this database, please contact{\" \"}\n                <a href=\"mailto:support@anvil.works\"> support@anvil.works</a>\n                <br />\n                To refer to <strong>{mapping.name}</strong>, use the Postgres schema{\" \"}\n                <code className={classes.selectable}>{`${schemaName}`}</code>\n            </div>\n            <p>\n                For more information, consult the{\" \"}\n                <HelpLink url={\"https://anvil.works/docs/data-tables/sql-access\"} iconRight inline>\n                    SQL access documentation\n                </HelpLink>\n            </p>\n        </Modal>\n    );\n};\n\nexport default connector(DirectSQLAccessModal) as typeof DirectSQLAccessModal;\n","import React, { ReactNode, useMemo } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { getAppRefs } from \"@/controllers/app/history\";\nimport { getUser } from \"@/controllers/ide\";\nimport { useStateWithReset } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ContentDropdownMenuItem } from \"./SharedComponents\";\n\ninterface RefSelectorProps {\n    value?: string | null;\n    items: Record<string, { commitId: string }>;\n    onSelect?: (value: string) => void;\n    onCreate?: () => void;\n    createLabel?: string;\n    additionalOptions?: ReactNode;\n}\n\nconst RefSelector: React.FC<RefSelectorProps> = ({\n    value,\n    items,\n    onSelect,\n    onCreate,\n    createLabel = \"Create new...\",\n    additionalOptions,\n}) => {\n    const [_value, setValue] = useStateWithReset(value);\n\n    const onChange = useEvent((v: string) => {\n        if (v === \"**\") {\n            onCreate?.();\n        } else {\n            setValue(v);\n            onSelect?.(v);\n        }\n    });\n\n    const options = useMemo(() => {\n        return Object.entries(items || {})\n            .sort((a, b) => a[0].localeCompare(b[0]))\n            .map(([name, { commitId }]) => (\n                <option key={`${name}-${commitId}`} value={name}>\n                    {name}\n                </option>\n            ));\n    }, [items]);\n\n    // TODO: Work out why dropdown caret is displaced upwards, but works in dependencies table.\n    return (\n        <ContentDropdownMenuItem\n            narrow\n            onChange={(e: React.ChangeEvent<HTMLSelectElement>) => onChange(e.target.value)}\n            value={_value || \"*\"}>\n            {!value && <option value={\"*\"} />}\n            {options}\n            {additionalOptions}\n            {onCreate && <option value={\"**\"}>{createLabel}</option>}\n        </ContentDropdownMenuItem>\n    );\n};\n\ninterface BranchSelectorProps {\n    branch?: string | null;\n    includePersonal?: boolean;\n    onSelect?: (branch: string) => void;\n    onCreate?: () => void;\n}\n\nconst BranchSelector: React.FC<BranchSelectorProps> = ({ branch, includePersonal, onSelect, onCreate }) => {\n    const refs = useSelector(getAppRefs);\n    const user = useSelector(getUser);\n\n    const userBranch = `users/${user.email}`;\n\n    return (\n        <RefSelector\n            value={branch}\n            items={refs?.nonCollaboratorBranches || {}}\n            onSelect={onSelect}\n            onCreate={onCreate}\n            createLabel=\"Create new branch...\"\n            additionalOptions={includePersonal && <option value={userBranch}>My development branch</option>}\n        />\n    );\n};\n\ninterface TagSelectorProps {\n    tag?: string | null;\n    onSelect?: (tag: string) => void;\n    onCreate?: () => void;\n}\n\nexport const TagSelector: React.FC<TagSelectorProps> = ({ tag, onSelect, onCreate }) => {\n    const refs = useSelector(getAppRefs);\n\n    return (\n        <RefSelector\n            value={tag}\n            items={refs?.tags || {}}\n            onSelect={onSelect}\n            onCreate={onCreate}\n            createLabel=\"Create new tag...\"\n        />\n    );\n};\n\nexport default BranchSelector;\n","import React, { useCallback, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faDocker } from \"@fortawesome/free-brands-svg-icons/faDocker\";\nimport { faSync } from \"@fortawesome/pro-regular-svg-icons/faSync\";\nimport { faCheck } from \"@fortawesome/pro-solid-svg-icons/faCheck\";\nimport { faExclamationTriangle } from \"@fortawesome/pro-solid-svg-icons/faExclamationTriangle\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport BranchSelector from \"@/components/reusable/BranchSelector\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { InputLabel } from \"@/components/reusable/Forms\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport TextInput from \"@/components/reusable/TextInput\";\nimport { exportAppToDocker, getAppEditState, getAppId, getAppPackageName } from \"@/controllers/app\";\nimport { IDETask, watchIDETask } from \"@/controllers/ide_tasks\";\nimport { getUserUiPrefs } from \"@/controllers/user\";\nimport { AnvilDispatch } from \"@/types\";\nimport { ModalComponent } from \".\";\nimport Modal from \"./Modal\";\n\nconst DockerExportModal: ModalComponent = ({ modalId }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const appId = useSelector(getAppId)!;\n    const editState = useSelector(getAppEditState);\n    const uiPrefs = useSelector(getUserUiPrefs);\n    const appPackageName = useSelector(getAppPackageName)!;\n    const [branch, setBranch] = useState(editState!.branch as string);\n    const [registryHost, setRegistryHost] = useState(uiPrefs.defaultContainerRegistry?.url || \"\");\n    const [registryUser, setRegistryUser] = useState(uiPrefs.defaultContainerRegistry?.username || \"\");\n    const [registryPassword, setRegistryPassword] = useState(uiPrefs.defaultContainerRegistry?.password || \"\");\n\n    const [repoPath, setRepoPath] = useState(\n        uiPrefs.defaultAppExportRepoPaths?.[appId] || `/anvil-${appPackageName.replace(\"_\", \"-\").toLowerCase()}`\n    );\n\n    // We'll probably want to move this into the redux state so you can return to it, but this is fine for now. Once\n    // it's in redux, we'll have to think about changing branches, apps, etc between visits to this modal.\n    const [exportTask, setExportTask] = useState<IDETask | null>(null);\n\n    const doExport = useCallback(async () => {\n        const taskId = await dispatch(\n            exportAppToDocker(\n                appId,\n                branch,\n                { url: registryHost, username: registryUser, password: registryPassword },\n                repoPath\n            )\n        );\n        dispatch(\n            watchIDETask(taskId, (task) => {\n                setExportTask(task);\n            })\n        );\n    }, [branch, registryHost, registryUser, registryPassword, repoPath]);\n\n    return (\n        <Modal\n            modalId={modalId}\n            title={\"Export to Docker\"}\n            icon={faDocker}\n            buttons={[{ text: \"Close\", close: true }]}\n            leftButtons={\n                exportTask?.completed && (\n                    <Button small icon={faSync} onClick={() => setExportTask(null)}>\n                        Start over\n                    </Button>\n                )\n            }>\n            {exportTask ? (\n                <div>\n                    {!exportTask.completed && (\n                        <div className={\"mt-16 text-center\"}>\n                            <div style={{ height: \"4rem\", position: \"relative\" }}>\n                                <div style={{ marginTop: \"1rem\", transform: \"scale(0.6)\" }}>\n                                    <LoadingSpinner />\n                                </div>\n                            </div>\n                            <Heading level={1}>{exportTask.state.status}</Heading>\n                        </div>\n                    )}\n                    {exportTask.succeeded && (\n                        <div className={\"text-center\"}>\n                            <FontAwesomeIcon icon={faCheck} className={\"text-7xl text-highlight\"} />\n                            <Heading level={1}>Export done!</Heading>\n                            <Text level={1}>\n                                Pull your app container image from:{\" \"}\n                                <code className={\"select-all\"}>{exportTask.state.repository}</code>\n                            </Text>\n                            <Text level={1}>\n                                Test your app locally:\n                                <br />\n                                <pre className={\"text-left select-text\"}>\n                                    {`docker run -it --rm -p 30000:30000 \\\\\n            ${exportTask.state.repository} \\\\\n            --origin http://localhost:30000`}\n                                </pre>\n                            </Text>\n                        </div>\n                    )}\n                    {exportTask.failed && (\n                        <div className={\"text-center\"}>\n                            <FontAwesomeIcon\n                                icon={faExclamationTriangle}\n                                className={\"text-7xl text-highlight text-secondary\"}\n                            />\n                            <Heading level={1}>Export failed</Heading>\n                            <Text level={1}>\n                                <code className={\"select-all\"}>{exportTask.error}</code>\n                            </Text>\n                        </div>\n                    )}\n                </div>\n            ) : (\n                <div>\n                    <Heading level={1}>Container Registry</Heading>\n\n                    <TextInput\n                        initialValue={registryHost}\n                        onChange={setRegistryHost}\n                        title={\"Hostname\"}\n                        description={\"The container registry to push to\"}\n                        placeholder={\"E.g. hub.docker.com\"}\n                    />\n                    <TextInput initialValue={registryUser} onChange={setRegistryUser} title={\"Username\"} />\n                    <TextInput\n                        initialValue={registryPassword}\n                        onChange={setRegistryPassword}\n                        title={\"Password\"}\n                        inputType={\"password\"}\n                    />\n                    <TextInput\n                        initialValue={repoPath}\n                        onChange={setRepoPath}\n                        title={\"Repository Path\"}\n                        description={`This image will be available at ${registryHost?.toLowerCase()}${repoPath?.toLowerCase()}`}\n                    />\n\n                    <InputLabel title={\"Branch\"} subtitle={\"Choose a branch to export\"}>\n                        <BranchSelector branch={branch} onSelect={setBranch} />\n                    </InputLabel>\n\n                    <div className={\"text-center\"}>\n                        <Button icon={faDocker} variant={\"primary\"} onClick={doExport}>\n                            Export to Docker Image\n                        </Button>\n                    </div>\n                </div>\n            )}\n        </Modal>\n    );\n};\n\nexport default DockerExportModal;\n","import { default as React } from \"react\";\nimport { connect } from \"react-redux\";\nimport { getAppEditState, getAppId, getAppPackageName } from \"@/controllers/app\";\nimport { getUser } from \"@/controllers/ide\";\nimport { modal, modalReturn } from \"@/controllers/modals\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport { ModalComponent } from \".\";\nimport { HelpLink } from \"../reusable/HelpLink\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport Modal from \"./Modal\";\nimport useStyles from \"./modalstyles\";\n\nconst connector = connect((state: State) => ({\n    appId: getAppId(state),\n    packageName: getAppPackageName(state),\n    user: getUser(state),\n    editState: getAppEditState(state),\n}));\n\ntype GitProps = AnvilConnectedProps<typeof connector>;\n\nconst Git: ModalComponent<never, boolean, GitProps> = ({ modalId, appId, packageName, user, editState, dispatch }) => {\n    const { classes } = useStyles();\n\n    const anvilHostName = window.location.hostname;\n    const port = user!.ideConfig?.externalSshPort === 22 ? \"\" : `:${user!.ideConfig?.externalSshPort}`;\n    const url = `ssh://${user!.email.replace(\"@\", \"%40\")}@${anvilHostName}${port}/${appId!}.git${editState?.branch && editState.branch !== \"master\" ? ` --branch ${editState.branch}` : \"\"}`;\n\n    return (\n        <Modal\n            modalId={modalId}\n            title=\"Git access\"\n            size=\"medium\"\n            buttons={[{ text: \"Close\", clickActionCreator: () => modalReturn(true) }]}>\n            <div>\n                <p>The Git repository for this app can be accessed at:</p>\n                <pre className={classes.selectable}>{url}</pre>\n                <p>Use the following command to clone this app as a Git repository:</p>\n                <pre className={classes.selectable}>{`git clone ${url} ${packageName || appId}`}</pre>\n                Use your Anvil account email and password to authenticate to git, or{\" \"}\n                <LinkInternal\n                    className={classes.underline}\n                    onClick={() => dispatch(modal(\"account\", { section: \"AUTHENTICATION\", hash: \"SSH\" }))}>\n                    add your SSH public key to Anvil\n                </LinkInternal>\n            </div>\n\n            <HelpLink url={\"/docs/version-control/git\"}>More Info</HelpLink>\n        </Modal>\n    );\n};\n\nexport default connector(Git) as typeof Git;\n","import React, { useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { startHawthornDeployment } from \"@/api/hawthorn\";\nimport { NoodlePane } from \"@/components/bottom_panel/History\";\nimport { DateTimePicker } from \"@/components/reusable/datepicker\";\nimport TextInput from \"@/components/reusable/TextInput\";\nimport { getAppId } from \"@/controllers/app\";\nimport {\n    getAppCommitHistory,\n    getAppCommitId,\n    getAppMalleableCommits,\n    updateAppCommitHistory,\n} from \"@/controllers/app/history\";\nimport { getCategorisedEnvironments } from \"@/controllers/environments\";\nimport { getUser } from \"@/controllers/ide\";\nimport { alert } from \"@/controllers/modals\";\nimport type { AnvilDispatch } from \"@/types\";\nimport type { ModalComponent } from \".\";\nimport Modal from \"./Modal\";\n\nconst errorMessage = (error: unknown) =>\n    error && typeof error === \"object\" && \"message\" in error\n        ? String(error.message)\n        : \"The request failed. Please try again.\";\n\nconst HawthornDeployModal: ModalComponent = ({ modalId }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const appId = useSelector(getAppId)!;\n    const currentCommit = useSelector(getAppCommitId);\n    const history = useSelector(getAppCommitHistory);\n    const malleableCommits = useSelector(getAppMalleableCommits);\n    const { real, restricted } = useSelector(getCategorisedEnvironments);\n    const appUrls = useSelector(getUser)?.ideConfig.appUrls;\n    const [commitId, setCommitId] = useState(currentCommit || \"\");\n    const defaultProdUrl = `${appUrls?.[0] || \"\"}PROD-SUBDOMAIN${appUrls?.[1] || \"\"}`;\n    const defaultUatUrl = `${appUrls?.[0] || \"\"}UAT-SUBDOMAIN${appUrls?.[1] || \"\"}`;\n    const [prodUrl, setProdUrl] = useState(\n        () =>\n            real.find((env) => env.tags?.includes(\"hawthorn-prod\") && env.origin)?.origin ||\n            restricted.find((env) => env.origin)?.origin ||\n            defaultProdUrl,\n    );\n    const [uatUrl, setUatUrl] = useState(\n        () =>\n            real.find((env) => env.tags?.includes(\"hawthorn-uat\") && env.origin)?.origin ||\n            defaultUatUrl,\n    );\n    const [deploymentTime, setDeploymentTime] = useState(() => new Date());\n    const [submitting, setSubmitting] = useState(false);\n    const [queued, setQueued] = useState(false);\n\n    const deploy = async () => {\n        setSubmitting(true);\n        try {\n            await startHawthornDeployment(appId, {\n                commit_id: commitId,\n                prod_url: prodUrl.trim(),\n                uat_url: uatUrl.trim(),\n                deployment_time: deploymentTime.toISOString(),\n            });\n            setQueued(true);\n        } catch (e) {\n            await dispatch(alert(\"Hawthorn deployment failed\", errorMessage(e)));\n        } finally {\n            setSubmitting(false);\n        }\n    };\n\n    return (\n        <Modal\n            modalId={modalId}\n            title=\"Hawthorn deployment\"\n            size=\"medium\"\n            allowDismiss={!submitting}\n            buttons={\n                queued\n                    ? [{ text: \"Close\", close: true }]\n                    : [\n                          { text: \"Cancel\", close: true, enabled: !submitting },\n                          {\n                              text: submitting ? \"Deploying…\" : \"Deploy\",\n                              variant: \"primary\",\n                              enabled:\n                                  !submitting &&\n                                  !!commitId &&\n                                  !!prodUrl.trim() &&\n                                  !!uatUrl.trim() &&\n                                  prodUrl !== defaultProdUrl &&\n                                  uatUrl !== defaultUatUrl &&\n                                  prodUrl.trim().replace(/\\/+$/, \"\") !== uatUrl.trim().replace(/\\/+$/, \"\") &&\n                                  !Number.isNaN(deploymentTime.getTime()),\n                              clickActionCreator: deploy,\n                          },\n                      ]\n            }\n        >\n            {queued ? (\n                <p role=\"status\">Hawthorn deployment queued.</p>\n            ) : (\n                <div className=\"flex flex-col gap-6\">\n                    <div>\n                        <div className=\"mb-2 font-medium\">Commit</div>\n                        <NoodlePane\n                            className=\"max-h-[40vh]\"\n                            commits={history?.versions}\n                            initialSelectedCommit={history?.versions.find((commit) => commit.v === commitId)}\n                            malleableCommitIds={Object.values(malleableCommits || {}).flatMap((commit) =>\n                                commit ? [commit.oid] : [],\n                            )}\n                            onSelectCommit={submitting ? undefined : (commit) => setCommitId(commit.v)}\n                            onLoadMore={async () => {\n                                await dispatch(updateAppCommitHistory((history?.versions.length || 0) + 50));\n                            }}\n                        />\n                    </div>\n                    <TextInput title=\"UAT URL\" value={uatUrl} onChange={setUatUrl} disabled={submitting} />\n                    <TextInput title=\"Prod URL\" value={prodUrl} onChange={setProdUrl} disabled={submitting} />\n                    <fieldset disabled={submitting} inert={submitting}>\n                        <legend className=\"mb-2 font-medium\">Deployment time</legend>\n                        <DateTimePicker\n                            value={deploymentTime}\n                            onChange={setDeploymentTime}\n                            format=\"do MMMM y 'at' HH:mm\"\n                        />\n                        <p className=\"mt-2 text-sm\">\n                            In your local time zone ({Intl.DateTimeFormat().resolvedOptions().timeZone}).\n                        </p>\n                    </fieldset>\n                </div>\n            )}\n        </Modal>\n    );\n};\n\nexport default HawthornDeployModal;\n","import { postJson } from \"@/util/fetch\";\n\nexport const startHawthornDeployment = (\n    appId: string,\n    parameters: {\n        commit_id: string;\n        prod_url: string;\n        uat_url: string;\n        deployment_time: string;\n    },\n) => postJson<{ queued: boolean; queue_id: string | null }>(`/ide/apps/${appId}/hawthorn/deploy`, parameters);\n","import React, { useMemo } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { LayoutMetadata } from \"@runtime/runner/data\";\nimport Modal from \"@/components/modals/Modal\";\nimport {\n    LayoutMetaContext,\n    LayoutMetaContextValue,\n    LayoutMetadataConfig,\n} from \"@/components/modals/customcomponent/LayoutMetadataConfig\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { CheckBox } from \"@/components/reusable/Forms\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport { updateEnableHtmlLayout, updateHtmlLayoutMetadata } from \"@/controllers/app/code\";\nimport { getLayoutsFromYaml } from \"@/controllers/designer\";\nimport { AnvilDispatch, StructureItem } from \"@/types\";\nimport { EMPTY_OBJECT } from \"@/util\";\nimport { useMemoiseObject } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport type { ModalComponent } from \".\";\n\nconst HtmlLayoutModal: ModalComponent<{ asset: StructureItem }> = ({ spec: { asset }, modalId }) => {\n    const dispatch: AnvilDispatch = useDispatch();\n    const customLayouts = useSelector(getLayoutsFromYaml);\n\n    const customLayout = useMemo(\n        () => customLayouts.find(({ layout: { properties } }) => properties?.html === `@theme:${asset.fullName}`),\n        [customLayouts, asset.fullName]\n    );\n\n    const onToggleLayout = useEvent(() => {\n        dispatch(updateEnableHtmlLayout(asset, !customLayout));\n    });\n\n    const updateCustomComponent = useEvent((update: any, msg?: string) => {\n        dispatch(updateHtmlLayoutMetadata(asset, update.layout_metadata));\n    });\n\n    const layoutContextValue: LayoutMetaContextValue = useMemoiseObject({\n        formName: asset.name,\n        layoutMetadata: customLayout?.metadata ?? (EMPTY_OBJECT as LayoutMetadata),\n        updateCustomComponent,\n    });\n\n    return (\n        <Modal modalId={modalId} title=\"Configure HTML Layout\">\n            <CheckBox checked={!!customLayout} onChange={onToggleLayout}>\n                <div className={\"flex gap-4\"}>\n                    <span>Make this HTML available as a layout</span>\n                    <HelpLink inline url={\"/docs/ui/layouts\"} />\n                </div>\n            </CheckBox>\n\n            <Expander isOpen={!!customLayout}>\n                <LayoutMetaContext.Provider value={layoutContextValue}>\n                    <LayoutMetadataConfig />\n                </LayoutMetaContext.Provider>\n            </Expander>\n        </Modal>\n    );\n};\n\nexport default HtmlLayoutModal;\n","import React from \"react\";\nimport Modal from \"@/components/modals/Modal\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { Heading } from \"@/components/reusable/Text\";\nimport { ModalComponent } from \".\";\n\nconst openInNewTab = (url: string) => {\n    const newWindow = window.open(url, \"_blank\", \"noopener\");\n    if (newWindow) {\n        newWindow.opener = null;\n    }\n};\n\n// This will (hopefully) eventually cover multiple achievements, but for now it's only for completing the IDE tutorial\n\nconst IdeTutorialIntro: ModalComponent = ({ modalId }) => {\n    return (\n        <Modal\n            title={\"Welcome to the Anvil Editor!\"}\n            modalId={modalId}\n            // allowDismiss={false}\n            buttons={[{ text: \"Get Started\", variant: \"primary\", close: true }]}>\n            <div className={\"flex\"}>\n                <div className={\"flex-none\"}>\n                    <img src={\"/ide/img/shield.png\"} className={\"w-[100px] mr-8 mt-2\"}/>\n                </div>\n                <div className={\"flex-1\"}>\n                    <Heading level={1}>Challenge: Unlock the rest of Anvil</Heading>\n                    <p>To help you get familiar with the editor, some advanced features are hidden until you complete a few quick steps.</p>\n\n                    <ol className={\"list-inside list-decimal marker:font-bold mt-4 mb-4 pl-4\"}>\n                        <li>Drag a button onto the canvas</li>\n                        <li>Write code to change the button's text when it is clicked</li>\n                        <li>Run your app</li>\n                    </ol>\n                    <p>This should take about a minute. Check the <strong>Get Started</strong> panel below for step-by-step guidance.</p>\n                </div>\n            </div>\n        </Modal>\n    );\n};\n\nexport default IdeTutorialIntro;\n","import React, { useEffect, useReducer, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faBook, faComments, faVideo } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faArrowRight, faPlay } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { getAppId } from \"@/controllers/app\";\nimport { updateUserEditorPrefs } from \"@/controllers/user\";\nimport { recordActivity } from \"@/controllers/util\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useTimeout } from \"@/util/hooks/use-timeout\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \".\";\nimport { Button } from \"../reusable/Button\";\nimport Link from \"../reusable/Link\";\nimport Modal, { ModalRef } from \"./Modal\";\n\nconst INIT_VIDEO_STATE = {\n    ended: false,\n    paused: false,\n    seeking: false,\n};\n\ntype VideoState = typeof INIT_VIDEO_STATE;\n\nconst videoStateReducer = (state: VideoState, event: { type: string }): VideoState => {\n    switch (event.type) {\n        case \"playing\":\n            return { ...state, paused: false, seeking: false };\n        case \"pause\":\n            return { ...state, paused: true };\n        case \"seeking\":\n            return { ...state, seeking: true };\n        case \"seeked\":\n            return { ...state, seeking: false };\n        case \"ended\":\n            return { ...state, ended: true };\n        default:\n            return state;\n    }\n};\n\nconst IntroVideoModal: ModalComponent = ({ modalId }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const modalRef = useRef<ModalRef>(null!);\n    const videoRef = useRef<HTMLVideoElement>(null);\n    const [videoState, dispatchVideoEvent] = useReducer(videoStateReducer, INIT_VIDEO_STATE);\n\n    const appId = useSelector(getAppId);\n\n    const onComplete = useEvent(() => {\n        dispatch(updateUserEditorPrefs(\"userWasShownIntroVideo\", true));\n        modalRef.current.returnValue();\n    });\n\n    // In case the video doesn't load\n    const cancelTimeout = useTimeout(() => {\n        dispatch(recordActivity(\"introVideoLoadTimedOut\"));\n        onComplete();\n    }, 5000);\n\n    // if they leave an app we close the modal\n    useEffect(() => {\n        if (!appId) {\n            modalRef.current.cancel(\"we left the app\");\n        }\n    }, [appId]);\n\n    const onDataLoaded = useEvent(() => {\n        cancelTimeout();\n        // In case autoplay fails\n        if (videoRef.current?.paused) {\n            dispatchVideoEvent({ type: \"pause\" });\n        }\n    });\n\n    const onPlayVideo = useEvent(async () => {\n        cancelTimeout();\n        videoRef.current?.focus();\n\n        try {\n            await videoRef.current?.play();\n        } catch (e) {\n            console.error(e);\n        }\n    });\n\n    return (\n        <Modal modalId={modalId} icon={faVideo} allowDismiss={false} size=\"large\" title={\"Anvil tour\"} ref={modalRef}>\n            <div className=\"flex flex-col items-center gap-8 px-10 py-5\">\n                {!videoState.ended && (\n                    <div className=\"relative\">\n                        {videoState.paused && !videoState.seeking && (\n                            <div\n                                onClick={onPlayVideo}\n                                className=\"absolute inset-0 z-10 flex cursor-pointer items-center justify-center bg-black/75 transition-colors hover:bg-black/80\">\n                                <Button large variant={\"primary\"} icon={faPlay} onClick={onPlayVideo}>\n                                    Play the video to continue\n                                </Button>\n                            </div>\n                        )}\n                        <video\n                            ref={videoRef}\n                            preload=\"metadata\"\n                            autoPlay\n                            disablePictureInPicture\n                            disableRemotePlayback\n                            controls\n                            onPlaying={dispatchVideoEvent}\n                            onPause={dispatchVideoEvent}\n                            onSeeking={dispatchVideoEvent}\n                            onEnded={dispatchVideoEvent}\n                            onError={(e) => {\n                                console.error(\"Video failed to load:\", e);\n                                dispatch(recordActivity(\"introVideoLoadError\"));\n                                onComplete();\n                            }}\n                            onLoadedData={onDataLoaded}\n                            onSeeked={(e) => dispatch(recordActivity(\"introVideoSkipped\"))}\n                            className=\"min-h-96 w-full rounded-md border-2 border-solid border-sectionborder dark:border-dark-sectionborder\">\n                            <source\n                                src=\"https://anvil-website-static.s3.eu-west-2.amazonaws.com/Anvil-Editor-Tour.mp4\"\n                                type=\"video/mp4\"\n                            />\n                        </video>\n                    </div>\n                )}\n                <div className={cx(\"flex flex-col gap-8\", { \"py-84\": videoState.ended })}>\n                    {videoState.ended && (\n                        <Button large variant={\"primary\"} iconRight icon={faArrowRight} onClick={onComplete}>\n                            Start Building\n                        </Button>\n                    )}\n                    <div className={\"flex gap-6 text-xl font-semibold\"}>\n                        <Link\n                            to=\"/docs?utm_source=ide:video-intro\"\n                            className=\"flex items-center gap-4 rounded-md bg-light-bg4 px-6 py-2 text-light-bg7 no-underline! hover:bg-light-bg5 active:bg-light-bg6 dark:bg-dark-bg3 dark:text-dark-fg1! dark:hover:bg-dark-bg8\">\n                            <FontAwesomeIcon className=\"h-5\" icon={faBook} />\n                            Read the docs\n                        </Link>\n                        <Link\n                            to=\"https://anvil.works/forum\"\n                            className=\"flex items-center gap-4 rounded-md bg-light-bg4 px-6 py-2 text-light-bg7 no-underline! hover:bg-light-bg5 active:bg-light-bg6 dark:bg-dark-bg3 dark:text-dark-fg1! dark:hover:bg-dark-bg8\">\n                            <FontAwesomeIcon className=\"h-5\" icon={faComments} />\n                            Join the Forum\n                        </Link>\n                    </div>\n                </div>\n            </div>\n        </Modal>\n    );\n};\n\nexport default IntroVideoModal;\n","import * as React from \"react\";\nimport { useRef } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faExternalLinkAlt } from \"@fortawesome/free-solid-svg-icons/faExternalLinkAlt\";\nimport { faRedo } from \"@fortawesome/free-solid-svg-icons/faRedo\";\nimport { faCodeMerge } from \"@fortawesome/pro-solid-svg-icons/faCodeMerge\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport type { ModalComponent } from \".\";\nimport Modal, { ModalRef } from \"./Modal\";\n\ninterface MergeCompletionConflictSpec {\n    branch: string;\n    canRestart?: boolean;\n}\n\nconst MergeCompletionConflict: ModalComponent<MergeCompletionConflictSpec, \"RETRY\" | \"RESTART\" | null> = ({\n    modalId,\n    spec: { branch, canRestart },\n}) => {\n    const modalRef = useRef<ModalRef>(null);\n\n    const buttons = [\n        {\n            text: \"Continue\",\n            icon: faCodeMerge,\n            variant: \"primary\" as const,\n            clickActionCreator: () => modalReturn(\"RETRY\"),\n        },\n        {\n            text: \"Restart from scratch\",\n            icon: faRedo,\n            variant: \"secondary\" as const,\n            clickActionCreator: () => modalReturn(\"RESTART\"),\n        },\n        { text: \"Cancel\", clickActionCreator: () => modalReturn(null) },\n    ];\n\n    return (\n        <Modal\n            modalId={modalId}\n            allowDismiss={false}\n            title={`The ${branch} branch has moved`}\n            buttons={buttons}\n            ref={modalRef}>\n            <p>\n                The <b>{branch}</b> branch has moved while you were resolving conflicts, so we can't merge into it right\n                away.\n            </p>\n\n            <p>You can:</p>\n\n            <ul style={{ marginLeft: 20, marginRight: 20 }}>\n                <li>\n                    <p>\n                        <b>Continue</b>, and merge your merge into <b>{branch}</b>. If you're not sure, choose this\n                        option.\n                    </p>\n                </li>\n                {canRestart && (\n                    <li>\n                        <p>\n                            <b>Restart from scratch</b>, and merge the source commit with the new position of{\" \"}\n                            <b>{branch}</b>. You will have to resolve conflicts again from scratch.\n                        </p>\n                    </li>\n                )}\n                <li>\n                    <p>\n                        <b>Cancel</b> and don't do anything yet.\n                    </p>\n                </li>\n            </ul>\n\n            <p>\n                Learn more about this situation in the{\" \"}\n                <a\n                    href={\"/docs/version-control/conflicts#when-the-target-branch-moves\"}\n                    rel=\"noreferrer\"\n                    target={\"_blank\"}>\n                    Anvil manual\n                </a>{\" \"}\n                <FontAwesomeIcon icon={faExternalLinkAlt} />.\n            </p>\n\n            {/*<ModalButton onClick={() => modalRef.current.returnValue(\"RETRY\")} variant={'primary'} icon={faRedo}>Continue the merge into {branch}</ModalButton>*/}\n            {/*{canRestart && <ModalButton onClick={() => modalRef.current.returnValue(\"RESTART\")} variant={'primary'} icon={faRedo}>Restart the merge from scratch</ModalButton>}*/}\n            {/*<ModalButton onClick={() => modalRef.current.returnValue(null)}>Cancel</ModalButton>*/}\n        </Modal>\n    );\n};\n\nexport default MergeCompletionConflict;\n","import React, { useRef } from \"react\";\nimport { connect, useDispatch, useSelector } from \"react-redux\";\nimport { faClock } from \"@fortawesome/free-solid-svg-icons/faClock\";\nimport { faTrash } from \"@fortawesome/pro-regular-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Button } from \"@/components/reusable/Button.tsx\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport UpgradeBadge from \"@/components/reusable/UpgradeBadge\";\nimport { useDeleteService } from \"@/components/sidebar/Sidebar\";\nimport { getApp } from \"@/controllers/app\";\nimport { getFeatures } from \"@/controllers/ide\";\nimport { modal, modalReturn } from \"@/controllers/modals\";\nimport { getAllAvailableServices } from \"@/controllers/services\";\nimport { ServiceNavTarget } from \"@/router/navTypes.ts\";\nimport { navigate } from \"@/router/navigation.ts\";\nimport { cx } from \"@/theme/styles.ts\";\nimport type { AnvilConnectedProps, AnvilDispatch, State } from \"@/types\";\nimport { featureSupported } from \"@/util/features\";\nimport { getServiceIcon, getServiceType } from \"@/util/index\";\nimport useEvent from \"@/util/useEventCallback.ts\";\nimport type { ModalComponent } from \".\";\nimport type { ModalRef } from \"./Modal\";\nimport Modal from \"./Modal\";\nimport useStyles from \"./modalstyles\";\n\ntype AvailableService = NonNullable<ReturnType<typeof getAllAvailableServices>>[number];\ninterface ScheduledTasksService {\n    name: string;\n    content_item: \"scheduled_tasks\";\n    requireFeatureOnSubscription: \"scheduled-tasks\";\n}\n\ntype ServiceChoice = AvailableService | ScheduledTasksService;\n\nconst connector = connect((state: State) => ({\n    app: getApp(state)!,\n    availableServices: getAllAvailableServices(state),\n}));\n\nconst useChooseService = (modalRef: React.RefObject<ModalRef | null>, service: ServiceChoice, inApp: boolean) => {\n    const features = useSelector(getFeatures);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    return useEvent(() => {\n        if (inApp && \"source\" in service && service.source) {\n            // added services navigate from here. scheduled task navigate in the else.\n            const { source } = service;\n            const serviceType = getServiceType(source as Parameters<typeof getServiceType>[0]);\n            const navTarget = { type: \"SERVICE\", service: serviceType };\n\n            dispatch(navigate(navTarget as ServiceNavTarget));\n            modalRef.current!.returnValue();\n        } else {\n            if (\n                !service.requireFeatureOnSubscription ||\n                featureSupported(features, service.requireFeatureOnSubscription)\n            ) {\n                modalRef.current!.returnValue(service);\n            } else {\n                dispatch(modal(\"upgradePrompt\", { featureId: service.requireFeatureOnSubscription }));\n            }\n        }\n    });\n};\n\nconst ServiceCard = ({\n    service,\n    inApp,\n    modalRef,\n}: {\n    service: AvailableService;\n    inApp: boolean;\n    modalRef: React.RefObject<ModalRef | null>;\n}) => {\n    const { classes } = useStyles();\n    const chooseService = useChooseService(modalRef, service, inApp);\n\n    const onDeleteService = useDeleteService(service.source, service.name);\n\n    return (\n        <li className={classes.listItem}>\n            <LinkInternal className={cx(classes.serviceLink)} onClick={chooseService}>\n                <div className={cx(\"relative flex w-full items-center\")}>\n                    <div className={cx(classes.sidebarNavIcon)}>\n                        <FontAwesomeIcon\n                            className={cx(classes.icon)}\n                            icon={getServiceIcon(service as unknown as Parameters<typeof getServiceIcon>[0])}\n                        />\n                        {service.name}\n                    </div>\n                    <div className={\"w-full flex-col\"}>\n                        <h4 className={\"text-3xl font-medium\"}>\n                            {service.headline ? service.headline : service.name}{\" \"}\n                            {service.requireFeatureOnSubscription && (\n                                <UpgradeBadge feature={service.requireFeatureOnSubscription} />\n                            )}\n                            {inApp && <span className={\"beta-label\"}>Added</span>}\n                        </h4>\n                        <p className={classes.description}>{service.description}</p>\n                    </div>\n                    <div className={cx(\"mr-8 hidden\", { block: inApp })}>\n                        <Button\n                            small={true}\n                            className={\"relative items-center justify-center\"}\n                            variant={\"danger\"}\n                            onClick={onDeleteService}>\n                            <FontAwesomeIcon icon={faTrash} />\n                        </Button>\n                    </div>\n                </div>\n            </LinkInternal>\n        </li>\n    );\n};\n\ntype NewServiceModalProps = AnvilConnectedProps<typeof connector>;\n\nconst NewServiceModal: ModalComponent<never, ServiceChoice | null, NewServiceModalProps> = ({\n    modalId,\n    app,\n    availableServices,\n    dispatch,\n}) => {\n    const { classes } = useStyles();\n\n    const modalRef = useRef<ModalRef>(null);\n    const scheduledTasks = app.config.scheduled_tasks;\n    const appServices = app.config.services ?? [];\n\n    const services = [];\n    for (const feature of availableServices ?? []) {\n        let inApp = false;\n\n        for (const appService of appServices) {\n            if (appService.source === feature.source) {\n                inApp = true;\n                break;\n            }\n        }\n        services.push({ feature, inApp });\n    }\n\n    const chooseService = useChooseService(\n        modalRef,\n        {\n            name: \"scheduled tasks\",\n            content_item: \"scheduled_tasks\",\n            requireFeatureOnSubscription: \"scheduled-tasks\",\n        },\n        !!scheduledTasks\n    );\n    const onDeleteScheduledService = useDeleteService(\"scheduled-tasks\", \"Scheduled Tasks\");\n    return (\n        <Modal\n            ref={modalRef}\n            modalId={modalId}\n            title=\"Add a Feature\"\n            buttons={[{ text: \"Close\", clickActionCreator: () => modalReturn(null) }]}>\n            <div>\n                <p>The following features are available. Click to add.</p>\n                <ul>\n                    <li className={classes.listItem} key=\"scheduled\">\n                        <LinkInternal key=\"scheduled\" className={cx(classes.serviceLink)} onClick={chooseService}>\n                            <div className={cx(\"relative flex w-full items-center\")}>\n                                <div className={cx(classes.sidebarNavIcon)}>\n                                    <FontAwesomeIcon className={classes.icon} icon={faClock} />\n                                    Scheduled Tasks\n                                </div>\n                                <div className={\"w-full flex-col\"}>\n                                    <h4 className={\"text-3xl font-medium\"}>\n                                        Scheduled Tasks\n                                        <UpgradeBadge feature={\"scheduled-tasks\"} />\n                                        {scheduledTasks && <span className={\"beta-label\"}>Added</span>}\n                                    </h4>\n                                    <p className={classes.description}>\n                                        Run any Background Task on a schedule you configure.\n                                    </p>\n                                </div>\n                                <div className={cx(\"mr-8 hidden\", { block: !!scheduledTasks })}>\n                                    <Button\n                                        small={true}\n                                        className={\"relative items-center justify-center\"}\n                                        variant={\"danger\"}\n                                        onClick={onDeleteScheduledService}>\n                                        <FontAwesomeIcon icon={faTrash} />\n                                    </Button>\n                                </div>\n                            </div>\n                        </LinkInternal>\n                    </li>\n                    {services\n                        .filter(({ feature }) => feature.source !== \"/runtime/services/tables.yml\")\n                        .map(({ feature, inApp }) => (\n                            <ServiceCard service={feature} inApp={inApp} modalRef={modalRef} key={feature.source} />\n                        ))}\n                </ul>\n            </div>\n        </Modal>\n    );\n};\n\nexport default connector(NewServiceModal) as typeof NewServiceModal;\n","import React, { useCallback, useMemo, useRef } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { getAppMalleableCommits } from \"@/controllers/app/history\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport type { CommitVersion } from \"@/types\";\nimport { usePartialReducer } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \".\";\nimport { CommitDetails } from \"../reusable/CommitDetail\";\nimport { ContentTextAreaInput, ContentTextInput } from \"../reusable/SharedComponents\";\nimport Modal, { ModalRef } from \"./Modal\";\n\ninterface PreCommitModalSpec {\n    title: React.ReactNode;\n    text?: React.ReactNode;\n    initialValue?: string | null;\n    commit: CommitVersion;\n}\n\ntype CommitMessageState = {\n    summary: string;\n    description: string;\n};\n\nconst parseCommitMessage = (message: string | null = \"\"): CommitMessageState => {\n    const safeMessage = message || \"\";\n    const [rawSummary, ...bodyLines] = safeMessage.split(/\\r?\\n/);\n    const summary = rawSummary?.trim() || safeMessage.trim() || \"\";\n    const description = bodyLines.join(\"\\n\").replace(/^\\n+/, \"\").replace(/\\s+$/, \"\");\n\n    return { summary, description };\n};\n\nexport const PreCommitModal: ModalComponent<PreCommitModalSpec> = ({\n    modalId,\n    spec: { title, text, initialValue, commit },\n}) => {\n    const malleableCommits = useSelector(getAppMalleableCommits);\n\n    const [commitMessage, updateCommitMessage] = usePartialReducer<CommitMessageState, string | null>(\n        initialValue ?? \"\",\n        parseCommitMessage\n    );\n\n    const { summary, description } = commitMessage;\n\n    const inputRef = useCallback((node: HTMLInputElement | null) => {\n        node?.focus();\n        node?.select();\n    }, []);\n\n    const buildCommitMessage = useEvent(() => {\n        const summaryText = summary.trim();\n        const descriptionText = description.trim();\n\n        if (!summaryText && !descriptionText) {\n            return \"\";\n        }\n\n        if (!summaryText) {\n            return descriptionText;\n        }\n\n        return descriptionText ? `${summaryText}\\n\\n${descriptionText}` : summaryText;\n    });\n\n    const malleableCommitIds = useMemo(() => {\n        const ids: string[] = [];\n        if (!malleableCommits) {\n            return ids;\n        }\n\n        for (const entry of Object.values(malleableCommits)) {\n            if (entry?.oid) {\n                ids.push(entry.oid);\n            }\n        }\n        return ids;\n    }, [malleableCommits]);\n\n    const isMalleable = malleableCommitIds.includes(commit.v);\n    const modal = useRef<ModalRef | null>(null);\n\n    const handleSubmit = useEvent(() => {\n        const message = buildCommitMessage();\n        void modal.current?.returnValue(message);\n    });\n\n    return (\n        <Modal\n            autoFocus={false}\n            size=\"huge\"\n            ref={modal}\n            modalId={modalId}\n            allowDismiss={true}\n            title={title}\n            buttons={[\n                { text: \"Commit\", clickActionCreator: () => modalReturn(buildCommitMessage()), defaultButton: true },\n                { text: \"Cancel\", clickActionCreator: () => modalReturn(null) },\n            ]}>\n            {text}\n            <ContentTextInput\n                ref={inputRef}\n                className=\"w-full px-2 py-3\"\n                onEnter={handleSubmit}\n                value={summary}\n                onChange={(event: React.ChangeEvent<HTMLInputElement>) =>\n                    updateCommitMessage({ summary: event.target.value })\n                }\n                disableEsc={true}\n            />\n            <div className=\"mt-4\">\n                <ContentTextAreaInput\n                    text=\"Detailed description (optional)\"\n                    value={description}\n                    onChange={(event: React.ChangeEvent<HTMLTextAreaElement>) =>\n                        updateCommitMessage({ description: event.target.value })\n                    }\n                    placeholder=\"Add notes about this commit\"\n                    disableEsc={true}\n                    className=\"w-full\"\n                />\n            </div>\n            <hr />\n            Changes {isMalleable ? \"to\" : \"in this\"} commit:\n            <br />\n            <CommitDetails\n                className=\"max-h-[50vh] overflow-y-auto\"\n                commitIdA={commit.p?.[0] ?? undefined}\n                commitIdB={commit.v}\n                showDetails={false}\n            />\n        </Modal>\n    );\n};\n\nexport default PreCommitModal;\n","import * as React from \"react\";\nimport { useCallback, useLayoutEffect, useRef, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { ModalComponent } from \"@/components/modals\";\nimport CommitDetail from \"@/components/reusable/CommitDetail\";\nimport Loading from \"@/components/reusable/Loading\";\nimport { ContentTextAreaInput } from \"@/components/reusable/SharedComponents\";\nimport { getAppId } from \"@/controllers/app\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport * as api from \"@/api\";\nimport { useEffectAsync, useStateWithReset } from \"@/util/hooks\";\nimport Modal from \"./Modal\";\n\ninterface PreMergeModalSpec {\n    commitId: string;\n    targetBranch: string;\n}\n\ntype ApiDiffData = Awaited<ReturnType<typeof api.getDiff>>;\n\nconst PreMergeModal: ModalComponent<PreMergeModalSpec, string | null> = ({\n    modalId,\n    spec: { commitId, targetBranch },\n}) => {\n    const appId = useSelector(getAppId);\n    const [diffData, setDiffData] = useState<ApiDiffData | undefined>();\n\n    useEffectAsync(\n        async function* () {\n            const diffData = await api.getDiff(appId, targetBranch, commitId, true);\n            yield;\n            setDiffData(diffData);\n        },\n        [commitId, targetBranch]\n    );\n\n    let defaultCommitMessage = `Merge ${commitId} into ${targetBranch}`;\n\n    const n_commits = diffData?.stats?.n_commits;\n    const [fromTime, toTime] = diffData?.stats?.timespan ?? [];\n    const authors = diffData?.stats?.authors;\n\n    const authorEmails = authors?.map?.((a) => a.email) || [];\n    const authorEmailDesc =\n        authorEmails.length <= 1\n            ? authorEmails[0]\n            : `${authorEmails.slice(0, -1).join(\", \")} and ${authorEmails[authorEmails.length - 1]}`;\n\n    if (n_commits) {\n        defaultCommitMessage = `Merge ${n_commits} commit${n_commits !== 1 ? \"s\" : \"\"} from ${authorEmailDesc}`;\n    }\n\n    const [commitMessage, setCommitMessage] = useStateWithReset<string>(defaultCommitMessage);\n    const onCommitMessageChange: React.ChangeEventHandler<HTMLTextAreaElement> = (e) => {\n        setCommitMessage(e.target.value);\n    };\n\n    const textboxRef = useCallback((node: HTMLTextAreaElement | null) => {\n        node?.focus();\n        node?.select();\n    }, []);\n\n    if (!diffData) {\n        return <Loading indicator />;\n    }\n\n    return (\n        <Modal\n            autoFocus={false}\n            size=\"huge\"\n            modalId={modalId}\n            allowDismiss={true}\n            title={`Merge into ${targetBranch}`}\n            buttons={\n                n_commits\n                    ? [\n                          { text: \"Merge\", clickActionCreator: () => modalReturn(commitMessage), defaultButton: true },\n                          { text: \"Cancel\", clickActionCreator: () => modalReturn(null) },\n                      ]\n                    : [{ text: \"Cancel\", clickActionCreator: () => modalReturn(null) }]\n            }>\n            {!diffData ? (\n                <Loading indicator={true} />\n            ) : !diffData.changed_items.length ? (\n                <>\n                    The <b>{targetBranch}</b> branch is already up to date, so there's nothing to merge!\n                </>\n            ) : (\n                <>\n                    <p>\n                        You're about to merge {n_commits} commit{(n_commits ?? 0) > 1 && \"s\"} from {authorEmailDesc}.\n                    </p>\n\n                    <p>Write a message to describe the changes you're merging:</p>\n                    <ContentTextAreaInput\n                        className=\"w-full px-2 py-3\"\n                        value={commitMessage}\n                        ref={textboxRef}\n                        rows={4}\n                        onChange={onCommitMessageChange}\n                        onKeyDown={(e: React.KeyboardEvent<HTMLTextAreaElement>) => e.stopPropagation()}\n                    />\n\n                    <p>Changes to merge:</p>\n\n                    <CommitDetail\n                        className=\"max-h-[50vh] overflow-y-auto\"\n                        diffData={diffData as React.ComponentProps<typeof CommitDetail>[\"diffData\"]}\n                    />\n                </>\n            )}\n        </Modal>\n    );\n};\n\nexport default PreMergeModal;\n","import React, { useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faChevronRight } from \"@fortawesome/pro-light-svg-icons/faChevronRight\";\nimport { faCandleHolder } from \"@fortawesome/pro-solid-svg-icons/faCandleHolder\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport Modal, { ModalRef } from \"@/components/modals/Modal\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { getShowNewDesigner } from \"@/controllers/designer\";\nimport { setUserAlwaysShowNewDesigner } from \"@/controllers/user\";\nimport { AnvilDispatch } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \".\";\n\nconst PreviewV3Designer: ModalComponent = ({ modalId }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const showNewDesignerPref = useSelector(getShowNewDesigner);\n    const modalRef = useRef<ModalRef>(null!);\n    // avoids a flash of the different modal styles when pref changes\n    const [showNewDesigner] = useState(showNewDesignerPref);\n\n    const onToggleNewDesigner = useEvent(() => {\n        dispatch(setUserAlwaysShowNewDesigner(!showNewDesigner));\n        modalRef.current.returnValue();\n    });\n\n    return (\n        <Modal\n            title={\n                showNewDesigner ? (\n                    <>\n                        <FontAwesomeIcon icon={faCandleHolder} /> Classic Designer\n                    </>\n                ) : (\n                    \"Classic Designer\"\n                )\n            }\n            modalId={modalId}\n            ref={modalRef}\n            buttons={[{ text: \"Close\", close: true }]}>\n            {showNewDesigner ? (\n                <>\n                    <Text>\n                        <b style={{ color: \"#d00\" }}>\n                            The Classic Designer will be{\" \"}\n                            <a\n                                href={\"https://anvil.works/forum/t/saying-goodbye-to-the-classic-editor/22854\"}\n                                target={\"_new\"}>\n                                discontinued\n                            </a>{\" \"}\n                            after the 13th of March.\n                        </b>\n                        Until then, you can switch to the Classic Designer.\n                    </Text>\n\n                    <Text className={\"pt-4\"}>\n                        If you have a use case that is not yet supported by the New Designer, please post on the\n                        <a href={\"https://anvil.works/forum\"}>Anvil Forum</a> and let us know!\n                    </Text>\n                </>\n            ) : (\n                <Text>\n                    You're using Anvil's classic drag-and-drop designer, which will be{\" \"}\n                    <b>\n                        <a\n                            href={\"https://anvil.works/forum/t/saying-goodbye-to-the-classic-editor/22854\"}\n                            target={\"_new\"}>\n                            discontinued after the 13th of March\n                        </a>\n                    </b>\n                    . Upgrade to the new designer for easier placement of components, inline editing, and more.\n                </Text>\n            )}\n            <div className={\"mt-4\"}>\n                <Button\n                    icon={faChevronRight}\n                    iconRight\n                    variant={!showNewDesigner ? \"secondary\" : \"primary\"}\n                    onClick={onToggleNewDesigner}>\n                    {!showNewDesigner ? \"Use the new designer\" : \"Switch to classic designer\"}\n                </Button>\n            </div>\n        </Modal>\n    );\n};\n\nexport default PreviewV3Designer;\n","import React, { useRef, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { faArrowRightArrowLeft } from \"@fortawesome/pro-regular-svg-icons/faArrowRightArrowLeft\";\nimport * as api from \"@/api\";\nimport { ModalComponent } from \"@/components/modals/index\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { ButtonGroup } from \"@/components/reusable/ButtonGroup\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { SecondaryNavAlert } from \"@/components/sidebar/SecondaryNavSection\";\nimport { getAppConfig, getAppId } from \"@/controllers/app\";\nimport { getDependencyCode } from \"@/controllers/app/code\";\nimport {\n    dependencyAndIdentifier,\n    getDependencyDisplayName,\n    getDependencyHints,\n} from \"@/controllers/dependencies\";\nimport { DependencyConfig } from \"@/types\";\nimport { useEffectAsync } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { MyApps, ThirdParty } from \"../tabs/settings/DependenciesConfig\";\nimport Modal, { ModalRef } from \"./Modal\";\n\ninterface RemapDependencySpec {\n    refDep: DependencyConfig;\n    setOfDepAppIds: Set<string>;\n    alreadyBroken: boolean;\n}\n\nconst RemapDependency: ModalComponent<RemapDependencySpec> = ({ modalId, spec }) => {\n    const { refDep, setOfDepAppIds, alreadyBroken } = spec;\n    const appId = useSelector(getAppId) as string;\n    const appConfig = useSelector(getAppConfig);\n    const dependencyCode = useSelector(getDependencyCode);\n    const { dep, activeDepAppId } = dependencyAndIdentifier(refDep, appConfig!);\n    const dependency = dep ?? refDep;\n    const logicalDepId = refDep.dep_id ?? refDep.app_id;\n    // Older runtimes key missing-app errors by the YAML reference; remove the fallback when those runtimes retire.\n    const activeDepCode = dependencyCode[activeDepAppId] ?? (logicalDepId ? dependencyCode[logicalDepId] : undefined);\n    const dependencyName = getDependencyDisplayName(dependency, activeDepCode);\n    const resolutionHints = getDependencyHints(dependency, activeDepCode);\n    const modal = useRef<ModalRef>(null);\n    const [thirdParty, setThirdParty] = useState(false);\n\n    const [depAppId, setDepAppId] = useState<string | null>(null);\n    const onSelectApp = useEvent(async (id: string) => {\n        if (id === depAppId) return;\n        setDepInfo(null);\n        setDepError(null);\n        setDepAppId(id);\n    });\n\n    const [depInfo, setDepInfo] = useState<any>(null);\n    const [depError, setDepError] = useState<string | null>(null);\n    const [suggestedDepInfo, setSuggestedDepInfo] = useState<any>(null);\n\n    useEffectAsync(\n        async function* () {\n            if (depAppId) {\n                let depInfo;\n                try {\n                    depInfo = await api.getDependencyInfo(appId, depAppId);\n                } catch (e) {\n                    // pass\n                }\n                yield;\n                if (depInfo) {\n                    setDepInfo(depInfo);\n                    setDepError(null);\n                } else {\n                    setDepInfo(null);\n                    setDepError(`Invalid Dependency ID ${depAppId}`);\n                }\n            } else {\n                setDepError(null);\n                setDepInfo(null);\n            }\n        },\n        [depAppId]\n    );\n\n    // Check the hinted app before offering it; choosing it still requires validation and explicit confirmation.\n    useEffectAsync(\n        async function* () {\n            setSuggestedDepInfo(null);\n            const suggestedAppId = resolutionHints?.app_id;\n            if (!suggestedAppId || suggestedAppId === activeDepAppId) {\n                return;\n            }\n\n            let suggestedInfo = null;\n            try {\n                suggestedInfo = await api.getDependencyInfo(appId, suggestedAppId);\n            } catch (e) {\n                // pass\n            }\n            yield;\n            setSuggestedDepInfo(suggestedInfo);\n        },\n        [appId, resolutionHints?.app_id, activeDepAppId]\n    );\n    return (\n        <Modal\n            modalId={modalId}\n            ref={modal}\n            title={alreadyBroken ? \"Resolve Missing Dependency\" : \"Change Dependency App\"}\n            icon={faArrowRightArrowLeft}\n            size=\"medium\"\n            buttons={[\n                {\n                    text: alreadyBroken ? \"Resolve\" : \"Change App\",\n                    variant: \"primary\",\n                    clickActionCreator: () => modal.current!.returnValue(depAppId),\n                    enabled: !!depInfo,\n                },\n                {\n                    text: \"Cancel\",\n                    close: true,\n                },\n            ]}>\n            <div>\n                {!alreadyBroken && <Text level={2}>Current app: {dependencyName || activeDepAppId}</Text>}\n                {!alreadyBroken && (\n                    <SecondaryNavAlert\n                        title={\"Warning: Global update\"}\n                        body={\n                            \"Changing the app used for this dependency will affect all branches of your app, not just this one.\"\n                        }\n                        className={\"bg-red-100!\"}\n                        iconClassName={\"text-red-500!\"}\n                    />\n                )}\n\n                {resolutionHints && (\n                    <div className=\"min-w-0 [overflow-wrap:anywhere]\">\n                        {resolutionHints.name && (\n                            <div>\n                                <span className=\"font-semibold\">{resolutionHints.name}</span>\n                                {resolutionHints.app_id && (\n                                    <>\n                                        {\" \"}\n                                        (<code>{resolutionHints.app_id}</code>)\n                                    </>\n                                )}\n                            </div>\n                        )}\n                        {resolutionHints.package_name && (\n                            <div>\n                                Python package: <code>{resolutionHints.package_name}</code>\n                            </div>\n                        )}\n                        {resolutionHints.app_id && !resolutionHints.name && (\n                            <div>\n                                App ID: <code>{resolutionHints.app_id}</code>\n                            </div>\n                        )}\n                    </div>\n                )}\n\n                {activeDepCode?.error && (\n                    <div className={\"mt-4\"}>\n                        <b>Error:</b> {activeDepCode.error}\n                    </div>\n                )}\n\n                {suggestedDepInfo && (\n                    <div className=\"mt-4 min-w-0 rounded border border-sectionborder bg-light-bg2 p-4 [overflow-wrap:anywhere] dark:border-dark-sectionborder dark:bg-dark-bg3\">\n                        <div className={\"font-semibold\"}>Suggested app</div>\n                        <div className={\"mt-1\"}>\n                            <div className=\"font-semibold\">{suggestedDepInfo.name}</div>\n                            {suggestedDepInfo.package_name && (\n                                <div>\n                                    Python package: <code>{suggestedDepInfo.package_name}</code>\n                                </div>\n                            )}\n                        </div>\n                        <div className=\"mt-2\">\n                            Matches the saved app ID (<code>{resolutionHints?.app_id}</code>).\n                        </div>\n                        <div className={\"mt-3\"}>\n                            <Button small onClick={() => onSelectApp(resolutionHints!.app_id!)}>\n                                Select this app\n                            </Button>\n                        </div>\n                    </div>\n                )}\n\n                <Text level={1}>Which app should this dependency use?</Text>\n\n                <div className={\"mt-8\"}>\n                    {thirdParty ? (\n                        <ThirdParty addNewDependency={onSelectApp} appId={appId} setOfDepIds={setOfDepAppIds} />\n                    ) : (\n                        <MyApps appId={appId} excludedAppIds={setOfDepAppIds} addNewDependency={onSelectApp} />\n                    )}\n\n                    <ButtonGroup\n                        className={\"mt-8\"}\n                        options={[\n                            { title: \"My Apps\", value: false },\n                            { title: \"Third Party\", value: true },\n                        ]}\n                        selectedVariant={\"primary\"}\n                        selectedOption={thirdParty}\n                        onClick={setThirdParty}\n                    />\n                </div>\n\n                {depInfo && (\n                    <div className={\"mt-8\"}>\n                        <b>Dependency:</b> {depInfo.name}\n                        <br />\n                        <b>Package Name:</b> <span className={\"font-mono\"}>{depInfo.package_name}</span>\n                    </div>\n                )}\n                {depError && <div className={\"mt-8 text-red-300 select-text\"}>{depError}</div>}\n            </div>\n        </Modal>\n    );\n};\n\nexport default RemapDependency;\n","import * as React from \"react\";\nimport { ModalComponent } from \"@/components/modals\";\nimport { getIndexTitle } from \"@/components/tabs/SchemaTab\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport type {Diff, SingleLinkColumn, TableMapping} from \"@/types/database\";\nimport Modal from \"./Modal\";\n\ninterface SchemaMismatchSpec {\n    tableMapping: TableMapping;\n    requiredChanges: Diff[];\n}\n\nconst describeOnDelete = (onDelete: SingleLinkColumn['on_delete']) => {\n    switch (onDelete) {\n        case \"cascade\":\n            return `also delete this row (\"Cascade\")`;\n        case \"set_null\":\n            return `set this column value to None (\"Set Null\")`;\n        case \"restrict\":\n            return `raise an exception and prevent the deletion (\"Restrict\")`;\n        default:\n            return \"do nothing\";\n    }\n};\n\nconst Action = ({ action }: { action: Diff }) => {\n    console.log(action);\n    switch (action.type) {\n        case \"CREATE_TABLES\":\n            return (\n                <li>\n                    Create tables:{\" \"}\n                    <b>\n                        {Object.values(action.tables)\n                            .map((t) => t.title)\n                            .join(\", \")}\n                    </b>\n                </li>\n            );\n        case \"DELETE_TABLE\":\n            return (\n                <li>\n                    Delete table: <b>{action.table}</b>\n                </li>\n            );\n        case \"UPDATE_TABLE\":\n            return (\n                <li>\n                    Update table: <b>{action.table}</b>\n                    <br />\n                    <pre>{JSON.stringify(action)}</pre>\n                </li>\n            );\n        case \"ADD_COLUMN\":\n            return (\n                <li>\n                    Add column{\" \"}\n                    <b>\n                        <code>{action.column.name}</code>\n                    </b>{\" \"}\n                    to table{\" \"}\n                    <b>\n                        <code>{action.table}</code>\n                    </b>\n                </li>\n            );\n        case \"DELETE_COLUMN\":\n            return (\n                <li>\n                    Delete column{\" \"}\n                    <b>\n                        <code>{action.column_name}</code>\n                    </b>{\" \"}\n                    from table{\" \"}\n                    <b>\n                        <code>{action.table}</code>\n                    </b>\n                </li>\n            );\n        case \"RENAME_COLUMN\":\n            return (\n                <li>\n                    Rename column{\" \"}\n                    <b>\n                        <code>{action.column_name}</code>\n                    </b>{\" \"}\n                    to{\" \"}\n                    <b>\n                        <code>'{action.new_column_name}'</code>\n                    </b>{\" \"}\n                    in table{\" \"}\n                    <b>\n                        <code>{action.table}</code>\n                    </b>\n                </li>\n            );\n        case \"UPDATE_COLUMN\":\n            // only client hidden and on_delete\n            return (\n                <li>\n                    Update the column{\" \"}\n                    <b>\n                        <code>{action.column_name}</code>\n                    </b>{\" \"}\n                    in table{\" \"}\n                    <b>\n                        <code>{action.table}</code>\n                    </b>:\n                    <br />\n                    <ul className={'px-8'}>\n                        {'on_delete' in action.changes\n                            && <li>When the linked row is deleted, {describeOnDelete(action.changes.on_delete)}.</li>}\n                        {'client_hidden' in action.changes\n                            && <li>Set client-hidden to <code>{`${action.changes.client_hidden}`}</code>.</li>}\n                    </ul>\n                </li>\n            );\n        case \"ADD_INDEX\":\n            return (\n                <li>\n                    Add a <b>{getIndexTitle(action.index)}</b> index on{\" \"}\n                    <b>\n                        <code>{action.index.columns.join(\", \")}</code>\n                    </b>{\" \"}\n                    in table{\" \"}\n                    <b>\n                        <code>{action.table}</code>\n                    </b>\n                </li>\n            );\n        case \"DELETE_INDEX\":\n            return (\n                <li>\n                    Delete the <b>{getIndexTitle(action.index)}</b> index on{\" \"}\n                    <b>\n                        <code>{action.index.columns.join(\", \")}</code>\n                    </b>{\" \"}\n                    in table{\" \"}\n                    <b>\n                        <code>{action.table}</code>\n                    </b>\n                </li>\n            );\n        default:\n            return <li>[Unknown change: {JSON.stringify(action)}]</li>;\n    }\n};\n\nconst SchemaMismatchModal: ModalComponent<SchemaMismatchSpec, \"update-db\" | \"manual-fix\"> = ({\n    modalId,\n    spec: { tableMapping, requiredChanges },\n}) => {\n    console.log(requiredChanges);\n    return (\n        <Modal\n            modalId={modalId}\n            allowDismiss={true}\n            title={`Migrate '${tableMapping.name}'?`}\n            buttons={[\n                { text: \"Migrate\", clickActionCreator: () => modalReturn(\"update-db\"), defaultButton: true },\n                { text: \"Cancel\", clickActionCreator: () => modalReturn(\"manual-fix\") },\n            ]}>\n            The following changes will be applied to make '<b>{tableMapping.name}</b>' match the schema of your app:\n            <ul style={{ margin: \"2rem\" }}>\n                {requiredChanges.map((action, i) => (\n                    <Action key={i} action={action} />\n                ))}\n            </ul>\n            Do you want to apply this migration to the '<b>{tableMapping.name}</b>' database?\n        </Modal>\n    );\n};\n\nexport default SchemaMismatchModal;\n","import React, { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faCopy } from \"@fortawesome/pro-light-svg-icons/faCopy\";\nimport { faCheck } from \"@fortawesome/pro-regular-svg-icons/faCheck\";\nimport { faDownload } from \"@fortawesome/pro-regular-svg-icons/faDownload\";\nimport { faSpinnerThird } from \"@fortawesome/pro-solid-svg-icons/faSpinnerThird\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { getAppEditState, getAppId } from \"@/controllers/app\";\nimport { getAppCommitHistory } from \"@/controllers/app/history\";\nimport {\n    getCanPublishApp,\n    getCategorisedEnvironments,\n    getDefaultPublishedEnvironment,\n    publishApp,\n    saveEnvironment,\n} from \"@/controllers/environments\";\nimport { getUser, isValidTableauDashboardUrl } from \"@/controllers/ide\";\nimport { alert, modal, modalReturn } from \"@/controllers/modals\";\nimport { testInTableau } from \"@/controllers/tableau\";\nimport { ANVIL_X_LOGO } from \"@/data/imageUrls\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport { Button } from \"../reusable/Button\";\nimport { ButtonGroup } from \"../reusable/ButtonGroup\";\nimport { Expander } from \"../reusable/Expander\";\nimport Link from \"../reusable/Link\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport TextInput from \"../reusable/TextInput\";\nimport { useCopyWithTooltip } from \"../reusable/Tooltip\";\nimport Modal from \"./Modal\";\nimport { useSelectVersion } from \"./environments/EnvironmentsModal\";\nimport type { ModalComponent } from \"./index\";\n\nexport const useStyles = makeStyles()((theme) => ({\n    root: {},\n    stepText: {\n        paddingLeft: \"2rem\",\n    },\n    stepNumber: {\n        width: \"2rem\",\n        display: \"inline-block\",\n    },\n    urlBlock: {\n        maxWidth: \"95%\",\n        overflowX: \"auto\",\n    },\n}));\n\nconst tableauDebugConnector = connect((state: State) => ({\n    appId: getAppId(state),\n    environments: getCategorisedEnvironments(state),\n}));\n\ntype TableauDebugModalProps = AnvilConnectedProps<typeof tableauDebugConnector>;\n\nconst TableauDebugModalComponent: ModalComponent<never, boolean, TableauDebugModalProps> = ({\n    modalId,\n    appId,\n    environments,\n    dispatch,\n}) => {\n    const { classes } = useStyles();\n    const debugEnvironment = environments.debug!;\n\n    const trexUrl = useMemo(() => {\n        return `/ide/apps/${appId}/tableau/trex/${debugEnvironment.env_id}`;\n    }, [appId, debugEnvironment]);\n\n    const [copyLink, copyTooltip, copyRef] = useCopyWithTooltip();\n    const copyUrl = useCallback(() => {\n        copyLink(debugEnvironment.origin.replace(/^https?:\\/\\//, \"\"));\n    }, [copyLink, debugEnvironment]);\n\n    const [showCloudInstructions, setShowCloudInstructions] = useState(true);\n    const toggleCloudInstructions = useCallback(\n        (e: React.ChangeEvent<HTMLInputElement>) => setShowCloudInstructions(e.currentTarget.value == \"yes\"),\n        [showCloudInstructions]\n    );\n\n    useEffect(() => {\n        if (\n            debugEnvironment.url?.tableau_dashboard &&\n            !isValidTableauDashboardUrl(debugEnvironment.url.tableau_dashboard)\n        ) {\n            dispatch(\n                alert(\n                    \"Invalid Dashboard URL\",\n                    <div>\n                        The Dashboard URL you have provided isn't a valid Tableau View URL.{\" \"}\n                        <Link\n                            target={\"_blank\"}\n                            className={\"underlined text-primary!\"}\n                            to={\"/docs/x/testing-in-tableau#anvil-says-my-dashboard-url-is-not-valid\"}>\n                            Click here to learn more\n                        </Link>\n                    </div>\n                )\n            );\n        }\n    }, [debugEnvironment.url?.tableau_dashboard]);\n\n    return (\n        <Modal\n            modalId={modalId}\n            allowDismiss={true}\n            title={\n                <div className={\"h-full\"}>\n                    <img className={\"mr-4 h-20 py-4\"} src={ANVIL_X_LOGO} />\n                    Test your Tableau extension\n                </div>\n            }\n            className={\"select-text\"}\n            buttons={[{ text: \"Close\", clickActionCreator: () => modalReturn(true) }]}>\n            <div className={\"text-center\"}>\n                <ButtonGroup\n                    options={[\n                        { title: \"Tableau Server or Tableau Cloud\", value: \"server\" },\n                        { title: \"Tableau Desktop\", value: \"desktop\" },\n                    ]}\n                    selectedVariant={\"primary\"}\n                    selectedOption={showCloudInstructions ? \"server\" : \"desktop\"}\n                    onClick={(selection) => setShowCloudInstructions(selection === \"server\")}\n                />\n            </div>\n\n            <Heading level={2}>\n                <span className={classes.stepNumber}>1.</span>Download your extension manifest\n            </Heading>\n\n            <Text className={classes.stepText} level={2}>\n                {debugEnvironment.origin ? (\n                    <>\n                        <FontAwesomeIcon icon={faDownload} /> <Link to={trexUrl}>Download the manifest file</Link>\n                    </>\n                ) : (\n                    <>\n                        <FontAwesomeIcon icon={faSpinnerThird} spin /> Loading...\n                    </>\n                )}\n            </Text>\n\n            <Expander isOpen={showCloudInstructions}>\n                <Heading level={2}>\n                    <span className={classes.stepNumber}>2.</span>Add your extension to the Tableau safe list\n                </Heading>\n\n                <div className={classes.stepText}>\n                    <Text>\n                        Follow{\" \"}\n                        <Link\n                            to={\n                                \"https://help.tableau.com/current/online/en-us/dashboard_extensions_server.htm#add-extensions-to-the-safe-list-and-configure-user-prompts\"\n                            }\n                            target={\"_blank\"}>\n                            these instructions\n                        </Link>{\" \"}\n                        to add your extension to the Tableau safe list. The URL of your extension is:\n                        <br />\n                        {debugEnvironment.origin ? (\n                            <>\n                                <code className={cx(\"select-all\", classes.urlBlock)}>{debugEnvironment.origin}</code>\n                                <Button ref={copyRef} small icon={faCopy} onClick={copyUrl}>\n                                    Copy URL\n                                </Button>\n                                {copyTooltip}\n                            </>\n                        ) : (\n                            <>\n                                <FontAwesomeIcon icon={faSpinnerThird} spin /> Loading...\n                            </>\n                        )}\n                    </Text>\n                </div>\n            </Expander>\n\n            <Heading level={2}>\n                <span className={classes.stepNumber}>{showCloudInstructions ? 3 : 2}.</span>Add your extension to your\n                Tableau Dashboard\n            </Heading>\n\n            <div className={classes.stepText}>\n                <Text>\n                    Follow{\" \"}\n                    <Link\n                        to={\n                            \"https://help.tableau.com/current/pro/desktop/en-us/dashboard_extensions.htm#add-an-extension-to-a-dashboard\"\n                        }\n                        target={\"_blank\"}>\n                        these instructions\n                    </Link>{\" \"}\n                    to add your extension to your Tableau Dashboard.\n                </Text>\n\n                <Text>\n                    <i>\n                        Now, when you load your dashboard, its <code>print()</code> output (and any errors) will appear\n                        in the \"Tableau Output\" panel at the bottom of the Anvil Editor.\n                    </i>\n                </Text>\n            </div>\n\n            <Expander isOpen={showCloudInstructions}>\n                <hr />\n\n                <Heading level={2}>\n                    <span className={classes.stepNumber}>4.</span>(Optional:) Test your dashboard in the Anvil Editor\n                </Heading>\n\n                <div className={classes.stepText}>\n                    <p>\n                        You can load your dashboard right inside the Anvil Editor, so you can quickly edit and test your\n                        Tableau extensions.\n                    </p>\n\n                    <p>Just publish your dashboard, then copy the published URL into the box below:</p>\n                    <TextInput\n                        title={\"Dashboard URL\"}\n                        description={\"The URL of the Tableau Dashboard you added this extension to\"}\n                        placeholder={\n                            \"https://prod-uk-a.online.tableau.com/#/site/anvil1/views/MyWorkbook/MyDashboard?:iid=1\"\n                        }\n                        saveDescription=\"Dashboard URL\"\n                        initialValue={debugEnvironment.url?.tableau_dashboard}\n                        onSave={(url) => {\n                            const { url: envUrl } = debugEnvironment;\n                            return dispatch(\n                                saveEnvironment(debugEnvironment, {\n                                    url: { ...envUrl, tableau_dashboard: url },\n                                })\n                            );\n                        }}\n                    />\n                </div>\n            </Expander>\n        </Modal>\n    );\n};\n\nexport const TableauDebugModal = tableauDebugConnector(TableauDebugModalComponent) as typeof TableauDebugModalComponent;\n\nconst tableauPublishConnector = connect((state: State) => ({\n    editState: getAppEditState(state),\n    canPublish: getCanPublishApp(state),\n    publishedEnv: getDefaultPublishedEnvironment(state),\n    appId: getAppId(state),\n    commitHistory: getAppCommitHistory(state),\n    user: getUser(state),\n}));\n\ntype TableauPublishModalProps = AnvilConnectedProps<typeof tableauPublishConnector>;\n\nconst TableauPublishModalComponent: ModalComponent<never, boolean, TableauPublishModalProps> = ({\n    modalId,\n    editState,\n    publishedEnv,\n    appId,\n    canPublish,\n    commitHistory,\n    user,\n    dispatch,\n}) => {\n    const { classes } = useStyles();\n\n    const trexUrl = useMemo(() => {\n        if (publishedEnv) {\n            return `/ide/apps/${appId}/tableau/trex/${publishedEnv?.env_id}`;\n        }\n    }, [publishedEnv]);\n\n    const selectVersion = useSelectVersion(commitHistory);\n\n    const [copyLink, copyTooltip, copyRef] = useCopyWithTooltip();\n    const copyUrl = useCallback(() => {\n        copyLink(publishedEnv!.origin.replace(/^https?:\\/\\//, \"\"));\n    }, [publishedEnv]);\n\n    console.log(\"publishedEnv =\", publishedEnv);\n\n    return (\n        <Modal\n            modalId={modalId}\n            allowDismiss={true}\n            title={\n                <div className={\"h-full\"}>\n                    <img className={\"mr-4 h-20 py-4\"} src={ANVIL_X_LOGO} />\n                    Publish your Tableau extension\n                    {/*Publish your <img className={\"h-full mx-2 py-4\"} src={theme.isDark ? \"ide/img/anvil-x-full-dark-bg.svg\" : \"/ide/img/anvil-x-full.svg\"} alt={\"Anvil X logo\"}/> extension*/}\n                </div>\n            }\n            buttons={[{ text: \"Close\", clickActionCreator: () => modalReturn(true) }]}\n            className={\"p-8 select-text\"}>\n            <div className={\"\"}>\n                <Text>\n                    By <b>Publishing</b> your Tableau extension, you can put it in a dashboard for other people to use,\n                    not just for your own debugging.\n                </Text>\n\n                <Text>\n                    If someone is using the Published version of your extension, you won't see the output in the Anvil\n                    Editor, so it won't get in your way. You can also publish a particular version of your extension, so\n                    you can keep working on your development version.\n                </Text>\n\n                <Text>\n                    If you don't need any of the above, close this dialog and go back to{\" \"}\n                    <LinkInternal className={\"bold underline\"} onClick={() => dispatch(testInTableau())}>\n                        Test in Tableau\n                    </LinkInternal>\n                    .\n                </Text>\n            </div>\n\n            <hr />\n\n            <Heading level={2}>\n                <span className={classes.stepNumber}>1.</span>Publish your extension\n            </Heading>\n            {canPublish && (\n                <Text className={classes.stepText} level={1}>\n                    {publishedEnv ? (\n                        <>\n                            Your extension is published <FontAwesomeIcon icon={faCheck} />\n                            <br />\n                            <LinkInternal\n                                style={{ textDecoration: \"underline\" }}\n                                onClick={() => selectVersion(publishedEnv)}>\n                                Publish a particular version...\n                            </LinkInternal>\n                        </>\n                    ) : (\n                        <Button onClick={() => dispatch(publishApp({ ref: `refs/heads/${editState!.branch}` }))}>\n                            Publish now\n                        </Button>\n                    )}\n                </Text>\n            )}\n            <Text className={classes.stepText} level={canPublish ? 3 : 1}>\n                <LinkInternal\n                    style={{ textDecoration: \"underline\" }}\n                    onClick={() => dispatch(modal(\"environments\", {}))}>\n                    View advanced publication settings...\n                </LinkInternal>\n            </Text>\n\n            {canPublish && (\n                <>\n                    <Heading level={2}>\n                        <span className={classes.stepNumber}>2.</span>Download your published extension manifest\n                    </Heading>\n                    {publishedEnv ? (\n                        <Text className={classes.stepText} level={1}>\n                            <FontAwesomeIcon icon={faDownload} />{\" \"}\n                            <Link to={trexUrl}>Download the published manifest file</Link>\n                        </Text>\n                    ) : (\n                        <Text className={classes.stepText} level={2}>\n                            Publish your extension to download its manifest.\n                        </Text>\n                    )}\n                </>\n            )}\n\n            {publishedEnv && (\n                <>\n                    <Heading level={2}>\n                        <span className={classes.stepNumber}>3.</span>Add your extension to the Tableau safe list\n                    </Heading>\n\n                    <Text className={classes.stepText} level={1}>\n                        If you're using Tableau Cloud or Tableau server, follow{\" \"}\n                        <Link\n                            to={\n                                \"https://help.tableau.com/current/online/en-us/dashboard_extensions_server.htm#add-extensions-to-the-safe-list-and-configure-user-prompts\"\n                            }\n                            target={\"_blank\"}>\n                            these instructions\n                        </Link>{\" \"}\n                        to add your published extension to the Tableau safe list. The URL of your extension is{\" \"}\n                        <code className={\"select-all\"}>{publishedEnv.origin}</code>{\" \"}\n                        <Button ref={copyRef} small icon={faCopy} onClick={copyUrl}>\n                            Copy URL\n                        </Button>\n                        {copyTooltip}\n                    </Text>\n\n                    <Heading level={2}>\n                        <span className={classes.stepNumber}>4.</span>Add your extension to your Tableau Dashboard\n                    </Heading>\n                    <Text className={classes.stepText} level={1}>\n                        Follow{\" \"}\n                        <Link\n                            to={\n                                \"https://help.tableau.com/current/pro/desktop/en-us/dashboard_extensions.htm#add-an-extension-to-a-dashboard\"\n                            }\n                            target={\"_blank\"}>\n                            these instructions\n                        </Link>{\" \"}\n                        to add your extension to your Tableau Dashboard.\n                    </Text>\n                </>\n            )}\n        </Modal>\n    );\n};\n\nexport const TableauPublishModal = tableauPublishConnector(\n    TableauPublishModalComponent\n) as typeof TableauPublishModalComponent;\n","import React from \"react\";\nimport { TableauCTASpec } from \"@/controllers/app/cta\";\nimport { ModalComponent } from \".\";\nimport { modalReturn } from \"../../controllers/modals\";\nimport Link from \"../reusable/Link\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport Modal from \"./Modal\";\n\nconst TableauCTA: ModalComponent<TableauCTASpec> = ({ modalId, spec: { description, sampleDashboardUrl } }) => {\n    return (\n        <Modal\n            title={\"How to use this Extension\"}\n            modalId={modalId}\n            buttons={[\n                { text: \"Close\" },\n                {\n                    text: \"Got it! Don't show this again.\",\n                    defaultButton: true,\n                    clickActionCreator: () => modalReturn(true),\n                },\n            ]}>\n            {description}\n            <Heading level={2}>Get Started</Heading>\n            <Text>\n                To use this extension, <Link to={sampleDashboardUrl}>download the sample Tableau dashboard</Link> it\n                goes with. You can open this in Tableau Desktop, or upload it to Tableau Cloud or Tableau Server.\n                Alternatively, you can use this extension with a dashboard you already have.\n            </Text>\n            <Text>\n                Follow{\" \"}\n                <Link target={\"_blank\"} to={\"/docs/x/testing-in-tableau\"}>\n                    these instructions\n                </Link>{\" \"}\n                to download the <code>.trex</code> file for this extension, add it to your dashboard, and take it for a\n                spin!\n            </Text>\n        </Modal>\n    );\n};\n\nexport default TableauCTA;\n","import React, { useCallback } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faPlus } from \"@fortawesome/free-solid-svg-icons/faPlus\";\nimport { faCheck } from \"@fortawesome/pro-light-svg-icons/faCheck\";\nimport { faExternalLinkAlt } from \"@fortawesome/pro-light-svg-icons/faExternalLinkAlt\";\nimport { faTimes } from \"@fortawesome/pro-light-svg-icons/faTimes\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { getAppEditState } from \"@/controllers/app\";\nimport {\n    createDefaultEnvironment,\n    enableEnvironmentUplink,\n    getCategorisedEnvironments,\n    getSelectedUplinkId,\n    loadEnvironments,\n    setSelectedEnvironmentId,\n    setSelectedUplinkId,\n} from \"@/controllers/environments\";\nimport { modal, modalReturn } from \"@/controllers/modals\";\nimport { cx } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, AppEnvironment, State } from \"@/types\";\nimport { useEffectAsync } from \"@/util/hooks\";\nimport type { ModalComponent } from \".\";\nimport { Accordion } from \"../reusable/Accordion\";\nimport { Button } from \"../reusable/Button\";\nimport { HelpLink } from \"../reusable/HelpLink\";\nimport { Text } from \"../reusable/Text\";\nimport Modal from \"./Modal\";\nimport { EnvironmentHeaderTemplate } from \"./environments/EnvironmentHeaderTemplate\";\nimport { EnvironmentUplinkConfig } from \"./environments/EnvironmentUplinkConfig\";\nimport { environmentStyles } from \"./environments/EnvironmentsModal\";\nimport useStyles from \"./modalstyles\";\n\nconst connector = connect((state: State) => ({\n    editState: getAppEditState(state),\n    environments: getCategorisedEnvironments(state),\n    selectedUplinkId: getSelectedUplinkId(state),\n}));\n\ntype UplinkModalProps = AnvilConnectedProps<typeof connector>;\n\nconst UplinkModal: ModalComponent<never, void, UplinkModalProps> = ({\n    modalId,\n    environments,\n    editState,\n    selectedUplinkId,\n    dispatch,\n}) => {\n    // not sure about this\n    const { classes } = useStyles(undefined, { props: environmentStyles() });\n\n    // Every time this modal is opened, reload the environments.\n    useEffectAsync(async () => {\n        await dispatch(loadEnvironments());\n    }, []);\n\n    const environmentsSorted = environments.sorted || [];\n\n    const selectUplink = useCallback(\n        async ({ env_id }: AppEnvironment) => {\n            if (selectedUplinkId === env_id) {\n                dispatch(setSelectedUplinkId(null));\n            } else {\n                dispatch(setSelectedUplinkId(env_id));\n            }\n        },\n        [selectedUplinkId]\n    );\n\n    const gotoEnvironment = useCallback(async (envId: AppEnvironment[\"env_id\"]) => {\n        await dispatch(setSelectedEnvironmentId(envId));\n        dispatch(modal(\"environments\", {}));\n    }, []);\n\n    let defaultUplinkDisplay =\n        environmentsSorted[0]?.server_keys?.uplink?.server_key ||\n        environmentsSorted[0]?.server_keys?.uplink?.client_key;\n    const currentBranch = editState?.branch;\n\n    const createAndEnableFirstEnv = useCallback(async (type: \"client\" | \"server\") => {\n        const newEnv = await dispatch(createDefaultEnvironment());\n        if (newEnv) {\n            await dispatch(enableEnvironmentUplink(newEnv, type));\n        }\n    }, []);\n\n    const enableInEnv = useCallback(async (env: AppEnvironment, type: \"client\" | \"server\") => {\n        await dispatch(enableEnvironmentUplink(env, type));\n    }, []);\n\n    let configUi: React.ReactNode;\n    if (environmentsSorted.length === 0) {\n        // These will need to both create the default environment and pre-configure appropriate keys.\n        configUi = (\n            <div style={{ textAlign: \"center\", margin: \"2rem 0\" }}>\n                <Button\n                    variant={\"primary\"}\n                    onClick={() => createAndEnableFirstEnv(\"client\")}\n                    style={{ marginRight: \"1rem\" }}>\n                    <FontAwesomeIcon fixedWidth icon={faPlus} /> Enable client Uplink\n                </Button>\n                <Button variant={\"primary\"} onClick={() => createAndEnableFirstEnv(\"server\")}>\n                    <FontAwesomeIcon fixedWidth icon={faPlus} /> Enable server Uplink\n                </Button>\n            </div>\n        );\n    } else if (environmentsSorted.length === 1) {\n        const env = environmentsSorted[0];\n        const envBranch = env.version?.ref?.substring(11); // TODO: What if it's a commitId?\n\n        // If there are keys, display the full config. If there aren't yet, just display the nice buttons as above.\n        if (!env.server_keys?.uplink?.client_key && !env.server_keys?.uplink?.server_key) {\n            configUi = (\n                <div style={{ textAlign: \"center\", margin: \"2rem 0\" }}>\n                    <Button\n                        variant={\"primary\"}\n                        onClick={() => enableInEnv(env, \"client\")}\n                        style={{ marginRight: \"1rem\" }}>\n                        <FontAwesomeIcon fixedWidth icon={faPlus} /> Enable client Uplink\n                    </Button>\n                    <Button variant={\"primary\"} onClick={() => enableInEnv(env, \"server\")}>\n                        <FontAwesomeIcon fixedWidth icon={faPlus} /> Enable server Uplink\n                    </Button>\n                </div>\n            );\n        } else {\n            configUi = (\n                <>\n                    <EnvironmentUplinkConfig env={env} style={{ margin: \"2rem 0\" }} />\n                    {`refs/heads/${currentBranch}` !== env.version?.ref &&\n                        currentBranch &&\n                        (envBranch ? (\n                            <Text level={3}>\n                                The Uplink will connect to the <code>{envBranch}</code> branch of your app. Changes you\n                                make to your app here on the <code>{currentBranch}</code> branch will not be visible on\n                                the Uplink until you merge them into the <code>{envBranch}</code> branch.\n                            </Text>\n                        ) : (\n                            <Text level={3}>\n                                The Uplink is configured to connect to an old version of your app, so changes you make\n                                here on the <code>{currentBranch}</code> branch will not be visible.\n                            </Text>\n                        ))}\n                </>\n            );\n        }\n    } else {\n        // There are multiple environments\n        configUi = (\n            <Accordion\n                items={environmentsSorted}\n                keyName={\"env_id\"}\n                expandedKeys={selectedUplinkId == null ? {} : { [selectedUplinkId]: true }}\n                onToggle={selectUplink}\n                renderHeader={(env: AppEnvironment, idx: number, isExpanded: boolean) => (\n                    <EnvironmentHeaderTemplate\n                        title={env.description}\n                        subtitle={\n                            env.version?.ref ? (\n                                <>\n                                    Connects to the <code>{env.version.ref.substring(11)}</code> branch of this app\n                                </>\n                            ) : (\n                                `Connects to a specific version of this app`\n                            )\n                        }\n                        actions={\n                            isExpanded && [\n                                [faExternalLinkAlt, \"Edit environment...\", () => gotoEnvironment(env.env_id)],\n                            ]\n                        }\n                        flags={\n                            <>\n                                <div className={cx(env.server_keys?.uplink?.client_key && \"present\")}>\n                                    Client{\" \"}\n                                    <FontAwesomeIcon\n                                        fixedWidth\n                                        icon={env.server_keys?.uplink?.client_key ? faCheck : faTimes}\n                                    />\n                                </div>\n                                <div className={cx(env.server_keys?.uplink?.server_key && \"present\")}>\n                                    Server{\" \"}\n                                    <FontAwesomeIcon\n                                        fixedWidth\n                                        icon={env.server_keys?.uplink?.server_key ? faCheck : faTimes}\n                                    />\n                                </div>\n                            </>\n                        }\n                    />\n                )}\n                renderBody={(env: AppEnvironment, idx: number) => (\n                    <div className=\"p-6\">\n                        <EnvironmentUplinkConfig env={env} />\n                    </div>\n                )}\n            />\n        );\n    }\n\n    return (\n        <Modal\n            modalId={modalId}\n            title=\"Anvil Uplink\"\n            size={environmentsSorted.length > 1 ? \"large\" : \"medium\"}\n            buttons={[{ text: \"Close\", clickActionCreator: () => modalReturn(undefined) }]}>\n            <div className=\"p-6\">\n                <h4 className=\"mb-8 text-center text-2xl font-medium\">Connect your app to existing code</h4>\n                {configUi}\n            </div>\n\n            <div className=\"space-y-4 p-6\">\n                <h4 className=\"my-2 mb-8 text-3xl font-medium\">Python example</h4>\n                <p>1. First, install the Anvil Uplink library:</p>\n                <pre className={classes.selectable}>pip install anvil-uplink</pre>\n                <p>2. Copy and paste this code into the top of your Python program:</p>\n                <pre className={classes.selectable}>\n                    import anvil.server\n                    <br />\n                    <br />\n                    anvil.server.connect(\"{defaultUplinkDisplay || \"[insert key here]\"}\"\n                    {document.location.origin !== \"https://anvil.works\"\n                        ? ', url=\"' + document.location.origin.replace(\"http\", \"ws\") + '/uplink\"'\n                        : \"\"}\n                    )\n                </pre>\n                <p>3. You can now use the Uplink locally.</p>\n                <p>\n                    For more information, consult the{\" \"}\n                    <HelpLink inline iconRight url={\"/docs/uplink\"}>\n                        uplink documentation\n                    </HelpLink>\n                </p>\n            </div>\n        </Modal>\n    );\n};\n\nexport default connector(UplinkModal) as typeof UplinkModal;\n","import React, { useRef, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faUpload } from \"@fortawesome/free-solid-svg-icons/faUpload\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { createAppFromYaml } from \"@/controllers/app\";\nimport { AnvilDispatch, IDETreeMapContent } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \".\";\nimport { ButtonGroup } from \"../reusable/ButtonGroup\";\nimport { TextArea } from \"../reusable/Forms\";\nimport { ModalButton } from \"../reusable/SharedComponents\";\nimport { Text } from \"../reusable/Text\";\nimport Modal, { ModalRef } from \"./Modal\";\n\nasync function loadYaml(yaml: string) {\n    const jsYaml = await import(\"js-yaml\");\n    const app: unknown = jsYaml.load(yaml);\n    if (\n        !app ||\n        typeof app !== \"object\" ||\n        Array.isArray(app) ||\n        !(\"name\" in app) ||\n        typeof app.name !== \"string\" ||\n        !app.name.trim()\n    ) {\n        throw new Error(\"The YAML must describe an app with a name.\");\n    }\n    return app as IDETreeMapContent;\n}\n\nconst AppInfo = ({ appYaml, fileName }: { appYaml: IDETreeMapContent | null; fileName: string }) => {\n    if (!appYaml) return null;\n    return (\n        <div className=\"grid grid-cols-2\">\n            <Text>File Uploaded:</Text>\n            <Text> {fileName}</Text>\n            <Text>App Found:</Text>\n            <Text>{appYaml.name ?? \"<Unknown>\"}</Text>\n        </div>\n    );\n};\n\nconst UploadAppYaml: ModalComponent = ({ modalId }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const modal = useRef<ModalRef>(null);\n    const [source, setSource] = useState<\"file\" | \"paste\">(\"file\");\n    const [fileName, setFileName] = useState(\"\");\n    const [appYaml, setAppYaml] = useState<IDETreeMapContent | null>(null);\n    const [pastedYaml, setPastedYaml] = useState(\"\");\n    const [error, setError] = useState<string | null>(null);\n\n    const onFileChange: React.ChangeEventHandler<HTMLInputElement> = useEvent(async (e) => {\n        const file = e.target.files?.[0];\n        setAppYaml(null);\n        setFileName(\"\");\n        setError(null);\n\n        if (!file) return;\n        setFileName(file.name ?? \"\");\n        const reader = new FileReader();\n        reader.onload = async (e) => {\n            const yaml = reader.result as string;\n\n            try {\n                const parsedApp = await loadYaml(yaml);\n                setAppYaml(parsedApp);\n            } catch (e) {\n                setError(e instanceof Error ? e.message : \"Failed to read the app YAML.\");\n            }\n        };\n\n        reader.readAsText(file);\n    });\n\n    const onImport = useEvent(async () => {\n        let app = appYaml;\n        if (source === \"paste\") {\n            try {\n                app = await loadYaml(pastedYaml);\n            } catch (e) {\n                setError(e instanceof Error ? e.message : \"Failed to read the app YAML.\");\n                return;\n            }\n        }\n        if (!app) return;\n        await dispatch(createAppFromYaml(app));\n        await modal.current?.returnValue();\n    });\n\n    const fileInputRef = useRef<HTMLInputElement>(null);\n\n    return (\n        <Modal\n            ref={modal}\n            title=\"Import App\"\n            modalId={modalId}\n            buttons={[\n                {\n                    text: \"Import\",\n                    enabled: source === \"file\" ? !!appYaml : !!pastedYaml.trim(),\n                    clickActionCreator: onImport,\n                    defaultButton: true,\n                    close: false,\n                },\n                { text: \"Cancel\" },\n            ]}>\n            <div className=\"flex flex-col items-center gap-8\">\n                <ButtonGroup\n                    options={\n                        [\n                            { title: \"Upload file\", value: \"file\" },\n                            { title: \"Paste YAML\", value: \"paste\" },\n                        ] as const\n                    }\n                    selectedOption={source}\n                    selectedVariant=\"primary\"\n                    onClick={(value) => {\n                        setSource(value);\n                        setError(null);\n                    }}\n                />\n                {source === \"file\" ? (\n                    <>\n                        <Text>Please choose the app you wish to import:</Text>\n                        <ModalButton\n                            className=\"w-max\"\n                            variant={\"primary\"}\n                            onClick={() => fileInputRef.current?.click()}>\n                            <div className=\"flex gap-4\">\n                                <FontAwesomeIcon icon={faUpload} />\n                                Upload App\n                            </div>\n                            <input\n                                ref={fileInputRef}\n                                className=\"hidden\"\n                                onClick={(e) => e.stopPropagation()}\n                                onChange={onFileChange}\n                                type=\"file\"\n                                accept=\".yaml\"\n                            />\n                        </ModalButton>\n                        <AppInfo appYaml={appYaml} fileName={fileName} />\n                    </>\n                ) : (\n                    <TextArea\n                        aria-label=\"App YAML\"\n                        placeholder=\"Paste the app YAML exported from Anvil\"\n                        className=\"min-h-[24rem] w-full resize-y font-mono\"\n                        rows={12}\n                        spellCheck={false}\n                        invalid={!!error}\n                        value={pastedYaml}\n                        onChange={(e) => {\n                            setPastedYaml(e.target.value);\n                            setError(null);\n                        }}\n                        onKeyDown={(e) => {\n                            // Enter should add a newline, not trigger the modal's default Import action.\n                            if (e.key === \"Enter\") e.stopPropagation();\n                        }}\n                    />\n                )}\n                {error && (\n                    <div role=\"alert\" className=\"w-full whitespace-pre-wrap text-danger\">\n                        {error}\n                    </div>\n                )}\n            </div>\n        </Modal>\n    );\n};\n\nexport default UploadAppYaml;\n","import React from \"react\";\nimport Link from \"@/components/reusable/Link\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { ModalComponent } from \".\";\nimport Modal from \"./Modal\";\n\nconst WelcomeModal: ModalComponent = ({ modalId }) => {\n    // const exampleApps = useExampleApps();\n\n    return (\n        <Modal\n            modalId={modalId}\n            title={\"Welcome to Anvil!\"}\n            className=\"w-340!\"\n            buttons={[\n                {\n                    text: \"Read the tutorial\",\n                    clickActionCreator: () => {\n                        window.open(\"/learn/tutorials/feedback-form?utm_source=ide:start-page-modal\");\n                    },\n                    variant: \"primary\",\n                },\n                { text: \"Take me to Anvil\", clickActionCreator: () => modalReturn(false) },\n            ]}>\n            <div className=\"flex flex-col items-center gap-10\">\n                <p>\n                    You’re all set to start building your very first web app. To help you get started, why not check out\n                    a tutorial?\n                </p>\n                <Link\n                    to=\"/learn/tutorials/feedback-form?utm_source=ide:start-page-modal\"\n                    target={\"_blank\"}\n                    className=\"mb-4 min-h-[200px] w-[360px] min-w-[270px] flex-wrap rounded-md border-2 border-sectionborder bg-[url('https://anvil.works/learn/tutorials/img/feedback-form/feedback-form-thumbnail.png')] bg-cover p-8 hover:shadow-[0_0_1rem_1rem_#1bb0ee38] md:flex-nowrap dark:border-dark-bg4\"></Link>\n                <p>\n                    If you need help, make sure to visit the{\" \"}\n                    <Link to=\"/forum\" className=\"text-[#1bb0ee]! no-underline!\">\n                        Anvil Community Forum.\n                    </Link>\n                </p>\n            </div>\n        </Modal>\n    );\n};\n\nexport default WelcomeModal;\n","import React, { useCallback, useState } from \"react\";\nimport { DropDown, InputLabel } from \"@/components/reusable/Forms\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { HeaderInfo } from \"@/components/tabs/database/types\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport {ColumnSpec, LiveObjectColumn, LiveObjectSingleColumn, TableMapping} from \"@/types/database\";\nimport { ModalComponent } from \"..\";\nimport Modal, { ModalButtons } from \"../Modal\";\n\ninterface AddColumnSpec {\n    info: HeaderInfo;\n    colSpec: Pick<ColumnSpec, \"name\" | \"admin_ui\">;\n    targets: [string, string][];\n}\n\nconst typeDescriptions = {\n    Text: \"string\",\n    Number: \"number\",\n    \"True/False\": \"bool\",\n    Date: \"date\",\n    \"Date and Time\": \"datetime\",\n    Media: \"media\",\n    \"Simple Object\": \"simpleObject\",\n    \"Single row from another table\": \"liveObject\",\n    \"Multiple rows from another table\": \"liveObjectArray\",\n} as const;\n\nconst typesWithTarget = [\"link_single\", \"link_multiple\", \"liveObject\", \"liveObjectArray\"];\n\nconst typeDescriptionEntries = Object.entries(typeDescriptions);\n\nconst isLinkColumn = (colSpec: any): colSpec is LiveObjectColumn => typesWithTarget.includes(colSpec.type);\n\n/** @todo - remove this - temporary while we use live objects */\nconst cleanLinkedColumnForOldTables = (colSpec: LiveObjectColumn, tableMapping: TableMapping, target: string) => {\n    colSpec.backend = \"anvil.tables.Row\";\n    const table = tableMapping.tables.find(({ python_name }) => python_name === target);\n    if (table === undefined) {\n        throw new Error(\"Problem creating linked row\");\n    }\n    colSpec.table_id = table.id;\n};\n\nconst AddColumn: ModalComponent<AddColumnSpec, ColumnSpec | null> = ({ modalId, spec: { colSpec, targets, info } }) => {\n    const { tableMapping } = info.table.options.meta!;\n    const isSplit = !!info.table.options.meta?.currentTable.split;\n    const [name, setName] = useState(colSpec.name);\n    const [type, setType] = useState(\"\");\n    const [target, setTarget] = useState(\"\");\n    const [onDelete, setOnDelete] = useState<LiveObjectSingleColumn[\"on_delete\"]>(\"set_null\");\n    const needsTarget = typesWithTarget.includes(type);\n    const needsOnDelete = type === \"liveObject\" && isSplit;\n\n    const modalButtons: ModalButtons = [\n        {\n            text: \"OK\",\n            variant: \"primary\",\n            enabled: !!(name && type && (!needsTarget || target)),\n            defaultButton: true,\n            clickActionCreator: () => {\n                const finalColSpec = { ...colSpec, name, type } as ColumnSpec;\n                // Don't support setting On Delete when creating columns until Split Tables are the default. Possibly not even then.\n                // if (needsOnDelete) {\n                //     finalColSpec.on_delete = onDelete;\n                // }\n                if (isLinkColumn(finalColSpec)) {\n                    cleanLinkedColumnForOldTables(finalColSpec, tableMapping!, target);\n                }\n                return modalReturn(finalColSpec);\n            },\n        },\n        { text: \"Cancel\", clickActionCreator: () => modalReturn(null) },\n    ];\n\n    const nameInputRef = useCallback((node: HTMLInputElement) => {\n        node?.focus();\n        node?.select();\n    }, []);\n\n    return (\n        <Modal autoFocus={false} size={\"small\"} modalId={modalId} title={\"Add a Column\"} buttons={modalButtons}>\n            <div className=\"flex flex-col gap-8\">\n                <InputLabel title={\"Column Name\"}>\n                    <div className={\"flex items-baseline\"}>\n                        <ContentTextInput\n                            ref={nameInputRef}\n                            value={name}\n                            placeholder={\"Set a name\"}\n                            onChange={(e) => setName(e.target.value)}\n                            type=\"text\"\n                        />\n                    </div>\n                </InputLabel>\n                <InputLabel title={\"Column Type\"}>\n                    <div className={\"flex items-baseline\"}>\n                        <DropDown value={type} onChange={(e: any) => setType(e.target.value)}>\n                            <option value=\"\" disabled>\n                                Select a type\n                            </option>\n                            {typeDescriptionEntries.map(([description, type]) => (\n                                <option key={type} value={type}>\n                                    {description}\n                                </option>\n                            ))}\n                        </DropDown>\n                    </div>\n                </InputLabel>\n                {needsTarget && (\n                    <InputLabel title={\"Linked Table\"}>\n                        <div className={\"flex items-baseline\"}>\n                            <DropDown value={target} onChange={(e: any) => setTarget(e.target.value)}>\n                                <option value=\"\" disabled>\n                                    Select the Table\n                                </option>\n                                {targets.map(([name, target]) => (\n                                    <option key={target} value={target}>\n                                        {name}\n                                    </option>\n                                ))}\n                            </DropDown>\n                        </div>\n                    </InputLabel>\n                )}\n            </div>\n        </Modal>\n    );\n};\nexport default AddColumn;\n","import React, { useMemo, useState } from \"react\";\nimport { isEmpty } from \"lodash-es\";\nimport { getLiveObject } from \"@/api/tables\";\nimport { Heading } from \"@/components/reusable/Text\";\nimport TableView from \"@/components/tabs/database/View\";\nimport { RowLinkSingle } from \"@/components/tabs/database/cells/Cell\";\nimport { CellInfo, HeaderInfo } from \"@/components/tabs/database/types\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { AnvilAction } from \"@/types\";\nimport { LiveObjectColumn, TableId, TableMapping, TableMappingId } from \"@/types/database\";\nimport { ModalComponent } from \"..\";\nimport Modal, { ModalButtons } from \"../Modal\";\n\ninterface AddColumnSpec {\n    info: CellInfo | HeaderInfo;\n    multiple?: boolean;\n    value: any;\n}\ntype AddLinkedRowModal = ModalComponent<AddColumnSpec>;\n\nconst getTableFromId = (tableMapping: TableMapping | undefined, tableId: TableId) => {\n    const table = tableMapping?.tables.find((table) => table.id === tableId);\n    if (table === undefined) {\n        throw new Error(\"Could not find a valid table\");\n    }\n    return table;\n};\n\nconst modalReturnLiveObject =\n    (\n        appId: string,\n        tableMappingId: TableMappingId,\n        tableId: TableId,\n        selectedRowIds: number[],\n        multiple?: boolean\n    ): AnvilAction =>\n    async (dispatch) => {\n        const liveObjectArray = await Promise.all(\n            selectedRowIds.map((rowId) => getLiveObject(appId, tableMappingId, tableId, rowId))\n        );\n        dispatch(modalReturn(multiple ? liveObjectArray : liveObjectArray[0]));\n    };\n\nconst getRowIdsFromLiveObject = (value: any): null | number[] => {\n    if (!value) return null;\n    if (!Array.isArray(value)) value = [value];\n    return value\n        .map(({ id }: any) => {\n            const [, rowId] = id.slice(1, -1).split(\",\");\n            return Number(rowId);\n        })\n        .sort();\n};\n\nconst AddLinkedRow: AddLinkedRowModal = ({ modalId, spec: { value, info, multiple } }) => {\n    const { original } = info.column.columnDef.meta!;\n    const { table_id: tableId } = original as LiveObjectColumn;\n    const { appId, tableMapping, tableMappingId } = info.table.options.meta!;\n\n    const initRowIds = useMemo(() => getRowIdsFromLiveObject(value), []);\n\n    const [rowSelection, setRowSelection] = useState(() => {\n        if (!initRowIds) return {};\n        return Object.fromEntries(initRowIds.map((rowId) => [rowId, true]));\n    });\n\n    const hasSelectedRows = !isEmpty(rowSelection);\n\n    const buttons: ModalButtons = [\n        {\n            text: \"Confirm\",\n            clickActionCreator: () => {\n                const selectedRowIds = Object.keys(rowSelection).map(Number).sort();\n                if (\n                    initRowIds?.length === selectedRowIds.length &&\n                    selectedRowIds.every((rowId, i) => rowId === initRowIds[i])\n                ) {\n                    return modalReturn(null);\n                }\n                if (!selectedRowIds.length) {\n                    // we return an empty array here to signal that the selection was removed\n                    return modalReturn([]);\n                }\n\n                return modalReturnLiveObject(appId, tableMappingId, tableId, selectedRowIds, multiple);\n            },\n            variant: \"primary\",\n        },\n        { text: \"Cancel\", clickActionCreator: () => modalReturn(null) },\n    ];\n\n    const rowTitle = multiple ? \"Rows\" : \"Row\";\n\n    const title = `Link to ${rowTitle}`;\n    let currentTable;\n    try {\n        currentTable = getTableFromId(tableMapping, tableId);\n    } catch {\n        return (\n            <Modal\n                modalId={modalId}\n                allowDismiss={true}\n                title={\"Failed to load table\"}\n                buttons={[{ text: \"OK\", clickActionCreator: () => modalReturn(null), defaultButton: true }]}>\n                There was a problem loading this table, it may have been deleted\n            </Modal>\n        );\n    }\n\n    return (\n        <Modal size={\"large\"} modalId={modalId} title={title} buttons={buttons}>\n            <div className=\"flex flex-col gap-2\">\n                <Heading className=\"mt-0!\" level={2}>\n                    Selected {rowTitle}\n                </Heading>\n                <div className=\"flex min-h-10 flex-wrap gap-2\">\n                    {hasSelectedRows ? (\n                        Object.keys(rowSelection).map((v) => (\n                            <RowLinkSingle\n                                key={v}\n                                value={{ id: `[${tableId},${v}]` }}\n                                info={info as CellInfo}\n                                onDelete={() => {\n                                    setRowSelection((prev) => {\n                                        const newSelection = { ...prev };\n                                        delete newSelection[v];\n                                        return newSelection;\n                                    });\n                                }}\n                            />\n                        ))\n                    ) : (\n                        <span className=\"text-muted text-lg\">No rows currently selected</span>\n                    )}\n                </div>\n            </div>\n\n            <div className=\"my-8 border-b border-sectionborder dark:border-dark-sectionborder\" />\n\n            <TableView\n                readonly\n                tableMapping={tableMapping}\n                currentTable={currentTable}\n                state={{ rowSelection }}\n                onRowSelectionChange={setRowSelection}\n                multiple={multiple}\n                maxHeight={\"65vh\"}\n            />\n        </Modal>\n    );\n};\n\nexport default AddLinkedRow;\n","import React, { useMemo, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { CheckBox, ContentDropdownMenuItem, ModalButton } from \"@/components/reusable/SharedComponents\";\nimport { DateTimePicker } from \"@/components/reusable/datepicker\";\nimport { cloneDatabaseToPool, createTableMapping, restoreDatabaseToPool } from \"@/controllers/db\";\nimport { getDeploymentPools } from \"@/controllers/ide\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { TableMapping } from \"@/types/database\";\nimport { DeploymentPool } from \"@/types/user\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \"..\";\nimport Modal, { ModalRef } from \"../Modal\";\n\nconst useDeploymentPoolDropdowns = () => {\n    const deploymentPools = useSelector(getDeploymentPools);\n    const hasDeploymentPools = deploymentPools && deploymentPools?.length > 0;\n    const [selectedPoolId, setSelectedPoolId] = useState<DeploymentPool[\"dp_id\"] | null>(null);\n\n    const ddPoolOptions = useMemo(() => {\n        return (\n            <>\n                <option value={\"\"}>Main Pool</option>\n                <hr />\n                {deploymentPools?.map((dp, ind) => (\n                    <option value={dp.dp_id} key={ind}>\n                        {dp.info?.title ?? dp.dp_id}\n                    </option>\n                ))}\n            </>\n        );\n    }, [deploymentPools]);\n    return { ddPoolOptions, hasDeploymentPools, selectedPoolId, setSelectedPoolId, deploymentPools };\n};\n\ninterface CloneDBSpecs {\n    mapping: TableMapping;\n}\n\nexport const CloneDatabase: ModalComponent<CloneDBSpecs> = ({\n    modalId,\n    spec: {\n        mapping: { table_mapping_id: tableMappingId, name },\n    },\n}) => {\n    const { ddPoolOptions, hasDeploymentPools, selectedPoolId, setSelectedPoolId } = useDeploymentPoolDropdowns();\n    const modalRef = useRef<ModalRef>(null!);\n\n    const dispatch = useDispatch<AnvilDispatch>();\n    const [copyMedia, setCopyMedia] = useState(true);\n\n    const onConfirm = useEvent(() => {\n        if (hasDeploymentPools) {\n            // console.log(\"Selected pool\", selectedPoolId);\n            dispatch(cloneDatabaseToPool(tableMappingId, !copyMedia, selectedPoolId));\n        } else {\n            dispatch(cloneDatabaseToPool(tableMappingId, !copyMedia, null));\n        }\n        return modalRef.current.returnValue(true);\n    });\n\n    return (\n        <Modal title={\"Clone Database\"} modalId={modalId} ref={modalRef}>\n            {hasDeploymentPools ? (\n                <>\n                    Select a deployment pool to clone <code>{name}</code> into\n                </>\n            ) : (\n                <>\n                    Make a copy of the database <code>{name}</code>\n                </>\n            )}\n            <div className={\"mt-4 ml-4 flex items-center gap-8\"}>\n                {hasDeploymentPools && (\n                    <ContentDropdownMenuItem\n                        narrow\n                        onChange={(e) => setSelectedPoolId(e.target.value)}\n                        value={selectedPoolId ?? \"\"}>\n                        {ddPoolOptions}\n                    </ContentDropdownMenuItem>\n                )}\n                <CheckBox\n                    text={`${hasDeploymentPools ? \"Also c\" : \"C\"}opy all media into cloned database`}\n                    checked={copyMedia}\n                    onChange={() => setCopyMedia(!copyMedia)}\n                />\n            </div>\n\n            <div className={cx(\"mt-8 flex justify-end gap-4\")}>\n                <ModalButton onClick={onConfirm} variant={\"primary\"}>\n                    {hasDeploymentPools ? \"Clone to Pool\" : \"Clone\"}\n                </ModalButton>\n                <ModalButton onClick={() => modalRef?.current.returnValue(false)}>Cancel</ModalButton>\n            </div>\n        </Modal>\n    );\n};\n\nexport const RestoreDatabase: ModalComponent<CloneDBSpecs> = ({\n    modalId,\n    spec: {\n        mapping: { table_mapping_id: tableMappingId, name },\n    },\n}) => {\n    const { ddPoolOptions, hasDeploymentPools, selectedPoolId, setSelectedPoolId } = useDeploymentPoolDropdowns();\n    const modalRef = useRef<ModalRef>(null!);\n\n    const dispatch = useDispatch<AnvilDispatch>();\n    const [copyMedia, setCopyMedia] = useState(true);\n    const [targetTime, setTargetTime] = useState<Date | null>(null);\n\n    const targetTimeError =\n        targetTime && targetTime.getTime() > Date.now() ? \"The restore Point cannot be in the future\" : \"\";\n\n    const onConfirm = useEvent(() => {\n        dispatch(restoreDatabaseToPool(tableMappingId, !copyMedia, selectedPoolId, targetTime!.toISOString()));\n        return modalRef.current.returnValue(true);\n    });\n\n    return (\n        <Modal title=\"Restore Database\" modalId={modalId} ref={modalRef}>\n            <div className=\"space-y-8\">\n                <div>\n                    Make a copy of the database <code>{name}</code> from a previous point in time.\n                </div>\n\n                {hasDeploymentPools && (\n                    <div>\n                        <label className=\"block font-semibold\">Deployment Pool</label>\n                        <ContentDropdownMenuItem\n                            onChange={(e) => setSelectedPoolId(e.currentTarget.value)}\n                            value={selectedPoolId ?? \"\"}>\n                            {ddPoolOptions}\n                        </ContentDropdownMenuItem>\n                    </div>\n                )}\n\n                <div>\n                    <label className=\"block font-semibold\">Restore Point</label>\n                    <DateTimePicker value={targetTime} onChange={setTargetTime} format=\"do MMMM y 'at' HH:mm\" />\n                    <div className=\"ml-6 text-danger\">{targetTimeError}</div>\n                </div>\n\n                <CheckBox\n                    text=\"Copy all media into the new database\"\n                    checked={copyMedia}\n                    onChange={() => setCopyMedia(!copyMedia)}\n                />\n\n                <div className=\"flex justify-end gap-4\">\n                    <ModalButton onClick={onConfirm} enabled={!!targetTime && !targetTimeError} variant=\"primary\">\n                        Restore\n                    </ModalButton>\n                    <ModalButton onClick={() => modalRef?.current.returnValue(false)}>Cancel</ModalButton>\n                </div>\n            </div>\n        </Modal>\n    );\n};\ninterface CreateDBInPoolSpecs {\n    proposedName: string;\n}\n\nexport const CreateNewDatabaseInPool: ModalComponent<CreateDBInPoolSpecs> = ({ modalId, spec: { proposedName } }) => {\n    const modalRef = useRef<ModalRef>(null!);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const { ddPoolOptions, selectedPoolId, setSelectedPoolId, deploymentPools } = useDeploymentPoolDropdowns();\n\n    const onConfirm = useEvent(async () => {\n        const newMapping = await dispatch(createTableMapping(proposedName, selectedPoolId));\n        return modalRef.current.returnValue(newMapping);\n    });\n\n    return (\n        <Modal title={\"Add New Database\"} modalId={modalId} ref={modalRef}>\n            <div className={\"flex gap-8\"}>\n                <div>Select a deployment pool to create a new database in</div>\n                <div>\n                    <ContentDropdownMenuItem\n                        narrow\n                        onChange={(e) => setSelectedPoolId(e.target.value)}\n                        value={selectedPoolId ?? \"\"}>\n                        {ddPoolOptions}\n                    </ContentDropdownMenuItem>\n                </div>\n            </div>\n            <div className={cx(\"mt-8 flex justify-end gap-4\")}>\n                <ModalButton onClick={onConfirm} variant={\"primary\"}>\n                    {deploymentPools && deploymentPools?.length > 0 ? \"Add New Database\" : \"Clone\"}\n                </ModalButton>\n                <ModalButton onClick={() => modalRef.current.returnValue(false)}>Cancel</ModalButton>\n            </div>\n        </Modal>\n    );\n};\n","import React, { useCallback, useState } from \"react\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { ModalComponent } from \"..\";\nimport Modal from \"../Modal\";\n\ninterface DeleteAllRowsSpec {\n    tableName: string;\n}\n\nconst DeleteAllRows: ModalComponent<DeleteAllRowsSpec> = ({ modalId, spec: { tableName: name } }) => {\n    const [input, setInput] = useState(\"\");\n    const enabled = name === input;\n\n    const inputRef = useCallback((node: HTMLElement | null) => {\n        node?.focus();\n    }, []);\n\n    return (\n        <Modal\n            autoFocus={false}\n            title={\"Delete all rows?\"}\n            modalId={modalId}\n            buttons={[\n                { text: \"Delete\", clickActionCreator: () => modalReturn(true), variant: \"danger\", enabled },\n                { text: \"Cancel\", clickActionCreator: () => modalReturn(false) },\n            ]}>\n            <Text>\n                This action cannot be undone. This will permanently delete the all rows from the{\" \"}\n                <span className={\"font-mono font-semibold text-primary select-text\"}>{name}</span> table.\n            </Text>\n            <Text>\n                Please type <span className={\"font-mono font-semibold text-primary select-text\"}>{name}</span> to\n                confirm.\n            </Text>\n\n            <ContentTextInput\n                ref={inputRef}\n                className={\"w-full\"}\n                value={input}\n                onChange={(e: React.ChangeEvent<HTMLInputElement>) => setInput(e.target.value)}\n            />\n        </Modal>\n    );\n};\n\nexport default DeleteAllRows;\n","import {useState} from \"react\";\nimport {ColumnSpec, LiveObjectSingleColumn} from \"@/types\";\nimport {HeaderInfo} from \"@/components/tabs/database/types.ts\";\nimport {ModalComponent} from \"@/components/modals\";\nimport Modal, {ModalButtons} from \"@/components/modals/Modal.tsx\";\nimport {DropDown, InputLabel} from \"@/components/reusable/Forms.tsx\";\nimport {modalReturn} from \"@/controllers/modals.ts\";\n\ninterface EditColumnSpec {\n    info: HeaderInfo;\n    colSpec: ColumnSpec;\n}\n\nexport const EditColumn: ModalComponent<EditColumnSpec, ColumnSpec | undefined> = ({modalId, spec: {colSpec, info}}) => {\n    const [onDelete, setOnDelete] = useState<LiveObjectSingleColumn[\"on_delete\"]>((colSpec as LiveObjectSingleColumn).on_delete || \"set_null\");\n    const isSplit = !!info.table.options.meta?.currentTable.split;\n    const needsOnDelete = colSpec.type === \"liveObject\" && isSplit;\n\n    const modalButtons: ModalButtons = [\n        {\n            text: \"OK\",\n            variant: \"primary\",\n            defaultButton: true,\n            clickActionCreator: () => {\n                const newColSpec: ColumnSpec = {...colSpec};\n                if (needsOnDelete) {\n                    (newColSpec as LiveObjectSingleColumn).on_delete = onDelete;\n                }\n                return modalReturn(newColSpec);\n            },\n        },\n        { text: \"Cancel\", clickActionCreator: () => modalReturn(undefined) },\n    ];\n\n    return <Modal autoFocus={false} size={\"small\"} modalId={modalId} title={`Edit Column ${colSpec.name}`} buttons={modalButtons}>\n        {needsOnDelete && (\n            <InputLabel title={\"When the linked row is deleted:\"}>\n                <div className={\"flex items-baseline\"}>\n                    <DropDown value={onDelete} onChange={(e: any) => setOnDelete(e.target.value)}>\n                        <option value=\"set_null\">Set this column value to None</option>\n                        <option value=\"cascade\">Cascade: Delete this row</option>\n                        <option value=\"restrict\">Restrict: Raise an Exception and prevent the deletion</option>\n                    </DropDown>\n                </div>\n            </InputLabel>\n        )}\n    </Modal>;\n};\n\n","import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faMinus, faTrashAlt, faTrashCanUndo } from \"@fortawesome/pro-light-svg-icons\";\nimport { faPlus } from \"@fortawesome/pro-solid-svg-icons\";\nimport { ModalComponent } from \"@/components/modals\";\nimport Modal, { ModalRef } from \"@/components/modals/Modal.tsx\";\nimport { Button } from \"@/components/reusable/Button.tsx\";\nimport { Heading } from \"@/components/reusable/Text.tsx\";\nimport { MultiSelectDropDown, SingleSelectDropDown } from \"@/components/reusable/selectdropdown\";\nimport { SelectionItem } from \"@/components/reusable/selectdropdown/SelectDropDown.tsx\";\nimport { tableIndexIdentifier } from \"@/controllers/db.ts\";\nimport { confirm } from \"@/controllers/modals\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch, IndexTypes, Table, TableIndex } from \"@/types\";\nimport { createContextHook, useMemoiseObject } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback.ts\";\nimport { faArrowRotateLeft } from \"@fortawesome/pro-regular-svg-icons\";\n\ninterface TableIndexesModalSpec {\n    table: Table;\n}\ninterface TableIndexesSharedProps {\n    table: Table;\n}\n\ninterface IndexDraftState extends TableIndex {\n    edit?: \"add\" | \"remove\";\n    id: string;\n}\n\ntype StringSelectionItem = Omit<SelectionItem, \"value\"> & { value: string };\ntype IndexTypeSelectionItem = Omit<SelectionItem, \"value\"> & { value: IndexTypes; };\n\ntype TableIndexesContextValue = {\n    table: Table;\n\n    draftState: IndexDraftState[];\n    setDraftState: React.Dispatch<React.SetStateAction<IndexDraftState[]>>;\n\n    newIndexType: IndexTypes | null;\n    indexingColumns: string[];\n\n    indexableColTypesItems: IndexTypeSelectionItem[];\n    indexableCols: StringSelectionItem[];\n\n    onChangeNewIndexType: (v: IndexTypes) => void;\n    onChangeSingleCol: (v: string | null) => void;\n    onChangeMultiCols: (v: string[]) => void;\n\n    onClickAddIndex: () => void;\n    onClickRemoveIndex: (tableIndex: TableIndex) => void;\n\n    clearForm: () => void;\n\n    colNameFromId: (colId: string) => string;\n    flashIndex: { id: string; token: number } | null;\n\n    edits: {\n        changes: {\n            toRemove: TableIndex[];\n            toAdd: TableIndex[];\n        };\n        hasDifferences: boolean;\n    };\n};\n\nconst useFlashIndexRow = (\n    indexKey: string,\n    shouldFlash: boolean,\n    token: number | undefined,\n    ref: React.RefObject<HTMLDivElement>\n) => {\n    useEffect(() => {\n        if (!shouldFlash || token == null) return;\n\n        const div = ref.current;\n        if (!div) return;\n\n        const flash = div.animate(\n            { backgroundColor: [\"rgba(250, 204, 21, 0.6)\", \"\"] },\n            { duration: 1500, easing: \"ease-out\" }\n        );\n\n        flash.play();\n\n        return () => flash.cancel();\n    }, [shouldFlash, token, indexKey, ref]);\n};\n\nconst colTypeToReadableNameLookup = {\n    b_tree: \"Lookup and Range queries\",\n    trigram: \"Pattern matching\",\n    full_text: \"Full-text search\",\n};\n\nconst indexDraftStatetoTableIndex = ({ type, columns }: IndexDraftState): TableIndex => ({\n    type,\n    columns,\n});\n\nconst useTableIndexes = ({ table }: TableIndexesSharedProps) => {\n    const { all_indexes, columns, split } = table;\n    const [flashIndex, setFlashIndex] = useState<{ id: string; token: number } | null>(null);\n\n    const [draftState, setDraftState] = useState<IndexDraftState[]>(() =>\n        all_indexes.map((index) => ({\n            ...index,\n            id: tableIndexIdentifier(index),\n        }))\n    );\n\n    const colNameFromId = (colId: string) => columns[colId].name;\n\n    const [newIndexType, setNewIndexType] = useState<IndexTypes | null>(null);\n\n    const [indexingColumns, setIndexingColumns] = useState<string[]>([]);\n\n\n    const bTreeTypes = useMemo(() => {\n        const type = [\"string\", \"number\", \"date\", \"datetime\"];\n        if (split) type.push(\"liveObject\", \"liveObjectArray\");\n        return type;\n    }, [split]);\n\n    const indexableColTypesItems = useMemo<IndexTypeSelectionItem[]>(() => {\n        const availableTypes: IndexTypes[] = [];\n\n        const types: Partial<Record<Table[\"columns\"][string][\"type\"], true>> = {};\n        for (const columnId of indexingColumns) {\n            types[columns[columnId].type] = true;\n        }\n\n        const selectedTypes = Object.keys(types);\n        if (selectedTypes.length === 0) return [];\n        if (types.liveObjectArray && indexingColumns.length > 1) return [];\n\n        if (selectedTypes.every((type) => bTreeTypes.includes(type))) {\n            availableTypes.push(\"b_tree\");\n        }\n        if (indexingColumns.length === 1 && selectedTypes.every((type) => type === \"string\")) {\n            availableTypes.push(\"trigram\", \"full_text\");\n        }\n\n        return availableTypes.map((value) => ({\n            value,\n            display: (\n                <div className={\"grid grid-cols-2 gap-4\"} key={value}>\n                    <div>{colTypeToReadableNameLookup[value]}</div>\n                    <div>({value})</div>\n                </div>\n            ),\n        }));\n    }, [bTreeTypes, columns, indexingColumns]);\n\n    const onChangeNewIndexType = useEvent((v: IndexTypes) => {\n        if (newIndexType === v) return;\n        setNewIndexType(v);\n    });\n\n    const indexableCols = useMemo(() => {\n        const c: StringSelectionItem[] = [];\n        Object.entries(columns).forEach(([colId, { type, name }]) => {\n            if (bTreeTypes.includes(type)) c.push({ value: colId, display: name });\n        });\n        return c;\n    }, [bTreeTypes, columns]);\n\n    const onChangeSingleCol = useEvent((v: string | null) => {\n        setIndexingColumns(v ? [v] : []);\n        setNewIndexType(null);\n    });\n\n    const onChangeMultiCols = useEvent((v: string[]) => {\n        setIndexingColumns(v);\n        setNewIndexType(null);\n    });\n\n    const clearForm = useEvent(() => {\n        setIndexingColumns([]);\n        setNewIndexType(null);\n    });\n\n    const onClickAddIndex = useEvent(() => {\n        if (!newIndexType || indexingColumns.length < 1) return;\n\n        const newIndex: TableIndex = { type: newIndexType, columns: indexingColumns };\n        const id = tableIndexIdentifier(newIndex);\n\n        setFlashIndex({ id, token: Date.now() });\n        setDraftState((prev) => {\n            const existingIndex = prev.find((draftIndex) => draftIndex.id === id);\n            if (!existingIndex) {\n                return [\n                    {\n                        ...newIndex,\n                        id,\n                        edit: \"add\",\n                    },\n                    ...prev,\n                ];\n            }\n\n            return prev.map((draftIndex) => {\n                if (draftIndex.id !== id) return draftIndex;\n\n                switch (draftIndex.edit) {\n                    case \"remove\": {\n                        const { edit, ...rest } = draftIndex;\n                        return rest;\n                    }\n\n                    case \"add\":\n                    default:\n                        return draftIndex;\n                }\n            });\n        });\n\n        clearForm();\n    });\n\n    const onClickRemoveIndex = useEvent((tableIndex: TableIndex) => {\n        setDraftState((prev) => {\n            const id = tableIndexIdentifier(tableIndex);\n\n            return prev.flatMap((draftIndex) => {\n                if (draftIndex.id !== id) return [draftIndex];\n\n                switch (draftIndex.edit) {\n                    case \"add\":\n                        // Newly added index: delete it from draft state.\n                        return [];\n\n                    case \"remove\": {\n                        // Already marked for removal: unmark it.\n                        const { edit, ...rest } = draftIndex;\n                        return [rest];\n                    }\n\n                    default:\n                        // Existing index: mark it for removal.\n                        return [{ ...draftIndex, edit: \"remove\" }];\n                }\n            });\n        });\n    });\n\n    const edits = useMemo(() => {\n        const toRemove = draftState.filter((i) => i.edit === \"remove\").map(indexDraftStatetoTableIndex);\n        const toAdd = draftState.filter((i) => i.edit === \"add\").map(indexDraftStatetoTableIndex);\n\n        return { changes: { toRemove, toAdd }, hasDifferences: toRemove.length > 0 || toAdd.length > 0 };\n    }, [draftState]);\n\n    return {\n        colNameFromId,\n        onClickRemoveIndex,\n        onClickAddIndex,\n        onChangeMultiCols,\n        onChangeSingleCol,\n        indexableCols,\n        onChangeNewIndexType,\n        indexableColTypesItems,\n        newIndexType,\n        indexingColumns,\n        clearForm,\n        draftState,\n        setDraftState,\n        flashIndex,\n        edits,\n    };\n};\n\nconst TableIndexesContext = React.createContext<TableIndexesContextValue | null>(null);\n\nexport const useTableIndexesContext = createContextHook(TableIndexesContext, \"TableIndexesContext\");\n\nconst TableIndexesProvider = ({\n    table,\n    children,\n}: TableIndexesModalSpec & { children: React.ReactNode }) => {\n\n    const tableIndexes = useTableIndexes({\n        table\n    });\n\n    const value = useMemoiseObject<TableIndexesContextValue>({\n        table,\n        ...tableIndexes,\n    });\n\n    return <TableIndexesContext.Provider value={value}>{children}</TableIndexesContext.Provider>;\n};\n\nconst NewIndexForm = ({ split }: { split: boolean }) => {\n    const {\n        indexableColTypesItems,\n        indexableCols,\n        newIndexType,\n        indexingColumns,\n        onChangeNewIndexType,\n        onChangeSingleCol,\n        onChangeMultiCols,\n        onClickAddIndex,\n        clearForm,\n    } = useTableIndexesContext();\n\n    return (\n        <div className={\"flex flex-col gap-4\"}>\n            <div>Create a new index</div>\n            <div>\n                {split ? (\n                    <MultiSelectDropDown\n                        onChange={onChangeMultiCols}\n                        selected={indexingColumns}\n                        items={indexableCols}\n                        className={\"w-full!\"}\n                        placeholder={\"Select Columns\"}\n                        explicitClose={true}\n                        orderMatters={true}\n                    />\n                ) : (\n                    <SingleSelectDropDown\n                        value={indexingColumns[0]}\n                        onChange={onChangeSingleCol ?? null}\n                        items={indexableCols}\n                        className={\"w-full!\"}\n                        placeholder={\"Select Column\"}\n                    />\n                )}\n\n            </div>\n\n            {indexingColumns.length > 0 && <div>\n                <SingleSelectDropDown\n                    items={indexableColTypesItems}\n                    value={newIndexType}\n                    className={\"w-full!\"}\n                    placeholder={\"Select type of index\"}\n                    onChange={onChangeNewIndexType}\n                    emptyItemsMessage={\"No indexes can be created with this combination of columns\"}\n                />\n            </div>}\n\n            <div className={\"flex justify-end gap-4\"}>\n                <Button\n                    disabled={!newIndexType}\n                    size={\"small\"}\n                    variant={\"primary\"}\n                    icon={faPlus}\n                    onClick={onClickAddIndex}>\n                    Add\n                </Button>\n                <Button size={\"small\"} variant={\"outlined\"} onClick={clearForm}>\n                    Cancel\n                </Button>\n            </div>\n        </div>\n    );\n};\n\ninterface ColumnNamePillProps {\n    colId: string;\n    identifierFn: (colId: string) => string;\n    toRemove: boolean;\n}\nconst ColumnNamePill = ({ colId, identifierFn, toRemove }: ColumnNamePillProps) => {\n    return (\n        <div\n            className={cx(\n                \"rounded border border-sectionborder bg-light-bg1 px-2 font-mono text-lg dark:border-dark-sectionborder dark:bg-dark-bg4\",\n                { \"opacity-30\": toRemove }\n            )}>\n            {identifierFn(colId)}\n        </div>\n    );\n};\n\nconst TableIndexRow = ({ tableIndex }: { tableIndex: IndexDraftState }) => {\n    const { colNameFromId, onClickRemoveIndex, flashIndex } = useTableIndexesContext();\n    const rowRef = useRef<HTMLDivElement>(null!);\n    const { edit, type, columns } = tableIndex;\n\n    const toRemove = edit === \"remove\";\n    const toAdd = edit === \"add\";\n\n    useFlashIndexRow(tableIndex.id, flashIndex?.id === tableIndex.id, flashIndex?.token, rowRef);\n\n    const icon = toAdd ? faArrowRotateLeft : toRemove ? faTrashCanUndo : faTrashAlt;\n    const text = toAdd ? \"Undo\" : toRemove ? \"Undo Delete\" : \"Delete\";\n\n    return (\n        <div\n            ref={rowRef}\n            className={cx(\n                \"flex items-center justify-between gap-4 border-b border-sectionborder px-4 last:border-b-0 odd:bg-light-bg2 dark:border-dark-sectionborder odd:dark:bg-dark-bg2\",\n                { \"bg-notice odd:bg-notice dark:bg-notice-dark dark:odd:bg-notice-dark\": toAdd },\n                { \"bg-danger-light odd:bg-danger-light dark:bg-danger-dark dark:odd:bg-danger-dark\": toRemove }\n            )}>\n            <div className={cx(\"grow\")}>\n                <div className={\"flex flex-wrap items-center gap-x-4 gap-y-1 pt-2\"}>\n                    {columns.map((colId) => (\n                        <ColumnNamePill colId={colId} identifierFn={colNameFromId} key={colId} toRemove={toRemove} />\n                    ))}\n                </div>\n                <div className={cx(\"pl-8\", { \"opacity-30\": toRemove })}>{colTypeToReadableNameLookup[type]}</div>\n            </div>\n            <Button\n                className={cx(\"grow-0\")}\n                onClick={() => onClickRemoveIndex(tableIndex)}\n                icon={icon}\n                variants={[\"danger\", \"outlined\"]}\n                tiny>\n                {text}\n            </Button>\n        </div>\n    );\n};\n\nconst ExistingIndexes = () => {\n    const { draftState } = useTableIndexesContext();\n    return (\n        <div className={\"overflow-hidden rounded border border-sectionborder dark:border-dark-sectionborder\"}>\n            {draftState.map((i) => (\n                <TableIndexRow key={i.id} tableIndex={i} />\n            ))}\n        </div>\n    );\n};\n\nconst TableIndexesModalBody = ({ modalId }: { modalId: number }) => {\n    const { draftState, edits, table } = useTableIndexesContext();\n    const dispatch = useDispatch<AnvilDispatch>();\n    const modalRef = useRef<ModalRef>(null!);\n\n    const onCancelClick = useEvent(async () => {\n        if (!edits.hasDifferences) return modalRef.current.returnValue(false);\n        if (await dispatch(confirm(\"Discard changes?\", \"There are unsaved changes to the indexes of this table. Discard these changes?\"))) {\n            modalRef.current.returnValue(false);\n        }\n    });\n\n    const changes = useMemo(() => {\n        const { toAdd, toRemove } = edits.changes;\n\n        const toAddNum = toAdd.length;\n        const toRemoveNum = toRemove.length;\n\n        const actions = [\n            toAddNum > 0 && `add ${toAddNum} ${toAddNum === 1 ? \"index\" : \"indexes\"}`,\n            toRemoveNum > 0 && `remove ${toRemoveNum} ${toRemoveNum === 1 ? \"index\" : \"indexes\"}`,\n        ].filter(Boolean);\n\n        return <div className={\"pl-8 pb-4\"}>\n            {actions.length > 0 && `You are about to ${actions.join(\" and \")}.`}\n\n        </div>;\n    }, [edits.changes]);\n\n    return (\n        <Modal ref={modalRef} title={\"Table indexes\"} modalId={modalId} allowDismiss={false} size={\"small\"}\n            buttons={[\n                {\n                    text: \"Apply changes\",\n                    returns: edits.changes,\n                    enabled: edits.hasDifferences,\n                    variant: \"primary\"\n                },\n                {\n                    text: \"Cancel\",\n                    clickActionCreator: onCancelClick,\n                    close: false,\n                },\n            ]}>\n            <NewIndexForm split={!!table.split} />\n\n            {draftState?.length > 0 && (\n                <>\n                    <hr />\n                    <Heading level={2}>Pending Changes: {edits.changes.toAdd.length + edits.changes.toRemove.length}</Heading>\n                    {changes}\n                    <ExistingIndexes />\n                </>\n            )}\n            <hr />\n            {edits.hasDifferences && <div className={\"font-semibold text-[1.2rem] !text-danger\"}>\n                Updating indexes may take some time\n                {table.split ? \"\" : \", and will block all writes to your tables until complete\"}.\n            </div>\n            }\n        </Modal>\n    );\n};\n\nconst TableIndexes: ModalComponent<TableIndexesModalSpec> = ({ modalId, spec }) => {\n    return (\n        <TableIndexesProvider {...spec}>\n            <TableIndexesModalBody modalId={modalId} />\n        </TableIndexesProvider>\n    );\n};\nexport default TableIndexes;\n","import React, { useEffect, useRef, useState } from \"react\";\nimport { faArrowsMinimize } from \"@fortawesome/pro-light-svg-icons\";\nimport { TextArea } from \"@/components/reusable/Forms\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { checkMeta } from \"@/util\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \"..\";\nimport Modal, { ModalRef } from \"../Modal\";\n\ninterface TextEditorSpec {\n    state: {\n        value: any;\n        selection: {\n            start: number | null;\n            end: number | null;\n        };\n    };\n}\n\nconst TextEditor: ModalComponent<TextEditorSpec> = ({ modalId, spec: { state } }) => {\n    const modalRef = useRef<ModalRef>(null!);\n    const [value, setValue] = useState(state.value ?? \"\");\n    const inputRef = useRef<HTMLTextAreaElement>(null);\n\n    useEffect(() => {\n        inputRef.current?.focus();\n        inputRef.current?.setSelectionRange(state.selection.start, state.selection.end);\n    }, []);\n\n    const onKeyDown: React.KeyboardEventHandler<HTMLTextAreaElement> = useEvent((e) => {\n        if (e.key === \"Enter\" && checkMeta(e)) {\n            modalRef.current.returnValue(true);\n            e.preventDefault();\n        }\n    });\n\n    return (\n        <Modal\n            modalId={modalId}\n            autoFocus={false}\n            ref={modalRef}\n            size=\"huge\"\n            title=\"Text Editor\"\n            closeIcon={faArrowsMinimize}\n            beforeClose={() => {\n                state.value = value;\n                state.selection = {\n                    start: inputRef.current?.selectionStart ?? null,\n                    end: inputRef.current?.selectionEnd ?? null,\n                };\n            }}\n            buttons={[\n                { text: \"Save Changes\", variant: \"primary\", clickActionCreator: () => modalReturn(value) },\n                { text: \"Discard Changes\", clickActionCreator: () => modalReturn(false) },\n            ]}>\n            <div className=\"h-[60vh]\">\n                <TextArea\n                    className=\"resize-none\"\n                    style={{ height: \"100%\" }}\n                    ref={inputRef}\n                    onKeyDown={onKeyDown}\n                    onChange={(e: any) => setValue(e.target.value)}\n                    value={value}\n                />\n            </div>\n        </Modal>\n    );\n};\n\nexport default TextEditor;\n","import React, { useCallback, useMemo, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faSync } from \"@fortawesome/free-solid-svg-icons/faSync\";\nimport { isEqual } from \"lodash-es\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport Link from \"@/components/reusable/Link\";\nimport { ModalButton, PublishLink } from \"@/components/reusable/SharedComponents\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { updateGlobalLoadingIndicator } from \"@/controllers/app\";\nimport {\n    getCustomDomainStatus,\n    getNewEnvironmentURL,\n    isSavedEnvironment,\n    markEnvironmentUnsaved,\n    saveEnvironment,\n} from \"@/controllers/environments\";\nimport { getUser } from \"@/controllers/ide\";\nimport { alert, confirm, modal, modalReturn } from \"@/controllers/modals\";\nimport { AnvilDispatch, AppEnvironment } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \"..\";\nimport Modal from \"../Modal\";\nimport { IDEModalType } from \"../names/ide-modals\";\nimport { useStyles } from \"./EnvironmentsModal\";\n\nexport const DNSRequiredNotification: ModalComponent = ({ modalId }) => {\n    return (\n        <Modal\n            className={\"select-text\"}\n            modalId={modalId}\n            allowDismiss={true}\n            title={\"DNS Configuration Required\"}\n            buttons={[{ text: \"OK\", clickActionCreator: () => modalReturn(true), defaultButton: true }]}>\n            <Text level={1}>\n                Create a DNS <code>A</code> record pointing your domain to{\" \"}\n                <code className=\"select-all\">52.56.203.177</code>.\n            </Text>\n\n            <Text level={1}>\n                Please allow up to 48 hours for DNS changes to propagate and TLS certificates to be set up.\n            </Text>\n\n            <Text level={1}>\n                For more tips on how to do this for some common domain registrars,{\" \"}\n                <HelpLink\n                    iconRight\n                    inline\n                    url={`${window.location.origin}/docs/deployment/choosing-urls#using-your-own-domain-name`}>\n                    see our DNS Guide\n                </HelpLink>\n            </Text>\n        </Modal>\n    );\n};\n\nconst sanitizeDomain = (url: string) => {\n    if (url.startsWith(\"https://\")) {\n        url = url.slice(8);\n    }\n    if (url.startsWith(\"http://\")) {\n        url = url.slice(7);\n    }\n    if (url.endsWith(\"/\")) {\n        url = url.slice(0, -1);\n    }\n    return url.toLowerCase();\n};\n\ninterface EnvUrlCommonProps {\n    env: AppEnvironment;\n    newUrl?: AppEnvironment[\"url\"];\n    errorMsg?: string;\n}\n\ntype UrlBuffer = NonNullable<AppEnvironment[\"url\"]>;\n\nconst useEnvUrlCommon = ({ env, newUrl, errorMsg }: EnvUrlCommonProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const [urlBuffer, setUrlBuffer] = useState<UrlBuffer>(() => newUrl || (env.url ? { ...env.url } : {}));\n    const [error, setError] = useState(errorMsg || null);\n\n    const onChange = useEvent((newUrlBuffer: UrlBuffer) => {\n        setError(null);\n        dispatch(markEnvironmentUnsaved(env));\n        setUrlBuffer(newUrlBuffer);\n    });\n    const onSave = useEvent(async (forceAlias?: string) => {\n        if (forceAlias) {\n            urlBuffer.alias = sanitizeDomain(forceAlias);\n            delete urlBuffer.domain;\n        } else if (urlBuffer.domain) {\n            urlBuffer.domain = sanitizeDomain(urlBuffer.domain);\n        }\n\n        if (!isEqual(urlBuffer, env.url) || env.$unsaved) {\n            const updatedEnv = await dispatch(saveEnvironment(env, { url: urlBuffer }));\n            if (isSavedEnvironment(updatedEnv) && updatedEnv.$saveError) {\n                return { error: updatedEnv.$saveError };\n            }\n        }\n        if (isEqual(urlBuffer, env.url)) {\n            return { newDomain: false };\n        }\n        return { success: true, savedURL: urlBuffer.alias || urlBuffer.domain };\n    });\n\n    const onCancel = useEvent(async () => {\n        if (!isEqual(urlBuffer, env.url) || env.$unsaved) {\n            // reset to original state\n            await dispatch(saveEnvironment(env, { url: env.$lastGood?.url || env.url }));\n        }\n        return modalReturn(false);\n    });\n\n    return { error, urlBuffer, onChange, onSave, onCancel };\n};\n\ninterface EnvUrlSpec {\n    env: AppEnvironment;\n    newUrl?: AppEnvironment[\"url\"];\n    errorMsg?: string;\n}\nexport const EnvUrlPublic: ModalComponent<EnvUrlSpec> = ({ modalId, type, spec: { env, newUrl, errorMsg } }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const user = useSelector(getUser);\n    const { classes } = useStyles();\n    const [saveClickable, setSaveClickable] = useState(true);\n    const { error, urlBuffer, onChange, onSave, onCancel } = useEnvUrlCommon({\n        env,\n        newUrl,\n        errorMsg,\n    });\n\n    const urlInputRef = useCallback((node: HTMLInputElement | null) => {\n        node?.focus();\n        node?.select();\n    }, []);\n\n    const handleSavePublicDomainButton = useEvent(async () => {\n        setSaveClickable(false);\n        const saved = await onSave();\n        if (saved.error) {\n            dispatch(modal(type as IDEModalType, { env, newUrl: urlBuffer, errorMsg: saved.error }));\n        }\n    });\n\n    const onGenerateNewUrl = useEvent(async () => {\n        const url = { ...urlBuffer, ...(await dispatch(getNewEnvironmentURL(\"public\"))) };\n        // Merge this in, just in case there's still a legacy access key we don't want to touch.\n        onChange(url);\n    });\n\n    return (\n        <Modal\n            title={\"Public URL\"}\n            autoFocus={false}\n            allowDismiss={false}\n            modalId={modalId}\n            buttons={[\n                {\n                    text: \"Save\",\n                    clickActionCreator: handleSavePublicDomainButton,\n                    variant: \"primary\",\n                    enabled: saveClickable,\n                },\n                { text: \"Cancel\", clickActionCreator: onCancel },\n            ]}>\n            <div className={classes.settingDescription}>Your app will be available at the following url:</div>\n            <PublishLink\n                preLink={user.ideConfig.appUrls?.[0]}\n                postLink={user.ideConfig.appUrls?.[1]}\n                alias={urlBuffer.alias || \"\"}\n                placeholder={\"Choose New URL\"}\n                ref={urlInputRef}\n                onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n                    onChange({ ...urlBuffer, alias: e.target.value?.toLowerCase() })\n                }\n                disableEsc={true}\n            />\n            {error && <div className=\"text-center text-danger italic\">{error}</div>}\n            <div style={{ textAlign: \"center\" }}>\n                <ModalButton onClick={onGenerateNewUrl} icon={faSync}>\n                    Generate New URL\n                </ModalButton>\n            </div>\n        </Modal>\n    );\n};\n\nconst ESCAPE_REGEX = /[.*+?^${}()|[\\]\\\\]/g;\nconst DNS_REGEX = /^(?!-)[A-Za-z0-9-]{1,63}(?<!-)(\\.[A-Za-z0-9-]{1,63})*(\\.[A-Za-z]{2,})$/;\nconst VALID_SUBDOMAIN_REGEX = /^[a-zA-Z0-9-]{1,63}$/;\n\nconst useCustomDomainValidation = () => {\n    const user = useSelector(getUser);\n    return useMemo(() => {\n        const preLink = user?.ideConfig?.appUrls?.[0] || \"\";\n        const postLink = user?.ideConfig?.appUrls?.[1] || \"\";\n\n        const escapedPostLink = postLink.replace(ESCAPE_REGEX, \"\\\\$&\");\n        const publicRegex = new RegExp(`^([a-zA-Z0-9-]{1,63})\\\\.${escapedPostLink}$`);\n\n        return { preLink, postLink, publicRegex };\n    }, [user]);\n};\n\nexport const EnvUrlCustom: ModalComponent<EnvUrlSpec> = ({ modalId, type, spec: { env, newUrl, errorMsg } }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { preLink, postLink, publicRegex } = useCustomDomainValidation();\n    const [saveClickable, setSaveClickable] = useState(true);\n    const { error, urlBuffer, onChange, onSave, onCancel } = useEnvUrlCommon({\n        env,\n        newUrl,\n        errorMsg,\n    });\n\n    const [underscoreError, setUnderscoreError] = useState(false);\n\n    const tryToSaveCustomDomain = useEvent(async () => {\n        const saved = await onSave();\n        if (saved.success) {\n            dispatch(updateGlobalLoadingIndicator(true));\n            let status;\n            try {\n                // this call can take a while so wrap it with a loading indicator\n                status = await dispatch(getCustomDomainStatus(urlBuffer.domain));\n            } finally {\n                dispatch(updateGlobalLoadingIndicator(false));\n            }\n\n            switch (status) {\n                case \"invalid\":\n                    //todo: make this a modal with a link to the docs\n                    dispatch(\n                        alert(\"Could not resolve Custom Domain\", \"The custom domain you entered could not be resolved.\")\n                    );\n                    break;\n                case \"dns-required\":\n                    dispatch(modal(\"dnsRequired\", {}));\n                    break;\n                case \"cert-required\":\n                    dispatch(\n                        alert(\n                            \"TLS Certificate Pending\",\n                            \"Your custom domain is being configured. TLS certificates can take up to 48 hours to be set up.\"\n                        )\n                    );\n                    break;\n                case \"configured\":\n                    dispatch(\n                        alert(\n                            \"Custom Domain Configured\",\n                            \"Your custom domain has been successfully configured. DNS changes are complete and TLS certificates have been set up.\"\n                        )\n                    );\n                    break;\n            }\n        } else if (saved.error) {\n            dispatch(modal(type as IDEModalType, { env, newUrl: urlBuffer, errorMsg: saved.error }));\n        }\n    });\n\n    const handleSaveCustomDomainButton = useEvent(async () => {\n        setSaveClickable(false);\n\n        const validDNS = urlBuffer.domain?.match(DNS_REGEX);\n        if (validDNS) {\n            if (!preLink) {\n                const shouldBePublic = urlBuffer.domain?.match(publicRegex);\n                if (shouldBePublic) {\n                    const subdomain = shouldBePublic[1];\n                    const saved = await onSave(subdomain);\n                    if (saved.error) {\n                        dispatch(modal(type as IDEModalType, { env, newUrl: urlBuffer, errorMsg: saved.error }));\n                    }\n                    return;\n                }\n            }\n            tryToSaveCustomDomain();\n        } else {\n            if (urlBuffer.domain && VALID_SUBDOMAIN_REGEX.test(urlBuffer.domain)) {\n                if (\n                    await dispatch(\n                        confirm(\n                            `Did you mean ${preLink}${urlBuffer.domain}${postLink}?`,\n                            `${urlBuffer.domain} is not a valid domain. Would you like to publish this environment as a public link at ${preLink}${urlBuffer.domain}${postLink}?`\n                        )\n                    )\n                ) {\n                    dispatch(modal(\"envURLpublic\", { env, newUrl: { alias: urlBuffer.domain } }));\n                    return;\n                } else {\n                    const saved = await onSave();\n                    if (saved.error) {\n                        dispatch(modal(type as IDEModalType, { env, newUrl: urlBuffer, errorMsg: saved.error }));\n                    }\n                }\n            } else {\n                const saved = await onSave();\n                if (saved.error) {\n                    dispatch(modal(type as IDEModalType, { env, newUrl: urlBuffer, errorMsg: saved.error }));\n                }\n            }\n        }\n    });\n\n    if (!env.url && !env.$unsaved) {\n        dispatch(markEnvironmentUnsaved(env));\n    }\n\n    const _onChange = useEvent((e: React.ChangeEvent<HTMLInputElement>) => {\n        setUnderscoreError(false);\n        setSaveClickable(true);\n\n        const newUrl = e.target.value;\n        if (newUrl?.includes(\"_\")) {\n            setUnderscoreError(true);\n            setSaveClickable(false);\n        }\n        onChange({ ...urlBuffer, domain: newUrl });\n    });\n\n    return (\n        <Modal\n            title={\"Custom Domain\"}\n            allowDismiss={false}\n            modalId={modalId}\n            buttons={[\n                {\n                    text: \"Save\",\n                    clickActionCreator: handleSaveCustomDomainButton,\n                    variant: \"primary\",\n                    enabled: saveClickable,\n                },\n                { text: \"Cancel\", clickActionCreator: onCancel },\n            ]}>\n            <Text level={2}>\n                Your domain should be configured according to our{\" \"}\n                <Link to={\"https://anvil.works/docs/deployment/custom-domains\"} target={\"_blank\"}>\n                    DNS Setup Guide\n                </Link>{\" \"}\n                before entering it here.\n            </Text>\n            <div>\n                <PublishLink\n                    alias={urlBuffer?.domain || \"\"}\n                    placeholder={\"Enter your custom domain\"}\n                    onChange={_onChange}\n                    disableEsc={true}\n                />\n            </div>\n            {error && <div className=\"text-center text-danger italic\">{error}</div>}\n            {underscoreError && (\n                <div>\n                    <div className=\"text-danger italic\">\n                        <div>Domain names may not contain underscores</div>\n                        <div>Anvil's TLS provider will not issue certificates for domains containing underscores.</div>\n                    </div>\n                </div>\n            )}\n        </Modal>\n    );\n};\n","import React, { useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faGithub } from \"@fortawesome/free-brands-svg-icons/faGithub\";\nimport TextInput from \"@/components/reusable/TextInput\";\nimport { getGitRemotes } from \"@/controllers/app/remotes\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport { getFeatureSupport } from \"@/util/features\";\nimport { ModalComponent } from \"..\";\nimport Modal from \"../Modal\";\n\ntype AddHTTPRemoteResult = {\n    name: string;\n    url: string;\n} & (\n    | {\n          username: string;\n          password: string;\n      }\n    | {\n          username?: undefined;\n          password?: undefined;\n      }\n);\n\nconst PrivateRepoError = () => (\n    <div>\n        Anvil will connect to this remote anonymously. Upgrade to the Business Plan to allow username and password\n        authentication to access private repositories.\n    </div>\n);\n\nconst connector = connect((state: State) => ({\n    remotes: getGitRemotes(state),\n    allowPrivate: getFeatureSupport(state, \"private-git-remotes\"),\n}));\n\ntype AddHTTPRemoteProps = AnvilConnectedProps<typeof connector>;\n\nconst AddHTTPRemote: ModalComponent<never, AddHTTPRemoteResult, AddHTTPRemoteProps> = ({\n    modalId,\n    remotes,\n    allowPrivate,\n}) => {\n\n    const [name, setName] = useState(\"origin\" in remotes ? \"\" : \"origin\");\n    const [url, setUrl] = useState<string | undefined>(undefined);\n    const [username, setUsername] = useState<string | undefined>(undefined);\n    const [password, setPassword] = useState<string | undefined>(undefined);\n\n    return (\n        <Modal\n            modalId={modalId}\n            title=\"Add Git Remote\"\n            icon={faGithub}\n            size=\"medium\"\n            buttons={[\n                {\n                    text: \"Add\",\n                    clickActionCreator: () =>\n                        modalReturn(\n                            username && password ? { name, url: url!, username, password } : { name, url: url! }\n                        ),\n                    defaultButton: true,\n                    enabled: !!(\n                        url &&\n                        ((!username && !password) || (username && password)) &&\n                        name &&\n                        !(name in remotes)\n                    ),\n                },\n                { text: \"Cancel\", close: true },\n            ]}>\n            <div>\n                <TextInput\n                    title={\"Name\"}\n                    description={\"The name of this remote\"}\n                    placeholder={\"Name\"}\n                    initialValue={name}\n                    onChange={setName}\n                />\n                <TextInput\n                    title={\"URL\"}\n                    description={\"The URL of the git remote to add\"}\n                    placeholder={\"https://...\"}\n                    initialValue={url}\n                    onChange={setUrl}\n                />\n                {allowPrivate ? (\n                    <>\n                        <TextInput\n                            title={\"Username\"}\n                            description={\"The username to connect with\"}\n                            placeholder={\"Username\"}\n                            initialValue={username}\n                            onChange={setUsername}\n                        />\n                        <TextInput\n                            title={\"Password\"}\n                            description={\"The password to connect with\"}\n                            placeholder={\"Password\"}\n                            initialValue={password}\n                            inputType={\"password\"}\n                            onChange={setPassword}\n                        />\n                    </>\n                ) : (\n                    <PrivateRepoError />\n                )}\n                {/* TODO: Error if name in remotes */}\n            </div>\n        </Modal>\n    );\n};\n\nexport default connector(AddHTTPRemote) as typeof AddHTTPRemote;\n","import React, { useCallback, useMemo, useRef, useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faGithub } from \"@fortawesome/free-brands-svg-icons/faGithub\";\nimport { faExternalLink } from \"@fortawesome/pro-light-svg-icons/faExternalLink\";\nimport { faCheck } from \"@fortawesome/pro-regular-svg-icons/faCheck\";\nimport { faExclamationTriangle } from \"@fortawesome/pro-regular-svg-icons/faExclamationTriangle\";\nimport { faRotate } from \"@fortawesome/pro-regular-svg-icons/faRotate\";\nimport { faLinkSlash } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { ButtonGroup } from \"@/components/reusable/ButtonGroup\";\nimport { InputLabel } from \"@/components/reusable/Forms\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport TextInput from \"@/components/reusable/TextInput\";\nimport {\n    ensureGithubConnection,\n    getGithubConnection,\n    installGithubApp,\n    loadGithubConnection,\n    promptAndMaybeDisconnectGitHubAccount,\n} from \"@/controllers/app/remotes\";\nimport { alert, modalReturn } from \"@/controllers/modals\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport type { GithubConnection, GithubInstallation, GithubRepository } from \"@/types/app-remotes\";\nimport { getFeatureSupport } from \"@/util/features\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \"..\";\nimport Modal, { ModalRef } from \"../Modal\";\n\ntype GitCloneAppResult = {\n    url?: string;\n    creds: { type: \"anonymous\" } | { type: \"github\" } | { type: \"http-basic\"; username: string; password: string };\n};\n\nconst getRepo = (conn: GithubConnection | null, url?: string) =>\n    conn?.repositories.find(({ html_url }: GithubRepository) => !!url && html_url === url.replace(/\\.git$/, \"\"));\n\nconst PrivateRepoError = () => (\n    <div>\n        <FontAwesomeIcon icon={faExclamationTriangle} className={\"text-danger\"} /> Upgrade to the Business Plan to clone\n        from private git repositories\n    </div>\n);\n\nconst githubAuthConnector = connect((state: State) => ({\n    conn: getGithubConnection(state),\n}));\n\ntype GithubAuthProps = AnvilConnectedProps<typeof githubAuthConnector> & {\n    url?: string;\n    allowPrivate: boolean;\n};\n\nlet GithubAuth = githubAuthConnector(({ url, conn, allowPrivate, dispatch }: GithubAuthProps) => {\n    const githubRepo = useMemo(() => getRepo(conn, url), [conn, url]);\n\n    const managePermissions = useCallback(() => {\n        // TODO: Spot enterprise hostname. It's already in conn.\n        let targetId = null;\n        const match = /https:\\/\\/github.com\\/(.*?)\\/.*/.exec(url ?? \"\");\n        if (match) {\n            const [_, accountName] = match;\n            targetId = conn?.installations.find(({ account: { login } }) => login === accountName)?.account.id;\n        }\n        dispatch(installGithubApp(targetId));\n    }, [conn, url]);\n\n    return (\n        <div>\n            {conn ? (\n                <div>\n                    <div>\n                        You are logged in to Github as{\" \"}\n                        <span className={\"font-mono font-semibold\"}>{conn.user.login}</span>\n                        {conn?.user?.name && ` (${conn.user.name})`}.\n                    </div>\n                    {url &&\n                        (githubRepo ? (\n                            allowPrivate || githubRepo.visibility === \"public\" ? (\n                                <div>\n                                    <FontAwesomeIcon icon={faCheck} className={\"text-highlight\"} /> This repository is\n                                    authorized\n                                </div>\n                            ) : (\n                                <PrivateRepoError />\n                            )\n                        ) : (\n                            <div className={\"flex items-center gap-2\"}>\n                                <FontAwesomeIcon icon={faExclamationTriangle} className={\"text-danger\"} />\n                                Not authorized.\n                                <Button small variant={\"secondary\"} icon={faExternalLink} onClick={managePermissions}>\n                                    Manage GitHub Permissions\n                                </Button>\n                                <Button small icon={faRotate} onClick={() => dispatch(loadGithubConnection())}>\n                                    Re-check Permissions\n                                </Button>\n                            </div>\n                        ))}\n                </div>\n            ) : (\n                <Button variant={\"secondary\"} icon={faGithub} onClick={() => dispatch(ensureGithubConnection())}>\n                    Connect to GitHub\n                </Button>\n            )}\n        </div>\n    );\n});\n\nconst connector = connect((state: State) => ({\n    conn: getGithubConnection(state),\n    allowPrivate: !!getFeatureSupport(state, \"private-git-remotes\"),\n}));\n\ntype GitCloneAppProps = AnvilConnectedProps<typeof connector>;\n\nconst GitCloneApp: ModalComponent<never, GitCloneAppResult | null, GitCloneAppProps> = ({\n    modalId,\n    conn,\n    allowPrivate,\n    dispatch,\n}) => {\n    const modal = useRef<ModalRef>(null);\n\n    const [url, _setUrl] = useState<string>();\n    const [username, setUsername] = useState(\"\");\n    const [password, setPassword] = useState(\"\");\n\n    const authOptions = useMemo(\n        () =>\n            [\n                { title: \"Anonymous\", value: \"anonymous\" },\n                { title: \"Github Account\", value: \"github\" },\n                { title: \"Username & Password\", value: \"http-basic\" },\n            ] as const,\n        []\n    );\n\n    const [selectedAuth, setSelectedAuth] = useState<(typeof authOptions)[number][\"value\"]>(\"anonymous\");\n\n    const setUrl = useCallback(\n        (url: string) => {\n            _setUrl(url);\n            // If the repo belongs to an account where Anvil is already installed, suggest using Github\n            if (getRepo(conn, url) && selectedAuth === \"anonymous\") {\n                setSelectedAuth(\"github\");\n            }\n        },\n        [conn, selectedAuth]\n    );\n\n    const creds = useMemo(() => {\n        switch (selectedAuth) {\n            case \"anonymous\":\n                return { type: \"anonymous\" };\n            case \"github\":\n                return { type: \"github\" };\n            case \"http-basic\":\n                return { type: \"http-basic\", username, password };\n        }\n    }, [selectedAuth, username, password]);\n\n    const githubRepo = useMemo(() => (url && conn ? getRepo(conn, url) : undefined), [conn, url]);\n    const publicRepo = useMemo(\n        () => selectedAuth === \"anonymous\" || (selectedAuth === \"github\" && githubRepo?.visibility === \"public\"),\n        [selectedAuth, githubRepo]\n    );\n    const enableClone = url && (allowPrivate || publicRepo);\n\n    const onHandleDisconnectClick = useEvent(async () => {\n        const { error, cancelled } = await dispatch(promptAndMaybeDisconnectGitHubAccount());\n        if (cancelled) return;\n        if (error) {\n            dispatch(alert(\"Failed to disconnect GitHub account\", `${error}   \\nPlease contact support@anvil.works`));\n        }\n    });\n\n    return (\n        <Modal\n            modalId={modalId}\n            ref={modal}\n            title={`Clone App from Git`}\n            icon={faGithub}\n            size=\"medium\"\n            buttons={[\n                {\n                    text: \"Cancel\",\n                    clickActionCreator: () => modalReturn(null),\n                },\n                {\n                    text: \"Clone App\",\n                    defaultButton: true,\n                    variant: \"primary\",\n                    clickActionCreator: () => modalReturn({ url, creds }),\n                    enabled: !!enableClone,\n                },\n            ]}\n            leftButtons={\n                selectedAuth === \"github\" &&\n                conn && (\n                    <LinkInternal className={\"text-danger\"} onClick={onHandleDisconnectClick}>\n                        <FontAwesomeIcon icon={faLinkSlash} className={\"mr-2\"} />\n                        Disconnect GitHub Account\n                    </LinkInternal>\n                )\n            }>\n            <TextInput\n                title={\"Git URL\"}\n                description={\"The URL of the git repository to clone\"}\n                placeholder={\"https://...\"}\n                initialValue={url}\n                onChange={setUrl}\n            />\n\n            <InputLabel title={\"Authentication\"} subtitle={\"How would you like to authenticate?\"}>\n                <ButtonGroup\n                    options={authOptions}\n                    selectedVariant={\"primary\"}\n                    selectedOption={selectedAuth}\n                    onClick={setSelectedAuth}\n                />\n            </InputLabel>\n\n            <div className={\"my-6\"}>\n                {selectedAuth === \"anonymous\" && (\n                    <div>You will not be able to push your changes back to the remote git repository</div>\n                )}\n                {selectedAuth === \"github\" && <GithubAuth url={url} allowPrivate={allowPrivate} />}\n                {selectedAuth === \"http-basic\" &&\n                    (allowPrivate ? (\n                        <>\n                            <TextInput\n                                title={\"Username\"}\n                                description={\"The username to connect with\"}\n                                placeholder={\"Username\"}\n                                initialValue={username}\n                                onChange={setUsername}\n                            />\n                            <TextInput\n                                title={\"Password\"}\n                                description={\"The password to connect with\"}\n                                placeholder={\"Password\"}\n                                initialValue={password}\n                                inputType={\"password\"}\n                                onChange={setPassword}\n                            />\n                        </>\n                    ) : (\n                        <PrivateRepoError />\n                    ))}\n            </div>\n        </Modal>\n    );\n};\n\nexport default connector(GitCloneApp) as typeof GitCloneApp;\n","import React, { useCallback, useRef } from \"react\";\nimport { connect, useSelector } from \"react-redux\";\nimport { faCodeBranch } from \"@fortawesome/pro-regular-svg-icons/faCodeBranch\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { createNewBranch, resetBranch } from \"@/controllers/app\";\nimport { getAppRefs } from \"@/controllers/app/history\";\nimport { forcePushRemote, getGitRemotes, mergeBranchIntoRemote } from \"@/controllers/app/remotes\";\nimport { getUser } from \"@/controllers/ide.ts\";\nimport { modal, modalReturn } from \"@/controllers/modals\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport { isUserGithubRemoteCreds } from \"@/types/app-remotes\";\nimport { ModalComponent } from \"..\";\nimport Modal, { ModalRef } from \"../Modal\";\n\nconst connector = connect((state: State) => ({\n    remotes: getGitRemotes(state),\n    appRefs: getAppRefs(state),\n}));\n\ntype GitDesyncSpec = {\n    branch: string;\n    remote: string;\n    sync: { status?: string; message?: string };\n};\n\nconst GitDesync: ModalComponent<GitDesyncSpec, boolean | null, AnvilConnectedProps<typeof connector>> = ({\n    modalId,\n    remotes,\n    appRefs,\n    dispatch,\n    spec: { branch, remote, sync },\n}) => {\n    const { email } = useSelector(getUser);\n    const modalRef = useRef<ModalRef>(null);\n    const remoteCreds = remotes[remote]?.creds;\n    const githubRemoteCreds = remoteCreds && isUserGithubRemoteCreds(remoteCreds) ? remoteCreds : null;\n    const remoteRef = (\n        <code className={\"bg-transparent! text-white!\"}>\n            {remote}/{branch}\n        </code>\n    );\n\n    const resetToRemote = useCallback(async () => {\n        console.log(branch, appRefs.remotes, remote);\n        await dispatch(resetBranch(branch, appRefs.remotes[`${remote}/${branch}`].commitId));\n        modalRef.current!.returnValue(true);\n    }, [branch, appRefs, remote]);\n\n    const mergeIntoRemote = useCallback(async () => {\n        modalRef.current!.returnValue(true);\n        await dispatch(mergeBranchIntoRemote(branch, remote));\n    }, [branch, appRefs, remote]);\n\n    const startNewBranch = useCallback(async () => {\n        const { commitId } = appRefs.branches[branch];\n        await dispatch(createNewBranch(commitId));\n        await dispatch(resetBranch(branch, appRefs.remotes[`${remote}/${branch}`].commitId, false));\n        modalRef.current!.returnValue(true);\n    }, [branch, appRefs]);\n\n    const forcePush = useCallback(async () => {\n        await dispatch(forcePushRemote(remote, `refs/heads/${branch}`));\n        modalRef.current!.returnValue(true);\n    }, [branch, appRefs, remote]);\n\n    const configureRemotes = useCallback(() => {\n        modalRef.current!.returnValue(false);\n        dispatch(modal(\"gitRemotes\", {}));\n    }, [remote]);\n\n    return (\n        <Modal\n            modalId={modalId}\n            ref={modalRef}\n            title={\"Branch out of sync\"}\n            icon={faCodeBranch}\n            size=\"medium\"\n            buttons={[\n                {\n                    text: \"Close\",\n                    clickActionCreator: () => modalReturn(null),\n                },\n            ]}>\n            {sync.status === \"REPO_FAIL\" ? (\n                <>\n                    <p>\n                        <b>\n                            We could not connect to the Git repository at <code>{remote}</code>:\n                        </b>\n                    </p>\n\n                    {sync.message && (\n                        <p className={\"text-danger\"}>\n                            <b>{sync.message}</b>\n                        </p>\n                    )}\n                    {githubRemoteCreds && githubRemoteCreds.user !== email ? (\n                        <>\n                            <p className={\"mt-8\"}>\n                                To resolve this problem, contact{\" \"}\n                                <span className={\"font-mono font-semibold\"}>{githubRemoteCreds.user}</span> to update\n                                the Git configuration for the <code>{remote}</code> repository.\n                            </p>\n\n                            <div className={\"my-2 block\"}>\n                                <Button variant={\"primary\"} onClick={configureRemotes}>\n                                    See Git remotes\n                                </Button>\n                            </div>\n                        </>\n                    ) : (\n                        <>\n                            <p className={\"mt-8\"}>\n                                To resolve this problem, update the Git configuration for the <code>{remote}</code>{\" \"}\n                                repository.\n                            </p>\n\n                            <div className={\"my-2 block\"}>\n                                <Button variant={\"primary\"} onClick={configureRemotes}>\n                                    Manage Git remotes\n                                </Button>\n                            </div>\n                        </>\n                    )}\n                </>\n            ) : (\n                <>\n                    <p>\n                        <b>\n                            The <code>{branch}</code> branch of this app is out of sync with the Git repository at{\" \"}\n                            <code>{remote}</code>.\n                        </b>\n                        This is probably because someone else has edited this branch at the same time as you.\n                    </p>\n\n                    <p>Choose an option to resolve this conflict:</p>\n\n                    <div className={\"my-2 block\"}>\n                        <h3 className={\"mt-10 mb-5 text-2xl font-bold\"}>Start a new branch</h3>\n                        <p>\n                            Start a new branch from your local changes to, and reset <code>{branch}</code> to upstream,\n                            so you can see both changes. <b>If you're not sure, do this.</b>\n                        </p>\n                        <Button className={\"mt-4\"} variant={\"primary\"} onClick={startNewBranch}>\n                            Start a new branch\n                        </Button>\n                    </div>\n                    <div className={\"my-2 block\"}>\n                        <h3 className={\"mt-10 mb-5 text-2xl font-bold\"}>Discard your local changes</h3>\n                        <p>\n                            Reset the <code>{branch}</code> branch to the remote version, discarding all your local\n                            changes.\n                        </p>\n                        <Button className={\"mt-4\"} variant={\"primary\"} onClick={resetToRemote}>\n                            Reset to remote\n                        </Button>\n                    </div>\n                    <div className={\"my-2 block\"}>\n                        <h3 className={\"mt-10 mb-5 text-2xl font-bold\"}>Discard remote changes</h3>\n                        <p>\n                            Try to overwrite the remote version with your local changes, discarding all remote changes.\n                        </p>\n                        <Button className={\"mt-4\"} variant={\"primary\"} onClick={forcePush}>\n                            Force push to {remoteRef}\n                        </Button>\n                    </div>\n                    <div className={\"my-2 block\"}>\n                        <h3 className={\"mt-10 mb-5 text-2xl font-bold\"}>Merge changes</h3>\n                        <p>\n                            Merge your local changes into {remote}'s version of {branch}. This may cause conflicts.\n                        </p>\n                        <Button className={\"mt-4\"} variant={\"primary\"} onClick={mergeIntoRemote}>\n                            Merge local changes into {remoteRef}\n                        </Button>\n                    </div>\n                </>\n            )}\n        </Modal>\n    );\n};\n\nexport default connector(GitDesync) as typeof GitDesync;\n","export interface RemoteCredsHttpBasic {\n    type: \"http-basic\";\n    username?: string;\n    password?: string;\n}\n\nexport interface RemoteCredsGithub {\n    type: \"github\";\n    accessToken: string;\n    refreshToken: string;\n}\n\nexport interface RemoteCredsUserGithub {\n    type: \"user-github\";\n    user: string;\n}\n\nexport interface RemoteCredsAnonymous {\n    type: \"anonymous\";\n}\n\nexport type RemoteCreds = RemoteCredsHttpBasic | RemoteCredsGithub | RemoteCredsUserGithub | RemoteCredsAnonymous;\n\nexport interface GithubConnectionUser {\n    id: number;\n    login: string;\n    name?: string;\n}\n\nexport interface GithubInstallation {\n    target_type: string;\n    target_id?: number;\n    account: {\n        id: number;\n        login: string;\n    };\n}\n\nexport interface GithubRepository {\n    html_url: string;\n    visibility?: string;\n}\n\nexport interface GithubConnection {\n    user: GithubConnectionUser;\n    installations: GithubInstallation[];\n    repositories: GithubRepository[];\n}\n\nexport interface RemoteSpec {\n    url: string;\n    creds: RemoteCreds;\n}\n\nexport interface AppRemotes {\n    [remote: string]: RemoteSpec;\n}\n\nexport const isUserGithubRemoteCreds = (creds: RemoteCreds): creds is RemoteCredsUserGithub =>\n    creds.type === \"user-github\";\n\nexport const getRemoteUser = (remote: RemoteSpec): string | undefined =>\n    isUserGithubRemoteCreds(remote.creds) ? remote.creds.user : undefined;\n","import { default as React, useCallback, useEffect, useMemo, useState } from \"react\";\nimport { connect, useDispatch, useSelector } from \"react-redux\";\nimport { faGithub } from \"@fortawesome/free-brands-svg-icons/faGithub\";\nimport { faChevronDown } from \"@fortawesome/pro-light-svg-icons\";\nimport { faPlus } from \"@fortawesome/pro-light-svg-icons/faPlus\";\nimport { faTrashAlt } from \"@fortawesome/pro-light-svg-icons/faTrashAlt\";\nimport { faTriangleExclamation } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faCheck } from \"@fortawesome/pro-regular-svg-icons/faCheck\";\nimport { faExclamationTriangle } from \"@fortawesome/pro-regular-svg-icons/faExclamationTriangle\";\nimport { faLink } from \"@fortawesome/pro-regular-svg-icons/faLink\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { EnvironmentHeaderTemplate } from \"@/components/modals/environments/EnvironmentHeaderTemplate\";\nimport { Accordion } from \"@/components/reusable/Accordion\";\nimport { Button } from \"@/components/reusable/Button\";\nimport DropdownMenu from \"@/components/reusable/DropdownMenu\";\nimport { Heading } from \"@/components/reusable/Text\";\nimport { resetBranch } from \"@/controllers/app\";\nimport { getAppRefs } from \"@/controllers/app/history\";\nimport {\n    addRemote,\n    connectToNewGithubRepo,\n    deleteRemote,\n    ensureGithubConnection,\n    forcePushRemote,\n    getGitRemotes,\n    getGithubConnection,\n    getGithubRemote,\n    loadGithubConnection,\n    mergeBranchIntoRemote,\n    pullAllRemotes,\n    reloadRemotes,\n    updateGithubCredentialsForRemote,\n} from \"@/controllers/app/remotes\";\nimport { getUser } from \"@/controllers/ide\";\nimport { confirm, modal } from \"@/controllers/modals\";\nimport type { AnvilConnectedProps, AnvilDispatch, State } from \"@/types\";\nimport type { AppRemotes } from \"@/types/app-remotes\";\nimport { getRemoteUser } from \"@/types/app-remotes\";\nimport { getFeatureSupport } from \"@/util/features\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \"..\";\nimport Modal from \"../Modal\";\n\ninterface OutOfSyncIndicatorAndActionsProps {\n    branch: string;\n    remote: string;\n}\nconst OutOfSyncIndicatorAndActions = ({ branch, remote }: OutOfSyncIndicatorAndActionsProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const refs = useSelector(getAppRefs);\n    const connected = !!useSelector(getGithubConnection);\n\n    const promptForReset = useEvent(async () => {\n        if (\n            await dispatch(\n                confirm(\n                    \"Discard your local changes\",\n                    <>\n                        Reset the <code>{branch}</code> branch to the remote version, discarding all your local changes.\n                    </>,\n                    `Reset to ${remote}/${branch}`,\n                    \"Cancel\"\n                )\n            )\n        ) {\n            await dispatch(resetBranch(branch, refs.remotes[`${remote}/${branch}`].commitId));\n        }\n    });\n    const promptForForcePush = useEvent(async () => {\n        if (\n            await dispatch(\n                confirm(\n                    \"Discard remote changes\",\n                    \"Try to overwrite the remote version with your local changes, discarding all remote changes.\",\n                    `Force push to ${remote}/${branch}`,\n                    \"Cancel\"\n                )\n            )\n        ) {\n            await dispatch(forcePushRemote(remote, `refs/heads/${branch}`));\n        }\n    });\n    const promptForMerge = useEvent(async () => {\n        if (\n            await dispatch(\n                confirm(\n                    \"Merge local changes\",\n                    \"Merge your local changes into the remote version.\",\n                    `Merge local changes into ${remote}/${branch}`,\n                    \"Cancel\"\n                )\n            )\n        ) {\n            await dispatch(mergeBranchIntoRemote(branch, remote));\n        }\n    });\n\n    return (\n        <div className={\"flex w-full items-center gap-5\"}>\n            <div className={\"min-w-max\"}>Out of sync</div>\n            {connected && (\n                <DropdownMenu\n                    render={(showMenu, anchor) => (\n                        <div className={\"w-full items-center\"}>\n                            <Button\n                                className={\"w-full\"}\n                                tiny\n                                iconRight\n                                icon={faChevronDown}\n                                onClick={(e) => showMenu(null, e.currentTarget)}>\n                                <div className={\"w-full\"}>Resolve this conflict</div>\n                            </Button>\n                            {anchor}\n                        </div>\n                    )}\n                    items={(selectItem, hideMenu) => [\n                        [\"Reset to remote\", promptForReset],\n                        [\"Force push to remote\", promptForForcePush],\n                        [\"Merge local changes\", promptForMerge],\n                    ]}\n                />\n            )}\n        </div>\n    );\n};\ntype RemoteAccordionItem = {\n    name: string;\n    url: string;\n    type: AppRemotes[string][\"creds\"][\"type\"];\n    gitHubUser?: string;\n};\n\ntype BranchSyncState = {\n    remoteSync?: Record<string, { status?: string; message?: string; \"synced?\"?: boolean }>;\n};\n\nconst connector = connect((state: State) => ({\n    remotesMap: getGitRemotes(state),\n    githubRemote: getGithubRemote(state),\n    refs: getAppRefs(state),\n    user: getUser(state),\n    allowPrivate: getFeatureSupport(state, \"private-git-remotes\"),\n}));\n\ntype GitRemotesProps = AnvilConnectedProps<typeof connector>;\n\nconst GitRemotes: ModalComponent<never, void, GitRemotesProps> = ({\n    modalId,\n    remotesMap,\n    githubRemote,\n    refs,\n    user,\n    allowPrivate,\n    dispatch,\n}) => {\n\n    useEffect(() => {\n        dispatch(loadGithubConnection());\n        dispatch(reloadRemotes());\n    }, []);\n\n    const [expandedRemotes, setExpandedRemotes] = useState<Record<string, boolean>>(() =>\n        Object.keys(remotesMap).length === 1 ? { [Object.keys(remotesMap)[0]]: true } : {}\n    );\n\n    const remotes = useMemo<RemoteAccordionItem[]>(\n        () =>\n            Object.entries(remotesMap).map(([name, { url, creds }]) => ({\n                name,\n                url,\n                type: creds.type,\n                gitHubUser: getRemoteUser(remotesMap[name]),\n            })),\n        [remotesMap]\n    );\n\n    const createGithubRemote = useCallback(() => {\n        dispatch(connectToNewGithubRepo());\n    }, []);\n\n    const addHttpRemote = useCallback(async () => {\n        const remote = await dispatch(modal(\"addHTTPRemote\", {}));\n        if (remote) {\n            const { name, url, username, password } = remote;\n            dispatch(\n                addRemote({\n                    name,\n                    url,\n                    creds: allowPrivate\n                        ? {\n                              type: \"http-basic\",\n                              username,\n                              password,\n                          }\n                        : { type: \"anonymous\" },\n                })\n            );\n        }\n    }, [allowPrivate]);\n\n    const onDelete = useCallback(async (remoteName: string) => {\n        if (\n            await dispatch(\n                confirm(\n                    \"Delete Remote?\",\n                    <span>\n                        Are you sure you want to delete remote <code>{remoteName}</code>?\n                    </span>\n                )\n            )\n        ) {\n            dispatch(deleteRemote(remoteName));\n        }\n    }, []);\n\n    const githubReconnect = useEvent(async (remoteName: string, gitHubUser?: string) => {\n        const conn = await dispatch(ensureGithubConnection());\n        if (!conn) {\n            //maybe show some kind of error\n            return;\n        }\n        if (gitHubUser !== user.email) {\n            await dispatch(updateGithubCredentialsForRemote(remoteName));\n        } else {\n            dispatch(pullAllRemotes());\n        }\n    });\n\n    const hasUnreachableRepoBranches = useCallback(\n        (repoName: string) => {\n            const branches = Object.values(refs.branches) as BranchSyncState[];\n            return branches.find((b) => b.remoteSync?.[repoName]?.status === \"REPO_FAIL\");\n        },\n        [refs.branches]\n    );\n\n    return (\n        <Modal\n            modalId={modalId}\n            title=\"Git Remotes\"\n            icon={faGithub}\n            size=\"medium\"\n            buttons={[{ text: \"Close\", close: true }]}>\n            <Accordion<RemoteAccordionItem>\n                items={remotes}\n                keyName={\"name\"}\n                expandedKeys={expandedRemotes}\n                renderHeader={({ name, url }) => (\n                    <EnvironmentHeaderTemplate\n                        title={name}\n                        subtitle={url}\n                        actions={expandedRemotes[name] && [[faTrashAlt, \"Delete\", () => onDelete(name)]]}\n                    />\n                )}\n                renderBody={({ name, type, gitHubUser }) => {\n                    return (\n                        <div className={\"p-8\"}>\n                            <Heading level={2}>Authentication</Heading>\n                            {type === \"http-basic\" && <div>Username and Password</div>}\n                            {type === \"user-github\" && (\n                                <>\n                                    <div className={\"text-4xl\"}>\n                                        <FontAwesomeIcon className={\"text-4xl\"} icon={faGithub} /> GitHub\n                                    </div>\n                                    {!!hasUnreachableRepoBranches(name) && (\n                                        <>\n                                            {gitHubUser === user.email ? (\n                                                <Button\n                                                    className=\"mt-4\"\n                                                    variant={\"secondary\"}\n                                                    icon={faGithub}\n                                                    onClick={() => githubReconnect(name, gitHubUser)}>\n                                                    Reconnect to GitHub\n                                                </Button>\n                                            ) : (\n                                                <div className={\"my-4 rounded-lg border-2 border-danger\"}>\n                                                    <div className={\"flex items-center\"}>\n                                                        <div className={\"p-8\"}>\n                                                            <FontAwesomeIcon\n                                                                className={\"text-6xl text-danger\"}\n                                                                icon={faTriangleExclamation}\n                                                            />\n                                                        </div>\n\n                                                        <div className={\"flex flex-col py-4 pt-4\"}>\n                                                            <div>\n                                                                This remote is currently configured to GitHub with the\n                                                                credentials of{\" \"}\n                                                                <span className={\"font-mono font-semibold\"}>\n                                                                    {gitHubUser}\n                                                                </span>\n                                                                . Contact them to reconnect the app or update the remote\n                                                                to use your own credentials.\n                                                            </div>\n\n                                                            <div className=\"my-2 flex grow items-center justify-center\">\n                                                                <Button\n                                                                    variant={\"secondary\"}\n                                                                    icon={faGithub}\n                                                                    onClick={() => githubReconnect(name, gitHubUser)}>\n                                                                    Use your own credentials\n                                                                </Button>\n                                                            </div>\n                                                        </div>\n                                                    </div>\n                                                </div>\n                                            )}\n                                        </>\n                                    )}\n                                </>\n                            )}\n                            {type === \"anonymous\" && <div>None</div>}\n\n                            <Heading level={2}>Branches</Heading>\n                            <div\n                                className={\n                                    \"grid grid-cols-[minmax(max-content,3fr)_auto] items-center gap-x-10 gap-y-4\"\n                                }>\n                                {Object.entries(refs.branches)\n                                    .sort((a, b) => a[0].localeCompare(b[0]))\n                                    .map(([refName, { remoteSync }]) => (\n                                        <React.Fragment key={refName}>\n                                            <div className=\"truncate font-mono font-semibold\" title={refName}>\n                                                {refName}\n                                            </div>\n                                            <div className={\"min-w-100\"}>\n                                                {remoteSync?.[name]?.[\"synced?\"] ? (\n                                                    <div className={\"flex w-full items-center gap-4\"}>\n                                                        <div>\n                                                            <FontAwesomeIcon\n                                                                className={\"text-highlight\"}\n                                                                icon={faCheck}\n                                                            />\n                                                        </div>\n                                                        <div>In sync</div>\n                                                    </div>\n                                                ) : (\n                                                    <div className={\"flex w-full items-center gap-4\"}>\n                                                        <div>\n                                                            <FontAwesomeIcon\n                                                                className={\"text-tertiary\"}\n                                                                icon={faExclamationTriangle}\n                                                            />\n                                                        </div>\n                                                        {remoteSync?.[name]?.message || (\n                                                            <OutOfSyncIndicatorAndActions\n                                                                branch={refName}\n                                                                remote={name}\n                                                            />\n                                                        )}\n                                                    </div>\n                                                )}\n                                            </div>\n                                        </React.Fragment>\n                                    ))}\n                            </div>\n                        </div>\n                    );\n                }}\n                onToggle={(itm) => setExpandedRemotes((s) => ({ [itm.name]: !s[itm.name] }))}\n            />\n\n            <div className={\"mt-8 text-center\"}>\n                <DropdownMenu\n                    render={(showMenu, anchor) => (\n                        <div className={\"inline-block\"}>\n                            <Button icon={faPlus} variant={\"primary\"} onClick={() => showMenu()}>\n                                Add new Remote\n                            </Button>\n                            {anchor}\n                        </div>\n                    )}\n                    items={(selectItem, hideMenu) => [\n                        !githubRemote && [\"Create repository in GitHub…\", createGithubRemote, faGithub],\n                        // [\"Use existing GitHub repository…\", useExistingGithubRemote, faGithub],\n                        [\"Add remote by URL…\", addHttpRemote, faLink],\n                    ]}\n                    align={\"left\"}\n                />\n            </div>\n        </Modal>\n    );\n};\n\nexport default connector(GitRemotes) as typeof GitRemotes;\n","import React, { useMemo, useRef } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faGithub } from \"@fortawesome/free-brands-svg-icons/faGithub\";\nimport { faPlus } from \"@fortawesome/pro-regular-svg-icons/faPlus\";\nimport { faRotate } from \"@fortawesome/pro-regular-svg-icons/faRotate\";\nimport { faLinkSlash } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport {\n    ensureGithubConnection,\n    getGithubConnection,\n    installGithubApp,\n    loadGithubConnection,\n    promptAndMaybeDisconnectGitHubAccount,\n} from \"@/controllers/app/remotes\";\nimport { getUser } from \"@/controllers/ide\";\nimport { alert, modalReturn } from \"@/controllers/modals\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport type { GithubInstallation } from \"@/types/app-remotes\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \"..\";\nimport Modal, { ModalRef } from \"../Modal\";\n\nconst connector = connect((state: State) => ({\n    conn: getGithubConnection(state),\n    user: getUser(state),\n}));\n\ntype GithubAccountChooserProps = AnvilConnectedProps<typeof connector>;\n\nconst GithubAccountChooser: ModalComponent<never, GithubInstallation | null, GithubAccountChooserProps> = ({\n    modalId,\n    conn,\n    dispatch,\n}) => {\n    const modal = useRef<ModalRef>(null);\n\n    const installationsAllowingCreation = useMemo(\n        () =>\n            conn?.installations.filter(\n                (inst) => inst.target_type === \"Organization\" || inst.target_id === conn.user.id\n            ),\n        [conn]\n    );\n\n    const onHandleDisconnectClick = useEvent(async () => {\n        const { error } = await dispatch(promptAndMaybeDisconnectGitHubAccount());\n        if (error) {\n            dispatch(alert(\"Failed to disconnect GitHub account\", `${error}   \\nPlease contact support@anvil.works`));\n        }\n    });\n\n    return (\n        <Modal\n            modalId={modalId}\n            ref={modal}\n            title={conn ? `Choose Account` : \"Connect to GitHub\"}\n            icon={faGithub}\n            size=\"medium\"\n            buttons={[\n                {\n                    text: \"Cancel\",\n                    clickActionCreator: () => modalReturn(null),\n                },\n            ]}\n            leftButtons={\n                conn ? (\n                    <LinkInternal className={\"text-danger\"} onClick={onHandleDisconnectClick}>\n                        <FontAwesomeIcon icon={faLinkSlash} className={\"mr-2\"} />\n                        Disconnect GitHub Account\n                    </LinkInternal>\n                ) : null\n            }>\n            {conn ? (\n                <>\n                    You are logged in to Github as <span className={\"font-mono font-semibold\"}>{conn?.user.login}</span>\n                    {conn?.user?.name && ` (${conn.user.name})`}.{\" \"}\n                    {conn?.installations.length > 0 && \"Where would you like to create the repository?\"}\n                    {installationsAllowingCreation?.map((inst) => (\n                        <div\n                            key={inst.account.login}\n                            className={\n                                \"my-2 flex items-center justify-between rounded-lg border border-sectionborder px-8 py-2 hover:bg-sectionborder dark:hover:bg-dark-sectionborder\"\n                            }>\n                            <div>\n                                <span className={\"font-mono text-2xl font-semibold\"}>{inst.account.login}</span>\n                                <span className={\"mx-2\"}>({inst.target_type})</span>\n                            </div>\n                            <Button variant={\"highlight1\"} onClick={() => modal.current?.returnValue(inst)}>\n                                Choose\n                            </Button>\n                        </div>\n                    ))}\n                    <div className={\"mt-12 flex justify-center gap-4 text-center\"}>\n                        <Button icon={faPlus} variant={\"primary\"} onClick={() => dispatch(installGithubApp())}>\n                            {conn?.installations.length > 0\n                                ? \"Choose a different account\"\n                                : \"Allow Anvil to access your Github account\"}\n                        </Button>\n                        <Button icon={faRotate} variant={\"primary\"} onClick={() => dispatch(loadGithubConnection())}>\n                            Refresh available accounts\n                        </Button>\n                    </div>\n                </>\n            ) : (\n                <>\n                    <Button variant={\"secondary\"} icon={faGithub} onClick={() => dispatch(ensureGithubConnection())}>\n                        Connect to GitHub\n                    </Button>\n                </>\n            )}\n        </Modal>\n    );\n};\n\nexport default connector(GithubAccountChooser) as typeof GithubAccountChooser;\n","import React, { useCallback, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { RadioButton } from \"@/components/reusable/Forms\";\nimport UpgradeBadge from \"@/components/reusable/UpgradeBadge\";\nimport { modal, modalReturn } from \"@/controllers/modals\";\nimport { LicenceSelection, appHasLicenceFile, licenceDescriptions } from \"@/controllers/ossLicences\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useFeatureSupported } from \"@/util/features\";\nimport { ModalComponent } from \"..\";\nimport Modal, { ModalRef } from \"../Modal\";\n\nconst GithubChooseVisibilityAndLicence: ModalComponent<never, LicenceSelection> = ({ modalId }) => {\n    const hasLicenceAlready = useSelector(appHasLicenceFile);\n    const dispatch = useDispatch<AnvilDispatch>();\n    const modalRef = useRef<ModalRef>(null);\n    const supportsPrivateRepos = useFeatureSupported(\"private-git-remotes\");\n    const [selection, setSelection] = useState<LicenceSelection>(() =>\n        supportsPrivateRepos\n            ? { private: true }\n            : hasLicenceAlready\n              ? { private: false, licence: \"none\" }\n              : { private: false, licence: \"mit\" }\n    );\n\n    const goPrivate = useCallback(async () => {\n        if (supportsPrivateRepos) {\n            setSelection({ private: true });\n        } else {\n            await dispatch(modal(\"upgradePrompt\", { featureId: \"private-git-remotes\" }));\n        }\n    }, [supportsPrivateRepos]);\n\n    const goPublic = useCallback(() => {\n        if (selection.private) {\n            setSelection({ private: false, licence: \"mit\" });\n        }\n    }, [selection.private]);\n\n    return (\n        <Modal\n            modalId={modalId}\n            ref={modalRef}\n            title={\"Choose Licence\"}\n            size={\"medium\"}\n            buttons={[\n                { text: \"Create\", variant: \"primary\", clickActionCreator: () => modalReturn(selection) },\n                { text: \"Cancel\", close: true, clickActionCreator: () => modalReturn(null) },\n            ]}>\n            <div\n                className={cx(\n                    \"my-2 cursor-pointer rounded-lg border px-8 py-4 hover:bg-sectionborder dark:hover:bg-dark-sectionborder\",\n                    selection.private ? \"border-sectionborder-darker\" : \"border-sectionborder\"\n                )}\n                onClick={goPrivate}>\n                <RadioButton checked={selection.private} onChange={goPrivate}>\n                    Private repository <UpgradeBadge feature={\"private-git-remotes\"} />\n                </RadioButton>\n                <p className={\"mx-12\"}>Nobody else can see your app's code</p>\n            </div>\n\n            <div\n                className={cx(\n                    \"my-4 cursor-pointer rounded-lg border px-8 py-4 hover:bg-sectionborder dark:hover:bg-dark-sectionborder\",\n                    !selection.private ? \"border-sectionborder-darker\" : \"border-sectionborder\"\n                )}\n                onClick={goPublic}>\n                <RadioButton checked={!selection.private} onChange={goPublic}>\n                    Public repository\n                </RadioButton>\n                <p className={\"mx-12\"}>Your app's code is available to everyone.</p>\n            </div>\n\n            {!selection.private && !hasLicenceAlready && (\n                <div className={\"mx-8 mt-8\"}>\n                    <p>Choose an open-source licence:</p>\n\n                    {licenceDescriptions.map(({ id, name, description }) => (\n                        <div\n                            key={id}\n                            className={\"mx-8 mt-8 cursor-pointer\"}\n                            onClick={() => setSelection({ private: false, licence: id })}>\n                            <RadioButton\n                                checked={selection.licence === id}\n                                onChange={() => setSelection({ private: false, licence: id })}>\n                                {name}\n                            </RadioButton>\n                            <p className={\"pl-12 text-base text-grey-1\"}>{description}</p>\n                        </div>\n                    ))}\n                </div>\n            )}\n        </Modal>\n    );\n};\n\nexport default GithubChooseVisibilityAndLicence;\n","import React, { useCallback, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { ModalComponent } from \"@/components/modals\";\nimport Modal from \"@/components/modals/Modal\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { getApp } from \"@/controllers/app\";\n\nconst ConfirmRemoveTesting: ModalComponent<never> = ({ modalId, spec: { appName } }) => {\n    const app = useSelector(getApp);\n    const name = appName || app?.name;\n    const [input, setInput] = useState(\"\");\n    const enabled = name === input;\n\n    const inputRef = useCallback((node: HTMLInputElement) => {\n        node?.focus();\n    }, []);\n\n    return (\n        <Modal\n            autoFocus={false}\n            title={`Delete Testing?`}\n            modalId={modalId}\n            buttons={[\n                { text: \"Delete\", returns: true, variant: \"danger\", enabled, defaultButton: true },\n                { text: \"Cancel\", returns: false },\n            ]}>\n            <Text>Removing the Testing Service will delete all files in the Tests folder.</Text>\n            <Text>\n                Please type <span className={\"font-mono font-semibold text-primary select-text\"}>{name}</span> to\n                confirm.\n            </Text>\n\n            <ContentTextInput\n                ref={inputRef}\n                className={\"w-full\"}\n                value={input}\n                onChange={(e) => setInput(e.target.value)}\n            />\n        </Modal>\n    );\n};\n\nexport default ConfirmRemoveTesting;\n","import React from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { getAppAssets, openCodeItem, uploadAsset } from \"@/controllers/app/code\";\nimport { confirm } from \"@/controllers/modals\";\nimport { AnvilDispatch, CodeItem } from \"@/types\";\nimport { Asset } from \"@/util/hooks/assets\";\nimport useEvent from \"@/util/useEventCallback\";\nimport type { ModalComponent } from \".\";\nimport { getDataUriForAsset } from \"../tabs/settings/RootConfig\";\nimport UriUploader, { UriSpec } from \"./UriUploader\";\n\nconst assetPrefix = \"asset:\";\nconst MSG_REPLACE = \"reduce the size of this image before uploading it to your assets?\";\nconst MSG_NEW = \"reduce the size of this image?\\n(This will create a new file in your assets)\";\n\nasync function getImageFromSrc(src: string) {\n    return new Promise<HTMLImageElement>((resolve, reject) => {\n        const img = new Image();\n        img.onload = () => resolve(img);\n        img.onerror = reject;\n        img.src = src;\n    });\n}\n\nasync function getImageFromAsset(codeAsset: CodeItem) {\n    const dataUri = getDataUriForAsset(codeAsset);\n    return getImageFromSrc(dataUri);\n}\n\nasync function canvasToFile(canvas: HTMLCanvasElement, filename: string, type: string) {\n    const blob = await new Promise<Blob>((resolve, reject) => {\n        canvas.toBlob((blob) => {\n            if (blob) {\n                resolve(blob);\n            } else {\n                reject(new Error(\"Failed to reduce image size\"));\n            }\n        }, type);\n    });\n    return new File([blob], filename, { type });\n}\n\nfunction reduceImageSize(img: HTMLImageElement, name: string, type: string, max: number) {\n    const canvas = document.createElement(\"canvas\");\n    const ctx = canvas.getContext(\"2d\")!;\n    const { naturalWidth: w, naturalHeight: h } = img;\n\n    let scale: number;\n    if (w >= h) {\n        scale = max / w;\n    } else {\n        scale = max / h;\n    }\n    scale = Math.min(scale, 1);\n\n    const newW = scale * w;\n    const newH = scale * h;\n\n    // Set the canvas width and height to the desired size\n    canvas.width = newW;\n    canvas.height = newH;\n    // Draw the original image on the canvas at a smaller size\n    ctx.drawImage(img, 0, 0, newW, newH);\n    return canvasToFile(canvas, name, type);\n}\n\nconst useOptimizeAsset = (max: number, suffix: string) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    async function optimizeAsset(asset: Asset, img: HTMLImageElement) {\n        const assetName = asset.name;\n        const dot = assetName.lastIndexOf(\".\");\n        const [rawName, rawType] = [assetName.slice(0, dot), assetName.slice(dot + 1)];\n        if (rawType === \"svg\") return assetPrefix + asset.fullName;\n        const type = rawType === \"png\" || rawType === \"gif\" ? rawType : \"jpeg\";\n        const fileType = \"image/\" + type;\n        const optimizedFile = await reduceImageSize(img, rawName + \"-\" + suffix + \".\" + type, fileType, max);\n        let pkgPrefix = \"\";\n        if (asset.fullName.length !== asset.name.length) {\n            // don't include slash\n            pkgPrefix = asset.fullName.slice(0, asset.fullName.length - asset.name.length - 1);\n        }\n        const codeStructure = await dispatch(uploadAsset(optimizedFile, pkgPrefix, false));\n        if (!codeStructure) return null;\n        return assetPrefix + codeStructure.fullName;\n    }\n    return optimizeAsset;\n};\n\nfunction useCheckImageShouldBeOptimized(max: number, errorMsg: string) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    return function checkImageShouldBeOptimized(img: HTMLImageElement, msgEnd: string) {\n        const { naturalWidth: width, naturalHeight: height } = img;\n        if (width > max || height > max) {\n            const title = \"Logo image not optimized\";\n            const msg = `${errorMsg}\nIt looks like your image is ${width}×${height} pixels.\nWould you like us to ${msgEnd}`;\n            return dispatch(confirm(title, msg));\n        }\n        return null;\n    };\n}\n\nconst useCheckValidity = (max: number, errorMsg: string) => {\n    const checkImageShouldBeOptimized = useCheckImageShouldBeOptimized(max, errorMsg);\n    return useEvent(async (file: File) => {\n        if (file.type === \"image/svg+xml\") return file; // we can't optimize svgs\n        const img = await getImageFromSrc(URL.createObjectURL(file));\n        if (await checkImageShouldBeOptimized(img, MSG_REPLACE)) {\n            return await reduceImageSize(img, file.name, file.type, max);\n        }\n        return file;\n    });\n};\n\nconst useOnModalReturn = (max: number, errorMsg: string, suffix: string) => {\n    const assets = useSelector(getAppAssets);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const checkImageShouldBeOptimized = useCheckImageShouldBeOptimized(max, errorMsg);\n    const optimizeAsset = useOptimizeAsset(max, suffix);\n\n    const onModalReturn = useEvent(async (selected: string | null) => {\n        let logo = selected;\n        if (selected?.startsWith(assetPrefix)) {\n            const imgAsset = assets.find((img) => assetPrefix + img.fullName === logo);\n            if (imgAsset && !imgAsset.fullName.endsWith(\".svg\")) {\n                const codeAsset = await dispatch(openCodeItem(imgAsset.codePath));\n                if (codeAsset !== null) {\n                    const img = await getImageFromAsset(codeAsset);\n                    if (await checkImageShouldBeOptimized(img, MSG_NEW)) {\n                        logo = await optimizeAsset(imgAsset, img);\n                    }\n                }\n            }\n        }\n        return logo;\n    });\n    return onModalReturn;\n};\n\nexport interface SizedImageSpec extends Partial<UriSpec> {\n    value: string | null | undefined;\n    maxSize: number;\n    title: string;\n    text: string;\n    defaultValue: string;\n    errorMsg: string;\n    suffix: string;\n    uploadInfo?: string;\n}\n\nconst SizedImageModal: ModalComponent<SizedImageSpec, string | null> = ({ spec, ...props }) => {\n    const { maxSize, errorMsg, suffix } = spec;\n    const onModalReturn = useOnModalReturn(maxSize, errorMsg, suffix);\n    const onCheckValidity = useCheckValidity(maxSize, errorMsg);\n\n    const uriSpec: UriSpec = { ...spec, accept: \"image/*\", freeText: true, assetPrefix };\n\n    return (\n        <UriUploader\n            spec={uriSpec}\n            onModalReturn={onModalReturn}\n            checkValidity={onCheckValidity}\n            closeOnDoubleClick={false}\n            includeDependencies={false}\n            {...props}\n        />\n    );\n};\n\nexport default SizedImageModal;\n","import React, { useRef } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { createApp } from \"@/controllers/app\";\nimport { ANVIL_X_LOGO } from \"@/data/imageUrls\";\nimport { AnvilDispatch } from \"@/types\";\nimport { ModalComponent } from \".\";\nimport { useExampleApps } from \"../StartPageContent\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport Modal, { ModalRef } from \"./Modal\";\n\nconst TemplatesModal: ModalComponent = ({ modalId }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const exampleApps = useExampleApps();\n    const modalRef = useRef<ModalRef>(null);\n\n    return (\n        <Modal ref={modalRef} modalId={modalId} title={\"Templates\"} size=\"large\">\n            <div\n                className={\"grid w-full grid-cols-1 gap-x-4 gap-y-6 px-2 sm:grid-cols-2 md:grid-cols-3\"}\n                style={{ minWidth: 0 }}>\n                {exampleApps.map((template) => (\n                    <LinkInternal\n                        key={template.name}\n                        onClick={() => {\n                            // close when the user clicks\n                            // probably the right thing to do\n                            modalRef.current?.returnValue(null);\n                            dispatch(createApp(template));\n                        }}\n                        className={\n                            \"m-auto block h-98 w-102 min-w-0 flex-[0_0_auto] overflow-hidden rounded-[0.4rem] border-2 border-solid border-sectionborder bg-light-bg2 text-center hover:bg-sidebar-highlight1 active:bg-light-bg4 dark:border-dark-sectionborder dark:bg-dark-bg3 dark:hover:bg-[#484d5866] dark:active:bg-dark-bg3\"\n                        }>\n                        <div\n                            className=\"h-52 border-b-2 border-light-bg4 bg-cover dark:border-dark-bg4\"\n                            style={{ backgroundImage: `url(${template.img})` }}\n                        />\n                        <div className=\"mt-5 text-2xl font-semibold text-light-grey2 dark:text-white\">\n                            {template.name}\n                        </div>\n                        <div className=\"mx-8 my-1.5 text-xl/9 font-medium text-light-bg6 dark:text-dark-fg1\">\n                            {template.description}\n                        </div>\n                        {template.tableau && (\n                            <img\n                                alt=\"anvil-X\"\n                                className={\"absolute right-1 bottom-0 mr-4 h-18 py-4\"}\n                                src={ANVIL_X_LOGO}\n                            />\n                        )}\n                    </LinkInternal>\n                ))}\n            </div>\n        </Modal>\n    );\n};\n\nexport default TemplatesModal;\n","import React, { useMemo, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { getDebugEnvironmentTableMapping } from \"@/controllers/db\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport { FormItemYaml } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ModalComponent } from \".\";\nimport { Text } from \"../reusable/Text\";\nimport { SingleSelectDropDown } from \"../reusable/selectdropdown\";\nimport Modal from \"./Modal\";\n\ntype ItemType = FormItemYaml[\"item_type\"];\n\ninterface ItemTypeSpec {\n    itemType?: ItemType;\n}\n\nconst NULL_VALUE = \"$$NULL$$\";\n\nconst UpdateFormItemType: ModalComponent<ItemTypeSpec, ItemType | false | null> = ({ modalId, spec: { itemType } }) => {\n    const currentTableMapping = useSelector(getDebugEnvironmentTableMapping);\n    const tableId = itemType?.table_id ?? NULL_VALUE;\n    const tableItems = useMemo(() => {\n        return [\n            { value: NULL_VALUE, display: \"[None]\" },\n            ...(currentTableMapping?.tables.map(({ id, name }) => ({ value: id, display: name })) ?? []),\n        ];\n    }, [currentTableMapping]);\n    const [value, setValue] = useState(tableId);\n\n    const onModalReturn = useEvent(() => {\n        if (value === tableId) return modalReturn(null);\n        if (value === NULL_VALUE) return modalReturn(false);\n        return modalReturn({ table_id: value as number });\n    });\n\n    return (\n        <Modal\n            title={\"Item Type\"}\n            modalId={modalId}\n            buttons={[{ text: \"Continue\", clickActionCreator: onModalReturn, defaultButton: true }]}>\n            <div className=\"flex flex-col items-baseline gap-2\">\n                <Text>Will this form be used to display rows from a Data Table? If so, which one?</Text>\n                <SingleSelectDropDown value={value} onChange={(v) => setValue(v)} items={tableItems} />\n                <Text level={3}>(Setting the item type may help with this Form's autocompletion suggestions)</Text>\n            </div>\n        </Modal>\n    );\n};\n\nexport default UpdateFormItemType;\n","import { useEffect, useRef, useState } from \"react\";\nimport { ModalComponent } from \"..\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { faArrowRightToBracket, faArrowUpRightFromSquare, faChevronDown, faChevronRight } from \"@fortawesome/pro-solid-svg-icons\";\nimport Modal, { ModalRef } from \"../Modal\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { TextBox } from \"@/components/reusable/Forms\";\nimport Link from \"@/components/reusable/Link\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { useConversationCallbacks } from \"@/agent/hooks\";\nimport { ConversationInfo } from \"@/agent/types\";\nimport { cx } from \"@/theme/styles\";\nimport { cleanedKey } from \"@/controllers/agents\";\n\ntype LoginViewTypes = \"token\" | \"apiKey\" | null;\n\ninterface AgentClaudeLoginSpec {\n    conversationInfo: ConversationInfo;\n}\n\nconst AgentClaudeLogin: ModalComponent<AgentClaudeLoginSpec, undefined> = ({ modalId, spec: { conversationInfo } }) => {\n    const modal = useRef<ModalRef | null>(null);\n    const { doApiKeyLogin, onChangeAgentType } =\n        useConversationCallbacks(conversationInfo);\n\n    const [view, setView] = useState<LoginViewTypes>(null);\n    const [apiKey, setApiKey] = useState(\"\");\n    const [token, setToken] = useState(\"\");\n\n    useEffect(() => {\n        if (conversationInfo.agent_type === 'claude') return;\n        onChangeAgentType('claude');\n    }, [conversationInfo, onChangeAgentType]);\n\n    const submitLogin = useEvent((value: string, loginType: \"anthropic_api_key\" | \"claude_oauth_token\") => {\n        if (!value) return;\n        doApiKeyLogin(cleanedKey(value), loginType);\n        void modal.current?.returnValue(null);\n    });\n\n    return <Modal\n        ref={modal}\n        modalId={modalId}\n        allowDismiss={true}\n        title={\"Connect to Claude\"}\n    >\n        <div className=\"flex flex-col w-full gap-8\">\n            <div className=\"rounded border border-sectionborder\">\n                <LinkInternal\n                    iconRight\n                    className={\"flex items-center text-3xl font-semibold select-none p-6\"}\n                    icon={view === \"token\" ? faChevronDown : faChevronRight}\n                    onClick={() => setView((c) => c === \"token\" ? null : \"token\")}>\n                    Log in with Claude Code token <div className=\"grow\" />\n                </LinkInternal>\n                {/* todo: check that there IS some kind of connection and change content to show that it's been successful */}\n                <Expander isOpen={view === \"token\"}>\n                    <div className={\"p-6\"}>\n                        <div className={cx(\"flex border border-sectionborder flex-col rounded w-full bg-light-bg2 px-12 py-4\", \"dark:bg-dark-bg2\")}>\n                            <ul className=\"list-disc ml-12 \">\n                                <li className=\"pb-2!\">\n                                    With Claude Code installed in your machine, run <span className=\"font-semibold font-mono select-all\">claude setup-token</span> from your terminal\n                                </li>\n                                <li className=\"pb-8!\">Copy the generated OAuth token below and click “Log in”</li>\n                            </ul>\n                            <div className=\"flex items-center gap-4\">\n                                <TextBox\n                                    className={\"w-full\"}\n                                    type={\"password\"}\n                                    value={token}\n                                    placeholder={\"Claude Code Token\"}\n                                    onChange={(e) => setToken(e.target.value.trim())}\n                                    onKeyDown={(e) => {\n                                        if (e.key === \"Enter\") {\n                                            submitLogin(token, \"claude_oauth_token\");\n                                        }\n                                    }}\n                                />\n                                <Button className={\"h-20!\"} variant={\"primary\"} onClick={() => submitLogin(token, \"claude_oauth_token\")} icon={faArrowRightToBracket}>Log in</Button>\n                            </div>\n                        </div>\n                    </div>\n                </Expander>\n            </div>\n            <div className=\"rounded border border-sectionborder\">\n                <LinkInternal\n                    iconRight\n                    className={\"flex items-center text-3xl font-semibold select-none p-6\"}\n                    icon={view === \"apiKey\" ? faChevronDown : faChevronRight}\n                    onClick={() => setView((c) => c === \"apiKey\" ? null : \"apiKey\")}>\n                    Log in with Anthropic API key <div className=\"grow\" />\n                </LinkInternal>\n                {/* todo: check that there IS some kind of connection and change content to show that it's been successful */}\n                <Expander isOpen={view === \"apiKey\"}>\n                    <div className={\"p-6\"}>\n                        <div className={cx(\"flex border border-sectionborder flex-col rounded w-full bg-light-bg2 px-12 py-4\", \"dark:bg-dark-bg2\")}>\n                            <ul className=\"list-disc ml-12 \">\n                                <li className=\"pb-2!\">Create an Anthropic API key at <Link className=\"text-primary! no-underline! font-semibold\" target={\"_blank\"} to={'https://platform.claude.com/'}>https://platform.claude.com/ <FontAwesomeIcon className={\"pl-2\"} icon={faArrowUpRightFromSquare} /></Link></li>\n                                <li className=\"pb-8!\">Paste your API key below and click “Log in”</li>\n                            </ul>\n                            <div className=\"flex items-center gap-4\">\n                                <TextBox\n                                    className={\"w-full\"}\n                                    type={\"password\"}\n                                    value={apiKey}\n                                    placeholder={\"API key\"}\n                                    onChange={(e) => setApiKey(e.target.value)}\n                                    onKeyDown={(e) => {\n                                        if (e.key === \"Enter\") {\n                                            submitLogin(apiKey, \"anthropic_api_key\");\n                                        }\n                                    }}\n                                />\n                                <Button className={\"h-20!\"} variant={\"primary\"} onClick={() => submitLogin(apiKey, \"anthropic_api_key\")} icon={faArrowRightToBracket}>Log in</Button>\n                            </div>\n                        </div>\n                    </div>\n                </Expander>\n            </div>\n        </div>\n    </Modal>;\n};\n\nexport default AgentClaudeLogin;\n","import { faExternalLink } from \"@fortawesome/pro-solid-svg-icons/faExternalLink\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { ParsedAgentUrlElicitation } from \"@/agent/types.ts\";\nimport { CopyButton } from \"@/components/reusable/CopyButton.tsx\";\nimport Link from \"@/components/reusable/Link.tsx\";\nimport { cx } from \"@/theme/styles.ts\";\nimport { faArrowUpRightFromSquare } from \"@fortawesome/pro-solid-svg-icons\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\n\nexport const UrlElicitation = ({ elicitation }: { elicitation: ParsedAgentUrlElicitation }) => {\n    if (elicitation.code) {\n        return (\n            <div className={\"flex flex-col gap-2\"}>\n                <div className=\" flex flex-col gap-2\">\n                    <div className=\"flex flex-col\">\n                        <div className=\"flex \">\n                            <div className=\"grow-0 w-8\">•</div>\n                            <div className=\"grow\">Copy this code: </div>\n                        </div>\n                        <div className=\"flex \">\n                            <div className=\"grow-0 w-8\"></div>\n                            <div className=\"grow\">\n                                <div\n                                    className={cx(\n                                        \"mt-2 mb-4 inline-block rounded-2xl border p-4 font-mono font-semibold select-all\",\n                                        \"border-sectionborder bg-secondary-50 text-primary-800 dark:bg-dark-bg2\",\n                                        \"dark:border-dark-sectionborder dark:bg-primary-900 dark:text-primary-100\"\n                                    )}>\n                                    {elicitation.code}\n                                </div>\n\n                                <CopyButton\n                                    copyText={elicitation.code}\n                                    variant={\"primary\"}\n                                    small\n                                    className={\"ml-4 inline-block\"}\n                                    title={\"Copy code\"}\n                                />\n                                <div className={\"font-semibold text-xl text-danger mb-2\"}>Do not share this code with anyone else.</div>\n                            </div>\n                        </div>\n                    </div>\n                    <div className=\"flex\">\n                        <div className=\"grow-0 w-8\">•</div>\n                        <div className=\"grow\">Navigate to <Link className=\"text-primary! no-underline! font-semibold\" target={\"_blank\"} to={'https://auth.openai.com/codex/device'}>https://auth.openai.com/codex/device <FontAwesomeIcon className={\"pl-2\"} icon={faArrowUpRightFromSquare} /></Link></div>\n                    </div>\n                    <div className=\"flex\">\n                        <div className=\"grow-0 w-8\">•</div>\n                        <div className=\"grow\">When prompted, paste the code you copied above. </div>\n                    </div>\n                </div>\n                <HelpLink className=\"font-semibold\" inline url={`/docs/ai/connecting-your-account#chatgptcodex`}>\n                    &nbsp;If you run into issues, check out our Troubleshooting guidelines\n                </HelpLink>\n            </div>\n        );\n    } else {\n        return <div className={\"whitespace-pre-line select-text\"}>{elicitation.message}</div>;\n    }\n};\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { ModalComponent } from \"..\";\nimport { Button } from \"@/components/reusable/Button\";\nimport {\n    faArrowRightToBracket,\n    faChevronDown,\n    faChevronRight,\n    faArrowUpRightFromSquare\n} from \"@fortawesome/pro-solid-svg-icons\";\nimport { faCircleCheck } from \"@fortawesome/pro-regular-svg-icons\";\nimport Modal, { ModalRef } from \"../Modal\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { UrlElicitation } from \"@/agent/components/UrlElicitation\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { useConversation, useConversationCallbacks } from \"@/agent/hooks\";\nimport { TextBox } from \"@/components/reusable/Forms\";\nimport Link from \"@/components/reusable/Link\";\nimport { ConversationInfo } from \"@/agent/types\";\nimport { faSparkle } from \"@fortawesome/pro-regular-svg-icons/faSparkle\";\nimport { cx } from \"class-variance-authority\";\nimport { cleanedKey } from \"@/controllers/agents\";\nimport {LoadingSpinner} from \"@/components/reusable/LoadingSpinner.tsx\";\n\ntype LoginViewTypes = \"chatgpt\" | \"apiKey\" | null;\ninterface AgentCodexLoginSpec {\n    conversationInfo: ConversationInfo;\n}\n\nconst AgentCodexLogin: ModalComponent<AgentCodexLoginSpec, undefined> = ({ modalId, spec: { conversationInfo } }) => {\n    {\n        const modal = useRef<ModalRef | null>(null);\n\n        const { conversation } = useConversation(conversationInfo.conversation_pid);\n\n        const sessionIsRunning = conversation?.sessionStatus === \"running\";\n        const didRequestChatgptLogin = useRef(false);\n\n        const { doLogin, doApiKeyLogin, onChangeAgentType } =\n            useConversationCallbacks(conversationInfo);\n        const [view, setView] = useState<LoginViewTypes>(null);\n\n        const openLoginWithElicitation = useEvent(() => {\n            if (!conversation?.urlElicitation && !didRequestChatgptLogin.current) {\n                didRequestChatgptLogin.current = true;\n                doLogin();\n            }\n            setView((c) => c === \"chatgpt\" ? null : \"chatgpt\");\n        });\n\n        useEffect(() => {\n            if (conversationInfo.agent_type === 'codex') return;\n            onChangeAgentType('codex');\n        }, [conversationInfo, onChangeAgentType]);\n\n        useEffect(() => {\n            if (conversation?.urlElicitation || sessionIsRunning) {\n                didRequestChatgptLogin.current = false;\n            }\n        }, [conversation?.urlElicitation, sessionIsRunning]);\n\n        const [apiKey, setApiKey] = useState(\"\");\n\n        const inputRef = useCallback((node: HTMLInputElement | null) => {\n            node?.focus();\n        }, [view]);\n\n        const onApiLoginClick = useEvent(() => {\n            if (apiKey) {\n                doApiKeyLogin(cleanedKey(apiKey), \"codex_api_key\");\n                void modal.current?.returnValue(null);\n            }\n        });\n\n        let modalContent = null;\n\n        switch(conversation.sessionStatus) {\n            case \"running\":\n                modalContent = <div className=\"flex flex-col gap-6 py-4 items-center\">\n                    <div className={\"flex items-center gap-2 text-highlight\"}>\n                        <FontAwesomeIcon\n                            className={\"text-3xl\"}\n                            icon={faCircleCheck} />\n                        <div className=\"text-3xl font-semibold\">Connected successfully.</div>\n                    </div>\n                    <div className=\"text-2xl text-text\">\n                        Your connection is ready to use.\n                    </div>\n                    <Button icon={faSparkle} iconRight variant={\"primary\"} onClick={() => { modal.current?.returnValue(true); }}>\n                        Continue to conversation\n                    </Button>\n                </div>;\n                break;\n\n            case \"stopped\":\n            case \"pending\":\n                modalContent = <div className={\"flex justify-center my-8\"}><LoadingSpinner sizeRem={5} inline/></div>;\n                break;\n\n            case \"needs_auth_to_start\":\n            case \"needs_auth_to_continue\":\n                modalContent = <div className=\"flex flex-col w-full gap-8\">\n                    <div className=\"rounded border border-sectionborder\">\n                        <LinkInternal\n                            iconRight\n                            className={\"flex items-center text-3xl font-semibold select-none p-6\"}\n                            icon={view === \"chatgpt\" ? faChevronDown : faChevronRight}\n                            onClick={openLoginWithElicitation}>\n                            Log in with ChatGPT <div className=\"grow\" />\n                        </LinkInternal>\n                        <Expander isOpen={view === \"chatgpt\"}>\n                            <div className={\"p-6\"}>\n                                <div className={cx(\"flex border border-sectionborder flex-col rounded w-full bg-light-bg2 px-12 py-4\", \"dark:bg-dark-bg2\")}>\n                                    {conversation?.urlElicitation ? (\n                                        <UrlElicitation elicitation={conversation.urlElicitation} />\n                                    ) : (\n                                        \"Loading Login details...\"\n                                    )}\n                                </div>\n                            </div>\n                        </Expander>\n                    </div>\n                    <div className=\"rounded border border-sectionborder\">\n                        <LinkInternal\n                            iconRight\n                            className={\"flex items-center text-3xl font-semibold select-none p-6\"}\n                            icon={view === \"apiKey\" ? faChevronDown : faChevronRight}\n                            onClick={() => setView((c) => c === \"apiKey\" ? null : \"apiKey\")}>\n                            Log in with API key <div className=\"grow\" />\n                        </LinkInternal>\n                        <Expander isOpen={view === \"apiKey\"}>\n                            <div className={\"p-6\"}>\n                                <div className={cx(\"flex border border-sectionborder flex-col rounded w-full bg-light-bg2 px-12 py-4\", \"dark:bg-dark-bg2\")}>\n                                    {(\n                                        <>\n                                            <ul className=\"list-disc ml-12 \">\n                                                <li className=\"pb-2!\">Create an OpenAI API key at <Link className=\"text-primary! no-underline! font-semibold\" target={\"_blank\"} to={'https://platform.openai.com/api-keys'}>https://platform.openai.com/api-keys <FontAwesomeIcon className={\"pl-2\"} icon={faArrowUpRightFromSquare} /></Link></li>\n                                                <li className=\"pb-8!\">Paste your API key below and click “Log in”</li>\n                                            </ul>\n                                            <div className=\"flex items-center gap-4\">\n                                                <TextBox\n                                                    ref={inputRef}\n                                                    className={\"w-full\"}\n                                                    type={\"password\"}\n                                                    value={apiKey}\n                                                    placeholder={\"API key\"}\n                                                    onChange={(e) => setApiKey(e.target.value)}\n                                                    onKeyDown={(e) => {\n                                                        if (e.key === \"Enter\") {\n                                                            onApiLoginClick();\n                                                        }\n                                                    }}\n                                                />\n                                                <Button className={\"h-20!\"} variant={\"primary\"} onClick={onApiLoginClick} icon={faArrowRightToBracket}>Log in</Button>\n                                            </div>\n                                        </>\n                                    )}\n                                </div>\n                            </div>\n\n                        </Expander>\n                    </div>\n                </div>;\n            break;\n        }\n\n        return (\n            <Modal\n                ref={modal}\n                modalId={modalId}\n                allowDismiss={true}\n                title={\"Connect to ChatGPT/Codex\"}\n            >\n                {modalContent}\n            </ Modal>);\n    }\n\n};\n\nexport default AgentCodexLogin;\n","import React from \"react\";\nimport { ModalComponent } from \"..\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { faArrowRight } from \"@fortawesome/pro-solid-svg-icons\";\nimport Modal from \"../Modal\";\nimport useEvent from \"@/util/useEventCallback\";\n\nconst AgentCustomModelProvider: ModalComponent = ({ modalId }) => {\n    const handleClick = useEvent(() => {\n        window.location.href = \"mailto:sales@anvil.works\";\n    });\n    return <Modal\n        size={\"small\"}\n        className={\"select-text\"}\n        modalId={modalId}\n        allowDismiss={true}\n        title={\"Use your own Model Provider\"}\n    >\n        <div className=\"flex flex-col gap-8 w-full text-2xl py-6\">\n            <div>Use your enterprise model provider and private endpoints with Anvil Enterprise. </div>\n            <div>Get in touch to discuss your requirements; we'll be happy to help.</div>\n            <div className=\"flex justify-center w-full\">\n                <Button variant={\"primary\"} iconRight icon={faArrowRight} onClick={handleClick}>Get in Touch</Button>\n            </div>\n        </div>\n    </Modal>;\n};\n\nexport default AgentCustomModelProvider;\n","import { useQuery } from \"@tanstack/react-query\";\nimport { getQuota } from \"@/api\";\nimport { AiCreditBar } from \"@/components/modals/account/usage/AiCreditBar\";\nimport type { AgentTypeId, ProviderExtraUsageStatus, UsageUpdate } from \"@agent-host/rpc_types\";\nimport { formatResetTime, formatTokenCount, percentLeft, percentUsed, sortedUsageWindows } from \"@/agent/usage\";\nimport type { ModalComponent } from \"@/components/modals\";\nimport Modal from \"@/components/modals/Modal\";\n\ninterface AgentUsageSpec {\n    agentType: AgentTypeId;\n    usage: UsageUpdate | null | undefined;\n}\n\ninterface UsageRowProps {\n    label: string;\n    percentLeft?: number;\n    details: string;\n}\n\nconst UsageRow = ({ label, percentLeft, details }: UsageRowProps) => (\n    <div className=\"grid grid-cols-[10rem_minmax(0,1fr)] items-center gap-x-6 gap-y-2\">\n        <div className=\"font-mono text-light-grey1 dark:text-dark-fg1\">{label}:</div>\n        <div className=\"min-w-0\">\n            <div className=\"mb-2 flex min-w-0 justify-between gap-4\">\n                <span className=\"truncate font-mono\">{details}</span>\n            </div>\n            <div\n                className=\"h-3 overflow-hidden rounded-full bg-sectionborder dark:bg-dark-sectionborder\"\n                role={percentLeft === undefined ? undefined : \"progressbar\"}\n                aria-label={percentLeft === undefined ? undefined : `${label}: ${percentLeft}% left`}\n                aria-valuemin={percentLeft === undefined ? undefined : 0}\n                aria-valuemax={percentLeft === undefined ? undefined : 100}\n                aria-valuenow={percentLeft}>\n                {percentLeft !== undefined && (\n                    <div\n                        className=\"h-full rounded-full bg-primary transition-[width]\"\n                        style={{ width: `${percentLeft}%` }}\n                    />\n                )}\n            </div>\n        </div>\n    </div>\n);\n\nconst EXTRA_USAGE_LABELS: Record<ProviderExtraUsageStatus, string> = {\n    active: \"In use\",\n    available: \"Available\",\n    unavailable: \"Unavailable\",\n    out_of_credits: \"Out of credits\",\n};\n\nconst AGENT_NAMES: Record<AgentTypeId, string> = {\n    codex: \"Codex\",\n    \"codex-anvil\": \"Codex Anvil\",\n    claude: \"Claude\",\n    zai: \"Z.ai\",\n};\n\nconst AgentUsage: ModalComponent<AgentUsageSpec, undefined> = ({ modalId, spec: { agentType, usage } }) => {\n    const managedCodex = agentType === \"codex-anvil\";\n    const { data: quotas, isPending, isError } = useQuery({\n        queryKey: [\"quota\", \"ai-credits\"],\n        queryFn: () => getQuota([\"ai-credits\"]),\n        enabled: managedCodex,\n        refetchOnMount: \"always\",\n    });\n    const aiCredits = quotas?.[\"ai-credits\"];\n    const contextUsage = usage && usage.size > 0 ? usage : undefined;\n    const contextUsedPercent = contextUsage ? percentUsed(contextUsage.used, contextUsage.size) : undefined;\n    const contextLeft = contextUsedPercent === undefined ? undefined : percentLeft(contextUsedPercent);\n    const providerUsage = managedCodex ? undefined : usage?.providerUsage;\n    const windows = sortedUsageWindows(providerUsage?.windows ?? []);\n\n    return (\n        <Modal modalId={modalId} title={`${AGENT_NAMES[agentType]} usage`} size=\"medium\" buttons={[{ text: \"Close\" }]}>\n            <div className=\"flex flex-col gap-8 py-2\">\n                <UsageRow\n                    label=\"Context\"\n                    percentLeft={contextLeft}\n                    details={\n                        contextUsage\n                            ? `${contextLeft}% left (${formatTokenCount(contextUsage.used)} used / ${formatTokenCount(contextUsage.size)})`\n                            : \"Unknown\"\n                    }\n                />\n\n                {managedCodex ? (\n                    isError ? (\n                        <UsageRow label=\"AI Credit\" details=\"Unable to load AI credit\" />\n                    ) : aiCredits ? (\n                        <AiCreditBar quota={aiCredits} />\n                    ) : (\n                        <UsageRow label=\"AI Credit\" details={isPending ? \"Loading…\" : \"Unknown\"} />\n                    )\n                ) : windows.length === 0 ? (\n                    <UsageRow label=\"Plan limits\" details=\"Unknown\" />\n                ) : (\n                    windows.map((window) => {\n                        const left = window.usedPercent === undefined ? undefined : percentLeft(window.usedPercent);\n                        const reset =\n                            window.resetsAtEpochSeconds === undefined\n                                ? undefined\n                                : formatResetTime(window.resetsAtEpochSeconds);\n                        return (\n                            <UsageRow\n                                key={window.id}\n                                label={window.label}\n                                percentLeft={left}\n                                details={`${left === undefined ? \"Unknown\" : `${left}% left`}${\n                                    reset ? ` (${reset})` : \"\"\n                                }`}\n                            />\n                        );\n                    })\n                )}\n\n                {providerUsage?.credits && (\n                    <UsageRow\n                        label=\"Credits\"\n                        details={\n                            providerUsage.credits.unlimited ? \"Unlimited\" : (providerUsage.credits.balance ?? \"Unknown\")\n                        }\n                    />\n                )}\n\n                {providerUsage?.extraUsage && (\n                    <UsageRow\n                        label=\"Extra usage\"\n                        details={`${EXTRA_USAGE_LABELS[providerUsage.extraUsage.status]}${\n                            providerUsage.extraUsage.resetsAtEpochSeconds\n                                ? ` (${formatResetTime(providerUsage.extraUsage.resetsAtEpochSeconds)})`\n                                : \"\"\n                        }`}\n                    />\n                )}\n            </div>\n        </Modal>\n    );\n};\n\nexport default AgentUsage;\n","import { useEffect, useRef, useState } from \"react\";\nimport { faArrowRightToBracket } from \"@fortawesome/pro-solid-svg-icons\";\nimport { ModalComponent } from \"..\";\nimport { useConversationCallbacks } from \"@/agent/hooks\";\nimport { ConversationInfo } from \"@/agent/types\";\nimport Modal, { ModalRef } from \"../Modal\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { TextBox } from \"@/components/reusable/Forms\";\nimport { cleanedKey } from \"@/controllers/agents\";\nimport useEvent from \"@/util/useEventCallback\";\n\ninterface AgentZaiLoginSpec {\n    conversationInfo: ConversationInfo;\n}\n\nconst AgentZaiLogin: ModalComponent<AgentZaiLoginSpec, undefined> = ({ modalId, spec: { conversationInfo } }) => {\n    const modal = useRef<ModalRef | null>(null);\n    const { doApiKeyLogin, onChangeAgentType } = useConversationCallbacks(conversationInfo);\n    const [apiKey, setApiKey] = useState(\"\");\n\n    useEffect(() => {\n        if (conversationInfo.agent_type === \"zai\") return;\n        onChangeAgentType(\"zai\");\n    }, [conversationInfo.agent_type, onChangeAgentType]);\n\n    const submitLogin = useEvent(async () => {\n        const key = cleanedKey(apiKey);\n        if (!key) return;\n        await doApiKeyLogin(key, \"zai_api_key\");\n        await modal.current?.returnValue(undefined);\n    });\n\n    return <Modal\n        ref={modal}\n        modalId={modalId}\n        allowDismiss={true}\n        title={\"Connect to Z.ai\"}\n    >\n        <div className=\"flex flex-col w-full gap-4\">\n            <div>Paste your Z.ai API key below.</div>\n            <div className=\"flex items-center gap-4\">\n                <TextBox\n                    className={\"w-full\"}\n                    type={\"password\"}\n                    value={apiKey}\n                    placeholder={\"Z.ai API key\"}\n                    onChange={(e) => setApiKey(e.target.value)}\n                    onKeyDown={(e) => {\n                        if (e.key === \"Enter\") {\n                            void submitLogin();\n                        }\n                    }}\n                />\n                <Button\n                    className={\"h-20!\"}\n                    variant={\"primary\"}\n                    onClick={() => void submitLogin()}\n                    icon={faArrowRightToBracket}>\n                    Log in\n                </Button>\n            </div>\n        </div>\n    </Modal>;\n};\n\nexport default AgentZaiLogin;\n","import { lazyComponent } from \"@/util/lazy\";\nimport type JsonEditor from \"./JsonEditor\";\n\nexport const LazyJsonEditorModal = lazyComponent<typeof JsonEditor>(() => import(\"./JsonEditor\")) as typeof JsonEditor;\n\nexport default LazyJsonEditorModal;\n","import { ModalTypes } from \"..\";\nimport { getAccountModals } from \"./account-modals\";\nimport { commonModalTypes } from \"./common-modals\";\n\nexport const createManagerModals = () => {\n    return {\n        ...commonModalTypes,\n        ...getAccountModals(),\n    } satisfies ModalTypes;\n};\n\nlet managerModals: ManagerModalTypes;\nexport const getManagerModals = () => {\n    return (managerModals ??= createManagerModals());\n};\n\nexport type ManagerModalTypes = ReturnType<typeof createManagerModals>;\nexport type ManagerModalType = keyof ManagerModalTypes;\n","import React from \"react\";\nimport type { IconProp } from \"@fortawesome/fontawesome-svg-core\";\nimport { faEllipsisV } from \"@fortawesome/pro-regular-svg-icons/faEllipsisV\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { IDETheme, cx, makeStyles, useIsPySpace } from \"@/theme/styles\";\nimport { useMergeRefs } from \"@/util/hooks\";\nimport DropdownMenu, { DropDownMenuItems } from \"./DropdownMenu\";\nimport { LinkInternal } from \"./LinkInternal\";\nimport { TooltipPosition, useTooltip } from \"./Tooltip\";\n\ntype HighlightButtonVariants =\n    | \"primary\"\n    | \"secondary\"\n    | \"tertiary\"\n    | \"danger\"\n    | \"highlight1\"\n    | \"highlight2\"\n    | \"highlight3\";\n\nexport type ButtonVariant =\n    | HighlightButtonVariants\n    | \"tiny\"\n    | \"small\"\n    | \"large\"\n    | \"hidden\"\n    | \"no-border\"\n    | \"disabled\"\n    | \"outlined\";\n\nexport const genButtonVariant = (\n    theme: IDETheme,\n    classes: Record<ButtonVariant, string>,\n    variant: HighlightButtonVariants,\n    outlined = false,\n    dropdownTrigger = false\n) => {\n    const bg = theme.button[variant].background.darken(dropdownTrigger ? 0.1 : 0);\n    const hoverBg = theme.isPySpace ? \"\" : theme.button[variant].background.darken(dropdownTrigger ? 0.2 : 0.2);\n    const activeBg = theme.isPySpace ? \"\" : theme.button[variant].background.darken(dropdownTrigger ? 0.1 : 0.1);\n\n    // Tint towards white so darker colours also become pale when disabled.\n    const disabledBg = bg.desaturate(0.3).mix(theme.button.background, 0.5);\n    const disabledColor = theme.button[variant].color.desaturate(0.3).mix(theme.button.disabledColor, 0.5);\n\n    return {\n        background: outlined ? \"transparent\" : bg.toString(),\n        color: theme.button[variant].color.toString(),\n        border: \"2px solid \" + (theme.isPySpace ? theme.button.border : bg).toString(),\n        [`&.${classes.outlined}`]: {\n            color: theme.button[variant].background.toString(),\n            [`&:not(.${classes.disabled}):hover,&:not(.${classes.disabled}):active`]: {\n                color: theme.button[variant].color.toString(),\n            },\n        },\n        [`&.${classes.disabled}`]: {\n            background: outlined ? \"transparent\" : disabledBg.toString(),\n            color: disabledColor.toString(),\n            border: \"2px solid \" + disabledBg.toString(),\n            [`&.${classes.outlined}`]: {\n                color: disabledColor.toString(),\n            },\n        },\n        [`&:not(.${classes.disabled}):hover`]: {\n            background: hoverBg.toString(),\n            borderColor: hoverBg.toString(),\n        },\n        [`&:not(.${classes.disabled}):active`]: {\n            background: activeBg.toString(),\n            borderColor: activeBg.toString(),\n        },\n    };\n};\n\ntype ButtonClasses =\n    | \"icon\"\n    | \"iconOnly\"\n    | \"smallRoot\"\n    | \"largeRoot\"\n    | \"tinyRoot\"\n    | \"withIconLeft\"\n    | \"withIconRight\"\n    | \"withDropdown\"\n    | \"disabled\"\n    | ButtonVariant;\n\nconst useStyles = makeStyles<void, ButtonClasses>()((theme, _props, classes) => ({\n    withIconLeft: {},\n    withIconRight: {},\n    withDropdown: {},\n    smallRoot: {},\n    tinyRoot: {},\n    largeRoot: {},\n    disabled: {\n        cursor: \"not-allowed\",\n    },\n    root: {\n        display: \"inline-flex\",\n        lineHeight: 1, // Why?! Otherwise the text is slightly above centre.\n        color: theme.button.color.toString(),\n        fontWeight: theme.button.fontWeight,\n        fontSize: theme.button.fontSize,\n        height: theme.button.height,\n        [`&.${classes.smallRoot}`]: {\n            height: theme.button.small.height,\n        },\n        [`&.${classes.largeRoot}`]: {\n            height: theme.button.large.height,\n        },\n        [`&.${classes.tinyRoot}`]: {\n            height: theme.button.tiny.height,\n        },\n        [`&.${classes.disabled}`]: {},\n    },\n    main: {\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        background: theme.button.background.toString(),\n        flex: \"1 0 auto\",\n        padding: theme.button.padding ?? \"5px 15px\",\n        borderRadius: theme.button.borderRadius,\n        border: \"2px solid \" + theme.button.border.toString(),\n        [`&.${classes.disabled}`]: {\n            background: theme.button.disabled?.background?.toString() ?? \"transparent\",\n            color: theme.button.disabledColor.toString(),\n            border: \"2px solid \" + (theme.button.disabled?.border ?? theme.button.background).toString(),\n        },\n        [`&.${classes.withIconLeft}`]: {\n            padding: \"0.5rem 1.9rem 0.5rem 1.5rem\",\n        },\n        [`&.${classes.withIconRight}`]: {\n            padding: \"0.5rem 1.5rem 0.5rem 1.9rem\",\n        },\n        [`&.${classes.withDropdown}`]: {\n            borderTopRightRadius: 0,\n            borderBottomRightRadius: 0,\n        },\n        [`&:not(.${classes.disabled}):hover`]: {\n            background: theme.button.hoverBg.toString(),\n            borderColor: theme.button.hoverBg.toString(),\n        },\n        [`&:not(.${classes.disabled}):active`]: {\n            background: theme.button.activeBg.toString(),\n            borderColor: theme.button.activeBg.toString(),\n        },\n    },\n    dropdownTrigger: {\n        width: \"3.5rem\",\n        flex: \"0 0 auto\",\n        background: theme.button.background.toString(),\n        border: \"2px solid \" + theme.button.background.toString(),\n        borderRadius: theme.button.borderRadius,\n        borderTopLeftRadius: 0,\n        borderBottomLeftRadius: 0,\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        [`&.${classes.small}`]: {\n            width: \"1.8rem\",\n        },\n        [`&.${classes.large}`]: {\n            width: \"2rem\",\n        },\n        [`&.${classes.tiny}`]: {\n            width: \"1rem\",\n        },\n        [`&:not(.${classes.disabled}):hover`]: {\n            background: theme.button.hoverBg.toString(),\n            borderColor: theme.button.hoverBg.toString(),\n        },\n        [`&:not(.${classes.disabled}):active`]: {\n            background: theme.button.activeBg.toString(),\n            borderColor: theme.button.activeBg.toString(),\n        },\n        [`&:not(.${classes.outlined})`]: {\n            [`&.${classes.primary}`]: genButtonVariant(theme, classes, \"primary\", false, true),\n            [`&.${classes.secondary}`]: genButtonVariant(theme, classes, \"secondary\", false, true),\n            [`&.${classes.tertiary}`]: genButtonVariant(theme, classes, \"tertiary\", false, true),\n            [`&.${classes.danger}`]: genButtonVariant(theme, classes, \"danger\", false, true),\n            [`&.${classes.highlight1}`]: genButtonVariant(theme, classes, \"highlight1\", false, true),\n            [`&.${classes.highlight2}`]: genButtonVariant(theme, classes, \"highlight2\", false, true),\n            [`&.${classes.highlight3}`]: genButtonVariant(theme, classes, \"highlight3\", false, true),\n        },\n        [`&.${classes.outlined}`]: {\n            [`&.${classes.primary}`]: genButtonVariant(theme, classes, \"primary\", true, true),\n            [`&.${classes.secondary}`]: genButtonVariant(theme, classes, \"secondary\", true, true),\n            [`&.${classes.tertiary}`]: genButtonVariant(theme, classes, \"tertiary\", true, true),\n            [`&.${classes.danger}`]: genButtonVariant(theme, classes, \"danger\", true, true),\n            [`&.${classes.highlight1}`]: genButtonVariant(theme, classes, \"highlight1\", true, true),\n            [`&.${classes.highlight2}`]: genButtonVariant(theme, classes, \"highlight2\", true, true),\n            [`&.${classes.highlight3}`]: genButtonVariant(theme, classes, \"highlight3\", true, true),\n        },\n        borderLeft: \"none !important\", // Override variant borders.\n    },\n    dropdownAnchor: {\n        position: \"absolute\",\n        right: -2,\n        bottom: -2,\n    },\n    icon: {\n        display: \"block\",\n        textAlign: \"center\",\n    },\n    iconOnly: {\n        aspectRatio: \"1 / 1\",\n        height: \"100%\",\n        padding: \"0 !important\",\n        [`& .${classes.icon}`]: {\n            margin: \"0 !important\",\n        },\n    },\n    iconLeft: {\n        marginRight: \"1rem\",\n    },\n    iconRight: {\n        marginLeft: \"1rem\",\n    },\n    tiny: {\n        //height: theme.button.small.height,\n        color: theme.button.tiny.color.toString(),\n        fontSize: theme.button.tiny.fontSize,\n        padding: 2,\n        fontWeight: theme.button.tiny.fontWeight,\n        [`&.${classes.withIconLeft}`]: {\n            padding: \"0.1rem 0.8rem 0.1rem 0.6rem\",\n        },\n        [`&.${classes.withIconRight}`]: {\n            padding: \"0.1rem 0.6rem 0.1rem 0.8rem\",\n        },\n        [`& .${classes.icon}`]: {\n            marginRight: \"0.3rem\",\n        },\n    },\n    small: {\n        //height: theme.button.small.height,\n        color: theme.button.small.color.toString(),\n        fontSize: theme.button.small.fontSize,\n        padding: \"2px \" + theme.button.small.padding,\n        fontWeight: theme.button.small.fontWeight,\n        [`&.${classes.withIconLeft}`]: {\n            padding: \"0.2rem 1.2rem 0.2rem 0.9rem\",\n        },\n        [`&.${classes.withIconRight}`]: {\n            padding: \"0.2rem 0.9rem 0.2rem 1.2rem\",\n        },\n        [`& .${classes.icon}`]: {\n            marginRight: \"0.7rem\",\n        },\n    },\n    large: {\n        fontSize: theme.button.large.fontSize,\n        padding: \"2px \" + theme.button.large.padding,\n        fontWeight: theme.button.large.fontWeight,\n        [`&.${classes.withIconLeft}`]: {\n            padding: \"2rem 2rem 2rem 1.7rem\",\n        },\n        [`&.${classes.withIconRight}`]: {\n            padding: \"2rem 1.1rem 2rem 1.5rem\",\n        },\n        [`& .${classes.icon}`]: {\n            marginRight: \"0.9rem\",\n        },\n    },\n    primary: genButtonVariant(theme, classes, \"primary\"),\n    secondary: genButtonVariant(theme, classes, \"secondary\"),\n    tertiary: genButtonVariant(theme, classes, \"tertiary\"),\n    danger: genButtonVariant(theme, classes, \"danger\"),\n    highlight1: genButtonVariant(theme, classes, \"highlight1\"),\n    highlight2: genButtonVariant(theme, classes, \"highlight2\"),\n    highlight3: genButtonVariant(theme, classes, \"highlight3\"),\n    outlined: {\n        background: \"transparent\",\n    },\n    \"no-border\": {\n        border: 0,\n    },\n    hidden: {\n        background: \"transparent\",\n        border: \"transparent\",\n        color: theme.button.hidden?.color?.toString(),\n        boxShadow: theme.button.hidden?.boxShadow,\n        \"&:hover\": {\n            transform: theme.button.hidden?.hoverTransform,\n            boxShadow: theme.button.hidden?.boxShadow,\n            background: theme.button.hidden?.hoverBg?.toString(),\n        },\n        \"&:active\": {\n            background: theme.button.hidden?.activeBg?.toString(),\n        },\n    },\n    shrinkable: {\n        maxWidth: \"max-content\",\n        width: \"100%\",\n        flex: 1,\n\n        minWidth: \"3rem\", //todo: maybe you can be smart the somehow set this to the icon\n        overflow: \"hidden\",\n    },\n}));\n\nexport interface ButtonProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, \"title\"> {\n    ref?: React.Ref<HTMLDivElement>;\n    onClick?: React.MouseEventHandler<HTMLElement>;\n    className?: string;\n    linkClassName?: string;\n    linkStyle?: React.CSSProperties;\n    style?: React.CSSProperties;\n    icon?: IconProp;\n    iconRight?: boolean;\n    iconSpin?: boolean;\n    small?: boolean;\n    large?: boolean;\n    tiny?: boolean;\n    title?: React.ReactNode;\n    variant?: ButtonVariant | \"\" | null;\n    disabled?: boolean;\n    size?: \"small\" | \"large\" | \"tiny\";\n    shrinkable?: boolean;\n    variants?: ButtonVariant[];\n    titlePosition?: TooltipPosition;\n    titleDelay?: true | number;\n    margin?: boolean;\n    elevated?: boolean;\n    round?: boolean;\n    menuItems?: DropDownMenuItems;\n    menuLabel?: string;\n    /** parents of the button might check for defaultPrevented (e.g. Popover implementation requires we don't call preventDefault()) */\n    preventDefaultClick?: boolean;\n    isIconButton?: boolean; //should be marked true if children is just a fontawesome icon and you want the button to be the same height and width\n}\n\nexport const Button = ({ ref, ...props }: React.PropsWithChildren<ButtonProps>) => {\n    /*eslint prefer-const: [\"error\", {\"destructuring\": \"all\"}]*/\n    const isPySpace = useIsPySpace();\n    let {\n        children,\n        variant,\n        variants = [],\n        small,\n        large,\n        tiny,\n        margin,\n        icon = null,\n        iconRight = false,\n        iconSpin = false,\n        disabled = false,\n        className,\n        menuItems = null,\n        menuLabel = \"More actions\",\n        title,\n        titlePosition = \"right\",\n        titleDelay,\n        onClick,\n        onDoubleClick,\n        onKeyDown,\n        shrinkable = false,\n        preventDefaultClick = true,\n        linkClassName,\n        linkStyle,\n        style,\n        size,\n        elevated = isPySpace, //only relevant to pyspace\n        round = false, //only relevant to pyspace\n        isIconButton = false, //only relevant to pyspace\n        ...restProps\n    } = props;\n\n    const { classes } = useStyles();\n    const iconOnly = !!icon && React.Children.count(children) === 0;\n\n    if (small) {\n        size = \"small\";\n    } else if (large) {\n        size = \"large\";\n    } else if (tiny) {\n        size = \"tiny\";\n    }\n\n    if (margin) {\n        style = { margin: `0 ${size === \"small\" ? \"0.5\" : size === \"tiny\" ? \"0.2\" : \"0.8\"}rem`, ...style };\n    }\n\n    const [tooltip, anchorRef] = useTooltip(title, titlePosition, { delay: titleDelay });\n    const buttonRef = useMergeRefs(anchorRef, ref);\n\n    return (\n        <div\n            ref={buttonRef}\n            style={style}\n            className={cx(\n                classes.root,\n                className,\n                size && classes[`${size}Root`],\n                disabled && classes.disabled,\n                shrinkable && classes.shrinkable\n            )}>\n            {title && tooltip}\n            <LinkInternal\n                onClick={(e) => disabled || onClick?.(e)}\n                className={cx(\n                    classes.main,\n                    size && classes[size],\n                    variant && classes[variant],\n                    iconOnly && classes.iconOnly,\n                    icon && !iconOnly && !iconRight && classes.withIconLeft,\n                    icon && !iconOnly && iconRight && classes.withIconRight,\n                    menuItems && classes.withDropdown,\n                    linkClassName,\n                    isPySpace && !disabled && (elevated ? \"ps-hover-raise-2\" : \"ps-hover-raise-1\"),\n                    ...variants.map((v) => classes[v]),\n                    disabled && classes.disabled,\n                    isPySpace &&\n                        round &&\n                        \"h-fit! rounded-full! px-[1.4rem]! py-[0.4rem]! text-[1.6rem] leading-[150%]!\",\n                    isPySpace && isIconButton && \"m-px! aspect-square! p-[0.2rem]!\"\n                )}\n                onDoubleClick={(e) => disabled || onDoubleClick?.(e)}\n                onKeyDown={(event) => {\n                    onKeyDown?.(event);\n                    if (\n                        !event.defaultPrevented &&\n                        !disabled &&\n                        event.target === event.currentTarget &&\n                        (event.key === \"Enter\" || event.key === \" \")\n                    ) {\n                        event.preventDefault();\n                        event.stopPropagation();\n                        event.currentTarget.click();\n                    }\n                }}\n                style={linkStyle}\n                shrinkable={shrinkable}\n                preventDefaultClick={preventDefaultClick}\n                {...restProps}>\n                {icon && iconOnly && <FontAwesomeIcon className={classes.icon} icon={icon} spin={iconSpin} />}\n                {icon && !iconOnly && !iconRight && (\n                    <div className={cx(classes.icon, classes.iconLeft)}>\n                        <FontAwesomeIcon icon={icon} spin={iconSpin} />\n                    </div>\n                )}\n                {shrinkable ? (\n                    <div className={\"flex-1 overflow-hidden text-ellipsis whitespace-nowrap\"}>{children}</div>\n                ) : (\n                    children\n                )}\n                {icon && !iconOnly && iconRight && (\n                    <div className={cx(classes.icon, classes.iconRight)}>\n                        <FontAwesomeIcon icon={icon} spin={iconSpin} />\n                    </div>\n                )}\n            </LinkInternal>\n            {menuItems && (\n                <DropdownMenu\n                    render={(showMenu, anchor) => (\n                        <LinkInternal\n                            aria-label={menuLabel}\n                            aria-haspopup=\"true\"\n                            onClick={(e) => showMenu(null, e.currentTarget)}\n                            onKeyDown={(event) => {\n                                if (!disabled && (event.key === \"Enter\" || event.key === \" \")) {\n                                    event.preventDefault();\n                                    event.stopPropagation();\n                                    showMenu(null, event.currentTarget);\n                                }\n                            }}\n                            className={cx(\n                                classes.dropdownTrigger,\n                                variant && classes[variant],\n                                size && classes[size],\n                                ...variants.map((v) => classes[v]),\n                                disabled && classes.disabled\n                            )}>\n                            <FontAwesomeIcon icon={size === \"small\" ? faEllipsisV : faEllipsisV} />\n                            <div className={classes.dropdownAnchor}>{anchor}</div>\n                        </LinkInternal>\n                    )}\n                    items={disabled ? () => [] : menuItems}\n                    align={\"right\"}\n                />\n            )}\n        </div>\n    );\n};\n","import * as React from \"react\";\nimport { cx, makeStyles, useIsPySpace } from \"../../theme/styles\";\nimport { ignoreSsrWarning } from \"../../theme/utils\";\nimport { useLongPress } from \"../../util/useLongPress\";\nimport { Button, ButtonProps, ButtonVariant } from \"./Button\";\n\nconst useStyles = makeStyles()((theme) => {\n    const groupTheme = (theme.buttonGroup ?? {}) as any;\n    return {\n        root: {\n            display: groupTheme.display ?? \"block\",\n            \"& > * > *\": {\n                borderRadius: \"0 !important\",\n            },\n            [`& > *:first-child${ignoreSsrWarning} > *`]: {\n                borderLeft: groupTheme.firstBorder,\n                borderRadius: groupTheme.firstBorderRadius ?? \"5px 0 0 5px !important\",\n            },\n            \"& > *:last-child > *\": {\n                borderRadius: groupTheme.lastBorderRadius ?? \"0 5px 5px 0 !important\",\n            },\n            \"& > *:not(:first-child)\": {\n                marginLeft: groupTheme.marginLeft ?? \"0\",\n            },\n            \"& > *:not(:first-child) > *\": {\n                borderLeft: \"0 !important\",\n            },\n        },\n    };\n});\n\ninterface ButtonGroupOption {\n    value: any;\n    title: React.ReactNode;\n    disabled?: boolean;\n}\ntype ButtonGroupOptions = ButtonGroupOption[] | readonly ButtonGroupOption[];\n\ninterface ButtonGroupProps<T extends ButtonGroupOptions> extends Omit<ButtonProps, \"onClick\"> {\n    options: T;\n    selectedVariant?: ButtonVariant;\n    selectedOption: T[number][\"value\"] | readonly T[number][\"value\"][];\n    onClick?: (value: T[number][\"value\"]) => void;\n    onDoubleClick?: (value: T[number][\"value\"]) => void;\n    allowReselect?: boolean;\n}\n\ninterface ButtonGroupItemProps<T extends ButtonGroupOptions> {\n    option: T[number];\n    isSelected: boolean;\n    selectedVariant?: ButtonVariant;\n    variant?: ButtonVariant;\n    isPySpace: boolean;\n    elevated: boolean;\n    disabled?: boolean;\n    onClick?: () => void;\n    onDoubleClick?: () => void;\n    buttonProps: Omit<ButtonProps, \"onClick\" | \"onDoubleClick\" | \"onTouchStart\" | \"onTouchEnd\" | \"onTouchMove\">;\n}\n\nconst ButtonGroupItem = <T extends ButtonGroupOptions>({\n    option,\n    isSelected,\n    selectedVariant,\n    variant,\n    isPySpace,\n    elevated,\n    disabled,\n    onClick,\n    onDoubleClick,\n    buttonProps,\n}: ButtonGroupItemProps<T>) => {\n    let longPressHandlers = useLongPress(() => onDoubleClick?.(), { threshold: 400 });\n    if (!onDoubleClick || option.disabled) {\n        longPressHandlers = {} as any;\n    }\n\n    return (\n        <Button\n            variant={isSelected ? selectedVariant : isPySpace ? \"highlight3\" : variant}\n            onClick={onClick}\n            onDoubleClick={onDoubleClick}\n            style={{ flex: \"1 1 100%\", height: isPySpace ? \"4rem\" : \"\" }}\n            linkClassName={cx(\n                isPySpace && \"text-[1.6rem] leading-8 font-semibold\",\n                isPySpace && \"hover:translate-x-0!\",\n                isPySpace &&\n                    (elevated\n                        ? \"hover:shadow-pselevated2_v! active:shadow-pselevated1!\"\n                        : \"hover:shadow-pselevated1_v! active:shadow-none!\")\n            )}\n            elevated={elevated}\n            disabled={option.disabled || disabled}\n            {...buttonProps}\n            {...longPressHandlers}>\n            {option.title}\n        </Button>\n    );\n};\n\nexport const ButtonGroup = <T extends ButtonGroupOptions>({\n    options,\n    selectedVariant,\n    selectedOption,\n    onClick,\n    onDoubleClick,\n    allowReselect = false,\n    className,\n    style,\n    variant,\n    elevated = true,\n    ...props\n}: ButtonGroupProps<T>) => {\n    const isPySpace = useIsPySpace();\n\n    const { classes } = useStyles();\n    const { disabled, ...buttonProps } = props;\n\n    return (\n        <div style={style} className={cx(classes.root, className)}>\n            {options.map((option) => {\n                const selectedValues = Array.isArray(selectedOption)\n                    ? (selectedOption as readonly T[number][\"value\"][])\n                    : undefined;\n                const isSelected = selectedValues\n                    ? selectedValues.includes(option.value)\n                    : selectedOption === option.value;\n\n                return (\n                    <ButtonGroupItem\n                        key={option.value}\n                        option={option}\n                        isSelected={isSelected}\n                        selectedVariant={selectedVariant}\n                        variant={(variant as ButtonVariant | undefined) ?? undefined}\n                        isPySpace={isPySpace}\n                        elevated={elevated}\n                        disabled={disabled}\n                        onClick={() => {\n                            if (!allowReselect && isSelected && !selectedValues) return;\n                            onClick?.(option.value);\n                        }}\n                        onDoubleClick={() => !option.disabled && onDoubleClick?.(option.value)}\n                        buttonProps={buttonProps}\n                    />\n                );\n            })}\n        </div>\n    );\n};\n","import * as React from \"react\";\nimport { faChevronRight } from \"@fortawesome/free-solid-svg-icons/faChevronRight\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport type { EditPath } from \"@designer/shared-types\";\nimport { cx, makeStyles } from \"@/theme/styles\";\n\nlet useStyles = makeStyles()((theme) => ({\n    root: {\n        display: \"inline-block\",\n    },\n    breadcrumb: {\n        display: \"inline-block\",\n        //backgroundColor: theme.bg0.hex(),\n        padding: 2,\n        margin: -2,\n        //borderRadius: 2,\n    },\n    pathElement: {\n        display: \"inline-block\",\n        fontWeight: \"bold\",\n        padding: \"0 4px\",\n        fontSize: \"90%\",\n        borderRadius: \"0.6rem\",\n        backgroundColor: theme.palette.bg2.hex(),\n        marginRight: \"0.4rem\",\n    },\n    pathSep: {\n        fontSize: \"60%\",\n        marginRight: \"0.4rem\",\n    },\n    marginLeft: {\n        marginLeft: \"0.6rem\",\n    },\n}));\n\ninterface BreadcrumbsProps {\n    className?: string;\n    path: EditPath;\n}\n\nexport const Breadcrumbs = ({ className, path }: BreadcrumbsProps) => {\n    const { classes } = useStyles();\n\n    return (\n        <div className={cx(classes.root, className)}>\n            {path.map((p, idx) => (\n                <div key={idx} className={cx(classes.breadcrumb, className)}>\n                    {idx !== 0 && <FontAwesomeIcon icon={faChevronRight} className={classes.pathSep} />}\n                    <div className={classes.pathElement}>{p}</div>\n                </div>\n            ))}\n        </div>\n    );\n};\n","import React, { ReactNode, useCallback, useMemo, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faClock } from \"@fortawesome/free-solid-svg-icons\";\nimport { faChevronDown } from \"@fortawesome/free-solid-svg-icons/faChevronDown\";\nimport { faChevronRight } from \"@fortawesome/free-solid-svg-icons/faChevronRight\";\nimport { faUser } from \"@fortawesome/free-solid-svg-icons/faUser\";\nimport { faCodeBranch } from \"@fortawesome/pro-solid-svg-icons/faCodeBranch\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport * as api from \"@/api\";\nimport { getAppId } from \"@/controllers/app\";\nimport { getCodeNames } from \"@/controllers/app/code\";\nimport { getAppCommitHistory } from \"@/controllers/app/history\";\nimport { alert } from \"@/controllers/modals\";\nimport { CodeNavTarget } from \"@/router/navTypes\";\nimport { navigate } from \"@/router/navigation\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch, StructureItem } from \"@/types\";\nimport type { CommitHistory, CommitVersion } from \"@/types/app-history\";\nimport { useEffectAsync } from \"@/util/hooks\";\nimport { Breadcrumbs } from \"./Breadcrumbs\";\nimport { LinkInternal } from \"./LinkInternal\";\nimport Loading from \"./Loading\";\nimport { CodeWithMarkers, StructuralValueDiff, addedBackground, removedBackground } from \"./StructuralValueDiff\";\n\ntype DiffItemId = string | string[];\ntype DiffItemTuple = [string, DiffItemId];\n\ninterface DiffTextChunk {\n    lines: {\n        a: [number, number];\n        b?: [number, number];\n    };\n    content: {\n        a?: string;\n        b?: string;\n    };\n}\n\ninterface DiffConfigEdit {\n    path: Array<string | number>;\n    type: string;\n    from?: unknown;\n    to?: unknown;\n}\n\ntype DiffStructureChange =\n    | {\n          type: \"module_structure\";\n          from?: \"module\" | \"package\";\n          to?: \"module\" | \"package\";\n      }\n    | {\n          type: \"template_format\";\n          from?: \"yaml\" | \"html\";\n          to?: \"yaml\" | \"html\";\n      };\n\ntype DiffComponentEditType =\n    | \"add\"\n    | \"remove\"\n    | \"move\"\n    | \"property\"\n    | \"layout_property\"\n    | \"event_binding\"\n    | \"data_binding\"\n    | (string & {});\n\ntype JsonPrimitive = string | number | boolean | null;\ntype JsonValue = JsonPrimitive | JsonValue[] | JsonObject;\ntype JsonObject = { [key: string]: JsonValue | undefined };\n\ntype SlotParent = [\"slot\", string];\ntype ParentReference = string | SlotParent;\ntype ParentDisplay = ParentReference | undefined;\n\nconst isSlotParent = (value: unknown): value is SlotParent =>\n    Array.isArray(value) && value[0] === \"slot\" && typeof value[1] === \"string\";\n\nconst hasParentField = (value: unknown): value is { parent?: unknown } =>\n    typeof value === \"object\" && value !== null && \"parent\" in value;\n\nconst normalizeParent = (value: unknown): ParentDisplay => {\n    if (isSlotParent(value)) {\n        return value;\n    }\n    if (typeof value === \"string\") {\n        return value;\n    }\n    return undefined;\n};\n\nconst extractParentFromLocation = (location: unknown): ParentDisplay => {\n    if (Array.isArray(location)) {\n        return normalizeParent((location as unknown[])[0]);\n    }\n    return normalizeParent(location);\n};\n\nconst parentsEqual = (a: ParentDisplay, b: ParentDisplay) => {\n    if (isSlotParent(a) && isSlotParent(b)) {\n        return a[1] === b[1];\n    }\n    return a === b;\n};\n\nconst renderParentDisplay = (parent: ParentDisplay): ReactNode =>\n    isSlotParent(parent) ? (\n        <>\n            slot <b>{parent[1]}</b>\n        </>\n    ) : (\n        <b>{parent ?? \"\"}</b>\n    );\n\ninterface DataBindingState extends JsonObject {\n    code?: string;\n    writeback?: boolean;\n}\n\ntype ComponentSnapshot = JsonObject & {\n    parent?: ParentReference;\n    parent_type?: string;\n    idx?: number;\n    layout_properties?: Record<string, JsonValue> | undefined;\n    type?: string;\n};\n\ntype ComponentMoveTuple = [\n    ParentDisplay,\n    number | undefined,\n    Record<string, JsonValue> | undefined,\n    string | undefined,\n];\n\ntype DiffComponentAdd = {\n    type: \"add\";\n    component: string;\n    to: ComponentSnapshot;\n    parent_type?: string;\n};\n\ntype DiffComponentRemove = {\n    type: \"remove\";\n    component: string;\n    from: ComponentSnapshot;\n};\n\ntype DiffComponentMove = {\n    type: \"move\";\n    component: string;\n    from: ComponentMoveTuple;\n    to: ComponentMoveTuple;\n};\n\ntype DiffComponentPropertyChange = {\n    type: \"property\" | \"layout_property\" | \"event_binding\";\n    component: string;\n    key: string;\n    from?: JsonValue;\n    to?: JsonValue;\n};\n\ntype DiffComponentDataBindingChange = {\n    type: \"data_binding\";\n    component: string;\n    key: string;\n    from?: DataBindingState;\n    to?: DataBindingState;\n};\n\ntype DiffComponentEditChange =\n    | DiffComponentAdd\n    | DiffComponentRemove\n    | DiffComponentMove\n    | DiffComponentPropertyChange\n    | DiffComponentDataBindingChange;\n\ninterface DiffItemData {\n    item: DiffItemTuple;\n    text_chunks?: DiffTextChunk[];\n    is_binary?: boolean;\n    whole_text?: string;\n    structure?: DiffStructureChange[];\n    edits?: DiffConfigEdit[];\n    components?: DiffComponentEditChange[];\n}\n\ninterface DiffData {\n    changed_items?: DiffItemData[];\n    error?: string;\n}\n\ninterface DiffItemDescriptor {\n    type: string;\n    typeName: string;\n    id: DiffItemId;\n    name: string | null;\n}\n\ninterface CodeNamesMap {\n    [key: string]: StructureItem | undefined;\n}\n\nconst formatDiffItemId = (id: DiffItemId): string => (Array.isArray(id) ? id.join(\"/\") : id);\n\n// TODO: Working out the paths to items is tricky here, because they're not necessarily items in the loaded app\nconst describeItem = ([type, id]: DiffItemTuple): DiffItemDescriptor => {\n    switch (type) {\n        case \"client_code\":\n            return { type, typeName: \"Client\", id, name: formatDiffItemId(id) };\n        case \"server_code\":\n            return { type, typeName: \"Server\", id, name: formatDiffItemId(id) };\n        case \"asset\":\n            return { type, typeName: \"Asset\", id, name: formatDiffItemId(id) };\n        case \"config\":\n            if (Array.isArray(id) && id[0] === \"theme\") {\n                return { type, typeName: \"Theme\", id, name: id[1] ?? null };\n            }\n            return {\n                type,\n                typeName: \"Settings\",\n                id,\n                name: Array.isArray(id) ? (id.length !== 0 ? id.join(\"/\") : null) : formatDiffItemId(id),\n            };\n        default:\n            return { type, typeName: `Unknown ${type}`, id, name: formatDiffItemId(id) };\n    }\n};\n\nconst getCodeItemForId = (codeNames: CodeNamesMap, id: DiffItemId): StructureItem | undefined => {\n    return codeNames[formatDiffItemId(id)];\n};\n\nconst structureChangeLabels: Record<DiffStructureChange[\"type\"], string> = {\n    module_structure: \"Code structure\",\n    template_format: \"Template format\",\n};\n\nconst structureChangeValueLabels: Record<string, string> = {\n    module: \"Module\",\n    package: \"Package\",\n    yaml: \"YAML\",\n    html: \"HTML\",\n};\n\ninterface DiffComponentEditProps {\n    component: string;\n    edit: DiffComponentEditChange;\n    className?: string;\n}\n\nexport const DiffComponentEdit: React.FC<DiffComponentEditProps> = ({ component, edit, className }) => {\n    const renderDataBindingState = (value: DataBindingState | undefined, wasAdded: boolean) => {\n        if (!value) {\n            return null;\n        }\n\n        const { code, writeback } = value;\n        return (\n            <CodeWithMarkers\n                className={wasAdded ? addedBackground : removedBackground}\n                marker={wasAdded ? \"+\" : \"-\"}\n                content={\n                    (code ?? \"\") +\n                    (writeback === undefined ? \"\" : `\\n(writeback ${writeback ? \"ENABLED\" : \"DISABLED\"})`)\n                }\n            />\n        );\n    };\n\n    const renderDetails = (): ReactNode => {\n        switch (edit.type) {\n            case \"property\":\n            case \"layout_property\":\n            case \"event_binding\": {\n                const { from, to } = edit;\n                return <StructuralValueDiff from={from} to={to} />;\n            }\n            case \"data_binding\": {\n                const { from, to } = edit;\n                return (\n                    <>\n                        {renderDataBindingState(from, false)}\n                        {renderDataBindingState(to, true)}\n                    </>\n                );\n            }\n            default:\n                return null;\n        }\n    };\n\n    const renderSummary = (): ReactNode => {\n        switch (edit.type) {\n            case \"add\": {\n                const parentDisplay = normalizeParent(edit.to.parent);\n                return (\n                    <i>\n                        Added\n                        {parentDisplay ? (\n                            <>\n                                {\" to \"}\n                                {renderParentDisplay(parentDisplay)}\n                            </>\n                        ) : null}\n                    </i>\n                );\n            }\n            case \"remove\":\n                return <i>Removed</i>;\n            case \"move\": {\n                const toParentLocation = extractParentFromLocation(edit.to);\n                const fromParentLocation = extractParentFromLocation(edit.from);\n                return (\n                    <i>\n                        Moved {parentsEqual(toParentLocation, fromParentLocation) ? \"within\" : \"to\"}{\" \"}\n                        {renderParentDisplay(toParentLocation)}\n                    </i>\n                );\n            }\n            case \"property\": {\n                const { key } = edit;\n                return (\n                    <span>\n                        <b>.{key}</b> <i>changed</i>\n                    </span>\n                );\n            }\n            case \"layout_property\": {\n                const { key } = edit;\n                return (\n                    <span>\n                        <i> layout</i>\n                        {` ${key} `}\n                        <i>changed</i>\n                    </span>\n                );\n            }\n            case \"event_binding\": {\n                const { key } = edit;\n                return (\n                    <span>\n                        {\" \"}\n                        <i>event</i>\n                        <b>{` ${key}`}</b>\n                    </span>\n                );\n            }\n            case \"data_binding\": {\n                const { key } = edit;\n                return (\n                    <span>\n                        {\" \"}\n                        data binding for<b>{` ${key}`}</b>\n                    </span>\n                );\n            }\n            default:\n                return null;\n        }\n    };\n\n    return (\n        <div className={className}>\n            <b>{component}</b> {renderSummary()}\n            {renderDetails()}\n        </div>\n    );\n};\n\ninterface DiffItemProps {\n    item: DiffItemData;\n    codeItem?: StructureItem;\n}\n\nconst lineTarget = (lines: DiffTextChunk[\"lines\"], codeItem: StructureItem) =>\n    ({\n        type: \"CODE\",\n        codePath: codeItem.codePath,\n        essentialView: { code: [lines.a[0] + 1, 0] },\n    }) satisfies CodeNavTarget;\n\nconst DiffItem: React.FC<DiffItemProps> = ({ item: diffItem, codeItem }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const [expanded, setExpanded] = useState(false);\n\n    const navigateOrPopUp = useCallback(\n        (lines: DiffTextChunk[\"lines\"]) => {\n            if (codeItem) {\n                dispatch(navigate(lineTarget(lines, codeItem)));\n            } else {\n                dispatch(\n                    alert(\n                        \"Unable to jump to line\",\n                        \"The item you are trying to jump to does not exist in this version of your app. Please change to a different version.\"\n                    )\n                );\n            }\n        },\n        [codeItem, diffItem.item]\n    );\n\n    /** @todo fix id: itemPath here */\n    const { id, name, typeName } = diffItem.item\n        ? describeItem(diffItem.item)\n        : {\n              id: \"unknown\",\n              typeName: \"Unknown\",\n              name: null,\n          };\n\n    const renderConfigEdits = (edits: DiffConfigEdit[]) => (\n        <div className=\"space-y-2\">\n            {edits.map(({ path, type, from, to }) => (\n                <div className=\"space-y-2\" key={JSON.stringify(path)}>\n                    <div>\n                        <Breadcrumbs path={path} />\n                    </div>\n                    <StructuralValueDiff\n                        from={type !== \"add\" ? from : undefined}\n                        to={type !== \"remove\" ? to : undefined}\n                    />\n                </div>\n            ))}\n        </div>\n    );\n\n    const renderStructureChanges = (structureChanges: DiffStructureChange[]) => (\n        <div className=\"space-y-2\">\n            {structureChanges.map(({ type, from, to }) => (\n                <div className=\"space-y-2\" key={`${type}/${from ?? \"_\"}/${to ?? \"_\"}`}>\n                    <div>\n                        <Breadcrumbs path={[structureChangeLabels[type]]} />\n                    </div>\n                    <StructuralValueDiff\n                        from={from ? structureChangeValueLabels[from] : undefined}\n                        to={to ? structureChangeValueLabels[to] : undefined}\n                    />\n                </div>\n            ))}\n        </div>\n    );\n\n    const renderComponentEdits = (components: DiffComponentEditChange[]) => (\n        <div>\n            {components.map((edit) => (\n                <DiffComponentEdit\n                    component={edit.component}\n                    edit={edit}\n                    key={`${edit.component}/${edit.type}/${\"key\" in edit ? (edit.key ?? \"_\") : \"_\"}`}\n                />\n            ))}\n        </div>\n    );\n\n    const renderTextEdits = (textChunks: DiffTextChunk[]) => (\n        <div className=\"space-y-2\">\n            {textChunks.map(({ lines, content }) => (\n                <div key={lines.a[0]}>\n                    <i>\n                        <LinkInternal className=\"underline hover:no-underline\" onClick={() => navigateOrPopUp(lines)}>\n                            Line {lines.a[0] + 1}\n                        </LinkInternal>\n                        :\n                    </i>\n\n                    {content.a && <CodeWithMarkers className={removedBackground} marker={\"-\"} content={content.a} />}\n                    {content.b && <CodeWithMarkers className={addedBackground} marker={\"+\"} content={content.b} />}\n                </div>\n            ))}\n        </div>\n    );\n\n    return (\n        <div className=\"mb-6\">\n            <h5 className=\"whitespace-nowrap\">\n                <LinkInternal onClick={() => setExpanded((e) => !e)}>\n                    <FontAwesomeIcon fixedWidth={true} icon={expanded ? faChevronDown : faChevronRight} />\n                    {<b>{name ?? formatDiffItemId(id)}</b>} <i>{typeName}</i>\n                </LinkInternal>\n            </h5>\n            {expanded && (\n                <div className=\"flex\">\n                    <div className=\"bg-light-bg1 px-4 whitespace-nowrap dark:bg-dark-bg3\">\n                        {diffItem.whole_text && <div className=\"text-sm italic\">File {diffItem.whole_text}</div>}\n                        {diffItem.is_binary && <div className=\"text-sm italic\">(Binary File)</div>}\n                        {diffItem.structure && renderStructureChanges(diffItem.structure)}\n                        {diffItem.edits && renderConfigEdits(diffItem.edits)}\n                        {diffItem.components && renderComponentEdits(diffItem.components)}\n                        {diffItem.text_chunks && renderTextEdits(diffItem.text_chunks)}\n                    </div>\n                </div>\n            )}\n            <hr className=\"border-light-bg2 dark:border-dark-bg2\" />\n        </div>\n    );\n};\n\ninterface CommitMessage {\n    summary: string;\n    body: string;\n}\n\ninterface CommitDetailProps {\n    diffData: DiffData;\n    commit?: CommitVersion;\n    showDetails?: boolean;\n    className?: string;\n}\n\nexport const CommitDetail: React.FC<CommitDetailProps> = ({ diffData, commit, showDetails, className }) => {\n    const allCodeNames = useSelector(getCodeNames);\n    const commitMessage = useMemo<CommitMessage>(() => {\n        const message = commit?.m ?? \"\";\n\n        if (!message) {\n            return { summary: \"\", body: \"\" };\n        }\n\n        const [rawSummary, ...bodyLines] = message.split(/\\r?\\n/);\n        const trimmedMessage = message.trim();\n        const summary = rawSummary?.trim() || trimmedMessage || \"\";\n        const body = bodyLines.join(\"\\n\").replace(/^\\n+/, \"\").replace(/\\s+$/, \"\");\n\n        return { summary, body };\n    }, [commit]);\n\n    return (\n        <div className={cx(className, \"offset-vscrollbar space-y-6 p-4\")}>\n            {commit && showDetails && (\n                <div className=\"space-y-3\">\n                    <h4 className=\"text-[2rem] leading-tight font-semibold select-text\">\n                        {commitMessage.summary || \"Commit details\"}\n                    </h4>\n                    <div className=\"mt-2 flex flex-wrap items-center gap-2 select-text\">\n                        <span className=\"flex items-center gap-1 rounded-md bg-light-bg2 px-2 py-1 text-[1.1rem] whitespace-nowrap dark:bg-dark-bg2\">\n                            <FontAwesomeIcon icon={faUser} />\n                            <span>{commit.e}</span>\n                        </span>\n                        <span className=\"flex items-center gap-1 rounded-md bg-light-bg2 px-2 py-1 text-[1.1rem] whitespace-nowrap dark:bg-dark-bg2\">\n                            <FontAwesomeIcon icon={faClock} />\n                            <span>{commit.t ? new Date(commit.t * 1000).toLocaleString() : \"\"}</span>\n                        </span>\n                        <span className=\"flex items-center gap-1 rounded-md bg-light-bg2 px-2 py-1 font-mono text-[1.1rem] whitespace-nowrap dark:bg-dark-bg2\">\n                            <FontAwesomeIcon icon={faCodeBranch} />\n                            <code>{commit.v}</code>\n                        </span>\n                    </div>\n                    {commitMessage.body && (\n                        <div className=\"rounded-lg bg-light-bg1 px-5 py-4 text-xl leading-relaxed whitespace-pre-wrap select-text dark:bg-dark-bg3\">\n                            {commitMessage.body}\n                        </div>\n                    )}\n                    <hr className=\"border-light-bg2 dark:border-dark-bg2\" />\n                </div>\n            )}\n            {diffData?.error ? (\n                <i>Could not display diff: {diffData.error}</i>\n            ) : diffData.changed_items?.length ? (\n                diffData.changed_items.map((item) => (\n                    <DiffItem\n                        key={item.item.toString()}\n                        item={item}\n                        codeItem={getCodeItemForId(allCodeNames, item.item[1])}\n                    />\n                ))\n            ) : (\n                <i>No changes in this commit</i>\n            )}\n        </div>\n    );\n};\n\ninterface CommitDetailsProps {\n    commitIdA?: string | null;\n    commitIdB: string;\n    forMerge?: boolean;\n    showDetails?: boolean;\n    className?: string;\n}\n\nexport const CommitDetails: React.FC<CommitDetailsProps> = ({\n    commitIdA,\n    commitIdB,\n    forMerge,\n    showDetails = true,\n    className,\n}) => {\n    const [diffData, setDiffData] = useState<DiffData | undefined>();\n    const appId = useSelector(getAppId);\n    const commitHistory = useSelector(getAppCommitHistory);\n\n    const selectedCommit = commitHistory?.versions?.find((v) => v.v === commitIdB);\n\n    useEffectAsync(\n        async function* () {\n            if (!appId) {\n                setDiffData({});\n                return;\n            }\n\n            if (commitIdA) {\n                let diff: DiffData;\n                try {\n                    diff = (await api.getDiff(appId, commitIdA, commitIdB, forMerge)) as DiffData;\n                } catch (e: any) {\n                    diff = { error: e?.message || \"Could not compute diff\" };\n                }\n                yield;\n                setDiffData(diff);\n            } else {\n                setDiffData({});\n            }\n        },\n        [appId, commitIdA, commitIdB, forMerge]\n    );\n\n    if (!diffData) {\n        return <Loading indicator={true}></Loading>;\n    }\n\n    return <CommitDetail className={className} diffData={diffData} commit={selectedCommit} showDetails={showDetails} />;\n};\n\nexport default CommitDetail;\n","import React, { useRef, useState } from \"react\";\nimport { faCheck, faClone } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { cx } from \"@/theme/styles\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { Button, ButtonProps } from \"./Button\";\n\ninterface CopyButtonProps extends ButtonProps {\n    copyText: string | (() => string);\n}\n\nexport function copyTextToClipboard(text: string) {\n    if (navigator.clipboard?.writeText) {\n        return navigator.clipboard.writeText(text);\n    }\n    // mostly for http://pyspace.local:3000 where navigator isn't available\n    const textArea = document.createElement(\"textarea\");\n    textArea.style.position = \"absolute\";\n    textArea.style.inset = \"0\";\n    textArea.value = text;\n    document.body.prepend(textArea);\n\n    textArea.select();\n    try {\n        document.execCommand(\"copy\");\n    } finally {\n        document.body.removeChild(textArea);\n    }\n}\n\nexport const CopyButton = ({ copyText, ...props }: CopyButtonProps) => {\n    const copiedTimeout = useRef<number | undefined>(undefined);\n    const [copied, setCopied] = useState(false);\n    const useCopiedHighlight = !props.variant;\n\n    const doCopy = useEvent(async () => {\n        clearTimeout(copiedTimeout.current);\n        await copyTextToClipboard(typeof copyText === \"function\" ? copyText() : copyText);\n        setCopied(true);\n        copiedTimeout.current = setTimeout(() => {\n            setCopied(false);\n        }, 3000);\n    });\n\n    const onBlur = useEvent(() => {\n        clearTimeout(copiedTimeout.current);\n        setCopied(false);\n    });\n\n    return (\n        <Button onBlur={onBlur} onClick={doCopy} {...props}>\n            <FontAwesomeIcon\n                className={cx(copied && useCopiedHighlight && \"text-highlight\")}\n                fixedWidth\n                icon={copied ? faCheck : faClone}\n            />\n        </Button>\n    );\n};\n","import React, { useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\r\nimport ReactDOM from \"react-dom\";\r\nimport {\r\n    type VirtualElement,\r\n    autoUpdate,\r\n    flip,\r\n    offset as floatingOffset,\r\n    shift,\r\n    useFloating,\r\n} from \"@floating-ui/react-dom\";\r\nimport { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { every, isEmpty } from \"lodash-es\";\r\nimport { ManagerInstanceGlobalsContext } from \"@/instance-globals\";\r\nimport { cx, makeStyles } from \"@/theme/styles\";\r\nimport { ignoreSsrWarning } from \"@/theme/utils\";\r\nimport { getMouseEventOrTouch } from \"@/util/dnd\";\r\nimport { useMergeRefs, useStateWithCustomUpdate } from \"@/util/hooks\";\r\nimport useEvent from \"@/util/useEventCallback\";\r\n\r\n/*\r\n\r\n    Example usage:\r\n\r\n        <DropdownMenu\r\n            onSelectItem={(x) => {x && dispatch(alert(`You chose ${x}`));}}\r\n            render={(showMenu, anchor) =>\r\n                <div role='button' onClick={(e) => showMenu(null, e.currentTarget)}>\r\n                    Choose something <FontAwesomeIcon icon={faChevronDown}/>\r\n                    {anchor}\r\n                </div>\r\n            }\r\n            items={(selectItem, hideMenu) => [\r\n                \"One\",\r\n                [\"Two\", 2],\r\n                <hr/>,\r\n                <div>Custom thingy <button onClick={() => selectItem(\"Custom\")}>X</button></div>,\r\n                [\"Three\", () => dispatch(alert(`CUSTOM HANDLER: Three`))]\r\n            ]}\r\n        />\r\n\r\n    Attributes:\r\n\r\n    - render: A function returning the element to render here. It is passed two args, showMenu (a function that causes the dropdown menu to appear) and anchor (an element that should be placed where you want the menu to appear).\r\n    - align: 'left' or 'right' - which edge of the anchor to align to.\r\n    - onSelectItem: A function called when an item without a custom callback is selected from the menu.\r\n    - items: A function returning a list of menu items to display. It is passed two args, selectItem (a function f(x) that causes onSelectItem to be called with x) and hideMenu (a function which dismisses the menu without selecting anything).\r\n    - showMenu: Call showMenu(null, targetElement) for normal trigger buttons. Call showMenu(event, targetElement) for context menus that should open at the pointer but track the target element as it scrolls. If targetElement is omitted for an event, showMenu uses event.currentTarget when possible.\r\n\r\n      Each item can be:\r\n        - A string, in which case it is rendered and onSelectItem is called with the string as its argument when the item is clicked.\r\n        - A tuple [string|element, value|function, [icon]], in which case the string or element is displayed, and onSelectItem is called with the value when the item is clicked. Alternatively, if the value is a function, the function is called when the item is clicked (and if it returns precisely true, the menu is not hidden).\r\n        - An element, in which case no click handling is done. The element is responsible for calling selectItem or not as it wishes.\r\n\r\n\r\n    NOTE: on the rendered element, use onClick={(e) => showMenu(null, e.currentTarget)} so when the menu is open, if the button gets clicked again, the menu closes instead of reopening\r\n\r\n */\r\n\r\nexport const useStyles = makeStyles()((theme) => ({\r\n    menu: {\r\n        whiteSpace: \"nowrap\",\r\n        backgroundColor: theme.dropDownMenu.background.toString(),\r\n        color: theme.dropDownMenu.color.toString(),\r\n        border: `${theme.dropDownMenu.borderWidth ?? 1}px solid ${theme.dropDownMenu.borderColor}`,\r\n        boxShadow: theme.dropDownMenu.shadow || \"rgba(0, 0, 0, 0.16) 0 3px 6px 0\",\r\n        zIndex: 500,\r\n        fontSize: theme.dropDownMenu.fontSize,\r\n        fontWeight: theme.dropDownMenu.fontWeight,\r\n        \"& hr\": {\r\n            margin: theme.dropDownMenu.separatorMargin ?? 2,\r\n            borderColor: theme.dropDownMenu.borderColor.toString(),\r\n            borderTopWidth: theme.dropDownMenu.separatorWidth ?? 1,\r\n        },\r\n        padding: theme.dropDownMenu.padding,\r\n        transform: \"scaleY(0)\",\r\n        transformOrigin: \"top\",\r\n        transition: \"transform 0.05s linear\",\r\n        maxHeight: \"50vh\",\r\n        overflowY: \"auto\",\r\n        borderRadius: theme.dropDownMenu.borderRadius || 0,\r\n    },\r\n    opened: {\r\n        transform: \"scaleY(1)\",\r\n    },\r\n    item: {\r\n        display: \"flex\",\r\n        alignItems: \"center\",\r\n        padding: theme.dropDownMenu.itemPadding ?? \"0.5rem 1rem\",\r\n        \"&:hover\": {\r\n            background: theme.dropDownMenu.hoverBg.toString(),\r\n        },\r\n        [`&:first-child${ignoreSsrWarning}`]: {\r\n            paddingTop: theme.dropDownMenu.firstItemPaddingTop ?? theme.dropDownMenu.itemPadding ?? \"0.5rem\",\r\n        },\r\n        [`&:last-child${ignoreSsrWarning}`]: {\r\n            paddingBottom: theme.dropDownMenu.lastItemPaddingBottom ?? theme.dropDownMenu.itemPadding ?? \"0.5rem\",\r\n        },\r\n    },\r\n    itemContent: {\r\n        lineHeight: \"20px\",\r\n        flex: \"1 0 auto\",\r\n        minWidth: 0,\r\n    },\r\n    itemIcon: {\r\n        flex: \"0 0 auto\",\r\n        marginRight: \"1rem\",\r\n        fontSize: theme.dropDownMenu.iconFontSize ?? \"1.2rem\",\r\n    },\r\n}));\r\n\r\ninterface ItemProps extends React.HTMLAttributes<HTMLDivElement> {\r\n    icon?: IconDefinition | React.ReactElement;\r\n    disabled?: boolean;\r\n}\r\n\r\nexport const Item = ({ className, icon, children, disabled, ...props }: ItemProps) => {\r\n    const { classes } = useStyles();\r\n    return (\r\n        <div className={cx(className, classes.item, disabled && \"cursor-not-allowed text-light-grey1!\")} {...props}>\r\n            {React.isValidElement(icon) ? (\r\n                <div className={classes.itemIcon}>{icon}</div>\r\n            ) : (\r\n                icon && <FontAwesomeIcon className={classes.itemIcon} fixedWidth icon={icon as IconDefinition} />\r\n            )}\r\n            <div className={classes.itemContent}>{children}</div>\r\n        </div>\r\n    );\r\n};\r\n\r\ninterface MenuBodyProps {\r\n    ref?: React.Ref<HTMLDivElement>;\r\n    className?: string;\r\n    visible: boolean;\r\n    renderedItems?: MenuItems;\r\n    onBlur: React.FocusEventHandler;\r\n    onClickItem: (itemOrFn: any) => void;\r\n    onKeyDown: React.KeyboardEventHandler;\r\n    style?: React.CSSProperties;\r\n}\r\n\r\nconst MenuBody = ({ ref, className, visible, renderedItems, onBlur, onClickItem, onKeyDown, style }: MenuBodyProps) => {\r\n    const { classes } = useStyles();\r\n    const localRef = useRef<HTMLDivElement>(null!);\r\n\r\n    useEffect(() => {\r\n        if (visible) {\r\n            localRef.current.style.transform = \"scaleY(1)\";\r\n        } else {\r\n            localRef.current.style.transform = \"\";\r\n        }\r\n    }, [visible]);\r\n\r\n    const mergedRefs = useMergeRefs(localRef, ref);\r\n\r\n    // dropdown uses fixed b/c in pyspace you can scroll the body\r\n    return (\r\n        <div\r\n            ref={mergedRefs}\r\n            className={cx(\"fixed\", classes.menu, className)}\r\n            style={style}\r\n            tabIndex={-1}\r\n            hidden={!visible}\r\n            onKeyDown={onKeyDown}\r\n            onClick={(e) => e.stopPropagation()}>\r\n            {renderedItems?.map((x, i) =>\r\n                React.isValidElement(x) ? (\r\n                    <React.Fragment key={i}>{x}</React.Fragment>\r\n                ) : Array.isArray(x) ? (\r\n                    <Item\r\n                        key={i}\r\n                        tabIndex={0}\r\n                        role=\"button\"\r\n                        className={cx(classes.item, x[3]?.className)}\r\n                        onBlur={onBlur}\r\n                        icon={x[2]}\r\n                        disabled={x[3]?.disabled}\r\n                        onClick={() => {\r\n                            if (!x[3]?.disabled) {\r\n                                onClickItem(x[1]);\r\n                            }\r\n                        }}>\r\n                        {x[0]}\r\n                    </Item>\r\n                ) : x ? (\r\n                    <Item\r\n                        key={i}\r\n                        tabIndex={0}\r\n                        role=\"button\"\r\n                        className={classes.item}\r\n                        onBlur={onBlur}\r\n                        onClick={() => {\r\n                            onClickItem(x);\r\n                        }}>\r\n                        {x}\r\n                    </Item>\r\n                ) : null\r\n            )}\r\n        </div>\r\n    );\r\n};\r\n\r\ninterface MenuItemOptions {\r\n    className?: string;\r\n    disabled?: boolean;\r\n}\r\n\r\ntype TItem = unknown | (() => void);\r\n\r\ntype MenuItemNoIcon<T = TItem> = [React.ReactNode, T];\r\ntype MenuItemIcon<T = TItem> = [React.ReactNode, T, IconDefinition | React.ReactElement];\r\ntype MenuItemIconWithOptions<T = TItem> = [React.ReactNode, T, IconDefinition | React.ReactElement, MenuItemOptions];\r\nexport type MenuItem<T = TItem> =\r\n    | MenuItemNoIcon<T>\r\n    | MenuItemIcon<T>\r\n    | MenuItemIconWithOptions<T>\r\n    | React.ReactNode\r\n    | Readonly<MenuItemIcon<T>>\r\n    | Readonly<MenuItemNoIcon<T>>\r\n    | Readonly<MenuItemIconWithOptions<T>>;\r\n\r\nexport type MenuItems<T = TItem> = MenuItem<T>[];\r\n\r\nexport type ShowMenuCallback = (\r\n    e?: MouseEvent | React.MouseEvent | React.TouchEvent | TouchEvent | null | undefined,\r\n    target?: null | HTMLElement\r\n) => void;\r\n\r\nexport type DropDownMenuItems = (selectItem: (item: any) => void, hideMenu: () => void) => MenuItems;\r\n\r\ntype OverridePos = {\r\n    x: number;\r\n    y: number;\r\n    target?: HTMLElement | null;\r\n    offsetX?: number;\r\n    offsetY?: number;\r\n};\r\n\r\ninterface DropdownMenuProps {\r\n    render: (showMenu: ShowMenuCallback, anchor: React.ReactElement) => React.ReactElement;\r\n    align?: \"left\" | \"right\";\r\n    onHide?: () => void;\r\n    onShow?: () => boolean | void;\r\n    hideOnNoItems?: boolean;\r\n    items?: DropDownMenuItems;\r\n    onSelectItem?: (item: any) => void;\r\n    anchorToTrigger?: boolean;\r\n    menuClassName?: string;\r\n    offset?: number;\r\n}\r\n\r\nconst DropdownMenu = ({\r\n    render,\r\n    items,\r\n    onSelectItem,\r\n    align = \"left\",\r\n    onShow,\r\n    onHide,\r\n    hideOnNoItems = false,\r\n    anchorToTrigger = false,\r\n    menuClassName,\r\n    offset = 0,\r\n}: DropdownMenuProps) => {\r\n    // allows us to render the menu lazily\r\n    const [renderMenu, setRenderMenu] = useState(false);\r\n    const [visible, setVisible] = useStateWithCustomUpdate(false, (v: boolean) => {\r\n        if (v) setRenderMenu(true);\r\n        return v;\r\n    });\r\n\r\n    const [overridePos, setOverridePos] = useState<null | OverridePos>(null);\r\n\r\n    const menuRef = useRef<HTMLDivElement>(null!);\r\n    const anchorRef = useRef<HTMLDivElement>(null);\r\n    const clickRef = useRef<HTMLElement | null>(null);\r\n\r\n    const pointReference = useMemo<VirtualElement | null>(() => {\r\n        if (!overridePos) return null;\r\n        return {\r\n            contextElement: overridePos.target ?? undefined,\r\n            getBoundingClientRect: () => {\r\n                const x =\r\n                    overridePos.target && overridePos.offsetX !== undefined\r\n                        ? overridePos.target.getBoundingClientRect().left + overridePos.offsetX\r\n                        : overridePos.x;\r\n                const y =\r\n                    overridePos.target && overridePos.offsetY !== undefined\r\n                        ? overridePos.target.getBoundingClientRect().top + overridePos.offsetY\r\n                        : overridePos.y;\r\n                return {\r\n                    x,\r\n                    y,\r\n                    top: y,\r\n                    right: x,\r\n                    bottom: y,\r\n                    left: x,\r\n                    width: 0,\r\n                    height: 0,\r\n                };\r\n            },\r\n        };\r\n    }, [overridePos]);\r\n\r\n    const { refs, floatingStyles, update } = useFloating({\r\n        open: visible,\r\n        placement: align === \"right\" && !overridePos ? \"bottom-end\" : \"bottom-start\",\r\n        strategy: \"fixed\",\r\n        transform: false,\r\n        whileElementsMounted: autoUpdate,\r\n        middleware: [floatingOffset(offset), flip(), shift()],\r\n    });\r\n\r\n    const floatingRef = useMergeRefs(menuRef, refs.setFloating);\r\n\r\n    const hideMenu = useEvent(() => {\r\n        setVisible(false);\r\n        onHide?.();\r\n    });\r\n\r\n    const showMenu: ShowMenuCallback = useEvent((e = undefined, target = null) => {\r\n        if (!items) return;\r\n        if (e) {\r\n            e.preventDefault();\r\n            e.stopPropagation();\r\n            const { clientX: x, clientY: y } = getMouseEventOrTouch(e);\r\n            const referenceTarget =\r\n                target ?? (\"currentTarget\" in e && e.currentTarget instanceof HTMLElement ? e.currentTarget : null);\r\n            const targetRect = referenceTarget?.getBoundingClientRect();\r\n            setOverridePos({\r\n                x,\r\n                y,\r\n                target: referenceTarget,\r\n                offsetX: targetRect ? x - targetRect.left : undefined,\r\n                offsetY: targetRect ? y - targetRect.top : undefined,\r\n            });\r\n        } else {\r\n            setOverridePos(null);\r\n        }\r\n        if (!e && target && clickRef.current === target && visible) {\r\n            hideMenu();\r\n            return;\r\n        }\r\n        // Context-menu targets are references for positioning, not click triggers.\r\n        clickRef.current = e ? null : target;\r\n        if (onShow?.() !== false) {\r\n            setVisible(true);\r\n        }\r\n    });\r\n\r\n    const onBlur = useEvent((e?: FocusEvent | React.FocusEvent) => {\r\n        const target = e?.relatedTarget as undefined | null | HTMLElement;\r\n        if (target && menuRef.current?.contains(target)) return; // We are switching focus to something else inside the menu\r\n        if (target && (clickRef.current === target || clickRef.current?.contains(target))) {\r\n            return;\r\n        }\r\n        hideMenu();\r\n    });\r\n\r\n    useEffect(() => {\r\n        if (!visible) return;\r\n        const onWindowFocus = () => {\r\n            menuRef.current?.focus();\r\n        };\r\n        window.addEventListener(\"focus\", onWindowFocus);\r\n        return () => {\r\n            window.removeEventListener(\"focus\", onWindowFocus);\r\n        };\r\n    }, [visible]);\r\n\r\n    useLayoutEffect(() => {\r\n        if (!visible) return;\r\n        refs.setReference(pointReference ?? (anchorToTrigger ? clickRef.current : null) ?? anchorRef.current);\r\n        void update();\r\n        menuRef.current.focus();\r\n        menuRef.current.addEventListener(\"focusout\", onBlur);\r\n        menuRef.current.scrollTop = 0;\r\n\r\n        return () => {\r\n            menuRef.current?.removeEventListener(\"focusout\", onBlur);\r\n        };\r\n    }, [visible, pointReference, refs, update]);\r\n\r\n    const selectItem = (itm: any) => {\r\n        onBlur();\r\n        onSelectItem?.(itm);\r\n    };\r\n\r\n    const renderedItems = items?.(selectItem, hideMenu);\r\n\r\n    const onClickItem = useEvent((itemOrFn: any) => {\r\n        if (typeof itemOrFn === \"function\") {\r\n            if (itemOrFn() !== true) {\r\n                onBlur();\r\n            }\r\n        } else {\r\n            onBlur();\r\n            onSelectItem?.(itemOrFn);\r\n        }\r\n    });\r\n\r\n    const onKeyDown = useEvent((event: React.KeyboardEvent) => {\r\n        if (event.defaultPrevented) return;\r\n        if (event.key === \"Escape\") {\r\n            event.preventDefault();\r\n            event.stopPropagation();\r\n            hideMenu();\r\n            clickRef.current?.focus();\r\n        } else if (\r\n            (event.key === \"Enter\" || event.key === \" \") &&\r\n            event.target instanceof HTMLElement &&\r\n            event.target.getAttribute(\"role\") === \"button\"\r\n        ) {\r\n            event.preventDefault();\r\n            event.target.click();\r\n        }\r\n    });\r\n\r\n    const { dropdownMenuRoot } = useContext(ManagerInstanceGlobalsContext)!;\r\n\r\n    if (hideOnNoItems && (isEmpty(renderedItems) || every(renderedItems, (i) => !i))) {\r\n        return null;\r\n    } else {\r\n        return (\r\n            <>\r\n                {render(showMenu, <div ref={anchorRef} />)}\r\n                {renderMenu &&\r\n                    ReactDOM.createPortal(\r\n                        <MenuBody\r\n                            ref={floatingRef}\r\n                            className={menuClassName}\r\n                            visible={visible}\r\n                            renderedItems={renderedItems}\r\n                            onBlur={onBlur}\r\n                            onClickItem={onClickItem}\r\n                            onKeyDown={onKeyDown}\r\n                            style={floatingStyles}\r\n                        />,\r\n                        dropdownMenuRoot\r\n                    )}\r\n            </>\r\n        );\r\n    }\r\n};\r\n\r\nexport default DropdownMenu;\r\n","import React, { Suspense } from \"react\";\nimport { faSync } from \"@fortawesome/free-solid-svg-icons/faSync\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { LinkInternal } from \"./LinkInternal\";\n\ninterface ErrorBoundaryProps {\n    children?: React.ReactNode;\n    deps?: unknown[];\n}\n\ninterface ErrorBoundaryState {\n    error: Error | null;\n}\n\nconst initialState: ErrorBoundaryState = { error: null };\n\nexport class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n    constructor(props: ErrorBoundaryProps) {\n        super(props);\n        this.state = initialState;\n    }\n\n    static getDerivedStateFromError(error: Error) {\n        // ignore aborted errors\n        console.error(error);\n        if (error?.message === \"Aborted\") return initialState;\n        return { error };\n    }\n\n    reset() {\n        this.setState(initialState);\n    }\n\n    componentDidUpdate(prevProps: ErrorBoundaryProps) {\n        let lastDeps = prevProps.deps || [];\n        let newDeps = this.props.deps || [];\n\n        if (lastDeps.length !== newDeps.length) {\n            this.reset();\n        } else {\n            for (let i = 0; i < newDeps.length; i++) {\n                if (newDeps[i] !== lastDeps[i]) {\n                    this.reset();\n                    return;\n                }\n            }\n        }\n    }\n    render() {\n        /** @todo show some more information about the error */\n        if (this.state.error) {\n            return (\n                <div\n                    style={{\n                        display: \"flex\",\n                        justifyContent: \"space-around\",\n                        alignItems: \"center\",\n                        textAlign: \"center\",\n                        height: \"100%\",\n                        background: \"#ccc\",\n                        color: \"#555\",\n                        fontSize: \"1.4rem\",\n                    }}>\n                    <div style={{ padding: 15 }}>\n                        <div style={{ marginBottom: 10 }}>\n                            Something went wrong rendering this part of the Anvil Editor.\n                        </div>\n                        <div>\n                            <LinkInternal\n                                style={{ color: \"#555\", border: \"1px solid #555\", padding: \"5px 10px\" }}\n                                onClick={() => {\n                                    this.reset();\n                                }}>\n                                <FontAwesomeIcon icon={faSync} /> Retry\n                            </LinkInternal>\n                        </div>\n                    </div>\n                </div>\n            );\n        }\n\n        return this.props.children;\n    }\n}\n\n// eslint-disable-next-line react/display-name\nexport const withErrorBoundary =\n    <P extends object>(Component: React.ComponentType<P>) =>\n    (props: P) => (\n        <ErrorBoundary>\n            <Component {...props} />\n        </ErrorBoundary>\n    );\n\ninterface ErrorSuspenseBoundaryProps {\n    fallback?: React.ReactNode;\n    children?: React.ReactNode;\n}\n\nexport const ErrorSuspenseBoundary = ({ fallback, children }: ErrorSuspenseBoundaryProps) => (\n    <ErrorBoundary>\n        <Suspense fallback={fallback}>{children}</Suspense>\n    </ErrorBoundary>\n);\n","import React, { useLayoutEffect, useRef, useState } from \"react\";\nimport { makeStyles } from \"@/theme/styles\";\nimport { cx } from \"@/theme/styles\";\n\ninterface ExpanderProps {\n    isOpen?: boolean;\n    duration?: number;\n    children?: React.ReactNode;\n    className?: string;\n    innerClassName?: string;\n    style?: React.CSSProperties;\n}\n\nconst useStyles = makeStyles<{ duration: number }>()((theme, { duration }) => ({\n    root: {\n        transition: `height ${duration}ms linear`,\n    },\n    hidden: {\n        // we need to turn this off when we've expanded so that absolute elements are not cut off\n        overflow: \"hidden\",\n    },\n    inner: {\n        // Prevent margin collapse so we can measure the height properly.\n        padding: \"1px 0px\",\n        margin: \"-1px 0px\",\n    },\n}));\n\nexport const Expander = ({ isOpen, duration = 100, children, className, innerClassName, style }: ExpanderProps) => {\n    const { classes } = useStyles({ duration });\n\n    const refOuter = useRef<HTMLDivElement>(null);\n    const refInner = useRef<HTMLDivElement>(null);\n    const initialHeight = useRef<number | undefined>(undefined);\n    const doneOpeningTimeout = useRef<number | null>(null);\n\n    const wasOpen = useRef(isOpen);\n    const [hasOpened, setHasOpened] = useState(isOpen);\n\n    // Whenever isOpen changes.\n    useLayoutEffect(() => {\n        if (!refOuter.current || !refInner.current) {\n            return;\n        }\n\n        if (doneOpeningTimeout.current) {\n            clearTimeout(doneOpeningTimeout.current);\n        }\n\n        if (wasOpen.current && isOpen) {\n            // don't do any animation if we were open and we're currently open\n            wasOpen.current = isOpen;\n            refOuter.current.style.height = \"auto\";\n            return;\n        }\n\n        // Measure content whenever we're about to animate.\n        initialHeight.current = refInner.current.clientHeight - 2;\n        const outer = refOuter.current;\n\n        // In case height is currently \"auto\", in which case we can't animate from there.\n        const wasAuto = outer.style.height === \"auto\";\n        if (wasAuto && wasOpen.current && !isOpen) {\n            outer.style.height = `${initialHeight.current}px`;\n            // Let the change to fixed height take effect, then animate to whatever height we should be now.\n            setTimeout(() => {\n                outer.style.height = \"0\";\n            }, 0);\n        } else {\n            // Animate to whatever height we should be now.\n            outer.style.height = isOpen ? `${initialHeight.current}px` : \"0\";\n        }\n\n        // If we're opening, switch height back to \"auto\" when we're done, in case content changes.\n        if (isOpen) {\n            // TODO: Switch to using transitionend event, but this will do for now.\n            doneOpeningTimeout.current = setTimeout(() => {\n                if (refOuter.current) {\n                    refOuter.current.style.height = \"auto\";\n                }\n                setHasOpened(isOpen);\n            }, duration + 100);\n        } else {\n            setHasOpened(isOpen);\n        }\n        wasOpen.current = isOpen;\n    }, [duration, isOpen]);\n\n    return (\n        <div\n            ref={refOuter}\n            x-ref-outer={\"y\"}\n            className={cx(classes.root, className, hasOpened || classes.hidden)}\n            style={style}>\n            <div ref={refInner} x-ref-inner={\"y\"} className={cx(classes.inner, innerClassName)}>\n                {children}\n            </div>\n        </div>\n    );\n};\n","import * as React from \"react\";\nimport type { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport { faCircle } from \"@fortawesome/pro-light-svg-icons/faCircle\";\nimport { faSquare } from \"@fortawesome/pro-light-svg-icons/faSquare\";\nimport { faCircleDot } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faChevronDown } from \"@fortawesome/pro-regular-svg-icons/faChevronDown\";\nimport { faCheck } from \"@fortawesome/pro-solid-svg-icons/faCheck\";\nimport { faCheckSquare } from \"@fortawesome/pro-solid-svg-icons/faCheckSquare\";\nimport { faChevronDown as faSolidChevronDown } from \"@fortawesome/pro-solid-svg-icons/faChevronDown\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { cx, makeStyles, useIsPySpace } from \"@/theme/styles\";\n\ntype VariantClass = \"small\" | \"checkBoxCheckedIcon\" | \"checkBoxUncheckedIcon\" | \"radioButtonLayers\" | \"checkBoxIcon\";\n\nexport const useStyles = makeStyles<void, VariantClass>()((theme, _props, classes) => ({\n    inputShared: {\n        height: theme.formInput.height,\n        padding: theme.isPySpace ? theme.formInput.padding : \"0 \" + theme.formInput.padding,\n        border: \"2px solid \" + theme.formInput.border.toString(),\n        borderRadius: \"0.4rem\",\n        color: theme.formInput.color.toString(),\n        fontSize: \"1.4rem\",\n        fontWeight: theme.isPySpace ? 600 : 400,\n        width: \"100%\",\n        background: theme.formInput.background.toString(),\n        [`&.${classes.small}`]: {\n            height: theme.formInput.smallHeight,\n            background: theme.formInput.smallBackground.toString(),\n            borderColor: theme.formInput.smallBorder.toString(),\n            fontSize: theme.formInput.smallFontSize,\n            padding: \"0 \" + theme.formInput.smallPadding,\n        },\n        \"&:focus\": {\n            outline: theme.formInput.focusOutline,\n            outlineOffset: theme.formInput.focusOffset,\n        },\n    },\n    textBoxRoot: {\n        \"&::placeholder\": {\n            color: theme.formInput.placeholderColor.toString(),\n            fontWeight: 400,\n        },\n        [`&.${classes.small}::placeholder`]: {\n            color: theme.formInput.smallPlaceholderColor.toString(),\n        },\n    },\n    textAreaRoot: {\n        padding: \"1.1rem 1.5rem\",\n        \"&::placeholder\": {\n            color: theme.formInput.placeholderColor.toString(),\n        },\n\n        [`&.${classes.small}::placeholder`]: {\n            color: theme.formInput.smallPlaceholderColor.toString(),\n        },\n        height: \"10rem\",\n        lineHeight: \"2.3rem\",\n    },\n    small: {},\n    dropDownContainer: {\n        display: \"inline-flex\",\n        alignItems: \"center\",\n        height: theme.dropDown?.height ?? \"5rem\",\n        position: \"relative\",\n\n        [`&.${classes.small}`]: {\n            height: theme.dropDown?.small?.height ?? \"2.2rem\",\n            fontSize: \"1.2rem\",\n        },\n    },\n    dropDownRoot: {\n        appearance: \"none\",\n        padding: theme.dropDown?.padding ?? \"\",\n        paddingRight: \"4rem\", //i can't figure out what this is for\n        height: theme.dropDown?.height ?? \"5rem\",\n        cursor: \"pointer\",\n\n        fontWeight: theme.dropDown?.fontWeight ?? \"400\",\n        // prevent bottom pixels disappearing\n        lineHeight: \"normal\",\n        [`&.${classes.small}`]: {\n            height: theme.dropDown?.small?.height ?? \"2.2rem\",\n            padding: theme.dropDown?.small?.padding ?? \"\",\n            paddingRight: \"3rem\",\n        },\n    },\n    dropDownChevron: {\n        pointerEvents: \"none\",\n        position: \"absolute\",\n        right: theme.dropDown?.chevron?.right ?? 15,\n        // top: \"calc(50% - 0.7rem)\",\n        fontWeight: theme.dropDown?.chevron?.fontWeight ?? \"400\",\n        fontSize: theme.dropDown?.chevron?.fontSize ?? \"1rem\",\n        color: theme.dropDown?.chevron?.color?.toString() ?? \"\",\n        [`&.${classes.small}`]: {\n            right: \"1rem\",\n            fontSize: theme.dropDown?.small?.chevron?.fontSize ?? \"1rem\",\n        },\n    },\n    checkBoxContainer: {\n        cursor: \"pointer\",\n        color: theme.form.checkbox.color.toString(),\n        [\"&:has(> input:disabled)\"]: {\n            cursor: \"not-allowed\",\n        },\n    },\n    checkBoxIcon: {\n        display: \"none\",\n        fontSize: \"2.2rem\",\n        verticalAlign: \"middle\",\n        marginRight: \"0.8rem\",\n    },\n    checkBoxCheckedIcon: {\n        color: theme.palette.primary.toString(),\n    },\n    checkBoxUncheckedIcon: {\n        color: theme.palette.bg5.toString(),\n    },\n    checkBoxInput: {\n        opacity: 0,\n        position: \"absolute\",\n        top: 0,\n        pointerEvents: \"none\",\n        [`&:checked ~ .${classes.checkBoxCheckedIcon}, &:checked ~ .${classes.radioButtonLayers}`]: {\n            display: \"inline-block\",\n        },\n        [`&:not(:checked) ~ .${classes.checkBoxUncheckedIcon}`]: {\n            display: \"inline-block\",\n        },\n    },\n    radioButtonLayers: {\n        marginTop: \"-0.4rem\",\n        marginRight: \"0.8rem\",\n        verticalAlign: \"middle\",\n        fontSize: \"2.2rem\",\n        display: \"none\",\n        [`&>.${classes.checkBoxIcon}`]: {\n            display: \"inline-block\",\n        },\n    },\n}));\n\nexport type TextProps = React.InputHTMLAttributes<HTMLInputElement> & {\n    invalid?: boolean;\n    nativeInvalid?: boolean;\n    small?: boolean;\n    ref?: React.Ref<HTMLInputElement>;\n};\n\nexport const TextBox = ({ ref, ...props }: TextProps) => {\n    const { className, small = false, nativeInvalid = false, type = \"text\", invalid = false, ...restProps } = props;\n    const { classes } = useStyles();\n    return (\n        <input\n            ref={ref}\n            type={type}\n            className={cx(\n                classes.inputShared,\n                classes.textBoxRoot,\n                small && classes.small,\n                // if the input is a number and sets min, max, step this can be useful (scheduled tasks)\n                nativeInvalid &&\n                    \"invalid:border-2! invalid:border-red-500! invalid:bg-red-50! dark:invalid:bg-red-900!\",\n                invalid && \"border-2! border-red-500! bg-red-50! dark:bg-red-900!\",\n                className\n            )}\n            {...restProps}\n        />\n    );\n};\n\nexport type TextAreaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement> & {\n    small?: boolean;\n    invalid?: boolean;\n    ref?: React.Ref<HTMLTextAreaElement>;\n};\n\nexport const TextArea = ({ ref, className, small = false, invalid, ...props }: TextAreaProps) => {\n    const { classes } = useStyles();\n\n    return (\n        <textarea\n            ref={ref}\n            className={cx(\n                classes.inputShared,\n                classes.textAreaRoot,\n                small && classes.small,\n                invalid && \"border-2! border-red-500! bg-red-50! dark:bg-red-900!\",\n                className\n            )}\n            {...props}\n        />\n    );\n};\n\nexport type DropDownProps = React.PropsWithChildren<\n    React.SelectHTMLAttributes<HTMLSelectElement> & {\n        containerClassName?: string;\n        variant?: VariantClass;\n        elevated?: boolean;\n        iconClassName?: string;\n    }\n>;\n\nexport const DropDown = ({\n    className,\n    containerClassName,\n    variant,\n    children,\n    elevated,\n    iconClassName,\n    ...props\n}: DropDownProps) => {\n    const { classes } = useStyles();\n    const isPySpace = useIsPySpace();\n\n    return (\n        <div className={cx(classes.dropDownContainer, variant && classes[variant], containerClassName)}>\n            <select\n                className={cx(\n                    classes.inputShared,\n                    classes.dropDownRoot,\n                    variant && classes[variant],\n                    isPySpace && elevated && \"shadow-pselevated1\",\n                    className\n                )}\n                {...props}>\n                {children}\n            </select>\n            <FontAwesomeIcon\n                className={cx(classes.dropDownChevron, variant && classes[variant], iconClassName)}\n                icon={isPySpace ? faSolidChevronDown : faChevronDown}\n            />\n        </div>\n    );\n};\n\nexport type InputChoiceProps = React.PropsWithChildren<\n    React.InputHTMLAttributes<HTMLInputElement> & {\n        icon?: IconDefinition;\n    }\n>;\n\nexport const CheckBox = ({ className, style, children, icon, disabled, ...props }: InputChoiceProps) => {\n    const { classes } = useStyles();\n    const isPySpace = useIsPySpace();\n\n    // we need relative otherwise the absolutely positioned input will get the focus on the label click and cause scrolling\n    return (\n        <label\n            className={cx(\"relative inline-flex items-center font-bold\", classes.checkBoxContainer, className)}\n            style={style}>\n            <input className={classes.checkBoxInput} disabled={disabled} type={\"checkbox\"} {...props} />\n            {isPySpace ? (\n                <>\n                    <div\n                        className={cx(\n                            classes.checkBoxIcon,\n                            classes.checkBoxCheckedIcon,\n                            \"relative aspect-square h-[2.2rem] items-center justify-center border-2 border-light-grey2 bg-primary\"\n                        )}>\n                        <FontAwesomeIcon\n                            className={\"absolute top-[0.2rem] left-[0.3rem] text-[1.4rem] text-light-bg0\"}\n                            icon={faCheck}\n                        />\n                    </div>\n                    <div\n                        className={cx(\n                            classes.checkBoxIcon,\n                            classes.checkBoxUncheckedIcon,\n                            \"aspect-square h-[2.2rem] border-2 border-light-grey2\"\n                        )}\n                    />\n                </>\n            ) : (\n                <>\n                    <FontAwesomeIcon\n                        className={cx(classes.checkBoxIcon, classes.checkBoxCheckedIcon)}\n                        icon={faCheckSquare}\n                    />\n                    <FontAwesomeIcon\n                        className={cx(classes.checkBoxIcon, classes.checkBoxUncheckedIcon)}\n                        icon={faSquare}\n                    />\n                </>\n            )}\n            {icon && (\n                <>\n                    &nbsp;\n                    <FontAwesomeIcon icon={icon} /> &nbsp;\n                </>\n            )}\n            {children}\n        </label>\n    );\n};\n\nexport const RadioButton = ({ className, style, children, ...props }: InputChoiceProps) => {\n    const { classes } = useStyles();\n\n    return (\n        <label\n            className={cx(\"relative inline-flex items-center font-bold\", classes.checkBoxContainer, className)}\n            style={style}>\n            <input className={classes.checkBoxInput} type={\"radio\"} {...props} />\n            <FontAwesomeIcon\n                className={cx(classes.checkBoxIcon, classes.checkBoxCheckedIcon, \"text-primary\")}\n                icon={faCircleDot}\n            />\n            <FontAwesomeIcon className={cx(classes.checkBoxIcon, classes.checkBoxUncheckedIcon)} icon={faCircle} />\n            {children}\n        </label>\n    );\n};\n\nexport const useTextStyles = makeStyles()((theme) => ({\n    labelTitle: {\n        fontSize: theme.inputLabel?.fontSize ?? theme.text.h3.fontSize,\n        lineHeight: theme.inputLabel?.lineHeight ?? \"normal\",\n        fontWeight: theme.inputLabel?.fontWeight ?? theme.text.h3.fontWeight,\n        color: theme.inputLabel?.color ?? theme.text.h3.color.toString(),\n        marginBottom: theme.inputLabel?.marginBottom ?? 0,\n    },\n    labelSubtitle: {\n        fontSize: theme.inputLabel?.subtitle?.fontSize ?? theme.text.h3.fontSize,\n        fontWeight: theme.inputLabel?.subtitle?.fontWeight ?? theme.text.h3.fontWeight,\n        color: theme.inputLabel?.subtitle?.color?.toString() ?? theme.text.p3.color.toString(),\n        marginBottom: theme.inputLabel?.subtitle?.marginBottom ?? 5,\n    },\n}));\n\nexport type InputLabelProps = React.PropsWithChildren<{\n    title?: React.ReactNode;\n    subtitle?: React.ReactNode;\n    className?: string;\n    titleClasses?: string;\n    subtitleClasses?: string;\n    style?: React.CSSProperties;\n}>;\n\nexport const InputLabel = ({\n    title,\n    subtitle,\n    children,\n    className,\n    titleClasses,\n    subtitleClasses,\n    style,\n}: InputLabelProps) => {\n    const { classes } = useTextStyles();\n\n    return (\n        <div className={cx(className)} style={style}>\n            {title && <div className={cx(classes.labelTitle, titleClasses)}>{title}</div>}\n            {subtitle && <div className={cx(classes.labelSubtitle, subtitleClasses)}>{subtitle}</div>}\n            {children}\n        </div>\n    );\n};\n","import React, { useState } from \"react\";\nimport { faQuestionCircle } from \"@fortawesome/free-solid-svg-icons/faQuestionCircle\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { cx, makeStyles } from \"../../theme/styles\";\nimport { LinkInternal } from \"./LinkInternal\";\n\nconst useStyles = makeStyles<void, \"left\">()((theme, _props, classes) => ({\n    root: {\n        clear: \"both\",\n    },\n    padding: {\n        padding: \"0 1rem 0.4rem 1rem\",\n    },\n    left: {},\n    right: { float: \"right\" },\n    helpIcon: {\n        color: theme.primary.hex(),\n        \"&:hover\": {\n            color: theme.primary.alpha(0.8).toString(),\n        },\n        [`&.${classes.left}`]: {\n            float: \"left\",\n            bottom: \"0.6em\",\n            left: \"-1.5em\",\n        },\n    },\n    helpContent: {\n        backgroundColor: \"#1bb0ee1a\",\n        padding: \"0 1rem 0.4rem 1rem\",\n        borderRadius: \"0.4rem\",\n    },\n}));\n\ninterface HelpLinkProps extends React.HTMLAttributes<HTMLDivElement> {\n    /** can be relative to anvil.works */\n    url?: string;\n    iconRight?: boolean;\n    left?: boolean;\n    inline?: boolean;\n    onClick?: () => void;\n}\n\nexport const HelpLink = ({\n    url,\n    children,\n    className,\n    iconRight,\n    inline = false,\n    left = false,\n    onClick: onClick_,\n}: HelpLinkProps) => {\n    const { classes } = useStyles();\n    const [expanded, setExpanded] = useState(false);\n\n    const openInNewTab = (url: string) => {\n        const newWindow = window.open(url, \"_blank\", \"noopener,noreferrer\");\n        if (newWindow) {\n            newWindow.opener = null;\n        }\n    };\n\n    const onClick = useEvent(() => {\n        onClick_?.();\n        if (url) {\n            openInNewTab(url);\n        } else {\n            setExpanded(!expanded);\n        }\n    });\n\n    return (\n        <>\n            {inline ? (\n                <LinkInternal\n                    onClick={onClick}\n                    icon={faQuestionCircle}\n                    className={cx(classes.helpIcon, className)}\n                    iconRight={iconRight}>\n                    {url && children}\n                </LinkInternal>\n            ) : (\n                <div className={cx(classes.root, expanded ? classes.helpContent : classes.padding, className)}>\n                    <LinkInternal\n                        onClick={onClick}\n                        icon={faQuestionCircle}\n                        className={cx(classes.helpIcon, classes.right, left && classes.left)}\n                        iconRight={iconRight}>\n                        {url && children}&nbsp;\n                    </LinkInternal>\n                    {expanded && <>{children}</>}\n                    <div className=\"clear-both\"></div>\n                </div>\n            )}\n        </>\n    );\n};\n","import { useCallback, useMemo } from \"react\";\nimport type { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport { faFacebook, faGoogle, faJenkins, faJs, faMicrosoft, faPython, faStripe } from \"@fortawesome/free-brands-svg-icons\";\nimport {\n    faClock as falClock,\n    faCode as falCode,\n    faCog as falCog,\n    faCube as falCube,\n    faDatabase as falDatabase,\n    faFileAlt as falFileAlt,\n    faFileCode as falFileCode,\n    faFolder as falFolder,\n    faHashtag as falHashtag,\n    faImage as falImage,\n    faLock as falLock,\n    faMailBulk as falMailBulk,\n    faPaintBrush as falPaintBrush,\n    faPlay as falPlay,\n    faHdd as falServer,\n    faStream as falStream,\n    faUserFriends as falUserFriends,\n} from \"@fortawesome/pro-light-svg-icons\";\nimport { faFolders } from \"@fortawesome/pro-light-svg-icons/faFolders\";\nimport { faList } from \"@fortawesome/pro-light-svg-icons/faList\";\nimport {\n    faClock as farClock,\n    faCode as farCode,\n    faCog as farCog,\n    faCube as farCube,\n    faDatabase as farDatabase,\n    faFileAlt as farFileAlt,\n    faFileCode as farFileCode,\n    faFolder as farFolder,\n    faHashtag as farHashtag,\n    faImage as farImage,\n    faLock as farLock,\n    faMailBulk as farMailBulk,\n    faPaintBrush as farPaintBrush,\n    faPlay as farPlay,\n    faHdd as farServer,\n    faStream as farStream,\n    faUserFriends as farUserFriends,\n} from \"@fortawesome/pro-regular-svg-icons\";\nimport { faChartLine } from \"@fortawesome/pro-regular-svg-icons/faChartLine\";\nimport { faQuestion } from \"@fortawesome/pro-regular-svg-icons/faQuestion\";\nimport { faSparkle } from \"@fortawesome/pro-regular-svg-icons/faSparkle\";\nimport { faTv } from \"@fortawesome/pro-regular-svg-icons/faTv\";\nimport {\n    faClock as fasClock,\n    faCode as fasCode,\n    faCog as fasCog,\n    faCube as fasCube,\n    faDatabase as fasDatabase,\n    faFileAlt as fasFileAlt,\n    faFileCode as fasFileCode,\n    faFolder as fasFolder,\n    faHashtag as fasHashtag,\n    faImage as fasImage,\n    faLock as fasLock,\n    faMailBulk as fasMailBulk,\n    faPaintBrush as fasPaintBrush,\n    faPlay as fasPlay,\n    faHdd as fasServer,\n    faStream as fasStream,\n    faUserFriends as fasUserFriends,\n} from \"@fortawesome/pro-solid-svg-icons\";\nimport { getTestFileIcon } from \"@/testing/test-file-icons\";\nimport type { StructureItem } from \"@/types\";\nimport { faAnvilX } from \"@/util/icons\";\n\ntype FileIconClassName = \"formIcon\" | \"otherClientIcon\" | \"serverIcon\" | \"assetIcon\" | \"testingIcon\";\ntype FileIconStyle = \"light\" | \"regular\" | \"solid\";\ntype FileIconItem = {\n    name?: string;\n    class_name?: string;\n    isPackage?: boolean;\n    is_package?: boolean;\n};\n\nexport type FileIconCategory = StructureItem[\"type\"] | \"testing\";\n\nexport const useFileIconClassGetter = (classes: Partial<Record<FileIconClassName, string>>) => {\n    return useCallback(\n        (fileType: FileIconCategory) => {\n            let iconClass: string | null = null;\n            switch (fileType) {\n                case \"form\":\n                    iconClass = classes.formIcon ?? null;\n                    break;\n                case \"module\":\n                    iconClass = classes.otherClientIcon ?? null;\n                    break;\n                case \"server_module\":\n                    iconClass = classes.serverIcon ?? null;\n                    break;\n                case \"folder\":\n                case \"asset\":\n                    iconClass = classes.assetIcon ?? null;\n                    break;\n                case \"testing\":\n                    iconClass = classes.testingIcon ?? null;\n                    break;\n                default:\n                    break;\n            }\n            return iconClass;\n        },\n        [classes]\n    );\n};\n\nconst pathRegex = /\\.((jpeg|jpg|gif|png)|(js)|(css)|(html))$/i;\n\nconst fileIcons = {\n    faUserFriends: { solid: fasUserFriends, light: falUserFriends, regular: farUserFriends },\n    faDatabase: { solid: fasDatabase, light: falDatabase, regular: farDatabase },\n    faCube: { solid: fasCube, light: falCube, regular: farCube },\n    faCode: { solid: fasCode, light: falCode, regular: farCode },\n    faFileAlt: { solid: fasFileAlt, light: falFileAlt, regular: farFileAlt },\n    faFileCode: { solid: fasFileCode, light: falFileCode, regular: farFileCode },\n    faFolder: { solid: fasFolder, light: falFolder, regular: farFolder },\n    faHashtag: { solid: fasHashtag, light: falHashtag, regular: farHashtag },\n    faImage: { solid: fasImage, light: falImage, regular: farImage },\n    faCog: { solid: fasCog, light: falCog, regular: farCog },\n    faLock: { solid: fasLock, light: falLock, regular: farLock },\n    faClock: { solid: fasClock, light: falClock, regular: farClock },\n    faPaintBrush: { solid: fasPaintBrush, light: falPaintBrush, regular: farPaintBrush },\n    faStream: { solid: fasStream, light: falStream, regular: farStream },\n    faMailBulk: { solid: fasMailBulk, light: falMailBulk, regular: farMailBulk },\n    faHdd: { solid: fasServer, light: falServer, regular: farServer },\n    faPlay: { solid: fasPlay, light: falPlay, regular: farPlay },\n} as const satisfies Record<string, Record<FileIconStyle, IconDefinition>>;\n\nexport const getIconFromFile = (\n    itemType: StructureItem[\"type\"],\n    item: FileIconItem,\n    style: FileIconStyle = \"light\"\n): IconDefinition => {\n    let icon: IconDefinition = fileIcons.faCode[style];\n    switch (itemType) {\n        case \"form\":\n            icon = fileIcons.faFileCode[style];\n            break;\n        case \"module\":\n            icon = item.is_package || item.isPackage ? fileIcons.faFolder[style] : fileIcons.faCube[style];\n            break;\n        case \"server_module\":\n            icon = item.is_package || item.isPackage ? fileIcons.faFolder[style] : fileIcons.faHdd[style];\n            break;\n        case \"script\":\n            icon = fileIcons.faPlay[style];\n            break;\n        case \"folder\":\n            icon = fileIcons.faFolder[style];\n            break;\n        case \"asset\":\n            const filePathMatch = item.name?.match(pathRegex);\n            if (filePathMatch == null) {\n                icon = fileIcons.faFileAlt[style];\n            } else if (filePathMatch[2]) {\n                icon = fileIcons.faImage[style];\n            } else if (filePathMatch[3]) {\n                icon = faJs;\n            } else if (filePathMatch[4]) {\n                icon = fileIcons.faHashtag[style];\n            } else if (filePathMatch[5]) {\n                icon = fileIcons.faCode[style];\n            }\n            break;\n        default:\n            icon = fileIcons.faCode[style];\n    }\n    return icon;\n};\n\nexport const getExtraFileIcon = (filePath: string) => {\n    if (filePath.startsWith(\"tests/\")) {\n        return {\n            icon: getTestFileIcon(\n                {\n                    type: \"extra_file\",\n                    fullName: filePath,\n                    isPackage: filePath.split(\"/\").at(-1) === \"__init__.py\",\n                },\n                false\n            ),\n            iconClass: \"testingIcon\" as const,\n        };\n    }\n    return {\n        icon: getIconFromFile(\"asset\", { name: filePath }),\n        iconClass: \"extraFileIcon\" as const,\n    };\n};\n\nexport const useFileIcon = (\n    file: Pick<StructureItem, \"type\" | \"name\" | \"isPackage\"> & { is_package?: boolean },\n    style: FileIconStyle = \"light\"\n) => {\n    return useMemo(() => getIconFromFile(file.type, file, style), [file, style]);\n};\n\nexport const icons: Record<string, IconDefinition> = {\n    CODE: fileIcons.faCode.light,\n    PYTHON_SOURCE: fileIcons.faLock.light,\n    DB_TABLE: fileIcons.faDatabase.light,\n    APP_SCHEMA: fileIcons.faDatabase.light,\n    SETTINGS: fileIcons.faCog.light,\n    SCHEDULED_TASKS: fileIcons.faClock.light,\n    THEME: fileIcons.faPaintBrush.light,\n    LOGS: fileIcons.faStream.light,\n    BACKGROUND_TASKS: fileIcons.faStream.light,\n    CPU_USAGE: fileIcons.faStream.light,\n    MEMORY_USAGE: fileIcons.faStream.light,\n    APP_DEPENDENCIES: fileIcons.faCube.light,\n    PYTHON_DEPENDENCIES: faPython,\n    JAVASCRIPT_DEPENDENCIES: fileIcons.faCode.light,\n    IMPORT_MAP: fileIcons.faCode.light,\n    SESSION: faList,\n    SESSIONS: faList,\n    CONVERSATION: faSparkle,\n    HELP: faQuestion,\n    _COMPONENTS: faTv,\n};\n\nexport const serviceIcons: Record<string, IconDefinition> = {\n    SECRETS: fileIcons.faLock.light,\n    MICROSOFT: faMicrosoft,\n    STRIPE: faStripe,\n    FACEBOOK: faFacebook,\n    EMAIL: fileIcons.faMailBulk.light,\n    GOOGLE: faGoogle,\n    USERS: fileIcons.faUserFriends.light,\n    TABLEAU: faAnvilX,\n    FILES: faFolders,\n    SAML: fileIcons.faLock.light,\n    HAWTHORN_DEPLOYMENT: faJenkins,\n};\n","import React, { useRef } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { getAppId } from \"@/controllers/app\";\nimport { hideIfOverlay } from \"@/controllers/sidebar\";\nimport { FullNavTarget, NavTarget } from \"@/router/navTypes\";\nimport { AnvilDispatch } from \"@/types\";\nimport { checkMeta } from \"@/util\";\nimport { getUrlForNavTarget, navigate } from \"../../router/navigation\";\nimport { cx } from \"../../theme/styles\";\nimport useEvent from \"../../util/useEventCallback\";\n\nexport interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n    to: string | NavTarget | null | undefined;\n    onClickOverrideNav?: (() => any) | null;\n    children?: React.ReactNode;\n    className?: string;\n    disableMetaClick?: boolean;\n    fn?(): void;\n    waitForSave?: boolean;\n    ref?: React.Ref<HTMLAnchorElement | HTMLButtonElement>;\n}\n\nconst useHref = (to: LinkProps[\"to\"]) => {\n    const appId = useSelector(getAppId);\n    // note we could put this in a useMemo\n    // but some components pass an object literal as the `to` argument\n    // defeating the purpose of useMemo\n    if (to == null) return undefined;\n    if (typeof to === \"string\") return to;\n    return getUrlForNavTarget({ ...to, appId: \"appId\" in to ? to.appId : appId } as FullNavTarget);\n};\n\nexport default function Link({ ref, ...props }: LinkProps) {\n    const {\n        to,\n        children,\n        className,\n        onClick: _onClick,\n        onClickOverrideNav,\n        disableMetaClick,\n        waitForSave,\n        ...restProps\n    } = props;\n    const href = useHref(to);\n    const dispatch: AnvilDispatch = useDispatch();\n    const lastClickTime = useRef(0);\n    const onClick: React.MouseEventHandler<HTMLAnchorElement> = useEvent((e) => {\n        e.stopPropagation();\n        _onClick?.(e);\n        if (typeof to === \"string\") return;\n        if (onClickOverrideNav) {\n            onClickOverrideNav();\n        } else if (to) {\n            if (!disableMetaClick && (checkMeta(e) || e.shiftKey)) {\n                // user wants to open this link in a new tab\n                return;\n            }\n            if (Date.now() - lastClickTime.current > 500) {\n                lastClickTime.current = Date.now();\n                dispatch(navigate(to, false, waitForSave));\n            }\n        }\n        e.preventDefault();\n\n        return false;\n    });\n\n    return href ? (\n        <a\n            ref={ref as React.Ref<HTMLAnchorElement>}\n            href={href}\n            onClick={onClick}\n            className={cx(className, { \"cursor-pointer\": !!(to ?? onClickOverrideNav) })}\n            {...restProps}>\n            {children}\n        </a>\n    ) : (\n        <button\n            role=\"link\"\n            ref={ref as React.Ref<HTMLButtonElement>}\n            onClick={onClick as unknown as React.MouseEventHandler<HTMLButtonElement>}\n            className={cx(\"text-left leading-[inherit]\", className, { \"cursor-pointer\": !!(to ?? onClickOverrideNav) })}\n            {...(restProps as any)}>\n            {children}\n        </button>\n    );\n}\n\nexport const SidebarLink = ({ ref, to, children, className, onDoubleClick, hideOverlayOnClick=true, ...props }: LinkProps & {hideOverlayOnClick?: boolean}) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const clickTimeoutRef = useRef<number | undefined>(undefined);\n    const onClick = useEvent(() => {\n        clearTimeout(clickTimeoutRef.current);\n        if (hideOverlayOnClick) {\n            clickTimeoutRef.current = setTimeout(() => {\n                dispatch(hideIfOverlay());\n            }, 250) as unknown as number;\n        }\n    });\n    const onDoubleClick_: React.MouseEventHandler<HTMLAnchorElement> = useEvent((e) => {\n        if (onDoubleClick) {\n            clearTimeout(clickTimeoutRef.current);\n            onDoubleClick(e);\n        }\n    });\n\n    return (\n        <Link ref={ref} to={to} className={className} onClick={onClick} onDoubleClick={onDoubleClick_} {...props}>\n            {children}\n        </Link>\n    );\n};\n","import React from \"react\";\nimport type { IconProp } from \"@fortawesome/fontawesome-svg-core\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { cx } from \"@/theme/styles\";\n\ninterface LinkInternalProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {\n    ref?: React.Ref<HTMLSpanElement>;\n    iconRight?: boolean;\n    icon?: IconProp;\n    shrinkable?: boolean;\n    preventDefaultClick?: boolean;\n}\n\nexport const LinkInternal = ({ ref, ...props }: LinkInternalProps) => {\n    const {\n        children,\n        onClick,\n        icon,\n        iconRight,\n        className,\n        style,\n        shrinkable = false,\n        preventDefaultClick = true,\n        ...restProps\n    } = props;\n\n    const _onClick: React.MouseEventHandler<HTMLSpanElement> = async (e) => {\n        if (onClick) {\n            if (preventDefaultClick) {\n                e.preventDefault();\n                e.stopPropagation();\n            }\n            onClick(e);\n        }\n    };\n\n    return (\n        <span\n            ref={ref}\n            className={cx(\"relative inline\", className, shrinkable && \"shrink! overflow-hidden\")}\n            tabIndex={0}\n            role=\"button\"\n            style={style}\n            onClick={_onClick}\n            {...restProps}>\n            {icon && !iconRight && <FontAwesomeIcon icon={icon} fixedWidth />}\n            {children}\n            {icon && iconRight && <FontAwesomeIcon icon={icon} fixedWidth />}\n        </span>\n    );\n};\n","import { createContext } from \"react\";\n\n/** Blocks embedded in a LiveOutput stream (e.g. the inline BG-task widgets) render live\n *  content that grows without the `messages` array changing, so LiveOutput's own\n *  scroll-on-new-messages logic never sees it. They report their growth through this\n *  context instead, and LiveOutput decides how to adjust the scroll position. */\nexport type EmbeddedBlockGrowthHandler = (blockEl: HTMLElement, delta: number) => void;\n\nexport const EmbeddedBlockGrowthContext = createContext<EmbeddedBlockGrowthHandler | null>(null);\n","import React, { useContext, useLayoutEffect, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faChevronRight } from \"@fortawesome/pro-light-svg-icons/faChevronRight\";\nimport { faStop } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faChevronRight as faChevronRightSolid } from \"@fortawesome/free-solid-svg-icons/faChevronRight\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { INACTIVE_TASK_TYPES, useBackgroundTasks } from \"@/controllers/background-tasks-query\";\nimport { EmbeddedBlockGrowthContext } from \"@/components/reusable/embedded-output-growth\";\nimport { getRunnerBgTask, stopRunnerBgTask } from \"@/controllers/runner-bg-tasks\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch, RunnerBgTask, State } from \"@/types\";\nimport Link from \"../reusable/Link\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { BottomPanelToolbarButton } from \"../reusable/SharedComponents\";\nimport { useTooltip } from \"../reusable/Tooltip\";\nimport { LogEvent, compressEvent } from \"../tabs/sessions/SessionLogs\";\n\nconst BLANK_SESSION = {};\n\ntype DisplayStatus = \"running\" | \"killing\" | \"completed\" | \"failed\" | \"killed\" | \"mia\";\n\nconst STATUS_LABELS: Record<DisplayStatus, string> = {\n    running: \"Running\",\n    killing: \"Stopping…\",\n    completed: \"Completed\",\n    failed: \"Failed\",\n    killed: \"Killed\",\n    mia: \"Vanished\",\n};\n\nconst STATUS_PILL_CLASSES: Record<DisplayStatus, string> = {\n    running: \"border-sky-500/60 text-sky-600 dark:text-sky-400\",\n    killing: \"border-amber-500/60 text-amber-600 dark:text-amber-400\",\n    completed: \"border-green-600/60 text-green-700 dark:text-green-400\",\n    failed: \"border-red-500/60 text-red-600 dark:text-red-400\",\n    killed: \"border-gray-500/60 text-gray-600 dark:text-gray-400\",\n    mia: \"border-gray-500/60 text-gray-600 dark:text-gray-400\",\n};\n\nconst finalStatusToDisplay = (finalStatus?: string): DisplayStatus => {\n    if (!finalStatus) return \"completed\";\n    if (finalStatus.startsWith(\"threw\")) return \"failed\";\n    if (finalStatus === \"killed\") return \"killed\";\n    if (finalStatus === \"mia\") return \"mia\";\n    return \"completed\";\n};\n\nconst useDisplayStatus = (task: RunnerBgTask): DisplayStatus => {\n    // Passively reflect the Background Tasks poller: if it has seen this task reach a\n    // terminal state the event stream didn't tell us about (notably \"mia\"), show that.\n    const { tasks: polledTasks } = useBackgroundTasks(false);\n    if (task.state === \"TERMINATED\") {\n        return finalStatusToDisplay(task.finalStatus);\n    }\n    const polled = polledTasks?.find((t) => t.session_id === task.sessionId);\n    if (polled && INACTIVE_TASK_TYPES.includes(polled.completion_status)) {\n        return finalStatusToDisplay(\n            polled.completion_status === \"threw\" ? \"threw an exception\" : polled.completion_status\n        );\n    }\n    return task.state === \"KILLING\" ? \"killing\" : \"running\";\n};\n\n/** Inline widget for a background task launched by the current runner session, embedded in\n *  the Running App Console output at the point the task was launched. */\nexport const RunnerBgTaskWidget = ({ sessionId }: { sessionId: string }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const task = useSelector((state: State) => getRunnerBgTask(sessionId)(state));\n    const [expanded, setExpanded] = useState(true);\n    const [stopTooltip, stopAnchorRef] = useTooltip(\"Stop this background task\", \"top-right\");\n\n    // Our output grows without LiveOutput's `messages` changing, so its scroll logic can't\n    // see it - report height growth caused by new output so it can adjust the scroll.\n    const rootRef = useRef<HTMLDivElement>(null);\n    const prevHeightRef = useRef<number | null>(null);\n    const prevOutputLenRef = useRef(0);\n    const onBlockGrowth = useContext(EmbeddedBlockGrowthContext);\n    const outputLen = task?.output.length ?? 0;\n    useLayoutEffect(() => {\n        const el = rootRef.current;\n        if (!el) return;\n        const height = el.offsetHeight;\n        if (outputLen > prevOutputLenRef.current && prevHeightRef.current !== null && height > prevHeightRef.current) {\n            onBlockGrowth?.(el, height - prevHeightRef.current);\n        }\n        prevOutputLenRef.current = outputLen;\n        prevHeightRef.current = height;\n    });\n\n    // Hooks must run unconditionally; tolerate a marker whose task has been forgotten.\n    const displayStatus = useDisplayStatus(task ?? ({ sessionId, state: \"TERMINATED\", output: [] } as any));\n    if (!task) return null;\n\n    const isStoppable = displayStatus === \"running\" && !!task.taskId;\n    let dropNextNewline = false; // Same newline-dedup hack as ScriptOutputTab's OutputScroller.\n\n    return (\n        <div\n            ref={rootRef}\n            className=\"my-2 rounded border border-sectionborder text-[1.3rem] dark:border-dark-sectionborder\">\n            <div className=\"flex items-center gap-3 px-2 py-1\">\n                <LinkInternal\n                    className=\"flex min-w-0 flex-1 items-center gap-3 hover:text-light-fg1/80 dark:hover:text-dark-fg1/80\"\n                    onClick={() => setExpanded(!expanded)}>\n                    <span className=\"inline-flex w-6 shrink-0 justify-center\">\n                        <FontAwesomeIcon\n                            icon={faChevronRight}\n                            className={cx(\"transition-transform\", expanded && \"rotate-90\")}\n                        />\n                    </span>\n                    <span className=\"shrink-0 italic\">{task.name?.startsWith(\"script:\") ? 'Script' : 'Background task'}</span>\n                    <code className=\"min-w-0 truncate\" title={task.taskId ? `Task ID: ${task.taskId}` : undefined}>\n                        {(task.name?.startsWith(\"script:\") ? task.name.substring(7) : task.name) || \"…\"}\n                    </code>\n                    <span\n                        className={cx(\n                            \"inline-flex shrink-0 items-center rounded-full border px-3 leading-[1.6]\",\n                            STATUS_PILL_CLASSES[displayStatus]\n                        )}>\n                        {STATUS_LABELS[displayStatus]}\n                    </span>\n                </LinkInternal>\n                {isStoppable && (\n                    <BottomPanelToolbarButton\n                        ref={stopAnchorRef}\n                        variant=\"danger\"\n                        icon={faStop}\n                        onClick={() => dispatch(stopRunnerBgTask(sessionId))}>\n                        {stopTooltip}\n                        Stop\n                    </BottomPanelToolbarButton>\n                )}\n                <Link\n                    to={{ type: \"SESSION\", sessionId, displayMode: \"LOGS\" } as const}\n                    className=\"inline-block shrink-0\">\n                    <BottomPanelToolbarButton preventDefaultClick={false} iconRight icon={faChevronRightSolid}>\n                        App Log\n                    </BottomPanelToolbarButton>\n                </Link>\n            </div>\n            {expanded && (\n                <div className=\"border-t border-sectionborder px-2 py-1 font-mono whitespace-pre dark:border-dark-sectionborder\">\n                    {task.output.map((event, idx) => {\n                        if (dropNextNewline && event.log_text === \"\\n\") {\n                            dropNextNewline = false;\n                            return null;\n                        }\n                        if (event.log_text !== \"\\n\") {\n                            dropNextNewline = true;\n                        }\n                        return (\n                            <LogEvent\n                                event={compressEvent(event)}\n                                key={event.seq ?? idx}\n                                session={task.session || BLANK_SESSION}\n                                isOpen\n                            />\n                        );\n                    })}\n                    {task.outputMayBeMissing && (\n                        <div className=\"my-1 text-[1.2rem] italic opacity-80\">\n                            [some output may be missing]{\" \"}\n                            <Link\n                                to={{ type: \"SESSION\", sessionId, displayMode: \"LOGS\" } as const}\n                                className=\"underline\">\n                                See the full App Log\n                            </Link>\n                        </div>\n                    )}\n                </div>\n            )}\n        </div>\n    );\n};\n","import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faAngleDown, faAngleUp, faTimes } from \"@fortawesome/pro-light-svg-icons\";\nimport { faSparkle } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faSpinnerThird } from \"@fortawesome/pro-solid-svg-icons/faSpinnerThird\";\nimport { faQuestionCircle } from \"@fortawesome/free-solid-svg-icons/faQuestionCircle\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { BindingError } from \"@runtime/runner/error-handling\";\nimport type { RuntimeWarning } from \"@runtime/runner/warnings\";\nimport { RunnerBgTaskWidget } from \"@/components/bottom_panel/RunnerBgTaskWidget\";\nimport { EmbeddedBlockGrowthContext } from \"@/components/reusable/embedded-output-growth\";\nimport { createConversation, getIsCreatingConversation, useAgentsEnabled } from \"@/controllers/agents\";\nimport { NavTarget } from \"@/router/navTypes\";\nimport { AnvilDispatch, CodePath } from \"@/types\";\nimport { ExternalStore, createExternalStoreHooks } from \"@/util/external-store\";\nimport { useUpdateEffect } from \"@/util/hooks\";\nimport { useCopyAllKeyBinding } from \"@/util/hooks/global-key-bindings\";\nimport { outputSearchHistoryStore, useSearchHistory, useSearchHistoryKeyDown } from \"@/util/search-history\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { getApp, getAppId, getAppPackageName } from \"../../controllers/app\";\nimport { getCodeNames, getInPlaceEditTarget } from \"../../controllers/app/code\";\nimport { getUser, stopApp } from \"../../controllers/ide\";\nimport { getRunnerViewMaximised, restoreRunnerView } from \"../../controllers/runner\";\nimport { navigate } from \"../../router/navigation\";\nimport { cx, makeStyles, useIsPySpace } from \"../../theme/styles\";\nimport { Button } from \"./Button\";\nimport { HelpLink } from \"./HelpLink\";\nimport Link from \"./Link\";\nimport { LinkInternal } from \"./LinkInternal\";\nimport { ContentTextInput } from \"./SharedComponents\";\n\ninterface MessageBase {\n    fromServer?: boolean;\n    read?: boolean;\n}\n\ninterface MessageStdOut extends MessageBase {\n    fn: \"stdout\";\n    text: string;\n}\n\ninterface MessageStdErr extends MessageBase {\n    fn: \"stderr\";\n    text: string;\n}\n\ninterface MessageWarning extends MessageBase, RuntimeWarning {\n    fn: \"warning\";\n}\n\ninterface MessagePythonError extends MessageBase {\n    fn: \"pythonError\";\n    type?: string;\n    msg?: string;\n    message?: string;\n    errorObj?: {\n        type: string;\n        message: string;\n        trace?: Array<[string, string]>;\n        docId?: string;\n        docUrl?: string;\n        docLinkTitle?: string;\n        bindingErrors?: Array<BindingError>;\n    };\n    traceback?: Array<{\n        filename: string;\n        lineno: string;\n        colno?: string;\n        fromServer?: boolean;\n    }>;\n}\n\ninterface MessageRuntimeError extends MessageBase {\n    fn: \"runtimeError\";\n    message: string;\n    type: string;\n    stackTrace?: string;\n    msg?: string;\n}\n\ninterface MessageReplCommand extends MessageBase {\n    fn: \"replCommand\";\n    command: string;\n    onServer?: boolean;\n}\n\ninterface MessageBindingError extends MessageBase {\n    fn: \"binding-error\";\n    bindingErrors: Array<{\n        path: string;\n        message: string;\n        binding: {\n            component_name: string;\n            property: string;\n            code: string;\n        };\n        formName: string;\n    }>;\n}\n\ninterface MessageClear extends MessageBase {\n    fn: \"clear\";\n}\n\ninterface MessageSession extends MessageBase {\n    fn: \"session\";\n    text: string;\n}\n\ninterface MessageBgTask extends MessageBase {\n    fn: \"bgTask\";\n    /** Keys into state.runnerBgTasks; the widget renders live from there */\n    sessionId: string;\n}\n\nexport type Message =\n    | MessageStdOut\n    | MessageStdErr\n    | MessageWarning\n    | MessagePythonError\n    | MessageRuntimeError\n    | MessageReplCommand\n    | MessageBindingError\n    | MessageClear\n    | MessageSession\n    | MessageBgTask;\n\ninterface RenderMessageClasses extends Classes {\n    codeOutput: string;\n    selectable: string;\n    server: string;\n    client: string;\n    read: string;\n    errorOutput: string;\n    bindingCode: string;\n    code: string;\n    codeHighlight: string;\n    alert: string;\n    alertDanger: string;\n    alertWarning: string;\n}\n\nconst useStyles = makeStyles<void, \"bindingCode\">()((theme, _props, classes) => ({\n    root: {\n        height: \"100%\",\n        width: \"100%\",\n        lineHeight: \"1.4rem\",\n        \"& hr\": {\n            margin: 0,\n        },\n    },\n    errorOutput: {\n        padding: \"0 0.6rem\",\n        lineHeight: 1.8,\n        marginTop: \"0.4rem\",\n        \"& li\": {\n            listStyle: \"none\",\n        },\n    },\n    read: {\n        opacity: 0.5,\n    },\n    server: {\n        borderLeft: \"3px solid \" + theme.liveOutput.serverBorder.toString(),\n    },\n    client: {\n        borderLeft: \"3px solid \" + theme.liveOutput.clientBorder.toString(),\n    },\n    bindingCode: {},\n    code: {\n        backgroundColor: \"transparent !important\",\n        fontFamily: theme.codeFont + \" !important\",\n\n        color: theme.liveOutput.codeColor.toString(),\n\n        [`&.${classes.bindingCode}`]: {\n            color: theme.liveOutput.codeColor.toString(),\n        },\n    },\n    codeOutput: {\n        padding: \"0 0.6rem\",\n        fontFamily: theme.codeFont,\n        whiteSpace: \"pre-wrap\",\n        lineHeight: 1.8,\n    },\n    codeHighlight: {\n        \"& code\": {\n            backgroundColor: theme.liveOutput.codeHighlightBg.toString(),\n            color: theme.liveOutput.codeColor.toString(),\n        },\n    },\n    prompt: {\n        lineHeight: \"inherit\",\n        whiteSpace: \"pre-wrap\",\n        userSelect: \"none\" /* supported by Chrome and Opera */,\n    },\n    replCommand: {\n        lineHeight: \"inherit\",\n        padding: \"0 0.6rem\",\n        whiteSpace: \"pre-wrap\",\n    },\n    displayFlex: {\n        display: \"flex\",\n    },\n    alert: {\n        padding: \"1.5rem\",\n        margin: \"0.5rem 0\",\n        border: \"1px solid \" + \"transparent\",\n        borderRadius: \"0.4rem\",\n        textAlign: \"center\",\n    },\n    alertDanger: {\n        color: theme.liveOutput.alert.color.toString(),\n        backgroundColor: theme.liveOutput.alert.bgColor.toString(),\n        borderColor: theme.liveOutput.alert.border.toString(),\n        \"& code\": {\n            fontWeight: \"bold\",\n        },\n    },\n    alertWarning: {\n        backgroundColor: theme.liveOutput.alert.warningBg.toString(),\n        borderColor: theme.liveOutput.alert.warningBorder.toString(),\n    },\n    link: {\n        color: theme.liveOutput.link.color.toString(),\n        borderBottom: \"1px dotted\",\n        \"& code\": {\n            color: theme.liveOutput.link.color.toString(),\n        },\n        \"&:hover\": {\n            textDecoration: \"none\",\n            borderBottom: \"1px solid\",\n            cursor: \"pointer\",\n        },\n    },\n    selectable: {\n        webkitUserSelect: \"text\" /* Chrome 49+ */,\n        mozUserSelect: \"text\" /* Firefox 43+ */,\n        msUserSelect: \"text\" /* No support yet */,\n        userSelect: \"text\" /* Likely future */,\n    },\n    sessionOutput: {\n        padding: \"0.6rem 0.6rem 1px 0.6rem\",\n        fontStyle: \"italic\",\n        background: theme.liveOutput.sessionOutputBg.toString(),\n        margin: \"1rem 0\",\n    },\n}));\n\nconst FILEMATCHER = /^(?:anvil-app-modules\\/|app\\/|\\/|C:\\/)?(.+?)(\\/__init__)?\\.py$/;\nconst JUMPMATCHER = /^(?:.+?)\\/(.+?)(\\/__init__)?$/;\nconst SLASH = /\\//g;\n\ntype Classes = Record<string, string>;\n\ninterface TraceBackLinkProps {\n    classes: Classes;\n    tracebackNavigate: (navTarget: NavTarget) => void;\n    allCodeNames: Record<string, { codePath: string; fullName: string }>;\n    appPackageName?: string;\n    filename: string;\n    lineno: string;\n    colno?: string;\n}\n\nconst TraceBackLink: React.FC<TraceBackLinkProps> = ({\n    classes,\n    tracebackNavigate,\n    allCodeNames,\n    appPackageName,\n    filename,\n    lineno,\n    colno = \"0\",\n}) => {\n    const codeItem = useMemo(\n        () => getTracebackCodeItem(filename, allCodeNames, appPackageName),\n        [filename, allCodeNames, appPackageName]\n    );\n\n    let navTarget: NavTarget | undefined;\n    if (codeItem?.codePath != null) {\n        navTarget = {\n            type: \"CODE\",\n            codePath: codeItem.codePath as CodePath,\n            essentialView: { code: [lineno, colno] },\n        };\n    }\n\n    return (\n        <>\n            {navTarget ? (\n                <LinkInternal className={classes.link} onClick={() => tracebackNavigate(navTarget)}>\n                    {`${codeItem?.fullName}, line ${lineno}`}\n                </LinkInternal>\n            ) : (\n                <span>\n                    {filename}:{lineno}\n                </span>\n            )}\n        </>\n    );\n};\n\nconst getTraceItems = (msg: MessagePythonError) => {\n    // traceback not available in every msg. In that case, create the trace using the errorObj\n    if (msg.traceback) return msg.traceback;\n    return msg.errorObj?.trace?.map(([filename, lineno]) => ({ filename, lineno, colno: undefined }));\n};\n\nconst getTracebackCodeItem = (\n    filename: string,\n    allCodeNames: Record<string, { codePath: string; fullName: string }>,\n    appPackageName?: string\n) => {\n    const match = filename.match(FILEMATCHER);\n    if (!match) return;\n\n    const itemName = match[1].replace(SLASH, \".\");\n    const packageName = appPackageName || \"main_app_package\";\n    if (!itemName.startsWith(packageName + \".\")) return;\n\n    const jumpToMatch = match[1].match(JUMPMATCHER);\n    const codePath = jumpToMatch?.[1].replace(SLASH, \".\");\n    if (!codePath) return;\n\n    return allCodeNames[codePath];\n};\n\nconst formatTracebackText = (\n    msg: MessagePythonError,\n    allCodeNames: Record<string, { codePath: string; fullName: string }>,\n    appPackageName?: string\n) =>\n    getTraceItems(msg)\n        ?.map(({ filename, lineno }, idx) => {\n            const prefix = idx === 0 ? \"at\" : \"called from\";\n\n            if (filename === \"<rpc>\") {\n                return `${prefix} <running on the server>`;\n            }\n\n            const codeItem = getTracebackCodeItem(filename, allCodeNames, appPackageName);\n            const location = codeItem?.fullName ? `${codeItem.fullName}, line ${lineno}` : `${filename}:${lineno}`;\n\n            return `${prefix} ${location}`;\n        })\n        .join(\"\\n\");\n\ninterface TraceBackProps {\n    classes: Classes;\n    msg: MessagePythonError;\n}\n\nconst TraceBack: React.FC<TraceBackProps> = ({ msg, classes }) => {\n    const traceItems = useMemo(() => getTraceItems(msg), [msg]);\n\n    const allCodeNames = useSelector(getCodeNames);\n    const runnerMaximised = useSelector(getRunnerViewMaximised);\n    const appPackageName = useSelector(getAppPackageName);\n    const appId = useSelector(getAppId);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const tracebackNavigate = useCallback(\n        async (navTarget: NavTarget) => {\n            if (runnerMaximised) {\n                await dispatch(restoreRunnerView());\n            }\n            dispatch(navigate(navTarget));\n        },\n        [runnerMaximised, appId]\n    );\n\n    return (\n        <ul>\n            {traceItems?.map(({ filename, lineno, colno }, idx) => (\n                <li key={idx}>\n                    {filename === \"<rpc>\" ? (\n                        <code>&lt;running on the server&gt;</code>\n                    ) : (\n                        <code className={classes.code}>\n                            {idx === 0 ? \"at \" : \" called from \"}\n                            <TraceBackLink\n                                filename={filename}\n                                lineno={lineno}\n                                colno={colno}\n                                classes={classes}\n                                allCodeNames={allCodeNames}\n                                appPackageName={appPackageName}\n                                tracebackNavigate={tracebackNavigate}\n                            />\n                        </code>\n                    )}\n                </li>\n            ))}\n        </ul>\n    );\n};\n\ninterface BindingTraceBackProps {\n    classes: Classes;\n    bindingErrors: BindingError[];\n}\n\nconst BindingTraceBack: React.FC<BindingTraceBackProps> = ({ classes, bindingErrors }) => {\n    const allCodeNames = useSelector(getCodeNames);\n    const dispatch = useDispatch<AnvilDispatch>();\n    const app = useSelector(getApp);\n\n    const stopAppAndNavigate = async ({ formName, binding: { component_name, property } }: BindingError) => {\n        await dispatch(stopApp());\n        const codePath = allCodeNames[formName].codePath;\n\n        const target: NavTarget = {\n            type: \"CODE\",\n            codePath,\n            view: { design: [\"binding\", `${component_name}.${property}`] },\n            ...getInPlaceEditTarget(app, codePath),\n        };\n        dispatch(navigate(target));\n    };\n\n    return (\n        <ul>\n            {bindingErrors.map((b, idx) => (\n                <li className={cx(classes.alert, classes.alertDanger)} key={idx}>\n                    Error binding\n                    <LinkInternal className={classes.link} onClick={() => stopAppAndNavigate(b)}>\n                        <code className={classes.code}>{b.binding.property}</code> of{\" \"}\n                        <code className={classes.code}>{b.binding.component_name || b.formName}</code>\n                    </LinkInternal>\n                    to<code className={cx(classes.code, classes.bindingCode)}>{b.binding.code}</code>:<br />\n                    <span className={classes.codeHighlight}>\n                        <code className={classes.code}>{b.message}</code>\n                    </span>\n                </li>\n            ))}\n        </ul>\n    );\n};\n\ninterface PythonErrorProps {\n    classes: Classes;\n    msg: MessagePythonError;\n}\n\nconst PythonError: React.FC<PythonErrorProps> = ({ msg, classes }) => {\n    const user = useSelector(getUser);\n    const errType = msg.type || msg.errorObj?.type || \"Error\";\n    const errMsg = `${errType}: ${msg.msg || msg.message || msg.errorObj?.message || \"\"}`;\n    const dispatch = useDispatch<AnvilDispatch>();\n    const allCodeNames = useSelector(getCodeNames);\n    const appPackageName = useSelector(getAppPackageName);\n    //todo: this i think used to be for some specific pyspace spacing. need to go back and fix at some point\n    const isPySpace = useIsPySpace();\n    const agentsEnabled = useAgentsEnabled();\n    const isCreatingConversation = useSelector(getIsCreatingConversation);\n\n    const getAIhelpForError = useEvent(() => {\n        let text = \"I've seen this exception. Can you work out what caused it and suggest what to do about it:\\n\\n\";\n        text += errMsg;\n\n        const tracebackText = formatTracebackText(msg, allCodeNames, appPackageName);\n        if (tracebackText) {\n            text += `\\n${tracebackText}`;\n        }\n\n        dispatch(createConversation([{ type: \"text\", text }]));\n    });\n\n    return (\n        <div\n            className={cx(\n                classes.errorOutput,\n                classes.selectable,\n                msg.traceback\n                    ? {\n                        [classes.server]: msg.traceback[0]?.fromServer,\n                        [classes.client]: !msg.traceback[0]?.fromServer,\n                        [classes.read]: msg.read,\n                    }\n                    : null,\n                \"group relative\"\n            )}>\n            {agentsEnabled && !user?.impersonator && (\n                <div className=\"absolute right-12 opacity-10 group-hover:opacity-100\">\n                    <Button\n                        onClick={getAIhelpForError}\n                        disabled={isCreatingConversation}\n                        small\n                        className=\"\"\n                        variant={\"primary\"}\n                        icon={isCreatingConversation ? faSpinnerThird : faSparkle}\n                        iconSpin={isCreatingConversation}\n                        iconRight>\n                        {isCreatingConversation ? \"Starting chat...\" : \"Ask AI for help\"}\n                    </Button>\n                </div>\n            )}\n            <code className={classes.code}>\n                {errMsg}\n                <br />\n            </code>\n            {msg.errorObj?.docId && (\n                <div className=\"alert alert-warning text-center\">\n                    <HelpLink url={`https://anvil.works/doc#${msg.errorObj.docId}`} className={cx(\"ml-4\")} left>\n                        {`${msg.errorObj.docLinkTitle} ` || \"More information\"}\n                    </HelpLink>\n                </div>\n            )}\n            {/** @todo check this will work with docUrl or if we need to add an absolute URL as above */}\n            {msg.errorObj?.docUrl && (\n                <div className=\"alert alert-warning text-center\">\n                    <HelpLink url={`docs${msg.errorObj.docUrl}`} className={cx(\"ml-4\")} left>\n                        {`${msg.errorObj.docLinkTitle} ` || \"More information\"}\n                    </HelpLink>\n                </div>\n            )}\n            {msg.errorObj?.bindingErrors && (\n                <BindingTraceBack bindingErrors={msg.errorObj.bindingErrors} classes={classes} />\n            )}\n            {(msg.traceback || msg.errorObj?.trace) && <TraceBack msg={msg} classes={classes} />}\n        </div>\n    );\n};\n\ninterface RuntimeErrorProps {\n    classes: Classes;\n    msg: MessageRuntimeError;\n}\n\nconst RuntimeError: React.FC<RuntimeErrorProps> = ({ msg, classes }) => {\n    const errorMsg = msg.stackTrace ?? msg.msg;\n\n    return (\n        <div className={cx(classes.errorOutput, classes.selectable, classes.client)}>\n            <ul>\n                <li>\n                    <code className={classes.code}>\n                        [An internal error has occurred] - <i>see browser console for more details</i>\n                    </code>\n                </li>\n                {errorMsg && (\n                    <li>\n                        <code style={{ whiteSpace: \"pre\" }} className={classes.code}>\n                            {errorMsg}\n                        </code>\n                    </li>\n                )}\n            </ul>\n        </div>\n    );\n};\n\ninterface ReplCommandProps {\n    classes: Classes;\n    msg: MessageReplCommand;\n}\n\nconst ReplCommand: React.FC<ReplCommandProps> = ({ classes, msg }) => {\n    const lines = msg.command.split(\"\\n\");\n\n    return (\n        <div\n            className={cx(classes.codeOutput, classes.selectable, {\n                [classes.server]: msg.onServer,\n                [classes.client]: !msg.onServer,\n                [classes.read]: msg.read,\n            })}>\n            <div className={classes.displayFlex}>\n                <span className={classes.prompt}>{`>>>`}</span>\n                <span className={classes.replCommand}>{`${lines[0]}`}</span>\n            </div>\n\n            {lines.slice(1).map((line, i) => (\n                <div key={i + line} className={classes.displayFlex}>\n                    <span className={classes.prompt}>{\"...\"}</span>\n                    <span className={classes.replCommand}>{`${line}`}</span>\n                </div>\n            ))}\n        </div>\n    );\n};\n\ninterface StdOutProps {\n    classes: Classes;\n    msg: MessageStdOut;\n}\n\nconst StdOut: React.FC<StdOutProps> = ({ classes, msg }) => (\n    <div\n        className={cx(classes.codeOutput, classes.selectable, {\n            [classes.server]: msg.fromServer,\n            [classes.client]: !msg.fromServer,\n            [classes.read]: msg.read,\n        })}>\n        {msg.text}\n    </div>\n);\n\nconst renderMessage = (msg: Message, classes: RenderMessageClasses): React.ReactNode => {\n    switch (msg.fn) {\n        case \"stdout\":\n            return <StdOut classes={classes} msg={msg} />;\n        case \"warning\":\n            return (\n                <div className={cx(classes.errorOutput, classes.selectable, classes.client, { [classes.read]: msg.read })}>\n                    <div role=\"status\" className={cx(classes.alertWarning, \"my-2 rounded border px-3 py-2\")}>\n                        <div>\n                            <code className={cx(classes.code, \"text-inherit!\")}>{msg.message}</code>\n                        </div>\n                        {msg.docUrl && (\n                            <Link\n                                to={`https://anvil.works/docs${msg.docUrl}`}\n                                target=\"_blank\"\n                                rel=\"noopener noreferrer\"\n                                className={classes.link}>\n                                <FontAwesomeIcon icon={faQuestionCircle} fixedWidth />{\" \"}\n                                {msg.docLinkTitle ?? \"More information\"}\n                            </Link>\n                        )}\n                    </div>\n                </div>\n            );\n        case \"clear\":\n            return (\n                <div className={cx(classes.codeOutput, classes.client, classes.selectable)}>\n                    <i>Console was cleared</i>\n                </div>\n            );\n        case \"pythonError\":\n            return <PythonError classes={classes} msg={msg} />;\n        case \"replCommand\":\n            return <ReplCommand classes={classes} msg={msg} />;\n        case \"session\":\n            return (\n                <div className={cx(classes.selectable, classes.sessionOutput, { [classes.read]: msg.read })}>\n                    <p className={\"mb-3\"}>{msg.text}</p>\n                </div>\n            );\n        case \"runtimeError\":\n            return <RuntimeError classes={classes} msg={msg} />;\n        case \"bgTask\":\n            return <RunnerBgTaskWidget sessionId={msg.sessionId} />;\n        default:\n            log.warn(\"unknown message\", msg);\n            return null;\n    }\n};\n\ninterface LiveOutputProps {\n    messages: Message[];\n    autoScroll: boolean;\n    setAutoScroll: (value: boolean) => void;\n}\n\nexport interface SearchHighlight {\n    left: number;\n    top: number;\n    width: number;\n    height: number;\n    text: string;\n}\n\nconst INIT_SEARCH = {\n    isSearchOpen: 0,\n    searchTerm: \"\",\n    searchHighlights: [] as SearchHighlight[],\n    currentSearchHighlight: -1,\n};\n\ntype SearchState = typeof INIT_SEARCH;\n\nclass LiveOutputSearchStore extends ExternalStore<SearchState> {\n    updateHighlights(highlights: SearchHighlight[], currentHighlight: number) {\n        this.setState({\n            searchHighlights: highlights,\n            currentSearchHighlight: currentHighlight,\n        });\n    }\n\n    reset() {\n        this.setState({\n            searchHighlights: [],\n            currentSearchHighlight: -1,\n            searchTerm: \"\",\n        });\n    }\n\n    close() {\n        this.setState({ isSearchOpen: 0 });\n    }\n\n    open() {\n        this.updateState((s) => {\n            s.isSearchOpen++;\n        });\n    }\n\n    toggle() {\n        this.updateState((s) => {\n            s.isSearchOpen = s.isSearchOpen ? 0 : 1;\n        });\n    }\n}\n\nexport const liveOutputSearchStore = new LiveOutputSearchStore(INIT_SEARCH, { deepEquality: true });\nexport const { useStore: useLiveOutputSearchStore } = createExternalStoreHooks(liveOutputSearchStore);\n\nconst SearchHighlights = () => {\n    const { searchHighlights: highlights, currentSearchHighlight: currentHighlight } = useLiveOutputSearchStore();\n\n    return (\n        <div className=\"pointer-events-none absolute inset-0\">\n            {highlights.map((highlight, i) => (\n                <mark\n                    key={i}\n                    className={cx(\"absolute\", i === currentHighlight ? \"bg-[#ff00ff8a]\" : \"bg-[#00ffff8a]\")}\n                    style={{\n                        left: `${highlight.left}px`,\n                        top: `${highlight.top}px`,\n                        width: `${highlight.width}px`,\n                        height: `${highlight.height}px`,\n                    }}\n                />\n            ))}\n        </div>\n    );\n};\n\nconst TEXT_NODE_FILTER: NodeFilter = {\n    acceptNode: (node: Node) => {\n        const parent = node.parentNode;\n        if (!parent || /^(script|style)$/i.test(parent.nodeName)) {\n            return NodeFilter.FILTER_REJECT;\n        }\n        return NodeFilter.FILTER_ACCEPT;\n    },\n};\n\nconst useProcessHighlights = (messageBodyRef: React.RefObject<HTMLDivElement | null>) => {\n    const { searchTerm } = useLiveOutputSearchStore();\n\n    const findHighlights = (node: Node, term: string): SearchHighlight[] => {\n        if (node.nodeType !== Node.TEXT_NODE || !node.textContent?.trim()) return [];\n\n        const messageBody = messageBodyRef.current;\n        if (!messageBody) return [];\n\n        const messageRect = messageBody.getBoundingClientRect();\n        const scrollTop = messageBody.scrollTop;\n        const text = node.textContent;\n        const searchText = text.toLowerCase();\n        const searchTerm = term.toLowerCase();\n\n        const range = document.createRange();\n        let startPos = 0;\n        let index: number;\n        const highlights: SearchHighlight[] = [];\n\n        while ((index = searchText.indexOf(searchTerm, startPos)) !== -1) {\n            range.setStart(node, index);\n            range.setEnd(node, index + term.length);\n            const rangeRect = range.getBoundingClientRect();\n\n            highlights.push({\n                left: rangeRect.left - messageRect.left,\n                top: rangeRect.top - messageRect.top + scrollTop,\n                width: rangeRect.width,\n                height: rangeRect.height,\n                text: text.slice(index, index + term.length),\n            });\n\n            startPos = index + term.length;\n        }\n\n        return highlights;\n    };\n\n    const processMessageBody = useEvent((term?: string) => {\n        term ??= searchTerm;\n\n        if (!term) {\n            liveOutputSearchStore.updateHighlights([], -1);\n            return;\n        }\n\n        const messageBody = messageBodyRef.current;\n        if (!messageBody) return;\n\n        const walker = document.createTreeWalker(messageBody, NodeFilter.SHOW_TEXT, TEXT_NODE_FILTER);\n        const allHighlights: SearchHighlight[] = [];\n        let currentNode: Node | null;\n\n        while ((currentNode = walker.nextNode())) {\n            allHighlights.push(...findHighlights(currentNode, term));\n        }\n\n        if (allHighlights.length === 0) {\n            liveOutputSearchStore.updateHighlights([], -1);\n            return;\n        }\n\n        // Find nearest visible highlight\n        const messageRect = messageBody.getBoundingClientRect();\n        const scrollTop = messageBody.scrollTop;\n        const viewportTop = 0;\n        const viewportBottom = messageRect.height;\n\n        const nearestHighlightIndex = allHighlights.findIndex((highlight) => {\n            const highlightTop = highlight.top - scrollTop;\n            return highlightTop >= viewportTop && highlightTop <= viewportBottom;\n        });\n\n        liveOutputSearchStore.updateHighlights(allHighlights, Math.max(0, nearestHighlightIndex));\n    });\n    return processMessageBody;\n};\n\nconst SearchControls = ({ messageBodyRef }: { messageBodyRef: React.RefObject<HTMLDivElement | null> }) => {\n    const {\n        isSearchOpen,\n        searchTerm,\n        searchHighlights: highlights,\n        currentSearchHighlight: currentHighlight,\n    } = useLiveOutputSearchStore();\n\n    const processMessageBody = useProcessHighlights(messageBodyRef);\n\n    const history = useSearchHistory(outputSearchHistoryStore);\n    const { showHistoryHint, resetNavigation, onFocus, onBlur } = history;\n    const updateSearchTerm = useEvent((searchTerm: string) => {\n        liveOutputSearchStore.updateState({ searchTerm, searchHighlights: [], currentSearchHighlight: -1 });\n        if (searchTerm) {\n            processMessageBody(searchTerm);\n        }\n    });\n\n    const onSearchTerm = useEvent((e: React.ChangeEvent<HTMLInputElement>) => {\n        resetNavigation();\n        updateSearchTerm(e.target.value);\n        outputSearchHistoryStore.recordAfterPause(e.target.value);\n    });\n\n    const onSearchKeyDown = useSearchHistoryKeyDown(history, searchTerm, (term) => {\n        outputSearchHistoryStore.cancelPendingRecord();\n        updateSearchTerm(term);\n    });\n\n    const onPreviousClick = useEvent(() => {\n        const newIndex = currentHighlight <= 0 ? highlights.length - 1 : currentHighlight - 1;\n        liveOutputSearchStore.updateState({ currentSearchHighlight: newIndex });\n\n        const highlight = highlights[newIndex];\n        if (messageBodyRef.current && highlight) {\n            messageBodyRef.current.scrollTo({\n                top: highlight.top - 100,\n            });\n        }\n    });\n\n    const onEnter: React.KeyboardEventHandler<HTMLInputElement> = useEvent((e) => {\n        resetNavigation();\n        outputSearchHistoryStore.record(searchTerm);\n        if (e.shiftKey) {\n            onPreviousClick();\n        } else {\n            onNextClick();\n        }\n    });\n\n    const onNextClick = useEvent(() => {\n        const newIndex = currentHighlight < highlights.length - 1 ? currentHighlight + 1 : 0;\n        liveOutputSearchStore.updateState({ currentSearchHighlight: newIndex });\n\n        const highlight = highlights[newIndex];\n        if (messageBodyRef.current && highlight) {\n            messageBodyRef.current.scrollTo({\n                top: highlight.top - 100,\n                behavior: \"smooth\",\n            });\n        }\n    });\n\n    const inputRef = useRef<HTMLInputElement>(null);\n    useUpdateEffect(() => {\n        resetNavigation();\n        isSearchOpen && inputRef.current?.select();\n    }, [isSearchOpen]);\n\n    const onEscape = useEvent(() => liveOutputSearchStore.close());\n\n    return (\n        <div className=\"absolute top-0 right-4 z-2 flex w-fit items-center gap-3 border-r border-b border-l border-sectionborder bg-white p-4 dark:border-dark-sectionborder dark:bg-dark-bg0\">\n            <div className=\"relative\">\n                <ContentTextInput\n                    ref={inputRef}\n                    className=\"h-[2.6rem]! pr-8! pl-2! text-lg!\"\n                    value={searchTerm}\n                    aria-label=\"Search output\"\n                    placeholder={showHistoryHint ? \"Find (⇅ for history)\" : \"Find\"}\n                    onChange={onSearchTerm}\n                    onKeyDown={onSearchKeyDown}\n                    onFocus={onFocus}\n                    onBlur={onBlur}\n                    onEscape={onEscape}\n                    onEnter={onEnter}\n                    autoFocus\n                    autoComplete=\"off\"\n                />\n                <div className=\"absolute top-1/2 right-3 flex -translate-y-1/2\">\n                    {searchTerm && (\n                        <LinkInternal\n                            className=\"opacity-50 hover:opacity-100\"\n                            icon={faTimes}\n                            onClick={() => {\n                                outputSearchHistoryStore.cancelPendingRecord();\n                                resetNavigation();\n                                liveOutputSearchStore.reset();\n                            }}\n                        />\n                    )}\n                </div>\n            </div>\n            <span className=\"text-muted min-w-14 text-center text-sm\">\n                {highlights.length ? `${currentHighlight + 1} of ${highlights.length}` : \"No Results\"}\n            </span>\n            <Button small onClick={onPreviousClick} disabled={highlights.length === 0}>\n                <FontAwesomeIcon icon={faAngleUp} />\n            </Button>\n            <Button small onClick={onNextClick} disabled={highlights.length === 0}>\n                <FontAwesomeIcon icon={faAngleDown} />\n            </Button>\n        </div>\n    );\n};\n\nconst LiveOutput: React.FC<LiveOutputProps> = ({ messages, autoScroll, setAutoScroll }) => {\n    const { classes } = useStyles();\n    const messageBodyRef = useRef<HTMLDivElement>(null);\n    const prevHeightFromBottom = useRef(0);\n\n    const { isSearchOpen } = useLiveOutputSearchStore();\n\n    const onScroll: React.UIEventHandler<HTMLDivElement> = useEvent(() => {\n        const outputBody = messageBodyRef.current;\n        if (!outputBody) return;\n\n        const heightFromBottom = outputBody.scrollHeight - outputBody.offsetHeight - outputBody.scrollTop;\n\n        // we only want to change autoScroll if we are very close to the bottom and we're scrolling down\n        const scrollingUp = prevHeightFromBottom.current < heightFromBottom;\n        prevHeightFromBottom.current = heightFromBottom;\n\n        if (!scrollingUp && heightFromBottom < 2) {\n            // we can't guarantee that scrolling to the bottom gives a heightFromBottom=0px so we use 2px to be safe\n            setAutoScroll(true);\n        } else if (scrollingUp && heightFromBottom > 50) {\n            // 50px is arbitrary\n            setAutoScroll(false);\n        }\n    });\n\n    const MessageElements = useMemo(\n        () => messages.map((msg, idx) => <div key={idx}>{renderMessage(msg, classes)}</div>),\n        [messages, classes]\n    );\n\n    useLayoutEffect(() => {\n        const outputBody = messageBodyRef.current;\n        if (!outputBody || !autoScroll) return;\n        outputBody.scrollTop = outputBody.scrollHeight - outputBody.clientHeight;\n        prevHeightFromBottom.current = 0;\n    }, [autoScroll, messages]);\n\n    // Embedded blocks (e.g. inline BG-task widgets) grow without `messages` changing, so\n    // the effect above never fires for them. When one grows:\n    //  * if lines below the block's end were in view, keep those same lines in view\n    //    (shift down by the added height - don't force the reader \"up\" within later output);\n    //  * otherwise, with auto-scroll on, follow the block's new output to its end.\n    const onEmbeddedBlockGrowth = useEvent((blockEl: HTMLElement, delta: number) => {\n        const outputBody = messageBodyRef.current;\n        if (!outputBody || delta <= 0) return;\n        const scrollTop = outputBody.scrollTop;\n        const viewportBottom = scrollTop + outputBody.clientHeight;\n        const blockEndAfter =\n            blockEl.getBoundingClientRect().bottom - outputBody.getBoundingClientRect().top + scrollTop;\n        const blockEndBefore = blockEndAfter - delta;\n        if (viewportBottom > blockEndBefore + 1) {\n            outputBody.scrollTop = scrollTop + delta;\n        } else if (autoScroll) {\n            outputBody.scrollTop = blockEndAfter - outputBody.clientHeight;\n        } else {\n            return;\n        }\n        // Keep the auto-scroll toggle heuristic in onScroll from misreading our\n        // programmatic scroll as the user scrolling.\n        prevHeightFromBottom.current = outputBody.scrollHeight - outputBody.offsetHeight - outputBody.scrollTop;\n    });\n\n    const onCopyAll = useCopyAllKeyBinding(messageBodyRef);\n\n    const processMessageBody = useProcessHighlights(messageBodyRef);\n\n    useEffect(() => {\n        processMessageBody();\n    }, [messages, processMessageBody]);\n\n    return (\n        <EmbeddedBlockGrowthContext.Provider value={onEmbeddedBlockGrowth}>\n            <div className={classes.root}>\n                {!!isSearchOpen && <SearchControls messageBodyRef={messageBodyRef} />}\n                <div\n                    tabIndex={0}\n                    ref={messageBodyRef}\n                    onKeyDown={onCopyAll}\n                    className={cx(classes.root, \"relative overflow-y-auto!\")}\n                    onScroll={onScroll}>\n                    {!!isSearchOpen && <SearchHighlights />}\n                    <div className=\"relative\">{MessageElements}</div>\n                </div>\n            </div>\n        </EmbeddedBlockGrowthContext.Provider>\n    );\n};\n\nexport default LiveOutput;\n","import React, { useMemo, useState } from \"react\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { useTimeout } from \"@/util/hooks\";\nimport useModalStyles from \"../modals/modalstyles\";\nimport { LoadingSpinner } from \"./LoadingSpinner\";\n\nconst useStyles = makeStyles()((theme) => ({\n    background: {\n        background: \"none\",\n        opacity: 1,\n        transition: \"opacity 0.2s ease-in 0.5s\",\n        pointerEvents: \"none\",\n    },\n    loading: {\n        border: \"none\",\n        minHeight: \"12rem\",\n        width: \"20rem\",\n        textAlign: \"center\",\n        background: \"transparent\",\n        display: \"flex\",\n        flexDirection: \"column\",\n        alignItems: \"center\",\n    },\n    indicatorText: {\n        background: theme.loading.background.toString(),\n        borderRadius: \"5px\",\n        padding: \"1rem\",\n        whiteSpace: \"nowrap\",\n        width: \"min-content\",\n    },\n    hide: {\n        opacity: 0,\n        transition: \"opacity 0.2s ease-in 0s\",\n    },\n    spacerMiddle: {\n        marginBottom: \"12rem\",\n    },\n}));\n\nexport const DelayedLoadingSpinner = ({ delay = 50 }) => {\n    const [showSpinner, setShowSpinner] = useState(false);\n    useTimeout(() => setShowSpinner(true), delay);\n\n    return showSpinner && <LoadingSpinner />;\n};\n\nconst Loading = ({ indicator, global }: { indicator: any; global?: boolean }) => {\n    const { classes: localClasses } = useStyles();\n    const { classes: modalClasses } = useModalStyles();\n    const classes = useMemo(() => ({ ...modalClasses, ...localClasses }), [localClasses, modalClasses]);\n\n    return (\n        <div className={cx(classes.root, classes.background, !indicator && classes.hide)}>\n            <div className={classes.spacerTop} />\n            <div className={cx(classes.modal, classes.loading)}>\n                <LoadingSpinner global={global} />\n                <div className={classes.spacerMiddle} />\n                {indicator && indicator !== true && <div className={classes.indicatorText}>{indicator}</div>}\n            </div>\n            <div className={classes.spacerBottom} />\n        </div>\n    );\n};\n\nexport default Loading;\n","import React from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { keyframes } from \"tss-react\";\nimport { getLoadingIndicator } from \"@/controllers/app\";\nimport { makeStyles } from \"@/theme/styles\";\n\nconst skChase = keyframes`\n100% {\n    transform: rotate(360deg);\n}\n`;\n\nconst skChaseDot = keyframes`\n80%, 100% {\n    transform: rotate(360deg);\n}\n`;\n\nconst skChaseDotBefore = keyframes`\n50% {\n    transform: scale(0.4);\n}\n100%, 0% {\n    transform: scale(1.0);\n}\n`;\n\nconst useStyles = makeStyles<{ inline?: boolean; sizeRem?: number }>()((theme, props, classes) => ({\n    root: {\n        zIndex: 9999,\n        width: `${props.sizeRem ?? 6.4}rem`,\n        height: `${props.sizeRem ?? 6.4}rem`,\n        position: props.inline ? \"relative\" : \"absolute\",\n        left: props.inline ? \"auto\" : \"calc(50% - 3.2rem)\",\n        top: props.inline ? \"auto\" : \"calc(30% - 3.2rem)\",\n        animation: `${skChase} 2.5s infinite linear both`,\n        marginTop: props.inline ? 0 : \"2rem\",\n    },\n    skChaseDot: {\n        width: \"100%\",\n        height: \"100%\",\n        position: \"absolute\",\n        left: 0,\n        top: 0,\n        animation: `${skChaseDot} 2.0s infinite ease-in-out both`,\n        \"&:before\": {\n            content: '\"\"',\n            display: \"block\",\n            width: \"25%\",\n            height: \"25%\",\n            background: theme.hl1.hex(),\n            borderRadius: \"100%\",\n            animation: `${skChaseDotBefore} 2.0s infinite ease-in-out both`,\n        },\n        \"&:nth-of-type(1)\": { animationDelay: \"-1.1s\" },\n        \"&:nth-of-type(2)\": { animationDelay: \"-1.0s\" },\n        \"&:nth-of-type(3)\": { animationDelay: \"-0.9s\" },\n        \"&:nth-of-type(4)\": { animationDelay: \"-0.8s\" },\n        \"&:nth-of-type(5)\": { animationDelay: \"-0.7s\" },\n        \"&:nth-of-type(6)\": { animationDelay: \"-0.6s\" },\n        \"&:nth-of-type(1):before\": { animationDelay: \"-1.1s\" },\n        \"&:nth-of-type(2):before\": { animationDelay: \"-1.0s\" },\n        \"&:nth-of-type(3):before\": { animationDelay: \"-0.9s\" },\n        \"&:nth-of-type(4):before\": { animationDelay: \"-0.8s\" },\n        \"&:nth-of-type(5):before\": { animationDelay: \"-0.7s\" },\n        \"&:nth-of-type(6):before\": { animationDelay: \"-0.6s\" },\n    },\n}));\n\nconst LoadingSpinnerInternal = ({ inline, sizeRem }: { inline?: boolean; sizeRem?: number }) => {\n    const { classes } = useStyles({ inline, sizeRem });\n    return (\n        <div className={classes.root}>\n            <div className={classes.skChaseDot} />\n            <div className={classes.skChaseDot} />\n            <div className={classes.skChaseDot} />\n            <div className={classes.skChaseDot} />\n            <div className={classes.skChaseDot} />\n            <div className={classes.skChaseDot} />\n        </div>\n    );\n};\n\nexport const LoadingSpinner = ({\n    global,\n    inline,\n    sizeRem,\n}: {\n    global?: boolean;\n    inline?: boolean;\n    sizeRem?: number;\n}) => {\n    const loadingIndicator = useSelector(getLoadingIndicator);\n    if (loadingIndicator && !global) return null;\n    return <LoadingSpinnerInternal inline={inline} sizeRem={sizeRem} />;\n};\n","import React, { useLayoutEffect, useRef } from \"react\";\nimport { useStateWithReset } from \"@/util/hooks\";\nimport { cx } from \"../../theme/styles\";\nimport useEvent from \"../../util/useEventCallback\";\nimport { ContentTextInput } from \"./SharedComponents\";\n\ninterface RenamerProps extends React.InputHTMLAttributes<HTMLInputElement> {\n    name: string;\n    initialSelectionStart?: number;\n    initialSelectionEnd?: number;\n    autoFocus?: boolean;\n    onRename?(nameBuffer: string): void;\n    onCancel?(): void;\n    small?: boolean;\n}\n\ninterface NavNodeRenamerProps extends RenamerProps {\n    isSelected?: boolean;\n}\n\nexport const NodeRenamer = ({\n    autoFocus = true,\n    small,\n    name,\n    onRename,\n    onCancel,\n    className,\n    initialSelectionStart = 0,\n    initialSelectionEnd,\n    ...props\n}: RenamerProps) => {\n    const [nameBuffer, setNameBuffer] = useStateWithReset(name);\n    const inputRef = useRef<HTMLInputElement>(null);\n\n    const onConfirm = useEvent(() => {\n        if (nameBuffer && name !== nameBuffer) {\n            onRename?.(nameBuffer);\n        } else {\n            onCancel?.();\n        }\n    });\n\n    useLayoutEffect(() => {\n        if (!autoFocus) return;\n\n        const input = inputRef.current;\n        if (!input) return;\n\n        input.focus();\n        input.setSelectionRange(initialSelectionStart, initialSelectionEnd ?? input.value.length);\n    }, []);\n\n    const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useEvent((e) => {\n        switch (e.key) {\n            case \"Enter\":\n                e.preventDefault();\n                e.stopPropagation();\n                // avoid double calling onConfirm\n                inputRef.current?.blur();\n                break;\n            case \"Escape\":\n                e.preventDefault();\n                e.stopPropagation();\n                onCancel?.();\n                break;\n        }\n    });\n\n    const onChange: React.ChangeEventHandler<HTMLInputElement> = useEvent((e) => setNameBuffer(e.target.value));\n\n    return (\n        <ContentTextInput\n            className={className}\n            small={small}\n            ref={inputRef}\n            type={\"text\"}\n            value={nameBuffer}\n            onChange={onChange}\n            onBlur={onConfirm}\n            onKeyDown={onKeyDown}\n            {...props}\n        />\n    );\n};\n\nexport const NavNodeRenamer = ({ className, isSelected = true, ...props }: NavNodeRenamerProps) => {\n    return (\n        <NodeRenamer\n            small\n            className={cx(\n                \"-ml-2 h-full! rounded-none! border-none! p-0! pl-2! font-medium!\",\n                isSelected\n                    ? \"bg-gray-600! text-white! selection:bg-gray-500\"\n                    : \"bg-transparent! text-[inherit]! selection:bg-sidebar-highlight3 dark:selection:bg-dark-bg6\",\n                className\n            )}\n            {...props}\n        />\n    );\n};\n","import React, { useCallback, useEffect, useReducer, useRef } from \"react\";\nimport { faCheck, faExclamationTriangle, faSync } from \"@fortawesome/free-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { cx } from \"@/theme/styles\";\n\ninterface SaveState {\n    saved: boolean | null;\n    saveError: string | boolean | null;\n    showSaving: boolean;\n}\n\nconst InitSaveIndicatorState = {\n    saved: null,\n    saveError: null,\n    showSaving: false,\n};\n\nconst saveIndicatorReducer = (prev: SaveState, next: Partial<SaveState>) => {\n    if (next.saveError) {\n        return { ...prev, ...next, showSaving: false, saved: null };\n    }\n    if (next.saved === true) {\n        // always show something is saved, even if the saving indicator delay timeout wasn't triggered\n        return { ...prev, ...next, showSaving: true, saveError: null };\n    }\n    if (next.saved === false) {\n        return { ...prev, ...next, saveError: null };\n    }\n    return { ...prev, ...next };\n};\n\nexport const useSaveIndicator = (delay = 250, display = 1000) => {\n    const [{ saved, saveError, showSaving }, updateState] = useReducer(saveIndicatorReducer, InitSaveIndicatorState);\n    const setSaved = useCallback((saved: boolean | null) => updateState({ saved }), []);\n    const setSaveError = useCallback((saveError: string | null) => updateState({ saveError }), []);\n\n    const showSavingTimeout = useRef<number | undefined>(undefined);\n    useEffect(() => {\n        if (saveError) {\n            clearTimeout(showSavingTimeout.current);\n        }\n    }, [saveError]);\n\n    useEffect(() => {\n        if (saved === true) {\n            showSavingTimeout.current = setTimeout(() => updateState({ saved: null, showSaving: false }), display);\n        } else if (saved === false) {\n            showSavingTimeout.current = setTimeout(() => updateState({ showSaving: true }), delay);\n        }\n        return () => clearTimeout(showSavingTimeout.current);\n    }, [saved]);\n\n    const FA = (\n        <FontAwesomeIcon\n            title={typeof saveError === \"string\" ? saveError : undefined}\n            className={cx(\"ml-3 text-light-fg1 dark:text-dark-fg1\", {\n                \"hidden!\": !saveError && !showSaving,\n                \"text-tertiary!\": !!saveError,\n            })}\n            fixedWidth={true}\n            spin={saved === false}\n            icon={saveError ? faExclamationTriangle : saved ? faCheck : faSync}\n        />\n    );\n\n    return [FA, setSaved, setSaveError] as const;\n};\n","import React, { useLayoutEffect, useRef, useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport type { IconProp } from \"@fortawesome/fontawesome-svg-core\";\nimport { faCaretDown } from \"@fortawesome/free-solid-svg-icons/faCaretDown\";\nimport { faCaretRight } from \"@fortawesome/free-solid-svg-icons/faCaretRight\";\nimport { faChevronDown } from \"@fortawesome/free-solid-svg-icons/faChevronDown\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useSaveIndicator } from \"@/components/reusable/SaveIndicator\";\nimport { getAppId } from \"@/controllers/app\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { ignoreSsrWarning } from \"@/theme/utils\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport * as api from \"@/api\";\nimport { useMergeRefs, useStateWithReset } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport type { ButtonProps } from \"./Button\";\nimport { Button } from \"./Button\";\nimport type { DropDownMenuItems } from \"./DropdownMenu\";\nimport DropdownMenu from \"./DropdownMenu\";\nimport { DropDown, InputLabel, TextArea, TextBox } from \"./Forms\";\nimport { LinkInternal } from \"./LinkInternal\";\n\nconst LINE_HEIGHT = 2; // REM\n\ntype SharedVariant = \"primary\" | \"danger\" | \"success\" | \"highlight\" | \"tertiary\";\ntype SharedComponentClasses = SharedVariant | \"disabled\" | \"selected\";\n\nexport const useStyles = makeStyles<void, SharedComponentClasses>()((theme, _props, classes) => ({\n    primary: {},\n    danger: {},\n    success: {},\n    highlight: {},\n    disabled: {\n        \"&:hover\": {\n            cursor: \"not-allowed\",\n        },\n    },\n    tertiary: {},\n    button: {\n        color: theme.isDark ? theme.palette.fg2.hex() : theme.palette.fg1.hex(),\n        backgroundColor: theme.isDark ? theme.palette.bg3.hex() : theme.palette.bg2.hex(),\n        border: \"1px solid \" + theme.isDark ? theme.palette.bg2.hex() : theme.palette.bg2.hex(),\n        display: \"inline-block\",\n        padding: \"2px 1.2rem\",\n        margin: 2,\n        fontSize: \"1.4rem\",\n        textAlign: \"center\",\n        cursor: \"pointer\",\n        borderRadius: 2,\n        \"&:hover\": {\n            backgroundColor: theme.isDark ? theme.palette.bg2.hex() : theme.palette.bg1.hex(),\n        },\n        \"&:active\": {\n            backgroundColor: theme.isDark ? theme.palette.bg1.hex() : theme.palette.bg2.hex(),\n        },\n        [`&.${classes.disabled}`]: {\n            backgroundColor: (theme.isDark ? theme.palette.bg3 : theme.palette.bg2).alpha(0.2).toString(),\n            color: (theme.isDark ? theme.palette.fg2 : theme.palette.fg1).alpha(0.2).toString(),\n            cursor: \"not-allowed\",\n            pointerEvents: \"none\",\n        },\n        [`&.${classes.success}`]: {\n            backgroundColor: theme.hl3.hex(),\n            color: theme.palette.bg0.hex(),\n            borderColor: theme.hl3.hex(),\n            \"&:hover\": {\n                backgroundColor: theme.hl3.lighten(0.2).hex(),\n            },\n            [`&.${classes.disabled}`]: {\n                backgroundColor: theme.hl3.alpha(0.2).toString(),\n                pointerEvents: \"none\",\n                borderColor: theme.hl3.alpha(0.2).toString(),\n            },\n        },\n        [`&.${classes.primary}`]: {\n            backgroundColor: theme.primary.hex(),\n            color: \"white\",\n            borderColor: theme.primary.hex(),\n            \"&:hover\": {\n                backgroundColor: theme.primary.lighten(0.2).hex(),\n            },\n            [`&.${classes.disabled}`]: {\n                backgroundColor: theme.primary.alpha(0.2).toString(),\n                pointerEvents: \"none\",\n                borderColor: theme.primary.alpha(0.2).toString(),\n            },\n        },\n        [`&.${classes.danger}`]: {\n            backgroundColor: theme.hl4.hex(),\n            color: \"white\",\n            borderColor: theme.hl4.hex(),\n            \"&:hover\": {\n                backgroundColor: theme.hl4.lighten(0.2).hex(),\n            },\n            [`&.${classes.disabled}`]: {\n                backgroundColor: theme.hl4.alpha(0.2).toString(),\n                pointerEvents: \"none\",\n                borderColor: theme.hl4.alpha(0.2).toString(),\n            },\n        },\n        [`&.${classes.tertiary}`]: {\n            backgroundColor: theme.tertiary.hex(),\n            color: \"white\",\n            borderColor: theme.tertiary.hex(),\n            \"&:hover\": {\n                backgroundColor: theme.tertiary.lighten(0.2).hex(),\n            },\n            [`&.${classes.disabled}`]: {\n                backgroundColor: theme.tertiary.alpha(0.2).toString(),\n                pointerEvents: \"none\",\n                borderColor: theme.tertiary.alpha(0.2).toString(),\n            },\n        },\n        [`&.${classes.highlight}`]: {\n            backgroundColor: theme.hl1.hex(),\n            color: \"white\",\n            borderColor: theme.hl1.hex(),\n            \"&:hover\": {\n                backgroundColor: theme.hl1.lighten(0.2).hex(),\n            },\n            [`&.${classes.disabled}`]: {\n                backgroundColor: theme.hl1.alpha(0.2).toString(),\n                pointerEvents: \"none\",\n                borderColor: theme.hl1.alpha(0.2).toString(),\n            },\n        },\n    },\n    modalLink: {\n        color: theme.isDark ? theme.palette.fg2.hex() : theme.palette.fg1.hex(),\n        margin: \"0 0.8rem\",\n        display: \"inline-block\",\n        textAlign: \"center\",\n        backgroundColor: \"transparent\",\n        borderColor: \"transparent\",\n        cursor: \"pointer\",\n        \"&:hover\": {\n            color: theme.isDark ? theme.palette.fg2.alpha(0.9).toString() : theme.palette.fg1.alpha(0.9).toString(),\n            cursor: \"pointer\",\n        },\n        [`&.${classes.success}`]: {\n            color: theme.hl3.hex(),\n            \"&:hover\": {\n                color: theme.hl3.lighten(0.2).hex(),\n            },\n        },\n    },\n    modalTopButton: {\n        float: \"right\",\n    },\n    sidebarButton: {\n        fontSize: `${(LINE_HEIGHT - 6) * 0.9}rem`,\n        padding: \"2px 0.6rem\",\n    },\n    bottomPanelToolbarButton: {\n        fontSize: `${(LINE_HEIGHT - 6) * 0.7}rem`,\n        padding: \"2px 0.6rem\",\n    },\n    bottomPanelContentButton: {\n        padding: \"0 0.6rem\",\n        fontSize: `${(LINE_HEIGHT - 6) * 0.7}rem`,\n        height: \"1.9rem\",\n        marginTop: \"0.3rem\",\n    },\n    selected: {\n        color: theme.hl1.hex(),\n    },\n    contentDropdownItem: {\n        height: \"2.8rem\",\n        padding: \"0.3rem 1.2rem\",\n        fontSize: \"1.4rem\",\n        backgroundColor: theme.palette.bg3.hex(),\n        color: theme.palette.fg1.hex(),\n        border: \"1px solid \" + theme.palette.bg2.hex(),\n        borderRadius: 2,\n        margin: \"0.4rem\",\n        \"& option\": {\n            height: \"3.4rem\",\n            padding: \"0.6rem 1.2rem\",\n            fontSize: \"1.4rem\",\n        },\n    },\n    contentTextInput: {\n        height: \"2.8rem\",\n        padding: \"0.6rem 1.2rem\",\n        backgroundColor: theme.palette.bg3.hex(),\n        border: \"1px solid \" + theme.palette.bg2.hex(),\n        borderRadius: 2,\n        margin: \"0.4rem\",\n        width: \"25rem\",\n    },\n    contentTextAreaInput: {\n        // height: 28,\n        padding: \"0.6rem 1.2rem\",\n        backgroundColor: theme.palette.bg3.hex(),\n        border: \"1px solid \" + theme.palette.bg2.hex(),\n        borderRadius: 2,\n        margin: \"0.4rem\",\n    },\n    contentInputNarrow: {\n        width: \"4em\",\n    },\n    publishLink: {\n        display: \"flex\",\n        paddingBottom: \"2rem\",\n    },\n    linkUrl: {\n        display: \"flex\",\n        alignItems: \"center\",\n        padding: \"0.6rem 1.2rem\",\n        margin: 0,\n        overflow: \"visible\", // overwrite normalize sass fix mis alignment on firefox\n        borderRadius: \"0.4rem\",\n        [`&:first-child${ignoreSsrWarning}`]: {\n            borderTopRightRadius: 0,\n            borderBottomRightRadius: 0,\n            borderRight: \"none\",\n        },\n        \"&:last-child\": {\n            borderTopLeftRadius: 0,\n            borderBottomLeftRadius: 0,\n            borderLeft: \"none\",\n        },\n        border: \"2px solid \" + theme.button.background.toString() + \" !important\",\n        backgroundColor: theme.button.background.toString() + \" !important\",\n        color: theme.formInput.color.toString() + \" !important\",\n    },\n    linkInput: {},\n    connectLeft: {\n        borderTopLeftRadius: 0,\n        borderBottomLeftRadius: 0,\n    },\n    connectRight: {\n        borderTopRightRadius: 0,\n        borderBottomRightRadius: 0,\n    },\n    // current styles used in CustomComponent\n    colourPickerContainer: {\n        position: \"relative\",\n        display: \"flex\",\n        // width: \"fit-content\",\n    },\n    colourPicker: {\n        position: \"absolute\",\n        right: 0,\n        bottom: 0,\n        paddingTop: 0,\n        paddingRight: \"0.25rem\",\n        width: \"2.5rem\",\n        height: \"100%\",\n        cursor: \"pointer\",\n        border: \"none\",\n        background: \"transparent\",\n        \"&::-webkit-color-swatch-wrapper\": {\n            padding: 0,\n        },\n        \"&::-webkit-color-swatch\": {\n            borderRadius: \"0.4rem\",\n            border: 0,\n            margin: \"0.2rem 0\",\n        },\n    },\n    fileLoader: {\n        display: \"inline-block !important\",\n        width: \"20rem\",\n    },\n    checkboxLabel: {\n        fontWeight: \"normal\",\n    },\n    expanderHeading: {\n        display: \"flex\",\n        cursor: \"pointer\",\n    },\n    expanderCaret: {\n        flexGrow: 0,\n    },\n\n    tabHeader: {\n        textAlign: \"left\",\n        paddingLeft: 1,\n        marginBottom: -1,\n        marginTop: 10,\n        display: \"flex\",\n        alignItems: \"center\",\n    },\n    tabHeaderButton: {\n        display: \"inline-block\",\n        background: theme.palette.bg0.hex(),\n        border: \"1px solid \" + theme.palette.bg2.alpha(0.5).toString(),\n        borderTopLeftRadius: \"0.8rem\",\n        borderTopRightRadius: \"0.8rem\",\n        padding: \"0.5rem 1rem\",\n        marginLeft: -1,\n        borderBottom: \"none\",\n        position: \"relative\",\n        [`&.${classes.selected}`]: {\n            borderColor: theme.palette.bg2.darken(0.1).toString(),\n            background: theme.isDark ? theme.palette.bg1.hex() : theme.palette.bg3.hex(),\n            zIndex: 1,\n            position: \"relative\",\n            borderTop: \"2px solid \" + theme.hl1.hex(),\n            borderTopColor: theme.hl1.hex(),\n        },\n    },\n    tabHeaderRemoveButton: {\n        color: theme.palette.fg1.hex(),\n        opacity: 0.9,\n        \"&:hover\": {\n            opacity: 1,\n        },\n        marginRight: \"1rem\",\n    },\n    tabBody: {\n        position: \"relative\",\n        // zIndex:999,\n        background: theme.isDark ? theme.palette.bg1.hex() : theme.palette.bg3.hex(),\n        border: \"1px solid \" + theme.palette.bg2.darken(0.1).toString(),\n        padding: \"1.2rem\",\n        borderRadius: 2,\n    },\n}));\n\nconst preventDefaultKeyEvents = (e: React.KeyboardEvent | KeyboardEvent) => {\n    e.preventDefault();\n    e.stopPropagation();\n};\n\nlet useSplitButtonStyles = makeStyles()((theme) => ({\n    root: {\n        cursor: \"pointer\",\n        display: \"inline-block\",\n    },\n    mainButton: {\n        color: theme.isDark ? theme.palette.fg2.hex() : theme.palette.fg1.hex(),\n        backgroundColor: theme.isDark ? theme.palette.bg3.hex() : theme.palette.bg2.hex(),\n        borderTopLeftRadius: 2,\n        borderBottomLeftRadius: 2,\n        padding: \"2px 1.2rem\",\n        paddingRight: \"0.6rem\",\n    },\n    menuButton: {\n        color: theme.isDark ? theme.palette.fg2.hex() : theme.palette.fg1.hex(),\n        backgroundColor: theme.isDark ? theme.palette.bg3.hex() : theme.palette.bg2.hex(),\n        padding: \"2px 0.8rem\",\n        paddingLeft: \"0.6rem\",\n        borderTopRightRadius: 2,\n        borderBottomRightRadius: 2,\n        position: \"relative\",\n    },\n    divider: {\n        position: \"absolute\",\n        left: 0,\n        top: \"0.4rem\",\n        bottom: \"0.4rem\",\n        width: 1,\n        backgroundColor: \"rgba(255,255,255,0.4)\",\n    },\n    primary: {\n        backgroundColor: theme.primary.toString(),\n        color: \"white\",\n        \"&:hover\": {\n            backgroundColor: theme.primary.lighten(0.2).toString(),\n        },\n        \"&:active\": {\n            backgroundColor: theme.primary.darken(0.1).toString(),\n        },\n    },\n}));\n\ntype SplitDropdownButtonProps = {\n    className?: string;\n    variant?: \"primary\";\n    children?: React.ReactNode;\n    onClick?: React.MouseEventHandler<HTMLSpanElement>;\n    menuItems?: DropDownMenuItems;\n};\n\nexport const SplitDropdownButton = ({ className, variant, children, onClick, menuItems }: SplitDropdownButtonProps) => {\n    let { classes } = useSplitButtonStyles();\n    return (\n        <DropdownMenu\n            items={menuItems}\n            align={\"right\"}\n            render={(showMenu, anchor) => (\n                <div className={cx(classes.root, className)}>\n                    <LinkInternal\n                        className={cx(classes.mainButton, variant ? classes[variant] : undefined)}\n                        onClick={onClick}>\n                        {children}\n                    </LinkInternal>\n                    <LinkInternal\n                        className={cx(classes.menuButton, variant ? classes[variant] : undefined)}\n                        onClick={(e) => showMenu(null, e.currentTarget)}>\n                        <div className={classes.divider} />\n                        <FontAwesomeIcon icon={faChevronDown} />\n                    </LinkInternal>\n                    {anchor}\n                </div>\n            )}\n        />\n    );\n};\n\ntype ModalButtonProps = React.PropsWithChildren<ButtonProps & { enabled?: boolean }>;\n\nexport const ModalButton = ({ className, children, variant, enabled = true, ...props }: ModalButtonProps) => {\n    // let { classes } = useStyles();\n\n    return (\n        <Button className={className} variant={variant} disabled={!enabled} {...props}>\n            {children}\n        </Button>\n    );\n    // <LinkInternal className={cx(className, classes.button, classes[variant], !enabled && classes.disabled)} {...props}>\n    //     {children}\n    // </LinkInternal>\n};\n\nexport const ModalBottomButton = ({ children, ...props }: ModalButtonProps) => {\n    return <ModalButton {...props}>{children}</ModalButton>;\n};\n\ntype ModalLinkProps = React.PropsWithChildren<React.ComponentProps<typeof LinkInternal> & { variant?: SharedVariant }>;\n\nexport const ModalLink = ({ className, children, variant, ...props }: ModalLinkProps) => {\n    let { classes } = useStyles();\n\n    return (\n        <LinkInternal className={cx(className, classes.modalLink, variant ? classes[variant] : undefined)} {...props}>\n            {children}\n        </LinkInternal>\n    );\n};\n\nexport const SidebarButton = ({ className, children, ...props }: ModalButtonProps) => {\n    let { classes } = useStyles();\n\n    return (\n        <ModalButton className={cx(className, classes.sidebarButton)} {...props}>\n            {children}\n        </ModalButton>\n    );\n};\n\nexport const DropdownButton = ({ className, children, ...props }: ModalButtonProps) => {\n    let { classes } = useStyles();\n\n    return (\n        <ModalButton className={cx(className, classes.sidebarButton)} {...props}>\n            {children}\n        </ModalButton>\n    );\n};\n\nexport const ContentButton = ({ className, children, ...props }: ModalButtonProps) => {\n    return (\n        <ModalButton className={className} {...props}>\n            {children}\n        </ModalButton>\n    );\n};\n\nexport const BottomPanelToolbarButton = ({ className, children, ...props }: ModalButtonProps) => {\n    let { classes } = useStyles();\n\n    return (\n        <ModalButton className={cx(className, classes.bottomPanelToolbarButton)} {...props}>\n            {children}\n        </ModalButton>\n    );\n};\n\nexport const BottomPanelContentButton = ({ className, children, ...props }: ModalButtonProps) => {\n    let { classes } = useStyles();\n\n    return (\n        <ModalButton className={cx(className, classes.bottomPanelContentButton)} {...props}>\n            {children}\n        </ModalButton>\n    );\n};\n\ntype HeaderDropdownMenuProps = React.PropsWithChildren<\n    React.HTMLAttributes<HTMLDivElement> & {\n        classes?: Record<string, string>;\n    }\n>;\n\nexport const HeaderDropdownMenu = ({ children, classes, ...props }: HeaderDropdownMenuProps) => {\n    ({ classes } = useStyles(undefined, { props: { classes } }));\n\n    return (\n        <div className={classes.dropdownMenu} {...props}>\n            {children}\n        </div>\n    );\n};\n\ntype ContentDropdownMenuItemProps = React.PropsWithChildren<\n    React.ComponentProps<typeof DropDown> & {\n        small?: boolean;\n        narrow?: boolean;\n    }\n>;\n\nexport const ContentDropdownMenuItem = ({\n    className,\n    small,\n    narrow,\n    children,\n    ...props\n}: ContentDropdownMenuItemProps) => {\n    let { classes } = useStyles();\n\n    return (\n        <DropDown\n            variant={small || narrow ? \"small\" : undefined}\n            className={cx(className, props.disabled && classes.disabled)}\n            {...props}>\n            {children}\n        </DropDown>\n    );\n};\n\ntype ContextTextProps = React.ComponentProps<typeof TextBox> & {\n    onEnter?: React.KeyboardEventHandler<HTMLInputElement>;\n    onEscape?: React.KeyboardEventHandler<HTMLInputElement>;\n    small?: boolean;\n    narrow?: boolean;\n    disableEsc?: boolean;\n    ref?: React.Ref<HTMLInputElement>;\n};\n\nexport const ContentTextInput = ({\n    ref,\n    className,\n    small,\n    /*deprecated*/ narrow,\n    disableEsc,\n    onEnter,\n    onKeyDown,\n    onEscape,\n    ...props\n}: ContextTextProps) => {\n    const { classes } = useStyles();\n\n    const onKeyDown_ = useEvent((e: React.KeyboardEvent<HTMLInputElement>) => {\n        switch (e.key) {\n            case \"Escape\":\n                if (disableEsc) {\n                    e.stopPropagation();\n                    e.preventDefault();\n                }\n                onEscape?.(e);\n                break;\n            case \"Enter\":\n                if (onEnter) {\n                    e.stopPropagation();\n                }\n                onEnter?.(e);\n                break;\n            default:\n                break;\n        }\n        onKeyDown?.(e);\n    });\n\n    return (\n        <TextBox\n            ref={ref}\n            onKeyDown={onKeyDown_}\n            small={narrow || small}\n            className={cx(className, props.disabled && classes.disabled)}\n            {...props}\n        />\n    );\n};\n\nconst encryptedTextInputConnector = connect((state: State) => ({\n    appId: getAppId(state),\n}));\n\ntype EncryptedTextInputOwnProps = React.ComponentProps<typeof ContentTextInput> & {\n    className?: string;\n    placeholder?: string;\n    hideText?: boolean;\n    initialValue?: string;\n    setButtonText?: string;\n    secretRestrict: string;\n    onSave(value: string): Promise<unknown> | unknown;\n    title?: React.ReactNode;\n    description?: React.ReactNode;\n};\n\ntype EncryptedTextInputProps = AnvilConnectedProps<typeof encryptedTextInputConnector> & EncryptedTextInputOwnProps;\n\nexport const EncryptedTextInput = encryptedTextInputConnector(\n    ({\n        appId,\n        className,\n        placeholder,\n        hideText = false,\n        initialValue = \"\",\n        setButtonText = \"Set value\",\n        secretRestrict,\n        onSave,\n        title,\n        description,\n        ...props\n    }: EncryptedTextInputProps) => {\n        const [value, setValue] = useStateWithReset(initialValue);\n        const [settingValue, setSettingValue] = useState(false);\n        const ref = useRef<HTMLInputElement>(null);\n\n        const [saveIndicator, setSaved, setSaveError] = useSaveIndicator();\n\n        const _onSave = useEvent(async () => {\n            setSettingValue(false);\n            setValue(initialValue); // Probably\n            setSaved(false);\n            try {\n                const { encrypted } = await api.encryptAppSecret(appId, false, false, secretRestrict, value);\n                await onSave(encrypted);\n                setSaved(true);\n            } catch (e) {\n                console.log(e);\n                setSaveError(\"Save failed\");\n            }\n        });\n\n        useLayoutEffect(() => {\n            if (ref.current) {\n                ref.current.focus();\n            }\n        }, [settingValue]);\n\n        return (\n            <InputLabel className={cx(className, \"mb-8\")} title={title} subtitle={description}>\n                {settingValue ? (\n                    <div className={\"flex items-center pr-10\"}>\n                        <ContentTextInput\n                            ref={ref}\n                            type={hideText ? \"password\" : \"text\"}\n                            placeholder={placeholder}\n                            value={value}\n                            onChange={(e) => {\n                                setValue(e.target.value);\n                            }}\n                            {...props}\n                        />\n                        <Button className={\"mx-4\"} variant={\"primary\"} onClick={_onSave}>\n                            Save\n                        </Button>\n                        <Button\n                            onClick={() => {\n                                setSettingValue(false);\n                                setValue(initialValue);\n                            }}>\n                            Cancel\n                        </Button>\n                    </div>\n                ) : (\n                    <div className={\"flex justify-between pr-10\"}>\n                        <div className={\"flex items-center\"}>\n                            <Button variant={\"primary\"} onClick={() => setSettingValue(true)}>\n                                {setButtonText}\n                            </Button>\n                            {saveIndicator}\n                        </div>\n                    </div>\n                )}\n            </InputLabel>\n        );\n    }\n);\n\ntype ContentTextAreaInputProps = React.ComponentProps<typeof TextArea> & {\n    text?: React.ReactNode;\n    narrow?: boolean;\n    disableEsc?: boolean;\n    autoExpand?: boolean;\n    labelClassName?: string;\n    ref?: React.Ref<HTMLTextAreaElement>;\n};\n\nexport const ContentTextAreaInput = ({\n    ref: ref_,\n    className,\n    small,\n    narrow,\n    text,\n    disableEsc,\n    value,\n    autoExpand,\n    labelClassName,\n    ...props\n}: ContentTextAreaInputProps) => {\n    const ref = useRef<HTMLTextAreaElement>(null);\n\n    const keydown = useEvent((e: KeyboardEvent) => {\n        switch (e.key) {\n            case \"Escape\":\n                if (disableEsc) {\n                    e.stopPropagation();\n                    e.preventDefault();\n                }\n                break;\n            case \"Enter\":\n                if (disableEsc) {\n                    e.stopPropagation();\n                }\n                break;\n            default:\n                break;\n        }\n    });\n\n    useLayoutEffect(() => {\n        const inputEl = ref.current;\n        if (!inputEl) return;\n        inputEl.addEventListener(\"keydown\", keydown);\n        return () => {\n            inputEl.removeEventListener(\"keydown\", keydown);\n        };\n    }, [keydown]);\n\n    useLayoutEffect(() => {\n        if (ref.current) {\n            ref.current.style.height = \"\";\n            ref.current.style.height = Math.min(ref.current.scrollHeight, 300) + 5 + \"px\";\n        }\n    }, [value]);\n\n    return (\n        <>\n            {text && <label className={labelClassName}>{text}</label>}\n            <TextArea\n                ref={useMergeRefs(ref, ref_)}\n                onKeyDown={(e) => disableEsc && e.key === \"Escape\" && preventDefaultKeyEvents(e)}\n                small={narrow || small}\n                value={value}\n                className={cx(className)}\n                {...props}\n            />\n        </>\n    );\n};\n\ntype ColourInputProps = React.ComponentProps<typeof ContentTextInput>;\n\nexport const ColourInput = ({ className, onEnter, ...props }: ColourInputProps) => {\n    const { classes } = useStyles();\n    return (\n        <div className={classes.colourPickerContainer}>\n            <ContentTextInput style={{ width: \"100%\" }} onEnter={onEnter} className={className} {...props} />\n            <input type={\"color\"} className={cx(classes.colourPicker)} {...props} />\n        </div>\n    );\n};\n\ntype PublishLinkProps = React.ComponentProps<typeof ContentTextInput> & {\n    ref?: React.Ref<HTMLInputElement>;\n    preLink?: React.ReactNode;\n    postLink?: React.ReactNode;\n    alias?: string | null;\n    children?: React.ReactNode;\n};\n\nexport const PublishLink = ({\n    ref,\n    className,\n    preLink = null,\n    postLink = null,\n    alias,\n    children,\n    ...props\n}: PublishLinkProps) => {\n    let { classes } = useStyles();\n\n    return (\n        <div className={cx(className, classes.publishLink)} onClick={(e) => e.stopPropagation()}>\n            {!!preLink && <pre className={cx(classes.linkUrl, classes.connectRight)}>{preLink}&nbsp;</pre>}\n            <ContentTextInput\n                className={cx(classes.linkInput, !!preLink && classes.connectLeft, !!postLink && classes.connectRight)}\n                ref={ref}\n                value={alias || \"\"}\n                type=\"text\"\n                {...props}\n            />\n            {!!postLink && (\n                <pre className={cx(classes.linkUrl, classes.connectLeft)}>\n                    {postLink ? `${postLink} ` : \"\"}\n                    {children}\n                </pre>\n            )}\n        </div>\n    );\n};\n\ntype SharedCheckboxProps = React.PropsWithChildren<\n    React.InputHTMLAttributes<HTMLInputElement> & {\n        ref?: React.Ref<HTMLInputElement>;\n        className?: string;\n        text?: React.ReactNode;\n        icon?: IconProp | null;\n    }\n>;\n\nexport const CheckBox = ({ ref, className, text, children, icon = null, ...props }: SharedCheckboxProps) => {\n    let { classes } = useStyles();\n    text = text || \"\";\n\n    return (\n        <>\n            <label\n                className={cx(\n                    classes.checkboxLabel,\n                    props?.disabled ? classes.disabled : undefined,\n                    \"inline-flex items-center gap-2\",\n                    className\n                )}>\n                <input\n                    ref={ref}\n                    className={cx(props.disabled && classes.disabled, \"m-0! accent-primary-darker\")}\n                    type=\"checkbox\"\n                    {...props}\n                />\n                {icon && <FontAwesomeIcon icon={icon} />}\n                {text}\n            </label>\n            {children}\n        </>\n    );\n};\n\ntype FileUploaderProps = React.PropsWithChildren<\n    React.InputHTMLAttributes<HTMLInputElement> & {\n        className?: string;\n        id: string;\n        text?: React.ReactNode;\n    }\n>;\n\nexport const FileUploader = ({ className, id, text, children, ...props }: FileUploaderProps) => {\n    const { classes } = useStyles();\n\n    return (\n        <>\n            <label htmlFor={id}>{text}</label>&nbsp;\n            <input className={cx(className, classes.fileLoader)} type=\"file\" id={id} {...props} />\n            {children}\n        </>\n    );\n};\n\ntype ExpanderProps = {\n    className?: string;\n    id?: string;\n    headline: React.ReactNode;\n    children?: React.ReactNode;\n};\n\nexport const Expander = ({ className, id, headline, children }: ExpanderProps) => {\n    let { classes } = useStyles();\n\n    let [isOpen, setOpen] = useState(false);\n\n    return (\n        <div>\n            <h4\n                className={classes.expanderHeading}\n                onClick={(e) => {\n                    setOpen(!isOpen);\n                    e.stopPropagation();\n                }}>\n                <FontAwesomeIcon icon={isOpen ? faCaretDown : faCaretRight} fixedWidth={true} />\n                <div>{headline}</div>\n            </h4>\n            {isOpen && children}\n        </div>\n    );\n};\n","import React from \"react\";\nimport { cx } from \"@/theme/styles\";\n\nexport const addedBackground = \"rounded-md bg-[#efe] dark:bg-[#232]\";\nexport const removedBackground = \"rounded-md bg-[#fee] dark:bg-[#322]\";\nconst contextBackground = \"rounded-md bg-light-bg2/50 dark:bg-dark-bg2/50\";\n\ntype LineDiffPart = {\n    type: \"context\" | \"remove\" | \"add\";\n    lines: string[];\n};\n\ninterface CodeWithMarkersProps {\n    className?: string;\n    marker: string;\n    content: string;\n}\n\ninterface StructuralValueDiffProps {\n    className?: string;\n    from?: unknown;\n    to?: unknown;\n}\n\nexport const formatStructuralValue = (value: unknown): string => {\n    if (typeof value === \"string\") {\n        return value;\n    }\n    const json = JSON.stringify(value);\n    return json === undefined ? String(value) : json;\n};\n\nexport const isMultilineStructuralValue = (value: unknown): value is string =>\n    typeof value === \"string\" && /\\r?\\n/.test(value);\n\nconst splitLines = (value: string) => value.replace(/\\r\\n/g, \"\\n\").split(\"\\n\");\n\nexport const getStructuralLineDiff = (from: string, to: string): LineDiffPart[] => {\n    const fromLines = splitLines(from);\n    const toLines = splitLines(to);\n    let prefix = 0;\n    while (prefix < fromLines.length && prefix < toLines.length && fromLines[prefix] === toLines[prefix]) {\n        prefix++;\n    }\n\n    let suffix = 0;\n    while (\n        suffix < fromLines.length - prefix &&\n        suffix < toLines.length - prefix &&\n        fromLines[fromLines.length - suffix - 1] === toLines[toLines.length - suffix - 1]\n    ) {\n        suffix++;\n    }\n\n    const parts: LineDiffPart[] = [];\n    const addPart = (type: LineDiffPart[\"type\"], lines: string[]) => {\n        if (lines.length > 0) {\n            parts.push({ type, lines });\n        }\n    };\n\n    addPart(\"context\", fromLines.slice(0, prefix));\n    addPart(\"remove\", fromLines.slice(prefix, fromLines.length - suffix));\n    addPart(\"add\", toLines.slice(prefix, toLines.length - suffix));\n    addPart(\"context\", fromLines.slice(fromLines.length - suffix));\n    return parts;\n};\n\nexport const CodeWithMarkers: React.FC<CodeWithMarkersProps> = ({ className, marker, content }) => {\n    const markers = marker + (\"\\n\" + marker).repeat(content.match(/\\n/g)?.length || 0);\n\n    return (\n        <div className={cx(\"flex px-2 font-mono whitespace-pre select-text\", className)}>\n            <div className=\"mr-2 flex-none whitespace-pre opacity-70\">{markers}</div>\n            <div className=\"min-w-0 flex-1 overflow-x-auto break-words whitespace-pre-wrap\">{content}</div>\n        </div>\n    );\n};\n\nconst markerForType: Record<LineDiffPart[\"type\"], string> = {\n    context: \" \",\n    remove: \"-\",\n    add: \"+\",\n};\n\nconst classForType: Record<LineDiffPart[\"type\"], string> = {\n    context: contextBackground,\n    remove: removedBackground,\n    add: addedBackground,\n};\n\nexport const StructuralValueDiff: React.FC<StructuralValueDiffProps> = ({ className, from, to }) => {\n    const fromIsMultiline = isMultilineStructuralValue(from);\n    const toIsMultiline = isMultilineStructuralValue(to);\n\n    if (fromIsMultiline && toIsMultiline) {\n        return (\n            <div className={cx(\"mt-1 space-y-1 text-[1.1rem]\", className)}>\n                {getStructuralLineDiff(from, to).map(({ type, lines }, idx) => (\n                    <CodeWithMarkers\n                        key={`${type}-${idx}`}\n                        className={classForType[type]}\n                        marker={markerForType[type]}\n                        content={lines.join(\"\\n\")}\n                    />\n                ))}\n            </div>\n        );\n    }\n\n    return (\n        <div className={cx(\"mt-1 space-y-1 text-[1.1rem]\", className)}>\n            {from !== undefined && (\n                <CodeWithMarkers className={removedBackground} marker=\"-\" content={formatStructuralValue(from)} />\n            )}\n            {to !== undefined && (\n                <CodeWithMarkers className={addedBackground} marker=\"+\" content={formatStructuralValue(to)} />\n            )}\n        </div>\n    );\n};\n","import * as React from \"react\";\nimport { cx, makeStyles } from \"@/theme/styles\";\n\ntype HeadingLevel = 1 | 2 | 3;\ntype TextLevel = 1 | 2 | 3;\n\ninterface HeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {\n    level?: HeadingLevel;\n}\n\ninterface TextProps extends React.HTMLAttributes<HTMLParagraphElement> {\n    level?: TextLevel;\n    narrow?: boolean;\n}\n\nlet useStyles = makeStyles()((theme) => ({\n    h1: {\n        fontSize: theme.text.h1.fontSize,\n        fontWeight: theme.text.h1.fontWeight,\n        color: theme.text.h1.color.toString(),\n        margin: theme.spacing.h1.margin,\n    },\n    h2: {\n        fontSize: theme.text.h2.fontSize,\n        fontWeight: theme.text.h2.fontWeight,\n        color: theme.text.h2.color.toString(),\n        margin: theme.spacing.h2.margin,\n    },\n    h3: {\n        fontSize: theme.text.h3.fontSize,\n        fontWeight: theme.text.h3.fontWeight,\n        color: theme.text.h3.color.toString(),\n        margin: theme.spacing.h3.margin,\n    },\n    p1: {\n        fontSize: theme.text.p1.fontSize,\n        fontWeight: theme.text.p1.fontWeight,\n        color: theme.text.p1.color.toString(),\n        margin: theme.spacing.p1.margin,\n    },\n    p2: {\n        fontSize: theme.text.p2.fontSize,\n        fontWeight: theme.text.p2.fontWeight,\n        color: theme.text.p2.color.toString(),\n        margin: theme.spacing.p2.margin,\n    },\n    p3: {\n        fontSize: theme.text.p3.fontSize,\n        fontWeight: theme.text.p3.fontWeight,\n        color: theme.text.p3.color.toString(),\n        margin: theme.spacing.p3.margin,\n    },\n}));\n\nexport const Heading = ({ level = 2, className = \"\", children, ...props }: HeadingProps) => {\n    const { classes } = useStyles();\n\n    return React.createElement(`h${level}`, { className: cx(classes[`h${level}`], className), ...props }, children);\n};\n\nexport const Text = ({ level = 1, className, children, narrow = false, ...props }: TextProps) => {\n    const { classes } = useStyles();\n    let { style, ...remainingProps } = props;\n    style = style || {};\n    if (narrow) {\n        style.marginBottom = 0;\n    }\n    return (\n        <p className={cx(className, classes[`p${level}`])} style={style} {...remainingProps}>\n            {children}\n        </p>\n    );\n};\n","import React, { useCallback, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faMinus, faPlus } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { blockNavigation, unblockNavigation } from \"@/controllers/ide\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useStateWithReset } from \"@/util/hooks\";\nimport { Button } from \"./Button\";\nimport { InputLabel } from \"./Forms\";\nimport { useSaveIndicator } from \"./SaveIndicator\";\nimport { ContentTextAreaInput, ContentTextInput } from \"./SharedComponents\";\n\ninterface TextInputPropsBase {\n    autoFocus?: boolean;\n    title?: React.ReactNode;\n    description?: React.ReactNode;\n    id?: string;\n    placeholder?: string;\n    initialValue?: string;\n    value?: string;\n    saveDescription?: string;\n    saveKey?: string;\n    onSave?(value: string): any | Promise<any>;\n    onChange?(value: string): void;\n    className?: string;\n    titleClasses?: string;\n    subtitleClasses?: string;\n    textBoxClassName?: string;\n    inputType?: null | string;\n    textarea?: boolean;\n    small?: boolean;\n    disabled?: boolean;\n    type?: string;\n    onBlur?: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n    onKeyDown?: React.KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n}\n\ntype TextInputAreaProps = TextInputPropsBase & { textarea: true; ref?: React.Ref<HTMLTextAreaElement> };\ntype TextInputFieldProps = TextInputPropsBase & { textarea?: false; ref?: React.Ref<HTMLInputElement> };\n\nexport type TextInputProps = TextInputAreaProps | TextInputFieldProps;\n\nconst isTextAreaProps = (props: TextInputProps): props is TextInputAreaProps => props.textarea === true;\n\nconst TextInput = (props: TextInputProps) => {\n    const {\n        ref,\n        title,\n        autoFocus,\n        description,\n        subtitleClasses,\n        titleClasses,\n        placeholder,\n        initialValue,\n        saveKey,\n        onSave,\n        onChange,\n        className = \"\",\n        inputType = null,\n        textBoxClassName,\n        ...restProps\n    } = props;\n\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const [value, setValue] = useStateWithReset(initialValue || \"\");\n    const [saveIndicator, setSaved] = useSaveIndicator();\n    const [changed, setChanged] = useState(false);\n\n    const _onChange = useCallback(\n        (newValue: string) => {\n            if (saveKey) {\n                dispatch(blockNavigation(saveKey));\n            }\n            setChanged(true);\n            onChange?.(newValue);\n        },\n        [saveKey, onChange]\n    );\n\n    const _onSave = useCallback(\n        async (value: string) => {\n            if (changed && onSave) {\n                setSaved(false);\n                if (saveKey) {\n                    dispatch(unblockNavigation(saveKey));\n                }\n                await onSave(value);\n                setSaved(true);\n                setChanged(false);\n            }\n        },\n        [changed, saveKey, onSave]\n    );\n\n    const onTextAreaChange: React.ChangeEventHandler<HTMLTextAreaElement> = (e) => {\n        setValue(e.target.value);\n        _onChange(e.target.value);\n    };\n\n    const onTextInputChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {\n        setValue(e.target.value);\n        _onChange(e.target.value);\n    };\n\n    const labelProps = {\n        className: cx(className, \"mb-8\"),\n        title,\n        subtitle: description,\n        subtitleClasses,\n        titleClasses,\n    };\n\n    const wrapInput = (input: React.ReactNode) => (\n        <InputLabel {...labelProps}>\n            <div className={\"flex items-baseline\"}>\n                {input}\n                {saveIndicator}\n            </div>\n        </InputLabel>\n    );\n\n    if (isTextAreaProps(props)) {\n        const { ref: textAreaRef } = props;\n        const textAreaProps = restProps as Omit<TextInputAreaProps, keyof TextInputPropsBase | \"ref\" | \"textarea\">;\n\n        return wrapInput(\n            <ContentTextAreaInput\n                ref={textAreaRef}\n                autoFocus={autoFocus}\n                value={value}\n                placeholder={placeholder}\n                onChange={onTextAreaChange}\n                onBlur={() => _onSave(value)}\n                className={textBoxClassName}\n                {...textAreaProps}\n            />\n        );\n    }\n\n    const { ref: textInputRef } = props;\n    const textInputProps = restProps as Omit<TextInputFieldProps, keyof TextInputPropsBase | \"ref\" | \"textarea\">;\n\n    return wrapInput(\n        <ContentTextInput\n            ref={textInputRef}\n            autoFocus={autoFocus}\n            value={value}\n            placeholder={placeholder}\n            onChange={onTextInputChange}\n            onBlur={() => _onSave(value)}\n            onEnter={() => _onSave(value)}\n            type={inputType || \"text\"}\n            className={textBoxClassName}\n            {...textInputProps}\n        />\n    );\n};\n\nexport default TextInput;\n\ninterface IncrementingNumericProps {\n    value: number;\n    small?: boolean;\n    lowerBound?: number;\n    upperBound?: number;\n    changeValueFn(value: number): void;\n}\n\n/** lower and upperBound are inclusive */\nexport const IncrementingNumericTextInput = ({\n    value,\n    small,\n    changeValueFn,\n    lowerBound,\n    upperBound,\n}: IncrementingNumericProps) => {\n    const setValue = useCallback(\n        (n: string | number) => {\n            const parsed = typeof n === \"number\" ? n : parseInt(n);\n            const v = isNaN(parsed) ? 0 : parsed;\n            if ((lowerBound !== undefined && v < lowerBound) || (upperBound !== undefined && v > upperBound)) return;\n            changeValueFn(v);\n        },\n        [lowerBound, upperBound, changeValueFn]\n    );\n\n    //todo: arrow keys? to increment\n\n    const inputRef = useCallback((node: HTMLInputElement) => {\n        node?.focus();\n    }, []);\n\n    return (\n        <>\n            <Button\n                size={\"tiny\"}\n                variant={\"primary\"}\n                className={\"mx-2\"}\n                onClick={() => {\n                    setValue(value - 1);\n                }}\n                disabled={lowerBound !== undefined && value <= lowerBound}>\n                <FontAwesomeIcon icon={faMinus} />\n            </Button>\n            <ContentTextInput\n                ref={inputRef}\n                small={small}\n                className={cx(\"w-24! text-center\")}\n                inputMode=\"numeric\"\n                value={value}\n                onChange={(e) => setValue(e.target.value)}\n                disableEsc={true}\n            />\n            <Button\n                size={\"tiny\"}\n                variant={\"primary\"}\n                className={\"mx-2\"}\n                onClick={() => {\n                    setValue(value + 1);\n                }}\n                disabled={upperBound !== undefined && value >= upperBound}>\n                <FontAwesomeIcon icon={faPlus} />\n            </Button>\n        </>\n    );\n};\n","import React, { useCallback, useContext, useEffect, useReducer, useRef, useState } from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { ManagerInstanceGlobalsContext } from \"@/instance-globals\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { copyTextToClipboard } from \"./CopyButton\";\n\nconst useStyles = makeStyles()((theme) => ({\n    root: {\n        transform: \"translate3d(0, 0, 0)\",\n        backfaceVisibility: \"hidden\",\n        //willChange: \"transform\",\n        opacity: 0,\n        pointerEvents: \"none\",\n        transition: \"all .18s ease-in-out 0s\",\n        zIndex: 501, // larger than dropdown\n        transformOrigin: \"top\",\n        background: theme.tooltip.background.toString(),\n        borderRadius: 4,\n        color: theme.tooltip.color.toString(),\n        padding: \".5em 1em\",\n        whiteSpace: \"nowrap\",\n        boxSizing: \"content-box\",\n        position: \"absolute\",\n        fontSize: \"1.3rem\",\n        \"&:before\": {\n            position: \"absolute\",\n            zIndex: 501, // larger than dropdown\n            //willChange: \"transform\",\n            backgroundSize: \"100% auto !important\",\n            content: \"''\",\n            transform: \"translate3d(0, 0, 0)\",\n            transformOrigin: \"top\",\n            transition: \"all .18s ease-in-out 0s\",\n            opacity: 0,\n            pointerEvents: \"none\",\n        },\n        \"&[data-tooltip-position|='top']:before, &[data-tooltip-position|='bottom']:before\": {\n            translate: \"calc(-1 * var(--tooltip-shift-x, 0px)) 0\",\n        },\n\n        \"&[data-tooltip-position='left']\": {\n            bottom: \"auto\",\n            left: \"auto\",\n            right: 0,\n            top: \"50%\",\n            transform: \"translate3d(1rem, -50%, 0)\",\n            marginRight: \"1.1rem\",\n            \"&:before\": {\n                bottom: \"auto\",\n                left: \"auto\",\n                right: \"-.6rem\",\n                top: \"50%\",\n                transform: \"translate3d(0, -50%, 0)\",\n                background: theme.tooltip.left.toString(),\n                height: \"1.8rem\",\n                width: \".6rem\",\n                marginBottom: 0,\n            },\n        },\n        \"&[data-tooltip-position|='top']\": {\n            bottom: 0,\n            left: \"50%\",\n            transform: \"translate3d(-50%, 0, 0)\",\n            marginBottom: \".8rem\",\n            \"&:before\": {\n                bottom: \"-1.1rem\",\n                left: \"50%\",\n                transform: \"translate3d(-50%, -.5rem, 0)\",\n                background: theme.tooltip.top.toString(),\n                height: \".6rem\",\n                width: \"1.8rem\",\n                marginBottom: 0,\n            },\n        },\n        \"&[data-tooltip-position|='bottom']\": {\n            bottom: \"auto\",\n            left: \"50%\",\n            top: 0,\n            marginTop: \".8rem\",\n            \"&:before\": {\n                bottom: \"auto\",\n                top: \"-1rem\",\n                background: theme.tooltip.bottom.toString(),\n                height: \".6rem\",\n                width: \"1.8rem\",\n                marginBottom: 0,\n                marginTop: \".5rem\",\n            },\n        },\n        \"&[data-tooltip-position='bottom']\": {\n            transform: \"translate3d(-50%, -1rem, 0)\",\n            \"&:before\": {\n                left: \"50%\",\n                transform: \"translate3d(-50%, 0, 0)\",\n            },\n        },\n\n        \"&[data-tooltip-position='bottom-left']\": {\n            transform: \"translate3d(calc(-100% + 1.6rem), -1rem, 0)\",\n            \"&:before\": {\n                right: \".7rem\",\n            },\n        },\n        \"&[data-tooltip-position='bottom-right']\": {\n            transform: \"translate3d(-1.6rem, -1rem, 0)\",\n            \"&:before\": {\n                left: \"auto\",\n            },\n        },\n        \"&[data-tooltip-position='top-left']\": {\n            transform: \"translate3d(calc(-100% + 1.6rem), 0, 0)\",\n            \"&:before\": {\n                right: \"0\",\n                left: \"auto\",\n            },\n        },\n        \"&[data-tooltip-position='right']\": {\n            bottom: \"auto\",\n            left: 0,\n            top: \"50%\",\n            transform: \"translate3d(-1rem, -50%, 0)\",\n            marginLeft: \"1.1rem\",\n            \"&:before\": {\n                bottom: \"auto\",\n                left: \"-1rem\",\n                top: \"50%\",\n                transform: \"translate3d(0, -50%, 0)\",\n                background: theme.tooltip.right.toString(),\n                height: \"1.8rem\",\n                width: \".6rem\",\n                marginBottom: 0,\n                marginLeft: \".5rem\",\n            },\n        },\n        \"&[data-tooltip-position='top-right']\": {\n            transform: \"translate3d(-1.6rem, 0, 0)\",\n            \"&:before\": {\n                left: \"auto\",\n            },\n        },\n    },\n\n    tooltipVisible: {\n        opacity: 1,\n        \"&:before\": {\n            opacity: 1,\n        },\n        \"&[data-tooltip-position='right']\": {\n            transform: \"translate3d(0, -50%, 0)\",\n            \"&:before\": {\n                transform: \"translate3d(0, -50%, 0)\",\n            },\n        },\n        \"&[data-tooltip-position='left']\": {\n            transform: \"translate3d(0, -50%, 0)\",\n            \"&:before\": {\n                transform: \"translate3d(0, -50%, 0)\",\n            },\n        },\n        \"&[data-tooltip-position='top']\": {\n            transform: \"translate3d(-50%, -.5rem, 0)\",\n            \"&:before\": {\n                transform: \"translate3d(-50%, -.5rem, 0)\",\n            },\n        },\n        \"&[data-tooltip-position='bottom']\": {\n            transform: \"translate3d(-50%, 0, 0)\",\n            \"&:before\": {\n                transform: \"translate3d(-50%, 0, 0)\",\n            },\n        },\n        \"&[data-tooltip-position='bottom-left']\": {\n            transform: \"translate3d(calc(-100% + 1.6rem), 0, 0)\",\n        },\n        \"&[data-tooltip-position='bottom-right']\": {\n            transform: \"translate3d(-1.6rem, 0, 0)\",\n        },\n        \"&[data-tooltip-position='top-left']\": {\n            transform: \"translate3d(calc(-100% + 1.6rem), -.5rem, 0)\",\n        },\n        \"&[data-tooltip-position='top-right']\": {\n            transform: \"translate3d(-1.6rem, -.5rem, 0)\",\n        },\n    },\n\n    tooltipSticky: {\n        pointerEvents: \"auto\",\n        \"&:before\": {\n            pointerEvents: \"auto\",\n        },\n    },\n}));\n\nexport type TooltipPosition =\n    | \"right\"\n    | \"left\"\n    | \"top\"\n    | \"bottom\"\n    | \"bottom-left\"\n    | \"bottom-right\"\n    | \"top-left\"\n    | \"top-right\";\n\nfunction getPos(pos: TooltipPosition, abs: DOMRect) {\n    let left, top;\n    switch (pos) {\n        case \"right\":\n            [left, top] = [abs.right, abs.top + abs.height / 2];\n            break;\n        case \"bottom\":\n        case \"bottom-left\":\n        case \"bottom-right\":\n            [left, top] = [abs.left + abs.width / 2, abs.bottom];\n            break;\n        case \"top\":\n        case \"top-left\":\n        case \"top-right\":\n            [left, top] = [abs.left + abs.width / 2, abs.top];\n            break;\n        case \"left\":\n            [left, top] = [abs.left, abs.top + abs.height / 2];\n            break;\n    }\n    return [left + \"px\", top + \"px\"] as const;\n}\n\n/**\n * If there is a delay we want to wait that long before open the tooltip\n * but if the tooltip was recently toggled then we want to also open regardless\n * after a given time, reset the recently opened value\n */\nlet lastOpened = Date.now();\nconst RESET_AFTER = 2000;\n\nfunction useDelayedStart(delay: number) {\n    const getCurrentDelay = useEvent(() => {\n        const diff = Date.now() - lastOpened;\n        if (diff > RESET_AFTER) return delay;\n        return 0;\n    });\n    return getCurrentDelay;\n}\n\ninterface TooltipProps extends TooltipOptions {\n    position?: TooltipPosition;\n    delay: number;\n    anchorRef: React.MutableRefObject<any>;\n    visible: boolean;\n    setVisible: (v: boolean) => void;\n}\n\nexport function Tooltip({\n    anchorRef,\n    position = \"right\",\n    sticky = false,\n    children,\n    className,\n    style,\n    useMouseX,\n    delay,\n    active = true,\n    visible,\n    setVisible,\n}: React.PropsWithChildren<TooltipProps>) {\n    const [el] = useState(() => ({ current: document.createElement(\"div\") }));\n    const hover = useRef(false);\n    const { classes } = useStyles();\n\n    const getCurrentDelay = useDelayedStart(delay);\n    const timeout = useRef<number | undefined>(undefined);\n\n    const { tooltipRoot } = useContext(ManagerInstanceGlobalsContext)!;\n\n    const delayTooltip = useCallback(() => {\n        if (!hover.current) return;\n        clearTimeout(timeout.current);\n        const currentDelay = getCurrentDelay();\n        timeout.current = setTimeout(() => setVisible(true), currentDelay);\n    }, []);\n\n    const mouseEnter = useCallback((e: MouseEvent) => {\n        hover.current = true;\n        const currentTooltip = tooltipRoot.firstElementChild;\n        if (el.current !== currentTooltip) {\n            currentTooltip && tooltipRoot.removeChild(currentTooltip);\n            tooltipRoot.appendChild(el.current);\n        }\n        const abs = (anchorRef.current?.getBoundingClientRect() || {}) as DOMRect;\n        // eslint-disable-next-line prefer-const\n        let [left, top] = getPos(position, abs);\n        if (useMouseX) {\n            left = e.clientX + \"px\";\n        }\n        tooltipRoot.style.left = left;\n        tooltipRoot.style.top = top;\n        const tooltipBounds = tooltipWrapperRef.current?.getBoundingClientRect();\n        if (tooltipBounds && (position.startsWith(\"top\") || position.startsWith(\"bottom\"))) {\n            // Keep room for the tooltip's slide-in animation at either edge.\n            const margin = 16;\n            const shift = Math.max(\n                margin - tooltipBounds.left,\n                Math.min(0, window.innerWidth - margin - tooltipBounds.right)\n            );\n            tooltipRoot.style.left = `${parseFloat(left) + shift}px`;\n            el.current.style.setProperty(\"--tooltip-shift-x\", `${shift}px`);\n        }\n        delayTooltip();\n    }, []);\n\n    const mouseLeave = useCallback(() => {\n        hover.current = false;\n        clearTimeout(timeout.current);\n        setTimeout(() => !hover.current && setVisible(false), sticky ? 150 : 40);\n    }, []);\n\n    const tooltipWrapperRef = useRef<HTMLDivElement>(null);\n    const scrollHandler = useCallback((e: Event) => {\n        if (e.target && tooltipWrapperRef.current?.contains(e.target as HTMLElement)) return;\n        setVisible(false);\n    }, []);\n\n    useEffect(() => {\n        const currentAnchor = anchorRef.current;\n        currentAnchor?.addEventListener(\"mouseenter\", mouseEnter);\n        currentAnchor?.addEventListener(\"mouseleave\", mouseLeave);\n        // if we can scroll we need the tooltip to disappear - otherwise we remain inplace while the page scrolls\n        // on resize window we get some weird behaviour if tooltip is off the screen\n        // hover takes care of putting it back on the screen\n        const currentEl = el.current;\n        const removeRef = () => {\n            el.current.remove();\n        };\n        window.addEventListener(\"resize\", removeRef);\n        window.addEventListener(\"scroll\", scrollHandler, true);\n\n        const stickyHover = () => (hover.current = true);\n\n        currentAnchor?.addEventListener(\"mousedown\", delayTooltip, { passive: true, capture: true });\n\n        if (sticky) {\n            currentEl.addEventListener(\"mouseenter\", stickyHover);\n            currentEl.addEventListener(\"mouseleave\", mouseLeave);\n        }\n        return () => {\n            clearTimeout(timeout.current);\n            if (el.current.isConnected) {\n                tooltipRoot.removeChild(el.current);\n            }\n            currentAnchor?.removeEventListener(\"mousedown\", delayTooltip, { capture: true });\n            if (sticky) {\n                currentEl.removeEventListener(\"mouseenter\", stickyHover);\n                currentEl.removeEventListener(\"mouseleave\", mouseLeave);\n            }\n            currentAnchor?.removeEventListener(\"mouseenter\", mouseEnter);\n            currentAnchor?.removeEventListener(\"mouseleave\", mouseLeave);\n            window.removeEventListener(\"scroll\", scrollHandler, true);\n            window.removeEventListener(\"resize\", removeRef);\n        };\n    }, []);\n\n    return ReactDOM.createPortal(\n        <div\n            ref={tooltipWrapperRef}\n            className={cx(\n                classes.root,\n                active && !!children && visible && classes.tooltipVisible,\n                visible && sticky && classes.tooltipSticky,\n                className\n            )}\n            style={style}\n            data-tooltip-position={position}>\n            <span className=\"block max-w-[min(50rem,calc(100vw-6rem))] truncate\">{children}</span>\n        </div>,\n        el.current\n    );\n}\n\nconst DEFAULT_DELAY = 1500;\nconst EMPTY_STYLE = {};\n\ninterface TooltipOptions {\n    sticky?: boolean;\n    useMouseX?: boolean;\n    delay?: number | true;\n    active?: boolean;\n    className?: string;\n    style?: React.CSSProperties;\n}\n\nexport function useTooltip(\n    title?: React.ReactNode,\n    position?: TooltipPosition,\n    {\n        sticky = false,\n        style = EMPTY_STYLE,\n        useMouseX = false,\n        delay: _delay = 0,\n        active = true,\n        className,\n    }: TooltipOptions = {}\n) {\n    const anchorRef = useRef<HTMLElement | null>(null);\n    const delay = _delay === true ? DEFAULT_DELAY : _delay;\n\n    const [visible, setVisible] = useReducer((_prev: boolean, v: boolean) => {\n        if (v) lastOpened = Date.now();\n        return v;\n    }, false);\n\n    let tooltip: React.ReactNode;\n    if (title == null) {\n        tooltip = null;\n    } else {\n        tooltip = (\n            <Tooltip\n                {...{ anchorRef, position, sticky, className, style, useMouseX, delay, visible, setVisible, active }}>\n                {title}\n            </Tooltip>\n        );\n    }\n\n    return [tooltip, anchorRef as React.RefObject<any>, setVisible] as const;\n}\n\nexport const useCopyWithTooltip = (title = \"Copied\", position: TooltipPosition = \"bottom\") => {\n    const copiedTimeout = useRef<number | undefined>(undefined);\n    const [active, setActive] = useState(false);\n    const [copyTooltip, copyTooltipRef, toggleTooltip] = useTooltip(title, position, { active });\n\n    const doCopy = useEvent(async (copyText: string) => {\n        clearTimeout(copiedTimeout.current);\n        await copyTextToClipboard(copyText);\n        toggleTooltip(true);\n        setActive(true);\n        copiedTimeout.current = setTimeout(() => {\n            toggleTooltip(false);\n            setActive(false);\n        }, 1000);\n    });\n\n    return [doCopy, copyTooltip, copyTooltipRef] as const;\n};\n\n// /* -------------------------------------------------------------------\n//   Microtip\n//   Modern, lightweight css-only tooltips\n//   Just 1kb minified and gzipped\n//   @author Ghosh\n//   @package Microtip\n// ----------------------------------------------------------------------\n//   1. Base Styles\n//   2. Direction Modifiers\n//   3. Position Modifiers\n// --------------------------------------------------------------------*/\n\n// /* ------------------------------------------------\n//   [1] Base Styles\n// -------------------------------------------------*/\n\n// [aria-label][role~=\"tooltip\"] {\n//     position: relative;\n//   }\n\n//   [aria-label][role~=\"tooltip\"]::before,\n//   [aria-label][role~=\"tooltip\"]::after {\n//     transform: translate3d(0, 0, 0);\n//     -webkit-backface-visibility: hidden;\n//     backface-visibility: hidden;\n//     will-change: transform;\n//     opacity: 0;\n//     pointer-events: none;\n//     transition: all var(--microtip-transition-duration, .18s) var(--microtip-transition-easing, ease-in-out) var(--microtip-transition-delay, 0s);\n//     position: absolute;\n//     box-sizing: border-box;\n//     z-index: 10;\n//     transform-origin: top;\n//   }\n\n//   [aria-label][role~=\"tooltip\"]::before {\n//     background-size: 100% auto !important;\n//     content: \"\";\n//   }\n\n//   [aria-label][role~=\"tooltip\"]::after {\n//     background: rgba(17, 17, 17, .9);\n//     border-radius: 4px;\n//     color: #ffffff;\n//     content: attr(aria-label);\n//     font-size: var(--microtip-font-size, 13px);\n//     font-weight: var(--microtip-font-weight, normal);\n//     text-transform: var(--microtip-text-transform, none);\n//     padding: .5em 1em;\n//     white-space: nowrap;\n//     box-sizing: content-box;\n//   }\n\n//   [aria-label][role~=\"tooltip\"]:hover::before,\n//   [aria-label][role~=\"tooltip\"]:hover::after,\n//   [aria-label][role~=\"tooltip\"]:focus::before,\n//   [aria-label][role~=\"tooltip\"]:focus::after {\n//     opacity: 1;\n//     pointer-events: auto;\n//   }\n\n//   /* ------------------------------------------------\n//     [2] Position Modifiers\n//   -------------------------------------------------*/\n\n//   [role~=\"tooltip\"][data-microtip-position|=\"top\"]::before {\n//     background: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E\") no-repeat;\n//     height: 6px;\n//     width: 18px;\n//     margin-bottom: 5px;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position|=\"top\"]::after {\n//     margin-bottom: 11px;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position|=\"top\"]::before {\n//     transform: translate3d(-50%, 0, 0);\n//     bottom: 100%;\n//     left: 50%;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position|=\"top\"]:hover::before {\n//     transform: translate3d(-50%, -5px, 0);\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position|=\"top\"]::after {\n//     transform: translate3d(-50%, 0, 0);\n//     bottom: 100%;\n//     left: 50%;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position=\"top\"]:hover::after {\n//     transform: translate3d(-50%, -5px, 0);\n//   }\n\n//   /* ------------------------------------------------\n//     [2.1] Top Left\n//   -------------------------------------------------*/\n//   [role~=\"tooltip\"][data-microtip-position=\"top-left\"]::after {\n//     transform: translate3d(calc(-100% + 16px), 0, 0);\n//     bottom: 100%;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position=\"top-left\"]:hover::after {\n//     transform: translate3d(calc(-100% + 16px), -5px, 0);\n//   }\n\n//   /* ------------------------------------------------\n//     [2.2] Top Right\n//   -------------------------------------------------*/\n//   [role~=\"tooltip\"][data-microtip-position=\"top-right\"]::after {\n//     transform: translate3d(calc(0% + -16px), 0, 0);\n//     bottom: 100%;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position=\"top-right\"]:hover::after {\n//     transform: translate3d(calc(0% + -16px), -5px, 0);\n//   }\n\n//   /* ------------------------------------------------\n//     [2.3] Bottom\n//   -------------------------------------------------*/\n//   [role~=\"tooltip\"][data-microtip-position|=\"bottom\"]::before {\n//     background: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E\") no-repeat;\n//     height: 6px;\n//     width: 18px;\n//     margin-top: 5px;\n//     margin-bottom: 0;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position|=\"bottom\"]::after {\n//     margin-top: 11px;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position|=\"bottom\"]::before {\n//     transform: translate3d(-50%, -10px, 0);\n//     bottom: auto;\n//     left: 50%;\n//     top: 100%;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position|=\"bottom\"]:hover::before {\n//     transform: translate3d(-50%, 0, 0);\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position|=\"bottom\"]::after {\n//     transform: translate3d(-50%, -10px, 0);\n//     top: 100%;\n//     left: 50%;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position=\"bottom\"]:hover::after {\n//     transform: translate3d(-50%, 0, 0);\n//   }\n\n//   /* ------------------------------------------------\n//     [2.4] Bottom Left\n//   -------------------------------------------------*/\n//   [role~=\"tooltip\"][data-microtip-position=\"bottom-left\"]::after {\n//     transform: translate3d(calc(-100% + 16px), -10px, 0);\n//     top: 100%;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position=\"bottom-left\"]:hover::after {\n//     transform: translate3d(calc(-100% + 16px), 0, 0);\n//   }\n\n//   /* ------------------------------------------------\n//     [2.5] Bottom Right\n//   -------------------------------------------------*/\n//   [role~=\"tooltip\"][data-microtip-position=\"bottom-right\"]::after {\n//     transform: translate3d(calc(0% + -16px), -10px, 0);\n//     top: 100%;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position=\"bottom-right\"]:hover::after {\n//     transform: translate3d(calc(0% + -16px), 0, 0);\n//   }\n\n//   /* ------------------------------------------------\n//     [2.6] Left\n//   -------------------------------------------------*/\n//   [role~=\"tooltip\"][data-microtip-position=\"left\"]::before,\n//   [role~=\"tooltip\"][data-microtip-position=\"left\"]::after {\n//     bottom: auto;\n//     left: auto;\n//     right: 100%;\n//     top: 50%;\n//     transform: translate3d(10px, -50%, 0);\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position=\"left\"]::before {\n//     background: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E\") no-repeat;\n//     height: 18px;\n//     width: 6px;\n//     margin-right: 5px;\n//     margin-bottom: 0;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position=\"left\"]::after {\n//     margin-right: 11px;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position=\"left\"]:hover::before,\n//   [role~=\"tooltip\"][data-microtip-position=\"left\"]:hover::after {\n//     transform: translate3d(0, -50%, 0);\n//   }\n\n//   /* ------------------------------------------------\n//     [2.7] Right\n//   -------------------------------------------------*/\n//   [role~=\"tooltip\"][data-microtip-position=\"right\"]::before,\n//   [role~=\"tooltip\"][data-microtip-position=\"right\"]::after {\n//     bottom: auto;\n//     left: 100%;\n//     top: 50%;\n//     transform: translate3d(-10px, -50%, 0);\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position=\"right\"]::before {\n//     background: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E\") no-repeat;\n//     height: 18px;\n//     width: 6px;\n//     margin-bottom: 0;\n//     margin-left: 5px;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position=\"right\"]::after {\n//     margin-left: 11px;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-position=\"right\"]:hover::before,\n//   [role~=\"tooltip\"][data-microtip-position=\"right\"]:hover::after {\n//     transform: translate3d(0, -50%, 0);\n//   }\n\n//   /* ------------------------------------------------\n//     [3] Size\n//   -------------------------------------------------*/\n//   [role~=\"tooltip\"][data-microtip-size=\"small\"]::after {\n//     white-space: initial;\n//     width: 80px;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-size=\"medium\"]::after {\n//     white-space: initial;\n//     width: 150px;\n//   }\n\n//   [role~=\"tooltip\"][data-microtip-size=\"large\"]::after {\n//     white-space: initial;\n//     width: 260px;\n//   }\n//\n","import React from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { getFeatures } from \"@/controllers/ide\";\nimport { featureSupported } from \"@/util/features\";\n\nconst UpgradeBadge = ({ feature }: { feature: string }) => {\n    const features = useSelector(getFeatures);\n    const supported = featureSupported(features, feature);\n    const featurePlan = features[feature]?.upgradePlan || features[feature]?.plan;\n    return feature && !supported ? <span className=\"beta-label\">{featurePlan || \"Paid\"} Plan</span> : null;\n};\n\nexport default UpgradeBadge;\n","import React, { useMemo } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faPlay, faStop, faTriangleExclamation } from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Button, ButtonProps } from \"@/components/reusable/Button\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { getZenMode, runApp, stopApp, toggleZenMod } from \"@/controllers/ide\";\nimport { getRunMode, getRunnerOutput, getRunnerViewMaximised } from \"@/controllers/runner\";\nimport type { AnvilDispatch } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\n\nexport const RunAppButton = ({ ...props }: ButtonProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const zenMode = useSelector(getZenMode);\n    const runMode = useSelector(getRunMode);\n    const isRunning = runMode !== null;\n    const isMaximized = useSelector(getRunnerViewMaximised);\n\n    const onClick = useEvent(() => {\n        if (isRunning) {\n            dispatch(stopApp());\n        } else {\n            dispatch(runApp());\n        }\n    });\n    const [tooltipAnchor, tooltipRef] = useTooltip(\n        isRunning ? \"Stop App\" : \"Run App\",\n        isRunning && isMaximized ? \"bottom\" : \"bottom-left\",\n        { delay: true }\n    );\n\n    if (!zenMode) return null;\n    return (\n        <Button\n            key=\"run-btn\"\n            onClick={onClick}\n            variant={isRunning ? \"tertiary\" : \"highlight1\"}\n            ref={tooltipRef}\n            {...props}>\n            <FontAwesomeIcon fixedWidth icon={isRunning ? faStop : faPlay} />\n            {tooltipAnchor}\n        </Button>\n    );\n};\n\nexport const NumErrorWarningBtn = (props: ButtonProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const zenMode = useSelector(getZenMode);\n    const runMode = useSelector(getRunMode);\n    const isRunning = runMode !== null;\n    const runnerOutput = useSelector(getRunnerOutput);\n    const numErrors = useMemo(() => {\n        if (!zenMode) return null;\n        if (!isRunning) return null;\n        return runnerOutput.filter((r) => r.fn === \"pythonError\").length;\n    }, [runnerOutput, zenMode, isRunning]);\n\n    const numErrorsWarningMsg = numErrors ? `${numErrors} Error${numErrors > 1 ? \"s\" : \"\"}` : \"\";\n\n    const [errorsAnchor, errorsRef] = useTooltip(numErrorsWarningMsg, \"top-left\");\n\n    const onToggleZenMode = useEvent(() => {\n        dispatch(toggleZenMod());\n    });\n\n    if (!zenMode) return null;\n\n    return (\n        numErrorsWarningMsg && (\n            <div className=\"absolute right-4 bottom-4\">\n                <Button\n                    key=\"error-warning\"\n                    linkClassName=\"px-4!\"\n                    variant=\"danger\"\n                    ref={errorsRef}\n                    onClick={onToggleZenMode}\n                    {...props}>\n                    <span className=\"fa-layers fa-fw\">\n                        <FontAwesomeIcon fixedWidth icon={faTriangleExclamation} />\n                        <span\n                            className=\"fa-layers-counter\"\n                            style={\n                                {\n                                    \"--fa-counter-scale\": \"0.5\",\n                                    \"--fa-counter-background-color\": \"transparent\",\n                                    \"--fa-right\": \"-0.5rem\",\n                                    \"--fa-top\": \"-0.5rem\",\n                                    border: \"1px solid white\",\n                                } as any\n                            }>\n                            {numErrors}\n                        </span>\n                    </span>\n                    {errorsAnchor}\n                </Button>\n            </div>\n        )\n    );\n};\n","import { createContext, useContext, useState } from \"react\";\nimport {\n    addMonths,\n    eachDayOfInterval,\n    eachWeekOfInterval,\n    endOfMonth,\n    endOfWeek,\n    format as formatDate,\n    startOfMonth,\n    startOfWeek,\n    subMonths,\n} from \"date-fns\";\nimport { inRange } from \"lodash-es\";\nimport { ExternalStore, useStoreSelector } from \"@/util/external-store\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { Offset } from \"./OffsetPicker\";\n\nexport const HOUR = \"HH\";\nexport const MIN = \"MM\";\nexport const SEC = \"SS\";\nexport const MIL = \"MS\";\n\nexport type TimeType = typeof HOUR | typeof MIN | typeof SEC | typeof MIL;\n\nexport const timeTypes = [HOUR, MIN, SEC, MIL] as const;\n\ntype TimeParts = Record<TimeType, string>;\n\nexport const timeDef = {\n    [HOUR]: {\n        bound: 24,\n        init: (d?: Date | null) => d?.getHours().toString().padStart(2, \"0\") ?? \"\",\n        setter: (d: Date, n: number) => d.setHours(n),\n        format: (s: string) => s.padStart(2, \"0\"),\n        visible: () => true,\n        sep: null,\n        placeholder: \"hh\",\n        title: \"Hours\",\n    },\n    [MIN]: {\n        bound: 60,\n        init: (d?: Date | null) => d?.getMinutes().toString().padStart(2, \"0\") ?? \"\",\n        setter: (d: Date, n: number) => d.setMinutes(n),\n        format: (s: string) => s.padStart(2, \"0\"),\n        visible: () => true,\n        sep: \":\",\n        placeholder: \"mm\",\n        title: \"Mins\",\n    },\n    [SEC]: {\n        bound: 60,\n        init: (d?: Date | null) => d?.getSeconds().toString().padStart(2, \"0\") ?? \"\",\n        setter: (d: Date, n: number) => d.setSeconds(n),\n        format: (s: string) => s.padStart(2, \"0\"),\n        visible: (props: any) => props.showSec,\n        sep: \":\",\n        placeholder: \"ss\",\n        title: \"Secs\",\n    },\n    [MIL]: {\n        bound: 1000,\n        init: (d?: Date | null) => d?.getMilliseconds().toString().padStart(3, \"0\") ?? \"\",\n        setter: (d: Date, n: number) => d.setMilliseconds(n),\n        format: (s: string) => s.padStart(3, \"0\"),\n        visible: (props: any) => props.showSec && props.showMil,\n        sep: \".\",\n        placeholder: \"ms\",\n        title: \"Millis\",\n    },\n} as const;\n\nconst initializeTimeBuffers = (value?: Date | null) =>\n    Object.fromEntries(Object.entries(timeDef).map(([type, { init }]) => [type, init(value)])) as TimeParts;\n\nexport interface DatePickerStoreProps {\n    value?: Date | null;\n    onChange?: (d: Date) => void;\n    format?: string;\n    offset?: Offset;\n    onOffsetChange?: (offset: Offset) => void;\n    withInput?: boolean;\n}\n\ninterface DatePickerState {\n    value: Date | null;\n    offset?: Offset;\n    format: string;\n    timeBuffers: TimeParts;\n    buffer: string;\n    month: Date[][];\n    viewing: Date;\n}\n\nconst now = new Date();\nconst INIT_DATE = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0);\n\nfunction isEqual(a: Date, b: Date) {\n    return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n}\n\nfunction isBefore(a: Date, b: Date) {\n    const yearA = a.getFullYear();\n    const yearB = b.getFullYear();\n    if (yearA !== yearB) return yearA < yearB;\n    const monthA = a.getMonth();\n    const monthB = b.getMonth();\n    if (monthA !== monthB) return monthA < monthB;\n    return a.getDate() < b.getDate();\n}\n\nfunction isAfter(a: Date, b: Date) {\n    const yearA = a.getFullYear();\n    const yearB = b.getFullYear();\n    if (yearA !== yearB) return yearA > yearB;\n    const monthA = a.getMonth();\n    const monthB = b.getMonth();\n    if (monthA !== monthB) return monthA > monthB;\n    return a.getDate() > b.getDate();\n}\n\nexport function dateInRange(date: Date, min: Date, max: Date) {\n    return (isEqual(date, min) || isAfter(date, min)) && (isEqual(date, max) || isBefore(date, max));\n}\n\nfunction createMonth(viewing: Date) {\n    return eachWeekOfInterval(\n        {\n            start: startOfMonth(viewing),\n            end: endOfMonth(viewing),\n        },\n        { weekStartsOn: 1 }\n    ).map((week) =>\n        eachDayOfInterval({\n            start: startOfWeek(week, { weekStartsOn: 1 }),\n            end: endOfWeek(week, { weekStartsOn: 1 }),\n        })\n    );\n}\n\nfunction dateFromDateAndTime(datePart: Date, timePart: Date) {\n    return new Date(\n        datePart.getFullYear(),\n        datePart.getMonth(),\n        datePart.getDate(),\n        timePart.getHours(),\n        timePart.getMinutes(),\n        timePart.getSeconds(),\n        timePart.getMilliseconds()\n    );\n}\n\nfunction formatDateWithOffset(value: Date, format: string, offset?: Offset) {\n    // note - if we use inputs then we should not include the offset in the format\n    // it'll just make it more difficult to parse\n    if (offset) {\n        format += \" '\" + offset + \"'\";\n    }\n    return formatDate(value, format);\n}\n\nconst DEFAULT_FORMAT = \"dd MMM, yyyy\";\n\nclass DatePickerStore extends ExternalStore<DatePickerState> {\n    onChange: DatePickerStoreProps[\"onChange\"];\n    onOffsetChange: DatePickerStoreProps[\"onOffsetChange\"];\n    constructor(state: DatePickerState, props: DatePickerStoreProps) {\n        super(state, { deepEquality: true });\n        this.onChange = props.onChange;\n        this.onOffsetChange = props.onOffsetChange;\n    }\n    updateDate = (d: Date) => {\n        const state = this.getState();\n        const value = state.value ?? INIT_DATE;\n        const offset = state.offset;\n        const newValue = dateFromDateAndTime(d, value);\n        const format = state.format;\n        this.updateState((state) => {\n            state.value = newValue;\n            state.buffer = formatDateWithOffset(newValue, format, offset);\n            state.timeBuffers = initializeTimeBuffers(newValue);\n            this.onChange?.(newValue);\n        });\n    };\n    updateOffset = (offset: Offset) => {\n        const state = this.getState();\n        const value = state.value;\n        const format = state.format;\n        this.updateState((state) => {\n            state.offset = offset;\n            if (value) state.buffer = formatDateWithOffset(value, format, offset);\n            this.onOffsetChange?.(offset);\n        });\n    };\n    setViewing = (d: Date) => {\n        this.updateState((state) => {\n            state.viewing = d;\n            state.month = createMonth(d);\n        });\n    };\n    viewNextMonth = () => {\n        const newViewing = addMonths(this.getState().viewing, 1);\n        this.updateState((state) => {\n            state.viewing = newViewing;\n            state.month = createMonth(newViewing);\n        });\n    };\n    viewPreviousMonth = () => {\n        const newViewing = subMonths(this.getState().viewing, 1);\n        this.updateState((state) => {\n            state.viewing = newViewing;\n            state.month = createMonth(newViewing);\n        });\n    };\n    isSelected = (d: Date) => {\n        const value = this.getState().value;\n        return value != null && isEqual(value, d);\n    };\n\n    updateBuffer = (buffer: string) => {\n        // TODO - if we support withInput here then we need to parse the buffer\n        // and if we don't get invalidDate after parsing - update the value, trigger on change\n        this.updateState((state) => {\n            state.buffer = buffer;\n        });\n    };\n\n    updateTimeBuffer = (buffer: string, type: TimeType) => {\n        const newValue = new Date(this.getState().value ?? INIT_DATE);\n        const { format, bound, setter } = timeDef[type];\n        let newBuffer = buffer;\n        let asInt = parseInt(buffer);\n        if (buffer === \"\") {\n            asInt = 0;\n        } else if (inRange(asInt, bound)) {\n            newBuffer = format(asInt.toString());\n        } else {\n            return;\n        }\n        setter(newValue, asInt);\n\n        this.updateState((state) => {\n            state.timeBuffers[type] = newBuffer;\n            state.value = newValue;\n            state.buffer = formatDateWithOffset(newValue, state.format, state.offset);\n            this.onChange?.(newValue);\n        });\n    };\n\n    addTimeBuffer = (type: TimeType, val: number) => {\n        const state = this.getState();\n        const buffer = state.timeBuffers[type];\n        const value = state.value;\n        let asInt = parseInt(buffer || \"0\");\n        if (Number.isNaN(asInt)) {\n            asInt = 0;\n        }\n        const { format, bound, setter } = timeDef[type];\n        const newNum = (((asInt + val) % bound) + bound) % bound;\n        const newValue = new Date(value ?? INIT_DATE);\n        setter(newValue, newNum);\n        this.updateState((state) => {\n            state.value = newValue;\n            state.buffer = formatDateWithOffset(newValue, state.format, state.offset);\n            state.timeBuffers = initializeTimeBuffers(newValue);\n            this.onChange?.(newValue);\n        });\n    };\n\n    incTimeBuffer = (type: TimeType) => {\n        this.addTimeBuffer(type, 1);\n    };\n\n    decTimeBuffer = (type: TimeType) => {\n        this.addTimeBuffer(type, -1);\n    };\n\n    updateFromExternalChange = ({ value, format, offset }: { value: Date | null; format: string; offset?: Offset }) => {\n        this.setState(initialize({ value, format, offset }));\n    };\n}\nconst initialize = ({\n    value = null,\n    format = DEFAULT_FORMAT,\n    offset,\n}: Partial<DatePickerStoreProps>): DatePickerState => {\n    const timeBuffers = initializeTimeBuffers(value);\n    const viewing = value ?? INIT_DATE;\n    const month = createMonth(viewing);\n    const buffer = value ? formatDateWithOffset(value, format, offset) : \"\";\n    return { value, format, offset, viewing, month, timeBuffers, buffer };\n};\n\nconst createDatePickerStore = (p: DatePickerStoreProps) => {\n    return new DatePickerStore(initialize({}), p);\n};\n\nexport const DatePickerContext = createContext<DatePickerStore | null>(null);\n\nconst useStoreContext = () => {\n    const store = useContext(DatePickerContext);\n    if (!store) throw new Error(`Missing Provider for date picker store in the tree`);\n    return store;\n};\nexport const useDatePickerSelector = <Ts>(selector: (state: DatePickerState) => Ts): Ts => {\n    const store = useStoreContext();\n    return useStoreSelector(store, selector);\n};\n\nexport const useDatePickerActions = useStoreContext;\n\nexport const useDatePicker = <T extends keyof DatePickerState>(key: T): DatePickerState[T] => {\n    return useDatePickerSelector((state) => state[key]);\n};\n\nconst noop = () => {};\n\nexport const useInitializeDatePickerStore = ({\n    value,\n    onChange,\n    format = DEFAULT_FORMAT,\n    offset,\n    onOffsetChange,\n}: DatePickerStoreProps) => {\n    // stable reference\n    onChange = useEvent(onChange ?? noop);\n    onOffsetChange = useEvent(onOffsetChange ?? noop);\n\n    const [store] = useState(() => createDatePickerStore({ value, onChange, format, offset, onOffsetChange }));\n\n    // handle external changes\n    // this shouldn't ever trigger, but just in case\n    const { value: storeValue, offset: storeOffset, format: storeFormat } = store.getState();\n    if (\n        (value !== undefined && storeValue?.getTime() !== value?.getTime()) ||\n        (format !== undefined && format !== storeFormat) ||\n        (offset !== undefined && offset !== storeOffset)\n    ) {\n        value = value === undefined ? storeValue : value;\n        format ??= storeFormat;\n        offset ??= storeOffset;\n        store.updateFromExternalChange({ value, format, offset });\n    }\n\n    return store;\n};\n","import React, { useRef, useState } from \"react\";\nimport { faChevronDown, faChevronLeft, faChevronRight } from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { endOfMonth, format, startOfMonth } from \"date-fns\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { cx } from \"@/theme/styles\";\nimport { Button as StandardButton } from \"../Button\";\nimport { dateInRange, useDatePicker, useDatePickerActions } from \"./DatePickerStore\";\n\nconst DAYS = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"];\n\nconst Button: typeof StandardButton = ({ ref, ...props }: any) => (\n    <StandardButton ref={ref} variants={[\"no-border\"]} small {...props} />\n);\n\nconst WeekHeadings = () => (\n    <div className=\"flex items-center justify-between\">\n        {DAYS.map((day, i) => {\n            return (\n                <Text level={3} className={cx(\"flex w-12 items-center justify-center\")} key={i}>\n                    {day}\n                </Text>\n            );\n        })}\n    </div>\n);\n\nconst MonthGrid = () => {\n    const viewing = useDatePicker(\"viewing\");\n    const currentMonth = useDatePicker(\"month\");\n    const { updateDate, isSelected } = useDatePickerActions();\n\n    return (\n        <div className={\"h-80 w-96\"}>\n            <div className=\"flex h-full flex-col\">\n                <WeekHeadings />\n                <div className=\"flex h-full flex-col justify-center\">\n                    {currentMonth.map((week) => (\n                        <div className=\"flex items-center justify-between\" key={`week-${week[0]}`}>\n                            {week.map((day, i) => (\n                                <Button\n                                    key={`${week[0]}-${day || i}`}\n                                    variant={isSelected(day) ? \"primary\" : \"hidden\"}\n                                    onClick={() => updateDate(day)}>\n                                    <span\n                                        className={cx(\n                                            \"flex w-8 items-center justify-center text-center text-lg font-normal\",\n                                            {\n                                                \"text-light-grey1! dark:text-grey-1!\": !dateInRange(\n                                                    day,\n                                                    startOfMonth(viewing),\n                                                    endOfMonth(viewing)\n                                                ),\n                                            }\n                                        )}>\n                                        {format(day, \"dd\")}\n                                    </span>\n                                </Button>\n                            ))}\n                        </div>\n                    ))}\n                </div>\n            </div>\n        </div>\n    );\n};\n\nconst YEARS = Array.from({ length: 200 }, (_, i) => 1900 + i);\n\ninterface YearGridProps {\n    setSelectingYear: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\nconst CURRENT_YEAR = new Date().getFullYear();\n\nfunction YearGrid({ setSelectingYear }: YearGridProps) {\n    const selectedDate = useDatePicker(\"value\");\n    const { setViewing, updateDate } = useDatePickerActions();\n    const selectedYear = selectedDate?.getFullYear() ?? CURRENT_YEAR;\n\n    const handleClick = (year: number) => {\n        const d = new Date(year, 0, 1);\n        setViewing(d);\n        updateDate(d);\n        setSelectingYear(false);\n    };\n\n    const selectedEl = useRef<HTMLElement | null>(null);\n\n    const setRef = (el: HTMLElement | null, year: number) => {\n        if (year === selectedYear) {\n            selectedEl.current = el;\n            selectedEl.current?.scrollIntoView({ block: \"nearest\" });\n        }\n    };\n\n    return (\n        <div className=\"grid h-80 w-96 max-w-md grid-cols-4 gap-x-2 gap-y-6 justify-self-center overflow-x-hidden overflow-y-auto rounded-md\">\n            {YEARS.map((year) => (\n                <Button\n                    ref={(el) => setRef(el, year)}\n                    variant={selectedYear === year ? \"primary\" : \"hidden\"}\n                    key={year}\n                    onClick={() => handleClick(year)}>\n                    <div className=\"text-xl font-normal\">{year}</div>\n                </Button>\n            ))}\n        </div>\n    );\n}\n\nexport const Calendar = () => {\n    const viewing = useDatePicker(\"viewing\");\n    const { viewNextMonth, viewPreviousMonth } = useDatePickerActions();\n    const [selectingYear, setSelectingYear] = useState(false);\n\n    return (\n        <div className=\"flex\">\n            <div className=\"w-96\">\n                <div className={cx(\"flex items-center\", selectingYear ? \"justify-center\" : \"justify-between\")}>\n                    {!selectingYear && (\n                        <Button\n                            variant=\"hidden\"\n                            small\n                            onClick={viewPreviousMonth}\n                            className={\"text-light-fg1 hover:text-slate-400 dark:text-dark-fg1\"}>\n                            <FontAwesomeIcon icon={faChevronLeft} fixedWidth />\n                        </Button>\n                    )}\n\n                    <div className=\"flex items-center gap-2\" onClick={() => setSelectingYear((v) => !v)}>\n                        <div className=\"w-6\" />\n                        <Text>{format(viewing, \"MMM\")}</Text>\n                        <Text>{format(viewing, \"yyyy\")}</Text>\n                        <Button variant=\"hidden\" small onClick={() => setSelectingYear((v) => !v)}>\n                            <FontAwesomeIcon\n                                className={cx(\"transition-transform duration-300 dark:text-dark-fg1\", {\n                                    \"-rotate-180 transform\": selectingYear,\n                                })}\n                                icon={faChevronDown}\n                                fixedWidth\n                            />\n                        </Button>\n                    </div>\n                    {!selectingYear && (\n                        <Button\n                            variant=\"hidden\"\n                            small\n                            className={\"hover:text-slate-400 dark:text-dark-fg1\"}\n                            onClick={viewNextMonth}>\n                            <FontAwesomeIcon icon={faChevronRight} fixedWidth />\n                        </Button>\n                    )}\n                </div>\n                <div className=\"relative h-80 w-96\">\n                    <div\n                        className={cx(\n                            \"absolute flex h-full flex-col justify-center transition-opacity duration-300\",\n                            selectingYear ? \"z-10 opacity-100 delay-150\" : \"opacity-0 delay-75\"\n                        )}>\n                        <YearGrid setSelectingYear={setSelectingYear} />\n                    </div>\n                    <div\n                        className={cx(\n                            \"absolute flex h-full flex-col justify-center transition-opacity duration-300\",\n                            !selectingYear ? \"z-10 opacity-100 delay-150\" : \"opacity-0\"\n                        )}>\n                        <MonthGrid />\n                    </div>\n                </div>\n            </div>\n        </div>\n    );\n};\n","import React from \"react\";\nimport { faCalendar } from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { cx } from \"@/theme/styles\";\nimport { LinkInternal } from \"../LinkInternal\";\nimport { useDatePicker } from \"./DatePickerStore\";\n\ninterface DateInputProps {\n    placeholder?: string;\n    showIcon?: boolean;\n    ref?: React.Ref<HTMLSpanElement>;\n}\n\ntype DateInputLinkProps = DateInputProps &\n    Omit<React.ComponentProps<typeof LinkInternal>, keyof DateInputProps | \"children\">;\n\nexport const DateInput = ({ ref, ...props }: DateInputLinkProps) => {\n    const { placeholder = \"Select a date\", showIcon = true, ...restProps } = props;\n    const buffer = useDatePicker(\"buffer\");\n    const isPlaceholder = !buffer;\n    return (\n        <LinkInternal ref={ref} preventDefaultClick={false} className=\"h-full w-full\" {...restProps}>\n            <div className=\"flex h-full items-center gap-4 rounded-md border-2 border-light-bg5 px-4 py-2 dark:border-dark-bg3 dark:text-white\">\n                {showIcon && <FontAwesomeIcon icon={faCalendar} />}\n                <span className={cx(\"truncate\", { \"text-gray-500\": isPlaceholder })}>{buffer || placeholder}</span>\n            </div>\n        </LinkInternal>\n    );\n};\n","import React, { useRef, useState } from \"react\";\nimport { cx } from \"@/theme/styles\";\nimport { useIsInView } from \"@/util/hooks/use-intersection-observer\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../Popover\";\nimport { DateInput } from \"./DateInput\";\nimport { DatePickerContext, DatePickerStoreProps, useInitializeDatePickerStore } from \"./DatePickerStore\";\n\nexport interface PickerProps extends DatePickerStoreProps {\n    placeholder?: string;\n    defaultOpen?: boolean;\n    showIcon?: boolean;\n    onConfirm?(): void;\n    onCancel?(): void;\n    contentRef?: React.RefObject<React.ElementRef<typeof PopoverContent>>;\n    collisionBoundary?: React.ComponentPropsWithoutRef<typeof PopoverContent>[\"collisionBoundary\"];\n    className?: string;\n}\n\nexport const GenericPicker = ({\n    placeholder,\n    defaultOpen,\n    showIcon = true,\n    onConfirm,\n    onCancel,\n    children,\n    className,\n    contentRef,\n    collisionBoundary,\n    ...props\n}: React.PropsWithChildren<PickerProps>) => {\n    const store = useInitializeDatePickerStore(props);\n    const [open, setOpen] = useState(defaultOpen);\n    const triggerRef = useRef<HTMLSpanElement>(null);\n    const [triggerVisible, setTriggerVisible] = useState(true);\n    // Hide when the trigger scrolls out of view without constraining popup placement.\n    useIsInView(triggerRef, setTriggerVisible);\n\n    const onEscapeKeyDown = useEvent((e: KeyboardEvent) => {\n        if (onCancel) {\n            e.preventDefault();\n            onCancel();\n        }\n    });\n\n    const onEnter: React.KeyboardEventHandler<HTMLDivElement> = useEvent((e) => {\n        if (e.key !== \"Enter\") return;\n        setOpen(false);\n        onConfirm?.();\n    });\n\n    const onOpenChange = useEvent((open: boolean) => {\n        setOpen(open);\n        if (!open) {\n            onConfirm?.();\n        }\n    });\n\n    return (\n        <DatePickerContext.Provider value={store}>\n            <Popover open={open} onOpenChange={onOpenChange} defaultOpen={defaultOpen}>\n                <PopoverTrigger asChild>\n                    <DateInput ref={triggerRef} placeholder={placeholder} showIcon={showIcon} />\n                </PopoverTrigger>\n                <PopoverContent\n                    ref={contentRef}\n                    className={cx(\"w-auto\", className, !triggerVisible && \"invisible\")}\n                    collisionBoundary={collisionBoundary}\n                    hideWhenDetached\n                    onEscapeKeyDown={onEscapeKeyDown}\n                    onKeyDown={onEnter}>\n                    {children}\n                </PopoverContent>\n            </Popover>\n        </DatePickerContext.Provider>\n    );\n};\n","import React from \"react\";\nimport { Calendar } from \"./Calendar\";\nimport { GenericPicker, PickerProps } from \"./Picker\";\n\n/** \n * @example\n * const DatePickerExample = () => {\n    const [date, setDate] = useState(null);\n    const onChange = useEvent((d) => setDate(d));\n    const onConfirm = useEvent(() => {});\n    // called when escape is pressed\n    const onCancel = useEvent(() => {});\n    return (\n        <DatePicker\n            value={date}\n            onChange={onChange}\n            onConfirm={onConfirm}\n            onCancel={onCancel}\n            format=\"MMM do, y\"\n            placeholder=\"Set a Date\"\n        />\n    );\n};\n*/\nexport const DatePicker = (props: PickerProps) => (\n    <GenericPicker {...props}>\n        <Calendar />\n    </GenericPicker>\n);\n","import React, { Fragment } from \"react\";\nimport { Text } from \"@/components/reusable/Text\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { TextBox } from \"../Forms\";\nimport { TimeType, timeDef, timeTypes, useDatePickerActions, useDatePickerSelector } from \"./DatePickerStore\";\n\ninterface TimeInputProps {\n    type: TimeType;\n}\n\nconst TimeInput = ({ type }: TimeInputProps) => {\n    const { placeholder, title } = timeDef[type];\n    const buffer = useDatePickerSelector((state) => state.timeBuffers[type]);\n    const { updateTimeBuffer, incTimeBuffer, decTimeBuffer } = useDatePickerActions();\n\n    const onChange: React.ChangeEventHandler<HTMLInputElement> = useEvent((e) => {\n        updateTimeBuffer(e.target.value, type);\n    });\n\n    const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useEvent((e) => {\n        switch (e.key) {\n            case \"ArrowUp\": {\n                e.preventDefault();\n                return incTimeBuffer(type);\n            }\n            case \"ArrowDown\": {\n                e.preventDefault();\n                return decTimeBuffer(type);\n            }\n        }\n    });\n\n    const onFocus: React.FocusEventHandler<HTMLInputElement> = useEvent((e) => {\n        e.target.setSelectionRange(0, e.target.value.length);\n    });\n\n    return (\n        <div className={\"m-0! flex flex-col items-center\"}>\n            <Text level={3} className={\"mb-[-0.2rem]!\"}>\n                {title}\n            </Text>\n            <TextBox\n                className={\"w-16! text-center\"}\n                small\n                placeholder={placeholder}\n                inputMode={\"numeric\"}\n                value={buffer}\n                onChange={onChange}\n                onKeyDown={onKeyDown}\n                onFocus={onFocus}\n            />\n        </div>\n    );\n};\n\ninterface TimePickerProps {\n    showSec?: boolean;\n    showMil?: boolean;\n}\n\nexport const TimePicker = ({ ...props }: TimePickerProps) => (\n    <div className=\"flex w-fit items-end justify-center gap-2\">\n        {timeTypes.map((type) => {\n            const { sep, visible } = timeDef[type];\n            if (!visible(props)) return null;\n            return (\n                <Fragment key={type}>\n                    {sep && (\n                        <Text level={3} className={\"m-0!\"}>\n                            {sep}\n                        </Text>\n                    )}\n                    <TimeInput type={type} />\n                </Fragment>\n            );\n        })}\n    </div>\n);\n","import React from \"react\";\nimport { Calendar } from \"./Calendar\";\nimport { GenericPicker, PickerProps } from \"./Picker\";\nimport { TimePicker } from \"./TimePicker\";\n\nexport const DateTimeCalendar = ({ showSec, showMil }: Pick<DateTimePickerProps, \"showSec\" | \"showMil\">) => (\n    <>\n        <Calendar />\n        <hr className=\"m-0 w-full border border-light-bg3 dark:border-dark-bg3\" />\n        <TimePicker showSec={showSec} showMil={showMil} />\n    </>\n);\n\ninterface DateTimePickerProps extends PickerProps {\n    showSec?: boolean;\n    showMil?: boolean;\n}\n\n/**\n * \n * @example\n * const DateTimePickerExample = () => {\n    const [date, setDate] = useState(null);\n    const onChange = useEvent((d) => setDate(d));\n    const onConfirm = useEvent(() => {});\n    // called when escape is pressed\n    const onCancel = useEvent(() => {});\n    return (\n        <DateTimePicker\n            value={date}\n            onChange={onChange}\n            onConfirm={onConfirm}\n            onCancel={onCancel}\n            format={\"yyyy-MM-dd HH:mm:ss.SSS\"}\n            showSec\n            showMil\n            placeholder={\"Select date and time\"}\n        />\n    );\n};\n * \n */\nexport const DateTimePicker = ({\n    format = \"MMM do, y HH:mm:ss\",\n    placeholder = \"Select a date and time\",\n    showSec,\n    showMil,\n    ...props\n}: DateTimePickerProps) => (\n    <GenericPicker format={format} placeholder={placeholder} {...props}>\n        <div className=\"flex flex-col items-center gap-2\">\n            <DateTimeCalendar showSec={showSec} showMil={showMil} />\n        </div>\n    </GenericPicker>\n);\n","import React, { useMemo } from \"react\";\nimport { DropDown } from \"../Forms\";\nimport { Text } from \"../Text\";\nimport { useDatePicker, useDatePickerActions } from \"./DatePickerStore\";\n\n// https://en.wikipedia.org/wiki/List_of_UTC_offsets\nexport const offsets = [\n    \"-12:00\",\n    \"-11:00\",\n    \"-10:00\",\n    \"-09:30\",\n    \"-09:00\",\n    \"-08:00\",\n    \"-07:00\",\n    \"-06:00\",\n    \"-05:00\",\n    \"-04:00\",\n    \"-03:30\",\n    \"-03:00\",\n    \"-02:00\",\n    \"-01:00\",\n    \"+00:00\",\n    \"+01:00\",\n    \"+02:00\",\n    \"+03:00\",\n    \"+03:30\",\n    \"+04:00\",\n    \"+04:30\",\n    \"+05:00\",\n    \"+05:30\",\n    \"+05:45\",\n    \"+06:00\",\n    \"+06:30\",\n    \"+07:00\",\n    \"+08:00\",\n    \"+08:45\",\n    \"+09:00\",\n    \"+09:30\",\n    \"+10:00\",\n    \"+10:30\",\n    \"+11:00\",\n    \"+12:00\",\n    \"+12:45\",\n    \"+13:00\",\n    \"+14:00\",\n] as const;\n\nexport type Offset = (typeof offsets)[number];\nconst isOffset = (o: any) => offsets.includes(o);\n\nexport const OffsetPicker = () => {\n    const offset = useDatePicker(\"offset\") ?? \"+00:00\";\n    const { updateOffset } = useDatePickerActions();\n\n    const localOffsets = useMemo(() => {\n        // account for the obscure case where a user offset has been created that isn't standard\n        if (isOffset(offset)) return offsets;\n        const localOffsets = [...offsets, offset].sort();\n        return localOffsets;\n    }, [offset]);\n\n    return (\n        <div className=\"flex flex-col items-center justify-center\">\n            <Text level={3} className={\"mb-[-0.2rem]!\"}>\n                Timezone Offset\n            </Text>\n            <DropDown\n                value={offset}\n                variant=\"small\"\n                onChange={(e: React.ChangeEvent<HTMLSelectElement>) => updateOffset(e.target.value as Offset)}>\n                {localOffsets.map((offset) => (\n                    <option key={offset} value={offset}>\n                        {offset}\n                    </option>\n                ))}\n            </DropDown>\n        </div>\n    );\n};\n","import React from \"react\";\nimport { DateTimeCalendar } from \"./DateTimePicker\";\nimport { OffsetPicker } from \"./OffsetPicker\";\nimport { GenericPicker, PickerProps } from \"./Picker\";\n\n/**\n * offset and value must be kept separate because of javascript Dates being awkward with offsets other than browser offset\n * typically you'll combine them in the onConfirm callback\n */\nexport const DateTimePickerWithOffset = ({\n    offset = \"+00:00\",\n    format = \"MMM do, y HH:mm:ss\",\n    placeholder = \"Select a date and time\",\n    ...props\n}: PickerProps) => (\n    <GenericPicker placeholder={placeholder} format={format} offset={offset} {...props}>\n        <div className=\"flex flex-col items-center gap-2\">\n            <DateTimeCalendar showSec showMil />\n            <OffsetPicker />\n        </div>\n    </GenericPicker>\n);\n","import React, { useCallback, useLayoutEffect, useRef, useState } from \"react\";\nimport { faCheck } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Item } from \"@/components/reusable/DropdownMenu\";\nimport { DropDownProps, SelectDropDown, SelectionItem } from \"@/components/reusable/selectdropdown/SelectDropDown\";\nimport { cx } from \"@/theme/styles\";\nimport { useResizeObserverTimeout } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\n\nexport interface MultiSelectProps<T extends SelectionItem> extends DropDownProps<T> {\n    onChange: (items: T[\"value\"][]) => void;\n    selected: T[\"value\"][];\n    explicitClose?: boolean;\n    orderMatters?: boolean;\n}\n\n/**\n *\n *  MultiSelectDropDown component - like <select> but dropdown items are checkboxes that can be selected and added/removed from the provided array\n *\n *  You need to set the width it'll change based off the selected value\n *\n *  @example\n *  const MultiSelectExample = () => {\n *      const [selected, setSelected] = useState([]);\n *      const onChange = useEvent( v => {\n *          setValue(v)\n *      });\n *      const items = [\n *          {value: 1, display: \"Lorem ipsum dolor sit amet, consectetur adipiscing elit\"},\n *          {value: 2, display: <>Etiam vestibulum ex non nisi pretium blandit</>},\n *          {value: \"3\", display: \"Morbi auctor odio sed nibh tempus, quis aliquam tortor varius\"},\n *          {value: \"4\", display: <>Praesent fermentum diam vitae turpis suscipit semper</>}\n *      ];\n *\n *      return <div className={\"m-4\"}>\n *          <MultiSelectDropDown items={items} selected={selected} className={\"w-[20rem]!\"} placeholder={\"Make a Selection\"} onChange={onChange} small/>\n *      </div>\n *  }\n *\n */\n\nexport const MultiSelectDropDown = <T extends SelectionItem>({\n    small = false,\n    selected,\n    placeholder = \"\",\n    className,\n    items,\n    onChange,\n    dropDownClassName,\n    explicitClose = false,\n    orderMatters = false,\n}: MultiSelectProps<T>) => {\n    const dropdownRef = useRef<HTMLDivElement>(null!);\n    const [hoverIndex, setHoverIndex] = useState<number>(-1);\n\n    const onItemSelect = useEvent((item: T) => {\n        const currentSelected = [...selected];\n        const value = item.value;\n        const ind = currentSelected.findIndex((s) => s === value);\n        if (ind >= 0) {\n            currentSelected.splice(ind, 1);\n        } else {\n            currentSelected.push(value);\n        }\n        onChange(currentSelected);\n    });\n\n    const renderItem = (item: T) => (\n        <Item className={cx(\"w-full\", { \"p-5!\": !small })} onClick={() => onItemSelect(item)}>\n            <div className={\"flex items-center justify-start\"}>\n                <div>\n                    {orderMatters\n                        ? <div className={\"w-[1.5rem] flex items-center\"}><span className={cx(\"text-lg\", selected.includes(item.value) ? \"text-primary\" : \"text-transparent\",)}>{selected.findIndex(s => s === item.value) + 1}</span></div>\n                        : <FontAwesomeIcon className={cx(\"text-[1.3rem]\", selected.includes(item.value) ? \"text-primary\" : \"text-transparent\",)} icon={faCheck} />\n                    }\n                </div>\n                <div className={\"w-full pl-[0.8rem]\"}>{item.display ?? item.value}</div>\n            </div>\n        </Item>\n    );\n\n    const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useEvent((e) => {\n        switch (e.key) {\n            case \"Enter\":\n            case \" \":\n                e.preventDefault();\n                onItemSelect(items[hoverIndex] as T);\n                break;\n        }\n    });\n\n    const selectedElementsRef = useRef<HTMLDivElement>(null);\n    const badgeRef = useRef<HTMLDivElement>(null);\n    const titleRef = useRef<HTMLDivElement>(null!);\n    const [showBadge, setShowBadge] = useState(false);\n\n    const onResize = useEvent(() => {\n        const titleContainer = titleRef.current;\n        const selectedElementContainer = selectedElementsRef.current;\n        const badgeContainer = badgeRef.current;\n        const badgeElement = badgeContainer?.firstElementChild;\n\n        setShowBadge(false);\n        if (!titleContainer || !selectedElementContainer || !badgeContainer || !badgeElement) return;\n\n        const selectedElementsChildren = selectedElementContainer.children ?? [];\n        const selectedElements = Array.from(selectedElementsChildren as Iterable<HTMLElement>);\n\n        let notShown = selected.length;\n        badgeElement.textContent = \"\";\n        let totalWidth = badgeContainer.offsetWidth;\n\n        selectedElements.forEach((element) => {\n            element.style.display = \"none\";\n        });\n        const containerWidth = titleRef.current.offsetWidth;\n\n        for (const element of selectedElements) {\n            element.style.display = \"\";\n            element.style.textOverflow = \"\";\n            element.style.whiteSpace = \"\";\n            element.style.overflow = \"\";\n\n            totalWidth += element.offsetWidth + 2;\n            totalWidth -= badgeContainer.offsetWidth;\n            if (notShown > 1) {\n                badgeElement.textContent = \"+\" + (notShown - 1);\n            } else {\n                badgeElement.textContent = \"\";\n            }\n            totalWidth += badgeContainer.offsetWidth;\n\n            if (totalWidth < containerWidth) {\n                notShown--;\n            } else {\n                element.style.display = \"none\";\n                setShowBadge(true);\n                break;\n            }\n        }\n\n        if (selected.length > 1 && notShown === selected.length) {\n            const element = selectedElements[0] as HTMLSpanElement;\n            element.style.display = \"\";\n            element.style.textOverflow = \"ellipsis\";\n            element.style.whiteSpace = \"no-wrap\";\n            element.style.overflow = \"hidden\";\n            notShown--;\n        }\n\n        if (notShown) {\n            badgeElement.textContent = \"+\" + notShown;\n        } else {\n            badgeElement.textContent = \"\";\n        }\n    });\n\n    useLayoutEffect(onResize, [selected?.length]);\n    useResizeObserverTimeout(titleRef, onResize);\n\n    return (\n        <SelectDropDown<T>\n            dropdownRef={dropdownRef}\n            items={items}\n            small={small}\n            className={className}\n            renderItem={renderItem}\n            onKeyDown={onKeyDown}\n            hoverIndex={hoverIndex}\n            dropDownClassName={dropDownClassName}\n            setHoverIndex={setHoverIndex}\n            explicitClose={explicitClose}>\n            {selected.length > 0 ? (\n                <div ref={titleRef} className={\"flex w-full justify-between\"}>\n                    {selected.length === 1 ? (\n                        <ItemTile small={small} single items={items} value={selected[0]} />\n                    ) : (\n                        <>\n                            <div ref={selectedElementsRef} className={\"flex w-full overflow-hidden whitespace-nowrap\"}>\n                                {selected.map((s, index) => (\n                                    <ItemTile small={small} items={items} value={s} />\n                                ))}\n                            </div>\n                            <div ref={badgeRef}>\n                                <div\n                                    className={cx(\n                                        \"mx-2 min-w-max self-center rounded-md bg-primary px-2 py-1 text-lg font-semibold dark:bg-primary-600\",\n                                        { \"rounded-md leading-4\": small, invisible: !showBadge }\n                                    )}\n                                />\n                            </div>\n                        </>\n                    )}\n                </div>\n            ) : (\n                <span className={cx(\"text-light-bg5 dark:text-dark-bg8\", small && \"dark:text-gray-400\")}>\n                    {placeholder}\n                </span>\n            )}\n        </SelectDropDown>\n    );\n};\n\ninterface ItemTileProps<T extends SelectionItem> {\n    small?: boolean;\n    single?: boolean;\n    items: T[];\n    value: T[\"value\"];\n}\n\nconst ItemTile = <T extends SelectionItem>({ small = false, single = false, items, value }: ItemTileProps<T>) => {\n    const item = items.find((item) => item.value === value);\n    return (\n        <span\n            className={cx(\n                \"mr-1 rounded-md bg-grey-0 px-2 dark:text-dark-fg2\",\n                small && \"bg-light-bg1 leading-6 dark:bg-dark-bg6 dark:text-dark-fg1\",\n                single && \"overflow-hidden text-ellipsis whitespace-nowrap\"\n            )}>\n            {item?.display ?? item?.value ?? value}\n        </span>\n    );\n};\n","import React, { useMemo, useRef, useState } from \"react\";\nimport { Item } from \"@/components/reusable/DropdownMenu\";\nimport { DropDownProps, SelectDropDown, SelectionItem } from \"@/components/reusable/selectdropdown/SelectDropDown\";\nimport { cx } from \"@/theme/styles\";\nimport useEvent from \"@/util/useEventCallback\";\n\ninterface SingleSelectDropDownProps<T extends SelectionItem> extends DropDownProps<T> {\n    value: T[\"value\"] | null;\n    onChange(s: T[\"value\"]): void;\n    selected?: T;\n    emptyItemsMessage?: string\n}\n\n/**\n *\n *  SingleSelectDropDown component - like the HTML <select>\n *\n *  You need to set the width it'll change based off the selected value\n *\n *  @example\n *  const SingleSelectExample = () => {\n *      const [value, setValue] = useState(null);\n *      const onChange = useEvent( v => {\n *          setValue(v)\n *      });\n *      const items = [\n *          {value: 1, display: \"Lorem ipsum dolor sit amet, consectetur adipiscing elit\"},\n *          {value: 2, display: <>Etiam vestibulum ex non nisi pretium blandit</>},\n *          {value: \"3\", display: \"Morbi auctor odio sed nibh tempus, quis aliquam tortor varius\"},\n *          {value: \"4\", display: <>Praesent fermentum diam vitae turpis suscipit semper</>}\n *      ];\n *\n *      return <div className={\"m-4\"}>\n *          <SingleSelectDropDown items={items} value={value} className={\"w-[20rem]!\"} placeholder={\"Make a Selection\"} onChange={onChange} small/>\n *      </div>\n *  }\n *\n */\nexport const SingleSelectDropDown = <T extends SelectionItem>({\n    value,\n    placeholder = \"\",\n    items,\n    small = false,\n    className,\n    onChange,\n    dropDownClassName,\n    emptyItemsMessage\n}: SingleSelectDropDownProps<T>) => {\n    const dropdownRef = useRef<HTMLDivElement>(null!);\n\n    useRef<HTMLInputElement>(null!);\n\n    const getIndexFromValue = (value: T[\"value\"]) => {\n        return items.findIndex((item) => item.value === value);\n    };\n\n    const selected = useMemo(() => items.find((item) => item.value === value), [value, items]);\n\n    const [hoverIndex, setHoverIndex] = useState(() => getIndexFromValue(value));\n\n    const renderItem = (item: SelectionItem) => (\n        <Item className={cx(\"w-full\", { \"text-primary-600\": item.value === value, \"p-5!\": !small })}>\n            {item.display ?? item.value}\n        </Item>\n    );\n\n    const onItemSelect = useEvent(({ value }: T) => {\n        onChange(value);\n        setHoverIndex(getIndexFromValue(value));\n    });\n\n    const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useEvent((e) => {\n        switch (e.key) {\n            case \"Enter\":\n            case \" \":\n                e.preventDefault();\n                const item = items[hoverIndex];\n                if (!item) return;\n                onItemSelect(item);\n                dropdownRef.current.blur();\n                break;\n        }\n    });\n\n    return (\n        <SelectDropDown<T>\n            dropdownRef={dropdownRef}\n            small={small}\n            className={className}\n            renderItem={renderItem}\n            onKeyDown={onKeyDown}\n            onItemSelect={onItemSelect}\n            items={items}\n            hoverIndex={hoverIndex}\n            dropDownClassName={dropDownClassName}\n            setHoverIndex={setHoverIndex}\n            emptyItemsMessage={emptyItemsMessage}>\n            {value ? (\n                typeof selected?.display === \"string\" ? (\n                    <div className={\"overflow-hidden text-ellipsis whitespace-nowrap\"}>\n                        {selected?.display ?? selected.value}\n                    </div>\n                ) : (\n                    (selected?.display ?? value)\n                )\n            ) : (\n                <span className={cx(\"text-light-bg5 dark:text-dark-bg8\", small && \"dark:text-gray-400\")}>\n                    {placeholder}\n                </span>\n            )}\n        </SelectDropDown>\n    );\n};\n","import React, { useMemo, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { MouseTouchEvent, getMouseEventOrTouch, isMultiTouch } from \"@/util/dnd\";\nimport useEvent from \"@/util/useEventCallback\";\n\nconst useStyles = makeStyles<void, \"end\" | \"start\" | \"handle\" | \"handleHitZone\">()((theme, _props, classes) => {\n    return {\n        root: {\n            position: \"relative\",\n            minWidth: \"10rem\",\n            flex: \"0 0 auto\",\n        },\n        start: {},\n        end: {},\n        handle: {\n            position: \"absolute\",\n            opacity: 1,\n            background:\n                (\"resizePanel\" in theme ? theme.resizePanel?.handleColor?.toString() : undefined) ??\n                theme.sectionBorderColor.toString(),\n            zIndex: 6,\n            [`&.${classes.start}`]: {\n                left: 0,\n                top: 0,\n            },\n            [`&.${classes.end}`]: {\n                right: 0,\n                bottom: 0,\n            },\n        },\n        horizontal: {\n            [`&>.${classes.handle}`]: {\n                height: \"100%\",\n                cursor: \"col-resize\",\n            },\n            [`&>.${classes.handle}>.${classes.handleHitZone}`]: {\n                top: 0,\n                height: \"100%\",\n            },\n        },\n        vertical: {\n            [`&>.${classes.handle}`]: {\n                width: \"100%\",\n                cursor: \"row-resize\",\n            },\n            [`&>.${classes.handle}>.${classes.handleHitZone}`]: {\n                right: 0,\n                left: 0,\n            },\n        },\n        shield: {\n            position: \"absolute\",\n            inset: 0,\n            zIndex: 5,\n        },\n        handleHitZone: {\n            position: \"absolute\",\n            opacity: 0,\n            background: theme.isDark ? \"white\" : \"black\",\n            \"&:hover\": {\n                opacity: 0.08,\n            },\n        },\n    };\n});\n\nconst getContainer = (element: Element, level: number) => {\n    let container: Element = element;\n    while (level > 0) {\n        container = container.parentElement!;\n        level--;\n    }\n    return container;\n};\n\ninterface ResizeProps {\n    children: React.ReactNode;\n    style?: any;\n    className?: string;\n    panelSize?: number | string;\n    horizontal?: boolean;\n    enabled?: boolean;\n    handleVisible?: boolean;\n    handleSize?: number;\n    hitZoneSize?: number;\n    handleAtStart?: boolean;\n    onFinishDrag?(v: number, oldV: number): void;\n    onDoubleClick?: React.MouseEventHandler<HTMLDivElement>;\n    closed?: boolean;\n    containerLevel?: number;\n    classes?: Record<string, string>;\n    // These two currently only work for horizontal panels.\n    minSize?: number;\n    snapToMinAtSize?: number; // If we get down to this size while dragging, snap to minSize\n}\n\nconst ResizePanel = ({\n    children,\n    className,\n    style,\n    panelSize,\n    horizontal,\n    handleAtStart,\n    enabled = true,\n    handleVisible = false,\n    handleSize = 1,\n    hitZoneSize = 10,\n    onFinishDrag,\n    onDoubleClick,\n    classes: rootClasses,\n    closed,\n    containerLevel = 1,\n    minSize = 32,\n    snapToMinAtSize = 80,\n}: ResizeProps) => {\n    const { classes } = useStyles();\n    const panel = useRef<HTMLDivElement>(null!);\n\n    const dragStartMousePos = useRef<number>(0);\n    const dragStartComponentValue = useRef<number>(0);\n    const dragStartBound = useRef<number>(0);\n\n    const [showShield, setShield] = useState(false);\n\n    const startDrag = useEvent((e: MouseTouchEvent) => {\n        if (isMultiTouch(e)) return;\n\n        // Don't start selecting things on the page. It messes up the dragging.\n        e.preventDefault();\n        e.stopPropagation();\n\n        document.body.addEventListener(\"mouseup\", stopDrag);\n        document.body.addEventListener(\"mouseleave\", stopDrag);\n        document.body.addEventListener(\"mousemove\", drag);\n        document.body.addEventListener(\"touchend\", stopDrag);\n        document.body.addEventListener(\"touchmove\", drag);\n\n        const { pageX, pageY } = getMouseEventOrTouch(e);\n        dragStartMousePos.current = horizontal ? pageX : pageY;\n        dragStartComponentValue.current = horizontal ? panel.current.offsetWidth : panel.current.offsetHeight;\n        // containerLevel determines the parent element that we're dragging within.\n        // Maybe not the best api as it will need changing if the heirarchy changes\n        // This defaults to 1 (the immediate parent). But in some cases (the sidebar) it's the parent-parent\n        const container = getContainer(panel.current, containerLevel);\n        dragStartBound.current = horizontal ? container.scrollWidth : container.scrollHeight;\n\n        setShield(true);\n    });\n\n    const drag = useEvent((e: MouseEvent | TouchEvent) => {\n        const container = getContainer(panel.current, containerLevel);\n        if (horizontal) {\n            const { pageX } = getMouseEventOrTouch(e);\n            const dx = handleAtStart ? pageX - dragStartMousePos.current : dragStartMousePos.current - pageX;\n            const panelWidth = panel.current.offsetWidth;\n            const newWidth = dragStartComponentValue.current - dx;\n\n            panel.current.style.width = `${newWidth < snapToMinAtSize ? minSize : newWidth}px`;\n            if (container.scrollWidth > dragStartBound.current && newWidth > snapToMinAtSize) {\n                // reset if the container scroll width increases during dragging\n                panel.current.style.width = `${panelWidth}px`;\n            }\n        } else {\n            const { pageY } = getMouseEventOrTouch(e);\n            const dy = handleAtStart ? pageY - dragStartMousePos.current : dragStartMousePos.current - pageY;\n            const panelHeight = panel.current.offsetHeight;\n            const newHeight = dragStartComponentValue.current - dy;\n            panel.current.style.height = `${newHeight < snapToMinAtSize ? minSize : newHeight}px`;\n            if (container.scrollHeight > dragStartBound.current && dy < 0) {\n                // reset if the container scroll height increases during dragging\n                panel.current.style.height = `${panelHeight}px`;\n            }\n        }\n    });\n\n    const stopDrag = useEvent(() => {\n        document.body.removeEventListener(\"mouseup\", stopDrag);\n        document.body.removeEventListener(\"mouseleave\", stopDrag);\n        document.body.removeEventListener(\"mousemove\", drag);\n        document.body.removeEventListener(\"touchend\", stopDrag);\n        document.body.removeEventListener(\"touchmove\", drag);\n\n        if (horizontal) {\n            onFinishDrag?.(panel.current.offsetWidth, dragStartComponentValue.current);\n        } else {\n            onFinishDrag?.(panel.current.offsetHeight, dragStartComponentValue.current);\n        }\n        setShield(false);\n    });\n\n    const finalStyle = useMemo(() => {\n        const s = { ...style };\n        if (closed) {\n            s.flex = \"1 0 auto\"; // N.B. This may not actually be correct everywhere, but it's what we need for the runner.\n        } else {\n            s[horizontal ? \"width\" : \"height\"] = panelSize;\n            // In case we're not actually changing finalStyle, make sure we override whatever the last drag state was.\n            // (This is needed when enforcing a maximum width externally, for instance)\n            if (horizontal && panel.current) {\n                panel.current.style.width = `${panelSize}px`;\n            } else if (panel.current) {\n                panel.current.style.height = `${panelSize}px`;\n            }\n        }\n        if (enabled) {\n            s[horizontal ? \"paddingLeft\" : \"paddingTop\"] = handleVisible && handleSize;\n            s[horizontal ? \"paddingRight\" : \"paddingBottom\"] = handleVisible && handleSize;\n        }\n\n        return s;\n    }, [style, closed, horizontal, panelSize, enabled, handleVisible, handleSize]);\n\n    const handleStyle = useMemo(() => {\n        const style: any = {};\n        if (horizontal) {\n            style.width = handleSize;\n            style[handleAtStart ? \"left\" : \"right\"] = handleVisible ? 0 : -handleSize / 2;\n        } else {\n            style.height = handleSize;\n            style[handleAtStart ? \"top\" : \"bottom\"] = handleVisible ? 0 : -handleSize / 2;\n        }\n        return style;\n    }, [horizontal, handleSize, handleAtStart, handleVisible]);\n\n    const handleHitZoneStyle = useMemo(() => {\n        return {\n            [horizontal ? \"width\" : \"height\"]: hitZoneSize,\n            [horizontal ? \"left\" : \"top\"]: -hitZoneSize * 0.5,\n        };\n    }, [horizontal, hitZoneSize]);\n\n    return (\n        <>\n            <div\n                ref={panel}\n                className={cx(\n                    classes.root,\n                    rootClasses?.root,\n                    {\n                        [classes.horizontal]: enabled && horizontal,\n                        [classes.vertical]: enabled && !horizontal,\n                    },\n                    className\n                )}\n                style={finalStyle}>\n                {children}\n                {enabled && (\n                    <div\n                        onDoubleClick={onDoubleClick}\n                        onMouseDown={startDrag}\n                        onTouchStart={startDrag}\n                        className={cx(classes.handle, handleAtStart ? classes.start : classes.end)}\n                        style={handleStyle}>\n                        <div className={classes.handleHitZone} style={handleHitZoneStyle} />\n                    </div>\n                )}\n            </div>\n            {showShield && createPortal(<div className={classes.shield} />, document.body)}\n        </>\n    );\n};\n\nexport default ResizePanel;\n","import React, { useEffect, useMemo, useState } from \"react\";\nimport { useDispatch, useSelector, useStore } from \"react-redux\";\nimport { faUpload } from \"@fortawesome/pro-light-svg-icons\";\nimport { faBolt } from \"@fortawesome/pro-light-svg-icons/faBolt\";\nimport { faCopy } from \"@fortawesome/pro-light-svg-icons/faCopy\";\nimport { faCube } from \"@fortawesome/pro-light-svg-icons/faCube\";\nimport { faCubes } from \"@fortawesome/pro-light-svg-icons/faCubes\";\nimport { faExternalLink } from \"@fortawesome/pro-light-svg-icons/faExternalLink\";\nimport { faObjectGroup } from \"@fortawesome/pro-light-svg-icons/faObjectGroup\";\nimport { faPencil } from \"@fortawesome/pro-light-svg-icons/faPencil\";\nimport { faTrashAlt } from \"@fortawesome/pro-light-svg-icons/faTrashAlt\";\nimport { faChevronDown } from \"@fortawesome/pro-regular-svg-icons/faChevronDown\";\nimport { faChevronRight } from \"@fortawesome/pro-regular-svg-icons/faChevronRight\";\nimport { faPlay } from \"@fortawesome/pro-regular-svg-icons/faPlay\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { sortBy } from \"lodash-es\";\nimport { getAppRuntimeVersion, getAppStartupItem } from \"@/controllers/app\";\nimport {\n    deleteCodeItem,\n    duplicateForm,\n    getCodeNavState,\n    renameCodeItem,\n    setAppStartupItem,\n    setFileExpanded,\n    setIsPackage,\n    updateCodeNavState,\n} from \"@/controllers/app/code\";\nimport { getShowNewDesigner } from \"@/controllers/designer\";\nimport { alert, modal } from \"@/controllers/modals\";\nimport { runScript } from \"@/controllers/scripts\";\nimport { CodeNavTarget, NavTarget } from \"@/router/navTypes\";\nimport { navigate } from \"@/router/navigation\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { AnvilDispatch, CodeStructureType, FileTreeItem, State, StructureItem, TreeType, isCodePath } from \"@/types\";\nimport { EMPTY_ARRAY } from \"@/util\";\nimport { useDrag } from \"@/util/dnd\";\nimport { useExternalState } from \"@/util/external-state\";\nimport { useMergeRefs } from \"@/util/hooks\";\nimport { useCopyAssetPath } from \"@/util/hooks/use-copy-asset-path\";\nimport { useReplaceAsset } from \"@/util/hooks/use-replace-asset\";\nimport useEffectEvent from \"@/util/useEffectEvent\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { MenuItems } from \"../reusable/DropdownMenu\";\nimport { useFileIcon, useFileIconClassGetter } from \"../reusable/IconHooks\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { NavNodeRenamer } from \"../reusable/NavNodeRenamer\";\nimport { ContextMenuItems, fileRenamingIdAtom, useSelectedFileContext } from \"./CodeNav\";\nimport { useFileDrop } from \"./CodeNavDragging\";\nimport { SecondaryNavLink } from \"./SecondaryNavSection\";\n\nconst useStyles = makeStyles<void, \"expanded\">()((theme, _props, classes) => ({\n    beingDragged: {\n        backgroundColor: theme.palette.bg1.hex(),\n    },\n    fileRoot: {\n        paddingLeft: \"1.8rem\",\n    },\n    fileLinkRoot: {\n        display: \"flex\",\n        alignItems: \"center\",\n    },\n    childList: {\n        paddingLeft: \"0.5rem\",\n    },\n    fileRootWithFolderLine: {\n        borderLeft: \"1px solid \" + theme.secondaryNav.folderLines.toString(),\n    },\n    expander: {\n        flex: \"0 0 auto\",\n        width: \"2rem\",\n    },\n    expanded: {},\n    expanderIcon: {\n        color: theme.secondaryNav.enabledChevron.toString(),\n        \"&:hover\": {\n            color: theme.secondaryNav.hoverChevron.toString(),\n        },\n        [`&.${classes.expanded}`]: {\n            color: theme.secondaryNav.expandedChevron.toString(),\n            \"&:hover\": {\n                color: theme.secondaryNav.hoverChevron.toString(),\n            },\n        },\n    },\n    expanderMuted: {\n        color: theme.secondaryNav.disabledChevron.toString(),\n    },\n    fileLinkContainer: {\n        flexGrow: 1,\n    },\n    renameBox: {\n        marginLeft: \"-0.2rem\",\n        color: theme.isDark ? theme.palette.fg2.hex() : theme.palette.fg1.hex(),\n        backgroundColor: theme.isDark ? theme.palette.bg3.hex() : theme.palette.bg0.hex(),\n        border: \"1px solid \" + theme.isDark ? theme.palette.bg2.hex() : theme.palette.bg1.hex(),\n    },\n    startupIndicator: {\n        color: theme.primary.hex(),\n        marginLeft: \"1.5rem\",\n    },\n    formIcon: {\n        background: theme.secondaryNav.icon1.background.toString(),\n        color: theme.secondaryNav.icon1.color.toString(),\n    },\n    otherClientIcon: {\n        background: theme.secondaryNav.icon3.background.toString(),\n        color: theme.secondaryNav.icon3.color.toString(),\n    },\n    serverIcon: {\n        background: theme.secondaryNav.icon2.background.toString(),\n        color: theme.secondaryNav.icon2.color.toString(),\n    },\n}));\n\nexport const useFileExpanded = (\n    treeType: TreeType,\n    file: Pick<FileTreeItem, \"id\" | \"fullName\" | \"isPackage\" | \"type\" | \"defaultExpanded\">,\n    hasChildren: boolean,\n    {\n        allowEmptyExpansion = false,\n    }: {\n        allowEmptyExpansion?: boolean;\n    } = {}\n) => {\n    const codeNavState = useSelector(getCodeNavState);\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { id, fullName } = file;\n\n    const savedExpanded = codeNavState[treeType]?.[id || fullName]?.expanded;\n\n    const expanded = hasChildren && (savedExpanded ?? file.defaultExpanded ?? false);\n\n    const setExpanded = useEvent((expanded: boolean) => {\n        if (!hasChildren && !allowEmptyExpansion) {\n            return;\n        }\n\n        dispatch(setFileExpanded(treeType, file, expanded));\n    });\n\n    return [expanded, setExpanded] as const;\n};\n\nexport const useFileIconAndClass = (file: StructureItem, classes: Record<string, string>) => {\n    const iconClass = useFileIconClassGetter(classes)(file.type);\n    const icon = useFileIcon(file, \"regular\");\n    return [icon, iconClass] as const;\n};\n\nconst usePrefersStandalone = (file: StructureItem, treeType: TreeType) => {\n    const standalonePref = useSelector(\n        (state: State) => getCodeNavState(state)[treeType]?.[file.id ?? file.fullName]?.standalone\n    );\n    return standalonePref;\n};\n\nconst useContextMenu = (\n    contextMenuItems: ContextMenuItems,\n    file: StructureItem,\n    treeType: TreeType,\n    appStartupItem: any,\n    setRenaming: React.Dispatch<React.SetStateAction<boolean>>\n) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const store = useStore<State>();\n    const runtimeVersion = useSelector(getAppRuntimeVersion);\n    const canUseClassic = runtimeVersion < 3;\n    const prefersStandalone = usePrefersStandalone(file, treeType);\n    const showNewDesigner = useSelector(getShowNewDesigner);\n\n    const [copyClickHandler] = useCopyAssetPath(file);\n    const [fileInput, onReplaceAsset] = useReplaceAsset(file);\n    const onUseAsHtmlLayout = useEvent(() => {\n        dispatch(modal(\"htmlLayout\", { asset: file }));\n    });\n\n    return useMemo(() => {\n        let items: (ReturnType<ContextMenuItems>[number] | React.ReactNode)[] = [];\n        if (file.isPackage || file.type === \"folder\") {\n            items = [...contextMenuItems(file), <hr />];\n        }\n        if (file.type === \"script\") {\n            items.push([\"Run script\", () => dispatch(runScript(file.name)), faPlay]);\n            items.push(<hr />);\n        }\n\n        items.push([`Rename...`, () => setRenaming(true), faPencil]);\n        items.push([`Delete ${file.name}`, () => dispatch(deleteCodeItem(file, true)), faTrashAlt]);\n        if (file.type === \"form\") {\n            items.push([`Duplicate ${file.name}`, () => dispatch(duplicateForm(file)), faCopy]);\n            const inPlaceEdit = showNewDesigner ? file.inPlaceEditV3 : file.inPlaceEdit;\n            if (inPlaceEdit) {\n                if (prefersStandalone) {\n                    items.push([\n                        \"Edit in place...\",\n                        () => {\n                            dispatch(navigate(inPlaceEdit));\n                            dispatch(updateCodeNavState(treeType, file, { standalone: false }));\n                        },\n                        faExternalLink,\n                    ]);\n                } else {\n                    items.push([\n                        \"Edit in standalone view...\",\n                        () => {\n                            dispatch(navigate({ type: \"CODE\", codePath: file.codePath }));\n                            dispatch(updateCodeNavState(treeType, file, { standalone: true }));\n                        },\n                        faExternalLink,\n                    ]);\n                }\n            }\n            items.push(<hr />);\n            items.push([\n                `Edit properties and events...`,\n                () => dispatch(modal(\"customcomponent\", { codePath: file.codePath })),\n                faObjectGroup,\n            ]);\n        }\n        if (file.type === \"asset\") {\n            items.push([\"Replace...\", onReplaceAsset, faUpload]);\n            items.push([\"Copy Asset Path\", copyClickHandler, faCopy]);\n            items.push(fileInput);\n            if (!canUseClassic && file.fullName.endsWith(\".html\")) {\n                // We're not sure we actually want to expose this feature like this. Perhaps using HTML assets as layouts directly will confuse people.\n                // items.push(<hr />);\n                // items.push([\"Use as layout...\", onUseAsHtmlLayout, faBrowser]);\n            }\n        }\n        if (\n            file.type !== \"asset\" &&\n            file.type !== \"folder\" &&\n            file.type !== \"script\" &&\n            (!file.isPackage || (file.children || []).length === 0)\n        ) {\n            items.push(<hr />);\n            items.push([\n                `Convert to ${file.isPackage ? \"Module\" : \"Package\"}`,\n                () => {\n                    dispatch(setIsPackage(file, !file.isPackage, { subscribe: store.subscribe })).catch((error) =>\n                        dispatch(alert(\"Conversion unavailable\", String(error)))\n                    );\n                },\n                file.isPackage ? faCube : faCubes,\n            ]);\n        }\n        if (file.name !== appStartupItem?.module) {\n            if (file.type === \"form\") {\n                items.push(<hr />);\n                items.push([\"Set as Startup Form\", () => dispatch(setAppStartupItem(file)), faBolt]);\n            } else if (file.type === \"module\") {\n                items.push(<hr />);\n                items.push([\"Set as Startup Module\", () => dispatch(setAppStartupItem(file)), faBolt]);\n            }\n        }\n        return () => items;\n    }, [contextMenuItems, file, appStartupItem, prefersStandalone, canUseClassic, treeType, showNewDesigner]);\n};\n\nconst isIdentifier = /^[a-zA-Z_][a-zA-Z0-9_]*$/;\n\nconst canBeNested = (typeA: CodeStructureType, typeB: CodeStructureType) => {\n    switch (typeA) {\n        case \"asset\":\n            return typeB === \"folder\";\n        case \"module\":\n        case \"form\":\n            return typeB === \"form\" || typeB === \"module\";\n        case \"server_module\":\n            return typeB === \"server_module\";\n        default:\n            return false;\n    }\n};\n\nconst isPythonIdentifier = (name: string) => {\n    return isIdentifier.test(name);\n};\n\nconst checkIsNested = (selected: FileTreeItem | null, file: StructureItem) => {\n    if (!selected) return false;\n    if (!(file.isPackage || file.type === \"folder\") || !canBeNested(selected.type, file.type)) {\n        return false;\n    }\n    const maybeDescendent = selected.fullName.startsWith(file.fullName);\n    if (!maybeDescendent) return false;\n    // make sure that it's not something odd like forms/Form1a.ItemTemplate\n    // being compared with forms/Form1\n    const nextPart = selected.fullName.at(file.fullName.length);\n    if ((selected.type === \"asset\" && nextPart === \"/\") || nextPart === \".\") {\n        return true;\n    }\n    return false;\n};\n\nconst useExpandWhenNodeSelected = (file: StructureItem, setExpanded: (v: boolean) => void) => {\n    const [globalSelectedFile, globalEditingContext] = useSelectedFileContext();\n\n    const nodeSelected = globalSelectedFile === file;\n    const editingNestedForm = globalEditingContext === file;\n\n    const expandToNestedFile = useEffectEvent(\n        (selectedFile: FileTreeItem | null, editingFile: StructureItem | null) => {\n            if (nodeSelected) return;\n\n            if (checkIsNested(selectedFile, file) || checkIsNested(editingFile, file)) {\n                setExpanded(true);\n            }\n        }\n    );\n\n    useEffect(() => {\n        expandToNestedFile(globalSelectedFile, globalEditingContext);\n    }, [globalSelectedFile, globalEditingContext]);\n\n    return [nodeSelected, editingNestedForm];\n};\n\nconst useRenamingFile = (file: StructureItem) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const store = useStore();\n    const [renaming, setRenaming] = useState(false);\n    const [fileRenamingId, setGlobalFileRenamingId] = useExternalState(fileRenamingIdAtom);\n\n    useEffect(() => {\n        if (fileRenamingId !== (file.id ?? file.fullName)) return;\n\n        const timeout = setTimeout(() => setRenaming(true));\n        return () => clearTimeout(timeout);\n    }, [fileRenamingId, file.id, file.fullName]);\n\n    const onRename = useEvent(async (name: string) => {\n        setRenaming(false);\n        setGlobalFileRenamingId(null);\n        if (file.type !== \"asset\" && file.type !== \"folder\") {\n            if (!isPythonIdentifier(name)) {\n                await dispatch(\n                    alert(\n                        \"Invalid name\",\n                        \"Python names can only contain letters, numbers or underscores, and cannot begin with a number.\"\n                    )\n                );\n                setRenaming(true);\n                return;\n            }\n        } else if (name.includes(\"/\")) {\n            await dispatch(alert(\"Invalid asset name\", \"Cannot use forward slash in asset name\"));\n            setRenaming(true);\n            return;\n        }\n\n        try {\n            await dispatch(renameCodeItem(file, name, { subscribe: store.subscribe }));\n        } catch (e: any) {\n            dispatch(alert(\"Failed to rename\", e?.message ?? \"Unable to rename to \" + name));\n            console.error(e);\n            setRenaming(true);\n        }\n    });\n\n    const onCancelRename = useEvent(() => {\n        setRenaming(false);\n        setGlobalFileRenamingId(null);\n    });\n\n    return { renaming, setRenaming, onRename, onCancelRename } as const;\n};\n\ninterface FileRawProps {\n    file: StructureItem;\n    treeType: TreeType;\n    contextMenuItems: ContextMenuItems;\n    level?: number;\n    onDragCallback?: (v: boolean) => void;\n}\n\nconst File = ({ file, treeType, contextMenuItems, level = 0, onDragCallback }: FileRawProps) => {\n    const appStartupItem = useSelector(getAppStartupItem);\n    const showNewDesigner = useSelector(getShowNewDesigner);\n\n    const { classes } = useStyles();\n\n    const { renaming, setRenaming, onRename, onCancelRename } = useRenamingFile(file);\n    const prefersStandalone = usePrefersStandalone(file, treeType);\n\n    const menuItems = useContextMenu(contextMenuItems, file, treeType, appStartupItem, setRenaming);\n\n    const [icon, iconClass] = useFileIconAndClass(file, classes);\n    const sortedChildren = useMemo(\n        () =>\n            sortBy(\n                file.children?.filter((c) => c.name !== \".gitkeep\"),\n                [\"name\"]\n            ),\n        [file.children]\n    );\n\n    const hasChildren = !!sortedChildren.length;\n    const canHaveChildren = file.isPackage || file.type === \"folder\";\n\n    const [expanded, setExpanded] = useFileExpanded(treeType, file, hasChildren);\n\n    let inPlaceEdit: undefined | CodeNavTarget;\n    if (!prefersStandalone) {\n        inPlaceEdit = showNewDesigner ? file.inPlaceEditV3 : file.inPlaceEdit;\n    }\n    const codePath = file.codePath;\n    // folders don't have codePaths\n    let fileNavTarget: NavTarget | null;\n\n    if (inPlaceEdit) {\n        fileNavTarget = inPlaceEdit;\n    } else if (!codePath || !isCodePath(codePath)) {\n        fileNavTarget = null;\n    } else if (file.type === \"form\") {\n        fileNavTarget = {\n            type: \"CODE\",\n            codePath,\n            editingPath: EMPTY_ARRAY,\n        };\n    } else {\n        fileNavTarget = {\n            type: \"CODE\",\n            codePath,\n        };\n    }\n\n    const [nodeSelected, editingNestedForm] = useExpandWhenNodeSelected(file, setExpanded);\n\n    const dragItem = useMemo(() => ({ ...file, treeType }), [file, treeType]);\n    const [{ isDragging }, dragRef] = useDrag({ item: dragItem, type: treeType });\n    const [{ isOver, canDrop }, dropRef, dragOverlayClass] = useFileDrop({ file, setExpanded, treeType });\n\n    const navLinkRef = useMergeRefs(dropRef, dragRef);\n\n    useEffect(() => {\n        onDragCallback?.(isDragging);\n    }, [onDragCallback, isDragging]);\n\n    if (file.name === \".gitkeep\") return null;\n\n    return (\n        <FileTreeBranch\n            level={level}\n            expanded={!!expanded}\n            hasChildren={hasChildren}\n            canHaveChildren={!!canHaveChildren}\n            onToggle={() => setExpanded(!expanded)}\n            row={\n                <SecondaryNavLink\n                    isSelected={nodeSelected}\n                    isDescendentSelected={editingNestedForm}\n                    className={cx(\n                        classes.fileLinkContainer,\n                        isOver && canDrop && dragOverlayClass,\n                        isDragging && classes.beingDragged\n                    )}\n                    to={fileNavTarget}\n                    onClickOverrideNav={fileNavTarget || renaming ? null : () => setExpanded(!expanded)}\n                    onDoubleClick={() => {\n                        if (!renaming) setRenaming(true);\n                    }}\n                    ref={navLinkRef}\n                    menuItems={menuItems}\n                    iconCircleClassName={iconClass}\n                    icon={\n                        <div className={\"fa-layers\"}>\n                            <FontAwesomeIcon fixedWidth icon={icon} />\n                        </div>\n                    }>\n                    {renaming ? (\n                        <NavNodeRenamer\n                            className={classes.renameBox}\n                            isSelected={nodeSelected}\n                            name={file.name}\n                            onRename={onRename}\n                            onCancel={onCancelRename}\n                        />\n                    ) : (\n                        <>\n                            &nbsp;{file.name}\n                            {file.customComponent && (\n                                <FontAwesomeIcon className={classes.startupIndicator} icon={faObjectGroup} />\n                            )}\n                            {appStartupItem?.module && file.fullName === appStartupItem.module && (\n                                <FontAwesomeIcon\n                                    title={\"Startup form\"}\n                                    className={classes.startupIndicator}\n                                    icon={faBolt}\n                                />\n                            )}\n                        </>\n                    )}\n                </SecondaryNavLink>\n            }>\n            {sortedChildren.map((c) => (\n                <File\n                    key={c.id || c.fullName}\n                    file={c}\n                    treeType={treeType}\n                    contextMenuItems={contextMenuItems}\n                    level={level + 1}\n                    onDragCallback={onDragCallback}\n                />\n            ))}\n        </FileTreeBranch>\n    );\n};\n\nexport default File;\n\ninterface FileTreeBranchProps extends React.PropsWithChildren {\n    level: number;\n    expanded: boolean;\n    hasChildren: boolean;\n    canHaveChildren: boolean;\n    onToggle: () => void;\n    row: React.ReactNode;\n    reserveExpanderSpace?: boolean;\n}\n\nexport const FileTreeBranch = ({\n    level,\n    expanded,\n    hasChildren,\n    canHaveChildren,\n    onToggle,\n    row,\n    reserveExpanderSpace = true,\n    children,\n}: FileTreeBranchProps) => {\n    const { classes } = useStyles();\n\n    return (\n        <div className={cx(reserveExpanderSpace && classes.fileRoot, level > 0 && classes.fileRootWithFolderLine)}>\n            <div className={classes.fileLinkRoot}>\n                {(reserveExpanderSpace || hasChildren || canHaveChildren) && (\n                    <div className={classes.expander}>\n                        {hasChildren ? (\n                            <LinkInternal onClick={onToggle}>\n                                <FontAwesomeIcon\n                                    className={cx(classes.expanderIcon, expanded && classes.expanded)}\n                                    icon={expanded ? faChevronDown : faChevronRight}\n                                    fixedWidth\n                                />\n                            </LinkInternal>\n                        ) : canHaveChildren ? (\n                            <span>\n                                <FontAwesomeIcon className={classes.expanderMuted} icon={faChevronRight} fixedWidth />\n                                &nbsp;\n                            </span>\n                        ) : null}\n                    </div>\n                )}\n\n                {row}\n            </div>\n\n            <ul className={classes.childList} hidden={!expanded}>\n                {children}\n            </ul>\n        </div>\n    );\n};\n","import React, { createContext, useCallback, useEffect, useLayoutEffect, useMemo, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faSquareMinus } from \"@fortawesome/pro-light-svg-icons\";\nimport { faFilePlus } from \"@fortawesome/pro-light-svg-icons/faFilePlus\";\nimport { faFolderPlus } from \"@fortawesome/pro-light-svg-icons/faFolderPlus\";\nimport { faPlus } from \"@fortawesome/pro-regular-svg-icons/faPlus\";\nimport { sortBy } from \"lodash-es\";\nimport { FileUploader } from \"@/components/reusable/SharedComponents\";\nimport {\n    addAssetWithModal,\n    addFormWithModal,\n    addNew,\n    collapseAllFiles,\n    getCodeStructure,\n} from \"@/controllers/app/code\";\nimport { snarfTheme } from \"@/controllers/app/themeSnarfer\";\nimport { getUser } from \"@/controllers/ide\";\nimport {\n    getSecondaryNavWidth,\n    getShowAssetsInCodeNav,\n    getShowDependenciesInCodeNav,\n    setCodeNavSectionExpanded,\n} from \"@/controllers/sidebar\";\nimport { getUserUiScale } from \"@/controllers/user\";\nimport { useNavTargetSelector } from \"@/router/navigation-hooks\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport {\n    AnvilDispatch,\n    CodeItemType,\n    CodeItemYaml,\n    FileTreeItem,\n    RootStructure,\n    StructureItem,\n    TreeType,\n} from \"@/types\";\nimport { ExternalState, useExternalState } from \"@/util/external-state\";\nimport { createContextHook } from \"@/util/hooks\";\nimport { USER_AB_FLAGS } from \"@/util/hooks/ab-flags\";\nimport { Button } from \"../reusable/Button\";\nimport { MenuItems } from \"../reusable/DropdownMenu\";\nimport { useFileDrop } from \"./CodeNavDragging\";\nimport File from \"./CodeNavFile\";\nimport { SecondaryNavLink, Section } from \"./SecondaryNavSection\";\n\nconst useStyles = makeStyles()((theme) => ({\n    sectionContent: {\n        padding: \"1.6rem 0 1.6rem 1.6rem\",\n        fontWeight: theme.secondaryNav.fontWeight,\n        fontSize: theme.secondaryNav.fontSize,\n    },\n}));\n\nexport type ContextMenuItems = (file: Partial<StructureItem>) => MenuItems;\n\ninterface CodeSectionBaseProps extends React.PropsWithChildren {\n    sectionTitle: string;\n    contextMenuItems: ContextMenuItems;\n    defaultMenuOption?: string;\n    defaultMenuFunction?: () => any;\n    treeType: TreeType;\n    showHeaderButton: boolean;\n    allowRootDrop?: boolean;\n    headerButton?: React.ReactNode;\n    rootDropTarget?: {\n        headerRef: React.Ref<HTMLDivElement>;\n        bodyRef: React.Ref<HTMLDivElement>;\n        className?: string;\n    };\n}\n\ntype CodeSectionProps = CodeSectionBaseProps &\n    (\n        | {\n              files: RootStructure;\n              renderFiles?: never;\n          }\n        | {\n              files: RootStructure<FileTreeItem>;\n              renderFiles: () => React.ReactNode;\n          }\n    );\n\nexport const CodeSection = (props: CodeSectionProps) => {\n    const {\n        sectionTitle,\n        files,\n        contextMenuItems,\n        defaultMenuOption,\n        defaultMenuFunction,\n        treeType,\n        showHeaderButton,\n        children,\n        headerButton,\n        allowRootDrop = true,\n        rootDropTarget,\n    } = props;\n    const dispatch = useDispatch<AnvilDispatch>();\n    const showAssetsInCodeNav = useSelector(getShowAssetsInCodeNav); // TODO if we keep this then generalise to all sections\n    const { classes } = useStyles();\n    const sortedFiles = useMemo(() => sortBy(files.children || [], [(c) => c.name]), [files]);\n    const asFile = useMemo(() => ({ fullName: \"\", name: sectionTitle, isPackage: true }), [sectionTitle]);\n\n    const [{ isOver: isOverBody, canDrop: canDropBody }, dropRefBody, dragOverlayClass] = useFileDrop({\n        file: asFile,\n        treeType,\n        enabled: allowRootDrop && !rootDropTarget,\n    });\n    const [{ isOver: isOverHeader, canDrop: canDropHeader }, dropRefHeader] = useFileDrop({\n        file: asFile,\n        treeType,\n        enabled: allowRootDrop && !rootDropTarget,\n    });\n\n    const isOver = isOverBody || isOverHeader;\n    const canDrop = (isOverBody && canDropBody) || (isOverHeader && canDropHeader);\n    const draggingClass = rootDropTarget ? rootDropTarget.className : isOver && canDrop && dragOverlayClass;\n\n    const [highlightState, setHighlightState] = useState<string | null>(null);\n\n    const handleDragFile = useCallback((drag: boolean) => {\n        setHighlightState(drag ? \"bg-light-bg3! dark:bg-dark-bg6!\" : null);\n    }, []);\n\n    const _assetState = useState(true);\n    const [expanded, setExpanded] =\n        treeType === \"assets\"\n            ? [!!showAssetsInCodeNav, (v: boolean) => dispatch(setCodeNavSectionExpanded(\"assets\", v))]\n            : _assetState;\n\n    const renderedFiles = props.renderFiles\n        ? props.renderFiles()\n        : sortBy(props.files.children, [\"name\"]).map((file) => (\n              <File\n                  key={file.id || file.fullName}\n                  file={file}\n                  treeType={treeType}\n                  contextMenuItems={contextMenuItems}\n                  onDragCallback={handleDragFile}\n              />\n          ));\n\n    return (\n        <Section\n            useExpander={true}\n            ref={rootDropTarget ? rootDropTarget.headerRef : dropRefHeader}\n            expanded={expanded}\n            title={sectionTitle}\n            className={draggingClass || highlightState || undefined}\n            onToggle={setExpanded}\n            menuItems={() => contextMenuItems({})}\n            button={\n                showHeaderButton\n                    ? (headerButton ??\n                      (defaultMenuFunction && sortedFiles.length > 0 && (\n                          <Button size=\"small\" icon={faPlus} onClick={defaultMenuFunction}>\n                              {defaultMenuOption}\n                          </Button>\n                      )))\n                    : null\n            }>\n            <div\n                className={cx(classes.sectionContent, draggingClass)}\n                ref={rootDropTarget ? rootDropTarget.bodyRef : dropRefBody}>\n                <div className=\"bg-light-bg2 dark:bg-dark-bg2\">\n                    {renderedFiles}\n                    {sortedFiles.length === 0 && defaultMenuFunction && (\n                        <div className={\"text-center\"}>\n                            <Button variant={\"primary\"} small icon={faPlus} onClick={defaultMenuFunction}>\n                                {defaultMenuOption}\n                            </Button>\n                        </div>\n                    )}\n                </div>\n            </div>\n            {children}\n        </Section>\n    );\n};\n\nfunction useShowHeaderButton() {\n    const scale = useSelector(getUserUiScale);\n    const secondaryNavWidth = useSelector(getSecondaryNavWidth);\n    const [showHeaderButton, setShowHeaderButton] = useState(false);\n\n    useLayoutEffect(() => {\n        if (!secondaryNavWidth) return setShowHeaderButton(false);\n        let minWidth;\n        switch (scale) {\n            case \"tiny\":\n                minWidth = 190;\n                break;\n            case \"small\":\n                minWidth = 260;\n                break;\n            case \"large\":\n                minWidth = 385;\n                break;\n            case \"huge\":\n                minWidth = 440;\n                break;\n            default:\n                minWidth = 320;\n                break; //medium is default\n        }\n        setShowHeaderButton(secondaryNavWidth > minWidth);\n    }, [secondaryNavWidth, scale]);\n\n    return showHeaderButton;\n}\n\nexport const fileRenamingIdAtom = new ExternalState<null | string>(null);\n\nconst useRenameOnAddCodeItem = () => {\n    const [_, setRenamingId] = useExternalState(fileRenamingIdAtom);\n    useEffect(() => () => setRenamingId(null), []);\n\n    return useCallback((cb: () => Promise<StructureItem | CodeItemYaml | null | undefined>) => {\n        return async () => {\n            const file = await cb();\n            if (!file) {\n                return setRenamingId(null);\n            }\n            let id = file.id ?? null;\n            if (\"fullName\" in file && file.fullName.endsWith(\"/.gitkeep\")) {\n                // because this is the hidden file that was created and we need a reference to the folder\n                // would be nice if the id just matched\n                id = file.fullName.slice(0, -\"/.gitkeep\".length);\n            }\n            setRenamingId(id);\n        };\n    }, []);\n};\n\nconst SelectedFileContext = createContext<readonly [FileTreeItem | null, StructureItem | null] | null>(null);\nexport const useSelectedFileContext = createContextHook(SelectedFileContext, \"selectedFileContext\");\n\nconst walkFiles = <T extends FileTreeItem>(\n    root: { children?: T[] },\n    pred: (file: FileTreeItem) => boolean\n): FileTreeItem | null => {\n    for (const file of root.children ?? []) {\n        if (pred(file)) return file;\n        const match = walkFiles(file, pred);\n        if (match) return match;\n    }\n    return null;\n};\n\n// when the nav target changes we set the selected file and editing file\n// we then determine whether we should expand inside CodeNavFile\nexport const SelectedFileProvider = ({ children }: React.PropsWithChildren) => {\n    const codeStructure = useSelector(getCodeStructure);\n\n    const currentNavTarget = useNavTargetSelector((target) =>\n        target?.type === \"CODE\" || target?.type === \"EXTRA_FILE\" ? target : null\n    );\n\n    const selectedFileValue = useMemo<readonly [FileTreeItem | null, StructureItem | null]>(() => {\n        if (!currentNavTarget) return [null, null];\n\n        if (currentNavTarget.type === \"EXTRA_FILE\") {\n            const codePath = `extra_files/${currentNavTarget.filePath}`;\n\n            for (const root of Object.values(codeStructure)) {\n                const selected = walkFiles(root, (file) => file.codePath === codePath);\n\n                if (selected) return [selected, null];\n            }\n\n            return [null, null];\n        }\n\n        // The target is now narrowed to CODE.\n        const { codePath, editingPath, topLevelFormClassName } = currentNavTarget;\n\n        const { clientCode, serverCode, assets, scripts } = codeStructure;\n\n        const findMatchingCodePath = (root: RootStructure) => walkFiles(root, (file) => file.codePath === codePath);\n\n        const type = codePath.slice(0, codePath.indexOf(\"/\") - 1) as CodeItemType;\n\n        switch (type) {\n            case \"server_module\":\n                return [findMatchingCodePath(serverCode), null];\n\n            case \"module\":\n                return [findMatchingCodePath(clientCode), null];\n\n            case \"asset\":\n                return [findMatchingCodePath(assets), null];\n\n            case \"form\": {\n                if (!editingPath?.length) {\n                    return [findMatchingCodePath(clientCode), null];\n                }\n\n                const findFormContext = (root: RootStructure | StructureItem): StructureItem | null => {\n                    for (const file of root.children ?? []) {\n                        if (file.name === topLevelFormClassName) return file;\n\n                        const match = findFormContext(file);\n                        if (match) return match;\n                    }\n\n                    return null;\n                };\n\n                return [findMatchingCodePath(clientCode), findFormContext(clientCode)];\n            }\n\n            case \"script\":\n                return [findMatchingCodePath(scripts), null];\n\n            default:\n                return [null, null];\n        }\n    }, [currentNavTarget, codeStructure]);\n\n    return <SelectedFileContext.Provider value={selectedFileValue}>{children}</SelectedFileContext.Provider>;\n};\n\nexport const CodeNav = () => {\n    const user = useSelector(getUser);\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { clientCode, serverCode, assets, scripts } = useSelector(getCodeStructure);\n\n    const renameOnAdd = useRenameOnAddCodeItem();\n\n    const clientContextMenuItems: ContextMenuItems = useCallback((file) => {\n        return [\n            // addFormWithModal actually returns a CodeItemItem rather than the CodeStructure\n            // but the ids match so it's ok for now\n            [\"Add Form\", renameOnAdd(() => dispatch(addFormWithModal(file.fullName))), faPlus],\n            [\"Add Module\", renameOnAdd(() => dispatch(addNew(\"module\", false, file.fullName))), faPlus],\n            [\"Add Package\", renameOnAdd(() => dispatch(addNew(\"module\", true, file.fullName))), faPlus],\n            <hr />,\n            [\"Collapse All\", () => dispatch(collapseAllFiles(\"client\")), faSquareMinus],\n        ];\n    }, []);\n\n    const serverContextMenuItems: ContextMenuItems = useCallback((file) => {\n        return [\n            [\n                \"Add Server Module\",\n                renameOnAdd(() => dispatch(addNew(\"server_module\", false, file.fullName))),\n                faFilePlus,\n            ],\n            [\"Add Server Package\", renameOnAdd(() => dispatch(addNew(\"server_module\", true, file.fullName))), faPlus],\n            <hr />,\n            [\"Collapse All\", () => dispatch(collapseAllFiles(\"server\")), faSquareMinus],\n        ];\n    }, []);\n\n    const scriptContextMenuItems: ContextMenuItems = useCallback((file) => {\n        return [[\"Add Script\", renameOnAdd(() => dispatch(addNew(\"script\", false))), faFilePlus]];\n    }, []);\n\n    const assetContextMenuItems: ContextMenuItems = useCallback((file) => {\n        return [\n            // TODO - the flow of assets might mean renaming during the upload process - so don't automatically rename for now\n            [\"Add Asset\", renameOnAdd(() => dispatch(addAssetWithModal(file.fullName))), faFilePlus],\n            [\"Add Folder\", renameOnAdd(() => dispatch(addNew(\"asset_folder\", true, file.fullName))), faFolderPlus],\n            <hr />,\n            [\"Collapse All\", () => dispatch(collapseAllFiles(\"assets\")), faSquareMinus],\n        ];\n    }, []);\n\n    const showHeaderButton = useShowHeaderButton();\n    return (\n        <div className={\"mb-20\"}>\n            <SelectedFileProvider>\n                <CodeSection\n                    sectionTitle={\"Client Code\"}\n                    files={clientCode}\n                    contextMenuItems={clientContextMenuItems}\n                    defaultMenuFunction={renameOnAdd(() => dispatch(addFormWithModal()))}\n                    defaultMenuOption={\"Add Form\"}\n                    treeType={\"client\"}\n                    showHeaderButton={showHeaderButton}\n                />\n                <CodeSection\n                    sectionTitle={\"Server Code\"}\n                    files={serverCode}\n                    contextMenuItems={serverContextMenuItems}\n                    defaultMenuFunction={renameOnAdd(() => dispatch(addNew(\"server_module\", false)))}\n                    defaultMenuOption={\"Add Server Module\"}\n                    treeType={\"server\"}\n                    showHeaderButton={showHeaderButton}\n                />\n                <CodeSection\n                    sectionTitle={\"Scripts\"}\n                    files={scripts}\n                    contextMenuItems={scriptContextMenuItems}\n                    defaultMenuOption={\"Add Script\"}\n                    defaultMenuFunction={renameOnAdd(() => dispatch(addNew(\"script\", false)))}\n                    treeType={\"scripts\"}\n                    showHeaderButton={showHeaderButton}\n                />\n                <CodeSection\n                    sectionTitle={\"Assets\"}\n                    files={assets}\n                    contextMenuItems={assetContextMenuItems}\n                    defaultMenuFunction={renameOnAdd(() => dispatch(addAssetWithModal()))}\n                    defaultMenuOption={\"Create or upload Asset\"}\n                    treeType={\"assets\"}\n                    showHeaderButton={showHeaderButton}></CodeSection>\n            </SelectedFileProvider>\n            {user?.ab?.[USER_AB_FLAGS.themeSnarfer] && (\n                <div className={\"text-center\"}>\n                    <FileUploader\n                        id={\"snarf-theme\"}\n                        text={\"Snarf a theme:\"}\n                        onChange={(e: any) => dispatch(snarfTheme(e.target.files[0]))}\n                    />\n                </div>\n            )}\n\n            <DependenciesSection />\n        </div>\n    );\n};\n\nconst DependenciesSection = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const expanded = useSelector(getShowDependenciesInCodeNav);\n    const currentTargetType = useNavTargetSelector((t) => t?.type);\n    return (\n        <Section\n            title=\"Dependencies\"\n            useExpander\n            expanded={!!expanded}\n            onToggle={(v: boolean) => dispatch(setCodeNavSectionExpanded(\"dependencies\", v))}>\n            <div className=\"py-3 pl-14\">\n                <SecondaryNavLink\n                    to={{ type: \"APP_DEPENDENCIES\" }}\n                    isSelected={currentTargetType === \"APP_DEPENDENCIES\"}>\n                    App Dependencies\n                </SecondaryNavLink>\n                <SecondaryNavLink\n                    to={{ type: \"PYTHON_DEPENDENCIES\" }}\n                    isSelected={currentTargetType === \"PYTHON_DEPENDENCIES\"}>\n                    Python Dependencies\n                </SecondaryNavLink>\n                <SecondaryNavLink\n                    to={{ type: \"JAVASCRIPT_DEPENDENCIES\" }}\n                    isSelected={currentTargetType === \"JAVASCRIPT_DEPENDENCIES\"}>\n                    JavaScript Dependencies\n                </SecondaryNavLink>\n            </div>\n        </Section>\n    );\n};\n\nexport default CodeNav;\n","import { addCodeItem, generateItemId } from \"@/controllers/app/code\";\nimport { AnvilAsyncAction } from \"@/types\";\n\ninterface Assets {\n    [url: string]: {\n        mime: any;\n        contentType: string;\n        assetName: string;\n        assetUrl: string;\n        substituted?: string;\n    };\n}\n\nexport const snarfTheme: (f: Blob) => AnvilAsyncAction = (f) => async (dispatch, getState, updateState) => {\n    console.log(f);\n    const contents = await f.text();\n    // @ts-ignore\n    const emailjsMimeParser = await import(\"emailjs-mime-parser\");\n    const parse = emailjsMimeParser.default.parse;\n    const mime = parse(contents);\n\n    // Our strategy:\n    // - Each part is going to be an asset\n    // - We need to retain a mapping of asset URLs to names, so we can string-substitute all .html and .css files\n    // - We then generate and upload the assets\n    // - ...and create a new Layout form based on the .html of the first asset.\n\n    // First, map names:\n    const assets: Assets = {};\n\n    for (const node of mime.childNodes) {\n        const url: string = node.headers[\"content-location\"][0].value;\n        const contentType: string = node.headers[\"content-type\"][0]?.value;\n        let assetName = url\n            .replace(/^.*:\\/\\//, \"\")\n            .replace(/:/g, \"_\")\n            .replace(/\\/$/, \"/index.html\");\n        if (contentType === \"text/html\" && !assetName.endsWith(\".html\")) {\n            assetName += \".html\";\n        }\n\n        assets[url] = {\n            mime: node,\n            contentType,\n            assetName,\n            assetUrl: `_/theme/${assetName}`,\n        };\n    }\n\n    const regex = new RegExp(\n        Object.keys(assets)\n            .map((s) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"))\n            .join(\"|\"),\n        \"g\"\n    );\n    const decoder = new TextDecoder(),\n        encoder = new TextEncoder();\n\n    for (const asset of Object.values(assets)) {\n        let contentBin: Uint8Array = asset.mime.content;\n        if (asset.contentType === \"text/html\" || asset.contentType === \"text/css\") {\n            const substituted = decoder.decode(asset.mime.content).replace(regex, (s) => assets[s].assetUrl);\n            contentBin = encoder.encode(substituted);\n        }\n        const base64url: string = await new Promise((r) => {\n            const reader = new FileReader();\n            reader.onload = () => r(reader.result as string);\n            reader.readAsDataURL(new Blob([asset.mime.content]));\n        });\n        const contentB64 = base64url.substring(base64url.indexOf(\",\") + 1);\n        // TODO this will make chaos if there are already assets of those names\n        await dispatch(\n            addCodeItem(`assets/${asset.assetName}`, \"asset\", {\n                name: asset.assetName,\n                id: generateItemId(),\n                content: contentB64,\n            })\n        );\n    }\n\n    // OK, we have assets, now to work out how to save them...\n    console.log(\"Preprocessed assets:\", assets);\n};\n","import { useEffect, useRef } from \"react\";\nimport { ExtraFileStructureItem, TreeType } from \"@/types\";\nimport { useDrop } from \"@/util/dnd\";\n\nexport type ExtraFileDragItem = ExtraFileStructureItem & {\n    treeType: TreeType;\n};\n\ninterface UseExtraFileDropOptions {\n    file: ExtraFileStructureItem;\n    treeType: TreeType;\n    enabled: boolean;\n    setExpanded?: (expanded: boolean) => void;\n    onMove?: (source: ExtraFileStructureItem, destination: ExtraFileStructureItem) => void;\n}\n\nfunction isDirectory(file: ExtraFileStructureItem) {\n    return file.type === \"folder\" || !!file.isPackage;\n}\n\nexport function canDropExtraFile(source: ExtraFileDragItem, destination: ExtraFileStructureItem, treeType: TreeType) {\n    if (source.treeType !== treeType || !isDirectory(destination)) {\n        return false;\n    }\n\n    const sourceParent = source.fullName.slice(0, source.fullName.lastIndexOf(\"/\"));\n\n    return (\n        source.fullName !== destination.fullName &&\n        sourceParent !== destination.fullName &&\n        !destination.fullName.startsWith(`${source.fullName}/`)\n    );\n}\n\nexport function useExtraFileDrop({ file, treeType, enabled, setExpanded, onMove }: UseExtraFileDropOptions) {\n    const expandTimeout = useRef<undefined | number>(undefined);\n\n    const [{ isOver, canDrop }, dropRef] = useDrop({\n        accept: treeType,\n\n        canDrop(source: ExtraFileDragItem) {\n            return enabled && canDropExtraFile(source, file, treeType);\n        },\n\n        onDrop(source: ExtraFileDragItem) {\n            if (enabled) {\n                onMove?.(source, file);\n            }\n        },\n\n        onOverChange({ isOver, canDrop }) {\n            window.clearTimeout(expandTimeout.current);\n\n            if (isOver && canDrop && setExpanded) {\n                expandTimeout.current = window.setTimeout(() => setExpanded(true), 600);\n            }\n        },\n\n        dropEffect: \"move\",\n    });\n\n    useEffect(() => () => window.clearTimeout(expandTimeout.current), []);\n\n    return [{ isOver, canDrop }, dropRef] as const;\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { IconDefinition, faFile, faFolder } from \"@fortawesome/pro-regular-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { sortBy } from \"lodash-es\";\nimport type { NavTarget } from \"@/router/navTypes\";\nimport { cx } from \"@/theme/styles\";\nimport type { ExtraFileStructureItem, TreeType } from \"@/types\";\nimport { useDrag } from \"@/util/dnd\";\nimport { useExternalState } from \"@/util/external-state\";\nimport { useMergeRefs } from \"@/util/hooks\";\nimport { MenuItems } from \"../reusable/DropdownMenu\";\nimport { NavNodeRenamer } from \"../reusable/NavNodeRenamer\";\nimport { fileRenamingIdAtom, useSelectedFileContext } from \"./CodeNav\";\nimport { FileTreeBranch, useFileExpanded } from \"./CodeNavFile\";\nimport { useExtraFileDrop } from \"./ExtraFileTreeDragging\";\nimport { SecondaryNavLink } from \"./SecondaryNavSection\";\n\ninterface ExtraFileTreeRowProps {\n    file: ExtraFileStructureItem;\n    treeType: TreeType;\n    level?: number;\n    getIcon?: (file: ExtraFileStructureItem, expanded: boolean) => IconDefinition;\n    iconCircleClassName?: string | null;\n    reserveExpanderSpace?: boolean;\n    getMenuItems?: (\n        file: ExtraFileStructureItem,\n        options: {\n            onStartRename?: () => void;\n        }\n    ) => MenuItems;\n    onRename?: (file: ExtraFileStructureItem, newName: string) => void;\n    canRenameItem?: (file: ExtraFileStructureItem) => boolean;\n    onMove?: (source: ExtraFileStructureItem, destination: ExtraFileStructureItem) => void;\n    canDragItem?: (file: ExtraFileStructureItem) => boolean;\n}\n\nexport default function ExtraFileTreeRow({\n    file,\n    treeType,\n    level = 0,\n    getIcon,\n    iconCircleClassName,\n    reserveExpanderSpace = true,\n    getMenuItems,\n    onRename,\n    canRenameItem,\n    onMove,\n    canDragItem,\n}: ExtraFileTreeRowProps) {\n    const children = sortBy(\n        (file.children ?? []).filter((child) => child.name !== \".gitkeep\"),\n        [\"name\"]\n    );\n    const hasChildren = children.length > 0;\n\n    const isDirectory = file.type === \"folder\" || !!file.isPackage;\n\n    const [renaming, setRenaming] = useState(false);\n    const canRename = !!onRename && (canRenameItem?.(file) ?? !isDirectory);\n    const filename = file.fullName.split(\"/\").at(-1) ?? file.name;\n\n    const [fileRenamingId, setRenamingId] = useExternalState(fileRenamingIdAtom);\n\n    useEffect(() => {\n        if (!canRename || fileRenamingId !== file.id) return;\n\n        // Match the existing forms tree: begin renaming after the row renders.\n        const timeout = window.setTimeout(() => setRenaming(true));\n\n        return () => window.clearTimeout(timeout);\n    }, [fileRenamingId, file.id, canRename]);\n\n    const onStartRename = canRename ? () => setRenaming(true) : undefined;\n\n    const onConfirmRename = (newName: string) => {\n        setRenaming(false);\n        setRenamingId(null);\n        onRename?.(file, newName);\n    };\n\n    const onCancelRename = () => {\n        setRenaming(false);\n        setRenamingId(null);\n    };\n\n    const [expanded, setExpanded] = useFileExpanded(treeType, file, hasChildren);\n\n    const [selectedFile] = useSelectedFileContext();\n    const icon = getIcon ? getIcon(file, !!expanded) : isDirectory ? faFolder : faFile;\n\n    const selectedPath = selectedFile?.codePath?.startsWith(\"extra_files/\") ? selectedFile.codePath : undefined;\n\n    const isSelected = file.codePath !== undefined && file.codePath === selectedPath;\n\n    const selectedFullName = selectedPath ? selectedFile?.fullName : undefined;\n\n    useEffect(() => {\n        if (isDirectory && selectedFullName?.startsWith(`${file.fullName}/`)) {\n            setExpanded(true);\n        }\n    }, [selectedPath, selectedFullName, file.fullName, isDirectory, setExpanded]);\n\n    useEffect(() => {\n        if (isDirectory && hasChildren && fileRenamingId?.startsWith(`extra_files/${file.fullName}/`)) {\n            setExpanded(true);\n        }\n    }, [fileRenamingId, file.fullName, isDirectory, hasChildren]);\n\n    const target: NavTarget | null = file.codePath\n        ? {\n              type: \"EXTRA_FILE\",\n              filePath: file.codePath.slice(\"extra_files/\".length),\n          }\n        : null;\n\n    const dragItem = useMemo(() => ({ ...file, treeType }), [file, treeType]);\n\n    const canDrag = !!onMove && !renaming && (canDragItem?.(file) ?? true);\n\n    const [{ isDragging }, dragRef] = useDrag({\n        item: dragItem,\n        type: treeType,\n    });\n\n    const [{ isOver, canDrop }, dropRef] = useExtraFileDrop({\n        file,\n        treeType,\n        enabled: !!onMove,\n        setExpanded,\n        onMove,\n    });\n\n    const navLinkRef = useMergeRefs(canDrag ? dragRef : undefined, dropRef);\n\n    const rowMenuItems = !renaming && getMenuItems ? getMenuItems(file, { onStartRename }) : [];\n\n    if (file.name === \".gitkeep\") return null;\n    const extensionStart = filename.lastIndexOf(\".\");\n    const initialSelectionStart =\n        fileRenamingId === file.id && !isDirectory && filename.startsWith(\"test_\") && filename.endsWith(\".py\")\n            ? \"test_\".length\n            : 0;\n    const initialSelectionEnd = !isDirectory && extensionStart > 0 ? extensionStart : undefined;\n\n    return (\n        <FileTreeBranch\n            level={level}\n            expanded={!!expanded}\n            reserveExpanderSpace={reserveExpanderSpace}\n            hasChildren={hasChildren}\n            canHaveChildren={isDirectory}\n            onToggle={() => setExpanded(!expanded)}\n            row={\n                <SecondaryNavLink\n                    ref={navLinkRef}\n                    isSelected={isSelected}\n                    className={cx(\n                        \"flex-grow\",\n                        isDragging && \"opacity-50\",\n                        isOver && canDrop && \"bg-light-bg4! dark:bg-dark-bg4!\"\n                    )}\n                    to={target}\n                    onClickOverrideNav={target ? null : () => setExpanded(!expanded)}\n                    iconCircleClassName={iconCircleClassName}\n                    icon={<FontAwesomeIcon icon={icon} fixedWidth />}\n                    onDoubleClick={() => {\n                        if (!renaming) onStartRename?.();\n                    }}\n                    menuItems={rowMenuItems.length > 0 ? () => rowMenuItems : undefined}>\n                    {renaming ? (\n                        <NavNodeRenamer\n                            className=\"min-w-0 flex-1\"\n                            isSelected={isSelected}\n                            name={filename}\n                            onRename={onConfirmRename}\n                            initialSelectionStart={initialSelectionStart}\n                            initialSelectionEnd={initialSelectionEnd}\n                            onCancel={onCancelRename}\n                            onDoubleClick={(event) => event.stopPropagation()}\n                            onClick={(event) => {\n                                event.preventDefault();\n                                event.stopPropagation();\n                            }}\n                        />\n                    ) : (\n                        <>&nbsp;{file.name}</>\n                    )}\n                </SecondaryNavLink>\n            }>\n            {children.map((child) => (\n                <ExtraFileTreeRow\n                    key={child.id || child.fullName}\n                    file={child}\n                    treeType={treeType}\n                    level={level + 1}\n                    iconCircleClassName={iconCircleClassName}\n                    getIcon={getIcon}\n                    getMenuItems={getMenuItems}\n                    onRename={onRename}\n                    canRenameItem={canRenameItem}\n                    onMove={onMove}\n                    canDragItem={canDragItem}\n                />\n            ))}\n        </FileTreeBranch>\n    );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faFileLines, faPlus } from \"@fortawesome/pro-light-svg-icons\";\nimport {\n    faAlignSlash,\n    faBug,\n    faEye,\n    faFilePlus,\n    faFolderPlus,\n    faGears,\n    faPencil,\n    faPlay,\n    faStop,\n} from \"@fortawesome/pro-solid-svg-icons\";\nimport { sortBy } from \"lodash-es\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { MenuItems } from \"@/components/reusable/DropdownMenu\";\nimport { useFileIconClassGetter } from \"@/components/reusable/IconHooks\";\nimport { CodeSection, SelectedFileProvider, fileRenamingIdAtom } from \"@/components/sidebar/CodeNav\";\nimport { useExtraFileDrop } from \"@/components/sidebar/ExtraFileTreeDragging\";\nimport ExtraFileTreeRow from \"@/components/sidebar/ExtraFileTreeRow\";\nimport { getAppExtraFiles, getAppIsEditable } from \"@/controllers/app\";\nimport { getCodeStructure } from \"@/controllers/app/code\";\nimport {\n    SERVER_TEST_INITIALIZER_PATH,\n    SERVER_TEST_REQUIREMENTS_PATH,\n    SERVER_TEST_ROOT,\n    convertExtraDirectoryToPackage,\n    createExtraDirectory,\n    createExtraFile,\n    createServerTestRequirements,\n    ensureServerTestRoot,\n    getExtraFileContent,\n    getExtraFileEntry,\n    moveExtraFileEntry,\n    renameExtraFile,\n} from \"@/controllers/app/extra-files\";\nimport { openOrFocusBottomTab } from \"@/controllers/bottom-tabs\";\nimport { alert } from \"@/controllers/modals\";\nimport {\n    cancelServerTestRuns,\n    clearDisplayedServerTestResults,\n    deleteFromTestingSuite,\n    getAreServerTestsBusy,\n    getAreServerTestsRunning,\n    getLatestServerTestRun,\n    getServerTestResults,\n    rerunLastServerTests,\n    runServerTests,\n    setSelectedServerTestId,\n} from \"@/controllers/server-tests\";\nimport { getTestingEnabled } from \"@/controllers/services\";\nimport { navigate } from \"@/router/navigation\";\nimport { useNavTargetSelector } from \"@/router/navigation-hooks\";\nimport { makeStyles } from \"@/theme/styles\";\nimport { AnvilDispatch, ExtraFileStructureItem, State } from \"@/types\";\nimport { useExternalState } from \"@/util/external-state\";\nimport { getTestFileIcon } from \"./test-file-icons\";\nimport { getTestRowMenuItems } from \"./test-file-menus\";\n\nconst useStyles = makeStyles()((theme) => ({\n    testingIcon: {\n        background: theme.secondaryNav.icon4.background.toString(),\n        color: theme.secondaryNav.icon4.color.toString(),\n    },\n}));\n\nexport const TestingNav = () => {\n    // py.space imports this component through a cycle with extra-files. Read its constants after module startup.\n    const serverTestRootDropItem: ExtraFileStructureItem = {\n        type: \"folder\",\n        name: \"server_tests\",\n        fullName: SERVER_TEST_ROOT,\n    };\n\n    const testingEnabled = useSelector(getTestingEnabled);\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { classes } = useStyles();\n    const getFileIconClass = useFileIconClassGetter(classes);\n    const testingIconClass = getFileIconClass(\"testing\");\n    const isEditable = useSelector(getAppIsEditable);\n    const latestRun = useSelector(getLatestServerTestRun);\n    const resultMap = useSelector(getServerTestResults);\n    const hasTestResults = Object.values(resultMap).some(({ result }) => result !== undefined);\n    const testsAreRunning = useSelector(getAreServerTestsRunning);\n    const testsAreBusy = useSelector(getAreServerTestsBusy);\n    const extraFiles = useSelector(getAppExtraFiles);\n    const serverTestRoot = getExtraFileEntry(extraFiles, SERVER_TEST_ROOT);\n    const hasServerTestRoot = serverTestRoot !== undefined && typeof serverTestRoot !== \"string\";\n    const [, setRenamingId] = useExternalState(fileRenamingIdAtom);\n\n    useEffect(() => {\n        return () => setRenamingId(null);\n    }, []);\n\n    const requirementsSelected = useNavTargetSelector(\n        (target) => target?.type === \"EXTRA_FILE\" && target.filePath === SERVER_TEST_REQUIREMENTS_PATH\n    );\n\n    const [expandConfig, setExpandConfig] = useState(true);\n\n    const { serverTests } = useSelector(getCodeStructure);\n\n    const hasTestDirectories = serverTests.children.some((file) => file.type === \"folder\" || !!file.isPackage);\n\n    const hasRequirements = useSelector(\n        (state: State) => getExtraFileContent(state, SERVER_TEST_REQUIREMENTS_PATH) !== undefined\n    );\n\n    const hasEmptyRootInitializer = useSelector(\n        (state: State) => getExtraFileContent(state, SERVER_TEST_INITIALIZER_PATH) === \"\"\n    );\n\n    const onMoveTestEntry = async (source: ExtraFileStructureItem, destination: ExtraFileStructureItem) => {\n        try {\n            await dispatch(\n                moveExtraFileEntry(source.fullName, destination.fullName, {\n                    rootPath: SERVER_TEST_ROOT,\n                    treeType: \"serverTests\",\n                })\n            );\n        } catch (error) {\n            await dispatch(\n                alert(\n                    \"Unable to move file\",\n                    error instanceof Error ? error.message : \"The file or directory could not be moved.\"\n                )\n            );\n        }\n    };\n\n    const [rootHeaderDrop, rootHeaderDropRef] = useExtraFileDrop({\n        file: serverTestRootDropItem,\n        treeType: \"serverTests\",\n        enabled: !!(testingEnabled && isEditable && hasServerTestRoot),\n        onMove: onMoveTestEntry,\n    });\n\n    const [rootBodyDrop, rootBodyDropRef] = useExtraFileDrop({\n        file: serverTestRootDropItem,\n        treeType: \"serverTests\",\n        enabled: !!(testingEnabled && isEditable && hasServerTestRoot),\n        onMove: onMoveTestEntry,\n    });\n\n    const highlightRootDrop =\n        (rootHeaderDrop.isOver && rootHeaderDrop.canDrop) || (rootBodyDrop.isOver && rootBodyDrop.canDrop);\n\n    if (!testingEnabled) {\n        return null;\n    }\n\n    const showRunSummary = () => {\n        // Every run from the sidebar shows the summary in the bottom panel, not a previously selected test's result\n        dispatch(setSelectedServerTestId(null));\n        dispatch(openOrFocusBottomTab({ type: \"serverTests\" }));\n    };\n\n    const onRunTestsAtPath = (extraFilePath: string) => {\n        if (testsAreBusy) {\n            return;\n        }\n\n        // Extra-file paths start with tests/, while pytest targets start\n        // with server_tests/.\n        const testTarget = extraFilePath.startsWith(\"tests/\") ? extraFilePath.slice(\"tests/\".length) : extraFilePath;\n\n        showRunSummary();\n\n        dispatch(\n            runServerTests({\n                selection: {\n                    test_targets: [testTarget],\n                },\n            })\n        );\n    };\n\n    const onRunAllTests = () => {\n        showRunSummary();\n        dispatch(runServerTests());\n    };\n\n    const onCancelTests = () => {\n        dispatch(cancelServerTestRuns());\n    };\n\n    const onRerunLastRun = () => {\n        if (!latestRun || testsAreBusy) {\n            return;\n        }\n\n        showRunSummary();\n        dispatch(rerunLastServerTests());\n    };\n\n    const onDiscoverAllTests = () => {\n        if (testsAreBusy) {\n            return;\n        }\n\n        showRunSummary();\n        dispatch(runServerTests({ collect_only: true }));\n    };\n\n    const onClearResults = () => {\n        if (testsAreBusy || !hasTestResults) {\n            return;\n        }\n\n        dispatch(clearDisplayedServerTestResults());\n    };\n\n    const getSuggestedEntryName = (parentPath: string, kind: \"file\" | \"directory\"): string => {\n        const parent = getExtraFileEntry(extraFiles, parentPath);\n\n        const base = kind === \"file\" ? \"test_file\" : \"directory\";\n        const extension = kind === \"file\" ? \".py\" : \"\";\n\n        if (!parent || typeof parent === \"string\") {\n            return `${base}${extension}`;\n        }\n\n        let name = `${base}${extension}`;\n        let number = 2;\n\n        while (Object.hasOwn(parent, name)) {\n            name = `${base}_${number}${extension}`;\n            number++;\n        }\n\n        return name;\n    };\n\n    const onAddEntry = async (parentPath: string, kind: \"file\" | \"directory\") => {\n        if (!isEditable) return;\n\n        const name = getSuggestedEntryName(parentPath, kind);\n\n        try {\n            if (kind === \"file\") {\n                await dispatch(createExtraFile(parentPath, name));\n            } else {\n                dispatch(createExtraDirectory(parentPath, name));\n            }\n            setRenamingId(`extra_files/${parentPath}/${name}`);\n        } catch (error) {\n            await dispatch(\n                alert(\n                    `Unable to create ${kind}`,\n                    error instanceof Error ? error.message : `The ${kind} could not be created.`\n                )\n            );\n        }\n    };\n\n    const onCreateRequirements = async () => {\n        if (!isEditable || !hasServerTestRoot) return;\n\n        try {\n            await dispatch(createServerTestRequirements());\n        } catch (error) {\n            await dispatch(\n                alert(\n                    \"Unable to create requirements.txt\",\n                    error instanceof Error ? error.message : \"The requirements file could not be created.\"\n                )\n            );\n        }\n    };\n\n    const testFilesDropdownItems = (): MenuItems => {\n        const items: MenuItems = [\n            [\n                \"Add file\",\n                () => onAddEntry(SERVER_TEST_ROOT, \"file\"),\n                faFilePlus,\n                { disabled: !isEditable || !hasServerTestRoot },\n            ],\n            [\n                \"Add directory\",\n                () => onAddEntry(SERVER_TEST_ROOT, \"directory\"),\n                faFolderPlus,\n                { disabled: !isEditable || !hasServerTestRoot },\n            ],\n        ];\n\n        if (hasEmptyRootInitializer) {\n            items.push([\n                \"Edit __init__.py\",\n                () =>\n                    dispatch(\n                        navigate({\n                            type: \"EXTRA_FILE\",\n                            filePath: SERVER_TEST_INITIALIZER_PATH,\n                        })\n                    ),\n                faPencil,\n            ]);\n        }\n\n        if (!hasRequirements) {\n            items.push([\n                \"Create requirements.txt\",\n                onCreateRequirements,\n                faFilePlus,\n                { disabled: !isEditable || !hasServerTestRoot },\n            ]);\n        }\n\n        items.push(\n            [\"Discover all server tests\", onDiscoverAllTests, faEye, { disabled: testsAreBusy }],\n            [\"Clear test results\", onClearResults, faAlignSlash, { disabled: testsAreBusy || !hasTestResults }]\n        );\n\n        return items;\n    };\n\n    const configItems = () => {\n        const items: MenuItems = [];\n        items.push([\"Edit Configs\", () => console.log(\"Edit Configs\"), faGears]);\n        return items;\n    };\n\n    const onSetupServerTests = () => {\n        try {\n            dispatch(ensureServerTestRoot());\n        } catch (error) {\n            void dispatch(\n                alert(\n                    \"Unable to set up server tests\",\n                    error instanceof Error ? error.message : \"The server-test directory could not be created.\"\n                )\n            );\n        }\n    };\n\n    return (\n        <div className={\"mb-20\"}>\n            <SelectedFileProvider>\n                <CodeSection\n                    allowRootDrop={false}\n                    rootDropTarget={{\n                        headerRef: rootHeaderDropRef,\n                        bodyRef: rootBodyDropRef,\n                        className: highlightRootDrop ? \"bg-light-bg4! dark:bg-dark-bg4!\" : undefined,\n                    }}\n                    sectionTitle=\"Server Tests\"\n                    files={serverTests}\n                    contextMenuItems={testFilesDropdownItems}\n                    defaultMenuOption={hasServerTestRoot ? \"Add file\" : \"Set up server tests\"}\n                    defaultMenuFunction={\n                        hasServerTestRoot ? () => onAddEntry(SERVER_TEST_ROOT, \"file\") : onSetupServerTests\n                    }\n                    treeType=\"serverTests\"\n                    showHeaderButton={true}\n                    renderFiles={() =>\n                        sortBy(serverTests.children, [\"name\"]).map((file) => (\n                            <ExtraFileTreeRow\n                                key={file.id || file.fullName}\n                                file={file}\n                                treeType=\"serverTests\"\n                                getIcon={getTestFileIcon}\n                                iconCircleClassName={testingIconClass}\n                                reserveExpanderSpace={hasTestDirectories}\n                                getMenuItems={(file, { onStartRename }) =>\n                                    getTestRowMenuItems(file, {\n                                        onRunTests: onRunTestsAtPath,\n                                        testsAreBusy,\n                                        onStartRename,\n                                        onStartAddDirectory: isEditable\n                                            ? () => onAddEntry(file.fullName, \"directory\")\n                                            : undefined,\n                                        onStartAddFile: isEditable\n                                            ? () => onAddEntry(file.fullName, \"file\")\n                                            : undefined,\n                                        onConvertToPackage: (path) => {\n                                            try {\n                                                dispatch(convertExtraDirectoryToPackage(path));\n                                            } catch (error) {\n                                                void dispatch(\n                                                    alert(\n                                                        \"Unable to convert directory\",\n                                                        error instanceof Error\n                                                            ? error.message\n                                                            : \"The directory could not be converted into a package.\"\n                                                    )\n                                                );\n                                            }\n                                        },\n                                        onClearAllTestResults: onClearResults,\n                                        onDiscoverAllTests,\n                                        onDelete: (path) => {\n                                            void dispatch(deleteFromTestingSuite(path));\n                                        },\n                                    })\n                                }\n                                onRename={\n                                    isEditable\n                                        ? async (file, newName) => {\n                                              try {\n                                                  await dispatch(\n                                                      renameExtraFile(file.fullName, newName, {\n                                                          rootPath: SERVER_TEST_ROOT,\n                                                          treeType: \"serverTests\",\n                                                      })\n                                                  );\n                                              } catch (error) {\n                                                  await dispatch(\n                                                      alert(\n                                                          \"Unable to rename file\",\n                                                          error instanceof Error\n                                                              ? error.message\n                                                              : \"The file could not be renamed.\"\n                                                      )\n                                                  );\n                                              }\n                                          }\n                                        : undefined\n                                }\n                                canRenameItem={(file) =>\n                                    file.fullName.startsWith(`${SERVER_TEST_ROOT}/`) &&\n                                    file.fullName !== `${SERVER_TEST_ROOT}/__init__.py` &&\n                                    file.fullName !== SERVER_TEST_REQUIREMENTS_PATH\n                                }\n                                onMove={isEditable ? onMoveTestEntry : undefined}\n                                canDragItem={(file) =>\n                                    file.fullName.startsWith(`${SERVER_TEST_ROOT}/`) &&\n                                    file.fullName !== `${SERVER_TEST_ROOT}/__init__.py` &&\n                                    file.fullName !== SERVER_TEST_REQUIREMENTS_PATH\n                                }\n                            />\n                        ))\n                    }\n                    headerButton={\n                        <Button\n                            size=\"small\"\n                            variant=\"primary\"\n                            icon={testsAreRunning ? faStop : faPlay}\n                            disabled={(!hasServerTestRoot && !testsAreRunning) || (testsAreBusy && !testsAreRunning)}\n                            title={\n                                testsAreRunning\n                                    ? \"Cancel server tests\"\n                                    : testsAreBusy\n                                      ? \"Starting server tests\"\n                                      : !hasServerTestRoot\n                                        ? \"Set up server tests first\"\n                                        : undefined\n                            }\n                            onClick={testsAreRunning ? onCancelTests : onRunAllTests}>\n                            {testsAreRunning ? \"Cancel tests\" : \"Run tests\"}\n                        </Button>\n                    }\n                />\n            </SelectedFileProvider>\n\n            {/* <Section title=\"Test Configurations\" useExpander expanded={expandConfig} onToggle={setExpandConfig}>\n                <div className=\"pt-3 pr-0 pb-3 pl-14\">\n\n                    {hasRequirements ? (\n                        <SecondaryNavLink\n                            icon={faFileLines}\n                            to={{\n                                type: \"EXTRA_FILE\",\n                                filePath: SERVER_TEST_REQUIREMENTS_PATH,\n                            }}\n                            isSelected={requirementsSelected}>\n                            requirements.txt\n                        </SecondaryNavLink>\n                    ) : (\n                        <div className=\"flex w-full items-center justify-center\">\n                            <Button\n                                size=\"small\"\n                                icon={faPlus}\n                                variant=\"primary\"\n                                disabled={!isEditable || !hasServerTestRoot}\n                                onClick={onCreateRequirements}>\n                                Add requirements.txt\n                            </Button>\n                        </div>\n                    )}\n                </div>\n            </Section> */}\n        </div>\n    );\n};\n\nexport default TestingNav;\n","import {\n    faAlignSlash,\n    faBug,\n    faEye,\n    faFilePlus,\n    faFolderGear,\n    faFolderPlus,\n    faPencil,\n    faPlay,\n    faTrashAlt,\n} from \"@fortawesome/pro-solid-svg-icons\";\nimport type { MenuItems } from \"@/components/reusable/DropdownMenu\";\nimport { SERVER_TEST_REQUIREMENTS_PATH, SERVER_TEST_ROOT } from \"@/controllers/app/extra-files\";\nimport type { ExtraFileStructureItem } from \"@/types\";\n\nexport function getTestRowMenuItems(\n    file: ExtraFileStructureItem,\n    options: {\n        onDelete: (path: string) => void;\n        onRunTests?: (path: string) => void;\n        testsAreBusy?: boolean;\n        onStartRename?: () => void;\n        onStartAddDirectory?: () => void;\n        onStartAddFile?: () => void;\n        onConvertToPackage?: (path: string) => void;\n        onDiscoverAllTests: () => void;\n        onClearAllTestResults: () => void;\n    }\n): MenuItems {\n    // const dispatch = useDispatch<AnvilDispatch>();\n    const path = file.fullName;\n\n    if (path === `${SERVER_TEST_ROOT}/__init__.py`) {\n        return [];\n    }\n\n    const filename = path.split(\"/\").at(-1) ?? \"\";\n\n    const isRoot = path === SERVER_TEST_ROOT;\n    const isDirectory = file.type === \"folder\" || !!file.isPackage;\n    const isPlainDirectory = file.type === \"folder\" && !file.isPackage;\n\n    // Todo: Current supported discovery filename convention. Verify with Pete to see what backend conventions will be\n    const isTestFile = /^test_.*\\.py$/.test(filename) || /^.*_test\\.py$/.test(filename);\n\n    const items: MenuItems = [];\n    const canRunTests = isRoot || isDirectory || isTestFile;\n\n    if (canRunTests && options.onRunTests) {\n        const label = isRoot ? \"Run all server tests\" : isDirectory ? \"Run tests in folder\" : \"Run tests in file\";\n\n        items.push([\n            label,\n            () => options.onRunTests?.(path),\n            faPlay,\n            {\n                disabled: options.testsAreBusy,\n            },\n        ]);\n    }\n    if (isRoot) {\n        items.push(\n            [<hr key=\"root-actions\" />],\n            [\n                \"Discover all server tests\",\n                options.onDiscoverAllTests,\n                faEye,\n                {\n                    disabled: options.testsAreBusy,\n                },\n            ]\n        );\n    }\n\n    if (isDirectory) {\n        let added = false;\n        if (options.onStartAddFile) {\n            items.push([\"Add a file\", options.onStartAddFile, faFilePlus]);\n            added = true;\n        }\n\n        if (options.onStartAddDirectory) {\n            items.push([\"Add a directory\", options.onStartAddDirectory, faFolderPlus]);\n            added = true;\n        }\n\n        if (added && !isRoot) items.push(<hr key=\"add-actions\" />);\n    }\n\n    if (isPlainDirectory && options.onConvertToPackage) {\n        items.push(\n            [\"Convert to package\", () => options.onConvertToPackage?.(path), faFolderGear],\n            <hr key=\"convert-action\" />\n        );\n    }\n\n    if (!isRoot && options.onStartRename && path !== SERVER_TEST_REQUIREMENTS_PATH) {\n        items.push([\"Rename...\", options.onStartRename, faPencil]);\n    }\n\n    if (!isRoot && path !== SERVER_TEST_REQUIREMENTS_PATH) {\n        items.push([\"Delete...\", () => options.onDelete(path), faTrashAlt]);\n    }\n\n    return items;\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faPlus } from \"@fortawesome/pro-light-svg-icons/faPlus\";\nimport { faPencil } from \"@fortawesome/pro-light-svg-icons/faPencil\";\nimport { faChevronLeft } from \"@fortawesome/pro-regular-svg-icons\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { Conversation } from \"@/agent/components/Conversation.tsx\";\nimport { ingestAgentSessionUpdate, useAgentAuth, useConversation } from \"@/agent/hooks.ts\";\nimport { AgentChatsLocation, ConversationInfo, ConversationPid } from \"@/agent/types.ts\";\nimport { Button } from \"@/components/reusable/Button.tsx\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { NavNodeRenamer } from \"@/components/reusable/NavNodeRenamer.tsx\";\nimport { DropDownMenuItems, MenuItems } from \"@/components/reusable/DropdownMenu\";\nimport { SecondaryNavLink, Section, useStyles } from \"@/components/sidebar/SecondaryNavSection.tsx\";\nimport {\n    createConversation,\n    deleteConversation,\n    getQueryOptions,\n    openConversation,\n    setAgentChatsLocationAndMoveOpenConversations,\n    activeSidebarConversation,\n    closeSidebarConversation,\n    getConversationListQueryKey,\n    ingestConversationInfoUpdate,\n    getAgentManagementMenuItems,\n    updateConversationInfo,\n} from \"@/controllers/agents.ts\";\nimport { getAppId } from \"@/controllers/app\";\nimport { getBottomPanelCurrentTab } from \"@/controllers/bottom-tabs.ts\";\nimport { getAgentsChatsLocation } from \"@/controllers/ide\";\nimport { alert } from \"@/controllers/modals.ts\";\nimport { useNavTargetSelector } from \"@/router/navigation-hooks.ts\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useExternalStateSelector } from \"@/util/external-state.ts\";\nimport { timeAgoShort } from \"@/util/time.ts\";\nimport useEvent from \"@/util/useEventCallback.ts\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { faDownToLine, faLeftToLine, faTrashCan, faWindowRestore, faCheckCircle } from \"@fortawesome/pro-solid-svg-icons\";\nimport { cx } from \"@/theme/styles\";\nimport { useTooltip } from \"@/components/reusable/Tooltip.tsx\";\nimport { EventCallback, useWebsocketEventListener } from \"@/controllers/websocket.ts\";\nimport { getNavMode } from \"@/controllers/sidebar.ts\";\n\nconst StatusDot = ({ status }: { status: ConversationInfo[\"session_status\"] }) => {\n    const [tooltip, tooltipRef] = useTooltip(status, \"top\");\n\n    return (\n        <>\n            {tooltip}\n            <div\n                ref={tooltipRef}\n                className={cx(\n                    \"h-3 w-3 rounded-full bg-[#6C858E60] mr-2\",\n                    status === \"running\" && \"bg-highlight\",\n                    (status === \"pending\" || status === \"needs_auth_to_continue\" || status === \"needs_auth_to_start\") && \"bg-secondary-400\",\n                    // status === \"stopped\" && \"bg-tertiary\"\n                )}\n            />\n        </>\n    );\n};\n\nexport const SidebarConversation = ({\n    conversationPid,\n}: {\n    conversationPid: ConversationPid;\n}) => {\n    const { conversationInfo, conversation, historyNotice } = useConversation(conversationPid!);\n\n    if (!conversationInfo) {\n        return (\n            <div className={\"bg-primary-50\"}>\n                <LoadingSpinner />\n            </div>\n        );\n    } else {\n        return (\n            <Conversation\n                conversationInfo={conversationInfo}\n                conversation={conversation}\n                historyNotice={historyNotice}\n                isVisible={true}\n                header={\n                    <>\n                        <Button size={\"small\"} className={\"aspect-square rounded-full overflow-hidden h-10! shrink-0\"}\n                            icon={faChevronLeft} onClick={() => { closeSidebarConversation(); }} />\n                        <div className={\"truncate\"}\n                            title={conversationInfo?.title || \"New Chat\"}>{conversationInfo?.title || \"New Chat\"}</div>\n                    </>\n                }\n            />\n        );\n    }\n};\n\nconst CheckedIcon = ({ icon, checked }: any) => {\n    // TODO: This is pretty horrible, but it works for now.\n    return <div className={\"fa-layers\"}>\n        <FontAwesomeIcon fixedWidth icon={icon} />\n        {checked && <FontAwesomeIcon className={\"translate-x-4 -translate-y-3 text-highlight\"} size={\"xs\"} fixedWidth icon={faCheckCircle} />}\n    </div>;\n};\n\ntype RenamingConversation = {\n    conversationPid: ConversationPid;\n    title: string;\n};\n\nconst getConversationTitle = (conversation: Pick<ConversationInfo, \"title\">) => conversation.title || \"New Chat\";\n\nconst useConversationListInteractions = (agentChatsLocation: AgentChatsLocation) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const queryClient = useQueryClient();\n    const appId = useSelector(getAppId)!;\n    const [renamingConversation, setRenamingConversation] = useState<RenamingConversation | null>(null);\n    const pendingSidebarConversationOpen = useRef<number | undefined>(undefined);\n    const pendingRenamePid = useRef<ConversationPid | null>(null);\n\n    const cancelPendingSidebarConversationOpen = useEvent(() => {\n        window.clearTimeout(pendingSidebarConversationOpen.current);\n        pendingSidebarConversationOpen.current = undefined;\n    });\n\n    useEffect(() => cancelPendingSidebarConversationOpen, [agentChatsLocation, cancelPendingSidebarConversationOpen]);\n\n    const openConversationFromList = useEvent((conversationPid: ConversationPid) => {\n        cancelPendingSidebarConversationOpen();\n        if (agentChatsLocation === \"side\") {\n            // Opening a side-located chat replaces the list, so wait long enough to distinguish a double-click rename.\n            pendingSidebarConversationOpen.current = window.setTimeout(() => {\n                pendingSidebarConversationOpen.current = undefined;\n                dispatch(openConversation(conversationPid));\n            }, 250);\n        } else {\n            dispatch(openConversation(conversationPid));\n        }\n    });\n\n    const beginRename = useEvent((conversation: ConversationInfo) => {\n        cancelPendingSidebarConversationOpen();\n        if (pendingRenamePid.current) return;\n        setRenamingConversation({\n            conversationPid: conversation.conversation_pid,\n            title: getConversationTitle(conversation),\n        });\n    });\n\n    const cancelRename = useEvent(() => setRenamingConversation(null));\n\n    const getCachedConversation = (conversationPid: ConversationPid) =>\n        queryClient\n            .getQueryData<ConversationInfo[]>(getConversationListQueryKey(appId))\n            ?.find((conversation) => conversation.conversation_pid === conversationPid);\n\n    const commitRename = useEvent(async (conversation: ConversationInfo, title: string) => {\n        if (pendingRenamePid.current) return;\n        const conversationPid = conversation.conversation_pid;\n        const previousTitle = conversation.title;\n        pendingRenamePid.current = conversationPid;\n        setRenamingConversation(null);\n\n        try {\n            await updateConversationInfo(appId, conversationPid, { title });\n        } catch (e: any) {\n            if (getCachedConversation(conversationPid)?.title === title) {\n                ingestConversationInfoUpdate(appId, conversationPid, { title: previousTitle });\n            }\n            void queryClient.invalidateQueries({ queryKey: getConversationListQueryKey(appId) });\n            await dispatch(alert(\"Failed to rename\", e?.message ?? \"Unable to rename conversation\"));\n\n            const latestConversation = getCachedConversation(conversationPid);\n            setRenamingConversation({\n                conversationPid,\n                title: latestConversation ? getConversationTitle(latestConversation) : previousTitle || \"New Chat\",\n            });\n        } finally {\n            pendingRenamePid.current = null;\n        }\n    });\n\n    return { renamingConversation, beginRename, cancelRename, commitRename, openConversationFromList } as const;\n};\n\nexport const AgentSidebar = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const queryClient = useQueryClient();\n    const appId = useSelector(getAppId)!;\n    const navMode = useSelector(getNavMode);\n\n    const { data: conversations } = useQuery(getQueryOptions(appId));\n    const { data: agentAuth } = useAgentAuth();\n\n    const newConversation = useEvent(() => {\n        dispatch(createConversation());\n    });\n\n    const hasConversations = (conversations?.length || 0) > 0;\n\n    const selectedConversationPid = useNavTargetSelector((t) =>\n        t?.type === \"CONVERSATION\" ? t.conversationPid : undefined\n    );\n    const agentChatsLocation = useSelector(getAgentsChatsLocation);\n    const { renamingConversation, beginRename, cancelRename, commitRename, openConversationFromList } =\n        useConversationListInteractions(agentChatsLocation);\n    const bottomPanelCurrentTab = useSelector(getBottomPanelCurrentTab);\n\n    const sidebarConversation = useExternalStateSelector(activeSidebarConversation, (v) => v);\n\n    const locationContextMenuItems: DropDownMenuItems = () => {\n        const items: MenuItems = [\n            [\"Chat in Sidebar\", () => { dispatch(setAgentChatsLocationAndMoveOpenConversations(\"side\")); }, <CheckedIcon icon={faLeftToLine} checked={agentChatsLocation === \"side\"} />],\n            [\"Chat in Bottom Panel\", () => { dispatch(setAgentChatsLocationAndMoveOpenConversations(\"bottom\")); }, <CheckedIcon icon={faDownToLine} checked={agentChatsLocation === \"bottom\"} />],\n            [\"Chat in Editor Tab\", () => { dispatch(setAgentChatsLocationAndMoveOpenConversations(null)); }, <CheckedIcon icon={faWindowRestore} checked={agentChatsLocation === null} />],\n            <hr />,\n            ...getAgentManagementMenuItems(dispatch, agentAuth),\n        ];\n        return items;\n    };\n\n    const onWsEvent: EventCallback = useEvent((event) => {\n        switch (event.event) {\n            case \"AGENT_SESSION_UPDATE\":\n                ingestAgentSessionUpdate(queryClient, dispatch, appId, event);\n                break;\n        }\n    });\n    useWebsocketEventListener(appId, onWsEvent, undefined, { conversation_session_updates: true });\n\n    const contextMenuItems =\n        (conversation: ConversationInfo): DropDownMenuItems =>\n            () => [\n                [\"Rename...\", () => beginRename(conversation), faPencil],\n                [\"Delete conversation\", () => dispatch(deleteConversation(conversation.conversation_pid)), faTrashCan]\n            ];\n\n    return (\n        <div className={cx(\n            \"flex h-full flex-col pb-16\",\n            sidebarConversation && agentChatsLocation === \"side\" && \"bg-white dark:bg-dark-bg0\"\n        )\n        }>\n            <Section\n                title={\"Chats\"}\n                button={\n                    hasConversations ? <Button size={\"small\"} variant={\"primary\"} icon={faPlus} onClick={newConversation}>\n                        New Chat\n                    </Button> : undefined\n                }\n                menuItems={locationContextMenuItems}\n            >\n\n\n                <div className={\"h-0 grow overflow-y-auto p-4 pr-0 flex flex-col\"}>\n                    {sidebarConversation && agentChatsLocation === \"side\"\n                        ? <div className={cx(\"w-full h-full flex flex-col pr-2\")}>\n                            <SidebarConversation conversationPid={sidebarConversation} />\n                        </div>\n                        : <div className=\"w-full flex flex-col h-full\">\n                            {!hasConversations && <div className={\"text-center pt-12\"}>\n                                <Button variant={\"primary\"} icon={faPlus} onClick={newConversation}>New Chat</Button>\n                            </div>}\n                            {conversations?.map((c) => {\n                                const title = getConversationTitle(c);\n                                const isRenaming = renamingConversation?.conversationPid === c.conversation_pid;\n                                const isBottomSelected =\n                                    bottomPanelCurrentTab?.type === \"agent\" &&\n                                    bottomPanelCurrentTab.conversationPid === c.conversation_pid;\n\n                                const isSideSelected = !!sidebarConversation;\n\n                                const isSelected =\n                                    agentChatsLocation === null\n                                        ? selectedConversationPid === c.conversation_pid\n                                        : agentChatsLocation === \"bottom\"\n                                            ? isBottomSelected\n                                            : isSideSelected;\n\n                                return (\n                                    <SecondaryNavLink\n                                        key={c.conversation_pid}\n                                        to={\n                                            agentChatsLocation === null\n                                                ? ({ type: \"CONVERSATION\", conversationPid: c.conversation_pid } as const)\n                                                : null\n                                        }\n                                        onClickOverrideNav={\n                                            agentChatsLocation === null\n                                                ? null\n                                                : () => {\n                                                    openConversationFromList(c.conversation_pid);\n                                                }\n                                        }\n                                        hideOverlayOnClick={agentChatsLocation !== \"side\"}\n                                        isSelected={isSelected}\n                                        onDoubleClick={() => {\n                                            if (!isRenaming) {\n                                                beginRename(c);\n                                            }\n                                        }}\n                                        menuItems={contextMenuItems(c)}>\n                                        <div className={\"flex flex-row items-center\"}>\n                                            <StatusDot status={c.session_status} />\n                                            {isRenaming ? (\n                                                <NavNodeRenamer\n                                                    className=\"w-0! grow\"\n                                                    isSelected={isSelected}\n                                                    name={renamingConversation.title}\n                                                    onClick={(e) => e.stopPropagation()}\n                                                    onDoubleClick={(e) => e.stopPropagation()}\n                                                    onRename={(newTitle) => commitRename(c, newTitle)}\n                                                    onCancel={cancelRename}\n                                                />\n                                            ) : (\n                                                <div className={\"w-0 grow truncate\"}>{title}</div>\n                                            )}\n                                            <div\n                                                className={cx(\n                                                    \"mr-4 flex items-center justify-center rounded-xl px-2 text-[1.2rem] text-[#6C858E60]\",\n                                                    isSelected && \"text-[#ffffff60]\"\n                                                )\n                                                }>\n                                                <span>{timeAgoShort(new Date(), new Date(c.updated_at))}</span>\n                                            </div>\n                                        </div>\n                                    </SecondaryNavLink>\n                                );\n                            })}\n                            {/*{Object.keys(agentAuth || {}).length > 0*/}\n                            {/*    ? <>*/}\n                            {/*        <div className=\"grow\" />*/}\n                            {/*        <div className=\"flex justify-center w-full\" >*/}\n                            {/*            <LinkInternal*/}\n                            {/*                icon={faLinkSlash}*/}\n                            {/*                onClick={() => dispatch(navigate({ type: \"ACCOUNT\", section: \"AUTHENTICATION\", hash: \"AI\" }))}>*/}\n                            {/*                {\"  \"}Disconnect Agents*/}\n                            {/*            </LinkInternal>*/}\n                            {/*        </div></>*/}\n                            {/*    : null*/}\n                            {/*}*/}\n                        </div>}\n                </div>\n            </Section >\n        </div >\n    );\n};\n","import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from \"react\";\nimport { connect, useSelector } from \"react-redux\";\nimport { faLink } from \"@fortawesome/free-solid-svg-icons/faLink\";\nimport {faInfoCircle, faRetweet} from \"@fortawesome/pro-light-svg-icons\";\nimport { faPencil } from \"@fortawesome/pro-light-svg-icons/faPencil\";\nimport { faPlus } from \"@fortawesome/pro-light-svg-icons/faPlus\";\nimport { faSitemap } from \"@fortawesome/pro-light-svg-icons/faSitemap\";\nimport { faSquare } from \"@fortawesome/pro-light-svg-icons/faSquare\";\nimport { faStar } from \"@fortawesome/pro-light-svg-icons/faStar\";\nimport { faTable } from \"@fortawesome/pro-light-svg-icons/faTable\";\nimport { faTrash } from \"@fortawesome/pro-light-svg-icons/faTrash\";\nimport { faExclamationTriangle } from \"@fortawesome/pro-regular-svg-icons/faExclamationTriangle\";\nimport {\n    faCheck,\n    faCheckSquare,\n    faClockRotateLeft,\n    faClone,\n    faMinus,\n    faUserFriends\n} from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { some, sortBy } from \"lodash-es\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { DbCTA } from \"@/components/reusable/CollapsibleCTA\";\nimport DropdownMenu from \"@/components/reusable/DropdownMenu\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { NavNodeRenamer } from \"@/components/reusable/NavNodeRenamer\";\nimport { ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport UpgradeBadge from \"@/components/reusable/UpgradeBadge\";\nimport { getAppDBSchema, getAppId, getTableMappings } from \"@/controllers/app\";\nimport {\n    createTable,\n    createTableMapping,\n    deleteTable,\n    deleteTableMapping,\n    getAppAccessibleTableMappings,\n    getDebugEnvironmentTableMapping,\n    getSharedTableCounts,\n    getTablesInUnrestrictedMappings,\n    reloadTableMapping,\n    removeTableMapping,\n    renameTable,\n    renameTableMapping,\n    setTableMappingRestricted,\n} from \"@/controllers/db\";\nimport {\n    checkForStagingDatabases,\n    getCategorisedEnvironments,\n    isSavedEnvironment,\n    saveEnvironment,\n    setCurrentTableMapping,\n} from \"@/controllers/environments\";\nimport { getDeploymentPools, getExpandedTableMappings, getUser, updateExpandedMappings } from \"@/controllers/ide\";\nimport { getIDETasks } from \"@/controllers/ide_tasks\";\nimport type { IDETask } from \"@/controllers/ide_tasks\";\nimport { alert, confirm, confirmWithCheckBox, modal } from \"@/controllers/modals\";\nimport { getRunMode } from \"@/controllers/runner\";\nimport { getSecondaryNavWidth, hideIfOverlay } from \"@/controllers/sidebar\";\nimport { claimAchievement, getUserUiScale, updateCtaKey } from \"@/controllers/user\";\nimport type { NavTarget } from \"@/router/navTypes\";\nimport { navigate } from \"@/router/navigation\";\nimport { useNavTargetSelector } from \"@/router/navigation-hooks\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport { getFeatureSupport } from \"@/util/features\";\nimport { useResizeObserver, useStateWithReset } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { SecondaryNavAlert, SecondaryNavLink, Section } from \"./SecondaryNavSection\";\n\ntype DatabaseMapping = NonNullable<ReturnType<typeof getTableMappings>>[number] & {\n    clone?: { task?: number; error?: string; complete?: boolean };\n    deployment_pool?: string | null;\n};\ntype DatabaseTable = DatabaseMapping[\"tables\"][number];\ntype AppId = ReturnType<typeof getAppId>;\ntype LooseIDETask = Omit<IDETask, \"type\"> & {\n    type?: string;\n    app_ids?: AppId[];\n};\n\nconst useStyles = makeStyles()((theme) => ({\n    tableMapping: {\n        padding: \"1.2rem\",\n        paddingRight: 0,\n    },\n    table: {\n        height: theme.secondaryNav.linkHeight,\n        display: \"flex\",\n        alignItems: \"center\",\n        padding: \"0 0.6rem\",\n        \"&:hover\": {\n            background: theme.palette.bg1.hex(),\n        },\n    },\n    selectedTable: {\n        backgroundColor: theme.hl1.alpha(0.15).toString(),\n        \"&:hover\": {\n            background: theme.hl1.alpha(0.15).toString(),\n        },\n    },\n    tableRenamer: {\n        flexGrow: 1,\n    },\n    sharedTableIndicator: {\n        color: theme.primary.hex(),\n    },\n    editMappingButton: {\n        margin: \"0 0.8rem\",\n        color: theme.palette.fg1.alpha(0.2).toString(),\n        \"&:hover\": {\n            color: theme.palette.fg1.hex(),\n        },\n    },\n    shortcutRow: {\n        whiteSpace: \"nowrap\",\n    },\n\n    dropdownAnchor: {\n        position: \"absolute\",\n        left: -2,\n        bottom: -2,\n    },\n    syncIconContainer: {\n        padding: \"0 0.5rem\",\n        borderRadius: \"3px\",\n        marginLeft: 12,\n        display: \"inline-block\",\n        // background: \"cyan\",\n        \"&:hover\": {\n            background: theme.palette.bg3.toString(),\n        },\n    },\n    syncIcon: {\n        color: theme.palette.secondary.toString(),\n    },\n    inSync: {\n        color: theme.palette.highlight.toString(),\n    },\n}));\n\nconst tableMappingConnector = connect((state: State) => ({\n    appId: getAppId(state),\n    environments: getCategorisedEnvironments(state),\n    user: getUser(state),\n    supportsDirectSqlAccess: getFeatureSupport(state, \"direct-sql-access\"),\n    supportsMultipleDatabases: getFeatureSupport(state, \"multiple-databases\"),\n    accessibleTableMappings: getAppAccessibleTableMappings(state),\n    expandedTableMappings: getExpandedTableMappings(state),\n    runMode: getRunMode(state),\n    allowRestrictedTableMappingUpdates: !!state.app?.allow_restricted_table_mapping_updates,\n}));\n\ntype DatabaseMappingWithMismatch = DatabaseMapping & {\n    schemaMismatch: boolean;\n    indexMismatch: boolean;\n};\n\ninterface TableMappingOwnProps {\n    mapping: DatabaseMappingWithMismatch;\n    isSelected: boolean;\n    onSelect(): void;\n    showHeaderButton: boolean;\n    shared: boolean;\n    sharedTables: Record<number, number>;\n}\n\ntype TableMappingProps = AnvilConnectedProps<typeof tableMappingConnector> & TableMappingOwnProps;\n\nconst SharedTableIndicator = ({ warning }: { warning: boolean }) => {\n    const { classes } = useStyles();\n    const [tooltip, anchor] = useTooltip(\n        warning\n            ? \"This table is shared with an unrestricted database.\"\n            : \"This table is shared with other databases.\",\n        \"right\"\n    );\n    return (\n        <span ref={anchor}>\n            <FontAwesomeIcon\n                icon={warning ? faExclamationTriangle : faLink}\n                className={warning ? \"text-danger\" : classes.sharedTableIndicator}\n                fixedWidth={true}\n                transform={{ x: 8, y: -8, size: 11 }}\n            />\n            {tooltip}\n        </span>\n    );\n};\n\nconst TableMapping = tableMappingConnector((props: TableMappingProps) => {\n    const {\n        appId,\n        mapping,\n        environments,\n        isSelected,\n        onSelect,\n        dispatch,\n        showHeaderButton,\n        user,\n        supportsDirectSqlAccess,\n        supportsMultipleDatabases,\n        shared,\n        sharedTables,\n        accessibleTableMappings,\n        expandedTableMappings,\n        runMode,\n        allowRestrictedTableMappingUpdates,\n    } = props;\n\n    const { classes } = useStyles();\n    const tablesInUnrestrictedMappings = useSelector(getTablesInUnrestrictedMappings);\n    const tooltipText = useMemo(() => {\n        const apps = accessibleTableMappings?.find(\n            (m) => m.table_mapping_id === mapping.table_mapping_id && !!appId && Object.keys(m.apps).includes(appId)\n        )?.apps;\n        return Object.values(apps || {}).join(\", \");\n    }, [accessibleTableMappings, appId]);\n\n    const isDebug = environments.debug.table_mapping_id === mapping.table_mapping_id;\n\n    const deploymentPools = useSelector(getDeploymentPools);\n    const dpPoolName = useMemo(() => {\n        if (mapping.deployment_pool) {\n            const p = deploymentPools?.find((dp) => dp.dp_id === mapping.deployment_pool);\n            return p?.info?.title ?? mapping.deployment_pool;\n        }\n    }, [deploymentPools, mapping.deployment_pool]);\n\n    const [sharedToolTip, sharedAnchor] = useTooltip(`Shared with ${tooltipText}`, \"right\");\n    const [inSyncToolTip, syncAnchor] = useTooltip(`App and database schemas are in sync`, \"right\");\n    const [outOfSyncToolTip, outSyncAnchor] = useTooltip(`Resolve schema mismatch...`, \"right\");\n    const [devDbTooltip, devDbAnchorRef] = useTooltip(\"Development database\", \"right\");\n    const [deploymentPoolTooltip, deploymentPoolAnchorRef] = useTooltip(\n        `Stored in the \"${dpPoolName}\" deployment pool`,\n        \"right\"\n    );\n\n    const ideTasks = useSelector(getIDETasks);\n    const cloneStatus = useMemo(() => {\n        const cloneTask = mapping.clone?.task != null ? ideTasks[mapping.clone.task] : undefined;\n        const looseIdeTasks = Object.values(ideTasks) as LooseIDETask[];\n        const appCloneTask =\n            cloneTask ?? looseIdeTasks.find((t) => t.type === \"app-clone\" && !!appId && t.app_ids?.includes(appId));\n        return {\n            show: !!appCloneTask,\n            error: appCloneTask?.error ?? mapping.clone?.error,\n            complete: appCloneTask?.completed || mapping.clone?.complete,\n            running: appCloneTask && !appCloneTask.completed && !appCloneTask.error && appCloneTask.state,\n        };\n    }, [ideTasks, mapping, appId]);\n\n    // Database Restores require a reload after completion\n    const closeStatusWasComplete = useRef(cloneStatus.complete);\n    useEffect(() => {\n        if (cloneStatus.complete && !closeStatusWasComplete.current) {\n            dispatch(reloadTableMapping(mapping.table_mapping_id));\n            closeStatusWasComplete.current = cloneStatus.complete;\n        }\n    }, [cloneStatus.complete, mapping.table_mapping_id]);\n\n    const showSyncStatus = !cloneStatus.running;\n\n    // This tooltip is used for both Clone and Restore. TODO: We should make the text more specific.\n    const [cloneStatusTooltip, cloneStatusAnchorRef] = useTooltip(\n        cloneStatus.running\n            ? cloneStatus.running.message || `Cloning: Copied ${cloneStatus.running.rows} rows so far`\n            : cloneStatus.error\n                ? `Cloning failed: ${cloneStatus.error}`\n                : \"Cloning complete\",\n        \"right\"\n    );\n\n    const [renamingTableId, setRenamingTableId] = useState<number | null>(null);\n    const [inFlightTableRenames, setInFlightTableRenames] = useState<Record<number, string>>({}); // So we display the new name immediately.\n\n    const tables = useMemo(() => sortBy(mapping?.tables || [], [\"name\"]), [mapping?.tables]);\n\n    const addTable = useCallback(async () => {\n        const name = `Table ${(tables.length || 0) + 1}`;\n        const newTable = (await dispatch(createTable(mapping.table_mapping_id, name))) as DatabaseTable;\n        dispatch(navigate({ type: \"DB_TABLE\", tableMappingId: mapping.table_mapping_id, tableId: newTable.id }));\n        setRenamingTableId(newTable.id);\n        dispatch(updateCtaKey(\"db\", true));\n        dispatch(claimAchievement(\"addedDataTable\"));\n    }, [mapping]);\n\n    const onRenameTable = useCallback(\n        async (table: DatabaseTable, newName: string) => {\n            setRenamingTableId(null);\n            setInFlightTableRenames((rs) => ({ ...rs, [table.id]: newName }));\n            await dispatch(renameTable(mapping, table, newName));\n            setInFlightTableRenames(({ [table.id]: _removed, ...rest }) => rest);\n        },\n        [mapping]\n    );\n\n    const onDeleteTable = useEvent(async (table: DatabaseTable, isSharedTable: boolean) => {\n        const action = isSharedTable ? \"Remove\" : \"Delete\";\n        const title = `${action} ${table.name}?`;\n        const msg = isSharedTable\n            ? \"This table is shared with other databases. Are you sure you wish to remove it from this database? This will not delete the table or its data.\"\n            : \"Are you sure you wish to delete this table and its data? This operation cannot be undone.\";\n        const confirmMessage = `Yes, I want to ${action.toLowerCase()} this table`;\n        if (await dispatch(confirmWithCheckBox(title, msg, confirmMessage, \"Delete\", \"Cancel\"))) {\n            await dispatch(deleteTable(mapping, table));\n        }\n    });\n\n    const contextMenuItems = useMemo(\n        () => (table: DatabaseTable) => {\n            const items: Array<[string, () => void]> = [];\n            const isSharedTable = sharedTables?.[table.id] > 1;\n            items.push([\"Rename...\", () => setRenamingTableId(table.id)]);\n            items.push([\n                `${isSharedTable ? \"Remove\" : \"Delete\"} table '${table.name}'`,\n                () => onDeleteTable(table, isSharedTable),\n            ]);\n            return () => items;\n        },\n        [sharedTables, onDeleteTable]\n    );\n\n    const [renaming, setRenaming] = useState(false);\n    const [nameBuffer, setNameBuffer] = useStateWithReset(mapping.name);\n    const renamerRef = useRef<HTMLInputElement | null>(null);\n    const [restricted, setRestricted] = useStateWithReset(!!mapping.restricted);\n\n    const onRestrictedChange = useEvent(async (newRestricted: boolean) => {\n        setRestricted(newRestricted);\n        try {\n            await dispatch(setTableMappingRestricted(mapping, newRestricted));\n        } catch (error) {\n            setRestricted(!newRestricted);\n            throw error;\n        }\n    });\n\n    const finishEditingMappingName = useCallback(\n        async (cancel?: boolean) => {\n            setRenaming(false);\n            if (cancel) {\n                setNameBuffer(mapping.name);\n            } else if (nameBuffer !== mapping.name) {\n                await dispatch(renameTableMapping(mapping, nameBuffer));\n            }\n        },\n        [mapping, nameBuffer]\n    );\n\n    useEffect(() => {\n        if (renaming && renamerRef.current) {\n            renamerRef.current.focus();\n            renamerRef.current.select();\n        }\n    }, [renaming]);\n\n    const onRemove = useCallback(async () => {\n        const inUse = some(environments.named, (env) => env.table_mapping_id === mapping.table_mapping_id);\n        if (inUse) {\n            await dispatch(\n                alert(\n                    \"Database in use\",\n                    \"This database cannot be deleted - it is in use in one or more of your deployed environments. To delete this database, make sure it is not in use.\"\n                )\n            );\n        } else if (\n            await dispatch(\n                confirm(\n                    \"Remove database?\",\n                    \"Are you sure you want to remove this database from this app? Other apps this database is shared with will continue to have access.\"\n                )\n            )\n        ) {\n            const removed = await dispatch(removeTableMapping(mapping));\n            if (\"success\" in removed && removed.success) {\n                if (isDebug && environments.debug) {\n                    dispatch(saveEnvironment(environments.debug, { table_mapping_id: null }));\n                }\n            } else {\n                dispatch(alert(\"Unable to Remove database\", \"Please contact support@anvil.works\"));\n            }\n        }\n    }, [mapping, environments]);\n\n    const onDelete = useCallback(async () => {\n        const inUse = some(environments.named, (env) => env.table_mapping_id === mapping.table_mapping_id);\n        if (inUse) {\n            await dispatch(\n                alert(\n                    \"Database in use\",\n                    \"This database cannot be deleted - it is in use in one or more of your deployed environments. To delete this database, make sure it is not in use.\"\n                )\n            );\n        } else if (\n            await dispatch(\n                confirmWithCheckBox(\n                    \"Delete database?\",\n                    \"This action will permanently delete this database\",\n                    \"Are you sure you wish to continue?\",\n                    \"Delete\",\n                    \"Cancel\"\n                )\n            )\n        ) {\n            await doDelete();\n        }\n    }, [mapping, environments]);\n\n    const doDelete = useCallback(async () => {\n        const deleted = await dispatch(deleteTableMapping(mapping));\n        if (\"success\" in deleted && deleted.success) {\n            if (isDebug && environments.debug) {\n                dispatch(saveEnvironment(environments.debug, { table_mapping_id: null }));\n            }\n        } else {\n            dispatch(alert(\"Unable to Delete database\", \"Please contact support@anvil.works\"));\n        }\n    }, [mapping, environments]);\n\n    const [expanded, setExpanded] = useReducer(\n        (_prev, val) => {\n            const id = mapping.table_mapping_id === null ? \"default\" : `${mapping.table_mapping_id}`;\n            if (val || expandedTableMappings?.[id]) {\n                dispatch(updateExpandedMappings(id, val));\n            }\n            return val;\n        },\n        false,\n        () => {\n            if (isDebug) {\n                return true;\n            }\n            return !!expandedTableMappings?.[mapping.table_mapping_id || \"default\"];\n        }\n    );\n\n    const openSQLAccessModal = useCallback(\n        async (mapping: DatabaseMapping) => {\n            if (supportsDirectSqlAccess) {\n                await dispatch(modal(\"directSQLAccess\", { mapping }));\n            } else {\n                dispatch(modal(\"upgradePrompt\", { featureId: \"direct-sql-access\" }));\n            }\n        },\n        [supportsDirectSqlAccess]\n    );\n\n    const openAddExistingTableModal = useCallback(() => {\n        dispatch(\n            modal(\"addExistingTable\", { tableMapping: mapping, addNewTable: addTable })\n        );\n    }, [mapping, addTable]);\n\n    const selectedTableId = useNavTargetSelector((t) =>\n        t?.type === \"DB_TABLE\" && t.tableMappingId === mapping.table_mapping_id ? t.tableId : undefined\n    );\n\n    const onOpenCloneDBModal = useEvent(async (mapping: DatabaseMapping) => {\n        if (supportsMultipleDatabases) {\n            await dispatch(modal(\"cloneDatabase\", { mapping }));\n        } else {\n            dispatch(modal(\"upgradePrompt\", { featureId: \"multiple-databases\" }));\n        }\n    });\n\n    const onOpenRestoreDBModal = useEvent(async (mapping: DatabaseMapping) => {\n        if (supportsMultipleDatabases) {\n            await dispatch(modal(\"restoreDatabase\", { mapping }));\n        } else {\n            dispatch(modal(\"upgradePrompt\", { featureId: \"multiple-databases\" }));\n        }\n    });\n\n    return (\n        <Section\n            title={\n                renaming ? (\n                    <ContentTextInput\n                        className={\"h-14!\"}\n                        ref={renamerRef}\n                        value={nameBuffer}\n                        onChange={(e) => setNameBuffer(e.target.value)}\n                        onBlur={(e) => finishEditingMappingName()}\n                        onKeyDown={(e) =>\n                            e.key === \"Enter\"\n                                ? finishEditingMappingName()\n                                : e.key === \"Escape\"\n                                  ? finishEditingMappingName(true)\n                                  : undefined\n                        }\n                    />\n                ) : (\n                    <div className={\"flex w-full items-center justify-start\"}>\n                        <div className={\"min-w-5 shrink overflow-hidden text-ellipsis whitespace-nowrap\"}>\n                            {mapping.name}\n                        </div>\n                        {restricted && (\n                            <div className=\"ml-2 inline-flex rounded-full border border-danger px-2 pt-0.5 text-sm font-semibold text-danger\">\n                                Restricted\n                            </div>\n                        )}\n                        {shared && (\n                            <div className={\"flex-none\"} ref={sharedAnchor}>\n                                <FontAwesomeIcon className={\"ml-3\"} icon={faUserFriends} />\n                                {sharedToolTip}\n                            </div>\n                        )}\n                        {cloneStatus.show && (\n                            <div className={\"ml-3\"} ref={cloneStatusAnchorRef}>\n                                {cloneStatus.running ? (\n                                    <div style={{ margin: \"-.4rem 0.8rem 0\", transform: \"scale(0.2)\" }}>\n                                        <LoadingSpinner />\n                                    </div>\n                                ) : (\n                                    <FontAwesomeIcon icon={cloneStatus.error ? faExclamationTriangle : faCheck} />\n                                )}\n                                {cloneStatusTooltip}\n                            </div>\n                        )}\n                        <div\n                            ref={outSyncAnchor}\n                            className={cx(\"flex-none\", showSyncStatus && mapping.schemaMismatch ? \"\" : \"hidden\")}>\n                            <Button\n                                className={\"ml-3\"}\n                                variant=\"hidden\"\n                                size={\"small\"}\n                                linkStyle={{ fontSize: \"1.4rem\" }}\n                                onClick={() =>\n                                    dispatch(navigate({ type: \"APP_SCHEMA\", tableMappingId: mapping.table_mapping_id }))\n                                }>\n                                <FontAwesomeIcon className={cx(classes.syncIcon)} icon={faExclamationTriangle} />\n                            </Button>\n                            {outOfSyncToolTip}\n                        </div>\n                        <div\n                            ref={syncAnchor}\n                            className={cx(\"flex-none\", showSyncStatus && !mapping.schemaMismatch ? \"\" : \"hidden\")}>\n                            <Button\n                                className={\"ml-3\"}\n                                variant=\"hidden\"\n                                size={\"small\"}\n                                linkStyle={{ fontSize: \"1.4rem\" }}\n                                onClick={() =>\n                                    dispatch(navigate({ type: \"APP_SCHEMA\", tableMappingId: mapping.table_mapping_id }))\n                                }>\n                                <FontAwesomeIcon className={cx(classes.syncIcon, classes.inSync)} icon={faCheck} />\n                            </Button>\n                            {inSyncToolTip}\n                        </div>\n                        {isSelected && (\n                            <div\n                                className={\n                                    \"mr-1 ml-3 shrink overflow-hidden rounded bg-zinc-200 px-2 text-base font-semibold text-ellipsis whitespace-nowrap text-stone-600 uppercase\"\n                                }\n                                ref={devDbAnchorRef}>\n                                DEBUG\n                            </div>\n                        )}\n                        {isSelected && devDbTooltip}\n                        {mapping.deployment_pool && (\n                            <div\n                                className={\n                                    \"mr-1 ml-3 shrink overflow-hidden rounded bg-zinc-400 px-2 text-base font-semibold text-ellipsis whitespace-nowrap text-stone-100 uppercase\"\n                                }\n                                ref={deploymentPoolAnchorRef}>\n                                {dpPoolName}\n                                {deploymentPoolTooltip}\n                            </div>\n                        )}\n                    </div>\n                )\n            }\n            expanded={expanded}\n            useExpander={true}\n            onToggle={setExpanded}\n            button={\n                !!tables.length &&\n                showHeaderButton && (\n                    <DropdownMenu\n                        onSelectItem={(select) => select}\n                        render={(showMenu, anchor) => (\n                            <Button size={\"small\"} icon={faPlus} onClick={(e) => showMenu(null, e.currentTarget)}>\n                                Add Table\n                                <div className={cx(classes.dropdownAnchor)}>{anchor}</div>\n                            </Button>\n                        )}\n                        items={(selectItem, hideMenu) => [\n                            [\"Add New Table\", addTable],\n                            [\"Add Existing Table…\", openAddExistingTableModal],\n                        ]}\n                        align={\"left\"}\n                    />\n                )\n            }\n            menuItems={() => [\n                !isSelected && [\n                    \"Use when debugging\",\n                    onSelect,\n                    faStar,\n                ],\n                [\n                    <>\n                        Direct SQL Access&hellip;{\" \"}\n                        <UpgradeBadge feature={\"direct-sql-access\"} />\n                    </>,\n                    () => openSQLAccessModal(mapping),\n                    faRetweet,\n                ],\n                [\n                    <>\n                        Clone Database&hellip;{\" \"}\n                        <UpgradeBadge feature={\"multiple-databases\"} />\n                    </>,\n                    () => onOpenCloneDBModal(mapping),\n                    faClone,\n                ],\n                user.ideConfig.enableDbRestore && [\n                    <>\n                        Restore to Previous Version&hellip;{\" \"}\n                        <UpgradeBadge feature={\"multiple-databases\"} />\n                    </>,\n                    () => onOpenRestoreDBModal(mapping),\n                    faClockRotateLeft,\n                ],\n                [\"Add New Table\", addTable, faPlus],\n                [\"Add Existing Table…\", openAddExistingTableModal, faPlus],\n                // We currently can't rename or delete the default database. This is going to annoy some power users.\n                mapping.table_mapping_id && [\"Rename Database...\", () => setRenaming(true), faPencil],\n                shared &&\n                    mapping.table_mapping_id && [\n                        \"Remove Database…\",\n                        onRemove,\n                        faMinus,\n                    ],\n                !shared &&\n                    mapping.table_mapping_id && [\n                        \"Delete Database…\",\n                        onDelete,\n                        faTrash,\n                    ],\n                allowRestrictedTableMappingUpdates && mapping.table_mapping_id !== null && <hr />,\n                allowRestrictedTableMappingUpdates &&\n                    mapping.table_mapping_id !== null && [\n                        \"Restrict access\",\n                        () => onRestrictedChange(!restricted),\n                        restricted ? faCheckSquare : faSquare,\n                    ],\n            ]}>\n            <ul className={classes.tableMapping}>\n                {tables.map((t) => {\n                    const isRenaming = renamingTableId === t.id;\n                    const navTarget = {\n                        type: \"DB_TABLE\",\n                        tableId: t.id,\n                        tableMappingId: mapping.table_mapping_id,\n                    } as const;\n                    return (\n                        <SecondaryNavLink\n                            isSelected={selectedTableId === t.id}\n                            key={`table-${t.id}`}\n                            to={navTarget}\n                            onDoubleClick={() => !isRenaming && setRenamingTableId(t.id)}\n                            menuItems={contextMenuItems(t)}\n                            icon={\n                                <div className={\"fa-layers\"}>\n                                    <FontAwesomeIcon icon={faTable} fixedWidth={true} />\n                                    {sharedTables?.[t.id] > 1 && (\n                                        <SharedTableIndicator warning={restricted && tablesInUnrestrictedMappings.has(t.id)} />\n                                    )}\n                                </div>\n                            }>\n                            {renamingTableId === t.id ? (\n                                <NavNodeRenamer\n                                    className={classes.tableRenamer}\n                                    isSelected={selectedTableId === t.id}\n                                    name={t.name}\n                                    onRename={(n) => onRenameTable(t, n)}\n                                    onCancel={() => setRenamingTableId(null)}\n                                />\n                            ) : (\n                                inFlightTableRenames[t.id] || t.name || <>&nbsp;</>\n                            )}\n                        </SecondaryNavLink>\n                    );\n                })}\n\n                <div style={{ textAlign: \"center\", marginTop: \"1em\" }}>\n                    <Button size={\"small\"} variant={\"primary\"} icon={faPlus} onClick={addTable}>\n                        Add New Table\n                    </Button>\n                </div>\n            </ul>\n\n            {showSyncStatus &&\n                (mapping.schemaMismatch\n                    ? <SecondaryNavAlert\n                        title={\"Schema Mismatch\"}\n                        body={\"Your app is expecting a schema that does not match this database.\"}\n                        actions={\n                            <Button\n                                size={\"small\"}\n                                onClick={() => {\n                                    dispatch(hideIfOverlay());\n                                    dispatch(navigate({ type: \"APP_SCHEMA\", tableMappingId: mapping.table_mapping_id }));\n                                }}>\n                                Resolve...\n                            </Button>\n                        }\n                    />\n                    : (mapping.indexMismatch\n                        ? <SecondaryNavAlert\n                            title={\"Indexes out of sync\"}\n                            body={\"Review DB indexes required by your app.\"}\n                            icon={faInfoCircle}\n                            actions={\n                                <Button\n                                    size={\"small\"}\n                                    onClick={() => {\n                                        dispatch(hideIfOverlay());\n                                        dispatch(navigate({ type: \"APP_SCHEMA\", tableMappingId: mapping.table_mapping_id }));\n                                    }}>\n                                    Review...\n                                </Button>\n                            }\n                        />\n                        : null))}\n\n        </Section>\n    );\n});\n\nconst databaseNavConnector = connect((state: State) => ({\n    appId: getAppId(state),\n    appSchema: getAppDBSchema(state),\n    tableMappings: getTableMappings(state),\n    currentTableMapping: getDebugEnvironmentTableMapping(state),\n    debugEnvironment: getCategorisedEnvironments(state).debug,\n    supportsMultipleDatabases: getFeatureSupport(state, \"multiple-databases\"),\n    secondaryNavWidth: getSecondaryNavWidth(state),\n    scale: getUserUiScale(state),\n    accessibleTableMappings: getAppAccessibleTableMappings(state),\n    sharedTables: getSharedTableCounts(state),\n    runMode: getRunMode(state),\n    deploymentPools: getDeploymentPools(state),\n}));\n\ntype DatabaseNavProps = AnvilConnectedProps<typeof databaseNavConnector>;\n\nconst DatabaseNav = ({\n    appId,\n    appSchema,\n    tableMappings,\n    currentTableMapping,\n    debugEnvironment,\n    supportsMultipleDatabases,\n    dispatch,\n    secondaryNavWidth,\n    scale,\n    accessibleTableMappings,\n    sharedTables,\n    runMode,\n    deploymentPools,\n}: DatabaseNavProps) => {\n    const { classes } = useStyles();\n\n    // Trigger an app tables refresh, in case anything has changed since we were last here\n    useEffect(() => {\n        if (appId) {\n            //dispatch(loadDataTables(appId));\n        }\n    }, [appId]);\n\n    const chooseEnvironmentMapping = useCallback(\n        async (tableMapping: DatabaseMapping) => {\n            dispatch(setCurrentTableMapping(tableMapping));\n            dispatch(checkForStagingDatabases());\n        },\n        [debugEnvironment, currentTableMapping]\n    );\n\n    const createNew = async () => {\n        if (supportsMultipleDatabases) {\n            // Try saving the environment first, in case we don't want to migrate\n            const saved = await dispatch(saveEnvironment(debugEnvironment));\n            if (isSavedEnvironment(saved)) {\n                // The environment saved just fine - we might even have migrated the app.\n                const baseName = \"New Database\";\n\n                let idx = 1;\n                let proposedName = baseName;\n                while (tableMappings?.find((t) => t.name === proposedName)) {\n                    proposedName = `${baseName} ${++idx}`;\n                }\n                if (deploymentPools && deploymentPools.length > 0) {\n                    const newMapping = (await dispatch(\n                        modal(\"createNewDatabaseInPool\", {\n                            proposedName,\n                        })\n                    )) as DatabaseMapping | null;\n                    if (newMapping) {\n                        await chooseEnvironmentMapping(newMapping);\n                    }\n                } else {\n                    const newMapping = (await dispatch(createTableMapping(proposedName))) as DatabaseMapping;\n                    await chooseEnvironmentMapping(newMapping);\n                }\n            }\n        } else {\n            dispatch(modal(\"upgradePrompt\", { featureId: \"multiple-databases\" }));\n        }\n    };\n\n    const [showHeaderButton, setShowHeaderButton] = useState(false);\n    const widthTest = useRef<HTMLDivElement | null>(null);\n\n    const checkPanelWidth = useEvent(() => {\n        let minWidth;\n        switch (scale) {\n            case \"tiny\":\n                minWidth = 190;\n                break;\n            case \"small\":\n                minWidth = 260;\n                break;\n            case \"large\":\n                minWidth = 385;\n                break;\n            case \"huge\":\n                minWidth = 440;\n                break;\n            default:\n                minWidth = 320;\n                break; //medium is default\n        }\n        setShowHeaderButton((widthTest.current?.clientWidth ?? 0) > minWidth);\n    });\n\n    useResizeObserver(widthTest, checkPanelWidth);\n\n    const isSharedMapping = useCallback(\n        (t: DatabaseMapping) => {\n            const mapping = accessibleTableMappings?.find(\n                (m) => m.table_mapping_id === t.table_mapping_id && !!appId && Object.keys(m.apps || {}).includes(appId)\n            );\n            return Object.keys(mapping?.apps || {}).length > 1;\n        },\n        [accessibleTableMappings, appId]\n    );\n\n    const tableMappingsWithMismatches = useMemo(() => tableMappings?.map(t => ({\n        ...t,\n        schemaMismatch: (t.diff?.filter(a => a.type !== \"ADD_INDEX\" && a.type !== \"DELETE_INDEX\").length ?? 0) > 0,\n        indexMismatch: (t.diff?.filter(a => a.type === \"ADD_INDEX\" || a.type === \"DELETE_INDEX\").length ?? 0) > 0,\n    })), [tableMappings]);\n\n    return (\n        <div className={\"mb-20\"}>\n            <div ref={widthTest} />\n            {/*<Heading level={2} style={{paddingLeft:12, marginBottom:13}}>Data Tables</Heading>*/}\n            {tableMappingsWithMismatches?.map((t) => (\n                <TableMapping\n                    key={t.table_mapping_id}\n                    mapping={t}\n                    isSelected={t.table_mapping_id === currentTableMapping?.table_mapping_id}\n                    onSelect={() => chooseEnvironmentMapping(t)}\n                    showHeaderButton={showHeaderButton}\n                    shared={isSharedMapping(t)}\n                    sharedTables={sharedTables}\n                />\n            ))}\n            <hr />\n            <div className={\"flex flex-wrap items-center justify-center\"}>\n                <DropdownMenu\n                    onSelectItem={(select) => select}\n                    render={(showMenu, anchor) => (\n                        <Button\n                            size={\"small\"}\n                            icon={faPlus}\n                            className={\"m-2\"}\n                            onClick={(e) => showMenu(null, e.currentTarget)}>\n                            Add Database\n                            <div className={cx(classes.dropdownAnchor)}>{anchor}</div>\n                        </Button>\n                    )}\n                    items={(selectItem, hideMenu) => [\n                        [\"Add new Database\", createNew],\n                        [\n                            \"Add Existing Database…\",\n                            () => dispatch(modal(\"addExistingDB\", { createNewDatabase: createNew })),\n                        ],\n                    ]}\n                    align={\"left\"}\n                />\n                <Button\n                    size={\"small\"}\n                    icon={faSitemap}\n                    className={\"m-2\"}\n                    onClick={() => {\n                        dispatch(hideIfOverlay());\n                        dispatch(navigate({ type: \"APP_SCHEMA\" }));\n                    }}>\n                    View App Schema\n                </Button>\n            </div>\n            <DbCTA />\n        </div>\n    );\n};\n\nexport default databaseNavConnector(DatabaseNav);\n","import React from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { getUser } from \"@/controllers/ide\";\nimport { useNavTargetSelector } from \"@/router/navigation-hooks\";\nimport { SecondaryNavLink, Section } from \"./SecondaryNavSection\";\n\nconst LOG_ITEMS_NO_ACCOUNTING = [\n    { title: \"App Sessions\", target: { type: \"SESSIONS\" } },\n    { title: \"Background Tasks\", target: { type: \"BACKGROUND_TASKS\" } },\n] as const;\n\nconst LOG_ITEMS = [\n    ...LOG_ITEMS_NO_ACCOUNTING,\n    { title: \"CPU Usage\", target: { type: \"CPU_USAGE\" } },\n    { title: \"Memory Usage\", target: { type: \"MEMORY_USAGE\" } },\n] as const;\n\nconst LogsNav = () => {\n    const user = useSelector(getUser);\n\n    const logItems = user?.ideConfig?.enableAccounting ? LOG_ITEMS : LOG_ITEMS_NO_ACCOUNTING;\n\n    const currentTargetType = useNavTargetSelector((t) => t?.type);\n\n    return (\n        <div className={\"mb-20\"}>\n            <Section title={\"App Logs\"}>\n                <div className=\"pt-3 pr-0 pb-3 pl-14\">\n                    {logItems.map(({ title, target }) => (\n                        <SecondaryNavLink key={target.type} to={target} isSelected={currentTargetType === target.type}>\n                            {title}\n                        </SecondaryNavLink>\n                    ))}\n                </div>\n            </Section>\n        </div>\n    );\n};\n\nexport default LogsNav;\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { connect, useDispatch, useSelector } from \"react-redux\";\nimport {\n    faChevronUp,\n    faFontCase,\n    faMinusSquare,\n    faPlusSquare,\n    faRedo,\n    faSearch,\n    faTimes,\n} from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport {\n    collapseAllSearchResults,\n    getSearchExpanded,\n    getSearchFocusInput,\n    getSearchIsCaseSensitive,\n    getSearchIsRegex,\n    getSearchTerm,\n    updateSearchExpanded,\n    updateSearchQuery,\n    useAppSearch,\n} from \"@/controllers/search\";\nimport { hideIfOverlay } from \"@/controllers/sidebar\";\nimport type { CodeNavTarget, ExtraFileNavTarget } from \"@/router/navTypes\";\nimport { navigate } from \"@/router/navigation\";\nimport { useNavTargetSelector } from \"@/router/navigation-hooks\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport type {\n    AnvilConnectedProps,\n    AnvilDispatch,\n    CodeItemType,\n    EditorPath,\n    EditorSearchResult,\n    FileResult,\n    State,\n} from \"@/types\";\nimport { EMPTY_ARRAY } from \"@/util\";\nimport { useDelayWhenTrueFlag, useStateWithReset } from \"@/util/hooks\";\nimport { searchHistoryStore, useSearchHistory, useSearchHistoryKeyDown } from \"@/util/search-history\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { Expander } from \"../reusable/Expander\";\nimport { getExtraFileIcon, useFileIconClassGetter } from \"../reusable/IconHooks\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { ContentTextInput } from \"../reusable/SharedComponents\";\nimport { useTooltip } from \"../reusable/Tooltip\";\n\ntype SearchNavClasses = \"searchMatchSelected\" | \"disabled\";\ntype FileIconClassName = \"formIcon\" | \"otherClientIcon\" | \"serverIcon\" | \"assetIcon\";\n\nconst useStyles = makeStyles<void, SearchNavClasses>()((theme, _props, classes) => ({\n    root: {\n        height: \"100%\",\n        display: \"flex\",\n        flexDirection: \"column\",\n    },\n    searchMatch: {\n        textOverflow: \"ellipsis\",\n        overflow: \"hidden\",\n        display: \"inline-block\",\n        whiteSpace: \"nowrap\",\n        fontSize: \"1.2rem\",\n        lineHeight: 1.6,\n        backgroundColor: \"transparent !important\", // important temporary while it's also a modal\n        color: \"inherit\",\n        padding: 0,\n        marginLeft: \"1rem\",\n    },\n    searchMatchContainer: {\n        display: \"flex\",\n        padding: \"0.9rem 2.6rem 0.7rem 0\",\n        [`&:hover:not(.${classes.searchMatchSelected})`]: {\n            backgroundColor: theme.secondaryNav.hoverBg.toString(),\n        },\n        [`&:hover:active:not(.${classes.searchMatchSelected}), &:active:not(.${classes.searchMatchSelected})`]: {\n            backgroundColor: theme.secondaryNav.activeBg.toString(),\n        },\n        borderBottomLeftRadius: \"1.7rem\",\n        borderTopLeftRadius: \"1.7rem\",\n        marginLeft: \"3rem\",\n        height: \"3.4rem\",\n    },\n    searchMatchSelected: {\n        color: theme.secondaryNav.selectedColor.toString(),\n        backgroundColor: theme.secondaryNav.selectedBg.toString(),\n        // Keep the preview location visible without competing with the focused file header.\n        \"[data-search-results]:has([data-search-file]:focus-visible) &\": {\n            color: theme.secondaryNav.color.toString(),\n            backgroundColor: theme.secondaryNav.hoverBg.toString(),\n        },\n        \"&:hover\": {\n            backgroundColor: theme.secondaryNav.selectedBg.darken(0.2).toString(),\n        },\n        \"&:active\": {\n            backgroundColor: theme.secondaryNav.selectedBg.toString(),\n        },\n    },\n    searchInputContainer: {\n        backgroundColor: theme.primaryNav.background.toString(),\n        display: \"flex\",\n        alignItems: \"center\",\n        padding: \"0 1.4rem\",\n    },\n    searchInput: {\n        padding: \"0 1rem\",\n        height: theme.tabBar.height,\n        border: \"none\",\n        borderRadius: 0,\n        flex: 1,\n    },\n    searchIcon: {\n        fontSize: \"1.8rem\",\n        color: theme.formInput.placeholderColor.toString(),\n    },\n    closeIcon: {\n        fontSize: \"1.3rem\",\n        color: theme.formInput.placeholderColor.toString(),\n    },\n    searchInputHasError: {\n        border: \"1px solid \" + theme.secondaryNav.icon3.background.toString(),\n    },\n    searchErrorMsg: {\n        padding: \"0 0.5rem\",\n        backgroundColor: theme.secondaryNav.icon3.background.fade(0.7).toString(),\n        color: theme.secondaryNav.icon3.background.toString(),\n        border: \"1px solid \" + theme.secondaryNav.icon3.background.toString(),\n        fontSize: \"1rem\",\n    },\n    searchInfo: {\n        fontSize: \"1rem\",\n        color: theme.secondaryNav.color.toString(),\n        flex: 1,\n    },\n    searchResultsContainer: {\n        display: \"flex\",\n        flexDirection: \"row\",\n        height: \"100%\",\n        backgroundColor: theme.primaryNav.background.toString(),\n    },\n    searchResults: {\n        display: \"flex\",\n        flex: 1,\n        flexDirection: \"column\",\n        paddingTop: \"1rem\",\n    },\n    sectionHeader: {\n        fontWeight: theme.secondaryNav.sectionHeader.fontWeight,\n        fontSize: theme.secondaryNav.sectionHeader.fontSize,\n        padding: \"1.3rem 1.4rem 1.1rem\",\n        margin: 0,\n    },\n    caret: {\n        margin: \"0 0.3rem 0 1.5rem\",\n    },\n    expandable: {\n        padding: \"0.9rem 0 0.7rem\",\n        display: \"flex\",\n        flex: \"0 0 auto\",\n        flexDirection: \"row\",\n        alignItems: \"center\",\n        \"&:hover\": {\n            backgroundColor: theme.secondaryNav.hoverBg.toString(),\n        },\n        \"&:active\": {\n            backgroundColor: theme.secondaryNav.activeBg.toString(),\n        },\n    },\n    searchToolBar: {\n        display: \"flex\",\n        alignItems: \"center\",\n        padding: \"0 1.5rem\",\n        minHeight: \"5rem\",\n        borderTop: \"1px solid \" + theme.sectionBorderColor.toString(),\n        borderBottom: \"1px solid \" + theme.sectionBorderColor.toString(),\n    },\n    searchTool: {\n        padding: \"0 0.4rem\",\n        fontSize: \"1.3rem\",\n        borderRadius: \"0.4rem\",\n        textAlign: \"center\",\n        width: \"2.9rem\",\n        height: \"2.9rem\",\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        color: theme.secondaryNav.sectionHeader.color.toString(),\n        [`&:not(.${classes.disabled}):hover`]: {\n            backgroundColor: theme.primaryNav.iconHoverBg.toString(),\n        },\n        [`&:not(.${classes.disabled}):active`]: {\n            backgroundColor: theme.primaryNav.iconActiveBg.toString(),\n            color: theme.primaryNav.iconActiveColor.toString(),\n        },\n    },\n    selected: {\n        backgroundColor: theme.primaryNav.selectedIconBg.toString(),\n        color: theme.primaryNav.selectedIconColor.toString(),\n        [`&:not(.${classes.disabled}):hover`]: {\n            backgroundColor: theme.primaryNav.selectedIconBg.darken(0.2).toString(),\n            // color: theme.primaryNav.selectedIconColor.darken(0.2).toString(),\n        },\n    },\n    disabled: {\n        color: theme.secondaryNav.disabledChevron.toString(),\n        cursor: \"not-allowed\",\n    },\n    node: {\n        margin: \"0 0.5rem\",\n        width: \"1.8rem\",\n        minWidth: \"1.8rem\",\n    },\n    nodeIcon: {\n        height: theme.secondaryNav.iconSize,\n        borderRadius: `calc(${theme.secondaryNav.iconSize} / 2)`,\n        fontSize: \"1rem\",\n        color: theme.secondaryNav.iconColor.toString(),\n        textAlign: \"center\",\n    },\n    fileTitle: {\n        margin: \"0 0.5rem\",\n        color: theme.isDark ? \"white\" : theme.secondaryNav.color.toString(),\n        fontSize: \"1.2rem\",\n        textOverflow: \"ellipsis\",\n        overflow: \"hidden\",\n        whiteSpace: \"nowrap\",\n    },\n    formIcon: {\n        background: theme.secondaryNav.icon1.background.toString(),\n        color: theme.secondaryNav.icon1.color.toString(),\n    },\n    otherClientIcon: {\n        background: theme.secondaryNav.icon3.background.toString(),\n        color: theme.secondaryNav.icon3.color.toString(),\n    },\n    testingIcon: {\n        background: theme.secondaryNav.icon4.background.toString(),\n        color: theme.secondaryNav.icon4.color.toString(),\n    },\n    extraFileIcon: {\n        background: theme.palette.fg3.alpha(0.2).toString(),\n        color: theme.palette.fg3.toString(),\n    },\n    serverIcon: {\n        background: theme.secondaryNav.icon2.background.toString(),\n        color: theme.secondaryNav.icon2.color.toString(),\n    },\n}));\n\nconst useDelayDispatch = (defaultDelay: number) => {\n    const setDelayDispatch = useRef<number | null>(null);\n    useEffect(\n        () => () => {\n            if (setDelayDispatch.current !== null) clearTimeout(setDelayDispatch.current);\n        },\n        []\n    );\n    const dispatchDelayFn = useEvent((dispatchFn: () => void, delay?: number | null) => {\n        if (setDelayDispatch.current) {\n            clearTimeout(setDelayDispatch.current);\n        }\n        setDelayDispatch.current = setTimeout(() => dispatchFn?.(), delay == null ? defaultDelay : delay);\n    });\n\n    return dispatchDelayFn;\n};\n\nconst connector = connect((state: State) => ({\n    searchTerm: getSearchTerm(state),\n    isCaseSensitive: getSearchIsCaseSensitive(state),\n    isRegex: getSearchIsRegex(state),\n    focusInput: getSearchFocusInput(state),\n    searchExpanded: getSearchExpanded(state),\n}));\n\ntype SearchNavProps = AnvilConnectedProps<typeof connector> & {\n    onResultClick?: () => void;\n};\n\nconst SearchNav = ({\n    dispatch,\n    searchTerm,\n    isCaseSensitive = false,\n    isRegex = false,\n    searchExpanded,\n    onResultClick,\n    focusInput,\n}: SearchNavProps) => {\n    const { classes } = useStyles();\n    const iconClassGetter = useFileIconClassGetter(classes as Record<FileIconClassName, string>);\n\n    const { data, error, isFetching: isSearching, refetch } = useAppSearch({ searchTerm, isCaseSensitive, isRegex });\n    const showSearching = useDelayWhenTrueFlag(isSearching, 200, false) && isSearching;\n    const searchData = error ? undefined : data;\n    const searchResultsAsArray = searchData?.results ?? EMPTY_ARRAY;\n    const errorMsg = error?.message;\n    const truncated = searchData?.truncated;\n    const skippedFiles = searchData?.skippedFiles ?? 0;\n\n    const [searchInput, setSearchInput] = useStateWithReset(searchTerm);\n    const history = useSearchHistory(searchHistoryStore);\n    const { showHistoryHint, resetNavigation, onFocus, onBlur } = history;\n    const [selectedResult, setSelectedResult] = useState<string | null>(null);\n\n    const onResultsKeyDown = useEvent((event: React.KeyboardEvent<HTMLDivElement>) => {\n        if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;\n        const target = event.target as HTMLElement;\n        if ((event.key === \" \" || event.key === \"Enter\") && target.hasAttribute(\"data-search-file\")) {\n            event.preventDefault();\n            event.stopPropagation();\n            target.click();\n            return;\n        }\n        if (event.key !== \"ArrowDown\" && event.key !== \"ArrowUp\") return;\n        const items = Array.from(\n            event.currentTarget.querySelectorAll<HTMLElement>(\n                '[data-search-file], [data-search-result][tabindex=\"0\"]'\n            )\n        );\n        const index = items.indexOf(target);\n        if (index === -1) return;\n        event.preventDefault();\n        event.stopPropagation();\n        const next = items[index + (event.key === \"ArrowDown\" ? 1 : -1)];\n        if (next) {\n            next.focus();\n            next.scrollIntoView({ block: \"nearest\" });\n            // Preview matches in the sidebar; file headers only receive focus.\n            if (!onResultClick && next.hasAttribute(\"data-search-result\")) next.click();\n        }\n    });\n\n    const allCollapsed =\n        searchResultsAsArray.length > 0 &&\n        searchResultsAsArray.every(({ file }) => searchExpanded[file.codePath] === false);\n\n    const delaySearchDispatch = useDelayDispatch(50);\n    // Controls can replace a pending typed query; keep its history-recording intent.\n    const pendingHistoryTerm = useRef<string | null>(null);\n    const [searchResults, numFiles, totalResults] = useMemo(() => {\n        const forms: EditorSearchResult[] = [];\n        const modules: EditorSearchResult[] = [];\n        const server: EditorSearchResult[] = [];\n        const assets: EditorSearchResult[] = [];\n        const extraFiles: EditorSearchResult[] = [];\n        let totalResults = 0;\n        searchResultsAsArray.forEach((result) => {\n            switch (result.file.itemType) {\n                case \"form\":\n                    forms.push(result);\n                    break;\n                case \"module\":\n                    modules.push(result);\n                    break;\n                case \"server_module\":\n                    server.push(result);\n                    break;\n                case \"asset\":\n                    assets.push(result);\n                    break;\n                case \"extra_file\":\n                    extraFiles.push(result);\n                    break;\n                default:\n                    break;\n            }\n            totalResults += result.results.length;\n        });\n        return [{ forms, modules, server, assets, extraFiles }, searchResultsAsArray.length, totalResults];\n    }, [searchResultsAsArray]);\n\n    const doSearch = useEvent(\n        (\n            search: string,\n            {\n                withCase = isCaseSensitive,\n                withRegex = isRegex,\n                delay,\n                recordHistory = false,\n            }: {\n                withCase?: boolean;\n                withRegex?: boolean;\n                delay?: number;\n                recordHistory?: boolean;\n            } = {}\n        ) => {\n            recordHistory ||= pendingHistoryTerm.current === search;\n            pendingHistoryTerm.current = recordHistory ? search : null;\n            delaySearchDispatch(() => {\n                pendingHistoryTerm.current = null;\n                dispatch(updateSearchQuery(search, { isCaseSensitive: withCase, isRegex: withRegex, recordHistory }));\n                if (search && search === searchTerm && withCase === isCaseSensitive && withRegex === isRegex) {\n                    void refetch();\n                }\n            }, delay);\n        }\n    );\n\n    const onChange = useEvent((e: React.ChangeEvent<HTMLInputElement>) => {\n        const val = e.target.value;\n        resetNavigation();\n        setSearchInput(val);\n        const len = val.length;\n        const mult = isRegex && len ? 2.5 : 1;\n        const delay = len === 1 || len === 2 ? 1000 : 300;\n        // if it's only a single letter wait a bit longer\n        // if it's regex wait even longer\n        doSearch(val, { delay: mult * delay, recordHistory: true });\n    });\n\n    const onSearchKeyDown = useSearchHistoryKeyDown(history, searchInput, (term) => {\n        setSearchInput(term);\n        doSearch(term);\n    });\n\n    const onCollapseAll = useEvent(() => {\n        dispatch(collapseAllSearchResults(searchResultsAsArray, !allCollapsed));\n    });\n\n    const onCaseSensitive = useEvent(() => {\n        doSearch(searchInput, { withCase: !isCaseSensitive });\n    });\n\n    const onRegex = useEvent(() => {\n        doSearch(searchInput, { withRegex: !isRegex });\n    });\n\n    const currentResultKey = useNavTargetSelector((t) => {\n        if (t?.type === \"EXTRA_FILE\") {\n            const position = t.view?.code;\n            if (!Array.isArray(position)) return null;\n            return `extra_files/${t.filePath}-code-${position[0]}-${position[1]}`;\n        }\n        if (t?.type !== \"CODE\") return null;\n        const viewType = t.view?.focus === \"html\" || !t.view?.code ? \"html\" : \"code\";\n        const position = t.view?.[viewType];\n        if (!Array.isArray(position)) return null;\n        const [line, column] = position;\n        return `${t.codePath}-${viewType}-${line}-${column}`;\n    });\n\n    useEffect(() => {\n        setSelectedResult(currentResultKey);\n    }, [currentResultKey]);\n\n    const searchInputEl = useRef<HTMLInputElement>(null);\n    useEffect(() => {\n        resetNavigation();\n        searchInputEl.current?.select();\n    }, [focusInput]);\n\n    const props = {\n        classes,\n        dispatch,\n        setSelectedResult,\n        selectedResult,\n        searchExpanded,\n        onResultClick,\n        iconClassGetter,\n    };\n\n    const [caseTT, caseTTRef] = useTooltip(\"Case sensitive\", \"top\");\n    const [regexTT, regexTTRef] = useTooltip(\"Regex\", \"top\");\n    const [refreshTT, refreshTTRef] = useTooltip(\"Refresh\", \"top\");\n    const [expandAllTT, expandAllTTRef] = useTooltip(allCollapsed ? \"Expand all\" : \"Collapse all\", \"top\");\n\n    return (\n        <div className={classes.root}>\n            <div\n                className={cx(\n                    classes.searchInputContainer,\n                    errorMsg && !isSearching ? classes.searchInputHasError : null\n                )}>\n                <FontAwesomeIcon icon={faSearch} className={classes.searchIcon}></FontAwesomeIcon>\n                <ContentTextInput\n                    ref={searchInputEl}\n                    className={classes.searchInput}\n                    value={searchInput}\n                    placeholder={showHistoryHint ? \"Search (⇅ for history)\" : \"Search\"}\n                    aria-label=\"Search\"\n                    onEnter={() => {\n                        resetNavigation();\n                        doSearch(searchInput, { recordHistory: true });\n                    }}\n                    onChange={onChange}\n                    onKeyDown={onSearchKeyDown}\n                    onFocus={onFocus}\n                    onBlur={onBlur}\n                    autoFocus\n                />\n                <LinkInternal\n                    className={classes.closeIcon}\n                    icon={faTimes}\n                    onClick={() => {\n                        if (searchInput) {\n                            resetNavigation();\n                            setSearchInput(\"\");\n                            doSearch(\"\");\n                        }\n                    }}\n                />\n            </div>\n            <div className={classes.searchToolBar}>\n                <span className={cx(classes.searchInfo, \"min-w-0 truncate\")}>\n                    {totalResults\n                        ? `${totalResults}${truncated ? \"+\" : \"\"} result${totalResults === 1 ? \"\" : \"s\"} / ${numFiles} file${\n                              numFiles === 1 ? \"\" : \"s\"\n                          }`\n                        : showSearching\n                          ? \"Searching…\"\n                          : isSearching\n                            ? \"\"\n                            : \"No results\"}\n                </span>\n                {caseTT}\n                <LinkInternal\n                    ref={caseTTRef}\n                    className={cx(classes.searchTool, isCaseSensitive ? classes.selected : null)}\n                    icon={faFontCase}\n                    onClick={onCaseSensitive}\n                />\n                {regexTT}\n                <LinkInternal\n                    ref={regexTTRef}\n                    style={{ padding: \"0 5px\" }}\n                    className={cx(classes.searchTool, isRegex ? classes.selected : null)}\n                    onClick={onRegex}>\n                    .*\n                </LinkInternal>\n                {refreshTT}\n                <LinkInternal\n                    ref={refreshTTRef}\n                    className={cx(classes.searchTool, searchInput ? null : classes.disabled)}\n                    onClick={() => doSearch(searchInput)}\n                    aria-label={showSearching ? \"Searching\" : \"Refresh\"}>\n                    <FontAwesomeIcon icon={faRedo} fixedWidth spin={showSearching} />\n                </LinkInternal>\n                {expandAllTT}\n                <LinkInternal\n                    ref={expandAllTTRef}\n                    className={cx(classes.searchTool, numFiles ? null : classes.disabled)}\n                    icon={allCollapsed && numFiles ? faPlusSquare : faMinusSquare}\n                    onClick={numFiles ? onCollapseAll : undefined}\n                />\n            </div>\n            {errorMsg && !isSearching && <small className={classes.searchErrorMsg}>{errorMsg}</small>}\n            <div\n                data-search-results\n                className={cx(classes.searchResultsContainer, \"offset-vscrollbar min-h-0 flex-1 pb-20\")}\n                aria-busy={isSearching}\n                onKeyDown={onResultsKeyDown}>\n                <div className={cx(classes.searchResults, \"offset-vscrollbar\")}>\n                    {numFiles !== 0 && (\n                        <>\n                            <CompiledResults title={\"Forms\"} results={searchResults.forms} {...props} />\n                            <CompiledResults title={\"Modules\"} results={searchResults.modules} {...props} />\n                            <CompiledResults title={\"ServerModules\"} results={searchResults.server} {...props} />\n                            <CompiledResults title={\"Assets\"} results={searchResults.assets} {...props} />\n                            <CompiledResults title={\"Extra Files\"} results={searchResults.extraFiles} {...props} />\n                        </>\n                    )}\n                </div>\n            </div>\n            {!!skippedFiles && (\n                <p className=\"shrink-0 px-5 py-2 text-sm\">\n                    {skippedFiles} non-text file{skippedFiles === 1 ? \"\" : \"s\"} skipped\n                </p>\n            )}\n            {truncated && (\n                <p className=\"shrink-0 px-5 py-2 text-sm\">\n                    Showing the first {totalResults} matches. Refine your search to see more.\n                </p>\n            )}\n        </div>\n    );\n};\n\ntype SearchNavClassRecord = ReturnType<typeof useStyles>[\"classes\"];\ntype MatchSharedProps = {\n    classes: SearchNavClassRecord;\n    dispatch: AnvilDispatch;\n    selectedResult: string | null;\n    setSelectedResult: React.Dispatch<React.SetStateAction<string | null>>;\n    searchExpanded: Record<EditorPath, boolean>;\n    onResultClick?: () => void;\n    iconClassGetter: (fileType: CodeItemType) => string | null;\n};\n\ntype CompiledResultsProps = MatchSharedProps & {\n    title: string;\n    results: EditorSearchResult[];\n};\n\nconst CompiledResults = ({ title, results, classes, ...props }: CompiledResultsProps) =>\n    results.length ? (\n        <div>\n            <h4 className={classes.sectionHeader}>{title}</h4>\n            {results.map(({ file, results }) => (\n                <MatchItem\n                    key={file.codePath}\n                    file={file}\n                    results={results}\n                    classes={classes}\n                    {...props}\n                />\n            ))}\n        </div>\n    ) : null;\n\ninterface MatchLinkProps {\n    navTarget: CodeNavTarget | ExtraFileNavTarget;\n    resultKey: string;\n    setSelectedResult: React.Dispatch<React.SetStateAction<string | null>>;\n    selectedResult: string | null;\n    classes: SearchNavClassRecord;\n    onResultClick?: () => void;\n    matchLine: string;\n    isExpanded: boolean;\n}\n\nconst MatchLink = ({\n    navTarget,\n    resultKey,\n    setSelectedResult,\n    selectedResult,\n    classes,\n    onResultClick,\n    matchLine,\n    isExpanded,\n}: MatchLinkProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    // Keep highlighted text nodes intact when blurring the search box rerenders results mid-click.\n    const matchHtml = useMemo(() => ({ __html: matchLine }), [matchLine]);\n    const onSelect = useEvent((activate: boolean) => {\n        if (activate) dispatch(hideIfOverlay());\n        const target = activate ? { ...navTarget, refocusView: Math.random() } : navTarget;\n        dispatch(navigate(target, false, false, { preserveFocus: !activate }));\n        setSelectedResult(resultKey);\n        if (activate) onResultClick?.();\n    });\n    const tooltip = (\n        <span className=\"block w-96 font-mono text-base whitespace-normal\" dangerouslySetInnerHTML={matchHtml} />\n    );\n    const [tooltipAnchor, tooltipRef] = useTooltip(tooltip, \"top\", { delay: true });\n    return (\n        <LinkInternal\n            ref={tooltipRef}\n            data-search-result={resultKey}\n            tabIndex={isExpanded ? 0 : -1}\n            className={cx(\n                classes.searchMatchContainer,\n                \"focus-visible:ring-1 focus-visible:ring-primary focus-visible:ring-inset\",\n                selectedResult === resultKey ? classes.searchMatchSelected : null\n            )}\n            onClick={() => onSelect(!!onResultClick)}\n            onDoubleClick={() => onSelect(true)}\n            onKeyDown={(event) => {\n                if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;\n                if (event.key === \"Enter\" || event.key === \" \") {\n                    event.preventDefault();\n                    event.stopPropagation();\n                    onSelect(true);\n                }\n            }}>\n            {/* we are using dangerouslySetInnerHTML until we use codemirror here instead - the results have the searchTerm in <b> tags */}\n            <code className={classes.searchMatch} dangerouslySetInnerHTML={matchHtml} />\n            {tooltipAnchor}\n        </LinkInternal>\n    );\n};\n\nconst MatchItem = ({\n    file,\n    results,\n    classes,\n    dispatch,\n    selectedResult,\n    setSelectedResult,\n    searchExpanded,\n    onResultClick,\n    iconClassGetter,\n}: MatchSharedProps & { file: EditorSearchResult[\"file\"]; results: FileResult[] }) => {\n    const { codePath, fullName: title, icon: fileIcon } = file;\n    const iconClass =\n        file.itemType === \"extra_file\"\n            ? classes[getExtraFileIcon(file.fullName).iconClass]\n            : iconClassGetter(file.itemType);\n\n    const isExpanded = useMemo(() => searchExpanded[codePath] !== false, [searchExpanded, codePath]);\n\n    const updateExpanded = useCallback(() => {\n        dispatch(updateSearchExpanded(file, !isExpanded));\n    }, [isExpanded]);\n\n    const matchProps = { selectedResult, setSelectedResult, classes, onResultClick };\n\n    return (\n        <>\n            <LinkInternal\n                data-search-file={codePath}\n                aria-expanded={isExpanded}\n                className={cx(\n                    classes.expandable,\n                    \"focus-visible:bg-primary/10 focus-visible:ring-1 focus-visible:ring-primary focus-visible:ring-inset\"\n                )}\n                onClick={updateExpanded}>\n                <div className={classes.caret}>\n                    <FontAwesomeIcon fixedWidth icon={faChevronUp} rotation={isExpanded ? 180 : 90} />\n                </div>\n                <div className={cx(classes.node)}>\n                    <div className={cx(classes.nodeIcon, iconClass)}>\n                        <FontAwesomeIcon fixedWidth icon={fileIcon} />\n                    </div>\n                </div>\n\n                <span className={classes.fileTitle}>{title}</span>\n            </LinkInternal>\n            <Expander isOpen={isExpanded}>\n                {/* {isExpanded && */}\n                {results.map(({ matchLine, navTarget, resultKey }) => (\n                    <MatchLink\n                        key={resultKey}\n                        navTarget={navTarget}\n                        resultKey={resultKey}\n                        matchLine={matchLine}\n                        isExpanded={!!isExpanded}\n                        {...matchProps}\n                    />\n                ))}\n                {/* } */}\n            </Expander>\n        </>\n    );\n};\n\nexport default connector(SearchNav);\n","import React from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faSignOut } from \"@fortawesome/pro-regular-svg-icons/faSignOut\";\nimport { faTrashAlt } from \"@fortawesome/pro-regular-svg-icons/faTrashAlt\";\nimport { faUndoAlt } from \"@fortawesome/pro-solid-svg-icons/faUndoAlt\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { getApp, getAppId } from \"@/controllers/app\";\nimport { getIsOwner } from \"@/controllers/app/permissions\";\nimport { deleteAppWithConfirm } from \"@/controllers/app/saving\";\nimport { useNavTargetSelector } from \"@/router/navigation-hooks\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { SecondaryNavLink, Section } from \"./SecondaryNavSection\";\n\nconst useDeleteLinkStyles = makeStyles()((theme) => ({\n    deleteLink: {\n        \"& > div > div \": {\n            color: theme.deleteLink.color.toString(),\n        },\n        \"&:hover\": {\n            \"& > div > div \": {\n                color: theme.deleteLink.hoverColor.toString(),\n            },\n        },\n    },\n\n    disabledDelete: {\n        \"& > div > div \": {\n            color: theme.disableDeleteApp.color.toString(),\n        },\n        \"&:hover\": {\n            \"& > div > div \": {\n                color: theme.disableDeleteApp.color.toString(),\n                cursor: \"default !important\",\n            },\n        },\n    },\n}));\n\nconst configItems = [\n    {\n        section: \"ROOT\",\n        title: \"General\",\n    },\n    {\n        section: \"DATATABLES\",\n        title: \"Data Tables\",\n    },\n    {\n        section: \"PERMISSIONS\",\n        title: \"Collaboration\",\n    },\n    {\n        section: \"EMBEDDING\",\n        title: \"Embedding\",\n    },\n] as const;\n\nconst SettingsNav = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const app = useSelector(getApp);\n    const appId = useSelector(getAppId);\n    const isOwner = useSelector(getIsOwner);\n\n    const { classes } = useDeleteLinkStyles();\n\n    const currentTargetType = useNavTargetSelector((t) => t?.type);\n    const currentSection = useNavTargetSelector((t) => t?.type === \"SETTINGS\" && t.section);\n\n    const [tooltip, anchorRef] = useTooltip(\"Cannot delete app you don't own\", \"right\");\n\n    return (\n        <div className={\"mb-20\"}>\n            <Section title={\"Settings\"}>\n                <div className={\"pt-3 pr-0 pb-3 pl-14\"}>\n                    {configItems.map(({ section, title }) => (\n                        <SecondaryNavLink\n                            key={section}\n                            to={{ type: \"SETTINGS\", section }}\n                            isSelected={currentSection === section}>\n                            {title}\n                        </SecondaryNavLink>\n                    ))}\n                </div>\n            </Section>\n            <Section title=\"Dependencies\">\n                <div className=\"pt-3 pr-0 pb-3 pl-14\">\n                    <SecondaryNavLink\n                        to={{ type: \"APP_DEPENDENCIES\" }}\n                        isSelected={currentTargetType === \"APP_DEPENDENCIES\"}>\n                        App dependencies\n                    </SecondaryNavLink>\n                    <SecondaryNavLink\n                        to={{ type: \"PYTHON_DEPENDENCIES\" }}\n                        isSelected={currentTargetType === \"PYTHON_DEPENDENCIES\"}>\n                        Python dependencies\n                    </SecondaryNavLink>\n                    <SecondaryNavLink\n                        to={{ type: \"JAVASCRIPT_DEPENDENCIES\" }}\n                        isSelected={currentTargetType === \"JAVASCRIPT_DEPENDENCIES\"}>\n                        JavaScript dependencies\n                    </SecondaryNavLink>\n                </div>\n            </Section>\n            <Section title={\"Manage this App\"}>\n                <div className={\"pt-3 pr-0 pb-3 pl-14\"}>\n                    <SecondaryNavLink to={{ type: \"START_PAGE\" }} icon={faSignOut}>\n                        Close app\n                    </SecondaryNavLink>\n                    <SecondaryNavLink\n                        className={cx(isOwner ? classes.deleteLink : classes.disabledDelete)}\n                        to={null}\n                        icon={faTrashAlt}\n                        ref={anchorRef}\n                        onClickOverrideNav={() => isOwner && dispatch(deleteAppWithConfirm())}\n                        iconCircleClassName=\"text-danger!\">\n                        Delete app\n                        {!isOwner && tooltip}\n                    </SecondaryNavLink>\n                </div>\n            </Section>\n        </div>\n    );\n};\n\nexport default SettingsNav;\n","import React from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { getAppColorsIncludingDependencies } from \"@/controllers/app/theme\";\nimport { useNavTargetSelector } from \"@/router/navigation-hooks\";\nimport { SecondaryNavLink, Section } from \"./SecondaryNavSection\";\n\nconst THEME_ITEMS_NO_COLORS = [{ section: \"ROLES\", title: \"Roles\" }] as const;\nconst THEME_ITEMS = [...THEME_ITEMS_NO_COLORS, { section: \"COLOUR_SCHEME\", title: \"Colour Scheme\" }] as const;\n\nconst ThemeNav = () => {\n    const colors = useSelector(getAppColorsIncludingDependencies);\n    const themeItems = colors ? THEME_ITEMS : THEME_ITEMS_NO_COLORS;\n\n    const currentSection = useNavTargetSelector((t) => (t?.type === \"THEME\" ? t.section : undefined));\n\n    return (\n        <div className={\"mb-20\"}>\n            <Section title={\"App Theme\"}>\n                <div className=\"pt-3 pr-0 pb-3 pl-14\">\n                    {themeItems.map(({ section, title }) => (\n                        <SecondaryNavLink\n                            key={section}\n                            to={{ type: \"THEME\", section }}\n                            isSelected={currentSection === section}>\n                            {title}\n                        </SecondaryNavLink>\n                    ))}\n                </div>\n            </Section>\n        </div>\n    );\n};\n\nexport default ThemeNav;\n","import React, { useCallback, useMemo, useRef, useState } from \"react\";\nimport { connect, useDispatch, useSelector } from \"react-redux\";\nimport type { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport { faChevronDown } from \"@fortawesome/free-solid-svg-icons/faChevronDown\";\nimport { faChevronUp } from \"@fortawesome/free-solid-svg-icons/faChevronUp\";\nimport { faSearch, faSparkle } from \"@fortawesome/pro-light-svg-icons\";\nimport { faCog } from \"@fortawesome/pro-light-svg-icons/faCog\";\nimport { faDatabase } from \"@fortawesome/pro-light-svg-icons/faDatabase\";\nimport { faFolderTree } from \"@fortawesome/pro-light-svg-icons/faFolderTree\";\nimport { faListUl } from \"@fortawesome/pro-light-svg-icons/faListUl\";\nimport { faPalette } from \"@fortawesome/pro-light-svg-icons/faPalette\";\nimport { faPlus } from \"@fortawesome/pro-light-svg-icons/faPlus\";\nimport { faChevronsLeft, faThumbtack } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faClock, faTrashAlt } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { capitalize, orderBy } from \"lodash-es\";\nimport { keyframes } from \"tss-react\";\nimport {\n    getUserHasCreatedConversation,\n    maybeDecideToOpenOpenConversation,\n    useAgentsEnabled,\n} from \"@/controllers/agents.ts\";\nimport { getApp, getInvalidYaml } from \"@/controllers/app\";\nimport { saveApp } from \"@/controllers/app/saving\";\nimport { getUser } from \"@/controllers/ide\";\nimport { confirm, modal } from \"@/controllers/modals\";\nimport { destroyRunnerRepls } from \"@/controllers/repl\";\nimport { addServiceWithModal, getTestingEnabled, removeService } from \"@/controllers/services\";\nimport {\n    closeNav,\n    evaluateSecondaryNavState,\n    getNavMode,\n    getPrimarySection,\n    getSecondaryNavOpen,\n    getSecondaryNavWidth,\n    hideIfOverlay,\n    openNav,\n    primaryNav,\n    secondaryNavResize,\n    setNavModeToDocked,\n    setNavModeToOverlay,\n} from \"@/controllers/sidebar\";\nimport { closeAllTabs, navigateToTabMatchingTarget } from \"@/controllers/tabs\";\nimport { getUserRegistrationAgeDays, useAbFlag } from \"@/controllers/user.ts\";\nimport type { NavTarget } from \"@/router/navTypes\";\nimport { navigate } from \"@/router/navigation\";\nimport TestingNav from \"@/testing/TestsSidebar.tsx\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport type { AnvilAction, AnvilConnectedProps, AnvilDispatch, AppService, AppState, State } from \"@/types\";\nimport { getServiceIcon, getServiceType } from \"@/util\";\nimport { useScrollWhenDragging } from \"@/util/dnd\";\nimport { useResizeObserver } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { AgentSidebar } from \"../../agent/AgentSidebar.tsx\";\nimport { Button } from \"../reusable/Button\";\nimport DropdownMenu from \"../reusable/DropdownMenu\";\nimport { ErrorBoundary } from \"../reusable/ErrorBoundary\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { useTooltip } from \"../reusable/Tooltip\";\nimport CodeNav from \"./CodeNav\";\nimport DatabaseNav from \"./DatabaseNav\";\nimport LogsNav from \"./LogsNav\";\nimport ResizePanel from \"./ResizePanel\";\nimport SearchNav from \"./SearchNav\";\nimport SettingsNav from \"./SettingsNav\";\nimport ThemeNav from \"./ThemeNav\";\n\ntype SidebarClasses = \"linkActive\" | \"icon\" | \"primary\";\ntype PrimarySection = \"code\" | \"search\" | \"db\" | \"settings\" | \"logs\" | \"theme\" | \"ai\" | \"tests\";\n\nconst useStyles = makeStyles<void, SidebarClasses>()((theme, _props, classes) => ({\n    root: {\n        height: \"100%\",\n        background: theme.palette.bg0.hex(),\n        flex: \"0 0 auto\",\n        display: \"flex\",\n        color: theme.palette.fg1.hex(),\n    },\n    primaryNav: {\n        flex: \"0 0 auto\",\n        width: \"7.1rem\",\n        // overflow: 'hidden',\n        // position: 'relative', // So the scroll buttons can be full width.\n        background: theme.primaryNav.background.toString(),\n        borderRight: \"1px solid \" + theme.sectionBorderColor.toString(),\n    },\n    primaryNavList: {\n        listStyleType: \"none\",\n        padding: 0,\n        textAlign: \"center\",\n        display: \"flex\",\n        flexDirection: \"column\",\n\n        // Scrolling\n        /**\n         * @todo make the scroll primary nav work with tooltips\n         * You can't have scroll in y and visible in x :-(\n         * scroll in y => hidden in x (breaks tooltips)\n         * scroll in y => scroll in x (breaks tooltips)\n         *\n         * Could make tooltips absolute on the body\n         * this would need a new implementation of tooltips\n         */\n        height: \"100%\",\n        overflowY: \"scroll\",\n        overflowX: \"hidden\",\n        \"&::-webkit-scrollbar\": {\n            display: \"none\",\n        },\n        scrollbarWidth: \"none\",\n\n        // Hide scrollbar\n        // marginRight: -100,\n        // paddingRight: 100,\n    },\n    primaryNavItem: {\n        height: \"7rem\",\n    },\n    primaryNavLink: {\n        padding: \"1.5rem\",\n        textAlign: \"center\",\n        display: \"block\",\n        [`&:hover:not(.${classes.linkActive}) .${classes.icon}`]: {\n            background: theme.primaryNav.iconHoverBg.toString(),\n            color: theme.primaryNav.iconHoverColor.toString(),\n            [`&.${classes.primary}`]: {\n                background: theme.primaryNav.addButtonBg.darken(0.1).toString(),\n                color: theme.primaryNav.addButtonColor.toString(),\n            },\n        },\n        [`&:active:not(.${classes.linkActive}) .${classes.icon}`]: {\n            background: theme.primaryNav.iconActiveBg.toString(),\n            color: theme.primaryNav.iconActiveColor.toString(),\n            [`&.${classes.primary}`]: {\n                background: theme.primaryNav.addButtonBg.darken(0.4).toString() + \" !important\", // Otherwise the :hover above wins.\n                color: theme.primaryNav.addButtonColor.toString(),\n            },\n        },\n    },\n    linkActive: {\n        [`& .${classes.icon}`]: {\n            background: theme.primaryNav.selectedIconBg.toString(),\n            color: theme.primaryNav.selectedIconColor.toString(),\n        },\n        // color: theme.hl1.hex(),\n        // borderLeftColor: theme.hl1.hex(),\n    },\n    triggered: {\n        animation: `${keyframes`\n        50% {\n            color: ${theme.hl1.hex()};\n            borderLeftColor: ${theme.hl1.hex()};\n        }`} 0.2s linear infinite`,\n    },\n    icon: {\n        color: theme.primaryNav.defaultIconColor.toString(),\n        fontSize: theme.primaryNav.iconSize,\n        width: \"4rem\",\n        height: \"4rem\",\n        borderTopLeftRadius: \"0.4rem\",\n        borderTopRightRadius: \"0.4rem\",\n        borderBottomLeftRadius: \"0.4rem\",\n        borderBottomRightRadius: \"0.4rem\",\n    },\n    title: {\n        fontSize: \"1.2rem\",\n        borderBottomLeftRadius: \"0.4rem\",\n        borderBottomRightRadius: \"0.4rem\",\n    },\n    secondaryNav: {\n        overflowX: \"hidden\",\n        background: theme.secondaryNav.background.toString(),\n        height: \"100%\", //scrolling\n        maxHeight: \"100%\",\n        //padding: \"20px 36px 20px 20px\",\n        transition: \"padding-right .2s ease-in .2s\",\n        \"& hr\": {\n            borderColor: theme.sectionBorderColor.toString(),\n        },\n        \"&::-webkit-scrollbar\": {\n            borderLeft: `1px solid ${theme.sectionBorderColor.toString()}`,\n        },\n    },\n    spring: {\n        flexGrow: 1,\n    },\n    separator: {\n        background: theme.palette.bg2.hex(),\n        height: 1,\n        flex: \"0 0 auto\",\n        margin: \"0px 5px\",\n    },\n    scroller: {\n        position: \"absolute\",\n        width: \"100%\",\n    },\n    scrollUp: {\n        top: 0,\n        paddingBottom: \"3rem\",\n        background: `linear-gradient(0deg, transparent 0, ${theme.palette.bg2.hex()} 20px, ${theme.palette.bg2.hex()})`,\n        \"&:hover\": {\n            background: `linear-gradient(0deg, transparent 0, ${theme.palette.bg2\n                .lighten(0.2)\n                .hex()} 20px, ${theme.palette.bg2.lighten(0.2).hex()})`,\n        },\n    },\n    scrollDown: {\n        bottom: 0,\n        paddingTop: \"3rem\",\n        background: `linear-gradient(180deg, transparent 0, ${theme.palette.bg2.hex()} 2rem, ${theme.palette.bg2.hex()})`,\n        \"&:hover\": {\n            background: `linear-gradient(180deg, transparent 0, ${theme.palette.bg2\n                .lighten(0.2)\n                .hex()} 2rem, ${theme.palette.bg2.lighten(0.2).hex()})`,\n        },\n    },\n    primary: {\n        background: theme.primaryNav.addButtonBg.toString(),\n        color: theme.primaryNav.addButtonColor.toString(),\n    },\n}));\n\nconst servicesOrder = [\n    \"/runtime/services/anvil/tests.yml\",\n    \"/runtime/services/anvil/tableau.yml\",\n    \"/runtime/services/anvil/users.yml\",\n    \"/runtime/services/anvil/files.yml\",\n    \"/runtime/services/anvil/email.yml\",\n    \"/runtime/services/anvil/secrets.yml\",\n    \"/runtime/services/facebook.yml\",\n    \"/runtime/services/google.yml\",\n    \"/runtime/services/anvil/microsoft.yml\",\n    \"/runtime/services/anvil/saml.yml\",\n    \"/runtime/services/stripe.yml\",\n    \"/runtime/services/kerberos.yml\",\n    \"/runtime/services/pki.yml\",\n];\n\nconst endingRe = /\\/([\\w-]+)\\.yml/;\n\ntype SidebarClassRecord = ReturnType<typeof useStyles>[\"classes\"];\n\ninterface PrimaryLinkProps {\n    icon: IconDefinition | undefined;\n    subNav?: PrimarySection;\n    navTarget?: NavTarget;\n    actionCreator?: () => AnvilAction;\n    onClick?: () => void;\n    primary?: boolean;\n    title: string;\n    canRemove?: boolean;\n    source?: string;\n    primarySection: PrimarySection | null;\n    secondaryNavOpen: boolean;\n    classes: SidebarClassRecord;\n    dispatch: AnvilDispatch;\n    linkClassName?: string;\n}\n\ntype PrimaryLinkConfig = Pick<\n    PrimaryLinkProps,\n    \"icon\" | \"subNav\" | \"navTarget\" | \"actionCreator\" | \"primary\" | \"title\" | \"canRemove\" | \"source\"\n>;\n\nconst serviceToProps = (\n    service: AppService,\n    app: AppState | null,\n    testingEnabled: boolean\n): (PrimaryLinkConfig & { key: string }) | null => {\n    const { source } = service;\n    const ending = source.match(endingRe)?.[1];\n    const serviceType = getServiceType(source as Parameters<typeof getServiceType>[0]);\n    const ret: PrimaryLinkConfig & { key: string } = {\n        key: ending!,\n        canRemove: true,\n        source,\n        icon: getServiceIcon(service),\n        title: capitalize(ending),\n    };\n    if (serviceType) {\n        ret.navTarget = { type: \"SERVICE\", service: serviceType };\n    }\n\n    if (ending === \"tests\" && !testingEnabled) {\n        return null;\n    }\n\n    switch (ending) {\n        case \"users\":\n        case \"files\":\n        case \"secrets\":\n        case \"email\":\n        case \"facebook\":\n        case \"google\":\n        case \"microsoft\":\n        case \"stripe\":\n        case \"kerberos\":\n            break;\n        case \"tests\":\n            ret.subNav = \"tests\";\n            delete ret.navTarget;\n            break;\n        case \"tableau\":\n            ret.title = \"Anvil X\";\n            break;\n        case \"hawthorn-deployment\":\n            ret.title = \"Hawthorn Deployment\";\n            break;\n        case \"saml\":\n            ret.title = \"SAML\";\n            break;\n        case \"pki\":\n            ret.title = \"PKI authentication\";\n            break;\n        default:\n            return null;\n    }\n    return ret;\n};\n\nexport const useDeleteService = (source?: string, title?: string) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    return useEvent(async () => {\n        const c =\n            source === \"/runtime/services/anvil/tests.yml\"\n                ? modal(\"confirmRemoveTesting\", {})\n                : confirm(\"Remove service\", `Are you sure you want to remove the ${title} service from your app?`);\n\n        if (await dispatch(c)) {\n            dispatch(removeService(source!, title!));\n        }\n    });\n};\n\nconst useIsAINewFeature = () => {\n    const hasAlreadyCreatedAgentConversation = useSelector(getUserHasCreatedConversation);\n    const daysRegistered = useSelector(getUserRegistrationAgeDays);\n\n    if (hasAlreadyCreatedAgentConversation) return false;\n    if (daysRegistered === undefined) return false;\n\n    const MS_PER_DAY = 24 * 60 * 60 * 1000;\n    const daysSinceLaunch = Math.floor((Date.now() - new Date(2026, 5, 24).getTime()) / MS_PER_DAY);\n\n    return daysRegistered < 10 || (daysSinceLaunch >= 0 && daysSinceLaunch < 10);\n};\n\nconst PrimaryLink = ({\n    icon,\n    subNav,\n    navTarget,\n    actionCreator,\n    onClick,\n    primary,\n    title,\n    canRemove,\n    source,\n    primarySection,\n    secondaryNavOpen,\n    classes,\n    dispatch,\n    linkClassName,\n}: PrimaryLinkProps) => {\n    const [triggered, setTriggered] = useState(false);\n\n    const onDeleteService = useDeleteService(source, title);\n\n    const tooltipEl = canRemove ? (\n        <div className=\"flex items-center gap-4\">\n            <span>{title}</span>\n            <Button small variant={\"highlight2\"} onClick={onDeleteService}>\n                <FontAwesomeIcon icon={faTrashAlt} />\n            </Button>\n        </div>\n    ) : (\n        title\n    );\n\n    const [tooltip, anchorRef] = useTooltip(tooltipEl, \"right\", { sticky: canRemove });\n\n    return (\n        <DropdownMenu\n            onSelectItem={onDeleteService}\n            render={(showMenu, anchor) => (\n                <>\n                    {tooltip}\n                    <li\n                        ref={anchorRef}\n                        className={cx(classes.primaryNavItem)}\n                        onContextMenu={(e) => {\n                            e.stopPropagation();\n                            e.preventDefault();\n                            canRemove && showMenu(e, e.currentTarget);\n                        }}>\n                        <LinkInternal\n                            className={cx(\n                                classes.primaryNavLink,\n                                {\n                                    [classes.linkActive]: subNav && primarySection === subNav && secondaryNavOpen,\n                                    [classes.triggered]: triggered,\n                                },\n                                linkClassName\n                            )}\n                            onClick={async () => {\n                                await dispatch(evaluateSecondaryNavState(subNav));\n\n                                if (subNav) {\n                                    dispatch(primaryNav(subNav));\n                                }\n\n                                if (navTarget) {\n                                    setTriggered(true);\n                                    setTimeout(() => setTriggered(false), 500);\n                                    dispatch(navigate(navTarget));\n                                }\n                                if (actionCreator) {\n                                    dispatch(actionCreator());\n                                }\n                                if (onClick) {\n                                    onClick();\n                                }\n                            }}>\n                            <div className={cx(classes.icon, primary && classes.primary)}>\n                                <FontAwesomeIcon icon={icon!} />\n                                {anchor}\n                            </div>\n                        </LinkInternal>\n                    </li>\n                </>\n            )}\n            items={(selectItem, hideMenu) => [\"Remove Service\"]}\n        />\n    );\n};\n\ninterface SecondaryNavContainerProps {\n    classes: SidebarClassRecord;\n    children: React.ReactNode;\n}\n\nexport const SecondaryNavContainer = ({ classes, children }: SecondaryNavContainerProps) => {\n    const secondaryNavRef = useRef<HTMLDivElement>(null);\n    useScrollWhenDragging(secondaryNavRef);\n\n    return (\n        <div ref={secondaryNavRef} className={cx(classes.secondaryNav, \"offset-vscrollbar\")}>\n            {children}\n        </div>\n    );\n};\n\nconst connector = connect((state: State) => ({\n    user: getUser(state),\n    app: getApp(state),\n    primarySection: getPrimarySection(state),\n    secondaryNavWidth: getSecondaryNavWidth(state),\n    secondaryNavOpen: getSecondaryNavOpen(state),\n    navMode: getNavMode(state),\n    invalidYaml: getInvalidYaml(state),\n    testingEnabled: getTestingEnabled(state),\n}));\n\ntype SidebarProps = AnvilConnectedProps<typeof connector>;\n\nexport const Sidebar = ({\n    user,\n    app,\n    primarySection,\n    secondaryNavWidth,\n    secondaryNavOpen,\n    navMode,\n    invalidYaml,\n    testingEnabled,\n    dispatch,\n}: SidebarProps) => {\n    const currentServices = useMemo(\n        () => orderBy(app?.config?.services || [], [({ source }) => servicesOrder.indexOf(source)]),\n        [app?.config?.services]\n    );\n    const scheduledTasks = app?.config?.scheduled_tasks;\n\n    const [overlayModeTooltip, overlayModeTooltipRef] = useTooltip(\n        navMode === \"overlay\" ? \"Click to use default Sidebar Mode\" : \"Click to enable Sidebar Overlay Mode\",\n        \"right\"\n    );\n\n    const { classes } = useStyles();\n\n    const secondaryNavContent = useMemo(() => {\n        switch (primarySection) {\n            case \"code\":\n                return <CodeNav />;\n            case \"search\":\n                return <SearchNav />;\n            case \"db\":\n                return <DatabaseNav />;\n            case \"settings\":\n                return <SettingsNav />;\n            case \"logs\":\n                return <LogsNav />;\n            case \"theme\":\n                return <ThemeNav />;\n            case \"ai\":\n                return <AgentSidebar />;\n            case \"tests\":\n                return testingEnabled ? <TestingNav /> : null;\n            default:\n                return null;\n        }\n    }, [primarySection, testingEnabled]);\n\n    const setDocked = useEvent(async (docked = true) => {\n        if (docked) {\n            dispatch(openNav());\n            await dispatch(setNavModeToDocked());\n        } else {\n            dispatch(closeNav());\n            await dispatch(setNavModeToOverlay());\n        }\n    });\n\n    const secondaryNavContainer = useMemo(() => {\n        return (\n            <>\n                <SecondaryNavContainer classes={classes}>\n                    <ErrorBoundary deps={[secondaryNavContent]}>{secondaryNavContent}</ErrorBoundary>\n                </SecondaryNavContainer>\n                {navMode === \"docked\" && secondaryNavOpen && (\n                    <div\n                        ref={overlayModeTooltipRef}\n                        className={\n                            \"absolute right-0 bottom-1 mb-2 flex h-16 w-14 cursor-pointer items-center justify-center rounded-l-full border-t border-b border-l border-sectionborder bg-light-bg3 pl-2 hover:bg-light-bg4 dark:border-dark-sectionborder dark:bg-dark-bg1 dark:hover:bg-dark-bg3\"\n                        }\n                        onClick={() => setDocked(false)}>\n                        <FontAwesomeIcon icon={faChevronsLeft} />\n                        {overlayModeTooltip}\n                    </div>\n                )}\n            </>\n        );\n    }, [secondaryNavContent, classes, overlayModeTooltipRef, overlayModeTooltip, navMode, secondaryNavOpen, setDocked]);\n\n    const [canScrollUp, setCanScrollUp] = useState(false);\n    const [canScrollDown, setCanScrollDown] = useState(false);\n    const sidebarScroller = useRef<HTMLUListElement>(null);\n\n    const checkScrollDirections = useEvent(() => {\n        const containerHeight = sidebarScroller.current?.offsetHeight ?? 0;\n        const contentHeight = sidebarScroller.current?.scrollHeight ?? 0;\n        const scrollTop = sidebarScroller.current?.scrollTop ?? 0;\n\n        setCanScrollDown(scrollTop < contentHeight - containerHeight - 1);\n        setCanScrollUp(scrollTop > 0);\n    });\n\n    useResizeObserver(sidebarScroller, checkScrollDirections);\n\n    const scroll = useEvent((delta: number) => {\n        const container = sidebarScroller.current;\n        if (container) {\n            const containerHeight = container.offsetHeight;\n            const scrollTop = container.scrollTop;\n\n            const newScrollPosition = scrollTop + (delta * containerHeight) / 2;\n\n            container.scroll({\n                top: newScrollPosition,\n                behavior: \"smooth\",\n            });\n        }\n    });\n\n    const closeTabsAndNavigate = async () => {\n        await dispatch(saveApp());\n        // await dispatch(waitFor(appSaveIsFinished, 5000)); // This is cute but unnecessary for now\n        await dispatch(closeAllTabs());\n        await dispatch(destroyRunnerRepls());\n        await dispatch(navigate({ type: \"START_PAGE\" }));\n    };\n\n    const onFinishResizeSecondaryNav = useCallback((size: number) => {\n        dispatch(secondaryNavResize(size));\n    }, []);\n\n    const props = {\n        classes,\n        dispatch,\n        primarySection,\n        secondaryNavOpen,\n    };\n\n    const resizePanel = useMemo(() => {\n        return (\n            <ResizePanel\n                panelSize={secondaryNavWidth}\n                horizontal={true}\n                handleAtStart={false}\n                containerLevel={2}\n                onFinishDrag={onFinishResizeSecondaryNav}>\n                {secondaryNavContainer}\n            </ResizePanel>\n        );\n    }, [secondaryNavWidth, onFinishResizeSecondaryNav, secondaryNavContainer]);\n\n    const secondaryNav = useMemo(() => {\n        if (!invalidYaml) {\n            if (secondaryNavContent && navMode === \"docked\" && secondaryNavOpen) {\n                return resizePanel;\n            } else if (navMode === \"overlay\") {\n                return (\n                    <>\n                        <div\n                            className={cx(\n                                \"pointer-events-none fixed top-[0rem] left-28 z-15 h-full w-full bg-black opacity-0 transition-opacity duration-100 ease-in dark:bg-grey-2\",\n                                { \"pointer-events-auto opacity-50\": secondaryNavContent && secondaryNavOpen }\n                            )}\n                            onClick={() => dispatch(hideIfOverlay())}\n                        />\n                        <div\n                            className={cx(\n                                \"absolute top-[0rem] h-full w-200 border border-sectionborder dark:border-dark-sectionborder\",\n                                \"z-15 transition-[left] duration-100 ease-in\",\n                                secondaryNavOpen ? \"left-28\" : \"-left-200\"\n                            )}>\n                            <div\n                                ref={overlayModeTooltipRef}\n                                className={\n                                    \"absolute -right-14 bottom-1 mb-2 flex h-16 w-14 cursor-pointer items-center justify-center rounded-r-full border border-sectionborder bg-light-bg3 pr-2 hover:bg-light-bg4 dark:border-dark-sectionborder dark:bg-dark-bg1 dark:hover:bg-dark-bg3\"\n                                }\n                                onClick={() => setDocked(true)}>\n                                <FontAwesomeIcon icon={faThumbtack} />\n                            </div>\n                            {overlayModeTooltip}\n                            {secondaryNavContainer}\n                        </div>\n                    </>\n                );\n            }\n        } else {\n            <></>;\n        }\n    }, [secondaryNavContent, resizePanel, secondaryNavContainer, navMode, secondaryNavOpen, setDocked, invalidYaml]);\n\n    const enableAgents = useAgentsEnabled();\n    const isAINewFeature = useIsAINewFeature();\n\n    if (invalidYaml) {\n        return null;\n    }\n\n    return (\n        <div className={classes.root}>\n            <div className={cx(classes.primaryNav, \"z-11 flex flex-col items-center justify-between\")}>\n                <div className={cx(\"min-h-1 shrink grow overflow-hidden\")}>\n                    <ul ref={sidebarScroller} onScroll={checkScrollDirections} className={classes.primaryNavList}>\n                        <PrimaryLink key=\"code\" icon={faFolderTree} subNav=\"code\" title=\"App\" {...props} />\n                        {enableAgents && (\n                            <PrimaryLink\n                                key=\"ai\"\n                                icon={faSparkle}\n                                subNav=\"ai\"\n                                onClick={() => dispatch(maybeDecideToOpenOpenConversation())}\n                                title=\"Build with AI\"\n                                linkClassName={cx(\n                                    \"relative isolate\",\n                                    // Glow effect\n                                    isAINewFeature && [\n                                        !(primarySection === \"ai\" && secondaryNavOpen) && \"[&_svg]:text-[#1BB0EE]\",\n                                        \"before:pointer-events-none before:absolute before:inset-[-8px] before:rounded-2xl before:content-['']\",\n                                        \"before:bg-[radial-gradient(closest-side,#1BB0EE85,transparent)]\",\n                                        \"before:-z-10 before:opacity-60 before:blur-md\",\n                                        \"before:animate-[ai-glow_4s_ease-in-out_infinite]\",\n                                        \"hover:before:bg-[radial-gradient(closest-side,#1BB0EE,transparent)] hover:before:[animation-play-state:paused] hover:[&_svg]:text-light-bg5 dark:hover:[&_svg]:text-dark-bg1\",\n                                    ]\n                                )}\n                                {...props}\n                            />\n                        )}\n                        <PrimaryLink key=\"db\" icon={faDatabase} subNav=\"db\" title=\"Data\" {...props} />\n                        <PrimaryLink\n                            key=\"settings\"\n                            icon={faCog}\n                            subNav=\"settings\"\n                            actionCreator={\n                                !secondaryNavOpen || primarySection !== \"settings\"\n                                    ? () => navigateToTabMatchingTarget({ type: \"SETTINGS\", section: \"ROOT\" })\n                                    : undefined\n                            }\n                            title=\"Settings\"\n                            {...props}\n                        />\n                        <PrimaryLink\n                            key=\"logs\"\n                            icon={faListUl}\n                            subNav=\"logs\"\n                            actionCreator={\n                                !secondaryNavOpen || primarySection !== \"logs\"\n                                    ? () => navigateToTabMatchingTarget({ type: \"SESSIONS\" }) //openOrFocusTabByUrlPrefix(\"/sessions\")\n                                    : undefined\n                            }\n                            title=\"Logs\"\n                            {...props}\n                        />\n                        <PrimaryLink key=\"theme\" icon={faPalette} subNav=\"theme\" title=\"Theme\" {...props} />\n                        <PrimaryLink key=\"search\" icon={faSearch} subNav=\"search\" title=\"Search\" {...props} />\n                        {scheduledTasks && (\n                            <PrimaryLink\n                                key=\"scheduled-tasks\"\n                                icon={faClock}\n                                navTarget={{ type: \"SCHEDULED_TASKS\" }}\n                                title=\"Scheduled Tasks\"\n                                canRemove={true}\n                                source=\"scheduled-tasks\"\n                                {...props}\n                            />\n                        )}\n                        {currentServices.map((service) => {\n                            const keyAndServiceProps = serviceToProps(service, app, testingEnabled);\n                            if (!keyAndServiceProps) return null;\n                            const { key, ...serviceProps } = keyAndServiceProps;\n                            return <PrimaryLink key={key} {...serviceProps} {...props} />;\n                        })}\n                        <div className={classes.separator} />\n                        <PrimaryLink\n                            key=\"add\"\n                            primary={true}\n                            icon={faPlus}\n                            actionCreator={addServiceWithModal}\n                            {...props}\n                            title=\"Add\"\n                        />\n                        <div className={classes.spring} />\n                    </ul>\n                </div>\n                {(canScrollUp || canScrollDown) && (\n                    <div className={\"w-full\"}>\n                        <div\n                            className={\n                                \"flex items-center justify-around border-t border-sectionborder p-2 dark:border-dark-sectionborder\"\n                            }>\n                            {canScrollUp ? (\n                                <FontAwesomeIcon\n                                    icon={faChevronUp}\n                                    className={\"cursor-pointer hover:text-primary\"}\n                                    onClick={() => scroll(-1)}\n                                />\n                            ) : (\n                                <FontAwesomeIcon icon={faChevronUp} className={\"text-grey-0 dark:text-dark-bg3\"} />\n                            )}\n                            {canScrollDown ? (\n                                <FontAwesomeIcon\n                                    icon={faChevronDown}\n                                    className={\"cursor-pointer hover:text-primary\"}\n                                    onClick={() => scroll(1)}\n                                />\n                            ) : (\n                                <FontAwesomeIcon icon={faChevronDown} className={\"text-grey-0 dark:text-dark-bg3\"} />\n                            )}\n                        </div>\n                    </div>\n                )}\n            </div>\n            {secondaryNav}\n        </div>\n    );\n};\n\nexport default connector(Sidebar);\n","import * as React from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faQuestion } from \"@fortawesome/free-solid-svg-icons\";\nimport { faCloudUpload, faFlask, faServer } from \"@fortawesome/pro-light-svg-icons\";\nimport { faCheck, faPencil, faTimes } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { EmailServiceCTA } from \"@/components/reusable/CollapsibleCTA\";\nimport { getSubscription } from \"@/controllers/ide\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport type { ServiceTab } from \"@/types/tabs\";\nimport * as api from \"@/api\";\nimport { useEffectAsync } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { getAppOrigins } from \"../../controllers/app\";\nimport { encryptPassword, testSmtp } from \"../../controllers/app/emailServices\";\nimport { getPublishInfo } from \"../../controllers/environments\";\nimport { modal } from \"../../controllers/modals\";\nimport { getEmailService, updateService } from \"../../controllers/services\";\nimport { useUpdateTabTitle } from \"../../controllers/tabs\";\nimport { makeStyles } from \"../../theme/styles\";\nimport { cx } from \"../../theme/styles\";\nimport { Button } from \"../reusable/Button\";\nimport { CheckBox, DropDown, InputLabel } from \"../reusable/Forms\";\nimport { HelpLink } from \"../reusable/HelpLink\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { useSaveIndicator } from \"../reusable/SaveIndicator\";\nimport { ContentTextInput } from \"../reusable/SharedComponents\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport TextInput from \"../reusable/TextInput\";\nimport TabToolbar from \"./TabToolbar\";\n\nlet useStyles = makeStyles()((theme) => ({\n    pagePanel: {\n        padding: \"1rem 4rem\",\n        width: \"90rem\",\n        borderRight: \"1px solid \" + theme.settings.separator.toString(),\n        background: theme.settings.background.toString(),\n        flexGrow: 1,\n        flexShrink: 0,\n    },\n    container: {\n        height: \"calc(100% - 5rem)\",\n        background: theme.settings.rightBarBackground.toString(),\n        display: \"flex\",\n        flexDirection: \"column\",\n        overflowY: \"scroll\",\n    },\n    alertBanner: {\n        width: \"auto\",\n        margin: \"1rem\",\n        border: \"1px solid \" + theme.emailService.alert.borderColor.toString(),\n        background: theme.emailService.alert.backgroundColor.toString(),\n        padding: \"2rem\",\n        borderRadius: \"2px\",\n        textAlign: \"center\",\n    },\n    customServerForm: {\n        display: \"grid\",\n        gridTemplateColumns: \"1fr 5fr\",\n        gap: \"1rem 3rem\",\n        alignItems: \"baseline\",\n        // width: '90%',\n    },\n    promptLabel: {\n        fontWeight: 700,\n        textAlign: \"right\",\n        margin: 0,\n        color: theme.palette.fg1.toString(),\n    },\n    domainEnvs: {\n        display: \"grid\",\n        gridTemplateColumns: \"1fr 3fr\",\n        gap: \"1rem 3rem\",\n        width: \"60%\",\n        marginBottom: \"3rem\",\n        marginLeft: \"10rem\",\n    },\n    failed: {\n        color: theme.palette.danger.toString(),\n    },\n    succeeded: {\n        color: theme.palette.highlight.toString(),\n    },\n\n    envBlock: {\n        marginTop: \"1rem\",\n        border: \"1px solid \" + theme.emailService.separator.toString(),\n        padding: \"0.75rem\",\n        borderRadius: \"4px\",\n        width: \"100%\",\n    },\n    placeholder: {\n        fontStyle: \"italic\",\n        fontWeight: 800,\n        color: theme.palette.fg1.fade(0.3).toString(),\n        //todo: set some color\n    },\n    title: {\n        fontWeight: 600,\n        color: theme.palette.fg1.toString(),\n    },\n}));\n\ntype PublishInfo = ReturnType<typeof getPublishInfo>;\n\nconst connector = connect((state: State) => ({\n    emailService: getEmailService(state),\n    subscription: getSubscription(state),\n    publishInfo: getPublishInfo(state),\n    origins: getAppOrigins(state)!,\n}));\n\ntype EmailServiceTabProps = AnvilConnectedProps<typeof connector> & {\n    tab: ServiceTab;\n};\n\nconst EmailServiceTab = ({ tab, emailService, subscription, publishInfo, origins, dispatch }: EmailServiceTabProps) => {\n    const { classes } = useStyles();\n\n    const [customHost, setCustomHost] = useState(emailService?.server_config?.smtp_host || \"\");\n    const [customPort, setCustomPort] = useState(emailService?.server_config?.smtp_port?.toString() || \"\");\n    const [customEncryption, setCustomEncryption] = useState(emailService?.server_config?.smtp_encryption || \"\");\n    const [customUsername, setCustomUsername] = useState(emailService?.server_config?.smtp_user || \"\");\n    const [customPassword, setCustomPassword] = useState(\"\");\n\n    const [saveEncryptionIndicator, setEncryptionSaved] = useSaveIndicator();\n    const [settingsTested, setSettingsTested] = useState(false);\n    const [connectionSucceed, setConnectionSucceed] = useState<boolean | null>(null);\n    const [settingPassword, setSettingPassword] = useState(false);\n    const [savePasswordIndicator, setPasswordSaved] = useSaveIndicator();\n    const [disableTest, setDisableTest] = useState(false);\n\n    const passwordRef = useRef<HTMLInputElement>(null);\n\n    const { privateEnvs, publicEnvs, customEnvs, isPublished } = publishInfo;\n\n    useUpdateTabTitle(tab, \"Email\");\n\n    const handleSetPassword = useEvent(() => {\n        setSettingPassword(true);\n        passwordRef.current?.focus();\n    });\n\n    useEffect(() => {\n        setSettingsTested(false);\n    }, [emailService?.server_config]);\n\n    const testMode = useMemo(\n        () => emailService?.server_config?.test_mode || false,\n        [emailService?.server_config?.test_mode]\n    );\n    const customMailServer = useMemo(\n        () => emailService?.server_config?.custom_smtp || false,\n        [emailService?.server_config?.custom_smtp]\n    );\n\n    const testModeBanner = useMemo(() => {\n        return (\n            <div className={cx(classes.alertBanner)}>\n                The Email service is currently in <b>Test</b> mode. All outgoing emails will be redirected to the app\n                owner.\n                <br />\n                <LinkInternal onClick={() => toggleSetting(\"test_mode\")}>\n                    Switch to <b>Live</b>\n                </LinkInternal>{\" \"}\n                mode to allow sending emails.\n            </div>\n        );\n    }, [classes, testMode]);\n\n    const customServerBanner = useMemo(\n        () => (\n            <div className={cx(classes.alertBanner)}>\n                <b>Please note:</b> You have configured a custom SMTP server. Anvil will let you send messages from any\n                address and domain, but your SMTP server may impose restrictions on sender domains.{\" \"}\n            </div>\n        ),\n        [classes]\n    );\n\n    const toggleSetting = useEvent(async (property: string) => {\n        const updatedValue = !emailService?.server_config?.[property];\n        await dispatch(updateService(\"email\", [\"server_config\", property], updatedValue));\n    });\n\n    const updateCustomSMTPSetting = useEvent(\n        async (property: string, newValue: unknown) =>\n            await dispatch(updateService(\"email\", [\"server_config\", property], newValue))\n    );\n\n    const testSettings = useEvent(async () => {\n        setDisableTest(true);\n        setSettingsTested(false);\n        const success = await dispatch(testSmtp(emailService?.server_config));\n        setDisableTest(false);\n        setSettingsTested(true);\n        setConnectionSucceed(Boolean(success));\n    });\n\n    const updateEncryptionSetting = useEvent(async (newOption: string) => {\n        setCustomEncryption(newOption);\n        setEncryptionSaved(false);\n        await dispatch(updateService(\"email\", [\"server_config\", \"smtp_encryption\"], newOption));\n        setEncryptionSaved(true);\n    });\n\n    const handlePasswordSave = useEvent(async () => {\n        setPasswordSaved(false);\n        const { encrypted } = (await dispatch(encryptPassword(customPassword))) as { encrypted: string };\n        await updateCustomSMTPSetting(\"smtp_password\", encrypted);\n        setSettingPassword(false);\n        setPasswordSaved(true);\n    });\n\n    const customMailServerForm = useMemo(() => {\n        return (\n            <>\n                <div className={\"text-center\"}>\n                    <Heading level={2}>Custom SMTP Settings</Heading>\n                </div>\n                <div className={classes.customServerForm}>\n                    <label className={classes.promptLabel}>Host</label>\n                    <TextInput\n                        id=\"host\"\n                        placeholder={\"SMTP Host\"}\n                        initialValue={customHost}\n                        onChange={setCustomHost}\n                        onSave={() => updateCustomSMTPSetting(\"smtp_host\", customHost)}\n                    />\n\n                    <label htmlFor={\"port\"} className={classes.promptLabel}>\n                        Port\n                    </label>\n                    <TextInput\n                        inputType={\"number\"}\n                        id=\"port\"\n                        placeholder={\"Port\"}\n                        initialValue={customPort}\n                        onChange={setCustomPort}\n                        onSave={() => updateCustomSMTPSetting(\"smtp_port\", parseInt(customPort))}\n                    />\n\n                    <label htmlFor={\"encryption\"} className={classes.promptLabel}>\n                        Encryption\n                    </label>\n                    <InputLabel className={\"mb-8\"}>\n                        <DropDown value={customEncryption} onChange={(e) => updateEncryptionSetting(e.target.value)}>\n                            <option key={\"\"} value={\"\"}>\n                                None\n                            </option>\n                            <option key={\"ssl\"} value={\"ssl\"}>\n                                SSL\n                            </option>\n                            <option key={\"starttls\"} value={\"starttls\"}>\n                                STARTTLS\n                            </option>\n                        </DropDown>\n                        {saveEncryptionIndicator}\n                    </InputLabel>\n\n                    <label htmlFor={\"username\"} className={classes.promptLabel}>\n                        Username\n                    </label>\n                    <TextInput\n                        id=\"username\"\n                        placeholder={\"Username\"}\n                        initialValue={customUsername}\n                        onChange={setCustomUsername}\n                        onSave={() => updateCustomSMTPSetting(\"smtp_user\", customUsername)}\n                    />\n\n                    <label htmlFor={\"password\"} className={classes.promptLabel}>\n                        Password\n                    </label>\n                    {settingPassword ? (\n                        <div className={\"flex items-center pr-10\"}>\n                            <ContentTextInput\n                                ref={passwordRef}\n                                type={\"password\"}\n                                placeholder={\"Password\"}\n                                value={customPassword}\n                                onChange={(e) => {\n                                    setCustomPassword(e.target.value);\n                                }}\n                            />\n                            <Button className={\"mx-4\"} variant={\"primary\"} onClick={handlePasswordSave}>\n                                Save\n                            </Button>\n                            <Button onClick={() => setSettingPassword(false)}>Cancel</Button>\n                        </div>\n                    ) : (\n                        <div className={\"flex justify-between pr-10\"}>\n                            <div className={\"flex items-center\"}>\n                                <Button variant={\"primary\"} onClick={handleSetPassword}>\n                                    Set password\n                                </Button>\n                                {savePasswordIndicator}\n                            </div>\n                            <div>\n                                {settingsTested &&\n                                    (connectionSucceed ? (\n                                        <span className={classes.succeeded}>\n                                            <FontAwesomeIcon className={\"mr-4\"} icon={faCheck} /> Connection succeeded\n                                        </span>\n                                    ) : (\n                                        <span className={classes.failed}>\n                                            <FontAwesomeIcon className={\"mr-4\"} icon={faTimes} /> Connection failed\n                                        </span>\n                                    ))}\n                                <Button disabled={disableTest} className={\"ml-4\"} onClick={testSettings}>\n                                    <FontAwesomeIcon className={\"mr-4\"} icon={faQuestion} /> Test settings\n                                </Button>\n                            </div>\n                        </div>\n                    )}\n                </div>\n            </>\n        );\n    }, [\n        classes,\n        updateCustomSMTPSetting,\n        customEncryption,\n        customHost,\n        customPort,\n        customUsername,\n        customPassword,\n        settingPassword,\n        settingsTested,\n        savePasswordIndicator,\n        saveEncryptionIndicator,\n        connectionSucceed,\n        testSettings,\n    ]);\n\n    const [quotas, setQuotas] = useState<Awaited<ReturnType<typeof api.getQuota>> | null>(null);\n\n    useEffectAsync(async () => {\n        const results = await api.getQuota([\"email\"]);\n        setQuotas(results);\n    }, []);\n\n    const showOneEnv = useCallback(\n        (\n            env:\n                | PublishInfo[\"privateEnvs\"][number]\n                | PublishInfo[\"publicEnvs\"][number]\n                | PublishInfo[\"customEnvs\"][number]\n        ) => {\n            const domain = env.email_domain || origins.defaultHostname;\n            return (\n                <div className={\"mb-10\"}>\n                    <Heading level={2}>\n                        Your app is published at <code className={\"select-all\"}>{env.origin}</code>\n                    </Heading>\n                    <Text level={2}>\n                        Outgoing emails can be sent from{\" \"}\n                        <code className={\"select-all\"}>\n                            <span className={classes.placeholder}>anything</span>@{domain}\n                        </code>\n                        .\n                    </Text>\n                    {/*<Text level={3}>Addresses can be explicit (eg. accounts@{domain} or support@{domain}), and messages sent without an explicit <code>from</code> domain, as well as invalid addresses, will also come from this domain. </Text>*/}\n                    {env.email_domain && (\n                        <Text level={2}>\n                            You can receive messages sent to{\" \"}\n                            <code className={\"select-all\"}>\n                                <span className={classes.placeholder}>anything</span>@{domain}\n                            </code>\n                            .\n                        </Text>\n                    )}\n                    <Button icon={faPencil} small onClick={() => dispatch(modal(\"environments\", {}))}>\n                        Click here to customise the domain settings for this app\n                    </Button>\n                </div>\n            );\n        },\n        []\n    );\n\n    const oneOfManyEnvs = useCallback((env: PublishInfo[\"publicEnvs\"][number] | PublishInfo[\"customEnvs\"][number]) => {\n        if (!env.url) {\n            return null;\n        }\n        return (\n            <React.Fragment key={env.env_id}>\n                <div className={classes.envBlock}>\n                    <Text level={3}>\n                        Environment: <span className={classes.title}>{env.name || env.description}</span>\n                    </Text>\n                    <Text level={1}>\n                        Email sent from this environment can be from{\" \"}\n                        <code className={\"select-all\"}>\n                            <span className={classes.placeholder}>anything</span>@\n                            {env.email_domain || origins.defaultHostname}\n                        </code>\n                    </Text>\n                    {env.email_domain && (\n                        <Text level={1}>\n                            This environment will receive email sent to{\" \"}\n                            <code className={\"all-seflectable\"}>\n                                <span className={classes.placeholder}>anything</span>@{env.email_domain}\n                            </code>\n                        </Text>\n                    )}\n                </div>\n            </React.Fragment>\n        );\n    }, []);\n\n    const domains = useMemo(() => {\n        const allPublicEnvs = [...customEnvs, ...publicEnvs];\n\n        switch (allPublicEnvs.length) {\n            case 0:\n                return privateEnvs.length === 0 ? (\n                    <>\n                        <Text level={1}>\n                            You can send email from any address with the{\" \"}\n                            <code className={\"select-all\"}>{origins.defaultHostname}</code> domain.\n                        </Text>\n                        <div className={\"my-8 flex justify-center\"}>\n                            <Button\n                                icon={faCloudUpload}\n                                variant={\"primary\"}\n                                large\n                                onClick={() => dispatch(modal(\"environments\", {}))}>\n                                Publish this app to receive email\n                            </Button>\n                        </div>\n                    </>\n                ) : (\n                    <>{showOneEnv(privateEnvs[0])}</>\n                );\n            case 1:\n                return showOneEnv(allPublicEnvs[0]);\n            default:\n                return (\n                    <>\n                        <Text level={2}>\n                            Each environment has its own domain with which email can be sent and received. Below are\n                            your published environments for this app and their respective domains.{\" \"}\n                        </Text>\n                        {/*<Text level={2}>Outgoing emails without an explicit <code>from</code> domain, as well as invalid addresses will be sent from the environment's domain.</Text>*/}\n                        {/*<Text level={2}>You can receive messages sent to any address with the environment domain.</Text>*/}\n                        <div className={cx(\"mx-10 mb-8 flex flex-col\")}>\n                            {allPublicEnvs.map((env) => oneOfManyEnvs(env))}\n                        </div>\n                        <Button icon={faPencil} small onClick={() => dispatch(modal(\"environments\", {}))}>\n                            Click here to customise the domain settings for this app\n                        </Button>\n                    </>\n                );\n        }\n    }, [publicEnvs, privateEnvs, customEnvs]);\n\n    const emailQuota = useMemo(() => {\n        return (\n            !/enterprise/.test(subscription?.plan ?? \"\") && (\n                <>\n                    <div>\n                        <Heading level={1}>Quota</Heading>\n                        <>\n                            {quotas && (\n                                <>\n                                    <>\n                                        {quotas[\"email\"] === \"infinite\" ? (\n                                            <>Unlimited</>\n                                        ) : (\n                                            <>\n                                                {quotas[\"email\"] ? (\n                                                    <>\n                                                        <Heading level={3}>\n                                                            Remaining quote: {quotas[\"email\"].current_token_count}{\" \"}\n                                                            emails\n                                                        </Heading>\n                                                        <Text level={2}>\n                                                            You can send {quotas[\"email\"]?.[\"bucket-size\"]} emails per\n                                                            month on your current plan. Your quota will reset on the 1st\n                                                            of each month.\n                                                        </Text>\n                                                    </>\n                                                ) : (\n                                                    <>Unknown</>\n                                                )}\n                                            </>\n                                        )}\n                                    </>\n                                </>\n                            )}\n                        </>\n                    </div>\n                    <hr />\n                </>\n            )\n        );\n    }, [subscription, quotas]);\n\n    return (\n        <div className={\"flex h-full flex-col\"}>\n            <TabToolbar>\n                <Text>\n                    Send and receive email from your app.{\" \"}\n                    <HelpLink url={\"https://anvil.works/docs/email\"} iconRight inline>\n                        Learn more\n                    </HelpLink>\n                </Text>\n            </TabToolbar>\n            <div className={classes.container}>\n                <div className={classes.pagePanel}>\n                    <EmailServiceCTA />\n                    {testMode && testModeBanner}\n                    <Heading level={1}>Options</Heading>\n                    <div className={\"mx-5 grid grid-cols-2\"}>\n                        <div className={\"col-span-1\"}>\n                            <CheckBox checked={testMode} icon={faFlask} onChange={() => toggleSetting(\"test_mode\")}>\n                                Test Mode\n                            </CheckBox>\n                            <Text level={3}>All outgoing emails are redirected to the app owner.</Text>\n                        </div>\n\n                        <div className={\"col-span-1\"}>\n                            <CheckBox\n                                checked={customMailServer}\n                                icon={faServer}\n                                onChange={() => toggleSetting(\"custom_smtp\")}>\n                                Use Custom Mail Server\n                            </CheckBox>\n                            <Text level={3}>Enter SMTP settings to send email through your own mail server.</Text>\n                        </div>\n                    </div>\n                    {customMailServer && customMailServerForm}\n                    <hr />\n\n                    {emailQuota}\n\n                    <Heading level={1}>\n                        Domains <HelpLink inline url={\"/docs/email/sending_and_receiving#receiving-email\"} />\n                    </Heading>\n                    {customMailServer && customServerBanner}\n                    {domains}\n                    <hr />\n                    <div>\n                        <Heading level={1}>Examples</Heading>\n                        <Heading level={3}>Send a simple email</Heading>\n                        <Text level={2}>\n                            Send an email from{\" \"}\n                            <code className={\"select-text\"}>\n                                My App Support &lt;no-reply@{origins.defaultHostname}&gt;\n                            </code>\n                        </Text>\n                        <pre className={\"m-4 select-all\"}>\n                            {`anvil.email.send(from_name = \"My App Support\", \n                 to = \"alice@example.com\",\n                 subject = \"Welcome\",\n                 text = \"Welcome to My App!\")`}\n                        </pre>\n                        {isPublished && (\n                            <>\n                                <Heading level={3}>Receive Email</Heading>\n                                <Text level={2}>\n                                    This function will receive and reply to every email sent to any address with the{\" \"}\n                                    <code>{origins.defaultHostname}</code> domain\n                                </Text>\n                                <pre className={\"m-4 select-all\"}>\n                                    {`@anvil.email.handle_message()\ndef message_handler(msg):\n    print(\"Message received from %s\" % msg.addressees.from_address.raw_value)\n    msg.reply(text=\"Thanks for your email!\")`}\n                                </pre>\n                            </>\n                        )}\n                        <Heading level={3}>Send an email with attachment</Heading>\n                        <Text level={2}>\n                            Attaches a simple text file to an email. Of course, you could also attach arbitrary Media\n                            from a Data Table or elsewhere.\n                        </Text>\n                        <pre className={\"m-4 select-all\"}>\n                            {`import anvil\n\nanvil.email.send(from_name=\"My App Support\",\n                 to=\"alice@example.com\",\n                 subject=\"A File\",\n                 text=\"Here is a text file\",\n                 attachments=[anvil.BlobMedia(\"text/plain\", \"Text file contents\", name=\"test.txt\")])`}\n                        </pre>\n                        <HelpLink url={\"https://anvil.works/docs/email\"} iconRight inline>\n                            Click here for more code samples\n                        </HelpLink>\n                    </div>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport default connector(EmailServiceTab);\n","import { AnvilAsyncAction } from \"@/types\";\nimport * as api from \"../../api\";\nimport { getAppId, updateGlobalLoadingIndicator } from \"./index\";\n\nexport const encryptPassword =\n    (secretValue: string): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = getAppId(state);\n        return await api.encryptAppSecret(appId, false, false, \"email-service/smtp-password\", secretValue);\n    };\n\nexport const testSmtp =\n    (config: unknown): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = getAppId(state);\n        try {\n            dispatch(updateGlobalLoadingIndicator(true));\n            const r = await api.testSmtp(appId, config);\n            return r.success;\n        } finally {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n    };\n","import React, { useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport { EncryptedTextInput } from \"@/components/reusable/SharedComponents\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport { getFacebookService, getFacebookServiceSpec, updateService } from \"@/controllers/services\";\nimport { useUpdateTabTitle } from \"@/controllers/tabs\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport type { ServiceTab } from \"@/types/tabs\";\nimport useEvent from \"@/util/useEventCallback\";\nimport TextInput from \"../reusable/TextInput\";\nimport TabToolbar from \"./TabToolbar\";\n\nconst useStyles = makeStyles()((theme) => ({\n    promptLabel: {\n        textAlign: \"right\",\n        margin: 0,\n    },\n    container: {\n        height: \"calc(100% - 5rem)\",\n        background: theme.facebookService.background.toString(),\n        display: \"flex\",\n        flexDirection: \"column\",\n        overflowY: \"scroll\",\n    },\n    panel: {\n        padding: \"0 4rem\",\n        width: \"60rem\",\n        borderRight: \"1px solid \" + theme.facebookService.border.toString(),\n        background: theme.facebookService.panelBackground.toString(),\n    },\n}));\n\nconst connector = connect((state: State) => ({\n    fbServiceSpec: getFacebookServiceSpec(state),\n    fbService: getFacebookService(state),\n}));\n\ntype FacebookServiceTabProps = AnvilConnectedProps<typeof connector> & {\n    tab: ServiceTab;\n};\n\nlet FacebookServiceTab = ({ tab, fbServiceSpec, fbService, dispatch }: FacebookServiceTabProps) => {\n    const { classes } = useStyles();\n\n    const [fbAppId, setFbAppId] = useState<string>(fbService?.server_config?.app_id || \"\");\n    const [fbAppSecretSet, setFbAppSecretSet] = useState<boolean>(\n        !!(fbService?.server_config?.app_secret || fbService?.server_config?.app_secret_enc)\n    );\n\n    const updateFbServerSetting = useEvent(async (property: string, newValue: unknown) => {\n        await dispatch(updateService(\"facebook\", [\"server_config\", property], newValue));\n    });\n\n    const saveAppSecret = async (encrypted: string) => {\n        setFbAppSecretSet(true);\n        await updateFbServerSetting(\"app_secret_enc\", encrypted);\n        if (fbService?.server_config?.app_secret) {\n            await updateFbServerSetting(\"app_secret\", null);\n        }\n    };\n\n    useUpdateTabTitle(tab, \"Facebook API\");\n\n    return (\n        <div className={cx(\"flex h-full flex-col\")}>\n            <TabToolbar>\n                <Text className={\"p-unset\"} level={1}>\n                    Log users into your app with Facebook.&nbsp;\n                    <HelpLink iconRight inline url={\"/docs/integrations/facebook\"}>\n                        Learn More\n                    </HelpLink>\n                </Text>\n            </TabToolbar>\n            <div className={classes.container}>\n                <div className={cx(\"shrink-0 grow\", classes.panel)}>\n                    <Heading level={1}>Server Properties</Heading>\n                    <div>\n                        <TextInput\n                            title={\"Facebook App ID\"}\n                            id=\"fbAppId\"\n                            placeholder={\"App ID\"}\n                            initialValue={fbAppId}\n                            onChange={setFbAppId}\n                            onSave={(v) => updateFbServerSetting(\"app_id\", v)}\n                        />\n\n                        <EncryptedTextInput\n                            title={\"Facebook App Secret\"}\n                            setButtonText={fbAppSecretSet ? \"Update App Secret\" : \"Set App Secret\"}\n                            id=\"fbAppSecret\"\n                            placeholder={\"App Secret\"}\n                            initialValue={\"\"}\n                            secretRestrict={\"facebook-service/app-secret\"}\n                            onSave={saveAppSecret}\n                        />\n                    </div>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport default connector(FacebookServiceTab);\n","import React, { useCallback, useMemo, useRef, useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faChevronUp } from \"@fortawesome/pro-light-svg-icons/faChevronUp\";\nimport { faFile } from \"@fortawesome/pro-light-svg-icons/faFile\";\nimport { faFolder } from \"@fortawesome/pro-light-svg-icons/faFolder\";\nimport { faPencilAlt } from \"@fortawesome/pro-light-svg-icons/faPencilAlt\";\nimport { faSync } from \"@fortawesome/pro-light-svg-icons/faSync\";\nimport { faTrashAlt } from \"@fortawesome/pro-light-svg-icons/faTrashAlt\";\nimport { faUpload } from \"@fortawesome/pro-light-svg-icons/faUpload\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { initial, last, map, sortBy } from \"lodash-es\";\nimport { v4 as uuid } from \"uuid\";\nimport * as tableApi from \"@/api/tables\";\nimport { getAppId, getTableMappings, updateGlobalLoadingIndicator } from \"@/controllers/app\";\nimport { createTable, getDebugEnvironmentTableMapping, reloadTableMapping } from \"@/controllers/db\";\nimport { blockNavigation, unblockNavigation } from \"@/controllers/ide\";\nimport { alert, confirm, prompt } from \"@/controllers/modals\";\nimport { ensureRequiredFileServiceColsExist, getFileService } from \"@/controllers/services\";\nimport { invalidateTableDataQuery, useTableRowsInfiniteQuery } from \"@/controllers/table-data-query\";\nimport { useUpdateTabTitle } from \"@/controllers/tabs\";\nimport { recordActivity } from \"@/controllers/util\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport type { ColumnSpec } from \"@/types/database\";\nimport type { ServiceTab } from \"@/types/tabs\";\nimport { useStateWithReset } from \"@/util/hooks\";\nimport { Button } from \"../reusable/Button\";\nimport { Expander } from \"../reusable/Expander\";\nimport { DropDown } from \"../reusable/Forms\";\nimport { HelpLink } from \"../reusable/HelpLink\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { LoadingSpinner } from \"../reusable/LoadingSpinner\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport TabToolbar from \"./TabToolbar\";\n\ntype FileServiceClasses = \"selected\" | \"deleteFileIcon\";\n\nexport const useStyles = makeStyles<void, FileServiceClasses>()((theme, _props, classes) => ({\n    container: {\n        height: \"calc(100% - 5rem)\",\n        background: theme.dataFileService.background.toString(),\n        display: \"flex\",\n        flexDirection: \"column\",\n        overflowY: \"scroll\",\n    },\n    panel: {\n        padding: \"0 4rem\",\n        width: \"60rem\",\n        borderRight: \"1px solid \" + theme.dataFileService.border.toString(),\n        background: theme.dataFileService.panelBackground.toString(),\n    },\n    content: {\n        maxWidth: \"60rem\",\n    },\n    filePanel: {\n        border: \"1px solid \" + theme.sectionBorderColor.toString(),\n        background: theme.secondaryNav.background.toString(),\n    },\n    droppingFiles: {\n        outline: \"3px dashed \" + theme.palette.primary.toString(),\n        outlineOffset: \"0.3rem\",\n        background: theme.dataFileService.nodeBgHover.toString(),\n    },\n    selected: {},\n    childNode: {\n        borderRadius: \"1.5rem 0 0 1.5rem\",\n    },\n    node: {\n        padding: \"0 0.5rem\",\n        display: \"flex\",\n        \"&:hover\": {\n            background: theme.dataFileService.nodeBgHover.toString(),\n        },\n        [`&.${classes.selected}`]: {\n            background: theme.dataFileService.nodeSelectedBg.toString(),\n            [`& .${classes.deleteFileIcon}`]: {\n                opacity: 0.7,\n                \"&:hover\": {\n                    opacity: 0.9,\n                },\n                \"&:active\": {\n                    opacity: 0.5,\n                },\n            },\n        },\n    },\n    nodeName: {\n        flex: \"1 0 auto\",\n        color: theme.dataFileService.nodeColor.toString(),\n        paddingRight: \"1rem\",\n    },\n    nodeLink: {},\n    nodeIcon: {\n        width: \"2rem\",\n        display: \"inline-block\",\n        textAlign: \"center\",\n        color: theme.dataFileService.nodeColor.toString(),\n    },\n    expanderIcon: {\n        paddingLeft: \"0rem\",\n        transition: \"transform 0.1s\",\n    },\n    children: {\n        paddingLeft: \"2rem\",\n    },\n    uploadLink: {\n        color: theme.text.light.toString(),\n        paddingLeft: \"2rem\",\n    },\n    deleteFileIcon: {\n        padding: \"0 0.5rem\",\n        color: theme.dataFileService.actionIcon.toString(),\n        textAlign: \"center\",\n        width: \"2rem\",\n        opacity: 0.4,\n        \"&:hover\": {\n            opacity: 0.7,\n        },\n        \"&:active\": {\n            opacity: 0.5,\n        },\n    },\n    emptyPlaceholder: {\n        padding: \"2rem\",\n    },\n    emptyPlaceholderDivider: {\n        margin: \"1rem 2rem\",\n        marginBottom: 0,\n        borderColor: theme.sectionBorderColor.toString(),\n    },\n    learnMoreLink: {\n        color: theme.palette.primary.toString() + \"!important\",\n        textDecoration: \"none\",\n        \"&:hover\": {\n            textDecoration: \"underline !important\",\n        },\n    },\n}));\n\nconst fullPathToName = (path: string) => last(path.split(\"/\")) ?? path;\n\ntype FileNode = {\n    fullPath: string;\n    name: string;\n    children: FileNode[];\n    _folder?: boolean;\n    _row?: TableRowData;\n    mediaObject?: unknown;\n    contentHash?: string;\n};\n\ntype TableRowData = Record<string, unknown> & { id: string | number };\ntype TableRowsPage = { more?: number | string | null; rows: TableRowData[] };\ntype EntryColumnNames = \"file\" | \"file_version\" | \"path\";\ntype FileTableColumnIds = Partial<Record<EntryColumnNames, string>>;\ntype FileTableContext = {\n    selectedTableMapping: ConnectedTableMapping;\n    fileTable: ConnectedTable;\n    pathColId: string;\n    fileColId: string;\n    fileVersionColId: string;\n};\n\ntype FileSystemEntry = {\n    fullPath: string;\n    isFile: boolean;\n    isDirectory: boolean;\n};\n\ntype FileSystemFileEntry = FileSystemEntry & {\n    isFile: true;\n    isDirectory: false;\n    file(success: (file: File) => void, error?: (error: DOMException) => void): void;\n};\n\ntype FileSystemDirectoryReader = {\n    readEntries(success: (entries: DroppedEntry[]) => void, error?: (error: DOMException) => void): void;\n};\n\ntype FileSystemDirectoryEntry = FileSystemEntry & {\n    isFile: false;\n    isDirectory: true;\n    createReader(): FileSystemDirectoryReader;\n};\n\ntype DroppedEntry = FileSystemFileEntry | FileSystemDirectoryEntry;\ntype DataTransferItemWithEntry = DataTransferItem & {\n    getAsEntry?: () => DroppedEntry | null;\n    webkitGetAsEntry?: () => DroppedEntry | null;\n};\n\ntype FileOrFolderProps = {\n    node: FileNode;\n    selectedPath?: string | null;\n    onSelect(node: FileNode): void;\n    onDelete(node: FileNode): void;\n    onRename(node: FileNode): void;\n    isChild?: boolean;\n};\n\nconst FileOrFolder = ({ node, selectedPath, onSelect, onDelete, onRename, isChild = false }: FileOrFolderProps) => {\n    const { classes } = useStyles();\n    const [isExpanded, setIsExpanded] = useState(false);\n    const canExpand = node.children?.length > 0;\n\n    const isSelected = selectedPath === node.fullPath;\n\n    return (\n        <div>\n            <div\n                className={cx(classes.node, isSelected && classes.selected, isChild && classes.childNode)}\n                onClick={() => onSelect(node)}\n                onDoubleClick={() => node._folder && setIsExpanded((e) => !e)}>\n                <div className={cx(classes.nodeIcon, classes.nodeLink)}>\n                    {canExpand && (\n                        <LinkInternal onClick={() => setIsExpanded((e) => !e)}>\n                            <FontAwesomeIcon\n                                fixedWidth\n                                className={classes.expanderIcon}\n                                icon={faChevronUp}\n                                rotation={isExpanded ? 180 : 90}\n                            />\n                        </LinkInternal>\n                    )}\n                </div>\n                <div className={classes.nodeIcon}>\n                    <FontAwesomeIcon fixedWidth icon={node._folder ? faFolder : faFile} />\n                </div>\n                <div className={classes.nodeName}>{node.name}</div>\n                {!node._folder && (\n                    <LinkInternal className={classes.deleteFileIcon} onClick={() => onRename(node)}>\n                        <FontAwesomeIcon icon={faPencilAlt} />\n                    </LinkInternal>\n                )}\n                <LinkInternal className={classes.deleteFileIcon} onClick={() => onDelete(node)}>\n                    <FontAwesomeIcon icon={faTrashAlt} />\n                </LinkInternal>\n            </div>\n            {canExpand && (\n                <Expander isOpen={isExpanded}>\n                    <div className={classes.children}>\n                        {node.children?.map((c) => (\n                            <FileOrFolder\n                                node={c}\n                                key={c.fullPath}\n                                selectedPath={selectedPath}\n                                onSelect={onSelect}\n                                onDelete={onDelete}\n                                onRename={onRename}\n                                isChild\n                            />\n                        ))}\n                    </div>\n                </Expander>\n            )}\n        </div>\n    );\n};\n\nconst connector = connect((state: State) => ({\n    appId: getAppId(state)!,\n    fileService: getFileService(state),\n    tableMappings: getTableMappings(state),\n    debugTableMapping: getDebugEnvironmentTableMapping(state),\n}));\n\ntype FileServiceTabProps = AnvilConnectedProps<typeof connector> & {\n    tab: ServiceTab;\n};\n\ntype ConnectedTableMapping = NonNullable<FileServiceTabProps[\"tableMappings\"]>[number];\ntype ConnectedTable = ConnectedTableMapping[\"tables\"][number];\n\nconst FileServiceTab = ({\n    tab,\n    appId,\n    fileService,\n    tableMappings,\n    debugTableMapping,\n    dispatch,\n}: FileServiceTabProps) => {\n    useUpdateTabTitle(tab, \"Data Files\");\n\n    let { classes } = useStyles();\n    const queryClient = useQueryClient();\n    let [selectedTableMapping, setSelectedTableMapping] = useStateWithReset<ConnectedTableMapping | undefined>(\n        debugTableMapping\n    ); // We don't really need withReset here, we really just want it to have a useful initial non-null value\n    const selectTableMapping = (e: React.ChangeEvent<HTMLSelectElement>) => {\n        const id = e.target.value === \"default\" ? null : parseInt(e.target.value);\n        setSelectedTableMapping((tableMappings ?? []).find((t) => t.table_mapping_id === id));\n    };\n\n    let [fileTable, fileTableCols] = useMemo<[ConnectedTable | undefined, FileTableColumnIds]>(() => {\n        const table = selectedTableMapping?.tables.find(\n            (t) =>\n                t.python_name === (fileService?.server_config?.file_table || \"files\") ||\n                t.id === fileService?.server_config?.file_table\n        );\n        const colsByName: FileTableColumnIds = {};\n        for (const [id, col] of Object.entries(table?.columns ?? {}) as Array<[string, ColumnSpec]>) {\n            if (col.name === \"path\" || col.name === \"file\" || col.name === \"file_version\") {\n                colsByName[col.name] = id;\n            }\n        }\n\n        return [table, colsByName];\n    }, [selectedTableMapping, fileService]);\n\n    const requireFileTableContext = useCallback((): FileTableContext => {\n        if (!selectedTableMapping || !fileTable) {\n            throw new Error(\"Expected file table context\");\n        }\n        const pathColId = fileTableCols.path;\n        const fileColId = fileTableCols.file;\n        const fileVersionColId = fileTableCols.file_version;\n        if (!pathColId || !fileColId || !fileVersionColId) {\n            throw new Error(\"Expected file table columns\");\n        }\n        return { selectedTableMapping, fileTable, pathColId, fileColId, fileVersionColId };\n    }, [selectedTableMapping, fileTable, fileTableCols]);\n\n    const fileTableContext = useMemo(() => {\n        try {\n            return requireFileTableContext();\n        } catch {\n            return null;\n        }\n    }, [requireFileTableContext]);\n\n    const invalidateFileTableData = useCallback(async () => {\n        if (!fileTableContext) return;\n        await invalidateTableDataQuery(queryClient, {\n            appId,\n            tableId: fileTableContext.fileTable.id,\n            tableMappingId: fileTableContext.selectedTableMapping.table_mapping_id,\n        });\n    }, [appId, fileTableContext, queryClient]);\n\n    const createFileTable = useCallback(async () => {\n        if (!fileTable) {\n            const tableMappingId = selectedTableMapping?.table_mapping_id ?? null;\n            await dispatch(createTable(tableMappingId, \"Files\"));\n            // TODO: Cope with the fileService having a table name other than \"files\"\n            await dispatch(ensureRequiredFileServiceColsExist());\n            await dispatch(reloadTableMapping(tableMappingId));\n            await invalidateFileTableData();\n        }\n    }, [selectedTableMapping, fileTable, invalidateFileTableData]);\n\n    const fileRowsQuery = useTableRowsInfiniteQuery({\n        appId,\n        tableId: fileTableContext?.fileTable.id ?? 0,\n        tableMappingId: fileTableContext?.selectedTableMapping.table_mapping_id ?? null,\n        columnSorting: [],\n        enabled: !!fileTableContext,\n    });\n\n    const [files, flatFiles] = useMemo<[FileNode[], FileNode[]]>(() => {\n        if (!fileTableContext) {\n            return [[], []];\n        }\n\n        const rows = fileRowsQuery.data?.pages.flatMap((page) => page.rows as TableRowData[]) ?? [];\n        const flatFiles: FileNode[] = rows.map((row) => ({\n            fullPath: String(row[fileTableContext.pathColId] ?? \"\"),\n            name: fullPathToName(String(row[fileTableContext.pathColId] ?? \"\")),\n            mediaObject: row[fileTableContext.fileColId],\n            contentHash: (() => {\n                const value = row[fileTableContext.fileVersionColId];\n                return typeof value === \"string\" ? value : undefined;\n            })(),\n            children: [],\n            _row: row,\n        }));\n\n        const root: FileNode = { fullPath: \"\", name: \"\", children: [] };\n        for (const f of flatFiles) {\n            const path = f.fullPath.split(\"/\");\n            let parent: FileNode = root;\n            let fullPath = \"\";\n            for (let p of initial(path)) {\n                let newParent = parent.children.find((c) => c.name === p);\n                if (fullPath) fullPath += \"/\";\n                fullPath += p;\n                if (!newParent) {\n                    newParent = { _folder: true, fullPath, name: p, children: [] };\n                    parent.children.push(newParent);\n                }\n                parent = newParent;\n            }\n            parent.children.push(f);\n        }\n\n        const sort = (f: FileNode) => {\n            f.children = sortBy(f.children, \"_folder\", \"name\");\n            for (const c of f.children) {\n                sort(c);\n            }\n        };\n        sort(root);\n\n        return [root.children, flatFiles];\n    }, [fileRowsQuery.data, fileTableContext]);\n\n    const refreshFilesNow = useCallback(async () => {\n        if (selectedTableMapping) {\n            await dispatch(reloadTableMapping(selectedTableMapping.table_mapping_id));\n        }\n        await invalidateFileTableData();\n    }, [selectedTableMapping, invalidateFileTableData]);\n\n    const uploader = useRef<HTMLInputElement>(null);\n    const [uploadPath, setUploadPath] = useState(\"\");\n    const upload = useCallback((folder: string) => {\n        setUploadPath(folder);\n        uploader.current?.click();\n    }, []);\n\n    const uploadFiles = useCallback(\n        async (filesToUpload: Array<{ path: string; blob: File }>) => {\n            const conflicts: Array<[FileNode, { path: string; blob: File }]> = [];\n            for (const f of filesToUpload) {\n                const conflict = flatFiles.find(({ fullPath }) => fullPath === f.path);\n                if (conflict) {\n                    conflicts.push([conflict, f]);\n                }\n            }\n\n            if (conflicts.length > 0) {\n                if (\n                    await dispatch(\n                        confirm(\n                            \"Overwrite existing files?\",\n                            <div>\n                                The following files already exist:\n                                <ul>\n                                    {conflicts.map(([c, f]) => (\n                                        <li key={c.fullPath} className={\"font-bold\"}>\n                                            {c.fullPath}\n                                        </li>\n                                    ))}\n                                </ul>\n                            </div>,\n                            \"Overwrite\",\n                            \"Skip these files\"\n                        )\n                    )\n                ) {\n                    // Overwrite - this is the default.\n                } else {\n                    // Skip conflicting files\n                    filesToUpload = filesToUpload.filter((f) => !conflicts.find(([c, ff]) => ff === f));\n                }\n            }\n\n            const uploadAborter = new AbortController();\n            dispatch(\n                blockNavigation(\"fileUpload\", () => {\n                    uploadAborter.abort();\n                    console.log(\"abort!\", uploadAborter.signal.aborted);\n                })\n            );\n            try {\n                dispatch(updateGlobalLoadingIndicator(true));\n                const errors: Array<[{ path: string; blob: File }, unknown]> = [];\n                const tableContext = requireFileTableContext();\n                for (const file of filesToUpload) {\n                    const overwrite = conflicts.find(([c, f]) => f === file)?.[0];\n                    const overwriteRowId = overwrite?._row?.id;\n                    if (overwrite && overwriteRowId == null) {\n                        throw new Error(\"Expected existing file row for overwrite\");\n                    }\n                    const ensuredOverwriteRowId = overwriteRowId as string | number | undefined;\n                    const { error } = await tableApi.uploadMedia(\n                        appId,\n                        tableContext.selectedTableMapping.table_mapping_id,\n                        tableContext.fileTable.id,\n                        overwriteRowId,\n                        tableContext.fileColId,\n                        file.blob,\n                        {\n                            [tableContext.pathColId]: file.path,\n                            [tableContext.fileVersionColId]: uuid(),\n                        },\n                        (percentUploaded: number) => {\n                            dispatch(updateGlobalLoadingIndicator(`Uploading: ${Math.round(percentUploaded)}%`));\n                        },\n                        uploadAborter\n                    );\n                    if (error) {\n                        errors.push([file, error]);\n                    } else if (overwrite) {\n                        await tableApi.updateTableRow(\n                            appId,\n                            tableContext.selectedTableMapping.table_mapping_id,\n                            tableContext.fileTable.id,\n                            ensuredOverwriteRowId!,\n                            {\n                                [tableContext.fileVersionColId]: uuid(),\n                            }\n                        );\n                    }\n                    if (uploadAborter.signal.aborted) {\n                        break;\n                    }\n                }\n                await invalidateFileTableData();\n                if (errors.length > 0) {\n                    // No await\n                    dispatch(\n                        alert(\n                            \"Upload failed\",\n                            <div>\n                                <ul>\n                                    {errors.map(([file, error]) => (\n                                        <li key={file.path}>\n                                            <span className={\"font-bold\"}>{file.blob.name}</span>: {String(error)}\n                                        </li>\n                                    ))}\n                                </ul>\n                            </div>\n                        )\n                    );\n                }\n            } finally {\n                dispatch(updateGlobalLoadingIndicator(false));\n                dispatch(unblockNavigation(\"fileUpload\"));\n            }\n        },\n        [appId, flatFiles, invalidateFileTableData, requireFileTableContext]\n    );\n\n    const chooseFile = useCallback(\n        async (e: React.ChangeEvent<HTMLInputElement>) => {\n            const files = [...(e.target.files || [])];\n            e.target.value = \"\";\n            await uploadFiles(\n                map(files, (f) => ({\n                    path: (uploadPath ? uploadPath + \"/\" : \"\") + f.name,\n                    blob: f,\n                }))\n            );\n            dispatch(recordActivity(\"uploadDataFiles\", { fileSizes: files.map(({ size }) => size) }));\n        },\n        [uploadPath, uploadFiles]\n    );\n\n    const [isDropping, setIsDropping] = useState(0);\n    const dragEnter = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n        e.preventDefault();\n        setIsDropping((d) => d + 1);\n    }, []);\n    const dragLeave = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n        e.preventDefault();\n        setIsDropping((d) => d - 1);\n    }, []);\n    const dragOver = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n        e.preventDefault();\n        e.dataTransfer.dropEffect = \"copy\";\n        //console.log(\"OVER\", e.dataTransfer.files, e.dataTransfer.effectAllowed);\n    }, []);\n    const drop = useCallback(\n        async (e: React.DragEvent<HTMLDivElement>) => {\n            e.preventDefault();\n            setIsDropping(0);\n\n            const droppedFileEntries = Array.from(e.dataTransfer.items)\n                .filter((item): item is DataTransferItemWithEntry => item.kind === \"file\")\n                .map((item) => (item.getAsEntry || item.webkitGetAsEntry)?.call(item))\n                .filter((entry): entry is DroppedEntry => entry != null);\n\n            const files: FileSystemFileEntry[] = [];\n            const walk = async (entry: DroppedEntry) => {\n                if (entry.isFile) {\n                    files.push(entry);\n                } else if (entry.isDirectory) {\n                    const children: DroppedEntry[] = [];\n                    const reader = entry.createReader();\n\n                    // Yes, this is a stupid API.\n                    const readPage = () =>\n                        new Promise<DroppedEntry[]>((resolve, reject) => reader.readEntries(resolve, reject));\n                    let page: DroppedEntry[];\n                    while ((page = await readPage()).length) {\n                        children.push(...page);\n                    }\n                    for (const c of children) {\n                        await walk(c);\n                    }\n                } else {\n                    // What else could it be?!\n                    console.warn(\"Unknown file entry:\", entry);\n                }\n            };\n            for (const f of droppedFileEntries) {\n                await walk(f);\n            }\n\n            // files is now a flat list of every file dropped.\n            const processedFiles = await Promise.all(\n                files.map(async (entry) => ({\n                    path: entry.fullPath.substring(1),\n                    blob: (await new Promise((resolve, reject) => entry.file(resolve, reject))) as File,\n                }))\n            );\n\n            await uploadFiles(processedFiles);\n        },\n        [uploadFiles]\n    );\n\n    const onDeleteNode = useCallback(\n        async (node: FileNode) => {\n            if (\n                await dispatch(\n                    confirm(\n                        `Delete ${node._folder ? \"folder\" : \"file\"}?`,\n                        `Are you sure you want to delete '${node.name}' ${node._folder ? \" and all its contents\" : \"\"}?`\n                    )\n                )\n            ) {\n                const walk = async (node: FileNode) => {\n                    if (node._folder) {\n                        for (const c of node.children) {\n                            await walk(c);\n                        }\n                    } else {\n                        if (!node._row) {\n                            throw new Error(\"Expected file row\");\n                        }\n                        const tableContext = requireFileTableContext();\n                        await tableApi.deleteTableRow(\n                            appId,\n                            tableContext.selectedTableMapping.table_mapping_id,\n                            tableContext.fileTable.id,\n                            node._row.id\n                        );\n                    }\n                };\n                await walk(node);\n                await invalidateFileTableData();\n            }\n        },\n        [appId, invalidateFileTableData, requireFileTableContext]\n    );\n\n    const onRenameNode = useCallback(\n        async (node: FileNode) => {\n            const newName = await dispatch(\n                prompt(`Rename ${node.name}`, `Enter a new name for ${node.name}`, node.name)\n            );\n            if (newName) {\n                if (!node._row) {\n                    throw new Error(\"Expected file row\");\n                }\n                const tableContext = requireFileTableContext();\n                const newPath = node.fullPath.substr(0, node.fullPath.lastIndexOf(\"/\") + 1) + newName;\n                await tableApi.updateTableRow(\n                    appId,\n                    tableContext.selectedTableMapping.table_mapping_id,\n                    tableContext.fileTable.id,\n                    node._row.id,\n                    {\n                        [tableContext.pathColId]: newPath,\n                    }\n                );\n                await invalidateFileTableData();\n            }\n        },\n        [appId, invalidateFileTableData, requireFileTableContext]\n    );\n\n    const [selectedNode, setSelectedNode] = useState<FileNode | null>(null);\n\n    return (\n        <div className={cx(\"flex h-full flex-col\")}>\n            <TabToolbar>\n                <Text className={\"p-unset\"} level={1}>\n                    Embed files in your app - great for ML models and static datasets.&nbsp;\n                    <HelpLink iconRight inline url={\"/docs/working-with-files/data-files\"}>\n                        Learn More\n                    </HelpLink>\n                </Text>\n            </TabToolbar>\n            <div className={classes.container}>\n                <div className={cx(\"shrink-0 grow\", classes.panel)}>\n                    <input\n                        ref={uploader}\n                        style={{ position: \"absolute\", left: -99999 }}\n                        type=\"file\"\n                        multiple\n                        onChange={chooseFile}\n                    />\n                    <div className={classes.content}>\n                        <Heading level={1}>Data Files</Heading>\n\n                        <Text>\n                            Data files are stored in your app's Data Tables, and can be accessed directly from server\n                            code.{\" \"}\n                        </Text>\n\n                        <div className={\"mb-4 flex items-center\"}>\n                            {(tableMappings?.length ?? 0) > 1 && (\n                                <div className={cx(\"flex items-center\")}>\n                                    <Text level={3} style={{ margin: 0, marginRight: 10 }}>\n                                        Database:\n                                    </Text>\n                                    <DropDown\n                                        variant={\"small\"}\n                                        onChange={selectTableMapping}\n                                        value={selectedTableMapping?.table_mapping_id || \"default\"}>\n                                        {(tableMappings ?? []).map((t) => (\n                                            <option key={t.table_mapping_id} value={t.table_mapping_id || \"default\"}>\n                                                {t.name}\n                                            </option>\n                                        ))}\n                                    </DropDown>\n                                </div>\n                            )}\n                            <div className={cx(\"grow\")}></div>\n                            {fileTable && (\n                                <div style={{ display: \"flex\", justifyContent: \"right\" }}>\n                                    <Button style={{ float: \"right\", marginRight: \"1rem\" }} onClick={refreshFilesNow}>\n                                        <FontAwesomeIcon icon={faSync} />\n                                    </Button>\n                                    <Button style={{ float: \"right\" }} icon={faUpload} onClick={() => upload(\"\")}>\n                                        Upload\n                                    </Button>\n                                </div>\n                            )}\n                        </div>\n                        {fileTable ? (\n                            <div\n                                className={cx(classes.filePanel, isDropping > 0 && classes.droppingFiles)}\n                                onDragOver={dragOver}\n                                onDrop={drop}\n                                onDragEnter={dragEnter}\n                                onDragLeave={dragLeave}>\n                                {fileRowsQuery.isLoading && (\n                                    <div className={\"flex items-center justify-center py-8\"}>\n                                        <LoadingSpinner inline />\n                                    </div>\n                                )}\n                                {files.length > 0 && <div style={{ height: \"1rem\" }} />}\n                                {files.map((f) => (\n                                    <FileOrFolder\n                                        key={f.fullPath}\n                                        node={f}\n                                        selectedPath={selectedNode?.fullPath}\n                                        onSelect={setSelectedNode}\n                                        onDelete={onDeleteNode}\n                                        onRename={onRenameNode}\n                                    />\n                                ))}\n                                {\n                                    <>\n                                        {files.length > 0 && <hr className={classes.emptyPlaceholderDivider} />}\n                                        <div className={cx(\"flex items-center\", classes.emptyPlaceholder)}>\n                                            <Text>\n                                                <i>Drop files/folders here, or</i>&nbsp;&nbsp;\n                                            </Text>\n                                            <Button small icon={faUpload} onClick={() => upload(\"\")}>\n                                                Upload\n                                            </Button>\n                                        </div>\n                                    </>\n                                }\n                            </div>\n                        ) : (\n                            <div>\n                                There is no <code>files</code> table in your database.{\" \"}\n                                <Button small onClick={createFileTable}>\n                                    Create one now to continue\n                                </Button>\n                            </div>\n                        )}\n                    </div>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport default connector(FileServiceTab);\n","import type { AnvilAction, AnvilAsyncAction } from \"@/types\";\nimport type {\n    GoogleAccessTokenResponse,\n    GoogleAllowedPermissions,\n    GoogleDriveCreatedItem,\n    GoogleDriveError,\n    GoogleDriveFile,\n    GoogleDriveItemType,\n    GoogleFileList,\n} from \"@/types/services\";\nimport * as api from \"@/api\";\nimport { getGoogleDelegatedAccessToken } from \"../api\";\nimport { getAppId, markAppPathUnsaved, updateGlobalLoadingIndicator } from \"./app\";\nimport { reloadAppConfig } from \"./app/autocompleter\";\nimport { pythonifyPackageName } from \"./dependencies\";\nimport { getGoogleService, updateService } from \"./services\";\n\ntype GoogleAppFile = Pick<GoogleDriveFile, \"id\" | \"python_name\" | \"title\"> & Record<string, unknown>;\n\nconst readGoogleError = async (response: Response): Promise<GoogleDriveError> => {\n    try {\n        const json = (await response.json()) as GoogleDriveError;\n        return {\n            ...json,\n            error: {\n                ...json.error,\n                message: json.error?.message ?? `Request failed (${response.status})`,\n            },\n        };\n    } catch {\n        const text = await response.text();\n        return { error: { message: text || `Request failed (${response.status})` } };\n    }\n};\n\nexport const removeUnencryptedToken = (): AnvilAction => async (dispatch, getState, updateState) => {\n    updateState(`Remove unencrypted token from google service`, (state) => {\n        const service = getGoogleService(state);\n        delete service?.server_config?.delegation_refresh_token;\n    });\n    dispatch(reloadAppConfig());\n    dispatch(markAppPathUnsaved([\"SETTINGS\", \"services\"]));\n};\n\nexport const encryptAndSaveRefreshToken =\n    (unencrypted: string): AnvilAsyncAction<void> =>\n    async (dispatch, getState) => {\n        const appId = getAppId(getState());\n        const r = await api.encryptAppSecret(\n            appId,\n            false,\n            false,\n            \"google-service/delegation-refresh-token\",\n            unencrypted\n        );\n        await dispatch(updateService(\"google\", [\"server_config\", \"enc_delegation_refresh_token\"], r.encrypted));\n        dispatch(reloadAppConfig());\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"services\"]));\n    };\n\nexport const removeAppFile =\n    (id: string): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        updateState(`Remove file from google service`, (state) => {\n            const service = getGoogleService(state);\n            const appFiles = service?.client_config?.app_files;\n            const file = appFiles?.find((file) => file.id === id);\n            const ind = file && appFiles ? appFiles.indexOf(file) : -1;\n            if (ind != null && ind > -1) {\n                appFiles?.splice(ind, 1);\n            }\n        });\n        dispatch(reloadAppConfig());\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"services\"]));\n    };\n\nexport const updateAppFileProperty =\n    (fileId: string, property: string, value: unknown): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        updateState(`Update ${property} of app file in google service`, (state) => {\n            const service = getGoogleService(state);\n            const file = service?.client_config?.app_files?.find((file) => file.id === fileId);\n            if (file) {\n                file[property] = value;\n            }\n        });\n\n        dispatch(reloadAppConfig());\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"services\"]));\n    };\n\nexport const pythonifyName = (name: string) => {\n    return pythonifyPackageName(name);\n};\n\nexport const getAccessToken = (): AnvilAsyncAction<GoogleAccessTokenResponse> => async (dispatch, getState) => {\n    const appId = getAppId(getState());\n    try {\n        return await getGoogleDelegatedAccessToken(appId);\n    } catch (e) {\n        throw e;\n    }\n};\n\nexport const getGoogleFiles =\n    (\n        accessToken: string,\n        folderId: string | null = null,\n        nextLink: string | null = null\n    ): AnvilAsyncAction<GoogleFileList> =>\n    async (dispatch) => {\n        try {\n            dispatch(updateGlobalLoadingIndicator(\"Connecting to Google Drive\"));\n            const q = folderId ? `trashed=false and '${folderId}' in parents` : `trashed=false`;\n            const link = nextLink\n                ? nextLink\n                : `https://www.googleapis.com/drive/v2/files?orderBy=folder,title&q=${encodeURIComponent(q)}`;\n            const response = await fetch(link, {\n                method: \"GET\",\n                headers: {\n                    \"Content-Type\": \"application/json\",\n                    Authorization: `Bearer ${accessToken}`,\n                },\n            });\n            if (!response.ok) {\n                return await readGoogleError(response);\n            }\n            return response.json() as Promise<GoogleFileList>;\n        } catch (e) {\n            return { error: { message: e instanceof Error ? e.message : String(e) } };\n        } finally {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n    };\n\nexport const getGoogleFile =\n    (accessToken: string, fileId: string): AnvilAsyncAction<GoogleDriveFile | GoogleDriveError> =>\n    async (dispatch) => {\n        try {\n            dispatch(updateGlobalLoadingIndicator(\"Connecting to Google Drive\"));\n            const response = await fetch(`https://www.googleapis.com/drive/v2/files/${fileId}?supportsAllDrives=true`, {\n                method: \"GET\",\n                headers: {\n                    \"Content-Type\": \"application/json\",\n                    Authorization: `Bearer ${accessToken}`,\n                },\n            });\n            return response.json() as Promise<GoogleDriveFile>;\n        } catch (e) {\n            return { error: { message: e instanceof Error ? e.message : String(e) }, id: fileId, title: \"\" };\n        } finally {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n    };\n\nexport const searchThruGoogleDrive =\n    (search: string, accessToken: string): AnvilAsyncAction<GoogleFileList> =>\n    async (dispatch) => {\n        try {\n            dispatch(updateGlobalLoadingIndicator(\"Connecting to Google Drive\"));\n            const safeSearch = search.replace(/'/g, \"\\\\'\");\n            const q = `trashed=false and title contains '${safeSearch}'`;\n            const link = `https://www.googleapis.com/drive/v2/files?orderBy=folder,title&q=${encodeURIComponent(q)}`;\n            const response = await fetch(link, {\n                method: \"GET\",\n                headers: {\n                    \"Content-Type\": \"application/json\",\n                    Authorization: `Bearer ${accessToken}`,\n                },\n            });\n            if (!response.ok) {\n                return await readGoogleError(response);\n            }\n            return response.json() as Promise<GoogleFileList>;\n        } catch (e) {\n            return { error: { message: e instanceof Error ? e.message : String(e) } };\n        } finally {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n    };\n\nexport const getNextPageOfFiles =\n    (accessToken: string, nextLink: string): AnvilAsyncAction<GoogleFileList> =>\n    async (dispatch) => {\n        try {\n            dispatch(updateGlobalLoadingIndicator(\"Connecting to Google Drive\"));\n            const response = await fetch(nextLink, {\n                method: \"GET\",\n                headers: {\n                    \"Content-Type\": \"application/json\",\n                    Authorization: `Bearer ${accessToken}`,\n                },\n            });\n            return response.json() as Promise<GoogleFileList>;\n        } catch (e) {\n            return { error: { message: e instanceof Error ? e.message : String(e) } };\n        } finally {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n    };\n\nexport const fileAlreadyExists =\n    (fileId: string): AnvilAsyncAction<boolean> =>\n    async (dispatch, getState) => {\n        const service = getGoogleService(getState());\n        const appFiles = service?.client_config?.app_files || [];\n        const fileIds = appFiles.map((file) => file.id);\n        return fileIds.includes(fileId);\n    };\n\nconst generateNewPythonName = (fileTitle: string, appFiles: GoogleAppFile[]) => {\n    const allPythonNames = appFiles.map((file) => file.python_name);\n    let pythonName = pythonifyName(fileTitle).toLowerCase();\n\n    if (!allPythonNames.includes(pythonName)) return pythonName;\n    if (!allPythonNames.includes(`${pythonName}_2`)) return `${pythonName}_2`;\n\n    const re = new RegExp(`${pythonName}_\\\\d+$`);\n    const matches = allPythonNames.filter((name) => re.test(name)) || [];\n    const len = pythonName.length + 1;\n    const numbers = matches.map((name) => parseInt(name.slice(len), 10));\n    let nameN = 2;\n    while (numbers.includes(nameN)) {\n        nameN++;\n    }\n    return `${pythonName}_${nameN}`;\n};\n\nexport const addFileFromDriveToGoogleService =\n    (driveFile: Omit<GoogleDriveFile, \"python_name\"> & GoogleDriveError): AnvilAsyncAction<void> =>\n    async (dispatch, getState) => {\n        const service = getGoogleService(getState());\n        const appFiles = service?.client_config?.app_files || [];\n        if (driveFile?.error) {\n            const e = new Error(driveFile.error.message) as Error & { title?: string };\n            e.title = \"Failed to add file\";\n            throw e;\n        }\n        const pythonName = generateNewPythonName(driveFile.title ?? \"\", appFiles);\n        const file = { ...driveFile, python_name: pythonName };\n\n        await dispatch(updateService(\"google\", [\"client_config\", \"app_files\"], [...appFiles, file]));\n        dispatch(reloadAppConfig());\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"services\"]));\n    };\n\nexport const getAllowedPermissions =\n    (accessToken: string): AnvilAsyncAction<GoogleAllowedPermissions> =>\n    async () => {\n        return (\n            await fetch(`https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=${accessToken}`, {\n                method: \"GET\",\n                headers: {\n                    \"Content-Type\": \"application/json\",\n                },\n            })\n        ).json();\n    };\n\nexport const createItemInDrive =\n    (\n        parentFolderId: string | null,\n        folderName: string,\n        type: GoogleDriveItemType,\n        accessToken: string\n    ): AnvilAsyncAction<GoogleDriveCreatedItem> =>\n    async () => {\n        const mimeType: Partial<Record<typeof type, string>> = {\n            folder: \"application/vnd.google-apps.folder\",\n            spreadsheet: \"application/vnd.google-apps.spreadsheet\",\n            text: \"text/plain\",\n        };\n\n        const body: {\n            mimeType?: string;\n            name: string;\n            parents?: string[];\n        } = {\n            name: folderName,\n        };\n\n        if (mimeType[type]) {\n            body.mimeType = mimeType[type];\n        }\n\n        if (parentFolderId) {\n            body.parents = [parentFolderId];\n        }\n\n        return (\n            await fetch(\"https://www.googleapis.com/drive/v3/files\", {\n                method: \"POST\",\n                headers: {\n                    \"content-type\": \"application/json\",\n                    Accept: \"application/json\",\n                    Authorization: `Bearer ${accessToken}`,\n                },\n                body: JSON.stringify(body),\n            })\n        ).json();\n    };\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { connect, useDispatch } from \"react-redux\";\nimport { faGoogle, faGoogleDrive } from \"@fortawesome/free-brands-svg-icons\";\nimport { faChevronDown } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n    faFile,\n    faFileSpreadsheet,\n    faFolder,\n    faLink,\n    faPencilAlt,\n    faPlus,\n    faUnlink,\n} from \"@fortawesome/pro-light-svg-icons\";\nimport { faSearch } from \"@fortawesome/pro-light-svg-icons/faSearch\";\nimport { faTimes } from \"@fortawesome/pro-light-svg-icons/faTimes\";\nimport { faCopy } from \"@fortawesome/pro-regular-svg-icons\";\nimport {\n    faArrowUp,\n    faEye,\n    faEyeSlash,\n    faFolderOpen,\n    faPencil,\n    faShare,\n    faTrashAlt,\n} from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { sortBy } from \"lodash-es\";\nimport { updateGlobalLoadingIndicator } from \"@/controllers/app\";\nimport { getUser } from \"@/controllers/ide\";\nimport { ignoreSsrWarning } from \"@/theme/utils\";\nimport type { AnvilConnectedProps, AnvilDispatch, State } from \"@/types\";\nimport type { GoogleAccessTokenResponse, GoogleDriveFile, GoogleDriveItemType } from \"@/types/services\";\nimport type { ServiceTab } from \"@/types/tabs\";\nimport * as api from \"@/api\";\nimport defer from \"@/util/defer\";\nimport {\n    addFileFromDriveToGoogleService,\n    createItemInDrive,\n    encryptAndSaveRefreshToken,\n    fileAlreadyExists,\n    getAccessToken,\n    getAllowedPermissions,\n    getGoogleFile,\n    getGoogleFiles,\n    pythonifyName,\n    removeAppFile,\n    removeUnencryptedToken,\n    searchThruGoogleDrive,\n    updateAppFileProperty,\n} from \"../../controllers/googleservice\";\nimport { alert, prompt } from \"../../controllers/modals\";\nimport { getGoogleService, updateService } from \"../../controllers/services\";\nimport { useUpdateTabTitle } from \"../../controllers/tabs\";\nimport { cx, makeStyles } from \"../../theme/styles\";\nimport { useDebounceFn, useMemoAsync } from \"../../util/hooks\";\nimport type { ModalComponent } from \"../modals\";\nimport Modal, { type ModalRef } from \"../modals/Modal\";\nimport { Button } from \"../reusable/Button\";\nimport DropdownMenu, { type DropDownMenuItems, type MenuItems } from \"../reusable/DropdownMenu\";\nimport { CheckBox, TextBox, useTextStyles } from \"../reusable/Forms\";\nimport { HelpLink } from \"../reusable/HelpLink\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { useSaveIndicator } from \"../reusable/SaveIndicator\";\nimport { ContentTextInput, EncryptedTextInput, ModalButton } from \"../reusable/SharedComponents\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport TextInput from \"../reusable/TextInput\";\nimport { useCopyWithTooltip, useTooltip } from \"../reusable/Tooltip\";\nimport TabToolbar from \"./TabToolbar\";\n\ntype BreadcrumbItem = {\n    id: string;\n    title: string;\n};\n\ntype AuthResult = GoogleAccessTokenResponse & {\n    unenc_refreshToken: string;\n};\n\ntype GooglePickerResult = {\n    action?: string;\n    docs?: GoogleDriveFile[];\n};\n\ntype GoogleServiceTabProps = AnvilConnectedProps<typeof connector> & { tab: ServiceTab };\n\ndeclare const gapi: any;\ndeclare const google: any;\n\nconst permissionOptions = [\n    [\"No client access\", \"noclient\", faEyeSlash],\n    [\"Client can read\", \"roclient\", faEye],\n    [\"Client can read and write\", \"rwclient\", faPencil],\n] satisfies MenuItems<string>;\n\nconst openURL = (url?: string | null) => {\n    if (!url) return;\n    const newWindow = window.open(url, \"_blank\", \"noopener,noreferrer\");\n    if (newWindow) {\n        newWindow.opener = null;\n    }\n};\n\nconst useStyles = makeStyles<void, \"gridItem\">()((theme, _props, classes) => ({\n    container: {\n        height: \"calc(100% - 5rem)\",\n        background: theme.googleService.background.toString(),\n        display: \"flex\",\n        flexDirection: \"column\",\n        overflowY: \"scroll\",\n    },\n    pagePanel: {\n        padding: \"1rem 4rem\",\n        maxWidth: \"180rem\",\n        minWidth: \"100rem\",\n        borderRight: \"1px solid \" + theme.settings.separator.toString(),\n        background: theme.settings.background.toString(),\n        flexGrow: 1,\n        flexShrink: 0,\n    },\n    sectionBody: {\n        margin: \"0 3rem\",\n    },\n\n    reconnect: {\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        display: \"flex\",\n        flexDirection: \"column\",\n        // gridColumn: 'span 2 / span 2',\n        border: \"3px solid \" + theme.sectionBorderColor.toString(),\n        borderRadius: \"6px\",\n        width: \"70%\",\n        margin: \"auto\",\n        padding: \"3rem\",\n    },\n\n    headingRow: {\n        fontWeight: \"bold\",\n        alignSelf: \"end\",\n        // justifySelf: 'center',\n        paddingBottom: \"1rem\",\n    },\n    itemName: {\n        width: \"80%\",\n        whiteSpace: \"nowrap\",\n        overflow: \"hidden\",\n        textOverflow: \"ellipsis\",\n    },\n    gridItem: {\n        display: \"flex\",\n        alignItems: \"center\",\n        height: \"5rem\",\n        overflow: \"hidden\",\n        width: \"100%\",\n    },\n    copyIcon: {\n        height: \"100%\",\n        display: \"flex\",\n        justifyContent: \"center\",\n        alignItems: \"center\",\n        \"&:hover\": {\n            cursor: \"pointer\",\n        },\n        color: theme.googleService.color.toString(),\n    },\n    pythonNameHitBox: {\n        width: \"max-content\",\n        overflow: \"hidden\",\n        display: \"flex\",\n        fontFamily: \"monospace\",\n        alignItems: \"center\",\n        backgroundColor: theme.googleService.pythonNameBg.toString(),\n        borderRadius: \"4px\",\n        paddingLeft: \"1rem\",\n        maxWidth: \"100%\",\n        color: theme.googleService.color.toString(),\n        \"&:hover\": {\n            cursor: \"pointer\",\n        },\n    },\n    fileGrid: {\n        display: \"grid\",\n        gridTemplateColumns: \"30% 1fr min-content max-content\",\n        \"& > div\": {\n            alignSelf: \"center\",\n        },\n        [`& .${classes.gridItem}:nth-child(8n-1), & .${classes.gridItem}:nth-child(8n-2), & .${classes.gridItem}:nth-child(8n-3), & .${classes.gridItem}:nth-child(8n)${ignoreSsrWarning}`]:\n            {\n                background: theme.googleService.fileRowBg.toString(),\n            },\n        [`& .${classes.gridItem}:nth-child(8n)${ignoreSsrWarning}`]: {\n            borderRadius: \"0 5px 5px 0\",\n        },\n        [`& .${classes.gridItem}:nth-child(8n-3)${ignoreSsrWarning}`]: {\n            borderRadius: \"5px 0 0 5px\",\n        },\n    },\n\n    selectBranchAnchor: {\n        position: \"absolute\",\n        left: -2,\n        bottom: -2,\n    },\n    inputTextBox: {\n        height: \"auto\",\n        maxWidth: \"100%\",\n        borderRadius: \"0 5px 5px 0\",\n        padding: \"0.5rem 0\",\n        flexGrow: 1,\n    },\n    pythonName: {\n        width: \"auto\",\n        whiteSpace: \"nowrap\",\n        overflow: \"hidden\",\n        textOverflow: \"ellipsis\",\n        flexShrink: 1,\n        flexGrow: 0,\n    },\n}));\n\nconst googleModalStyles = makeStyles()((theme) => ({\n    container: {\n        height: \"80vh\",\n        [`&:nth-child(2)${ignoreSsrWarning}`]: {\n            height: \"auto\",\n            // overflowY: 'hidden',\n        },\n    },\n    fileListContainer: {\n        border: \"1px solid \" + theme.sectionBorderColor.toString(),\n        borderRadius: \"3px\",\n        overflowY: \"auto\",\n        height: \"50vh\", //this can be maxheight instead of height if we decide we want the window to be small. maxheight 60 seemed pretty dec\n        paddingBottom: \"1rem\",\n    },\n    fileRow: {\n        minHeight: \"5rem\",\n        display: \"flex\",\n        alignItems: \"center\",\n        padding: \"0.5rem 2rem\",\n        borderRadius: \"4px\",\n        \"&:hover\": {\n            background: theme.googleService.modal.rowHoverBg.toString(),\n            cursor: \"pointer\",\n        },\n    },\n    selected: {\n        background: theme.googleService.modal.rowSelectBg.toString(),\n        \"&:hover\": {\n            background: theme.googleService.modal.rowSelectBg.toString(),\n        },\n    },\n    lowerButtons: {\n        marginTop: \"2rem\",\n        display: \"flex\",\n        justifyContent: \"flex-end\",\n        gap: \"1rem\",\n    },\n\n    searchBox: {\n        height: \"4rem\",\n        border: \"1px solid \" + theme.sectionBorderColor.toString(),\n        borderRadius: 0,\n        paddingLeft: \"4rem\",\n    },\n    searchIcon: {\n        position: \"absolute\",\n        top: \"1rem\",\n        left: \"1.2rem\",\n        fontSize: \"2rem\",\n        color: theme.formInput.placeholderColor.toString(),\n    },\n    clearSearchIconLink: {\n        position: \"absolute\",\n        top: 0,\n        right: 0,\n        padding: \"2px 1.2rem\",\n        fontSize: \"2rem\",\n        color: theme.formInput.placeholderColor.toString(),\n        \"&:hover\": {\n            color: theme.formInput.color.toString(),\n        },\n    },\n\n    selectBranchAnchor: {\n        position: \"absolute\",\n        left: -2,\n        bottom: -2,\n    },\n    breadcrumbContainer: {\n        paddingRight: \"2rem\",\n        width: \"65%\",\n        display: \"flex\",\n        alignItems: \"center\",\n    },\n    breadcrumbItem: {\n        whiteSpace: \"nowrap\",\n        overflow: \"hidden\",\n        textOverflow: \"ellipsis\",\n        flexShrink: 2,\n        flexBasis: \"max-content\",\n    },\n    noResults: {\n        fontSize: \"1.5rem\",\n        color: theme.googleService.modal.emptyTextColor.toString(),\n        background: theme.googleService.modal.emptyNotice.toString(),\n        textAlign: \"center\",\n        padding: \"2rem\",\n        height: \"100%\",\n    },\n}));\n\nconst isFolder = (file: Pick<GoogleDriveFile, \"mimeType\"> | null | undefined) =>\n    file?.mimeType === \"application/vnd.google-apps.folder\";\n\ntype GoogleModalFileRowProps = {\n    file: GoogleDriveFile;\n    selected: boolean;\n    setSelected: React.Dispatch<React.SetStateAction<GoogleDriveFile | null>>;\n    setFolder: React.Dispatch<React.SetStateAction<string>>;\n    breadCrumbPath: BreadcrumbItem[];\n    setBreadCrumbPath: React.Dispatch<React.SetStateAction<BreadcrumbItem[]>>;\n    addfileAndCloseModal: () => void;\n};\n\nconst GoogleModalFileRow = ({\n    file,\n    selected,\n    setSelected,\n    setFolder,\n    breadCrumbPath,\n    setBreadCrumbPath,\n    addfileAndCloseModal,\n}: GoogleModalFileRowProps) => {\n    const { classes } = googleModalStyles();\n\n    const openFolder = useCallback(\n        (folderId: string) => {\n            setFolder(folderId);\n            const newPath = [...breadCrumbPath, { id: file.id, title: file.title }];\n            setBreadCrumbPath(newPath);\n        },\n        [breadCrumbPath, file]\n    );\n\n    const handleClick = useCallback(\n        (e: React.MouseEvent<HTMLDivElement>) => {\n            setSelected(file);\n            if (isFolder(file)) {\n                if (e.detail === 2) {\n                    openFolder(file.id);\n                }\n            }\n        },\n        [file, openFolder]\n    );\n\n    return (\n        <div className={cx(classes.fileRow, selected && classes.selected)} onClick={handleClick}>\n            <div className={\"flex shrink items-center overflow-hidden\"}>\n                <img className={\"mr-2 block\"} src={`${file.iconLink}`} />\n                <div className={\"shrink overflow-hidden text-ellipsis whitespace-nowrap\"} title={file.title}>\n                    {file.title}\n                </div>\n            </div>\n            <div className={\"flex-1\"}></div>\n            <div className={\"flex min-w-fit\"}>\n                {selected && (\n                    <Button variant={\"primary\"} className={\"mx-1\"} onClick={addfileAndCloseModal}>\n                        Add {isFolder(file) ? \"folder\" : \"file\"} to app\n                    </Button>\n                )}\n                {isFolder(file) ? (\n                    <Button className={\"mx-1\"} icon={faFolderOpen} onClick={() => openFolder(file.id)}>\n                        Browse\n                    </Button>\n                ) : (\n                    <Button className={\"mx-1\"} icon={faEye} onClick={() => openURL(file?.alternateLink)}>\n                        View\n                    </Button>\n                )}\n            </div>\n        </div>\n    );\n};\n\ntype BreadCrumbsProps = {\n    breadCrumbPath: BreadcrumbItem[];\n    goToFolder: (id: string) => void;\n    search: string;\n    goToSearch: () => void;\n};\n\nconst BreadCrumbs = ({ breadCrumbPath, goToFolder, search, goToSearch }: BreadCrumbsProps) => {\n    const { classes } = googleModalStyles();\n\n    const crumbLength = useMemo(() => breadCrumbPath.length, [breadCrumbPath]);\n\n    const childIndicator = useMemo(() => <div className={\"mx-2\"}>{\">\"}</div>, []);\n\n    const hiddenFolders = useMemo(\n        () => (breadCrumbPath?.slice(0, crumbLength - 2) || []).map((folder) => [folder.title, folder.id] as const),\n        [crumbLength, breadCrumbPath]\n    );\n\n    const hiddenFoldersEllipsis = useMemo(() => {\n        return (\n            <DropdownMenu\n                onSelectItem={(select) => goToFolder(select)}\n                render={(showMenu, anchor) => (\n                    <Button variant={\"outlined\"} onClick={(e) => showMenu(null, e.currentTarget)}>\n                        {\"•••\"}\n                        <div className={cx(classes.selectBranchAnchor)}>{anchor}</div>\n                    </Button>\n                )}\n                items={(selectItem, hideMenu) => hiddenFolders}\n                align={\"left\"}\n            />\n        );\n    }, [hiddenFolders, goToFolder]);\n\n    return (\n        <Heading level={1} className={cx(classes.breadcrumbContainer)}>\n            <LinkInternal\n                className={cx(\"shrink-0!\", crumbLength > 0 && \"underline\", classes.breadcrumbItem)}\n                onClick={() => goToFolder(\"root\")}>\n                My Drive\n            </LinkInternal>\n            {!!search && (\n                <>\n                    {childIndicator}\n                    <FontAwesomeIcon className={\"mx-2 font-bold\"} icon={faSearch} /> '\n                    <LinkInternal className={cx(\"underline\")} onClick={() => goToSearch()}>\n                        {search}\n                    </LinkInternal>\n                    '\n                </>\n            )}\n            {crumbLength > 0 && (\n                <>\n                    {crumbLength > 3 ? (\n                        <>\n                            {childIndicator}\n                            {hiddenFoldersEllipsis}\n                            {childIndicator}\n                            <LinkInternal\n                                title={breadCrumbPath[crumbLength - 2].title}\n                                className={cx(\"underline\", classes.breadcrumbItem)}\n                                onClick={() => goToFolder(breadCrumbPath[crumbLength - 2].id)}>\n                                {breadCrumbPath[crumbLength - 2].title}\n                            </LinkInternal>\n                        </>\n                    ) : (\n                        <>\n                            {breadCrumbPath.slice(0, crumbLength - 1).map((file, ind) => {\n                                return (\n                                    <>\n                                        {childIndicator}\n                                        <LinkInternal\n                                            title={breadCrumbPath[ind].title}\n                                            className={cx(\"underline\", classes.breadcrumbItem)}\n                                            key={ind}\n                                            onClick={() => goToFolder(file.id)}>\n                                            {file.title}\n                                        </LinkInternal>\n                                    </>\n                                );\n                            })}\n                        </>\n                    )}\n                    {childIndicator}\n                    <div\n                        title={breadCrumbPath[crumbLength - 1].title}\n                        className={cx(\"shrink!\", classes.breadcrumbItem)}>\n                        {breadCrumbPath[crumbLength - 1].title}\n                    </div>\n                </>\n            )}\n        </Heading>\n    );\n};\n\ntype GoogleServiceModalSpec = { token: string };\ntype GoogleServiceModalType = ModalComponent<GoogleServiceModalSpec, GoogleDriveFile | false>;\n\nexport const GoogleServiceModal: GoogleServiceModalType = ({ modalId, spec: { token } }) => {\n    const [createTooltip, createTooltipRef] = useTooltip(\"Create a item in your Google Drive\", \"left\");\n    const { classes } = googleModalStyles();\n    const [currentFolderId, setCurrentFolderId] = useState(\"root\");\n    const [loaded, setLoaded] = useState(false);\n    const [breadCrumbPath, setBreadCrumbPath] = useState<BreadcrumbItem[]>([]);\n    const [googleFiles, setGoogleFiles] = useState<GoogleDriveFile[]>([]);\n    const [nextPageOfFiles, setNextPageOfFiles] = useState<string | null>(null);\n    const [nextPageInSearch, setNextPageInSearch] = useState<string | null>(null);\n    const [searchResults, setSearchResults] = useState<GoogleDriveFile[]>([]);\n    const [selectedFile, setSelectedFile] = useState<GoogleDriveFile | null>(null);\n    const [searchApiCalled, setSearchApiCalled] = useState(true);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const modalRef = useRef<ModalRef>(null);\n    const [search, setSearch] = useState(\"\");\n\n    const clearSearch = useCallback(() => {\n        setSearch(\"\");\n        setSearchResults([]);\n        setNextPageInSearch(null);\n        setSearchApiCalled(false);\n        setBreadCrumbPath([]);\n        setCurrentFolderId(\"root\");\n    }, []);\n\n    const getAndSetFilesInFolder = useCallback(\n        async (folderId: string) => {\n            if (folderId) {\n                setLoaded(false);\n                const list = await dispatch(getGoogleFiles(token, folderId));\n                const items = list?.items ?? [];\n\n                if (search) {\n                    setNextPageInSearch(list?.nextLink || null);\n                    setSearchResults(items);\n                } else {\n                    setNextPageOfFiles(list?.nextLink || null);\n                    setGoogleFiles(items);\n                }\n\n                setLoaded(true);\n            }\n        },\n        [search, token]\n    );\n\n    const goToFolder = useCallback(\n        (id: string) => {\n            if (id == \"root\") {\n                clearSearch();\n                setBreadCrumbPath([]);\n            } else {\n                const ind = breadCrumbPath.findIndex((itm) => itm.id === id);\n                setBreadCrumbPath(breadCrumbPath.slice(0, ind + 1));\n            }\n            setCurrentFolderId(id);\n            setSelectedFile(null);\n        },\n        [breadCrumbPath]\n    );\n\n    useEffect(() => {\n        getAndSetFilesInFolder(currentFolderId);\n    }, [currentFolderId]);\n\n    const upOneFolder = useCallback(() => {\n        if (breadCrumbPath.length === 1) {\n            if (search) {\n                return getSearchResults();\n            }\n            return goToFolder(\"root\");\n        } else {\n            const upFolder = breadCrumbPath.at(-2)?.id;\n            if (!upFolder) return;\n            return goToFolder(upFolder);\n        }\n    }, [breadCrumbPath, goToFolder, search]);\n\n    const changeSearchTerm = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n        setSearch(e.target.value);\n        setSearchApiCalled(false);\n        setNextPageInSearch(null);\n        setBreadCrumbPath([]);\n    }, []);\n\n    const getSearchResults = useCallback(async () => {\n        setBreadCrumbPath([]);\n        if (!searchApiCalled) {\n            setSearchApiCalled(true);\n            const list = await dispatch(searchThruGoogleDrive(search, token));\n            if (list?.items) {\n                setSearchResults(list?.items);\n                setNextPageInSearch(list?.nextLink || null);\n            } else {\n                console.error(\"unable to filter items\", list?.error);\n                setSearchResults([]);\n                setNextPageInSearch(null);\n                setSearch(\"\");\n            }\n        }\n    }, [search, token, searchApiCalled]);\n    const debouncedSearchResults = useDebounceFn(getSearchResults, 200);\n\n    useEffect(() => {\n        debouncedSearchResults();\n    }, [getSearchResults]);\n\n    const promptAndCreate = useCallback(\n        async (type: GoogleDriveItemType) => {\n            const name = await dispatch(prompt(`Create a new ${type} in your Google Drive`, `New ${type} name`));\n            if (name) {\n                const newItem = await dispatch(createItemInDrive(currentFolderId, name, type, token));\n                if (newItem.error) {\n                    console.error(\"Unable to add item\", newItem.message);\n                } else {\n                    getAndSetFilesInFolder(currentFolderId);\n                    //todo: maybe instead of refreshing - just sort and add to list cuz you don't avtually have to get the whole thing again...\n                }\n            }\n        },\n        [currentFolderId, token, goToFolder, breadCrumbPath]\n    );\n\n    const createMenuItems = useCallback<DropDownMenuItems>(\n        (_selectItem, _hideMenu) => [\n            [\"New Folder\", () => promptAndCreate(\"folder\"), faFolder],\n            [\"New Spreadsheet\", () => promptAndCreate(\"spreadsheet\"), faFileSpreadsheet],\n            [\"New Text File\", () => promptAndCreate(\"text\"), faFile],\n        ],\n        [promptAndCreate]\n    );\n\n    const getNextPageOfFiles = useCallback(async () => {\n        if (search) {\n            const list = await dispatch(getGoogleFiles(token, null, nextPageInSearch));\n            setNextPageInSearch(list?.nextLink || null);\n            const sorted = sortBy(\n                [...(list?.items ?? []), ...searchResults],\n                [(file) => (isFolder(file) ? -1 : 1), (file) => file.title.toLowerCase()]\n            );\n            //todo: check if you need to sort. It hnk you don't. they should already be in the right order cuz of orderby\n            setSearchResults(sorted);\n        } else {\n            const list = await dispatch(getGoogleFiles(token, null, nextPageOfFiles));\n            const items = list?.items;\n            setNextPageOfFiles(list?.nextLink || null);\n            const sorted = sortBy(\n                [...(items ?? []), ...googleFiles],\n                [(file) => (isFolder(file) ? -1 : 1), (file) => file.title.toLowerCase()]\n            );\n            //todo: check if you need to sort. It hnk you don't. they should already be in the right order cuz of orderby\n            setGoogleFiles(sorted);\n        }\n    }, [token, searchResults, nextPageOfFiles, googleFiles, search, nextPageInSearch]);\n\n    const addfileAndCloseModal = useCallback(() => modalRef.current?.returnValue(selectedFile), [selectedFile]);\n\n    const maybeNoResults = useMemo(() => {\n        const text = () => {\n            if (search && searchResults?.length === 0) {\n                return \"This search yielded no results\";\n            } else if (googleFiles?.length === 0) {\n                return \"Empty folder\";\n            }\n            return null;\n        };\n        return text() && <div className={classes.noResults}>{text()}</div>;\n    }, [classes, search, searchResults, googleFiles]);\n\n    return (\n        <Modal\n            title={\"Add a file to your app from Google Drive\"}\n            modalId={modalId}\n            allowDismiss={true}\n            size={\"large\"}\n            ref={modalRef}\n            className={classes.container}>\n            <div className={\"mb-8 h-auto\"}>\n                <div className={\"flex h-full items-baseline justify-between\"}>\n                    <BreadCrumbs\n                        breadCrumbPath={breadCrumbPath}\n                        goToFolder={goToFolder}\n                        search={search}\n                        goToSearch={getSearchResults}\n                    />\n                    <div className={\"relative my-8 w-2/6\"}>\n                        <ContentTextInput\n                            className={classes.searchBox}\n                            placeholder=\"Search your Google Drive\"\n                            value={search}\n                            onChange={(e) => changeSearchTerm(e)}\n                            onEnter={getSearchResults}\n                        />\n                        <FontAwesomeIcon icon={faSearch} className={classes.searchIcon} />\n                        {search && (\n                            <LinkInternal className={classes.clearSearchIconLink} onClick={clearSearch}>\n                                <FontAwesomeIcon icon={faTimes} />\n                            </LinkInternal>\n                        )}\n                    </div>\n                </div>\n                <div className={cx(\"flex items-center justify-between\")}>\n                    <div className={\"ml-8\"}>\n                        {breadCrumbPath.length > 0 && (\n                            <Button icon={faArrowUp} onClick={upOneFolder} small variant={\"primary\"}>\n                                Back up one folder\n                            </Button>\n                        )}\n                    </div>\n                    <div>\n                        <Button\n                            disabled={!!search && breadCrumbPath.length === 0}\n                            ref={createTooltipRef}\n                            variant={\"highlight1\"}\n                            icon={faPlus}\n                            onClick={() => promptAndCreate(\"file\")}\n                            menuItems={createMenuItems}>\n                            New File\n                        </Button>\n                        {createTooltip}\n                    </div>\n                </div>\n            </div>\n            <div className={cx(classes.fileListContainer, \"overflow-y-auto\", maybeNoResults && \"p-0!\")}>\n                {loaded && (\n                    <>\n                        {(search ? searchResults : googleFiles).map((item, idx) => (\n                            <GoogleModalFileRow\n                                key={idx}\n                                file={item}\n                                selected={selectedFile === item}\n                                setSelected={setSelectedFile}\n                                setFolder={setCurrentFolderId}\n                                breadCrumbPath={breadCrumbPath}\n                                setBreadCrumbPath={setBreadCrumbPath}\n                                addfileAndCloseModal={addfileAndCloseModal}\n                            />\n                        ))}\n                        {((!search && nextPageOfFiles) || (search && nextPageInSearch)) && (\n                            <div className={\"my-16 flex justify-center\"}>\n                                <Button onClick={getNextPageOfFiles} variant={\"primary\"} small>\n                                    Load More...\n                                </Button>\n                            </div>\n                        )}\n\n                        {maybeNoResults}\n                    </>\n                )}\n            </div>\n            <div className={classes.lowerButtons}>\n                {selectedFile && (\n                    <ModalButton icon={faPlus} variant={\"primary\"} onClick={addfileAndCloseModal}>\n                        Add {isFolder(selectedFile) ? \"folder\" : \"file\"} to app\n                    </ModalButton>\n                )}\n                <ModalButton onClick={() => modalRef.current?.returnValue(false)}>Cancel</ModalButton>\n            </div>\n        </Modal>\n    );\n};\n\ntype PythonNameInputRef = React.RefObject<HTMLInputElement | null>;\ntype FileRowProps = {\n    ref?: PythonNameInputRef;\n    file: GoogleDriveFile;\n    pythonAppNames: string[];\n};\n\nconst FileRow = ({ ref, file, pythonAppNames }: FileRowProps) => {\n    const { classes } = useStyles();\n    const dispatch = useDispatch<AnvilDispatch>();\n    const [removeTooltip, removeTooltipAnchorRef] = useTooltip(\"Revoke access to this file from your app\", \"left\");\n    const [settingName, setSettingName] = useState(false);\n    const [copyPythonName, copyToolTip, copyRef] = useCopyWithTooltip(\"Copied to clipboard\", \"left\");\n\n    const exportLinks = useMemo<MenuItems<string>>(() => {\n        return Object.entries(file?.exportLinks || {})\n            .map((entry) => {\n                switch (true) {\n                    case /vnd.oasis.opendocument.text/g.test(entry[0]):\n                        return [\"Open Office doc\", entry[1]];\n                    case /vnd.openxmlformats-officedocument.wordprocessingml.document/g.test(entry[0]):\n                        return [\"MS Word document\", entry[1]];\n                    case /vnd.openxmlformats-officedocument.spreadsheetml.sheet/g.test(entry[0]):\n                        return [\"MS Excel\", entry[1]];\n                    case /vnd.oasis.opendocument.spreadsheet/g.test(entry[0]):\n                        return [\"Open Office sheet\", entry[1]];\n                    case /vnd.openxmlformats-officedocument.presentationml.presentation/g.test(entry[0]):\n                        return [\"MS PowerPoint\", entry[1]];\n                    case /vnd.oasis.opendocument.presentation/g.test(entry[0]):\n                        return [\"Open Office presentation\", entry[1]];\n                    case /png/g.test(entry[0]):\n                        return [\"PNG\", entry[1]];\n                    case /plain/g.test(entry[0]):\n                        return [\"Plain text\", entry[1]];\n                    case /html/g.test(entry[0]):\n                        return [\"HTML\", entry[1]];\n                    case /pdf/g.test(entry[0]):\n                        return [\"PDF\", entry[1]];\n                    case /rtf/g.test(entry[0]):\n                        return [\"Rich text\", entry[1]];\n                    case /tab/g.test(entry[0]):\n                        return [\"TSV\", entry[1]];\n                    case /json/g.test(entry[0]):\n                        return [\"JSON\", entry[1]];\n                    case /csv/g.test(entry[0]):\n                        return [\"CSV (first sheet only)\", entry[1]];\n                    case /jpeg/g.test(entry[0]):\n                        return [\"JPEG\", entry[1]];\n                    case /svg/g.test(entry[0]):\n                        return [\"SVG\", entry[1]];\n                    case /epub/g.test(entry[0]):\n                        return [\"EPUB\", entry[1]];\n                    case /zip/g.test(entry[0]):\n                        return [\"Zip\", entry[1]];\n                    default:\n                        return entry;\n                }\n            })\n            .sort((a, b) => a[0].localeCompare(b[0]));\n    }, [file?.exportLinks]);\n\n    const exportDropDown = useMemo(\n        () => (\n            <DropdownMenu\n                onSelectItem={(url) => openURL(url)}\n                render={(showMenu, anchor) => (\n                    <Button\n                        className={\"mx-1\"}\n                        iconRight\n                        small\n                        onClick={(e) => showMenu(null, e.currentTarget)}\n                        icon={faChevronDown}>\n                        Export\n                        <div className={cx(classes.selectBranchAnchor)}>{anchor}</div>\n                    </Button>\n                )}\n                items={(_selectItem, _hideMenu) => exportLinks}\n                align={\"left\"}\n            />\n        ),\n        [exportLinks, classes, openURL]\n    );\n\n    const permissionsIcon = useMemo(() => {\n        return permissionOptions?.find((entry) => entry[1] === file?.permission)?.[2] || faPencil;\n    }, [file?.permission]);\n\n    const permissionsDropDown = useMemo(\n        () => (\n            <DropdownMenu\n                onSelectItem={(select) => dispatch(updateAppFileProperty(file?.id, \"permission\", select))}\n                render={(showMenu, anchor) => (\n                    <Button\n                        className={cx(\"mx-1\")}\n                        iconRight\n                        small\n                        onClick={(e) => showMenu(null, e.currentTarget)}\n                        icon={faChevronDown}>\n                        <FontAwesomeIcon icon={permissionsIcon} />\n                        <div className={cx(classes.selectBranchAnchor)}>{anchor}</div>\n                    </Button>\n                )}\n                items={(_selectItem, _hideMenu) => permissionOptions}\n                align={\"left\"}\n            />\n        ),\n        [file?.id, classes, permissionsIcon]\n    );\n\n    return (\n        <>\n            <Text className={cx(classes.gridItem)}>\n                <img className={\"mx-4\"} src={file?.iconLink} />\n                <span className={classes.itemName} title={file?.title || file?.id}>\n                    {file?.title || file?.id}\n                </span>\n            </Text>\n\n            <div className={classes.gridItem}>\n                <div\n                    ref={copyRef}\n                    className={cx(\"pr-4\", classes.copyIcon)}\n                    onClick={() => copyPythonName(`app_files.${file?.python_name}`)}>\n                    <FontAwesomeIcon icon={faCopy} />\n                    {copyToolTip}\n                </div>\n                <PythonNameBox\n                    file={file}\n                    settingName={settingName}\n                    setSettingName={setSettingName}\n                    pythonAppNames={pythonAppNames}\n                    ref={ref}\n                />\n            </div>\n\n            <div className={cx(\"flex justify-center\", classes.gridItem)}>{permissionsDropDown}</div>\n            <div className={cx(classes.gridItem, \"flex flex-row-reverse pr-4 pl-12\")}>\n                <Button\n                    small\n                    ref={removeTooltipAnchorRef}\n                    className={\"mx-1\"}\n                    onClick={() => dispatch(removeAppFile(file.id))}\n                    variant={\"danger\"}>\n                    {removeTooltip}\n                    <FontAwesomeIcon icon={faTrashAlt} />\n                </Button>\n                <Button small className={\"mx-1\"} icon={faEye} onClick={() => openURL(file?.alternateLink)}>\n                    View\n                </Button>\n                {file?.exportLinks && exportDropDown}\n            </div>\n        </>\n    );\n};\n\ntype PythonNameBoxProps = {\n    ref?: PythonNameInputRef;\n    file: GoogleDriveFile;\n    settingName: boolean;\n    setSettingName: React.Dispatch<React.SetStateAction<boolean>>;\n    pythonAppNames: string[];\n};\n\nconst PythonNameBox = ({ ref, file, settingName, setSettingName, pythonAppNames }: PythonNameBoxProps) => {\n    const { classes } = useStyles();\n    const dispatch = useDispatch<AnvilDispatch>();\n    const [pythonName, setPythonName] = useState(file?.python_name);\n\n    const focusInput = useCallback(async () => {\n        await setSettingName(true);\n        ref?.current?.focus();\n        ref?.current?.select();\n    }, [ref]);\n\n    const saveNewName = useCallback(async () => {\n        const saveName = pythonifyName(pythonName);\n        if (saveName !== file?.python_name) {\n            if (pythonAppNames.includes(saveName)) {\n                await dispatch(alert(\"Unable to rename file\", `A file in the app named ${saveName} already exists.`));\n                setPythonName(file?.python_name);\n                focusInput();\n                return;\n            } else {\n                await dispatch(updateAppFileProperty(file.id, \"python_name\", saveName));\n            }\n        }\n        setPythonName(saveName);\n        setSettingName(false);\n    }, [pythonName, file?.python_name, pythonAppNames]);\n\n    return (\n        <>\n            <div\n                title={file?.python_name}\n                className={cx(classes.pythonNameHitBox, settingName && \"w-full!\")}\n                onClick={focusInput}>\n                {settingName ? (\n                    <>\n                        <div className={\"w-fit\"}>app_files.</div>\n                        <TextBox\n                            className={classes.inputTextBox}\n                            ref={ref}\n                            value={pythonName}\n                            onChange={(e: React.ChangeEvent<HTMLInputElement>) => setPythonName(e.target.value)}\n                            onBlur={saveNewName}\n                        />\n                    </>\n                ) : (\n                    <>\n                        <div>app_files.</div>\n                        <div className={cx(classes.pythonName)} title={file?.python_name}>\n                            {file?.python_name}\n                        </div>\n                        <FontAwesomeIcon className={\"mx-4\"} icon={faPencilAlt} />\n                    </>\n                )}\n            </div>\n        </>\n    );\n};\n\nconst GoogleServiceTab = ({ tab, googleService, user }: GoogleServiceTabProps) => {\n    const { classes: formClasses } = useTextStyles();\n    const { classes } = useStyles();\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const pythonAppNames = useMemo(\n        () => googleService?.client_config?.app_files?.map((file) => file.python_name) ?? [],\n        [googleService?.client_config?.app_files]\n    );\n\n    //Tab Title\n    useUpdateTabTitle(tab, \"Google API\");\n    //Encrypting if unencrypted\n    useEffect(() => {\n        const unencrypted = googleService?.server_config?.delegation_refresh_token;\n        if (unencrypted) {\n            dispatch(encryptAndSaveRefreshToken(unencrypted));\n            dispatch(removeUnencryptedToken());\n        }\n    }, [googleService?.server_config?.delegation_refresh_token]);\n\n    const ref = useRef<HTMLInputElement | null>(null);\n    const authDefer = useRef<ReturnType<typeof defer<AuthResult>> | null>(null);\n\n    const window_onMessage = useCallback(async (e: MessageEvent) => {\n        if (e.origin != window.location.origin) {\n            return;\n        }\n        const data = e.data;\n        if (data?.fn === \"googleAuthSuccessCallback\") {\n            const tokens = await api.getGoogleAuthTokens();\n            authDefer.current?.resolve({\n                accessToken: tokens.accessToken,\n                unenc_refreshToken: tokens.refreshToken,\n            });\n        } else if (data?.fn === \"googleAuthErrorCallback\") {\n            authDefer.current?.reject(data.args.message);\n        }\n    }, []);\n\n    const doAuth = useCallback(async () => {\n        authDefer.current = defer<AuthResult>();\n\n        const authParams = {\n            // This is the Google Picker web-app integration, even when the IDE is opened\n            // from a desktop browser. Do not add trigger_onepick=true to this OAuth request:\n            // Google's OnePick flow is for native desktop/mobile apps or embedded-webview\n            // integrations, requires the OAuth request to contain only the drive.file scope,\n            // and returns selected files as picked_file_ids on the OAuth redirect instead of\n            // via the google.picker.PickerBuilder callback used below.\n            // See:\n            // https://developers.google.com/workspace/drive/picker/guides/web-picker\n            // https://developers.google.com/workspace/drive/picker/guides/desktop-mobile-picker\n            //scope: \"https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/gmail.send\",\n            scope: \"https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/gmail.send\",\n        };\n\n        const authUrl = api.googleOAuthURL + \"?\" + new URLSearchParams(authParams).toString();\n\n        const windowFeatures: Record<string, string | number> = {\n            width: 450,\n            height: 500,\n            scrollbars: \"yes\",\n        };\n\n        let strWindowFeatures = \"\";\n        for (const k in windowFeatures) {\n            if (strWindowFeatures.length > 0) strWindowFeatures += \",\";\n\n            strWindowFeatures += k;\n\n            const v = windowFeatures[k as keyof typeof windowFeatures];\n            strWindowFeatures += \"=\" + String(v);\n        }\n\n        window.open(authUrl, undefined, strWindowFeatures);\n        return await authDefer.current!.promise;\n    }, []);\n\n    const appFiles = useMemo(\n        () => googleService?.client_config?.app_files ?? [],\n        [googleService?.client_config?.app_files]\n    );\n    const [mapsApiKey, setMapsApiKey] = useState(googleService?.client_config?.api_key || \"\");\n    const [clientId, setClientId] = useState(googleService?.server_config?.client_id || \"\");\n    const appOriginRedirect = useMemo(\n        () => googleService?.server_config?.app_origin_redirect || false,\n        [googleService?.server_config?.app_origin_redirect]\n    );\n    const [saveRedirectIndicator, setRedirectSaved] = useSaveIndicator();\n\n    const [clientSecretSet, setClientSecretSet] = useState<boolean>(\n        !!(googleService?.server_config?.client_secret_enc || googleService?.server_config?.client_secret)\n    );\n    const saveClientSecret = async (encrypted: string) => {\n        setClientSecretSet(true);\n        await updateGoogleSetting(\"client_secret_enc\", encrypted, false);\n        if (googleService?.server_config?.client_secret) {\n            await updateGoogleSetting(\"client_secret\", null, false);\n        }\n    };\n\n    const refreshToken = useMemo(\n        () => googleService?.server_config?.enc_delegation_refresh_token,\n        [googleService?.server_config?.enc_delegation_refresh_token]\n    );\n    const [accessToken, setAccessToken] = useState<string | null>(null);\n    const accessTokenRef = useRef<string | null>(null);\n    const [tokenError, setTokenError] = useState(false);\n    const mailEnabled = useMemoAsync(\n        false,\n        async () => {\n            try {\n                const token = accessToken || accessTokenRef.current;\n                if (!token) {\n                    return false;\n                }\n                const permissions = await dispatch(getAllowedPermissions(token));\n                return /(^| )https:\\/\\/www.googleapis.com\\/auth\\/gmail.send( |$)/.test(permissions.scope);\n            } catch (e) {\n                return false;\n            }\n        },\n        [accessToken, accessTokenRef]\n    );\n\n    const updateRedirectAndSave = useCallback(async (value: boolean) => {\n        setRedirectSaved(false);\n        await updateGoogleSetting(\"app_origin_redirect\", value, false);\n        setRedirectSaved(true);\n    }, []);\n\n    useEffect(() => {\n        window.addEventListener(\"message\", window_onMessage);\n        return () => window.removeEventListener(\"message\", window_onMessage);\n    }, [window_onMessage]);\n\n    const initialLogin = useCallback(async () => {\n        try {\n            const { accessToken, unenc_refreshToken } = await doAuth();\n            dispatch(encryptAndSaveRefreshToken(unenc_refreshToken));\n            accessTokenRef.current = accessToken;\n            setTokenError(false);\n            await setAccessToken(accessToken);\n            return accessToken;\n        } catch (e) {\n            setTokenError(true);\n            console.error(\"Unable to log in:\", e);\n            dispatch(alert(\"Unable to login to Google\", \"An error occurred. Please try again.\"));\n            return false;\n        }\n    }, []);\n\n    const addFileFromPicker = useCallback(async (accessToken: string) => {\n        //const driveFile = await dispatch(modal('googleService', {token: accessToken || accessTokenRef?.current}));\n        const d = defer<void>();\n        gapi.load(\"picker\", d.resolve);\n        await d.promise;\n\n        const pick = defer<GooglePickerResult>();\n        const drive = new google.picker.DocsView();\n        drive.setIncludeFolders(true);\n        drive.setMode(google.picker.DocsViewMode.LIST);\n        drive.setSelectFolderEnabled(true);\n        const sharedDrives = new google.picker.DocsView();\n        sharedDrives.setEnableDrives(true);\n        sharedDrives.setIncludeFolders(true);\n        sharedDrives.setSelectFolderEnabled(true);\n        sharedDrives.setMode(google.picker.DocsViewMode.LIST);\n        const picker = new google.picker.PickerBuilder()\n            .addView(drive)\n            .addView(sharedDrives)\n            .setOAuthToken(accessToken)\n            .setAppId(user?.ideConfig?.googleProjectNumber) // This is necessary so that the picked file ends up associated with this project, allowing this app to access it.\n            .setDeveloperKey(user?.ideConfig?.googlePickerApiKey)\n            .setCallback((e: GooglePickerResult) => {\n                if (e.action === \"picked\" || e.action === \"cancel\") {\n                    pick.resolve(e);\n                }\n            })\n            .build();\n        picker.setVisible(true);\n        const picked = await pick.promise;\n        const driveFile = picked.docs?.[0];\n        if (driveFile) {\n            if (await dispatch(fileAlreadyExists(driveFile.id))) {\n                dispatch(alert(\"File Already Exists\", `${driveFile.title} already exists in the app.`));\n            } else {\n                const fullFile = await dispatch(getGoogleFile(accessToken, driveFile.id));\n                if (!fullFile.error) {\n                    await dispatch(addFileFromDriveToGoogleService(fullFile));\n                }\n            }\n        }\n    }, []);\n\n    const addNewFile = useCallback(async (accessToken: string, type: GoogleDriveItemType) => {\n        const name = await dispatch(prompt(`Create a new ${type} in your Google Drive`, `New ${type} name`));\n        if (name) {\n            try {\n                dispatch(updateGlobalLoadingIndicator(true));\n                const newItem = await dispatch(createItemInDrive(null, name, type, accessToken));\n                if (newItem.error) {\n                    console.error(\"Unable to add item\", newItem.message);\n                } else {\n                    const fullFile = await dispatch(getGoogleFile(accessToken, newItem.id));\n                    if (!fullFile.error) {\n                        await dispatch(addFileFromDriveToGoogleService(fullFile));\n                    }\n                }\n            } finally {\n                dispatch(updateGlobalLoadingIndicator(false));\n            }\n        }\n    }, []);\n\n    const addExistingButtonHandler = useCallback(async () => {\n        if (accessToken) {\n            await addFileFromPicker(accessToken);\n        } else {\n            const successfulToken = await getAccess();\n            if (successfulToken) {\n                await addFileFromPicker(successfulToken);\n            } else {\n                await loginThenOpenModal(null);\n            }\n        }\n    }, [accessToken]);\n\n    const addNewButtonHandler = useCallback(\n        async (type: GoogleDriveItemType) => {\n            if (accessToken) {\n                await addNewFile(accessToken, type);\n            } else {\n                const successfulToken = await getAccess();\n                if (successfulToken) {\n                    await addNewFile(successfulToken, type);\n                } else {\n                    await loginThenOpenModal(type);\n                }\n            }\n        },\n        [accessToken]\n    );\n\n    const createMenuItems = useCallback<DropDownMenuItems>(\n        (_selectItem, _hideMenu) => [\n            [\"New Folder\", () => addNewButtonHandler(\"folder\"), faFolder],\n            [\"New Spreadsheet\", () => addNewButtonHandler(\"spreadsheet\"), faFileSpreadsheet],\n            [\"New Text File\", () => addNewButtonHandler(\"text\"), faFile],\n            [\"New Blank File\", () => addNewButtonHandler(\"file\"), faFile],\n        ],\n        [addNewButtonHandler]\n    );\n\n    const loginThenOpenModal = useCallback(async (newFileType: GoogleDriveItemType | null = null) => {\n        const token = await initialLogin();\n        if (token) {\n            if (newFileType) {\n                await addNewFile(token, newFileType);\n            } else {\n                await addFileFromPicker(token);\n            }\n        } else {\n            dispatch(alert(\"Unable to login to Google\", \"An error occurred. Please try again.\"));\n        }\n    }, []);\n\n    const getAccess = useCallback(async () => {\n        try {\n            const resp = await dispatch(getAccessToken());\n            setAccessToken(resp.accessToken);\n            accessTokenRef.current = resp.accessToken;\n            setTokenError(false);\n            return resp.accessToken;\n        } catch (e) {\n            setTokenError(true);\n            console.error(\"Error refreshing access token:\", e);\n            return false;\n        }\n    }, []);\n\n    useEffect(() => {\n        if (refreshToken && !accessToken) {\n            getAccess();\n        }\n    }, [refreshToken, accessToken]);\n\n    useEffect(() => {\n        if (googleService?.client_config?.app_files) {\n            if (!refreshToken) {\n                setTokenError(true);\n            }\n        }\n    }, [googleService, refreshToken]);\n\n    const updateGoogleSetting = useCallback(async (property: string, newValue: unknown, isClientConfig: boolean) => {\n        await dispatch(\n            updateService(\"google\", [isClientConfig ? \"client_config\" : \"server_config\", property], newValue)\n        );\n    }, []);\n\n    return (\n        <div className={cx(\"flex h-full flex-col\")}>\n            <TabToolbar>\n                <Text className={\"p-unset\"} level={1}>\n                    Integrate your Anvil app with various Google services.&nbsp;\n                    <HelpLink iconRight inline url={\"/docs/integrations/google\"}>\n                        Learn More\n                    </HelpLink>\n                </Text>\n            </TabToolbar>\n\n            <div className={classes.container}>\n                <div className={classes.pagePanel}>\n                    <Heading level={1}>\n                        Google Drive <HelpLink inline url={\"/docs/integrations/google/google-drive#google-drive\"} />\n                    </Heading>\n                    <div className={cx(classes.sectionBody)}>\n                        <Text>\n                            App files are files or folders from your Google Drive that are available to any user of the\n                            app. Your users do not have to log in with Google; these files are always available to this\n                            application.{\" \"}\n                            <HelpLink iconRight inline url={\"/docs/integrations/google/google-drive#drive-app-files\"}>\n                                See example code\n                            </HelpLink>\n                        </Text>\n\n                        <div className={\"my-4\"}>\n                            {tokenError ? (\n                                <div className={classes.reconnect}>\n                                    <Heading level={1} className={\"mb-12\"}>\n                                        There was a problem connecting to your Google Account\n                                    </Heading>\n                                    <Button variant={\"tertiary\"} large onClick={initialLogin}>\n                                        Connect your account\n                                    </Button>\n                                </div>\n                            ) : refreshToken ? (\n                                <>\n                                    {appFiles.length > 0 ? (\n                                        <>\n                                            <div className={cx(classes.fileGrid)}>\n                                                <div className={cx(classes.headingRow, \"ml-4\")}>\n                                                    <Heading level={2}>Name</Heading>\n                                                </div>\n                                                <div className={classes.headingRow}>\n                                                    <Heading level={2}>Python Identifier</Heading>\n                                                </div>\n                                                <div className={cx(classes.headingRow, \"justify-self-center\")}>\n                                                    <Heading level={2}>Permissions</Heading>\n                                                </div>\n                                                <div className={cx(classes.headingRow, \"ml-12 justify-self-end\")}></div>\n\n                                                {appFiles.map((file, idx) => (\n                                                    <FileRow\n                                                        key={idx}\n                                                        file={file}\n                                                        pythonAppNames={pythonAppNames}\n                                                        ref={ref}\n                                                    />\n                                                ))}\n                                            </div>\n                                            <div className={\"flex justify-center py-12\"}>\n                                                <Button\n                                                    className={\"mr-6\"}\n                                                    variant={\"primary\"}\n                                                    icon={faPlus}\n                                                    onClick={addExistingButtonHandler}>\n                                                    Add existing file from Google Drive\n                                                </Button>\n                                                <Button\n                                                    variant={\"highlight1\"}\n                                                    icon={faPlus}\n                                                    onClick={() => addNewButtonHandler(\"file\")}\n                                                    menuItems={createMenuItems}>\n                                                    Add new file to Google Drive\n                                                </Button>\n                                            </div>\n                                            <Text level={3}>\n                                                Warning: A determined person with access to your app can read{\" \"}\n                                                <FontAwesomeIcon icon={faEye} /> files, and edit/delete{\" \"}\n                                                <FontAwesomeIcon icon={faPencil} /> files.{\" \"}\n                                                <HelpLink\n                                                    inline\n                                                    url={\"/docs/integrations/google/google-drive#drive-app-files\"}\n                                                />\n                                            </Text>\n                                        </>\n                                    ) : (\n                                        <div className={\"my-4 flex flex-col items-center justify-center gap-4\"}>\n                                            <Button\n                                                variant={\"primary\"}\n                                                large\n                                                icon={faPlus}\n                                                onClick={addExistingButtonHandler}>\n                                                Add files from Google Drive to this app\n                                            </Button>\n                                            <Button\n                                                variant={\"highlight1\"}\n                                                icon={faPlus}\n                                                onClick={() => addNewButtonHandler(\"file\")}\n                                                menuItems={createMenuItems}>\n                                                Add new file to Google Drive\n                                            </Button>\n                                        </div>\n                                    )}\n                                </>\n                            ) : (\n                                <div className={\"my-4 flex flex-col justify-center gap-4\"}>\n                                    <Button\n                                        variant={\"primary\"}\n                                        large\n                                        icon={faGoogleDrive}\n                                        onClick={() => loginThenOpenModal()}>\n                                        Add files from Google Drive to this app\n                                    </Button>\n                                    <Button\n                                        variant={\"highlight1\"}\n                                        icon={faPlus}\n                                        onClick={() => addNewButtonHandler(\"file\")}\n                                        menuItems={createMenuItems}>\n                                        Add new file to Google Drive\n                                    </Button>\n                                </div>\n                            )}\n                        </div>\n                    </div>\n                    {/*Auth*/}\n                    <>\n                        <hr />\n                        <Heading level={1}>\n                            Authorization with Google{\" \"}\n                            <HelpLink inline url={\"/docs/integrations/google/authenticating-users\"} />\n                        </Heading>\n\n                        <div className={cx(classes.sectionBody)}>\n                            <Text>\n                                Use <code className={\"select-all\"}>anvil.google.auth.login()</code> to login the user,\n                                then call <code className={\"select-all\"}>anvil.google.auth.get_user_email()</code> to\n                                get the email address of the logged-in user.\n                            </Text>\n                            <HelpLink iconRight inline url={\"/docs/integrations/google/authenticating-users#log-in\"}>\n                                See example code\n                            </HelpLink>\n                        </div>\n                    </>\n\n                    <hr />\n                    {/*Email*/}\n                    <div className={\"mr-14 flex\"}>\n                        <Heading level={1}>\n                            Gmail <HelpLink inline url={\"/docs/integrations/google/gmail\"} />\n                        </Heading>\n                        <div className={\"flex-1\"}></div> {/*Spacer*/}\n                        {mailEnabled ? ( //todo: make this some kind of indicator or label instead of disabled buttons\n                            <Button small icon={faLink} disabled variant={\"highlight1\"}>\n                                Enabled\n                            </Button>\n                        ) : (\n                            <Button small icon={faUnlink} disabled variant={\"danger\"}>\n                                Disabled\n                            </Button>\n                        )}\n                    </div>\n                    <div className={cx(classes.sectionBody)}>\n                        <pre className={\"m-4 select-all\"}>\n                            {`anvil.google.mail.send(to = \"sarah@example.com\",\n                       subject = \"Hello\",\n                       text = \"Hi, Sarah!\")`}\n                        </pre>\n                        <HelpLink url={\"/docs/integrations/google/gmail\"}>See example code</HelpLink>\n                        {!mailEnabled ? (\n                            <Button onClick={initialLogin} variant={\"primary\"} icon={faGoogle}>\n                                Enable Gmail\n                            </Button>\n                        ) : (\n                            <div className={\"m-12\"}></div>\n                        )}\n                    </div>\n                    {/*Advanced Settings*/}\n                    <>\n                        <hr />\n                        <Heading level={1}>Advanced Settings</Heading>\n                        <div className={cx(classes.sectionBody)}>\n                            <Heading level={2}>\n                                Access users' Google Drive{\" \"}\n                                <HelpLink inline url={\"/docs/integrations/google/google-drive#user-files\"} />\n                            </Heading>\n\n                            <Text>\n                                To access a user's Google Drive files, you must register your app with Google and then\n                                ask your user to log in using the <code>anvil.google.drive.login()</code> function.\n                            </Text>\n\n                            <Text>\n                                Get a Client ID and Client Secret from the{\" \"}\n                                <HelpLink inline iconRight url={\"/docs/integrations/google/linking-google-and-anvil\"}>\n                                    Google Developer Console\n                                </HelpLink>\n                            </Text>\n\n                            <Text level={3}>\n                                A client ID and secret are not needed if you're just using app files, sending email or{\" \"}\n                                <code>anvil.google.auth.login()</code>.\n                            </Text>\n                            <div className={\"mx-10\"}>\n                                <TextInput\n                                    className={\"w-3/4\"}\n                                    title={\"Client ID\"}\n                                    id={\"clientId\"}\n                                    placeholder={\"Client ID\"}\n                                    initialValue={clientId}\n                                    onChange={setClientId}\n                                    onSave={(v) => updateGoogleSetting(\"client_id\", v, false)}\n                                />\n                                <EncryptedTextInput\n                                    className={\"w-3/4\"}\n                                    setButtonText={clientSecretSet ? \"Update Client Secret\" : \"Set Client Secret\"}\n                                    title={\"Client Secret\"}\n                                    id={\"clientSecret\"}\n                                    placeholder={\"Client Secret\"}\n                                    initialValue={\"\"}\n                                    secretRestrict={\"google-service/client-secret\"}\n                                    onSave={saveClientSecret}\n                                />\n                                <div className={cx(formClasses.labelTitle)}>\n                                    <CheckBox\n                                        checked={appOriginRedirect}\n                                        icon={faShare}\n                                        onChange={() => updateRedirectAndSave(!appOriginRedirect)}>\n                                        <span className={\"font-semibold\"}>Redirect to App Origin</span>\n                                    </CheckBox>\n                                    {saveRedirectIndicator}\n                                </div>\n                                <div className={cx(formClasses.labelSubtitle, \"mb-8!\")}> </div>{\" \"}\n                                {/* todo: Maybe put some kind of useful text or description here */}\n                            </div>\n                            <Heading level={2}>\n                                Google Maps API{\" \"}\n                                <HelpLink inline url={\"/docs/client/components/maps#google-maps-in-production\"} />\n                            </Heading>\n                            <Text>\n                                To use Google Maps in production, you should{\" \"}\n                                <HelpLink\n                                    iconRight\n                                    inline\n                                    url={\"https://developers.google.com/maps/documentation/javascript/get-api-key\"}>\n                                    obtain an API key for your app\n                                </HelpLink>\n                            </Text>\n                            <Text level={3}>\n                                If you do not set an API key, you will be subject to the usage limits of our free-plan\n                                key, shared with other Anvil users.\n                            </Text>\n                            <div className={\"mx-10\"}>\n                                <TextInput\n                                    className={\"w-3/4\"}\n                                    title={\"Google Maps API Key\"}\n                                    id=\"mapsApiKey\"\n                                    placeholder={\"Maps API Key\"}\n                                    initialValue={mapsApiKey}\n                                    onChange={setMapsApiKey}\n                                    onSave={(v) => updateGoogleSetting(\"api_key\", v, true)}\n                                />\n                            </div>\n                        </div>\n                    </>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nconst connector = connect((state: State) => ({\n    googleService: getGoogleService(state),\n    user: getUser(state),\n}));\n\nexport default connector(GoogleServiceTab) as typeof GoogleServiceTab;\n","import { CST, isMap, isScalar, parseDocument, stringify } from \"yaml\";\n\ninterface StringProperty {\n    type: \"string\";\n    title: string;\n    enum?: string[];\n}\n\ninterface ObjectProperty {\n    type: \"object\";\n    properties: Record<string, StringProperty | ObjectProperty>;\n}\n\n// Illustrative JSON Schema properties; replace these with the agreed CI fields.\n// Only declared string leaves are editable; all other YAML content remains in the document.\nexport const deploymentSchema: ObjectProperty = {\n    type: \"object\",\n    properties: {\n        controls: {\n            type: \"object\",\n            properties: {\n                ice_component_name: { type: \"string\", title: \"ICE Component Name\" },\n                cyberflows: {\n                    type: \"object\",\n                    properties: {\n                        dast: {\n                            type: \"object\",\n                            properties: {\n                                configuration_id: { type: \"string\", title: \"DAST Configuration ID\" },\n                            },\n                        },\n                    },\n                },\n            },\n        },\n    },\n};\n\ninterface DeploymentField extends StringProperty {\n    path: string[];\n}\n\nfunction getSchemaFields(schema: ObjectProperty, path: string[] = []): DeploymentField[] {\n    return Object.entries(schema.properties).flatMap(([key, property]) =>\n        property.type === \"object\" ? getSchemaFields(property, [...path, key]) : [{ ...property, path: [...path, key] }]\n    );\n}\n\nconst deploymentFields = getSchemaFields(deploymentSchema);\n\nfunction parseAndValidateDeploymentDocument(content: string) {\n    const document = parseDocument(content, { keepSourceTokens: true });\n    if (document.errors.length) throw new Error(document.errors[0].message);\n    if (document.contents !== null && !isMap(document.contents)) {\n        throw new Error(\"The form editor requires a YAML mapping. Use the YAML editor for this file.\");\n    }\n    for (const property of deploymentFields) {\n        for (let length = 1; length < property.path.length; length++) {\n            const parentPath = property.path.slice(0, length);\n            const parent = document.getIn(parentPath, true);\n            if (parent !== undefined && !isMap(parent)) {\n                throw new Error(\n                    `${parentPath.join(\".\")} must be a mapping. Use the YAML editor to edit its current value.`\n                );\n            }\n        }\n        const node = document.getIn(property.path, true);\n        if (node !== undefined && (!isScalar(node) || typeof node.value !== \"string\")) {\n            throw new Error(`${property.title} must be text. Use the YAML editor to edit its current value.`);\n        }\n    }\n    return document;\n}\n\nexport function readDeploymentFields(content: string): Array<DeploymentField & { value: string }> {\n    const document = parseAndValidateDeploymentDocument(content);\n    return deploymentFields.map((field) => ({\n        ...field,\n        value: (document.getIn(field.path) as string | undefined) ?? \"\",\n    }));\n}\n\n/** Patch source tokens so static YAML values and formatting are never reserialized. */\nexport function patchDeploymentField(content: string, path: string[], value: string): string {\n    const property = deploymentFields.find(\n        (field) => field.path.length === path.length && field.path.every((key, index) => key === path[index])\n    );\n    if (!property) throw new Error(`Unknown deployment field: ${path.join(\".\")}`);\n    const document = parseAndValidateDeploymentDocument(content);\n    if (document.getIn(path) === value) return content;\n    if (property.enum && !property.enum.includes(value)) {\n        throw new Error(`Choose a supported value for ${property.title}.`);\n    }\n\n    const node = document.getIn(path, true);\n    let updated: string;\n    if (isScalar(node)) {\n        const token = node.srcToken!;\n        const end = token.offset + CST.stringify(token).length;\n        // Quoting prevents text like \"true\" or \"123\" from becoming another YAML type.\n        CST.setScalarValue(token, value, { type: \"QUOTE_DOUBLE\", afterKey: true });\n        updated = content.slice(0, token.offset) + CST.stringify(token) + content.slice(end);\n    } else {\n        // Insert just the missing subtree into the nearest existing mapping.\n        const missing = path.findIndex((_, index) => document.getIn(path.slice(0, index + 1), true) === undefined);\n        const parent = missing === 0 ? document.contents : document.getIn(path.slice(0, missing), true);\n        const subtree = path.slice(missing).reduceRight<unknown>((child, key) => ({ [key]: child }), value);\n        const newline = content.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n        let offset: number;\n        let insertion: string;\n        if (isMap(parent)) {\n            const token = parent.srcToken!;\n            if (token.type === \"flow-collection\") {\n                offset = token.end.find((part) => part.type === \"flow-map-end\")!.offset;\n                const lastItem = token.items.at(-1);\n                const trailingComma = lastItem?.start.some((part) => part.type === \"comma\") && !lastItem.key;\n                const separator = parent.items.length && !trailingComma ? \", \" : \" \";\n                insertion = separator + JSON.stringify(subtree).slice(1, -1);\n            } else if (token.type === \"block-map\") {\n                offset = token.offset + CST.stringify(token).length;\n                insertion =\n                    stringify(subtree)\n                        .trimEnd()\n                        .split(\"\\n\")\n                        .map((line) => \" \".repeat(token.indent) + line)\n                        .join(newline) + newline;\n                if (offset && content[offset - 1] !== \"\\n\") insertion = newline + insertion;\n            } else {\n                throw new Error(\"Use the YAML editor to add this field to its current mapping.\");\n            }\n        } else {\n            // An empty or comments-only file has no mapping token yet.\n            offset = content.length;\n            insertion =\n                (offset && content[offset - 1] !== \"\\n\" ? newline : \"\") + stringify(subtree).replaceAll(\"\\n\", newline);\n        }\n        updated = content.slice(0, offset) + insertion + content.slice(offset);\n    }\n    parseAndValidateDeploymentDocument(updated);\n    return updated;\n}\n","import { useMemo } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { DropDown, TextBox } from \"@/components/reusable/Forms\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { getAppIsEditable } from \"@/controllers/app\";\nimport { getExtraFileContent, saveExtraFile } from \"@/controllers/app/extra-files\";\nimport { alert } from \"@/controllers/modals\";\nimport type { AnvilDispatch, State } from \"@/types\";\nimport { decodeAssetContent } from \"@/util/asset-content\";\nimport { patchDeploymentField, readDeploymentFields } from \"./hawthorn-deployment-schema\";\n\nconst HawthornDeploymentFields = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const editable = useSelector(getAppIsEditable);\n    const content = useSelector((state: State) => getExtraFileContent(state, \"ci-config.yaml\"));\n    const parsed = useMemo(() => {\n        try {\n            return { values: readDeploymentFields(decodeAssetContent(content ?? \"\")) };\n        } catch (error) {\n            return { error: (error as Error).message };\n        }\n    }, [content]);\n\n    const saveFieldValue = (path: string[], value: string) => {\n        dispatch((dispatch, getState) => {\n            try {\n                // Patch the current file so another editor's changes are retained.\n                const current = getExtraFileContent(getState(), \"ci-config.yaml\");\n                dispatch(\n                    saveExtraFile(\n                        \"ci-config.yaml\",\n                        patchDeploymentField(decodeAssetContent(current ?? \"\"), path, value)\n                    )\n                );\n            } catch (error) {\n                dispatch(alert(\"Cannot update deployment fields\", (error as Error).message));\n            }\n        });\n    };\n\n    return (\n        <div className=\"h-full overflow-auto p-8\">\n            <div className=\"flex max-w-3xl flex-col gap-6\">\n                <Text>\n                    Prototype fields: these are illustrative, pending the final CI schema. Changes save to\n                    ci-config.yaml automatically.\n                </Text>\n                {parsed.error ? (\n                    <Text role=\"alert\">{parsed.error}</Text>\n                ) : (\n                    parsed.values!.map((property) => {\n                        const { path, value } = property;\n                        return (\n                            <label key={path.join(\".\")} className=\"flex flex-col gap-2\">\n                                <span className=\"font-semibold\">{property.title}</span>\n                                <span className=\"font-mono text-sm\">{path.join(\".\")}</span>\n                                {property.enum ? (\n                                    <DropDown\n                                        value={value}\n                                        disabled={!editable}\n                                        onChange={(event) => saveFieldValue(path, event.target.value)}>\n                                        <option value=\"\" disabled>\n                                            Choose a value\n                                        </option>\n                                        {value && !property.enum.includes(value) && (\n                                            <option value={value}>{value} (current value)</option>\n                                        )}\n                                        {property.enum.map((option) => (\n                                            <option key={option} value={option}>\n                                                {option}\n                                            </option>\n                                        ))}\n                                    </DropDown>\n                                ) : (\n                                    <TextBox\n                                        value={value}\n                                        disabled={!editable}\n                                        onChange={(event) => saveFieldValue(path, event.target.value)}\n                                    />\n                                )}\n                            </label>\n                        );\n                    })\n                )}\n            </div>\n        </div>\n    );\n};\n\nexport default HawthornDeploymentFields;\n","import { useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faSliders } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { ExtraFileEditor } from \"@/code_mirror/editors\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { Text } from \"@/components/reusable/Text\";\nimport { getAppExtraFiles, getAppIsEditable } from \"@/controllers/app\";\nimport { copyExtraAppFileFromTemplate } from \"@/controllers/app/extra-files\";\nimport {alert, confirm, modal} from \"@/controllers/modals\";\nimport { useUpdateTabTitle } from \"@/controllers/tabs\";\nimport type { AnvilDispatch, ServiceTab, State } from \"@/types\";\nimport HawthornDeploymentFields from \"./HawthornDeploymentFields\";\nimport TabToolbar from \"./TabToolbar\";\n\nconst HawthornDeploymentServiceTab = ({ tab, selected }: { tab: ServiceTab; selected: boolean }) => {\n    const [showFields, setShowFields] = useState(true);\n    const [copyingTemplate, setCopyingTemplate] = useState(false);\n    const dispatch = useDispatch<AnvilDispatch>();\n    const editable = useSelector(getAppIsEditable);\n    const file = useSelector((state: State) => getAppExtraFiles(state)[\"ci-config.yaml\"]);\n    const fileExists = typeof file === \"string\";\n    useUpdateTabTitle(tab, \"Hawthorn Deployment\");\n\n    const copyTemplateFile = async ({ restore = false } = {}) => {\n        setCopyingTemplate(true);\n        try {\n            if (\n                restore &&\n                !(await dispatch(\n                    confirm(\n                        \"Restore ci-config.yaml from template?\",\n                        \"This will replace ci-config.yaml with the template provided by your administrator. Your current changes to this file will be lost.\",\n                        \"Restore from template\",\n                        \"Cancel\"\n                    )\n                ))\n            ) {\n                return;\n            }\n            const copied = await dispatch(copyExtraAppFileFromTemplate(\"ci-config.yaml\", { replaceExisting: restore }));\n            if (!copied) {\n                await dispatch(\n                    alert(\n                        \"Configuration template unavailable\",\n                        `We couldn’t find a template for ci-config.yaml. ${restore ? \"Your current file has not been changed.\" : \"No file was created.\"} Ask your administrator to check the deployment configuration.`\n                    )\n                );\n            } else {\n                setShowFields(false);\n            }\n        } catch (error) {\n            await dispatch(alert(\"Could not load configuration template\", (error as Error).message));\n        } finally {\n            setCopyingTemplate(false);\n        }\n    };\n\n    return (\n        <div className=\"flex h-full min-h-0 flex-col\">\n            <TabToolbar className=\"gap-4\">\n                <Button\n                    size=\"small\"\n                    disabled={tab.$loading || copyingTemplate || !fileExists}\n                    onClick={() => setShowFields(!showFields)}>\n                    <FontAwesomeIcon icon={faSliders} className=\"mr-2\" />\n                    {showFields ? \"View YAML\" : \"Edit fields\"}\n                </Button>\n                <span className=\"font-mono\">ci-config.yaml</span>\n                {fileExists && (\n                    <Button\n                        size=\"small\"\n                        disabled={tab.$loading || copyingTemplate || !editable}\n                        onClick={() => copyTemplateFile({ restore: true })}>\n                        Restore from template\n                    </Button>\n                )}\n                <Button\n                    small\n                    variant={'primary'}\n                    onClick={() => dispatch(modal(\"hawthornDeploy\", {}))}\n                >\n                    Deploy Now\n                </Button>\n            </TabToolbar>\n            {tab.$loading ? (\n                <LoadingSpinner />\n            ) : !fileExists ? (\n                <div className=\"flex flex-1 flex-col items-center justify-center gap-4 p-8\">\n                    <Text>\n                        {file === undefined\n                            ? \"ci-config.yaml does not exist.\"\n                            : \"ci-config.yaml is a directory, not a file.\"}\n                    </Text>\n                    {file === undefined && (\n                        <Button disabled={!editable || copyingTemplate} onClick={() => copyTemplateFile()}>\n                            {copyingTemplate ? \"Creating file…\" : \"Create from template\"}\n                        </Button>\n                    )}\n                </div>\n            ) : (\n                <>\n                    {/* Keep CodeMirror mounted across view changes so its undo history survives. */}\n                    <div className={showFields ? \"hidden\" : \"min-h-0 flex-1\"}>\n                        <ExtraFileEditor\n                            filePath=\"ci-config.yaml\"\n                            fileType=\"yaml\"\n                            selected={selected && !showFields}\n                            height=\"100%\"\n                        />\n                    </div>\n                    {showFields && (\n                        <div className=\"min-h-0 flex-1\">\n                            <HawthornDeploymentFields />\n                        </div>\n                    )}\n                </>\n            )}\n        </div>\n    );\n};\n\nexport default HawthornDeploymentServiceTab;\n","import React, { useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faLink } from \"@fortawesome/pro-light-svg-icons\";\nimport { EncryptedTextInput } from \"@/components/reusable/SharedComponents\";\nimport { getMicrosoftService, updateService } from \"@/controllers/services\";\nimport { useUpdateTabTitle } from \"@/controllers/tabs\";\nimport { makeStyles } from \"@/theme/styles\";\nimport { cx } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport type { ServiceTab } from \"@/types/tabs\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { ButtonGroup } from \"../reusable/ButtonGroup\";\nimport { CheckBox, InputLabel } from \"../reusable/Forms\";\nimport { HelpLink } from \"../reusable/HelpLink\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport TextInput from \"../reusable/TextInput\";\nimport TabToolbar from \"./TabToolbar\";\n\nlet useStyles = makeStyles()((theme) => ({\n    container: {\n        background: theme.settings.rightBarBackground.toString(),\n        display: \"flex\",\n        flexDirection: \"column\",\n        overflowY: \"scroll\",\n    },\n    pagePanel: {\n        padding: \"1rem 4rem\",\n        width: \"90rem\",\n        borderRight: \"1px solid \" + theme.settings.separator.toString(),\n        background: theme.settings.background.toString(),\n        flexGrow: 1,\n        flexShrink: 0,\n    },\n    linkAppForm: {\n        marginTop: \"3rem\",\n        display: \"grid\",\n        gridTemplateColumns: \"2fr 4fr\",\n        gap: \"1rem 3rem\",\n        alignItems: \"baseline\",\n        width: \"80%\",\n    },\n    promptLabel: {\n        textAlign: \"right\",\n        margin: 0,\n    },\n    inputs: {},\n}));\n\nconst connector = connect((state: State) => ({\n    microsoftService: getMicrosoftService(state),\n}));\n\ntype MicrosoftServiceTabProps = AnvilConnectedProps<typeof connector> & {\n    tab: ServiceTab;\n};\n\nconst MicrosoftServiceTab = ({ tab, microsoftService, dispatch }: MicrosoftServiceTabProps) => {\n    const { classes } = useStyles();\n\n    useUpdateTabTitle(tab, \"Microsoft API\");\n\n    const updateMicrosoftServerSetting = useEvent(async (property: string, newValue: unknown) => {\n        await dispatch(updateService(\"microsoft\", [\"server_config\", property], newValue));\n    });\n\n    const [azureAppId, setAzureAppId] = useState(microsoftService?.server_config?.application_id || \"\");\n    const [linkAzureApp, setLinkAzureApp] = useState(azureAppId !== \"\");\n\n    const updateUserProvidedApp = useEvent(async (v: boolean) => {\n        if (!v) {\n            setAzureAppId(\"\");\n            await updateMicrosoftServerSetting(\"application_id\", null);\n        }\n        setLinkAzureApp(v);\n    });\n\n    const [azureAppSecretSet, setAzureAppSecretSet] = useState(\n        !!(\n            microsoftService?.server_config?.application_secret_enc ||\n            microsoftService?.server_config?.application_secret\n        )\n    );\n\n    const saveAzureAppSecret = useEvent(async (encrypted: string) => {\n        setAzureAppSecretSet(true);\n        await dispatch(updateService(\"microsoft\", [\"server_config\", \"application_secret_enc\"], encrypted));\n        if (microsoftService?.server_config?.application_secret) {\n            await dispatch(updateService(\"microsoft\", [\"server_config\", \"application_secret\"], null));\n        }\n    });\n\n    const [tenantType, setTenantType] = useState<\"single\" | \"organizations\">(\n        microsoftService?.server_config?.tenant_id === \"organizations\" ? \"organizations\" : \"single\"\n    );\n    const tenantOptions = [\n        { value: \"single\", title: \"Single-tenant\" },\n        { value: \"organizations\", title: \"Multi-tenant\" },\n    ] as const;\n    const [singleTenantId, setSingleTenantId] = useState(\n        tenantType === \"single\" ? microsoftService?.server_config?.tenant_id : \"\"\n    );\n    const updateTenantId = useEvent(async (value: \"single\" | \"organizations\") => {\n        setTenantType(value);\n        await updateMicrosoftServerSetting(\"tenant_id\", value === \"single\" ? singleTenantId : \"organizations\");\n    });\n\n    const [requestExtraOAuth, setRequestExtraOAuth] = useState(\n        !!microsoftService?.server_config?.additional_oauth_scopes\n    );\n    const extraOAuthOptions = [\n        { value: true, title: \"Yes\" },\n        { value: false, title: \"No\" },\n    ];\n    const [extraOAthScopes, setExtraOAthScopes] = useState(\n        microsoftService?.server_config?.additional_oauth_scopes || \"\"\n    );\n    const updateExtraScopes = useEvent(async (value: boolean) => {\n        setRequestExtraOAuth(value);\n        await updateMicrosoftServerSetting(\"additional_oauth_scopes\", value ? extraOAthScopes : null);\n    });\n\n    return (\n        <div className={\"flex h-full flex-col\"}>\n            <TabToolbar>\n                <Text className={\"p-unset\"} level={1}>\n                    Log users into your app with Microsoft.&nbsp;\n                    <HelpLink iconRight inline url={\"/docs/integrations/microsoft\"}>\n                        Learn More\n                    </HelpLink>\n                </Text>\n            </TabToolbar>\n            <div\n                className={cx(classes.container)}\n                style={{\n                    height: \"calc(100% - 5rem)\", // subtract height of TabToolbar\n                }}>\n                <div className={cx(classes.pagePanel)}>\n                    <Heading level={1}>\n                        <img src={\"ide/img/logos/microsoft.svg\"} /> Sign into your app with Microsoft\n                    </Heading>\n\n                    <Text level={1}>\n                        This service allows you to authenticate your app's users with their Microsoft accounts, such as\n                        Office 365, via Entra ID.\n                    </Text>\n                    <Text level={1}>\n                        Call <code>anvil.microsoft.auth.login()</code> from client code to log in, and{\" \"}\n                        <code>anvil.microsoft.auth.get_user_email()</code> from client or server code to identify the\n                        logged-in user.\n                    </Text>\n                    <Text level={1}>\n                        If you add the Users service and enable Microsoft sign-in, you can also use{\" \"}\n                        <code>anvil.users.login_with_form()</code> and <code>anvil.users.get_user()</code> as normal.\n                    </Text>\n                    <Text level={1}>\n                        You can use this service to authenticate any user with a Microsoft account, or you can restrict\n                        your app to users of a single Entra ID or Office 365 tenant.\n                    </Text>\n                    <Heading level={3}>Sample Code</Heading>\n                    <pre className=\"select-all\">\n                        {`anvil.microsoft.auth.login()\n\nalert(\"You are logged in as: %s\" % anvil.microsoft.auth.get_user_email())`}\n                    </pre>\n                    <hr />\n                    <Heading level={2} className=\"flex items-center gap-4\">\n                        <CheckBox\n                            checked={linkAzureApp}\n                            icon={faLink}\n                            onChange={() => updateUserProvidedApp(!linkAzureApp)}>\n                            Link to your own Entra ID app\n                        </CheckBox>{\" \"}\n                        <HelpLink inline url={\"docs/integrations/microsoft/linking-azure-and-anvil\"} />\n                    </Heading>\n                    <Text level={1}>\n                        If you would like to restrict logins to a single Entra ID or Office 365 tenant, or obtain OAuth\n                        Access Tokens for accessing other Microsoft APIs, you will need to set up an Entra ID app.{\" \"}\n                        <HelpLink inline iconRight url={\"docs/integrations/microsoft/linking-azure-and-anvil\"}>\n                            <br />\n                            See how to set up an app\n                        </HelpLink>\n                    </Text>\n                    <Text level={1}>{/*todo: add link icon when email services is merged in*/}</Text>\n                    {linkAzureApp && (\n                        <div>\n                            <TextInput\n                                title={\"Application ID\"}\n                                className={\"w-3/4\"}\n                                id=\"azureAppId\"\n                                placeholder={\"Enter Application ID\"}\n                                initialValue={azureAppId}\n                                onChange={setAzureAppId}\n                                onSave={(v) => updateMicrosoftServerSetting(\"application_id\", v)}\n                            />\n\n                            <EncryptedTextInput\n                                className={\"w-3/4\"}\n                                setButtonText={azureAppSecretSet ? \"Update Client Secret\" : \"Set Client Secret\"}\n                                title={\"Application client secret\"}\n                                id={\"azureAppSecret\"}\n                                placeholder={\"Application client secret\"}\n                                initialValue={\"\"}\n                                secretRestrict={\"microsoft-service/application-secret\"}\n                                onSave={saveAzureAppSecret}\n                            />\n\n                            <InputLabel title={\"Tenant ID\"}>\n                                <ButtonGroup\n                                    className={cx(\"mb-8\")}\n                                    options={tenantOptions}\n                                    selectedVariant={\"primary\"}\n                                    selectedOption={tenantType}\n                                    onClick={updateTenantId}></ButtonGroup>\n                                {tenantType === \"single\" && (\n                                    <TextInput\n                                        className={cx(classes.inputs, \"col-start-2\")}\n                                        id=\"singleTenantId\"\n                                        placeholder={\"Enter Tenant ID\"}\n                                        initialValue={singleTenantId}\n                                        onChange={setSingleTenantId}\n                                        onSave={(v) => updateMicrosoftServerSetting(\"tenant_id\", v)}\n                                    />\n                                )}\n                            </InputLabel>\n\n                            <InputLabel title={\"Request extra OAuth scopes\"}>\n                                <ButtonGroup\n                                    options={extraOAuthOptions}\n                                    selectedVariant={\"primary\"}\n                                    selectedOption={requestExtraOAuth}\n                                    onClick={updateExtraScopes}></ButtonGroup>\n                                {requestExtraOAuth && (\n                                    <TextInput\n                                        className={cx(classes.inputs, \"col-start-2\")}\n                                        id=\"extraOAthScopes\"\n                                        placeholder={\"Enter extra OAuth scopes to request (space-separated)\"}\n                                        initialValue={extraOAthScopes}\n                                        onChange={setExtraOAthScopes}\n                                        onSave={(v) => updateMicrosoftServerSetting(\"additional_oauth_scopes\", v)}\n                                    />\n                                )}\n                            </InputLabel>\n                        </div>\n                    )}\n                    <hr />\n                    <Heading level={2}>Using Other Microsoft APIs</Heading>\n                    <Text level={1}>\n                        If you link to an Entra ID app, you can access other Microsoft APIs on behalf of your users.\n                        Access files in OneDrive, edit documents in Office 365, and more. Just call{\" \"}\n                        <code>anvil.microsoft.auth.get_user_access_token()</code>.\n                    </Text>\n\n                    <HelpLink inline iconRight url={\"/docs/integrations/microsoft\"}>\n                        Learn how to use Microsoft APIs with Anvil\n                    </HelpLink>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport default connector(MicrosoftServiceTab);\n","import * as React from \"react\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faDownload, faLock, faShare } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { CheckBox, DropDown, InputLabel, useTextStyles } from \"@/components/reusable/Forms\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport Link from \"@/components/reusable/Link\";\nimport { useSaveIndicator } from \"@/components/reusable/SaveIndicator\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport TextInput from \"@/components/reusable/TextInput\";\nimport { getAppId, getAppOrigins } from \"@/controllers/app\";\nimport { getSAMLService, updateService } from \"@/controllers/services\";\nimport { useUpdateTabTitle } from \"@/controllers/tabs\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, AnvilDispatch, State } from \"@/types\";\nimport type { ServiceTab } from \"@/types/tabs\";\nimport * as api from \"@/api\";\nimport { useMemoAsync } from \"@/util/hooks\";\nimport TabToolbar from \"./TabToolbar\";\n\nconst useStyles = makeStyles()((theme) => ({\n    container: {\n        background: theme.settings.rightBarBackground.toString(),\n        display: \"flex\",\n        flexDirection: \"column\",\n        overflowY: \"scroll\",\n        height: \"calc(100% - 5rem)\",\n    },\n    pagePanel: {\n        padding: \"1rem 4rem\",\n        width: \"90rem\",\n        borderRight: \"1px solid \" + theme.settings.separator.toString(),\n        background: theme.settings.background.toString(),\n        flexGrow: 1,\n        flexShrink: 0,\n    },\n}));\n\nconst connector = connect((state: State) => ({\n    appId: getAppId(state)!,\n    samlService: getSAMLService(state),\n    appOrigins: getAppOrigins(state),\n}));\n\ntype SAMLServiceTabProps = AnvilConnectedProps<typeof connector> & {\n    tab: ServiceTab;\n};\n\nconst SAMLServiceTab = ({ tab, appId, samlService, appOrigins, dispatch }: SAMLServiceTabProps) => {\n    const { classes: formClasses } = useTextStyles();\n    const { classes } = useStyles();\n    const typedDispatch = dispatch as AnvilDispatch;\n\n    useUpdateTabTitle(tab, \"SAML Config\");\n\n    const updateSAMLServerSetting = useCallback(\n        async (property: string, newValue: string | boolean) => {\n            await typedDispatch(updateService(\"saml\", [\"server_config\", property], newValue));\n        },\n        [typedDispatch]\n    );\n\n    const updatePropertyAndSave = useCallback(\n        async (property: string, value: string | boolean, setIndicator: (saved: boolean) => void) => {\n            setIndicator(false);\n            await updateSAMLServerSetting(property, value);\n            setIndicator(true);\n        },\n        [updateSAMLServerSetting]\n    );\n\n    const [entityId, setEntityId] = useState(samlService?.server_config?.idp_entity_id || \"\");\n    const [ssoUrl, setSsoUrl] = useState(samlService?.server_config?.idp_sso_url || \"\");\n    const [signingCert, setSigningCert] = useState(samlService?.server_config?.idp_signing_cert || \"\");\n    const [emailAttribute, setEmailAttribute] = useState(samlService?.server_config?.email_attribute || \"\");\n    const shareSAMLConfig = useMemo(\n        () => samlService?.server_config?.shared || false,\n        [samlService?.server_config?.shared]\n    );\n    const forceAuth = useMemo(\n        () => samlService?.server_config?.force_authentication || false,\n        [samlService?.server_config?.force_authentication]\n    );\n    const signatureAlgorithm = useMemo(\n        () => samlService?.server_config?.signature_algorithm || \"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\",\n        [samlService?.server_config?.signature_algorithm]\n    );\n\n    const [saveShareIndicator, setSaveShareIndicator] = useSaveIndicator();\n    const [saveForceAuthIndicator, setForceAuthIndicator] = useSaveIndicator();\n    const [saveSignatureIndicator, setSaveSignatureIndicator] = useSaveIndicator();\n\n    const signatureAlgorithmOptions = useMemo(\n        () => [\n            { key: \"DSA-SHA1\", value: \"http://www.w3.org/2000/09/xmldsig#dsa-sha1\" },\n            { key: \"RSA-SHA1\", value: \"http://www.w3.org/2000/09/xmldsig#rsa-sha1\" },\n            { key: \"RSA-SHA256\", value: \"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\" },\n            { key: \"RSA-SHA384\", value: \"http://www.w3.org/2001/04/xmldsig-more#rsa-sha384\" },\n            { key: \"RSA-SHA512\", value: \"http://www.w3.org/2001/04/xmldsig-more#rsa-sha512\" },\n        ],\n        []\n    );\n\n    const samlMetadata = useMemoAsync<Awaited<ReturnType<typeof api.getSamlMetadata>> | null>(\n        null,\n        async () => await api.getSamlMetadata(appId),\n        [appId]\n    );\n\n    return (\n        <div className={\"flex h-full flex-col\"}>\n            <TabToolbar>\n                <Text className={\"p-unset\"} level={1}>\n                    Log users into your app with SAML.&nbsp;\n                    <HelpLink iconRight inline url={\"/docs/integrations/saml\"}>\n                        Learn More\n                    </HelpLink>\n                </Text>\n            </TabToolbar>\n            <div className={classes.container}>\n                <div className={classes.pagePanel}>\n                    <Heading level={1}>SAML</Heading>\n                    <Text level={1}>\n                        This service makes it easy to authenticate users using a third-party SAML Identity Provider.\n                        Your Anvil app will act as a SAML Service Provider.\n                    </Text>\n                    <hr />\n\n                    <Heading level={2}>\n                        Step 1: Configure this Anvil App to trust your SAML Identity Provider{\" \"}\n                        <HelpLink\n                            inline\n                            url={\n                                \"/docs/integrations/saml/configuration-options#configuring-your-anvil-app-with-your-identity-provider-s-details\"\n                            }\n                        />\n                    </Heading>\n                    <div className={\"mx-20\"}>\n                        <TextInput\n                            title={\"Entity ID\"}\n                            description={\n                                <>\n                                    The <code>EntityID</code> of your Identity Provider\n                                </>\n                            }\n                            id=\"entityId\"\n                            placeholder={\"Entity ID\"}\n                            initialValue={entityId}\n                            onChange={setEntityId}\n                            onSave={(v) => updateSAMLServerSetting(\"idp_entity_id\", v)}\n                        />\n                        <TextInput\n                            title={\"SSO URL\"}\n                            description={\"The Single-Sign-On URL of your Identity Provider\"}\n                            id=\"ssoUrl\"\n                            placeholder={\"SSO URL\"}\n                            initialValue={ssoUrl}\n                            onChange={setSsoUrl}\n                            onSave={(v) => updateSAMLServerSetting(\"idp_sso_url\", v)}\n                        />\n                        {/*todo: PEM format, check if this should be a textarea instead of textbox*/}\n                        <TextInput\n                            title={\"Signing Certificate\"}\n                            description={\n                                \"The certificate your Identity Provider uses to sign SAML responses, in PEM format\"\n                            }\n                            id=\"signingCert\"\n                            placeholder={\"Signing Certificate\"}\n                            initialValue={signingCert}\n                            onChange={setSigningCert}\n                            onSave={(v) => updateSAMLServerSetting(\"idp_signing_cert\", v)}\n                        />\n                        <TextInput\n                            title={\"Email Attribute\"}\n                            description={\n                                \"The SAML response attribute containing the email address of the user. Only required if the Identity Provider doesn't support the 'emailaddress' NameID Format, and doesn't provide the email address in the standard attributes.\"\n                            }\n                            id=\"emailAttribute\"\n                            placeholder={\"Optional attribute name - usually not required\"}\n                            initialValue={emailAttribute}\n                            onChange={setEmailAttribute}\n                            onSave={(v) => updateSAMLServerSetting(\"email_attribute\", v)}\n                        />\n                    </div>\n\n                    <Heading level={2}>\n                        Step 2: Configure SAML Authentication{\" \"}\n                        <HelpLink\n                            inline\n                            url={\n                                \"/docs/integrations/saml/configuration-options#configuring-your-saml-authentication-within-anvil\"\n                            }\n                        />\n                    </Heading>\n                    <div className={\"mx-20\"}>\n                        <div className={cx(formClasses.labelTitle)}>\n                            <CheckBox\n                                checked={shareSAMLConfig}\n                                icon={faShare}\n                                onChange={() =>\n                                    updatePropertyAndSave(\"shared\", !shareSAMLConfig, setSaveShareIndicator)\n                                }>\n                                <span className={\"font-semibold\"}>\n                                    Share SAML Configuration with my other apps{\" \"}\n                                    <HelpLink inline url={\"/docs/integrations/saml/sharing-credentials-across-apps\"} />\n                                </span>\n                            </CheckBox>\n                            {saveShareIndicator}\n                        </div>\n                        <div className={cx(formClasses.labelSubtitle, \"mb-8!\")}>\n                            Allow all your apps to authenticate to the same provider with the same Service Provider\n                            Metadata\n                        </div>\n\n                        <div className={cx(formClasses.labelTitle)}>\n                            <CheckBox\n                                checked={forceAuth}\n                                icon={faLock}\n                                onChange={() =>\n                                    updatePropertyAndSave(\"force_authentication\", !forceAuth, setForceAuthIndicator)\n                                }>\n                                <span className={\"font-semibold\"}>Force authentication</span>\n                            </CheckBox>\n                            {saveForceAuthIndicator}\n                        </div>\n                        <div className={cx(formClasses.labelSubtitle, \"mb-8!\")}>\n                            Force the user to re-authenticate with the Identity Provider every time, even if already\n                            logged in\n                        </div>\n                        <InputLabel\n                            title={\"Signature Algorithm\"}\n                            subtitle={\"The signature algorithm used to sign SAML requests\"}\n                            className={\"mb-8!\"}>\n                            <DropDown\n                                value={signatureAlgorithm}\n                                onChange={(e) =>\n                                    updatePropertyAndSave(\n                                        \"signature_algorithm\",\n                                        e.target.value,\n                                        setSaveSignatureIndicator\n                                    )\n                                }>\n                                {signatureAlgorithmOptions.map((option) => (\n                                    <option key={option.key} value={option.value}>\n                                        {option.key}\n                                    </option>\n                                ))}\n                            </DropDown>\n                            {saveSignatureIndicator}\n                        </InputLabel>\n                    </div>\n\n                    <Heading level={2}>\n                        Step 3: Configure your SAML Identity Provider to trust this Anvil App{\" \"}\n                        <HelpLink\n                            inline\n                            url={\n                                \"/docs/integrations/saml/configuration-options#configuring-your-identity-provider-with-your-anvil-app-s-details\"\n                            }\n                        />\n                    </Heading>\n                    <div className={\"mx-20\"}>\n                        <Link to={`${appOrigins?.debugOrigin}/_/saml-sp-metadata`}>\n                            <FontAwesomeIcon icon={faDownload} /> Download Service Provider Metadata\n                        </Link>\n                        <div className={cx(formClasses.labelSubtitle, \"mb-8!\")}>\n                            Download the metadata as an XML file that can be uploaded to some Identity Providers\n                        </div>\n\n                        <div className={cx(formClasses.labelTitle)}>Entity ID</div>\n                        <div className={cx(formClasses.labelSubtitle)}>\n                            The <code>EntityID</code> of this Service Provider (your Anvil App)\n                        </div>\n                        <pre className={cx(\"mb-8 select-all\")}>\n                            {samlMetadata?.entity_ids?.[shareSAMLConfig ? \"shared\" : \"app\"]}\n                        </pre>\n\n                        <div className={cx(formClasses.labelTitle)}>Signing Certificate</div>\n                        <div className={cx(formClasses.labelSubtitle)}>\n                            The certificate that will be used to sign all SAML requests to your Identity Provider\n                        </div>\n                        <pre className={cx(\"mb-8 select-all\")}>{samlMetadata?.signing_cert}</pre>\n\n                        <div className={cx(formClasses.labelTitle)}>Assertion Consumer Service URL</div>\n                        <Text level={1}>\n                            For information about your app's Assertion Consumer Service URL, see{\" \"}\n                            <HelpLink\n                                inline\n                                iconRight\n                                url={\n                                    \"/docs/integrations/saml/configuration-options#configuring-your-identity-provider-with-your-anvil-app-s-details\"\n                                }>\n                                the documentation\n                            </HelpLink>\n                        </Text>\n                    </div>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport default connector(SAMLServiceTab);\n","import React, { useMemo } from \"react\";\nimport { connect, useDispatch, useSelector } from \"react-redux\";\nimport { faCheck } from \"@fortawesome/free-solid-svg-icons/faCheck\";\nimport { faExclamationTriangle } from \"@fortawesome/free-solid-svg-icons/faExclamationTriangle\";\nimport { faTable } from \"@fortawesome/free-solid-svg-icons/faTable\";\nimport { faArrowLeft, faArrowRight, faUser, faUserSlash } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { sortBy } from \"lodash-es\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { getAvailableIndexTypesForSingleColumn } from \"@/components/tabs/database/header/ColumnHeader\";\nimport { getUser } from \"@/controllers/ide\";\nimport { alert, modal } from \"@/controllers/modals\";\nimport type {AnvilConnectedProps, AnvilDispatch, SingleLinkColumn, State} from \"@/types\";\nimport type {\n    AppSchema,\n    TableSchema as DatabaseTableSchema,\n    Diff,\n    NamedTableSchema,\n    SchemaColumnSpec,\n    TableIndex,\n    TableMapping,\n} from \"@/types/database\";\nimport type { SchemaTab as AppSchemaTab } from \"@/types/tabs\";\nimport { useFeatureSupported } from \"@/util/features\";\nimport { getAppDBSchema, getAllTableMappings, updateAppDBSchema, updateAppSchemaSync } from \"../../controllers/app\";\nimport {\n    getDebugEnvironmentTableMappingId,\n    getTableMappingDisplayName,\n    getRequiredSchemaDiffs,\n    maybeMigrateAppOrDB,\n    updateTableMappingSchema,\n} from \"../../controllers/db\";\nimport { useUpdateTabTitle } from \"../../controllers/tabs\";\nimport { cx, makeStyles } from \"../../theme/styles\";\nimport { useMemoAsync } from \"../../util/hooks\";\nimport useEvent from \"../../util/useEventCallback\";\nimport { Button } from \"../reusable/Button\";\nimport { Text } from \"../reusable/Text\";\n\nconst tableAccessTitle = {\n    none: \"No access\",\n    search: \"Read access\",\n    full: \"Full access\",\n} as const;\n\ntype SchemaTabClasses = \"columnContainer\" | \"columns\" | \"tableHeader\" | \"buttons\";\ninterface TableColumnDiff {\n    appColumn: SchemaColumnSpec | null;\n    currentColumn: SchemaColumnSpec | null;\n}\n\nexport const getIndexTitle = (index: TableIndex) => {\n    return {\n        b_tree: \"Lookup\",\n        trigram: \"Pattern matching\",\n        full_text: \"Full text\",\n    }[index.type];\n};\nexport const getIndexKey = (index: TableIndex) => `${index.type}:${index.columns.join(\":\")}`;\n\ninterface TableIndexDiff {\n    appIndex: TableIndex | null;\n    currentIndex: TableIndex | null;\n\n    // Only required if currentIndex is null - i.e. the index is missing from the DB.\n    indexAllowedInDb?: boolean; // True if the DB supports the index (e.g. link column indexes only supported in split tables)\n    indexAllowedForUser?: boolean; // True if the user has permission to create the index (e.g. Only dedicated users can create indexes in unified tables)\n}\n\ninterface CreateTableTableDiff extends DatabaseTableSchema {\n    type: \"CREATE_TABLES\";\n}\n\ntype OrganisedTableDiff = Exclude<Diff, Extract<Diff, { type: \"CREATE_TABLES\" }>> | CreateTableTableDiff;\ninterface TableChange {\n    type: \"table\";\n}\n\ntype TableMetaField = \"title\" | \"name\" | \"client\" | \"server\";\ninterface TableMetaChange {\n    type: \"updateTable\";\n    data: TableMetaField;\n}\n\ninterface ColumnChange {\n    type: \"column\";\n    appColumn: SchemaColumnSpec | null;\n    currentColumn: SchemaColumnSpec | null;\n}\n\ninterface IndexChange {\n    type: \"index\";\n    appIndex: TableIndex | null;\n    currentIndex: TableIndex | null;\n}\n\ntype TableUpdateChange = TableChange | TableMetaChange | ColumnChange | IndexChange;\ninterface TablePair {\n    appSchema: NamedTableSchema | null;\n    currentSchema: NamedTableSchema | null;\n}\n\ninterface SideBySideTable {\n    name: string;\n    schemas: TablePair;\n    diffs?: OrganisedTableDiff[];\n}\n\nconst connector = connect((state: State) => ({\n    appSchema: getAppDBSchema(state),\n    tableMappings: getAllTableMappings(state),\n}));\n\nconst useStyles = makeStyles<void, SchemaTabClasses>()((theme, _props, classes) => ({\n    root: {\n        padding: \"0 2rem\",\n        \"& ul\": {\n            listStyleType: \"none\",\n        },\n        display: \"flex\",\n        justifyContent: \"space-around\",\n        color: theme.schema.color.toString(),\n        width: \"100%\",\n        \"& > div\": {\n            maxWidth: \"130rem\",\n        },\n    },\n    status: {\n        textAlign: \"center\",\n        padding: \"0 2rem\",\n    },\n    check: {\n        margin: \"3rem\",\n        color: theme.palette.highlight.toString(),\n    },\n    exclamation: {\n        margin: \"3rem\",\n        color: theme.palette.secondary.toString(),\n    },\n    statusAction: {\n        margin: \"2rem 0\",\n        \"& > svg\": {},\n    },\n    actionButton: {\n        padding: \"1rem 0\",\n        // // height: '40rem',\n        height: \"max-content\",\n        \"& > div\": {\n            borderRadius: \"10px\",\n        },\n    },\n    colList: {\n        paddingLeft: \"4rem\",\n    },\n    mismatchAlert: {\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        display: \"flex\",\n        flexDirection: \"row\",\n        gridColumn: \"span 2 / span 2\",\n        border: \"3px solid \" + theme.sectionBorderColor.toString(),\n        borderRadius: \"6px\",\n        width: \"70%\",\n        margin: \"auto\",\n    },\n    columnContainer: {\n        display: \"contents\",\n    },\n    buttons: {},\n    tableDiffs: {\n        // border: '1px solid' + theme.sectionBorderColor.toString(),\n        borderRadius: \"5px\",\n        margin: \"1rem 0\",\n        background: theme.schema.tableBackgrounds.toString(),\n        [`& .${classes.columnContainer}:last-child`]: {\n            [`& .${classes.columns}:nth-last-of-type(2)`]: {\n                borderRadius: \"0 0 0 5px\",\n                borderBottom: \"1px solid \" + theme.sectionBorderColor.toString(),\n            },\n            [`& .${classes.columns}:last-child`]: {\n                borderRadius: \"0 0 5px 0\",\n                borderBottom: \"1px solid \" + theme.sectionBorderColor.toString(),\n            },\n        },\n        [`& :not(.${classes.buttons}).${classes.tableHeader}`]: {\n            [`&:nth-of-type(odd)`]: {\n                borderRadius: \"5px 0 0 0\",\n                borderTop: \"1px solid \" + theme.sectionBorderColor.toString(),\n            },\n            [`&:nth-of-type(even)`]: {\n                borderRadius: \"0 5px 0 0\",\n                borderTop: \"1px solid \" + theme.sectionBorderColor.toString(),\n            },\n        },\n    },\n    tableHeader: {\n        borderLeft: \"1px solid \" + theme.sectionBorderColor.toString(),\n        borderBottom: \"1px solid \" + theme.sectionBorderColor.toString(),\n    },\n    columns: {\n        borderLeft: \"1px solid \" + theme.sectionBorderColor.toString(),\n    },\n    highlightRow: {\n        backgroundColor: theme.schema.highlightRow.toString(),\n    },\n    highlightDiff: {\n        backgroundColor: theme.schema.highlightDiff.toString(),\n    },\n}));\n\nconst getNamedTableSchema = (schema: AppSchema | undefined | null, tableName: string): NamedTableSchema | null => {\n    const tableSchema = schema?.[tableName];\n    return tableSchema ? { ...tableSchema, name: tableName } : null;\n};\n\nconst Schema = ({ schema }: { schema: AppSchema | undefined | null }) => (\n    <ul>\n        {sortBy(Object.entries(schema ?? {}) as [string, DatabaseTableSchema][], [([pythonName]) => pythonName]).map(\n            ([python_name, schema]) => (\n                <TableSchema key={python_name} pythonName={python_name} schema={schema} />\n            )\n        )}\n    </ul>\n);\n\ntype ColumnSchemaProps = {\n    col: SchemaColumnSpec;\n};\n\nconst onDeleteDisplay = (onDeleteVal: SingleLinkColumn[\"on_delete\"]) => {\n    switch (onDeleteVal) {\n        case \"cascade\":\n            return \"Cascade\";\n        case \"set_null\":\n            return \"Set None\";\n        case \"restrict\":\n            return \"Restrict\";\n        default:\n            return \"not set\";\n    }\n};\n\nconst ColumnSchema = ({ col }: ColumnSchemaProps) => {\n    const { name, type } = col;\n    const target = \"target\" in col ? col.target : undefined;\n    const displayType = useMemo(() => {\n        if (target) {\n            return `Link to '${target}' row${type === \"link_multiple\" ? \"s\" : \"\"}${col.type === \"link_single\" && 'on_delete' in col ? ` (on delete ${onDeleteDisplay(col.on_delete!)})` : \"\"}`;\n        } else {\n            return type;\n        }\n    }, [type, target]);\n\n    return (\n        <li>\n            <span className={\"font-mono\"}>\n                <ClientHiddenIcon column={col} /> {name}\n            </span>{\" \"}\n            - <i>{displayType}</i>\n        </li>\n    );\n};\n\ntype TableSchemaProps = {\n    pythonName: string;\n    schema: DatabaseTableSchema;\n};\n\nconst TableSchema = ({ pythonName, schema }: TableSchemaProps) => {\n    const { classes } = useStyles();\n    return (\n        <li>\n            <FontAwesomeIcon icon={faTable} /> {schema?.title} (<span className={\"font-mono\"}>{pythonName}</span>) -\n            Client: {tableAccessTitle[schema?.client]}, Server: {tableAccessTitle[schema?.server]}\n            <ul className={classes.colList}>\n                {schema?.columns?.map((column) => (\n                    <ColumnSchema key={column.name} col={column} />\n                ))}\n            </ul>\n            <ul className={classes.colList}>\n                {schema?.indexes?.map((x, i) => (\n                    <li className=\"italic\" key={i}>\n                        {getIndexTitle(x)} index on{\" \"}\n                        <span className={\"font-mono font-semibold\"}>{x.columns.join(\", \")}</span>\n                    </li>\n                ))}\n            </ul>\n        </li>\n    );\n};\n\n// Utility functions for column operations\nconst columnUtils = {\n    hiddenMatches: (a: SchemaColumnSpec | null, b: SchemaColumnSpec | null) =>\n        !!a?.client_hidden === !!b?.client_hidden,\n\n    onDeleteMatches: (a: SingleLinkColumn | null, b: SingleLinkColumn | null) =>\n        a?.on_delete === b?.on_delete,\n\n    getDisplayType: (column: SchemaColumnSpec | null) => {\n        if (!column) return \"\";\n        const target = \"target\" in column ? column.target : undefined;\n        return target ? `Link to '${target}' row${column.type === \"link_multiple\" ? \"s\" : \"\"}${column.type === \"link_single\" && 'on_delete' in column ? ` (on delete ${onDeleteDisplay(column.on_delete)})` : \"\"}` : column.type;\n    },\n\n    getTooltip: (columnA: SchemaColumnSpec | null, columnB: SchemaColumnSpec | null, location: string) => {\n        if (!columnA) return `Delete this column in the ${location}`;\n        if (columnB && !columnUtils.hiddenMatches(columnA, columnB)) {\n            return `${columnA.client_hidden ? \"Hide\" : \"Show\"} this column on the client in the ${location}`;\n        }\n        if (columnA.type === \"link_single\" && columnB?.type === \"link_single\" && !columnUtils.onDeleteMatches(columnA, columnB)) {\n            return `Change the on-delete action for this column in the ${location}`;\n        }\n        return `Create this column in the ${location}`;\n    },\n};\n\n// UI Components\ntype ClientHiddenIconProps = {\n    column: SchemaColumnSpec | null;\n};\n\nconst ClientHiddenIcon = ({ column }: ClientHiddenIconProps) => {\n    const [tooltip, tooltipRef] = useTooltip(column?.client_hidden ? \"Hidden from client\" : \"Visible to client\", \"top\");\n\n    return (\n        <span ref={tooltipRef}>\n            <FontAwesomeIcon\n                className={cx({ \"text-primary\": !column?.client_hidden })}\n                icon={column?.client_hidden ? faUserSlash : faUser}\n                fixedWidth\n            />\n            {tooltip}\n        </span>\n    );\n};\n\ntype ColumnInfoProps = {\n    column: SchemaColumnSpec | null;\n};\n\nconst ColumnInfo = ({ column }: ColumnInfoProps) => {\n    if (!column) return null;\n    return (\n        <div className={\"inline-flex items-center gap-4\"}>\n            <ClientHiddenIcon column={column} />\n            <div>\n                <span className={\"font-mono\"}>{column?.name}</span> -<i>{columnUtils.getDisplayType(column)}</i>\n            </div>\n        </div>\n    );\n};\n\nconst IndexInfo = ({ index }: { index: TableIndex | null }) => {\n    if (!index) return null;\n    return (\n        <div className={\"inline-flex items-center gap-4\"}>\n            <div>\n                {getIndexTitle(index)} index on <span className={\"font-mono\"}>{index.columns.join(\", \")}</span>\n            </div>\n        </div>\n    );\n};\n\nconst useColumnTooltip = (\n    columnA: SchemaColumnSpec | null,\n    columnB: SchemaColumnSpec | null,\n    location: string,\n    direction: \"top\" | \"left\" | \"right\"\n) => {\n    const tooltip = columnUtils.getTooltip(columnA, columnB, location);\n    return useTooltip(tooltip, direction);\n};\n\ntype MigrationButtonProps = {\n    tooltipRef: React.Ref<HTMLDivElement>;\n    position?: \"right\" | \"left\";\n    variant?: React.ComponentProps<typeof Button>[\"variant\"];\n    onClick: () => void;\n    disabled?: boolean;\n};\n\nconst MigrationButton = ({\n    tooltipRef,\n    position = \"right\",\n    variant = \"tertiary\",\n    onClick,\n    disabled,\n}: MigrationButtonProps) => (\n    <Button\n        ref={tooltipRef}\n        className={cx(`absolute ${position}-2`)}\n        size={\"tiny\"}\n        variant={variant}\n        onClick={onClick}\n        disabled={disabled}>\n        <FontAwesomeIcon icon={position === \"right\" ? faArrowRight : faArrowLeft} />\n    </Button>\n);\n\ntype TableItemContainerProps = {\n    column: SchemaColumnSpec | null;\n    showMigrateButton: boolean;\n    disableMigrationButton?: boolean;\n    hasDiff: boolean;\n    hasTableInSchema: boolean;\n    hasTableInOtherSchema: boolean;\n    tooltipRef: React.Ref<HTMLDivElement>;\n    tooltip: React.ReactNode;\n    buttonPosition?: \"right\" | \"left\";\n    buttonVariant?: React.ComponentProps<typeof Button>[\"variant\"];\n    onMigrate: () => void;\n    extraClassName?: string;\n    children?: React.ReactNode;\n};\n\nconst TableItemContainer = ({\n    column,\n    showMigrateButton,\n    disableMigrationButton = false,\n    hasDiff,\n    hasTableInSchema,\n    hasTableInOtherSchema,\n    tooltipRef,\n    tooltip,\n    buttonPosition = \"right\",\n    buttonVariant = \"tertiary\",\n    onMigrate,\n    extraClassName = \"\",\n    children,\n}: TableItemContainerProps) => {\n    const { classes } = useStyles();\n\n    const containerClasses = cx(\n        \"relative\",\n        \"flex items-center justify-between pr-8 pl-20\",\n        showMigrateButton && \"group-hover/columns:bg-light-bg4 dark:group-hover/columns:bg-dark-bg3\",\n        classes.columns,\n        (hasTableInSchema || (hasDiff && column)) && classes.highlightDiff,\n        hasDiff && !hasTableInOtherSchema && classes.highlightRow,\n        extraClassName\n    );\n\n    return (\n        <div className={containerClasses}>\n            {children ?? <ColumnInfo column={column} />}\n            {showMigrateButton && (\n                <MigrationButton\n                    tooltipRef={tooltipRef}\n                    position={buttonPosition}\n                    variant={buttonVariant}\n                    onClick={onMigrate}\n                    disabled={disableMigrationButton}\n                />\n            )}\n            {tooltip}\n        </div>\n    );\n};\n\ntype ColDiffsProps = {\n    colData: TableColumnDiff;\n    hasTableInAppSchema: boolean;\n    hasTableInCurrentSchema: boolean;\n    updateAppSchema: (change: TableUpdateChange) => Promise<void>;\n    updateTable: (change: TableUpdateChange) => Promise<void>;\n};\n\nconst ColDiffs = ({\n    colData: { appColumn, currentColumn },\n    hasTableInAppSchema,\n    hasTableInCurrentSchema,\n    updateAppSchema,\n    updateTable,\n}: ColDiffsProps) => {\n    const { classes } = useStyles();\n\n    const hasDiff =\n        appColumn?.name !== currentColumn?.name ||\n        appColumn?.type !== currentColumn?.type ||\n        !columnUtils.hiddenMatches(appColumn, currentColumn) ||\n        (appColumn?.type === \"link_single\" && currentColumn?.type === \"link_single\" && !columnUtils.onDeleteMatches(appColumn, currentColumn));\n\n    const showMigrateButton = hasDiff && hasTableInAppSchema === hasTableInCurrentSchema;\n\n    const [changeDBTT, changeDBTTRef] = useColumnTooltip(appColumn, currentColumn, \"database\", \"left\");\n    const [changeAppTT, changeAppTTRef] = useColumnTooltip(currentColumn, appColumn, \"app schema\", \"right\");\n\n    return (\n        <div className={cx(classes.columnContainer, \"group/columns\")}>\n            <TableItemContainer\n                column={appColumn}\n                showMigrateButton={showMigrateButton}\n                hasDiff={hasDiff}\n                hasTableInSchema={hasTableInAppSchema}\n                hasTableInOtherSchema={hasTableInCurrentSchema}\n                tooltipRef={changeDBTTRef}\n                tooltip={changeDBTT}\n                onMigrate={() => updateTable({ type: \"column\", appColumn, currentColumn })}\n            />\n            <TableItemContainer\n                column={currentColumn}\n                showMigrateButton={showMigrateButton}\n                hasDiff={hasDiff}\n                hasTableInSchema={hasTableInCurrentSchema}\n                hasTableInOtherSchema={hasTableInAppSchema}\n                tooltipRef={changeAppTTRef}\n                tooltip={changeAppTT}\n                buttonPosition=\"left\"\n                buttonVariant=\"primary\"\n                onMigrate={() => updateAppSchema({ type: \"column\", appColumn, currentColumn })}\n                extraClassName=\"border-r-[1px] border-sectionborder dark:border-dark-sectionborder\"\n            />\n        </div>\n    );\n};\n\ntype TableDiffsProps = {\n    name: string;\n    schemas: TablePair;\n    diffs?: OrganisedTableDiff[];\n    tableMapping: TableMapping;\n};\n\nconst IndexDiffs = ({\n    entry: { appIndex, currentIndex, indexAllowedInDb, indexAllowedForUser },\n    hasTableInAppSchema,\n    hasTableInCurrentSchema,\n    updateAppSchema,\n    updateTable,\n}: {\n    entry: TableIndexDiff;\n    hasTableInAppSchema: boolean;\n    hasTableInCurrentSchema: boolean;\n    updateAppSchema: (change: TableUpdateChange) => Promise<void>;\n    updateTable: (change: TableUpdateChange) => Promise<void>;\n}) => {\n    const { classes } = useStyles();\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const hasDiff = !appIndex || !currentIndex;\n    const showMigrateButton = hasDiff && hasTableInAppSchema === hasTableInCurrentSchema;\n\n    let changeDbToolTipText;\n    const actionText = appIndex ? \"Create this index in\" : \"Delete this index from\";\n    if (!indexAllowedInDb) {\n        changeDbToolTipText = `Cannot ${actionText} the database - index type not supported.`;\n    } else if (!indexAllowedForUser) {\n        changeDbToolTipText = `Upgrade to ${actionText} the database.`;\n    } else {\n        changeDbToolTipText = `${actionText} the database`;\n    }\n\n    const [changeDBTT, changeDBTTRef] = useTooltip(changeDbToolTipText, \"left\");\n    const [changeAppTT, changeAppTTRef] = useTooltip(\n        `${currentIndex ? \"Create this index in\" : \"Delete this index from\"} the app schema`,\n        \"right\"\n    );\n    return (\n        <div className={cx(classes.columnContainer, \"group/columns\")}>\n            <TableItemContainer\n                column={null}\n                showMigrateButton={showMigrateButton}\n                disableMigrationButton={!indexAllowedInDb}\n                hasDiff={hasDiff}\n                hasTableInSchema={hasTableInAppSchema}\n                hasTableInOtherSchema={hasTableInCurrentSchema}\n                tooltipRef={changeDBTTRef}\n                tooltip={changeDBTT}\n                onMigrate={() =>\n                    indexAllowedForUser\n                        ? updateTable({ type: \"index\", appIndex, currentIndex })\n                        : dispatch(modal(\"upgradePrompt\", { featureId: \"db-indexes\" }))\n                }>\n                <IndexInfo index={appIndex} />\n            </TableItemContainer>\n            <TableItemContainer\n                column={null}\n                showMigrateButton={showMigrateButton}\n                hasDiff={hasDiff}\n                hasTableInSchema={hasTableInCurrentSchema}\n                hasTableInOtherSchema={hasTableInAppSchema}\n                tooltipRef={changeAppTTRef}\n                tooltip={changeAppTT}\n                buttonPosition=\"left\"\n                buttonVariant=\"primary\"\n                onMigrate={() => updateAppSchema({ type: \"index\", appIndex, currentIndex })}\n                extraClassName=\"border-r-[1px] border-sectionborder dark:border-dark-sectionborder\">\n                <IndexInfo index={currentIndex} />\n            </TableItemContainer>\n        </div>\n    );\n};\n\nconst TableDiffs = ({ name, schemas: { appSchema, currentSchema }, diffs = [], tableMapping }: TableDiffsProps) => {\n    const { classes } = useStyles();\n    const hasTableUpdate = useMemo(() => diffs.some((diff) => diff.type === \"UPDATE_TABLE\"), [diffs]);\n    const hasTableInAppSchema = useMemo(() => diffs.some((diff) => diff.type === \"CREATE_TABLES\"), [diffs]);\n    const hasTableInCurrentSchema = useMemo(() => diffs.some((diff) => diff.type === \"DELETE_TABLE\"), [diffs]);\n    const hasNewTableInASchema = useMemo(\n        () => hasTableInCurrentSchema || hasTableInAppSchema,\n        [hasTableInAppSchema, hasTableInCurrentSchema]\n    );\n\n    const dispatch = useDispatch<AnvilDispatch>();\n    const entireAppSchema = useSelector(getAppDBSchema);\n    const supportsDbIndexes = useFeatureSupported(\"db-indexes\");\n    const supportsDbIndexesSplit = useFeatureSupported(\"db-indexes-split\");\n\n    const tableSidebySide = useMemo(() => {\n        const appColumns = appSchema?.columns?.map((column) => column.name) ?? [];\n        const currentColumns = currentSchema?.columns?.map((column) => column.name) ?? [];\n        const allColumns = [...new Set([...appColumns, ...currentColumns])];\n\n        const twoTables: Record<string, TableColumnDiff> = {};\n        allColumns.forEach((columnName) => {\n            const appColumn = appSchema?.columns?.find((col) => col.name === columnName) ?? null;\n            const currentColumn = currentSchema?.columns?.find((col) => col.name === columnName) ?? null;\n            //todo: this whole part will need to be redone once the renaming in the diffs is fixed\n            if (appColumn && currentColumn && appColumn.type !== currentColumn.type) {\n                twoTables[`${columnName}-app`] = {\n                    appColumn,\n                    currentColumn: null,\n                };\n                twoTables[`${columnName}-curr`] = {\n                    appColumn: null,\n                    currentColumn,\n                };\n            } else {\n                twoTables[columnName] = {\n                    appColumn,\n                    currentColumn,\n                };\n            }\n        });\n        return twoTables;\n    }, [appSchema, currentSchema]);\n\n    const tableIndexesSideBySide = useMemo<Record<string, TableIndexDiff>>(() => {\n        const appIndexes = appSchema?.indexes || [];\n        const currentIndexes = currentSchema?.indexes || [];\n\n        const accumulateIndexesByKey = (all: Record<string, TableIndex>, index: TableIndex) => {\n            all[getIndexKey(index)] = index;\n            return all;\n        };\n        const appIndexesByKey = appIndexes.reduce(accumulateIndexesByKey, {});\n        const currentIndexesByKey = currentIndexes.reduce(accumulateIndexesByKey, {});\n\n        const allKeys = [...new Set([...Object.keys(appIndexesByKey), ...Object.keys(currentIndexesByKey)])];\n\n        return allKeys.reduce<Record<string, TableIndexDiff>>((pairs, key) => {\n            const appIndex = appIndexesByKey[key] ?? null;\n            const currentIndex = currentIndexesByKey[key] ?? null;\n            pairs[key] = {\n                appIndex: appIndex,\n                currentIndex: currentIndex,\n            };\n            if (!currentIndex) {\n                const table = tableMapping.tables.find((t) => t.python_name === name);\n                if (appIndex.columns.length > 1) {\n                    // This multi-column index is allowed iff the type is b_tree and the table is split.\n                    pairs[key].indexAllowedInDb = !!table?.split && appIndex.type === \"b_tree\";\n                } else {\n                    // This is a single-column index. We need to see if it's valid for the type of column it refers to (and the table storage mode)\n                    const col = Object.values(table?.columns || {}).find((c) => c.name === appIndex.columns[0]);\n                    if (col) {\n                        pairs[key].indexAllowedInDb = getAvailableIndexTypesForSingleColumn(col.type, table!).some(\n                            (i) => i.type === appIndex.type\n                        );\n                    } else {\n                        pairs[key].indexAllowedInDb = false;\n                    }\n                }\n                pairs[key].indexAllowedForUser = table?.split ? supportsDbIndexesSplit : supportsDbIndexes;\n            }\n            return pairs;\n        }, {});\n    }, [appSchema, currentSchema, name, tableMapping?.tables, supportsDbIndexes, supportsDbIndexesSplit]);\n\n    //choose app Schema (left)\n    const updateTable = useEvent(async (change: TableUpdateChange) => {\n        const requiredChanges: Diff[] = [];\n\n        switch (change?.type) {\n            case \"table\": {\n                diffs.forEach((diff) => {\n                    if (diff.type === \"CREATE_TABLES\") {\n                        const tables: AppSchema = {\n                            [name]: {\n                                title: diff.title,\n                                client: diff.client,\n                                server: diff.server,\n                                columns: diff.columns,\n                                indexes: diff.indexes,\n                            },\n                        };\n                        requiredChanges.push({\n                            type: \"CREATE_TABLES\",\n                            tables,\n                        });\n                    } else {\n                        requiredChanges.push(diff);\n                    }\n                });\n                break;\n            }\n            case \"column\": {\n                const { appColumn, currentColumn } = change;\n                //todo: rework how this works with renaming. the ADD_COLUMN kind of takes care of it atm\n                if (!appColumn) {\n                    //remove column from tablemapping\n                    const diff = diffs.find(\n                        (entry): entry is Extract<Diff, { type: \"DELETE_COLUMN\" }> =>\n                            entry.type === \"DELETE_COLUMN\" && entry.column_name === currentColumn?.name\n                    );\n                    if (diff) {\n                        requiredChanges.push(diff);\n                    }\n                } else if (currentColumn && appColumn.name === currentColumn.name) {\n                    // This is an update to an existing column (e.g. client_hidden change)\n                    const diff = diffs.find(\n                        (entry): entry is Extract<Diff, { type: \"UPDATE_COLUMN\" }> =>\n                            entry.type === \"UPDATE_COLUMN\" &&\n                            entry.column_name === appColumn.name &&\n                            (!columnUtils.hiddenMatches({ ...currentColumn, ...entry.changes }, currentColumn)\n                                 || (currentColumn.type === \"link_single\" && !columnUtils.onDeleteMatches({ ...currentColumn, ...entry.changes }, currentColumn)))\n                    );\n                    if (diff) {\n                        requiredChanges.push(diff);\n                    }\n                } else if (currentSchema) {\n                    // This is a new column or rename\n                    if (currentSchema.columns.find((col) => col.name === appColumn.name)) {\n                        await dispatch(\n                            alert(\n                                `Cannot add ${appColumn.name} to table in database`,\n                                `A column titled ${appColumn.name} already exists in the database. Please remove the existing ${appColumn.name} in ${currentSchema.title} of the database before replacing it.`\n                            )\n                        );\n                        return;\n                    }\n                    const diff = diffs.find(\n                        (entry): entry is Extract<Diff, { type: \"ADD_COLUMN\" }> =>\n                            entry.type === \"ADD_COLUMN\" && entry.column.name === appColumn.name\n                    );\n                    if (diff) {\n                        requiredChanges.push(diff);\n                    }\n                    // todo: check if you add a column but a column of that same name exists, is it supposed to do nothing or add and overwrite what already exists\n                }\n                break;\n            }\n            case \"index\":\n                const { appIndex, currentIndex } = change;\n                // We are either creating or deleting an index, there are no updates.\n                if (appIndex) {\n                    // We are creating the index in the DB\n                    const key = getIndexKey(appIndex);\n                    const diff = diffs.find(\n                        (entry): entry is Extract<Diff, { type: \"ADD_INDEX\" }> =>\n                            entry.type === \"ADD_INDEX\" && getIndexKey(entry.index) === key\n                    );\n                    if (diff) {\n                        requiredChanges.push(diff);\n                    }\n                } else {\n                    // We are deleting the index from the DB\n                    if (!currentIndex) return;\n                    const key = getIndexKey(currentIndex);\n                    const diff = diffs.find(\n                        (entry): entry is Extract<Diff, { type: \"DELETE_INDEX\" }> =>\n                            entry.type === \"DELETE_INDEX\" && getIndexKey(entry.index) === key\n                    );\n                    if (diff) {\n                        requiredChanges.push(diff);\n                    }\n                }\n                break;\n            case \"updateTable\": {\n                if (!appSchema || !currentSchema) return;\n                const diff = {\n                    type: \"UPDATE_TABLE\",\n                    title: currentSchema.title,\n                    client: currentSchema.client,\n                    server: currentSchema.server,\n                    new_python_name: currentSchema.name,\n                    table: currentSchema.name,\n                    [change.data === \"name\" ? \"new_python_name\" : change.data]: appSchema[change.data],\n                } satisfies Extract<Diff, { type: \"UPDATE_TABLE\" }>;\n\n                requiredChanges.push(diff);\n                break;\n            }\n            default:\n                break;\n        }\n        const resp = await dispatch(\n            modal(\"schemaMismatch\", {\n                requiredChanges,\n                tableMapping,\n            })\n        );\n        if (resp === \"update-db\") {\n            await dispatch(updateTableMappingSchema(tableMapping, requiredChanges));\n            dispatch(updateAppSchemaSync());\n            // todo: This will need to also change the read privileges for tabs that are already open\n        }\n    });\n\n    //choose database (right)\n    const updateAppSchema = useEvent(async (change: TableUpdateChange) => {\n        const schema: AppSchema = { ...(entireAppSchema ?? {}) };\n        if (!schema[name]) {\n            schema[name] = { client: \"none\", columns: [], indexes: [], server: \"none\", title: name };\n        }\n        switch (change?.type) {\n            case \"table\":\n                if (tableMapping.schema?.[name]) {\n                    schema[name] = tableMapping.schema?.[name];\n                } else {\n                    delete schema[name];\n                }\n                break;\n            case \"column\": {\n                const columns = [...schema[name].columns];\n                const { appColumn, currentColumn } = change;\n                if (!currentColumn) {\n                    const ind = columns.findIndex(\n                        (column) => column.name === appColumn?.name && column.type === appColumn?.type\n                    );\n                    columns.splice(ind, 1);\n                } else if (appColumn && currentColumn.name === appColumn?.name) {\n                    // This is an update to an existing column (e.g. client_hidden)\n                    const existingColumnIndex = columns.findIndex((column) => column.name === currentColumn.name);\n                    if (existingColumnIndex !== -1) {\n                        columns[existingColumnIndex] = currentColumn;\n                    }\n                } else {\n                    const sameName = columns.find((column) => column.name === currentColumn.name);\n                    if (sameName) {\n                        //todo: alert is just for show. This just won't happen becuase of how updateAppDBSchema works\n                        dispatch(\n                            alert(\n                                \"Unable to update app schema\",\n                                `A column named ${sameName.name} already exists in the app schema. Migration aborted. Please remove the column before replacing it.`\n                            )\n                        );\n                        return;\n                    } else {\n                        columns.push(currentColumn);\n                    }\n                }\n                schema[name] = { ...schema[name], columns };\n                break;\n            }\n            case \"index\": {\n                const { appIndex, currentIndex } = change;\n                const indexes = [...(schema[name].indexes||[])];\n                // We are either creating or deleting an index, there are no updates.\n                if (appIndex) {\n                    // We must be deleting the index\n                    const currentIndexKey = getIndexKey(appIndex);\n                    indexes.splice(\n                        indexes.findIndex((idx) => getIndexKey(idx) === currentIndexKey),\n                        1\n                    );\n                } else if (currentIndex) {\n                    // We must be creating the index\n                    indexes.push(currentIndex);\n                }\n                schema[name] = { ...schema[name], indexes };\n                break;\n            }\n            case \"updateTable\": {\n                if (!tableMapping.schema?.[name]) return;\n                const { client, server, title } = tableMapping.schema[name];\n                const newPythonName = diffs.find(\n                    (diff): diff is Extract<Diff, { type: \"UPDATE_TABLE\" }> => diff.type === \"UPDATE_TABLE\"\n                )?.new_python_name;\n\n                if (change.data === \"name\") {\n                    if (!newPythonName) return;\n                    // rename the object\n                    schema[name] = { ...schema[newPythonName] };\n                    delete schema[newPythonName];\n                } else {\n                    schema[name] = { ...schema[name], [change.data]: tableMapping.schema[name][change.data] };\n                }\n                break;\n            }\n            default:\n                break;\n        }\n\n        await dispatch(updateAppDBSchema(schema));\n        dispatch(updateAppSchemaSync());\n    });\n\n    const tableColumns = useMemo(() => {\n        const entries = Object.entries(tableSidebySide);\n        if (entries.length === 0)\n            return (\n                <div\n                    className={\n                        \"col-span-2 rounded-b-[5px] border-x border-b border-sectionborder py-1 dark:border-dark-sectionborder\"\n                    }\n                />\n            );\n\n        return (\n            <>\n                {sortBy(entries, [([name, _]) => name]).map(([colName, colData]) => {\n                    return (\n                        <ColDiffs\n                            key={colName}\n                            colData={colData}\n                            hasTableInAppSchema={hasTableInAppSchema}\n                            hasTableInCurrentSchema={hasTableInCurrentSchema}\n                            updateAppSchema={updateAppSchema}\n                            updateTable={updateTable}\n                        />\n                    );\n                })}\n            </>\n        );\n    }, [\n        appSchema,\n        currentSchema,\n        tableSidebySide,\n        hasTableInAppSchema,\n        hasTableInCurrentSchema,\n        updateTable,\n        updateAppSchema,\n    ]);\n\n    const tableIndexes = useMemo(() => {\n        const entries = Object.entries(tableIndexesSideBySide || {});\n        if (entries.length === 0)\n            return (\n                <div\n                    className={\n                        \"col-span-2 rounded-b-[5px] border-x border-b border-sectionborder py-1 dark:border-dark-sectionborder\"\n                    }\n                />\n            );\n\n        return (\n            <>\n                {sortBy(entries, [([key]) => key]).map(([key, entry]) => {\n                    return (\n                        <IndexDiffs\n                            key={key}\n                            entry={entry}\n                            hasTableInAppSchema={hasTableInAppSchema}\n                            hasTableInCurrentSchema={hasTableInCurrentSchema}\n                            updateAppSchema={updateAppSchema}\n                            updateTable={updateTable}\n                        />\n                    );\n                })}\n            </>\n        );\n    }, [\n        appSchema,\n        currentSchema,\n        tableIndexesSideBySide,\n        hasTableInAppSchema,\n        hasTableInCurrentSchema,\n        updateTable,\n        updateAppSchema,\n    ]);\n\n    const metaDiffs = useMemo<Record<string, boolean> | null>(() => {\n        if (!hasTableUpdate || !appSchema || !currentSchema) return null;\n        const d: Record<string, boolean> = {};\n        Object.keys(appSchema)\n            .filter(\n                (key) =>\n                    key !== \"columns\" &&\n                    currentSchema[key as keyof NamedTableSchema] !== appSchema[key as keyof NamedTableSchema]\n            )\n            .map((k) => (d[k] = true));\n        return d;\n    }, [hasTableUpdate, appSchema, currentSchema]);\n\n    //tooltips for meta data\n\n    const [appTitleTT, appTitleTTRef] = useTooltip(\n        <>\n            Change the table name\n            <br />\n            in the database to this\n        </>,\n        \"left\"\n    );\n    const [appNameTT, appNameTTRef] = useTooltip(\n        <>\n            Change the python name\n            <br />\n            in the database to this\n        </>,\n        \"left\"\n    );\n\n    const [appClientTT, appClientTTRef] = useTooltip(\n        <>\n            Change the client access\n            <br />\n            in the database to this\n        </>,\n        \"left\"\n    );\n    const [appServerTT, appServerTTRef] = useTooltip(\n        <>\n            Change the server access\n            <br />\n            in the database to this\n        </>,\n        \"left\"\n    );\n    const [appTableTT, appTableTTRef] = useTooltip(\n        diffs[0]?.type === \"CREATE_TABLES\" ? (\n            <>\n                Add <b>{appSchema?.title}</b> to the database\n            </>\n        ) : (\n            <>\n                Remove <b>{currentSchema?.title}</b> from the database\n            </>\n        ),\n        \"left\"\n    );\n    const [currentTitleTT, currentTitleTTRef] = useTooltip(\n        <>\n            Change the table name\n            <br />\n            in the app schema to this\n        </>,\n        \"right\"\n    );\n\n    const [currentNameTT, currentNameTTRef] = useTooltip(\n        <>\n            Change the python name\n            <br />\n            in the app schema to this\n        </>,\n        \"right\"\n    );\n\n    const [currentClientTT, currentClientTTRef] = useTooltip(\n        <>\n            Change the client access\n            <br />\n            in the app schema to this\n        </>,\n        \"right\"\n    );\n    const [currentServerTT, currentServerTTRef] = useTooltip(\n        <>\n            Change the server access\n            <br />\n            in the app schema to this\n        </>,\n        \"right\"\n    );\n    const [currentTableTT, currentTableTTRef] = useTooltip(\n        diffs[0]?.type === \"DELETE_TABLE\" ? (\n            <>\n                Add <b>{currentSchema?.title}</b> to the app schema\n            </>\n        ) : (\n            <>\n                Remove <b>{appSchema?.title}</b> from the app schema\n            </>\n        ),\n        \"right\"\n    );\n\n    return (\n        <>\n            <div\n                className={cx(\n                    \"group/table relative col-span-2 grid grid-cols-2\",\n                    classes.tableDiffs,\n                    hasNewTableInASchema && classes.highlightRow\n                )}>\n                {/*diffs && (\n                    <>\n                        <Button\n                            size=\"small\"\n                            className={cx(\n                                classes.buttons,\n                                \"invisible absolute -top-8 right-[50%] z-10 mx-4 group-hover/table:visible\"\n                            )}\n                            variants={[\"tertiary\"]}\n                            onClick={() => updateTable({ type: \"table\" })}>\n                            {hasTableInAppSchema\n                                ? \"Add this table to the database\"\n                                : hasTableInCurrentSchema\n                                    ? \"Delete the table from the database\"\n                                    : \"Update database to match this table\"}\n                        </Button>\n\n                        <Button\n                            size=\"small\"\n                            className={cx(\n                                classes.buttons,\n                                \"invisible absolute -top-8 right-0  z-10 mx-4 group-hover/table:visible\"\n                            )}\n                            variants={[\"primary\"]}\n                            onClick={() => updateAppSchema({ type: \"table\" })}>\n                            {hasTableInAppSchema\n                                ? \"Remove the table from the app schema\"\n                                : hasTableInCurrentSchema\n                                    ? \"Add this table to the app schema\"\n                                    : \"Update app schema to match this table\"}\n                        </Button>\n                    </>\n                ) */}\n                <div className={\"group/header relative col-span-2 grid grid-cols-2\"}>\n                    <div\n                        className={cx(\n                            \"relative flex items-center justify-between px-8\",\n                            classes.tableHeader,\n                            hasTableUpdate && classes.highlightRow,\n                            hasTableInAppSchema && classes.highlightDiff\n                        )}>\n                        {[\"CREATE_TABLES\", \"DELETE_TABLE\"].includes(diffs[0]?.type ?? \"\") && (\n                            <Button\n                                ref={appTableTTRef}\n                                size=\"tiny\"\n                                className={cx(classes.buttons, \"absolute -right-2 z-10 mx-4\")}\n                                variants={[\"tertiary\"]}\n                                onClick={() => updateTable({ type: \"table\" })}>\n                                <FontAwesomeIcon className={\"w-4 text-white\"} icon={faArrowRight} />\n                                {appTableTT}\n                            </Button>\n                        )}\n                        {appSchema?.title && (\n                            <>\n                                <div className={cx(\"flex\")}>\n                                    <div className={cx(\"my-1 flex grow items-center items-stretch rounded-md px-2\")}>\n                                        <div\n                                            className={cx(\n                                                \"grow rounded-l-md px-2 font-semibold\",\n                                                metaDiffs?.title && classes.highlightDiff\n                                            )}>\n                                            {appSchema?.title}\n                                        </div>\n                                        <div\n                                            ref={appTitleTTRef}\n                                            className={cx(\n                                                \"flex cursor-pointer items-center px-2\",\n                                                \"rounded-r-md border-transparent\",\n                                                metaDiffs?.title && \"bg-tertiary\"\n                                            )}\n                                            onClick={() => updateTable({ type: \"updateTable\", data: \"title\" })}>\n                                            {metaDiffs?.title && (\n                                                <>\n                                                    <FontAwesomeIcon className={\"w-4 text-white\"} icon={faArrowRight} />\n                                                    {appTitleTT}\n                                                </>\n                                            )}\n                                        </div>\n                                    </div>\n\n                                    <div className={cx(\"my-1 flex grow items-center rounded-md px-2\")}>\n                                        <div\n                                            className={cx(\n                                                \"grow rounded-l-md px-2 font-mono\",\n                                                metaDiffs?.name && classes.highlightDiff\n                                            )}>\n                                            ({appSchema?.name})\n                                        </div>\n                                        <div\n                                            ref={appNameTTRef}\n                                            className={cx(\n                                                \"cursor-pointer px-2\",\n                                                \"rounded-r-md border-transparent\",\n                                                metaDiffs?.name && \"bg-tertiary\"\n                                            )}\n                                            onClick={() => updateTable({ type: \"updateTable\", data: \"name\" })}>\n                                            {metaDiffs?.name && (\n                                                <>\n                                                    <FontAwesomeIcon className={\"w-4 text-white\"} icon={faArrowRight} />\n                                                    {appNameTT}\n                                                </>\n                                            )}\n                                        </div>\n                                    </div>\n                                </div>\n                                <div>\n                                    <div className={cx(\"my-1 flex grow items-center items-stretch rounded-md px-2\")}>\n                                        <div\n                                            className={cx(\n                                                \"grow rounded-l-md px-2\",\n                                                metaDiffs?.client && classes.highlightDiff\n                                            )}>\n                                            Client: {tableAccessTitle[appSchema?.client]}\n                                        </div>\n                                        <div\n                                            ref={appClientTTRef}\n                                            className={cx(\n                                                \"flex cursor-pointer items-center px-2\",\n                                                \"rounded-r-md border-transparent\",\n                                                metaDiffs?.client && \"bg-tertiary\"\n                                            )}\n                                            onClick={() => updateTable({ type: \"updateTable\", data: \"client\" })}>\n                                            {metaDiffs?.client && (\n                                                <>\n                                                    <FontAwesomeIcon className={\"w-4 text-white\"} icon={faArrowRight} />\n                                                    {appClientTT}\n                                                </>\n                                            )}\n                                        </div>\n                                    </div>\n                                    <div className={cx(\"my-1 flex items-center items-stretch rounded-md px-2\")}>\n                                        <div\n                                            className={cx(\n                                                \"grow rounded-l-md px-2\",\n                                                metaDiffs?.server && classes.highlightDiff\n                                            )}>\n                                            Server: {tableAccessTitle[appSchema?.server]}\n                                        </div>\n                                        <div\n                                            ref={appServerTTRef}\n                                            className={cx(\n                                                \"flex cursor-pointer items-center px-2\",\n                                                \"rounded-r-md border-transparent\",\n                                                metaDiffs?.server && \"bg-tertiary\"\n                                            )}\n                                            onClick={() => updateTable({ type: \"updateTable\", data: \"server\" })}>\n                                            {metaDiffs?.server && (\n                                                <>\n                                                    <FontAwesomeIcon className={\"w-4 text-white\"} icon={faArrowRight} />\n                                                    {appServerTT}\n                                                </>\n                                            )}\n                                        </div>\n                                    </div>\n                                </div>\n                            </>\n                        )}\n                    </div>\n                    <div\n                        className={cx(\n                            \"relative flex items-center justify-between border-r border-sectionborder px-8 dark:border-dark-sectionborder\",\n                            classes.tableHeader,\n                            hasTableUpdate && classes.highlightRow,\n                            hasTableInCurrentSchema && classes.highlightDiff\n                        )}>\n                        {[\"CREATE_TABLES\", \"DELETE_TABLE\"].includes(diffs[0]?.type ?? \"\") && (\n                            <Button\n                                ref={currentTableTTRef}\n                                size=\"tiny\"\n                                className={cx(classes.buttons, \"absolute -left-2 z-10 mx-4\")}\n                                variants={[\"primary\"]}\n                                onClick={() => updateAppSchema({ type: \"table\" })}>\n                                <FontAwesomeIcon className={\"w-4 text-white\"} icon={faArrowLeft} />\n                                {currentTableTT}\n                            </Button>\n                        )}\n\n                        {currentSchema?.title && (\n                            <>\n                                <div className={cx(\"-ml-6 flex\")}>\n                                    <div className={cx(\"my-1 flex grow items-center items-stretch rounded-md pr-2\")}>\n                                        <div\n                                            ref={currentTitleTTRef}\n                                            className={cx(\"px-2\", \"flex items-center rounded-l-md border-transparent\", {\n                                                \"cursor-pointer bg-primary\": metaDiffs?.title,\n                                            })}\n                                            onClick={() => {\n                                                if (metaDiffs?.title) {\n                                                    updateAppSchema({\n                                                        type: \"updateTable\",\n                                                        data: \"title\",\n                                                    });\n                                                }\n                                            }}>\n                                            <FontAwesomeIcon\n                                                className={cx(\"invisible w-4 text-white\", {\n                                                    visible: metaDiffs?.title,\n                                                })}\n                                                icon={faArrowLeft}\n                                            />\n                                            {metaDiffs?.title && currentTitleTT}\n                                        </div>\n                                        <div\n                                            className={cx(\n                                                \"grow rounded-r-md px-2 text-right font-semibold\",\n                                                metaDiffs?.title && classes.highlightDiff\n                                            )}>\n                                            {currentSchema?.title}\n                                        </div>\n                                    </div>\n\n                                    <div className={cx(\"my-1 flex grow items-center rounded-md px-2\")}>\n                                        <div\n                                            ref={currentNameTTRef}\n                                            className={cx(\"px-2\", \"rounded-l-md border-transparent\", {\n                                                \"cursor-pointer bg-primary\": metaDiffs?.name,\n                                            })}\n                                            onClick={() => {\n                                                if (metaDiffs?.name) {\n                                                    updateAppSchema({\n                                                        type: \"updateTable\",\n                                                        data: \"name\",\n                                                    });\n                                                }\n                                            }}>\n                                            <FontAwesomeIcon\n                                                className={cx(\"invisible w-4 text-white\", { visible: metaDiffs?.name })}\n                                                icon={faArrowLeft}\n                                            />\n                                            {metaDiffs?.name && currentNameTT}\n                                        </div>\n                                        <div\n                                            className={cx(\n                                                \"grow rounded-r-md px-2 text-right font-mono\",\n                                                metaDiffs?.name && classes.highlightDiff\n                                            )}>\n                                            ({currentSchema?.name})\n                                        </div>\n                                    </div>\n                                </div>\n                                <div>\n                                    <div className={cx(\"my-1 flex grow items-center items-stretch rounded-md px-2\")}>\n                                        <div\n                                            ref={currentClientTTRef}\n                                            className={cx(\"px-2\", \"flex items-center rounded-l-md border-transparent\", {\n                                                \"cursor-pointer bg-primary\": metaDiffs?.client,\n                                            })}\n                                            onClick={() => {\n                                                if (metaDiffs?.client) {\n                                                    updateAppSchema({\n                                                        type: \"updateTable\",\n                                                        data: \"client\",\n                                                    });\n                                                }\n                                            }}>\n                                            <FontAwesomeIcon\n                                                className={cx(\"invisible w-4 text-white\", {\n                                                    visible: metaDiffs?.client,\n                                                })}\n                                                icon={faArrowLeft}\n                                            />\n                                            {metaDiffs?.client && currentClientTT}\n                                        </div>\n                                        <div\n                                            className={cx(\n                                                \"grow rounded-r-md px-2 text-right\",\n                                                metaDiffs?.client && classes.highlightDiff\n                                            )}>\n                                            Client: {tableAccessTitle[currentSchema?.client]}\n                                        </div>\n                                    </div>\n\n                                    <div className={cx(\"my-1 flex grow items-center items-stretch rounded-md px-2\")}>\n                                        <div\n                                            ref={currentServerTTRef}\n                                            className={cx(\"px-2\", \"flex items-center rounded-l-md border-transparent\", {\n                                                \"cursor-pointer bg-primary\": metaDiffs?.server,\n                                            })}\n                                            onClick={() => {\n                                                if (metaDiffs?.server) {\n                                                    updateAppSchema({\n                                                        type: \"updateTable\",\n                                                        data: \"server\",\n                                                    });\n                                                }\n                                            }}>\n                                            <FontAwesomeIcon\n                                                className={cx(\"invisible w-4 text-white\", {\n                                                    visible: metaDiffs?.server,\n                                                })}\n                                                icon={faArrowLeft}\n                                            />\n                                            {metaDiffs?.server && currentServerTT}\n                                        </div>\n                                        <div\n                                            className={cx(\n                                                \"grow rounded-r-md px-2 text-right\",\n                                                metaDiffs?.server && classes.highlightDiff\n                                            )}>\n                                            Server: {tableAccessTitle[currentSchema?.server]}\n                                        </div>\n                                    </div>\n                                </div>\n                            </>\n                        )}\n                    </div>\n                </div>\n                {tableColumns}\n                {tableIndexes}\n            </div>\n        </>\n    );\n};\n\ntype SchemaTabProps = AnvilConnectedProps<typeof connector> & {\n    tab: AppSchemaTab;\n};\n\nconst SchemaTab = ({ tab, tableMappings, appSchema, dispatch }: SchemaTabProps) => {\n    const { classes } = useStyles();\n\n    const user = useSelector(getUser);\n    const debugTableMappingId = useSelector(getDebugEnvironmentTableMappingId);\n\n    const tableMapping = useMemo(() => {\n        const tableMappingId =\n            tab.navTarget.tableMappingId === \"debug\" ? debugTableMappingId : tab.navTarget.tableMappingId;\n\n        if (tableMappingId === undefined) {\n            return null;\n        }\n        return tableMappings?.find(({ table_mapping_id }) => table_mapping_id === tableMappingId) ?? null;\n    }, [debugTableMappingId, tab.navTarget.tableMappingId, tableMappings]);\n\n    const tableMappingName = getTableMappingDisplayName(tableMapping);\n    useUpdateTabTitle(tab, tableMapping ? `Database Schema - ${tableMappingName}` : `App Schema`);\n\n    const diffs = useMemoAsync<Diff[] | null>(\n        null,\n        async () => (tableMapping ? await dispatch(getRequiredSchemaDiffs(tableMapping)) : null),\n        [appSchema, tableMapping]\n    );\n\n    const mappingSchema = useMemo(() => tableMapping?.schema, [tableMapping]);\n    const diffsOfTables = useMemo(() => {\n        const organizedDiffs: Record<string, OrganisedTableDiff[]> = {};\n        diffs?.forEach((d) => {\n            if (d.type === \"CREATE_TABLES\") {\n                Object.keys(d.tables).forEach((tableName) => {\n                    organizedDiffs[tableName] = [{ ...d.tables[tableName], type: d.type }];\n                });\n            } else {\n                if (organizedDiffs[d.table]) {\n                    organizedDiffs[d.table] = [...organizedDiffs[d.table], d];\n                } else {\n                    organizedDiffs[d.table] = [d];\n                }\n            }\n        });\n        return organizedDiffs;\n    }, [diffs]);\n\n    const sideBySide = useMemo(() => {\n        const createTables = Object.keys(\n            diffs?.find((diff): diff is Extract<Diff, { type: \"CREATE_TABLES\" }> => diff.type === \"CREATE_TABLES\")\n                ?.tables ?? {}\n        );\n        const deleteTables =\n            diffs\n                ?.filter((diff): diff is Extract<Diff, { type: \"DELETE_TABLE\" }> => diff.type === \"DELETE_TABLE\")\n                .map((diff) => diff.table) ?? [];\n\n        const exclusive = [...createTables, ...deleteTables];\n\n        const toRemoveFromList = diffs\n            ?.filter(\n                (diff): diff is Extract<Diff, { type: \"UPDATE_TABLE\" }> =>\n                    diff.type === \"UPDATE_TABLE\" && !!diff.new_python_name\n            )\n            .map((diff) => diff.new_python_name);\n\n        const inclusive =\n            diffs\n                ?.filter(\n                    (\n                        diff\n                    ): diff is Exclude<Diff, Extract<Diff, { type: \"CREATE_TABLES\" } | { type: \"DELETE_TABLE\" }>> =>\n                        [\"UPDATE_TABLE\", \"ADD_COLUMN\", \"DELETE_COLUMN\", \"RENAME_COLUMN\"].includes(diff.type)\n                )\n                .map((diff) => diff.table) ?? [];\n        const appSchemaTableNames = Object.keys(appSchema ?? {});\n        const currentSchemaTableNames = Object.keys(mappingSchema ?? {});\n        const allTableNames = [...new Set([...appSchemaTableNames, ...currentSchemaTableNames])]?.sort();\n\n        toRemoveFromList?.forEach((table) => {\n            if (!table) return;\n            const ind = allTableNames.indexOf(table);\n            if (ind !== -1) {\n                allTableNames.splice(ind, 1);\n            }\n        });\n\n        const twoSchemas: SideBySideTable[] = [];\n        const changedTables: SideBySideTable[] = [];\n        const deletedTables: SideBySideTable[] = [];\n        const createdTables: SideBySideTable[] = [];\n\n        allTableNames.forEach((tableName) => {\n            if (exclusive?.includes(tableName)) {\n                if (appSchema?.[tableName]) {\n                    createdTables.push({\n                        name: tableName,\n                        diffs: diffsOfTables?.[tableName],\n                        schemas: {\n                            appSchema: getNamedTableSchema(appSchema, tableName),\n                            currentSchema: getNamedTableSchema(mappingSchema, tableName),\n                        },\n                    });\n                } else {\n                    deletedTables.push({\n                        name: tableName,\n                        diffs: diffsOfTables?.[tableName],\n                        schemas: {\n                            appSchema: getNamedTableSchema(appSchema, tableName),\n                            currentSchema: getNamedTableSchema(mappingSchema, tableName),\n                        },\n                    });\n                }\n            } else if (inclusive?.includes(tableName)) {\n                const newPythonName = diffsOfTables[tableName]?.find(\n                    (diff): diff is Extract<Diff, { type: \"UPDATE_TABLE\" }> =>\n                        diff.type === \"UPDATE_TABLE\" && !!diff.new_python_name\n                )?.new_python_name;\n                const appTableName = newPythonName ? newPythonName : tableName;\n                changedTables.push({\n                    name: tableName,\n                    diffs: diffsOfTables?.[tableName],\n                    schemas: {\n                        appSchema: getNamedTableSchema(appSchema, appTableName),\n                        currentSchema: getNamedTableSchema(mappingSchema, tableName),\n                    },\n                });\n            } else {\n                twoSchemas.push({\n                    name: tableName,\n                    schemas: {\n                        appSchema: getNamedTableSchema(appSchema, tableName),\n                        currentSchema: getNamedTableSchema(mappingSchema, tableName),\n                    },\n                });\n            }\n        });\n\n        return [...twoSchemas, ...changedTables, ...createdTables, ...deletedTables];\n    }, [appSchema, mappingSchema, diffs, diffsOfTables]);\n\n    // const diffsByTable = useMemo(() => {\n    //     const organizedDiffs = {\n    //         tableChanges: { createDelete: [], update: [] },\n    //         colChanges: {},\n    //     };\n    //     diffs?.forEach((entry) => {\n    //         switch (entry.type) {\n    //             case \"CREATE_TABLES\":\n    //                 organizedDiffs.tableChanges.createDelete = [\n    //                     ...organizedDiffs.tableChanges.createDelete,\n    //                     ...Object.keys(entry.tables),\n    //                 ];\n    //                 break;\n    //             case \"DELETE_TABLE\":\n    //                 organizedDiffs.tableChanges.createDelete = [\n    //                     ...organizedDiffs.tableChanges.createDelete,\n    //                     entry.table,\n    //                 ];\n    //                 break;\n    //             case \"UPDATE_TABLE\":\n    //                 organizedDiffs.tableChanges.update = [...organizedDiffs.tableChanges.update, entry.new_python_name];\n    //                 break;\n    //             case \"ADD_COLUMN\":\n    //             case \"DELETE_COLUMN\":\n    //             case \"RENAME_COLUMN\":\n    //                 organizedDiffs.colChanges[entry.table] = organizedDiffs.colChanges[entry.table] || [];\n    //                 organizedDiffs.colChanges[entry.table].push(entry);\n    //                 break;\n    //         }\n    //     });\n    //     return organizedDiffs;\n    // }, [diffs]);\n\n    const schemaDiffs = useMemo(() => {\n        if (!tableMapping) return null;\n        return (\n            <div className={cx(\"col-span-2 grid grid-cols-2\")}>\n                {sideBySide.map((table) => (\n                    <TableDiffs\n                        key={table.name}\n                        name={table.name}\n                        schemas={table.schemas}\n                        diffs={diffsOfTables[table.name]}\n                        tableMapping={tableMapping}\n                    />\n                ))}\n            </div>\n        );\n    }, [sideBySide, diffsOfTables, tableMapping]);\n\n    const updateApp = useEvent(async () => {\n        if (!mappingSchema) return;\n        dispatch(updateAppDBSchema(mappingSchema));\n        await dispatch(updateAppSchemaSync());\n    });\n\n    return (\n        <div className={classes.root}>\n            {mappingSchema && tableMapping ? (\n                <>\n                    {tableMapping.diff?.length === 0 ? (\n                        <div className={\"flex h-full w-full items-center justify-evenly\"}>\n                            <div className=\"mt-20 ml-20 w-1/2\">\n                                <h2 className={\"mt-9 mb-4 text-5xl font-medium\"}>Source Code</h2>\n                                <Text level={1}>\n                                    The source code of your app expects a database with the following schema:\n                                </Text>\n                                <Schema schema={appSchema} />\n                            </div>\n                            <div className=\"w-1/2\">\n                                <div className={\"px-2 text-center\"}>\n                                    <div className={cx(\"m-10\")}>\n                                        <FontAwesomeIcon className={classes.check} icon={faCheck} size={\"6x\"} />\n                                    </div>\n                                    The '<b>{tableMappingName}</b>' database schema matches the source code of your\n                                    app.\n                                </div>\n                            </div>\n                        </div>\n                    ) : (\n                        <div className={\"grid w-full max-w-max grid-cols-2 gap-x-20 p-10\"}>\n                            <div className={classes.mismatchAlert}>\n                                <div className={\"px-2 text-center\"}>\n                                    {/*todo: secondary orange*/}\n                                    <FontAwesomeIcon\n                                        icon={faExclamationTriangle}\n                                        size={\"6x\"}\n                                        className={classes.exclamation}\n                                    />\n                                </div>\n                                <div className={\"mr-12\"}>\n                                    The '<strong>{tableMappingName}</strong>' database schema does not match your app\n                                </div>\n                            </div>\n\n                            <div className={cx(\"col-span-1\")}>\n                                <h2 className={\"mt-9 mb-4 text-center text-5xl font-medium\"}>Source Code Schema</h2>\n                            </div>\n\n                            <div className={cx(\"col-span-1\")}>\n                                <h2 className={\"mt-9 mb-4 text-center text-5xl font-medium\"}>\n                                    '{tableMappingName}' Schema\n                                </h2>\n                            </div>\n                            {\n                                <>\n                                    <div className=\"col-span-1 mx-auto text-center\">\n                                        <Button\n                                            className={cx(classes.actionButton)}\n                                            variant={\"tertiary\"}\n                                            onClick={() => dispatch(maybeMigrateAppOrDB(tableMapping))}>\n                                            <div className={\"flex flex-col p-4\"}>\n                                                <div className={\"px-auto text-center text-4xl\"}>\n                                                    The schema of the source code is correct\n                                                </div>\n                                                <div className={\"px-auto pt-4 text-center text-xl font-normal\"}>\n                                                    View changes that will be made when you migrate '{tableMappingName}\n                                                    '\n                                                </div>\n                                            </div>\n                                        </Button>\n                                    </div>\n                                    <div className=\"col-span-1 mx-auto text-center\">\n                                        <Button\n                                            className={classes.actionButton}\n                                            variant={\"primary\"}\n                                            onClick={updateApp}>\n                                            <div className={\"flex flex-col p-4\"}>\n                                                <div className={\"px-auto text-center text-4xl\"}>\n                                                    The schema of '{tableMappingName}' is correct\n                                                </div>\n                                                <div className={\"px-auto pt-4 text-center text-xl font-normal\"}>\n                                                    Update the app's source code to match '{tableMappingName}'\n                                                </div>\n                                            </div>\n                                        </Button>\n                                    </div>\n\n                                    <Text className=\"col-span-1 pl-10 text-center\" level={1}>\n                                        The source code of your app expects a database with the following schema:\n                                    </Text>\n                                    <Text className=\"col-span-1 text-center\" level={1}>\n                                        The <b>'{tableMappingName}'</b> database has the following schema:\n                                    </Text>\n                                </>\n                            }\n                            {schemaDiffs}\n                        </div>\n                    )}\n                </>\n            ) : (\n                <>\n                    {/*<div className={\"w-full flex justify-evenly h-full items-center\"}>*/}\n                    <div className=\"mt-20\">\n                        <h2 className={\"mt-9 mb-4 text-5xl font-medium\"}>Source Code</h2>\n                        <Text level={1}>The source code of your app expects a database with the following schema:</Text>\n                        <Schema schema={appSchema} />\n                    </div>\n                    <div></div>\n                    {/*</div>*/}\n                </>\n            )}\n        </div>\n    );\n};\n\nexport default connector(SchemaTab);\n","import type { AnvilAsyncAction } from \"@/types\";\nimport * as api from \"../api\";\nimport { markAppPathUnsaved } from \"./app\";\nimport { getStripeService } from \"./services\";\n\nexport type StripeAccount = {\n    error?: unknown;\n    business_profile?: {\n        name?: string;\n        support_email?: string;\n    };\n    email?: string;\n};\n\nexport const getStripeAccount = async (accessToken: string, stripeUserId: string): Promise<StripeAccount> =>\n    await (\n        await fetch(`https://api.stripe.com/v1/accounts/${stripeUserId}`, {\n            method: \"GET\",\n            headers: {\n                \"Content-Type\": \"application/x-www-form-urlencoded\",\n                Authorization: `Bearer ${accessToken}`,\n            },\n        })\n    ).json();\n\nexport const fetchStripeAccount = async (accessToken: string, stripeUserId: string): Promise<StripeAccount> => {\n    const account = await getStripeAccount(accessToken, stripeUserId);\n    if (account.error) {\n        console.error(\"Error\", account.error);\n        throw new Error(\"account_details_failed\");\n    }\n\n    return account;\n};\n\nexport const loadStripeAccount = async (refreshToken: string, stripeUserId: string): Promise<StripeAccount> => {\n    const access = await api.getStripeAccessToken(refreshToken);\n    if (!access.accessToken) {\n        console.error(\"Unable to get Stripe access token\", access.error ?? access.message);\n        throw new Error(\"refresh_failed\");\n    }\n\n    return fetchStripeAccount(access.accessToken, stripeUserId);\n};\n\nexport const removeConnection = (): AnvilAsyncAction<void> => async (dispatch, getState, updateState) => {\n    const stripeUserId = getStripeService(getState())?.server_config?.stripe_user_id;\n    await api.disconnectStripe(stripeUserId);\n    updateState((state) => {\n        const service = getStripeService(state);\n        delete service?.server_config?.refresh_token;\n        delete service?.server_config?.stripe_user_id;\n    });\n    dispatch(markAppPathUnsaved([\"SETTINGS\", \"services\"]));\n};\n","import * as React from \"react\";\nimport { useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faStripe } from \"@fortawesome/free-brands-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { reloadAppConfig } from \"@/controllers/app/autocompleter\";\nimport { getStripeService, updateService } from \"@/controllers/services\";\nimport { fetchStripeAccount, loadStripeAccount, removeConnection } from \"@/controllers/stripeservice\";\nimport { useUpdateTabTitle } from \"@/controllers/tabs\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport type { ServiceTab } from \"@/types/tabs\";\nimport { sleep } from \"@/util\";\nimport * as api from \"@/api\";\nimport { queryClient } from \"@/util/queryClient\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { Button } from \"../reusable/Button\";\nimport { HelpLink } from \"../reusable/HelpLink\";\nimport Link from \"../reusable/Link\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { LoadingSpinner } from \"../reusable/LoadingSpinner\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport TextInput from \"../reusable/TextInput\";\nimport { useTooltip } from \"../reusable/Tooltip\";\nimport TabToolbar from \"./TabToolbar\";\n\nlet useStyles = makeStyles()((theme) => ({\n    promptLabel: {\n        textAlign: \"right\",\n        margin: 0,\n    },\n    container: {\n        height: \"calc(100% - 5rem)\",\n        background: theme.stripeService.background.toString(),\n        display: \"flex\",\n        flexDirection: \"column\",\n        overflowY: \"scroll\",\n    },\n    panel: {\n        padding: \"0 4rem\",\n        width: \"90rem\",\n        borderRight: \"1px solid \" + theme.stripeService.border.toString(),\n        background: theme.stripeService.panelBackground.toString(),\n    },\n    accountLink: {\n        padding: \"0 3px\",\n        color: theme.palette.primary.toString() + \"!important\",\n        borderBottom: \"3px solid \" + theme.palette.primary.toString(),\n    },\n    alertBanner: {\n        width: \"auto\",\n        margin: \"1rem\",\n        border: \"1px solid \" + theme.stripeService.alert.borderColor.toString(),\n        background: theme.stripeService.alert.backgroundColor.toString(),\n        padding: \"2rem\",\n        borderRadius: \"2px\",\n        textAlign: \"center\",\n    },\n    error: {\n        width: \"auto\",\n        margin: \"1rem\",\n        border: \"1px solid\" + theme.stripeService.alert.borderColor.toString(),\n        background: theme.stripeService.error.backgroundColor.toString(),\n        color: theme.stripeService.error.color.toString(),\n        padding: \"2rem\",\n        borderRadius: \"2px\",\n        textAlign: \"center\",\n    },\n    buttonContainer: {\n        display: \"flex\",\n        paddingLeft: \"3rem\",\n        paddingRight: \"3rem\",\n    },\n    button: {\n        width: \"50%\",\n        margin: \"0 1rem\",\n        height: \"inherit\",\n        padding: \"1rem 0\",\n        \"& > span\": {\n            flexShrink: 1,\n        },\n    },\n}));\n\nconst connector = connect((state: State) => ({\n    stripeService: getStripeService(state),\n}));\n\ntype StripeServiceTabProps = AnvilConnectedProps<typeof connector> & {\n    tab: ServiceTab;\n};\n\nconst StripeServiceTab = ({ tab, stripeService, dispatch }: StripeServiceTabProps) => {\n    useUpdateTabTitle(tab, \"Stripe API\");\n    const { classes } = useStyles();\n\n    const refreshToken = stripeService?.server_config?.refresh_token;\n    const stripeUserId = stripeService?.server_config?.stripe_user_id;\n    const [localStripeError, setLocalStripeError] = useState<string | null>(null);\n    const [tooltip, tooltipAnchor] = useTooltip(\"Go to Stripe Dashboard\", \"right\");\n\n    const stripeAccountQuery = useQuery({\n        queryKey: [\"stripe-account\", refreshToken, stripeUserId] as const,\n        enabled: !!refreshToken && !!stripeUserId,\n        retry: false,\n        queryFn: async ({ queryKey }) => {\n            const [, refreshToken, stripeUserId] = queryKey;\n            if (!refreshToken || !stripeUserId) {\n                throw new Error(\"missing_stripe_connection\");\n            }\n            return loadStripeAccount(refreshToken, stripeUserId);\n        },\n    });\n\n    const stripeAccount = stripeAccountQuery.data ?? null;\n    const refreshFailed = stripeAccountQuery.isError && stripeAccountQuery.error.message === \"refresh_failed\";\n    const stripeError =\n        localStripeError ??\n        (stripeAccountQuery.isError && stripeAccountQuery.error.message !== \"refresh_failed\"\n            ? \"Error getting Stripe account details. Please contact support@anvil.works.\"\n            : null);\n\n    const clearConnection = useEvent(async () => {\n        try {\n            await dispatch(removeConnection());\n            setLocalStripeError(null);\n        } catch (e) {\n            console.error(\"Deauthorize failed:\", e);\n        }\n    });\n\n    const connectAccount = useEvent(async (register: boolean) => {\n        const authUrl = `${api.stripeOAuthURL}?landing=${register ? \"register\" : \"login\"}`;\n\n        const windowFeatures = {\n            width: 420,\n            height: 500,\n            scrollbars: \"yes\",\n        };\n\n        let strWindowFeatures = \"\";\n        for (const k in windowFeatures) {\n            if (strWindowFeatures.length > 0) strWindowFeatures += \",\";\n\n            strWindowFeatures += k;\n\n            const v = windowFeatures[k as keyof typeof windowFeatures];\n\n            strWindowFeatures += \"=\" + v;\n        }\n\n        const popup = window.open(authUrl, undefined, strWindowFeatures) as\n            | (Window & {\n                  authCompleted?: boolean;\n                  errorMessage?: string;\n              })\n            | null;\n        if (!popup) {\n            setLocalStripeError(\"Could not open Stripe auth window.\");\n            return;\n        }\n\n        // For some reason, window.opener is null after a Stripe OAuth flow.\n        // Instead, we have to wait for a flag to say we're done.\n        while (true) {\n            await sleep(1000);\n            if (popup.closed) {\n                if (popup.authCompleted) {\n                    //todo: should probably move this to a controller\n                    const tokens = await api.getStripeAuthTokens();\n                    const account = await fetchStripeAccount(tokens.accessToken, tokens.stripeUserId);\n                    queryClient.setQueryData([\"stripe-account\", tokens.refreshToken, tokens.stripeUserId], account);\n                    await dispatch(updateService(\"stripe\", [\"server_config\", \"refresh_token\"], tokens.refreshToken));\n                    await dispatch(updateService(\"stripe\", [\"server_config\", \"stripe_user_id\"], tokens.stripeUserId));\n                    dispatch(reloadAppConfig()); //not sure if i really even need to do this at all.\n                    setLocalStripeError(null);\n                    return;\n                } else {\n                    console.error(\"Stripe OAuth Error: \", popup.errorMessage);\n                    setLocalStripeError(\"Error connecting to your Stripe account.\");\n                    return;\n                }\n            }\n        }\n    });\n\n    const liveMode = stripeService?.client_config?.live_mode || false;\n    const [liveKey, setLiveKey] = useState(stripeService?.client_config?.publishable_key?.live || \"\");\n    const [testKey, setTestKey] = useState(stripeService?.client_config?.publishable_key?.test || \"\");\n\n    const updateKeys = useEvent(async (mode: \"test\" | \"live\", newValue: string) => {\n        await dispatch(updateService(\"stripe\", [\"client_config\", \"publishable_key\", mode], newValue));\n    });\n\n    const toggleMode = useEvent(async () => {\n        await dispatch(updateService(\"stripe\", [\"client_config\", \"live_mode\"], !liveMode));\n    });\n\n    return (\n        <div className={cx(\"flex h-full flex-col\")}>\n            <TabToolbar>\n                <Text className={\"p-unset\"} level={1}>\n                    Accept payments online with Stripe.&nbsp;\n                    <HelpLink iconRight inline url={\"/docs/integrations/stripe\"}>\n                        Learn More\n                    </HelpLink>\n                </Text>\n            </TabToolbar>\n            <div className={classes.container}>\n                <div className={cx(\"shrink-0 grow\", classes.panel)}>\n                    <div className={\"text-9xl\"}>\n                        <Link target={\"_blank\"} to={\"https://stripe.com/\"}>\n                            <FontAwesomeIcon icon={faStripe} />\n                        </Link>\n                    </div>\n                    {stripeError && <div className={classes.error}>{stripeError}</div>}\n\n                    {refreshToken ? (\n                        <>\n                            {stripeAccountQuery.isLoading && (\n                                <div className=\"flex justify-center py-24\">\n                                    <LoadingSpinner inline />\n                                </div>\n                            )}\n                            {refreshFailed && (\n                                <div className={classes.error}>\n                                    A previously connected Stripe account is no longer available. Please connect a new\n                                    account.\n                                </div>\n                            )}\n                            {stripeAccount && (\n                                <>\n                                    <Heading level={2}>\n                                        Your app is connected to the{\" \"}\n                                        <Link\n                                            ref={tooltipAnchor}\n                                            className={classes.accountLink}\n                                            target={\"_blank\"}\n                                            to={\"https://dashboard.stripe.com\"}>\n                                            {stripeAccount?.business_profile?.name} Stripe account{\" \"}\n                                            {(stripeAccount?.business_profile?.support_email || stripeAccount?.email) &&\n                                                `(${stripeAccount?.business_profile?.support_email || stripeAccount?.email})`}\n                                        </Link>\n                                    </Heading>\n                                    {tooltip}\n                                    {!liveMode && (\n                                        <div className={classes.alertBanner}>\n                                            The Stripe service is currently in <b>Test</b> mode.\n                                            <br />\n                                            <LinkInternal onClick={toggleMode}>\n                                                Switch to <b>Live</b> mode\n                                            </LinkInternal>{\" \"}\n                                            to accept real payments{\" \"}\n                                            <HelpLink inline url={\"https://stripe.com/docs/testing\"} />\n                                        </div>\n                                    )}\n\n                                    <div className={classes.buttonContainer}>\n                                        <Button className={classes.button} onClick={clearConnection}>\n                                            Disconnect from Stripe\n                                        </Button>\n                                        <Button className={classes.button} variant={\"primary\"} onClick={toggleMode}>\n                                            Switch to {liveMode ? \"TEST\" : \"LIVE\"} mode\n                                        </Button>\n                                    </div>\n\n                                    <Heading level={2}>\n                                        Raw Stripe API keys (Advanced){\" \"}\n                                        <HelpLink inline url={\"/docs/integrations/stripe/raw-api-tokens\"} />\n                                    </Heading>\n                                    <div className={\"mx-10\"}>\n                                        <TextInput\n                                            title={\"Test Publishable Key\"}\n                                            id=\"testKey\"\n                                            placeholder={\"Test-mode publishable key\"}\n                                            initialValue={testKey}\n                                            onChange={setTestKey}\n                                            onSave={(v) => updateKeys(\"test\", v)}\n                                        />\n                                        <TextInput\n                                            title={\"Live Publishable Key\"}\n                                            id=\"liveKey\"\n                                            placeholder={\"Live-mode publishable key\"}\n                                            initialValue={liveKey}\n                                            onChange={setLiveKey}\n                                            onSave={(v) => updateKeys(\"live\", v)}\n                                        />\n                                    </div>\n                                    <Heading level={2}>Examples</Heading>\n                                    <pre className={\"select-all\"}>\n                                        {`import stripe.checkout\n\n# Take a payment of £9.99\nstripe.checkout.charge(amount=999,\n                       currency=\"GBP\",\n                       title=\"Acme Online Store\",\n                       description=\"3 Widgets\")`}\n                                    </pre>\n                                </>\n                            )}\n                        </>\n                    ) : (\n                        <>\n                            <div className={classes.buttonContainer}>\n                                <Button\n                                    className={classes.button}\n                                    variant={\"primary\"}\n                                    onClick={() => connectAccount(false)}>\n                                    <div className={\"flex flex-col p-4\"}>\n                                        <div className={\"px-auto text-center text-4xl\"}>Connect your account</div>\n                                        <div className={\"px-auto py-1 text-center text-xl font-normal\"}>\n                                            Connect an existing Stripe account to your Anvil app{\" \"}\n                                        </div>\n                                    </div>\n                                </Button>\n                                <Button className={classes.button} onClick={() => connectAccount(true)}>\n                                    <div className={\"flex flex-col p-4\"}>\n                                        <div className={\"px-auto text-center text-4xl\"}>Connect a new account</div>\n                                        <div className={\"px-auto py-1 text-center text-xl font-normal\"}>\n                                            Create a new Stripe account to connect to your app\n                                        </div>\n                                    </div>\n                                </Button>\n                            </div>\n                        </>\n                    )}\n                    <hr />\n                    <Text level={3}>\n                        Stripe apply a transaction fee to payments you receive through Stripe -{\" \"}\n                        <Link target={\"_blank\"} to={\"https://stripe.com/pricing\"}>\n                            see their pricing page\n                        </Link>{\" \"}\n                        for more information.\n                    </Text>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport default connector(StripeServiceTab);\n","import React, { MutableRefObject, createContext, useMemo, useRef } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { ErrorSuspenseBoundary } from \"@/components/reusable/ErrorBoundary\";\nimport { getInvalidYaml } from \"@/controllers/app\";\nimport { getCurrentTabId, getTabs } from \"@/controllers/tabs\";\nimport { cx } from \"@/theme/styles\";\nimport { Tab } from \"@/types\";\nimport { useTabPanelRef } from \"@/util/TabPanelRefContext\";\nimport { LoadingSpinner } from \"../reusable/LoadingSpinner\";\nimport TabBar from \"./TabBar\";\nimport TabContent from \"./TabContent\";\n\ninterface TabProps {\n    tab: Tab | null;\n    selected: boolean;\n}\n\nexport const WrappedTabContext = createContext<MutableRefObject<HTMLDivElement | null>>({ current: null });\n\nexport const WrappedTabContent = ({ tab, selected }: TabProps) => {\n    const wrappedTabContentRef = useRef<HTMLDivElement>(null);\n\n    return (\n        <div\n            data-anvil-tab-id={tab?.id}\n            className={cx(\"offset-vscrollbar absolute h-full w-full\", {\n                \"pointer-events-none invisible\": !selected,\n            })}\n            ref={wrappedTabContentRef}>\n            <WrappedTabContext.Provider value={wrappedTabContentRef}>\n                <ErrorSuspenseBoundary fallback={<LoadingSpinner />}>\n                    <TabContent tab={tab} selected={selected} />\n                </ErrorSuspenseBoundary>\n            </WrappedTabContext.Provider>\n        </div>\n    );\n};\n\nconst TabPanel = () => {\n    const tabs = useSelector(getTabs);\n    const currentTabId = useSelector(getCurrentTabId);\n    // TODO: If there's no current tab object, dispatch an action to set one. This should never happen anyway.\n    const ref = useTabPanelRef();\n\n    const orderedTabs = useMemo(() => {\n        // ordered by id which is an increasing sequence number\n        // by fixing the render order we prevent iframes from being unnecessarily removed/re-added to the dom\n        // this is a problem with the form editor when we re-arrange the tabs\n        // inserting a new tab would cause all subsequent tabs to be unmounted and remounted, unnecessarily refreshing the iframe\n        return [...tabs].sort((a, b) => a.id - b.id);\n    }, [tabs]);\n\n    const invalidYaml = useSelector(getInvalidYaml);\n\n    return (\n        <div className=\"flex h-full grow flex-col overflow-hidden\">\n            <TabBar />\n            {invalidYaml ? (\n                <div ref={ref} className=\"relative h-full w-full overflow-auto bg-white p-8 dark:bg-black\">\n                    <div className=\"mx-auto max-w-5xl\">\n                        <h2 className=\"mb-6 text-3xl font-semibold text-red-600 dark:text-red-400\">\n                            Could not load app\n                        </h2>\n                        <p className=\"mb-4 text-lg text-gray-700 dark:text-gray-300\">\n                            This app cannot be loaded because it contains invalid YAML. This is likely due to the YAML\n                            being edited remotely.\n                        </p>\n                        <p className=\"mb-8 text-lg text-gray-700 dark:text-gray-300\">\n                            Please use the <strong>Version History</strong> panel to revert to a valid version of this\n                            app, or use an external editor to correct the YAML errors.\n                        </p>\n                    </div>\n                </div>\n            ) : (\n                <div ref={ref} className=\"relative h-full w-full bg-white dark:bg-black\">\n                    {/* key=t.url forces a re-render if the tab url changes - this behaviour is currently relied upon */}\n                    {/* We add the forceReload to the key so that the Tab will be forced to re-render with up to date state when a forceReload is requested */}\n                    {orderedTabs.map((t) => (\n                        <WrappedTabContent key={`${t.id}-${t.forceReload}`} tab={t} selected={t.id === currentTabId} />\n                    ))}\n                    {orderedTabs.length === 0 && <WrappedTabContent tab={null} selected={true} />}\n                </div>\n            )}\n        </div>\n    );\n};\n\nexport default TabPanel;\n","import React from \"react\";\nimport { cx } from \"@/theme/styles\";\n\ninterface ToolBarProps extends React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>> {\n    leftSide?: null | React.ReactNode;\n    allowScroll?: boolean;\n    ref?: React.Ref<HTMLDivElement>;\n}\n\nconst TabToolbar = ({ ref, className, children, leftSide = null, allowScroll = false, ...restProps }: ToolBarProps) => {\n    return (\n        <div\n            ref={ref}\n            className={cx(\n                \"flex h-20 w-full flex-none items-center overflow-hidden border-b border-sectionborder bg-white px-5 py-0 dark:border-dark-sectionborder dark:bg-dark-bg1 dark:text-dark-fg1\",\n                allowScroll ? \"overflow-x-auto\" : \"overflow-x-hidden\",\n                className\n            )}\n            {...restProps}>\n            {children}\n            {leftSide && (\n                <>\n                    <div className=\"grow\" />\n                    {leftSide}\n                </>\n            )}\n        </div>\n    );\n};\n\nexport default TabToolbar;\n","import React, { useEffect } from \"react\";\nimport { connect } from \"react-redux\";\nimport {\n    disableEnvironmentUplink,\n    enableEnvironmentUplink,\n    getCategorisedEnvironments,\n    getDefaultPublishedEnvironment,\n} from \"@/controllers/environments\";\nimport { getUser } from \"@/controllers/ide\";\nimport { modal } from \"@/controllers/modals\";\nimport { publishToTableau } from \"@/controllers/tableau\";\nimport { useUpdateTabTitle } from \"@/controllers/tabs\";\nimport TableauUsers from \"@/manager/components/TableauUsers\";\nimport { loadTableauLicence } from \"@/manager/controller\";\nimport { cx, makeStyles, useTheme } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, State } from \"@/types\";\nimport type { AppEnvironment } from \"@/types/app-environment\";\nimport type { ServiceTab } from \"@/types/tabs\";\nimport { Button } from \"../reusable/Button\";\nimport { HelpLink } from \"../reusable/HelpLink\";\nimport Link from \"../reusable/Link\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport TabToolbar from \"./TabToolbar\";\n\nlet useStyles = makeStyles()((theme) => ({\n    root: {\n        padding: \"2rem\",\n    },\n    container: {\n        background: theme.settings.rightBarBackground.toString(),\n        display: \"flex\",\n        flexDirection: \"column\",\n        overflowY: \"scroll\",\n    },\n    pagePanel: {\n        padding: \"1rem 4rem\",\n        width: \"90rem\",\n        borderRight: \"1px solid \" + theme.settings.separator.toString(),\n        background: theme.settings.background.toString(),\n        flexGrow: 1,\n        flexShrink: 0,\n    },\n}));\n\nconst dbUplinkConnector = connect((state: State) => ({\n    user: getUser(state),\n}));\n\ntype DBUplinkConfigProps = AnvilConnectedProps<typeof dbUplinkConnector> & {\n    env: AppEnvironment;\n};\n\nconst DBUplinkConfig = dbUplinkConnector(({ user, env, dispatch }: DBUplinkConfigProps) => {\n    if (env?.server_keys?.uplink?.db_read_key) {\n        return (\n            <>\n                Follow{\" \"}\n                <Link\n                    className={\"text-primary!\"}\n                    to={\"https://help.tableau.com/current/pro/desktop/en-us/examples_postgresql.htm\"}\n                    target={\"_blank\"}>\n                    these instructions\n                </Link>{\" \"}\n                to query your Data Tables from Tableau.\n                <p>\n                    Data source: <b>PostgreSQL</b>\n                    <br />\n                    Server name: <code className={\"select-text\"}>{user?.ideConfig.dbUplinkHost}</code>\n                    <br />\n                    Port: <code className={\"select-text\"}>5432</code>\n                    <br />\n                    Database: <code className={\"select-text\"}>tableau</code>\n                    <br />\n                    Authentication: <b>Username and Password</b>\n                    <br />\n                    Username: <code className={\"select-text\"}>tableau</code>\n                    <br />\n                    Password: <code className={\"select-text\"}>{env.server_keys.uplink.db_read_key}</code>\n                </p>\n                <Button small onClick={() => dispatch(disableEnvironmentUplink(env, \"db_read\"))}>\n                    Disable\n                </Button>\n            </>\n        );\n    } else {\n        return (\n            <Text>\n                Connect your Tableau dashboard to your Anvil Data Tables:{\" \"}\n                <Button small onClick={() => dispatch(enableEnvironmentUplink(env, \"db_read\"))}>\n                    Enable\n                </Button>\n            </Text>\n        );\n    }\n});\n\nconst connector = connect((state: State) => ({\n    publishedEnv: getDefaultPublishedEnvironment(state),\n    environments: getCategorisedEnvironments(state),\n}));\n\ntype TableauServiceTabProps = AnvilConnectedProps<typeof connector> & {\n    tab: ServiceTab;\n};\n\nconst TableauServiceTab = ({ tab, publishedEnv, environments, dispatch }: TableauServiceTabProps) => {\n    const { classes } = useStyles();\n    const debugEnv = environments.debug;\n\n    useUpdateTabTitle(tab, \"Anvil X\");\n    useEffect(() => {\n        dispatch(loadTableauLicence());\n    }, []);\n    const theme = useTheme();\n\n    return (\n        <div className={\"flex h-full flex-col\"}>\n            <TabToolbar>\n                <Text className={\"p-unset\"} level={1}>\n                    Embedded this app in a Tableau Dashboard.&nbsp;\n                    <HelpLink iconRight inline url={\"/docs/x\"}>\n                        Learn More\n                    </HelpLink>\n                </Text>\n            </TabToolbar>\n            <div\n                className={cx(classes.container)}\n                style={{\n                    height: \"calc(100% - 5rem)\", // subtract height of TabToolbar\n                }}>\n                <div className={cx(classes.pagePanel)}>\n                    {/*todo: fix sizing of this*/}\n                    <img\n                        className={\"mt-4 w-[20rem]\"}\n                        src={theme.isDark ? \"ide/img/anvil-x-full-dark-bg.svg\" : \"/ide/img/anvil-x-full.svg\"}\n                        alt={\"Anvil X logo\"}\n                    />\n                    <Heading level={2}>1. Test your extension in Tableau</Heading>\n                    <Text>\n                        To try out your app as a Tableau extension, click \"Test in Tableau\" above.\n                        <br />\n                        You will be able to see print output and Exceptions right here in the Anvil Editor.\n                    </Text>\n\n                    <Heading level={2}>2. Publish your extension to Tableau</Heading>\n                    <Text>\n                        When you're ready, publish a particular version of your app for use as a Tableau extension.\n                        Click \"Publish\" above to get started.\n                    </Text>\n\n                    {/* TODO: Do we only want to display step 3 for apps with tables? */}\n                    <Heading level={2}>3. Access your Data Tables from Tableau</Heading>\n\n                    {publishedEnv ? (\n                        <>\n                            <Heading level={3}>For Testing</Heading>\n                            <DBUplinkConfig env={debugEnv} />\n                            <Heading level={3}>Published Version</Heading>\n                            <DBUplinkConfig env={publishedEnv} />\n                            <Text level={3}>\n                                <LinkInternal onClick={() => dispatch(modal(\"environments\", {}))}>\n                                    Advanced publication options...\n                                </LinkInternal>\n                            </Text>\n                        </>\n                    ) : (\n                        <>\n                            <DBUplinkConfig env={debugEnv} />\n                            <Text level={3}>\n                                These connection details should be used for testing only. For production use,{\" \"}\n                                <LinkInternal className={`text-primary`} onClick={() => dispatch(publishToTableau())}>\n                                    publish your extension\n                                </LinkInternal>\n                            </Text>\n                        </>\n                    )}\n\n                    <hr />\n\n                    <div className={cx(\"mb-12 flex w-full justify-center\")}>\n                        <div className={\"w-full max-w-7xl\"}>\n                            <TableauUsers />\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n    );\n};\n\nexport default connector(TableauServiceTab);\n","import React, { useCallback, useEffect, useLayoutEffect, useRef } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport type { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport {\n    faBold,\n    faH1,\n    faH2,\n    faH3,\n    faItalic,\n    faLink,\n    faListOl,\n    faListUl,\n    faParagraph,\n    faUnderline,\n} from \"@fortawesome/pro-regular-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { $generateHtmlFromNodes, $generateNodesFromDOM } from \"@lexical/html\";\nimport { $isLinkNode, LinkNode, TOGGLE_LINK_COMMAND } from \"@lexical/link\";\nimport {\n    $isListNode,\n    INSERT_ORDERED_LIST_COMMAND,\n    INSERT_UNORDERED_LIST_COMMAND,\n    ListItemNode,\n    ListNode,\n    REMOVE_LIST_COMMAND,\n} from \"@lexical/list\";\nimport { InitialConfigType, LexicalComposer } from \"@lexical/react/LexicalComposer\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\nimport { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\nimport { HistoryPlugin } from \"@lexical/react/LexicalHistoryPlugin\";\nimport { LinkPlugin } from \"@lexical/react/LexicalLinkPlugin\";\nimport { ListPlugin } from \"@lexical/react/LexicalListPlugin\";\nimport { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\nimport { $createHeadingNode, $isHeadingNode, HeadingNode, HeadingTagType } from \"@lexical/rich-text\";\nimport { $setBlocksType } from \"@lexical/selection\";\nimport {\n    $createParagraphNode,\n    $createRangeSelection,\n    $getRoot,\n    $getSelection,\n    $isRangeSelection,\n    $isTextNode,\n    $setSelection,\n    DOMExportOutput,\n    ElementNode,\n    FORMAT_TEXT_COMMAND,\n    Klass,\n    LexicalEditor as LexicalEditorType,\n    LexicalNode,\n    ParagraphNode,\n    TextNode,\n} from \"lexical\";\nimport { prompt } from \"@/controllers/modals\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useConstant, usePartialReducer } from \"@/util/hooks\";\nimport useEffectEvent from \"@/util/useEffectEvent\";\nimport { Button, ButtonProps } from \"./Button\";\nimport DropdownMenu from \"./DropdownMenu\";\n\n/**\n * Traverses up the node tree to find the nearest ancestor of a specific type.\n * Note: This is equivalent to $getNearestNodeOfType from @lexical/utils, but\n * we avoid that dependency since it's not currently installed.\n */\nfunction $getNearestNodeOfType<T extends ElementNode>(node: LexicalNode, klass: Klass<T>): T | null {\n    let current: LexicalNode | null = node;\n    while (current !== null) {\n        if (current instanceof klass) {\n            return current as T;\n        }\n        current = current.getParent();\n    }\n    return null;\n}\n\nconst editorTheme = {\n    text: {\n        bold: \"font-bold\",\n        italic: \"italic\",\n        underline: \"underline\",\n        strikethrough: \"line-through\",\n    },\n    heading: {\n        h1: \"text-4xl font-bold\",\n        h2: \"text-3xl font-bold\",\n        h3: \"text-2xl font-bold\",\n        h4: \"text-xl font-bold\",\n        h5: \"text-lg font-bold\",\n        h6: \"text-base font-bold\",\n    },\n    list: {\n        ul: \"list-disc ml-8\",\n        ol: \"list-decimal ml-8\",\n        listitem: \"my-1\",\n        nested: {\n            listitem: \"list-none\",\n        },\n    },\n    link: \"text-blue-600 underline cursor-pointer\",\n};\n\n/**\n * Pretty-prints HTML by adding newlines and indentation for block elements.\n * This makes the HTML output more readable when stored/displayed as source.\n */\nconst formatHtml = (html: string): string => {\n    const blockTags = [\"p\", \"ul\", \"ol\", \"li\", \"div\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\"];\n\n    // Insert newlines before opening tags (except at start of string)\n    let formatted = html;\n    for (const tag of blockTags) {\n        formatted = formatted.replace(new RegExp(`(?<!^)(<${tag}[^>]*>)`, \"gi\"), \"\\n$1\");\n    }\n    // Insert newlines after closing tags (except at end of string)\n    for (const tag of blockTags) {\n        formatted = formatted.replace(new RegExp(`(</${tag}>)(?!$)`, \"gi\"), \"$1\\n\");\n    }\n\n    // Apply indentation for nested lists\n    const lines = formatted.split(\"\\n\");\n    let indent = 0;\n    const indentedLines: string[] = [];\n\n    for (const line of lines) {\n        const trimmed = line.trim();\n        if (!trimmed) continue;\n\n        // Decrease indent before closing list tags\n        if (/^<\\/(ul|ol)>/i.test(trimmed)) {\n            indent = Math.max(0, indent - 1);\n        }\n\n        indentedLines.push(\"  \".repeat(indent) + trimmed);\n\n        // Increase indent after opening list tags (but not self-closing)\n        if (/<(ul|ol)[^>]*>$/i.test(trimmed) && !trimmed.includes(\"</\")) {\n            indent++;\n        }\n    }\n\n    return indentedLines.join(\"\\n\");\n};\n\ninterface ToolBarButtonProps {\n    icon: ButtonProps[\"icon\"];\n    title: string;\n    onClick: () => void;\n    disabled?: boolean;\n    active: boolean;\n}\n\nconst ToolBarButton = ({ icon, title, onClick, disabled, active }: ToolBarButtonProps) => (\n    <Button\n        variant={active ? null : \"outlined\"}\n        small\n        onClick={onClick}\n        disabled={disabled}\n        title={title}\n        titleDelay\n        titlePosition=\"top\">\n        {icon && <FontAwesomeIcon icon={icon} fixedWidth />}\n    </Button>\n);\n\ninterface LexicalEditorProps {\n    placeholder?: string;\n    onHTMLChange?: (html: string, source: string) => void;\n    HTML?: string;\n    disabled?: boolean;\n    className: string;\n}\n\ninterface SelectionData {\n    anchorKey: string;\n    anchorOffset: number;\n    focusKey: string;\n    focusOffset: number;\n}\n\n/** Captures the current selection's anchor and focus points. */\nconst captureSelectionData = (selection: ReturnType<typeof $getSelection>): SelectionData | null => {\n    if (!$isRangeSelection(selection)) return null;\n    return {\n        anchorKey: selection.anchor.key,\n        anchorOffset: selection.anchor.offset,\n        focusKey: selection.focus.key,\n        focusOffset: selection.focus.offset,\n    };\n};\n\n/** Restores selection from previously captured selection data. */\nconst restoreSelection = (selectionData: SelectionData) => {\n    try {\n        const newSelection = $createRangeSelection();\n        newSelection.anchor.set(selectionData.anchorKey, selectionData.anchorOffset, \"text\");\n        newSelection.focus.set(selectionData.focusKey, selectionData.focusOffset, \"text\");\n        $setSelection(newSelection);\n    } catch {\n        // Nodes may have been deleted; selection restoration failed silently\n    }\n};\n\n/**\n * Opens a prompt to edit a link URL and applies it to the current selection.\n * Handles three cases:\n * 1. Existing link selected: pre-fills URL, optionally selects entire link text\n * 2. Text selected: converts selection to link\n * 3. Collapsed cursor in text node: selects entire text node as link text\n */\nconst editLink = async (\n    editor: LexicalEditorType,\n    dispatch: AnvilDispatch,\n    selectLinkNode: boolean = false\n): Promise<void> => {\n    let currentUrl = \"\";\n    let selectionData: SelectionData | null = null;\n\n    // Phase 1: Read current state and expand selection if needed\n    editor.getEditorState().read(() => {\n        const selection = $getSelection();\n        if (!$isRangeSelection(selection)) return;\n\n        const anchorNode = selection.anchor.getNode();\n        const parent = anchorNode.getParent();\n\n        // Check if we're inside an existing link\n        if ($isLinkNode(parent)) {\n            currentUrl = parent.getURL();\n            if (selectLinkNode) {\n                // Select the entire link text for editing\n                const firstChild = parent.getFirstChild();\n                const lastChild = parent.getLastChild();\n                if (firstChild && lastChild) {\n                    selectionData = {\n                        anchorKey: firstChild.getKey(),\n                        anchorOffset: 0,\n                        focusKey: lastChild.getKey(),\n                        focusOffset: lastChild.getTextContentSize(),\n                    };\n                }\n            }\n        } else if ($isLinkNode(anchorNode)) {\n            currentUrl = anchorNode.getURL();\n        }\n\n        // If we don't have selection data yet, capture or expand selection\n        if (!selectionData) {\n            if (!selection.isCollapsed()) {\n                // User has text selected - use that\n                selectionData = captureSelectionData(selection);\n            } else if (currentUrl) {\n                // Inside existing link with collapsed cursor\n                selectionData = captureSelectionData(selection);\n            } else if ($isTextNode(anchorNode) && anchorNode.getTextContentSize() > 0) {\n                // Collapsed cursor inside a text node - select the entire text node\n                selectionData = {\n                    anchorKey: anchorNode.getKey(),\n                    anchorOffset: 0,\n                    focusKey: anchorNode.getKey(),\n                    focusOffset: anchorNode.getTextContentSize(),\n                };\n            }\n            // If none of the above, selectionData stays null (nothing to link)\n        }\n    });\n\n    // Can't create a link with nothing selected\n    if (!selectionData) return;\n\n    // Phase 2: Prompt user for URL\n    const url = await dispatch(prompt(\"Enter URL\", \"Please enter a URL:\", currentUrl));\n    if (url === null) return;\n\n    const trimmedUrl = typeof url === \"string\" ? url.trim() : \"\";\n    const data = selectionData;\n\n    if (!trimmedUrl) {\n        // Empty URL removes the link\n        editor.update(() => {\n            restoreSelection(data);\n            editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);\n        });\n        return;\n    }\n\n    // Add https:// if no protocol specified (but allow mailto:, tel:, etc.)\n    const hasProtocol = /^(https?:\\/\\/|mailto:|tel:)/i.test(trimmedUrl);\n    const formattedUrl = hasProtocol ? trimmedUrl : \"https://\" + trimmedUrl;\n\n    // Phase 3: Apply the link\n    editor.update(() => {\n        restoreSelection(data);\n        editor.dispatchCommand(TOGGLE_LINK_COMMAND, formattedUrl);\n    });\n};\n\ntype BlockType = HeadingTagType | \"p\" | \"bullet\" | \"number\";\n\nconst NORMAL_BLOCK = { label: \"Normal\", value: \"p\", icon: faParagraph } as const;\n\nconst BLOCK_TYPE_OPTIONS: { label: string; value: BlockType; icon: IconDefinition }[] = [\n    NORMAL_BLOCK,\n    { label: \"Heading 1\", value: \"h1\", icon: faH1 },\n    { label: \"Heading 2\", value: \"h2\", icon: faH2 },\n    { label: \"Heading 3\", value: \"h3\", icon: faH3 },\n    { label: \"Bullet list\", value: \"bullet\", icon: faListUl },\n    { label: \"Numbered list\", value: \"number\", icon: faListOl },\n];\n\nconst DEFAULT_TOOLBAR_STATE = {\n    isBold: false,\n    isItalic: false,\n    isUnderline: false,\n    listType: null as string | null,\n    isLink: false,\n    blockType: \"p\" as HeadingTagType | \"p\",\n};\n\nconst ToolbarPlugin = ({ disabled }: { disabled?: boolean }) => {\n    const [editor] = useLexicalComposerContext();\n    const dispatch = useDispatch<AnvilDispatch>();\n    const [toolbarState, setToolbarState] = usePartialReducer(DEFAULT_TOOLBAR_STATE);\n\n    /** Syncs toolbar button states with the current selection's formatting. */\n    const updateToolbar = useCallback(() => {\n        const selection = $getSelection();\n        if (!$isRangeSelection(selection)) {\n            setToolbarState(DEFAULT_TOOLBAR_STATE);\n            return;\n        }\n\n        const anchorNode = selection.anchor.getNode();\n        const parentList = $getNearestNodeOfType(anchorNode, ListNode);\n        const parentHeading = $getNearestNodeOfType(anchorNode, HeadingNode);\n        const parent = anchorNode.getParent();\n\n        setToolbarState({\n            isBold: selection.hasFormat(\"bold\"),\n            isItalic: selection.hasFormat(\"italic\"),\n            isUnderline: selection.hasFormat(\"underline\"),\n            listType: $isListNode(parentList) ? parentList.getListType() : null,\n            isLink: $isLinkNode(parent) || $isLinkNode(anchorNode),\n            blockType: $isHeadingNode(parentHeading) ? parentHeading.getTag() : \"p\",\n        });\n    }, [setToolbarState]);\n\n    // Update toolbar on any editor state change (covers selection changes, formatting, etc.)\n    useEffect(() => {\n        // Initial toolbar state\n        editor.getEditorState().read(updateToolbar);\n\n        return editor.registerUpdateListener(({ editorState }) => {\n            editorState.read(updateToolbar);\n        });\n    }, [editor, updateToolbar]);\n\n    const handleFormat = (format: \"bold\" | \"italic\" | \"underline\") => {\n        editor.dispatchCommand(FORMAT_TEXT_COMMAND, format);\n    };\n\n    const handleBlockType = (value: BlockType) => {\n        if (value === \"bullet\" || value === \"number\") {\n            const targetType = value;\n            if (toolbarState.listType === targetType) {\n                editor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);\n            } else if (value === \"bullet\") {\n                editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);\n            } else {\n                editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined);\n            }\n        } else {\n            editor.update(() => {\n                const selection = $getSelection();\n                if ($isRangeSelection(selection)) {\n                    $setBlocksType(selection, () =>\n                        value === \"p\" ? $createParagraphNode() : $createHeadingNode(value)\n                    );\n                }\n            });\n        }\n    };\n\n    const handleLink = async () => {\n        if (toolbarState.isLink) {\n            editor.update(() => {\n                editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);\n            });\n        } else {\n            await editLink(editor, dispatch);\n        }\n    };\n\n    const getCurrentBlockLabel = () => {\n        const type = toolbarState.listType || toolbarState.blockType;\n        return BLOCK_TYPE_OPTIONS.find((opt) => opt.value === type) ?? NORMAL_BLOCK;\n    };\n\n    const currentBlock = getCurrentBlockLabel();\n\n    return (\n        <div className=\"flex h-18 items-center gap-4 rounded-t border-2 border-b border-light-bg5 bg-white p-3.5 dark:border-dark-bg3 dark:bg-dark-bg1\">\n            <DropdownMenu\n                align=\"left\"\n                items={() =>\n                    BLOCK_TYPE_OPTIONS.map((option) => [\n                        option.label,\n                        () => {\n                            handleBlockType(option.value);\n                        },\n                        option.icon,\n                    ])\n                }\n                render={(showMenu, anchor) => (\n                    <Button\n                        small\n                        onClick={(e) => showMenu(null, e.currentTarget)}\n                        disabled={disabled}\n                        className=\"min-w-54\"\n                        title=\"Text style\"\n                        titlePosition=\"top\"\n                        titleDelay\n                        icon={currentBlock.icon}>\n                        {currentBlock.label}\n                        {anchor}\n                    </Button>\n                )}\n            />\n            <div className=\"h-6 w-px bg-light-bg5 dark:bg-dark-bg3\" />\n            <ToolBarButton\n                icon={faBold}\n                title=\"Bold\"\n                onClick={() => handleFormat(\"bold\")}\n                disabled={disabled}\n                active={toolbarState.isBold}\n            />\n            <ToolBarButton\n                icon={faItalic}\n                title=\"Italic\"\n                onClick={() => handleFormat(\"italic\")}\n                disabled={disabled}\n                active={toolbarState.isItalic}\n            />\n            <ToolBarButton\n                icon={faUnderline}\n                title=\"Underline\"\n                onClick={() => handleFormat(\"underline\")}\n                disabled={disabled}\n                active={toolbarState.isUnderline}\n            />\n            <div className=\"h-6 w-px bg-light-bg5 dark:bg-dark-bg3\" />\n            <ToolBarButton\n                icon={faLink}\n                title=\"Insert link\"\n                onClick={handleLink}\n                disabled={disabled}\n                active={toolbarState.isLink}\n            />\n        </div>\n    );\n};\n\nconst DoubleClickLinkPlugin = () => {\n    const [editor] = useLexicalComposerContext();\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const handleDoubleClick = useEffectEvent((event: MouseEvent) => {\n        const target = event.target as HTMLElement;\n        const linkElement = target.closest(\"a\");\n        if (!linkElement) return;\n        event.preventDefault();\n        event.stopPropagation();\n\n        editor.update(\n            () => {\n                const selection = $getSelection();\n                if ($isRangeSelection(selection)) {\n                    const anchorNode = selection.anchor.getNode();\n                    let linkNode = anchorNode.getParent();\n\n                    while (linkNode && !$isLinkNode(linkNode)) {\n                        linkNode = linkNode.getParent();\n                    }\n\n                    if (linkNode && $isLinkNode(linkNode)) {\n                        const firstChild = linkNode.getFirstChild();\n                        const lastChild = linkNode.getLastChild();\n                        if (firstChild && lastChild) {\n                            const newSelection = $createRangeSelection();\n                            newSelection.anchor.set(firstChild.getKey(), 0, \"text\");\n                            newSelection.focus.set(lastChild.getKey(), lastChild.getTextContentSize(), \"text\");\n                            $setSelection(newSelection);\n                        }\n                    }\n                }\n            },\n            { discrete: true }\n        );\n\n        editLink(editor, dispatch, true);\n    });\n\n    useEffect(() => {\n        return editor.registerRootListener((rootElement, prevRootElement) => {\n            prevRootElement?.removeEventListener(\"dblclick\", handleDoubleClick);\n            rootElement?.addEventListener(\"dblclick\", handleDoubleClick);\n        });\n    }, [editor, handleDoubleClick]);\n\n    return null;\n};\n\nconst HTML_SYNC_TAG = \"html-sync\";\n\nconst HtmlSyncPlugin = ({\n    HTML,\n    onHTMLChange,\n}: {\n    HTML?: string;\n    onHTMLChange?: (html: string, source: string) => void;\n}) => {\n    const [editor] = useLexicalComposerContext();\n    const lastHtmlRef = useRef<string>(\"\");\n\n    useLayoutEffect(() => {\n        const htmlToLoad = HTML ?? \"\";\n        if (htmlToLoad === lastHtmlRef.current) return;\n\n        editor.update(\n            () => {\n                const root = $getRoot();\n                root.clear();\n\n                if (htmlToLoad) {\n                    const parser = new DOMParser();\n                    const dom = parser.parseFromString(htmlToLoad, \"text/html\");\n                    const nodes = $generateNodesFromDOM(editor, dom);\n                    if (nodes.length > 0) {\n                        root.append(...nodes);\n                        return;\n                    }\n                }\n                // Empty content or no valid nodes - start with empty paragraph\n                root.append($createParagraphNode());\n            },\n            { discrete: true, tag: HTML_SYNC_TAG }\n        );\n\n        lastHtmlRef.current = htmlToLoad;\n    }, [HTML, editor]);\n\n    useLayoutEffect(() => {\n        return editor.registerUpdateListener(({ editorState, tags }) => {\n            // Skip updates triggered by external HTML sync to avoid loops\n            if (tags.has(HTML_SYNC_TAG)) return;\n\n            editorState.read(() => {\n                const htmlString = $generateHtmlFromNodes(editor, null);\n                const formattedHtml = formatHtml(htmlString);\n                if (formattedHtml !== lastHtmlRef.current) {\n                    lastHtmlRef.current = formattedHtml;\n                    onHTMLChange?.(formattedHtml, \"user\");\n                }\n            });\n        });\n    }, [editor, onHTMLChange]);\n\n    return null;\n};\n\nconst EditablePlugin = ({ disabled }: { disabled?: boolean }) => {\n    const [editor] = useLexicalComposerContext();\n\n    useEffect(() => {\n        editor.setEditable(!disabled);\n    }, [editor, disabled]);\n\n    return null;\n};\n\nconst cleanTextNode = (editor: LexicalEditorType, node: LexicalNode) => {\n    let { element } = node.exportDOM(editor);\n    if (!element) return { element };\n    if (element instanceof HTMLSpanElement && element.firstChild instanceof Text) {\n        element = element.firstChild;\n    }\n    let child: typeof element | null = element;\n    while (child instanceof HTMLElement) {\n        child.removeAttribute(\"class\");\n        child.style.removeProperty(\"white-space\");\n        if (!child.getAttribute(\"style\")) {\n            child.removeAttribute(\"style\");\n        }\n        child.removeAttribute(\"dir\");\n        child = child.firstElementChild as typeof child;\n    }\n    return { element };\n};\n\n/** Exports a node's DOM without Tailwind classes and dir attributes (for clean HTML output). */\nconst stripClassesFromExport = (editor: LexicalEditorType, node: LexicalNode): DOMExportOutput => {\n    const { element } = node.exportDOM(editor);\n    if (!element || !(element instanceof HTMLElement)) return { element };\n    element.removeAttribute(\"class\");\n    element.removeAttribute(\"dir\");\n    return { element };\n};\n\nconst exportMap = new Map<Klass<LexicalNode>, (editor: LexicalEditorType, target: LexicalNode) => DOMExportOutput>([\n    [TextNode, cleanTextNode],\n    [LinkNode, stripClassesFromExport],\n    [ListNode, stripClassesFromExport],\n    [ListItemNode, stripClassesFromExport],\n    [ParagraphNode, stripClassesFromExport],\n    [HeadingNode, stripClassesFromExport],\n]);\n\nexport const LexicalEditor = ({ placeholder, onHTMLChange, HTML, disabled, className }: LexicalEditorProps) => {\n    const initialConfig: InitialConfigType = useConstant(\n        () =>\n            ({\n                namespace: \"EmailEditor\",\n                nodes: [ParagraphNode, TextNode, LinkNode, ListNode, ListItemNode, HeadingNode],\n                theme: editorTheme,\n                onError: (error: Error) => {\n                    console.error(\"Lexical error:\", error);\n                },\n                editable: !disabled,\n                html: { export: exportMap },\n            }) satisfies InitialConfigType\n    );\n\n    return (\n        <div className={className}>\n            <LexicalComposer initialConfig={initialConfig}>\n                <ToolbarPlugin disabled={disabled} />\n                <div className=\"relative min-h-0 overflow-auto rounded-b border-2 border-t-0 border-light-bg5 bg-white dark:border-dark-bg3 dark:bg-dark-bg1\">\n                    <RichTextPlugin\n                        contentEditable={\n                            <ContentEditable\n                                className=\"font-inherit empty:before:font-inherit min-h-[200px] p-3 pb-96 outline-none empty:before:text-light-bg5 empty:before:content-[attr(data-placeholder)] empty:before:dark:text-dark-bg3\"\n                                data-placeholder={placeholder}\n                                data-lexical-editor=\"true\"\n                            />\n                        }\n                        placeholder={null}\n                        ErrorBoundary={LexicalErrorBoundary}\n                    />\n                    <HistoryPlugin />\n                    <LinkPlugin />\n                    <ListPlugin />\n                    <DoubleClickLinkPlugin />\n                    <HtmlSyncPlugin HTML={HTML} onHTMLChange={onHTMLChange} />\n                    <EditablePlugin disabled={disabled} />\n                </div>\n            </LexicalComposer>\n        </div>\n    );\n};\n","import React, { useCallback, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { connect, useDispatch, useSelector } from \"react-redux\";\nimport { faMagnifyingGlass } from \"@fortawesome/pro-light-svg-icons\";\nimport { HtmlBodyEditor } from \"@/code_mirror/editors\";\nimport { UserServiceCTA } from \"@/components/reusable/CollapsibleCTA\";\nimport { getAppName } from \"@/controllers/app\";\nimport { addTableColumn, getDebugEnvironmentTableMapping } from \"@/controllers/db\";\nimport { getFeatures, getSubscription, getUser } from \"@/controllers/ide\";\nimport { alert, confirm, modal, prompt } from \"@/controllers/modals\";\nimport {\n    addService,\n    ensureUsersServiceTableConfigured,\n    getAllAvailableServices,\n    getServiceSourceFromName,\n    getUsersService,\n    getUsersTable,\n    serviceNameToSource,\n    updateUsersService,\n} from \"@/controllers/services\";\nimport { useUpdateTabTitle } from \"@/controllers/tabs\";\nimport { getUserUiPrefs, updateUserEditorPrefs } from \"@/controllers/user\";\nimport { useRemToPixels } from \"@/theme/ThemeProvider\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { AnvilConnectedProps, AnvilDispatch, State, Tab } from \"@/types\";\nimport { CurrentTable } from \"@/types/database\";\nimport type { AvailableService, UsersClientConfig, UsersServerConfig } from \"@/types/services\";\nimport { User } from \"@/types/user\";\nimport * as api from \"@/api\";\nimport { featureSupported, getPlanName, useFeatureSupported } from \"@/util/features\";\nimport { useResizeObserver } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { Accordion } from \"../reusable/Accordion\";\nimport { Button } from \"../reusable/Button\";\nimport { ButtonGroup } from \"../reusable/ButtonGroup\";\nimport DropdownMenu, { MenuItems } from \"../reusable/DropdownMenu\";\nimport { HelpLink } from \"../reusable/HelpLink\";\nimport { LexicalEditor } from \"../reusable/LexicalEditor\";\nimport { LinkInternal } from \"../reusable/LinkInternal\";\nimport { CheckBox, ContentDropdownMenuItem, ContentTextInput } from \"../reusable/SharedComponents\";\nimport { Heading, Text } from \"../reusable/Text\";\nimport UpgradeBadge from \"../reusable/UpgradeBadge\";\nimport { Section } from \"../sidebar/SecondaryNavSection\";\nimport TableView from \"./database/View\";\nimport { useUpdateRowMutation } from \"./database/cells/EditingCell\";\nimport { CellInfo } from \"./database/types\";\n\nexport const useStyles = makeStyles()((theme) => ({\n    root: {\n        padding: \"1rem 4rem\",\n        color: theme.userService.color.toString(),\n        \"& h4\": {\n            marginTop: \"2rem\",\n        },\n        \"& pre\": {\n            backgroundColor: theme.userService.sampleCode.background.toString(),\n            borderColor: theme.userService.sampleCode.borderColor.toString(),\n            color: theme.userService.sampleCode.color.toString(),\n        },\n    },\n    usersServiceOption: {\n        display: \"inline-block\",\n        verticalAlign: \"top\",\n        width: \"48%\",\n        fontWeight: \"normal\",\n        paddingLeft: \"1.5em\",\n    },\n    description: {\n        fontSize: \"90%\",\n        color: theme.palette.fg1.alpha(0.7).toString(),\n        paddingRight: \"2rem\",\n        paddingBottom: \"1em\",\n        fontStyle: \"italic\",\n    },\n    usersHeader: {\n        borderBottom: \"1px solid \" + theme.palette.bg2.hex(),\n        padding: \"0 2rem\",\n    },\n    usersTable: {\n        margin: \"2rem 0\",\n        border: \"1px solid \" + theme.palette.bg2.hex(),\n    },\n}));\n\nconst findColumnByName = (usersTable: CurrentTable | undefined, name: string) => {\n    const columns = usersTable?.columns ?? {};\n\n    for (const [id, columnSpec] of Object.entries(columns)) {\n        if (columnSpec.name === name) {\n            return id;\n        }\n    }\n    return null;\n};\n\nconst useUserRowMenu = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const usersService = useSelector(getUsersService);\n    const usersTable = useSelector(getUsersTable);\n    const mutation = useUpdateRowMutation();\n\n    const resetPasswordCallback = async (info: CellInfo) => {\n        const pw1 = await dispatch(prompt(\"New password\", \"Please enter a new password\"));\n        if (pw1 == null) {\n            return;\n        }\n\n        const pw2 = await dispatch(prompt(\"New password\", \"Please enter the new password again\"));\n        if (pw2 == null) {\n            return;\n        }\n\n        if (pw1 !== pw2) {\n            await dispatch(alert(\"Please try again\", \"The passwords you entered do not match - please try again.\"));\n            return;\n        }\n\n        const { tableMappingId, tableId } = info.table.options.meta!;\n\n        let passwordColId = findColumnByName(usersTable, \"password_hash\");\n        let emailConfirmedColId = findColumnByName(usersTable, \"confirmed_email\");\n        let colCount = Object.keys(usersTable?.columns ?? {}).length;\n\n        const data = { ...info.row.original };\n        if (passwordColId == null) {\n            const addedPasswordCol = (await dispatch(\n                addTableColumn(tableMappingId, tableId, {\n                    name: \"password_hash\",\n                    type: \"string\",\n                    admin_ui: { order: colCount++ },\n                    client_hidden: true,\n                })\n            )) as { id?: string } | undefined;\n            passwordColId = addedPasswordCol?.id ?? null;\n        }\n        if (usersService?.client_config?.confirm_email) {\n            if (emailConfirmedColId == null) {\n                const addedEmailConfirmedCol = (await dispatch(\n                    addTableColumn(tableMappingId, tableId, {\n                        name: \"confirmed_email\",\n                        type: \"bool\",\n                        admin_ui: { order: colCount++ },\n                        client_hidden: false,\n                    })\n                )) as { id?: string } | undefined;\n                emailConfirmedColId = addedEmailConfirmedCol?.id ?? null;\n            }\n            if (emailConfirmedColId == null) {\n                await dispatch(\n                    alert(\"Could not reset password\", \"Couldn't find or create the 'confirmed_email' column.\")\n                );\n                return;\n            }\n            data[emailConfirmedColId as string] = true;\n        }\n        if (passwordColId == null) {\n            await dispatch(alert(\"Could not reset password\", \"Couldn't find or create the 'password_hash' column.\"));\n            return;\n        }\n        data[passwordColId as string] = await api.hashPassword(pw1);\n        mutation.mutate({ data, info });\n    };\n\n    const clearRememberedLoginsCallback = async (info: CellInfo) => {\n        const rememberedColId = findColumnByName(usersTable, \"remembered_logins\");\n        if (rememberedColId == null) return;\n        const { row } = info;\n        mutation.mutate({ data: { ...row.original, [rememberedColId]: null }, info });\n        await dispatch(\n            alert(\"Remembered logins cleared\", \"This user will have to login again next time they use your app.\")\n        );\n    };\n\n    const resetMfaCallback = async (info: CellInfo) => {\n        const mfaColId = findColumnByName(usersTable, \"mfa\");\n        const emailColId = findColumnByName(usersTable, \"email\");\n        if (mfaColId == null || emailColId == null) return;\n        const { row } = info;\n        const data = { ...row.original };\n        const c = await dispatch(\n            confirm(\n                \"Clear 2-Factor Authentication Methods?\",\n                `This will prevent ${data[emailColId]} from logging in until they reset their two-factor authentication method via email.`\n            )\n        );\n        if (!c) return;\n\n        data[mfaColId] = null;\n        mutation.mutate({ data, info });\n    };\n\n    const forceMfaOnNextLoginCallback = async (info: CellInfo) => {\n        const mfaColId = findColumnByName(usersTable, \"mfa\");\n        const emailColId = findColumnByName(usersTable, \"email\");\n        if (mfaColId == null || emailColId == null) return;\n\n        const { row } = info;\n        const data = { ...row.original };\n\n        const c = await dispatch(\n            confirm(\n                \"Force 2-Factor Authentication on next login?\",\n                `This will require ${data[emailColId]} to use two-factor authentication on next login, discarding any remembered devices.`\n            )\n        );\n        if (!c) return;\n\n        const mfaData = data[mfaColId] ?? [];\n        for (let i = 0; i < mfaData.length; i++) {\n            mfaData[i].serial++;\n        }\n        mutation.mutate({ data, info });\n    };\n\n    const menuItems = useCallback(\n        (info: CellInfo) => {\n            const items: MenuItems = [];\n            if (usersService?.client_config?.use_email) {\n                items.push([\"Reset password...\", () => resetPasswordCallback(info)]);\n            }\n            if (usersService?.client_config?.allow_remember_me) {\n                items.push([\"Clear remembered logins\", () => clearRememberedLoginsCallback(info)]);\n            }\n            if (usersService?.client_config?.require_mfa) {\n                items.push([\"Clear two-factor authentication methods\", () => resetMfaCallback(info)]);\n                items.push([\"Force two-factor authentication on next login\", () => forceMfaOnNextLoginCallback(info)]);\n            }\n            return items;\n        },\n        [usersService, usersTable]\n    );\n\n    return menuItems;\n};\n\nconst UserServiceTable = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const usersService = useSelector(getUsersService);\n    const usersTable = useSelector(getUsersTable);\n    const currentTableMapping = useSelector(getDebugEnvironmentTableMapping);\n    const menuItems = useUserRowMenu();\n    const maxHeight = useRemToPixels(60);\n    const [isRepairing, setRepairing] = useState(false);\n\n    const repairUserTableConfig = useEvent(async () => {\n        setRepairing(true);\n        try {\n            await dispatch(ensureUsersServiceTableConfigured());\n        } finally {\n            setRepairing(false);\n        }\n    });\n\n    const availableUsersTables = useMemo(\n        () => [...(currentTableMapping?.tables ?? [])].sort((a, b) => a.name.localeCompare(b.name)),\n        [currentTableMapping?.tables]\n    );\n    const hasConventionalUsersTable = availableUsersTables.some(({ python_name }) => python_name === \"users\");\n    const repairUserTableLabel = hasConventionalUsersTable ? \"Use Users table\" : \"Create a Users table\";\n\n    const chooseExistingUserTable = useEvent((table: CurrentTable) => {\n        dispatch(updateUsersService([\"server_config\", \"user_table\"], table.python_name));\n    });\n\n    const addExistingTableToDebugDatabase = useEvent(() => {\n        if (!currentTableMapping) return;\n        dispatch(\n            modal(\"addExistingTable\", {\n                tableMapping: currentTableMapping,\n                addNewTable: repairUserTableConfig,\n                addNewTableLabel: repairUserTableLabel,\n            })\n        );\n    });\n\n    if (!usersTable) {\n        const configuredTable = usersService?.server_config?.user_table;\n        return (\n            <div className=\"m-0 p-8\">\n                <Heading level={3} className=\"my-2!\">\n                    Users table not configured\n                </Heading>\n                <Text level={3} className=\"pr-8 pb-4 text-[90%] text-current/70 italic\">\n                    {configuredTable\n                        ? `The Users service is configured to use '${configuredTable}', but that table is not available in this environment.`\n                        : \"The Users service needs a table before it can manage users.\"}\n                </Text>\n                <Button\n                    small\n                    variant=\"primary\"\n                    className=\"mt-4\"\n                    disabled={isRepairing}\n                    onClick={repairUserTableConfig}>\n                    {isRepairing ? \"Configuring Users table\" : repairUserTableLabel}\n                </Button>\n                <DropdownMenu\n                    anchorToTrigger\n                    render={(showMenu) => (\n                        <Button\n                            small\n                            className=\"mt-4 ml-4\"\n                            disabled={isRepairing || !currentTableMapping}\n                            onClick={(event) => showMenu(null, event.currentTarget)}>\n                            Choose an existing table\n                        </Button>\n                    )}\n                    items={() => [\n                        ...availableUsersTables.map(\n                            (table) =>\n                                [\n                                    <span>\n                                        {table.name} (<span className=\"font-mono\">{table.python_name}</span>)\n                                    </span>,\n                                    () => chooseExistingUserTable(table),\n                                ] as const\n                        ),\n                        availableUsersTables.length > 0 && <hr />,\n                        [\n                            \"Add a table from another app or database…\",\n                            addExistingTableToDebugDatabase,\n                        ],\n                    ]}\n                />\n            </div>\n        );\n    }\n    return (\n        <TableView\n            currentTable={usersTable}\n            tableMapping={currentTableMapping}\n            menuItems={menuItems}\n            toolbarOptions={{ pythonName: false }}\n            maxHeight={maxHeight}\n        />\n    );\n};\n\ninterface UserServiceTabProps extends AnvilConnectedProps<typeof connector> {\n    tab: Tab;\n}\n\ntype SupportedSignInService = keyof typeof serviceNameToSource | \"token\";\n\nconst getServiceBySource = (services: AvailableService[] | undefined, source: string) =>\n    services?.find((service) => service.source === source);\n\nconst EmptyUsersClientConfig: UsersClientConfig = {};\n\nconst EmptyUsersServerConfig: UsersServerConfig = {};\n\nconst UserServiceTab = ({ tab, availableServices, usersService, features, dispatch }: UserServiceTabProps) => {\n    const { classes } = useStyles();\n    const clientConfig: UsersClientConfig = usersService?.client_config ?? EmptyUsersClientConfig;\n\n    useUpdateTabTitle(tab, \"Users\");\n\n    const updateUsersConfig = useEvent(\n        async (name: SupportedSignInService | \"_\", add_service = false, requireFeatureOnSubscription?: string) => {\n            if (!requireFeatureOnSubscription || featureSupported(features, requireFeatureOnSubscription)) {\n                const config_name = `use_${name}`;\n                const use_service = !clientConfig[config_name as keyof UsersClientConfig];\n                await dispatch(updateUsersService([\"client_config\", config_name], use_service));\n                if (add_service && use_service) {\n                    const source = getServiceSourceFromName(name as keyof typeof serviceNameToSource);\n                    const service = getServiceBySource(availableServices, source);\n                    if (service) {\n                        await dispatch(addService(service, true, false, false));\n                    }\n                }\n            } else {\n                dispatch(modal(\"upgradePrompt\", { featureId: requireFeatureOnSubscription }));\n            }\n        }\n    );\n\n    const toggleAllowRememberMe = useEvent(async () => {\n        if (!usersService) return;\n        const newVal = !clientConfig.allow_remember_me;\n        await dispatch(updateUsersService([\"client_config\", \"allow_remember_me\"], newVal));\n        if (newVal && !(\"remember_me_days\" in clientConfig)) {\n            await dispatch(updateUsersService([\"client_config\", \"remember_me_days\"], 30));\n        }\n    });\n\n    const toggleRequireMfa = useEvent(async () => {\n        if (!usersService) return;\n        const newVal = !clientConfig.require_mfa;\n        await dispatch(updateUsersService([\"client_config\", \"require_mfa\"], newVal));\n        if (newVal && !(\"mfa_timeout_days\" in clientConfig)) {\n            await dispatch(updateUsersService([\"client_config\", \"mfa_timeout_days\"], 0));\n        }\n    });\n\n    const toggleUseEmail = useEvent(async () => {\n        if (!usersService) return;\n        const newVal = !clientConfig.use_email;\n        await dispatch(updateUsersService([\"client_config\", \"use_email\"], newVal));\n        if (newVal && !(\"require_secure_passwords\" in clientConfig)) {\n            await dispatch(updateUsersService([\"client_config\", \"require_secure_passwords\"], true));\n        }\n    });\n\n    // TODO: Add Google, Facebook, SAML service, etc as required.\n    // TODO: Add badges to features only available on certain plans.\n\n    if (!usersService) return null;\n\n    return (\n        <div className={classes.root}>\n            <UserServiceCTA />\n            This service makes it easy to register and manage multiple users of your app.{\" \"}\n            <HelpLink inline iconRight url={`${window.location.origin}/docs/users`}>\n                Learn more\n            </HelpLink>\n            <h4 className={\"my-2 text-3xl font-medium\"}>Sample code:</h4>\n            <div>\n                <pre className=\"mb-3 select-all\">anvil.users.login_with_form()</pre>\n                Then just call <code className=\"select-all\">anvil.users.get_user()</code> to get the currently logged-in\n                user.{\" \"}\n                <HelpLink left inline iconRight url={`${window.location.origin}/docs/users/presenting-a-login-form`}>\n                    Click here for more code samples\n                </HelpLink>\n            </div>\n            <h4 className=\"my-2 text-3xl font-medium\">Supported sign-in methods:</h4>\n            <div>\n                <div className={classes.usersServiceOption}>\n                    <CheckBox\n                        text={\"Email + Password\"}\n                        checked={usersService.client_config?.use_email || false}\n                        onChange={toggleUseEmail}\n                    />\n                    <div className={classes.description}>Users can sign in with an email address and a password</div>\n                </div>\n                <div className={classes.usersServiceOption}>\n                    <CheckBox\n                        text={\"Sign in with Google\"}\n                        checked={usersService.client_config?.use_google || false}\n                        onChange={() => updateUsersConfig(\"google\", true)}\n                    />\n                    <div className={classes.description}>Users can sign in with their Google account</div>\n                </div>\n                <div className={classes.usersServiceOption}>\n                    <CheckBox\n                        text={\"Sign in with Facebook\"}\n                        checked={usersService.client_config?.use_facebook || false}\n                        onChange={() => updateUsersConfig(\"facebook\", true)}\n                    />\n                    <div className={classes.description}>Users can sign in with their Facebook account</div>\n                </div>\n                <div className={classes.usersServiceOption}>\n                    <CheckBox\n                        text={\"Email Link\"}\n                        checked={usersService.client_config?.use_token || false}\n                        onChange={() => updateUsersConfig(\"token\")}\n                    />\n                    <div className={classes.description}>Users can sign in by following a link in an email</div>\n                </div>\n                <div className={classes.usersServiceOption}>\n                    <CheckBox\n                        text={\n                            <>\n                                Microsoft (Entra ID/Office 365) <UpgradeBadge feature={\"microsoft\"} />\n                            </>\n                        }\n                        checked={usersService.client_config?.use_microsoft || false}\n                        onChange={() => updateUsersConfig(\"microsoft\", true, \"microsoft\")}\n                    />\n                    <div className={classes.description}>\n                        Users can sign in with their Office 365 or Microsoft Entra ID credentials\n                    </div>\n                </div>\n                <div className={classes.usersServiceOption}>\n                    <CheckBox\n                        text={\n                            <>\n                                SAML <UpgradeBadge feature={\"saml\"} />\n                            </>\n                        }\n                        checked={usersService.client_config?.use_saml || false}\n                        onChange={() => updateUsersConfig(\"saml\", true, \"saml\")}\n                    />\n                    <div className={classes.description}>Users can sign in via your own SAML Identity Provider</div>\n                </div>\n                <div className={classes.usersServiceOption}>\n                    <CheckBox\n                        text={\n                            <>\n                                Local Active Directory <UpgradeBadge feature={\"kerberos\"} />\n                            </>\n                        }\n                        checked={false}\n                        onChange={() => updateUsersConfig(\"_\", false, \"kerberos\")}\n                    />\n                    <div className={classes.description}>Users can sign in with their domain credentials</div>\n                </div>\n                <div className={classes.usersServiceOption}>\n                    <CheckBox\n                        text={\n                            <>\n                                Client Certificates (PKI) <UpgradeBadge feature={\"pki\"} />\n                            </>\n                        }\n                        checked={false}\n                        onChange={() => updateUsersConfig(\"_\", false, \"pki\")}\n                    />\n                    <div className={classes.description}>Users can sign in with an X.509 certificate</div>\n                </div>\n            </div>\n            <h4 className={\"my-2 text-3xl font-medium\"}>Login options:</h4>\n            <div>\n                {usersService.client_config?.use_email && (\n                    <div className={classes.usersServiceOption}>\n                        <CheckBox\n                            text={\"Require secure passwords\"}\n                            checked={clientConfig.require_secure_passwords ?? false}\n                            onChange={() =>\n                                dispatch(\n                                    updateUsersService(\n                                        [\"client_config\", \"require_secure_passwords\"],\n                                        !clientConfig.require_secure_passwords\n                                    )\n                                )\n                            }\n                        />\n                        <HelpLink\n                            inline\n                            url={`${window.location.origin}/docs/users/presenting-a-login-form#configuration-options`}\n                        />\n                        {/*TODO: Link to users_configuration help dialog*/}\n                        <div className={classes.description}>\n                            Prevent users from choosing passwords that are too short or that have been leaked online.\n                        </div>\n                    </div>\n                )}\n                <div className={classes.usersServiceOption}>\n                    <CheckBox\n                        text={\"Remember login between sessions\"}\n                        checked={clientConfig.allow_remember_me ?? false}\n                        onChange={toggleAllowRememberMe}\n                    />\n                    <div className={classes.description}>Users can choose \"Remember me\" when logging in.</div>\n                </div>\n                {clientConfig.allow_remember_me && (\n                    <div className={classes.usersServiceOption}>\n                        <CheckBox\n                            text={\"Share login status with other apps\"}\n                            checked={clientConfig.share_login_status ?? false}\n                            onChange={() =>\n                                dispatch(\n                                    updateUsersService(\n                                        [\"client_config\", \"share_login_status\"],\n                                        !clientConfig.share_login_status\n                                    )\n                                )\n                            }\n                        />\n                        <div className={classes.description}>\n                            Users logged into this app will automatically be logged in to other apps sharing the same\n                            'Users' table, if they also have this option enabled.\n                        </div>\n                    </div>\n                )}\n                {clientConfig.allow_remember_me && (\n                    <div className={classes.usersServiceOption}>\n                        Remember login state for:&nbsp;\n                        <ContentDropdownMenuItem\n                            value={clientConfig.remember_me_days ?? 30}\n                            onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>\n                                dispatch(\n                                    updateUsersService(\n                                        [\"client_config\", \"remember_me_days\"],\n                                        parseFloat(e.target.value)\n                                    )\n                                )\n                            }>\n                            <option value={0.02083}>30 minutes</option>\n                            <option value={0.3333}>8 hours</option>\n                            <option value={1}>24 hours</option>\n                            <option value={7}>7 days</option>\n                            <option value={30}>30 days</option>\n                            <option value={365}>1 year</option>\n                        </ContentDropdownMenuItem>\n                    </div>\n                )}\n\n                <div>\n                    <div className={classes.usersServiceOption}>\n                        <CheckBox\n                            text={\"Require 2-factor authentication\"}\n                            checked={clientConfig.require_mfa ?? false}\n                            onChange={toggleRequireMfa}\n                        />\n                        <div className={classes.description}>\n                            Users must use a hardware key or a TOTP code from an authenticator app to log in.\n                        </div>\n                    </div>\n                    {clientConfig.require_mfa && (\n                        <div className={classes.usersServiceOption}>\n                            <CheckBox\n                                text={\"Allow 2-factor reset by email\"}\n                                checked={clientConfig.allow_mfa_email_reset ?? false}\n                                onChange={() =>\n                                    dispatch(\n                                        updateUsersService(\n                                            [\"client_config\", \"allow_mfa_email_reset\"],\n                                            !clientConfig.allow_mfa_email_reset\n                                        )\n                                    )\n                                }\n                            />\n                            <div className={classes.description}>\n                                Users can reset their 2-factor authentication credentials by email.\n                            </div>\n                        </div>\n                    )}\n                    {clientConfig.require_mfa && (\n                        <div className={classes.usersServiceOption}>\n                            Remember 2-factor authentication state for:&nbsp;\n                            <ContentDropdownMenuItem\n                                value={clientConfig.mfa_timeout_days ?? 0}\n                                onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>\n                                    dispatch(\n                                        updateUsersService(\n                                            [\"client_config\", \"mfa_timeout_days\"],\n                                            parseFloat(e.target.value)\n                                        )\n                                    )\n                                }>\n                                <option value={0}>Disabled</option>\n                                <option value={0.02083}>30 minutes</option>\n                                <option value={1}>24 hours</option>\n                                <option value={7}>7 days</option>\n                                <option value={30}>30 days</option>\n                                <option value={365}>1 year</option>\n                            </ContentDropdownMenuItem>\n                        </div>\n                    )}\n                </div>\n            </div>\n            <h4 className={\"my-2 text-3xl font-medium\"}>New user registration:</h4>\n            <div>\n                <div className={classes.usersServiceOption}>\n                    <CheckBox\n                        text={\"Allow visitors to sign up\"}\n                        checked={clientConfig.allow_signup ?? false}\n                        onChange={() =>\n                            dispatch(updateUsersService([\"client_config\", \"allow_signup\"], !clientConfig.allow_signup))\n                        }\n                    />\n                    <div className={classes.description}>\n                        Users can create their own accounts. Otherwise, you need to create them manually.\n                    </div>\n                </div>\n                <div className={classes.usersServiceOption}>\n                    <CheckBox\n                        text={\"Confirm email address before users can log in\"}\n                        checked={clientConfig.confirm_email ?? false}\n                        onChange={() =>\n                            dispatch(\n                                updateUsersService([\"client_config\", \"confirm_email\"], !clientConfig.confirm_email)\n                            )\n                        }\n                    />\n                    <div className={classes.description}>\n                        Users need to confirm their email address by clicking a link before they can use their accounts.\n                    </div>\n                </div>\n                <div className={classes.usersServiceOption}>\n                    <CheckBox\n                        text={\"New user accounts can be used right away\"}\n                        checked={clientConfig.enable_automatically ?? false}\n                        onChange={() =>\n                            dispatch(\n                                updateUsersService(\n                                    [\"client_config\", \"enable_automatically\"],\n                                    !clientConfig.enable_automatically\n                                )\n                            )\n                        }\n                    />\n                    <div className={classes.description}>\n                        Users can log in as soon as they've registered. Otherwise, you must check the{\" \"}\n                        <code>enabled</code> box below before they can log in.\n                    </div>\n                </div>\n            </div>\n            <UserEmailTemplate />\n            <div className={classes.usersTable}>\n                <div className={classes.usersHeader}>\n                    <h2 className={\"my-10 text-5xl font-medium\"}>Users</h2>\n                </div>\n\n                <UserServiceTable />\n            </div>\n        </div>\n    );\n};\n\nconst connector = connect((state: State) => ({\n    usersService: getUsersService(state),\n    availableServices: getAllAvailableServices(state),\n    features: getFeatures(state),\n    subscription: getSubscription(state),\n}));\n\nexport default connector(UserServiceTab);\n\nconst UpgradePrompt = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const user = useSelector(getUser);\n    return (\n        <div className=\"text-danger\">\n            Custom notification emails are available on the{\" \"}\n            <LinkInternal onClick={() => dispatch(modal(\"upgradePrompt\", { featureId: \"custom-user-emails\" }))}>\n                {getPlanName(user.features[\"custom-user-emails\"].plan)} Plan and above\n            </LinkInternal>\n            . Settings in this section cannot be changed on the free plan.\n        </div>\n    );\n};\n\ntype ServiceEmailKey = keyof User[\"usersServiceEmails\"];\n\nexport const UserEmailTemplate = () => {\n    const usersService = useSelector(getUsersService);\n    const supportsCustomUserEmails = useFeatureSupported(\"custom-user-emails\");\n    const clientConfig: UsersClientConfig = usersService?.client_config ?? EmptyUsersClientConfig;\n    const serverConfig: UsersServerConfig = usersService?.server_config ?? EmptyUsersServerConfig;\n\n    const [isOpen, setOpen] = useState(false);\n\n    const [expandedKeys, setExpandedKeys] = useState<{ [key: string]: boolean }>({});\n\n    const items = useMemo(() => {\n        const emailTypes: { title: string; emailId: keyof User[\"usersServiceEmails\"]; description: string }[] = [];\n        if (!usersService?.client_config) return emailTypes;\n\n        if (clientConfig.confirm_email) {\n            emailTypes.push({\n                title: \"Email Confirmation\",\n                emailId: \"confirm_address\",\n                description: \"Sent when the user signs up, prompting them to confirm ownership of this email address\",\n            });\n        }\n        if (clientConfig.use_email) {\n            emailTypes.push({\n                title: \"Password Reset\",\n                emailId: \"reset_password\",\n                description: 'Sent when the user uses the \"Forgot Password\" feature',\n            });\n        }\n        if (clientConfig.require_mfa && clientConfig.allow_mfa_email_reset) {\n            emailTypes.push({\n                title: \"Two-Factor Reset\",\n                emailId: \"mfa_reset\",\n                description: \"Sent when the user requests a reset of their two-factor authentication method\",\n            });\n        }\n        if (clientConfig.use_token) {\n            emailTypes.push({\n                title: \"Email Login\",\n                emailId: \"token_login\",\n                description: 'Sent when the user requests login by email (\"magic link\")',\n            });\n        }\n        return emailTypes;\n    }, [clientConfig]);\n\n    const onToggle = useEvent(({ emailId }: { emailId: string }) => {\n        setExpandedKeys({ [emailId]: !expandedKeys[emailId] });\n    });\n\n    const [fromAddress, setFromAddress] = useState(serverConfig.email_from_address || \"\");\n    const updateFromAddress = useUpdateServerConfig([\"server_config\", \"email_from_address\"], fromAddress);\n\n    const onChangeFromAddress: React.ChangeEventHandler<HTMLInputElement> = useEvent((e) => {\n        const val = e.target.value;\n        setFromAddress(val);\n        updateFromAddress(val);\n    });\n    const disabled = !supportsCustomUserEmails;\n\n    return (\n        <Section\n            title={\"Configure emails from the Users Service\"}\n            expanded={isOpen}\n            onToggle={() => setOpen(!isOpen)}\n            className=\"mx-0! my-4!\">\n            {/* <Expander isOpen={isOpen}> */}\n            <div>\n                {disabled && <UpgradePrompt />}\n                <span>\n                    From address<i> - this will default to accounts@your-app-domain</i>\n                </span>\n                <ContentTextInput\n                    // text={\"Send Users Service emails from address:\"}\n                    disabled={disabled}\n                    type={\"text\"}\n                    value={fromAddress}\n                    className=\"mx-0 mt-4 mb-8\"\n                    placeholder={\"accounts@your-app-domain\"}\n                    onChange={onChangeFromAddress}\n                />\n            </div>\n            <Accordion\n                items={items}\n                onToggle={onToggle}\n                keyName=\"emailId\"\n                expandedKeys={expandedKeys}\n                headerStyle={{ height: \"4rem\" }}\n                renderHeader={({ title, description }) => <EmailEditorHeader description={description} title={title} />}\n                renderBody={({ emailId }) => <EmailEditor emailId={emailId} disabled={disabled} />}\n            />\n        </Section>\n    );\n};\n\n/**\n * path should not change when using this hook.\n */\nfunction useUpdateServerConfig(path: string[], currentVal: any) {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const onTextChange = (newVal: any) => {\n        if (newVal === currentVal) return;\n        if (newVal === \"\") {\n            // EmptyString - We can remove newVal from the config at the given path\n            newVal = undefined;\n        }\n        dispatch(updateUsersService(path, newVal));\n    };\n\n    return useEvent(onTextChange);\n}\n\ninterface EmailEditorHeaderProps {\n    title: string;\n    description: string;\n}\n\nconst EmailEditorHeader = ({ title, description }: EmailEditorHeaderProps) => {\n    return (\n        <div className=\"flex items-center\">\n            <Heading\n                title={title}\n                level={3}\n                className=\"mx-4! my-0! flex-1 overflow-hidden text-ellipsis whitespace-nowrap\">\n                {title}\n            </Heading>\n            <Text\n                title={description}\n                level={3}\n                className={\"mx-4! my-0! flex-6 overflow-hidden text-ellipsis whitespace-nowrap\"}>\n                {description}\n            </Text>\n        </div>\n    );\n};\n\nconst EMAIL_BODY_EDIT_OPTIONS = [\n    { title: \"Rich Text\", value: \"RICH\" },\n    { title: \"Html\", value: \"HTML\" },\n] as const;\n\ntype EditorType = (typeof EMAIL_BODY_EDIT_OPTIONS)[number][\"value\"];\n\nconst EmailEditor = ({ emailId, disabled }: { emailId: ServiceEmailKey; disabled?: boolean }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const userUiPrefs = useSelector(getUserUiPrefs);\n    const appName = useSelector(getAppName);\n    const usersService = useSelector(getUsersService);\n    const user = useSelector(getUser);\n    const { usersServiceEmails } = user;\n    const serverConfig: UsersServerConfig = usersService?.server_config ?? EmptyUsersServerConfig;\n\n    const thisEmailDefaults = usersServiceEmails?.[emailId];\n    const thisEmailContent = serverConfig.email_content?.[emailId];\n\n    const defaultSubject =\n        thisEmailDefaults?.subject ||\n        (thisEmailDefaults?.subject_suffix && `${appName} ${thisEmailDefaults?.subject_suffix}`) ||\n        \"\";\n    const defaultBody = thisEmailDefaults?.html || \"\";\n\n    const [emailSubject, setEmailSubject] = useState(thisEmailContent?.subject ?? defaultSubject);\n    const [emailBody, setEmailBody] = useState(thisEmailContent?.html ?? defaultBody);\n    const [htmlBody, setHtmlBody] = useState(thisEmailContent?.html ?? defaultBody);\n\n    const updateServerConfigSubject = useUpdateServerConfig(\n        [\"server_config\", \"email_content\", emailId, \"subject\"],\n        emailSubject\n    );\n\n    const updateServerConfigBody = useUpdateServerConfig(\n        [\"server_config\", \"email_content\", emailId, \"html\"],\n        emailBody\n    );\n\n    const onSubjectChange: React.ChangeEventHandler<HTMLInputElement> = useEvent((e) => {\n        const subject = e.target.value;\n        setEmailSubject(subject);\n        updateServerConfigSubject(subject);\n    });\n\n    const onResetSubject = useEvent(() => {\n        if (emailSubject !== defaultSubject) {\n            setEmailSubject(defaultSubject);\n            updateServerConfigSubject(\"\");\n        }\n    });\n\n    const onResetBody = useEvent(() => {\n        if (emailBody !== defaultBody) {\n            setEmailBody(defaultBody);\n            setHtmlBody(defaultBody);\n            updateServerConfigBody(\"\");\n        }\n    });\n\n    const htmlTimeout = useRef<undefined | number>(undefined);\n    const onHtmlChange = useEvent((body: string, source: string) => {\n        clearTimeout(htmlTimeout.current);\n        if (source === \"user\") {\n            htmlTimeout.current = setTimeout(() => {\n                flushSync(() => {\n                    const emptyPattern = /^(?:<p><br><\\/p>|<p><\\/p>)*$/;\n                    const htmlBody = body.replace(emptyPattern, \"\");\n                    updateServerConfigBody(htmlBody);\n                    setEmailBody(body);\n                    setHtmlBody(htmlBody);\n                });\n            }, 500);\n        }\n    });\n\n    const onChangeBody = useEvent((body: string) => {\n        setEmailBody(body);\n        setHtmlBody(body);\n        updateServerConfigBody(body);\n    });\n\n    const updateEmailDefaultEditor = (selected: EditorType) => {\n        dispatch(updateUserEditorPrefs(\"userServiceEmailEditor\", selected));\n    };\n\n    const editOption = userUiPrefs?.userServiceEmailEditor ?? \"RICH\";\n    const htmlEditor = editOption === \"HTML\";\n\n    return (\n        <div className=\"mx-8 my-4\">\n            <div className=\"grid grid-cols-[max-content_1fr] gap-4\">\n                <Heading level={3} className=\"m-auto! w-32\">\n                    Subject:\n                </Heading>\n\n                <div className=\"relative min-w-0\">\n                    <Button small className=\"absolute top-1/2 right-3 z-1 -translate-y-1/2\" onClick={onResetSubject}>\n                        Reset to Default\n                    </Button>\n                    <ContentTextInput\n                        type={\"text\"}\n                        disabled={disabled}\n                        value={emailSubject}\n                        // text={\"Subject:\"}\n                        placeholder={\"Enter a Subject\"}\n                        className=\"h-16! pl-3! text-xl!\"\n                        onChange={onSubjectChange}\n                    />\n                </div>\n\n                <div className=\"flex flex-col\">\n                    <Heading level={3} className=\"mt-4! w-32\">\n                        Body:\n                    </Heading>\n                </div>\n\n                <div className=\"relative h-128\">\n                    <div className=\"pointer-events-none absolute top-0 right-0 z-1 flex w-full gap-4 p-3.5\">\n                        {htmlEditor && <IconWithPreview className=\"pointer-events-auto\" emailBody={emailBody} />}\n                        <Button className=\"pointer-events-auto ml-auto\" small onClick={onResetBody}>\n                            Reset to Default\n                        </Button>\n                        <ButtonGroup\n                            small\n                            // @ts-ignore - todo Type ButtonGroup\n                            className=\"pointer-events-auto\"\n                            options={EMAIL_BODY_EDIT_OPTIONS}\n                            selectedVariant=\"primary\"\n                            selectedOption={editOption}\n                            // variant=\"outlined\"\n                            onClick={updateEmailDefaultEditor}\n                        />\n                    </div>\n                    {htmlEditor ? (\n                        <HtmlBodyEditor\n                            emailId={emailId}\n                            body={htmlBody}\n                            onChangeBody={onChangeBody}\n                            disabled={disabled}\n                        />\n                    ) : (\n                        <LexicalEditor\n                            className=\"flex h-full w-full flex-col\"\n                            disabled={disabled}\n                            HTML={emailBody}\n                            onHTMLChange={onHtmlChange}\n                            placeholder={\"Email body\"}\n                        />\n                    )}\n                </div>\n            </div>\n        </div>\n    );\n};\n\ninterface IconWithPreviewProps {\n    emailBody: string;\n    className?: string;\n}\n\nconst IconWithPreview: React.FC<IconWithPreviewProps> = ({ emailBody, className }) => {\n    const [isHovering, setIsHovering] = useState(false);\n\n    return (\n        <div\n            className={cx(\"min-w-0\", className)}\n            onMouseEnter={() => setIsHovering(true)}\n            onMouseLeave={() => setIsHovering(false)}>\n            <div className=\"relative\">\n                <Button small icon={faMagnifyingGlass}>\n                    Preview\n                </Button>\n                {isHovering && <EmailPreview emailBody={emailBody} />}\n            </div>\n        </div>\n    );\n};\n\ninterface EmailPreviewProps {\n    emailBody: string;\n}\n\nconst EmailPreview: React.FC<EmailPreviewProps> = ({ emailBody }) => {\n    const ref = useRef<HTMLDivElement>(null);\n    const shadowBodyRef = useRef<Element | null>(null);\n    const [scale, setScale] = useState(1);\n\n    useLayoutEffect(() => {\n        const el = ref.current;\n        if (!el) return;\n        const shadowRoot = el.shadowRoot ?? el.attachShadow({ mode: \"open\" });\n        shadowRoot.innerHTML = emailBody;\n        shadowBodyRef.current = shadowRoot.firstElementChild;\n    }, [emailBody]);\n\n    useResizeObserver(shadowBodyRef, () => {\n        const el = ref.current;\n        const shadowEl = shadowBodyRef.current;\n        if (!el || !shadowEl) return;\n        const { width } = shadowEl.getBoundingClientRect();\n        const scaleX = (scale * el.clientWidth) / width;\n        const newScale = Math.min(scaleX, 1);\n        setScale(newScale);\n    });\n\n    return (\n        <div className=\"absolute top-full left-0 z-3 flex max-h-120 w-max max-w-4xl overflow-auto rounded-md border border-sectionborder bg-white p-4 shadow-md dark:border-dark-sectionborder dark:bg-dark-bg1\">\n            <div\n                className=\"pointer-events-none min-h-0 min-w-0\"\n                style={{ transform: `scale(${scale})`, transformOrigin: \"top left\" }}\n                ref={ref}\n            />\n        </div>\n    );\n};\n","import { isEqual, union } from \"lodash-es\";\nimport { type FormFieldEdit, applyFormFields } from \"@/analysis/workspace-edits\";\nimport type { FormDesignItem, FormItemYaml } from \"@/types\";\n\n// snapshots shouldn't include the code object\n// they're part of a different editHistory object\n\ntype Listener = (this: EventEmitter, ...args: any[]) => void;\n\nconst EVENTS = Symbol();\n\nclass EventEmitter {\n    [EVENTS]: { [key: string]: Set<Listener> } = {};\n\n    on(event: string, listener: Listener) {\n        (this[EVENTS][event] ??= new Set()).add(listener);\n    }\n\n    removeListener(event: string, listener: Listener) {\n        this[EVENTS][event]?.delete(listener);\n    }\n\n    emit(event: string, ...args: any[]) {\n        for (const listener of this[EVENTS][event] ?? []) {\n            listener.apply(this, args);\n        }\n    }\n\n    once(event: string, listener: Listener) {\n        const g = (...args: any[]) => {\n            this.removeListener(event, g);\n            listener.apply(this, args);\n        };\n        this.on(event, g);\n    }\n}\n\nexport class HistoryState extends EventEmitter {\n    private renameBoundaries = new WeakMap<FormDesignItem, number>();\n    maxDepth = 100;\n    delay = 500;\n    constructor(\n        readonly current: FormItemYaml,\n        readonly done: FormDesignItem[],\n        readonly undone: FormDesignItem[],\n        public prevTime: number = 0\n    ) {\n        super();\n    }\n    takeSnapshot() {\n        const time = Date.now();\n        if (time - this.prevTime < this.delay) return false;\n        this.prevTime = time;\n        const cloned = this.snapshot();\n        if (!this.renameBoundary(\"before\") && isEqual(cloned, this.done.at(-1))) return false;\n        if (this.done.length < this.maxDepth) {\n            this.done.push(cloned);\n        } else {\n            this.done.shift();\n            this.done.push(cloned);\n        }\n        this.undone.length = 0;\n        this.emit(\"change\");\n        return true;\n    }\n\n    addRenameBoundary(id: number) {\n        if ([...this.done, ...this.undone].some((entry) => this.renameBoundaries.get(entry) === id)) return;\n        const snapshot = this.snapshot();\n        this.renameBoundaries.set(snapshot, id);\n        this.done.push(snapshot);\n        if (this.done.length > this.maxDepth) this.done.shift();\n        this.undone.length = 0;\n        this.prevTime = 0;\n        this.emit(\"change\");\n    }\n\n    mapRenameFields(fields: FormFieldEdit[], direction: \"before\" | \"after\") {\n        const path = fields[0]?.codePath;\n        if (!path) return;\n        // Ordinary Designer undo must not restore pre-rename references from older Form snapshots.\n        for (const snapshot of [...this.done, ...this.undone]) {\n            applyFormFields(new Map([[path, snapshot as FormItemYaml]]), fields, {\n                direction,\n                historicalSnapshot: true,\n            });\n        }\n    }\n\n    renameBoundary(direction: \"before\" | \"after\") {\n        const entry = (direction === \"before\" ? this.done : this.undone).at(-1);\n        return entry && this.renameBoundaries.get(entry);\n    }\n\n    moveRenameBoundary(id: number, direction: \"before\" | \"after\") {\n        if (this.renameBoundary(direction) !== id) return;\n        if (direction === \"before\") this.undo();\n        else this.redo();\n    }\n\n    snapshot() {\n        const clone = structuredClone(this.current);\n        // @ts-ignore\n        delete clone.code;\n        return clone as FormDesignItem;\n    }\n\n    canUndo() {\n        return !!this.done.length;\n    }\n\n    canRedo() {\n        return !!this.undone.length;\n    }\n\n    previousDesignState() {\n        return this.done.at(-1);\n    }\n\n    redo() {\n        if (this.undone.length === 0) return;\n        const prev = this.undone.pop()!;\n        const snapshot = this.snapshot();\n        const id = this.renameBoundaries.get(prev);\n        if (id) this.renameBoundaries.set(snapshot, id);\n        this.done.push(snapshot);\n        this.emit(\"change\");\n        return prev;\n    }\n\n    undo() {\n        if (this.done.length === 0) return;\n        const prev = this.done.pop()!;\n        const snapshot = this.snapshot();\n        const id = this.renameBoundaries.get(prev);\n        if (id) this.renameBoundaries.set(snapshot, id);\n        this.undone.push(snapshot);\n        this.emit(\"change\");\n        return prev;\n    }\n\n    mutate(state: FormDesignItem) {\n        const keys = Object.keys(this.current).filter((key) => key !== \"code\") as (keyof FormDesignItem)[];\n        const stateKeys = Object.keys(state) as (keyof FormDesignItem)[];\n\n        for (const key of union(keys, stateKeys)) {\n            if (!(key in state)) {\n                delete this.current[key];\n            } else {\n                (this.current as any)[key] = state[key];\n            }\n        }\n    }\n\n    toJSON() {\n        const ids = (entries: FormDesignItem[]) =>\n            Object.fromEntries(\n                entries.flatMap((entry, index) => {\n                    const id = this.renameBoundaries.get(entry);\n                    return id ? [[index, id]] : [];\n                })\n            );\n        return {\n            done: [...this.done],\n            undone: [...this.undone],\n            renameBoundaries: { done: ids(this.done), undone: ids(this.undone) },\n        };\n    }\n\n    static fromJSON(editingForm: FormItemYaml, json?: NonNullable<import(\"@/types\").EditHistory[\"design\"]>) {\n        const history = new HistoryState(\n            editingForm,\n            structuredClone(json?.done ?? []),\n            structuredClone(json?.undone ?? [])\n        );\n        for (const side of [\"done\", \"undone\"] as const) {\n            for (const [index, id] of Object.entries(json?.renameBoundaries?.[side] ?? {})) {\n                const entry = history[side][Number(index)];\n                if (entry) history.renameBoundaries.set(entry, id);\n            }\n        }\n        return history;\n    }\n}\n","import { useEffect, useId, useLayoutEffect, useState } from \"react\";\nimport { checkMeta, getRandomString, isMac } from \"@/util\";\nimport { ExternalStore, createExternalStoreHooks, useStoreSelector, useStoreState } from \"@/util/external-store\";\nimport useEvent from \"@/util/useEventCallback\";\n\nconst INIT_ID = getRandomString();\n\nconst INIT_STATE = {\n    canUndo() {\n        return false;\n    },\n    canRedo() {\n        return false;\n    },\n    undo() {}, // noop\n    redo() {}, // noop\n    id: INIT_ID,\n    lastUpdated: 0,\n};\n\ntype HistoryState = typeof INIT_STATE;\n\nclass HistoryStore extends ExternalStore<HistoryState> {\n    setState(state: Partial<HistoryState>) {\n        super.setState({ ...state, lastUpdated: Date.now() });\n    }\n    reset(id: string) {\n        if (id !== this.getState().id) return;\n        super.setState(INIT_STATE);\n    }\n    forceChange(id: string) {\n        if (id !== this.getState().id) return;\n        this.setState({});\n    }\n}\n\nconst historyStore = new HistoryStore(INIT_STATE);\n\nexport const { useStoreState: useHistoryStore, useStoreSelector: useHistoryStoreSelector } =\n    createExternalStoreHooks(historyStore);\n\nexport const useSetGlobalHistory = (\n    state: Omit<HistoryState, \"id\" | \"lastUpdated\">,\n    active = true,\n    deps: any[] = []\n) => {\n    const ID = useId();\n\n    const [hasFocus, setFocus] = useState(+active);\n\n    const onFocus = useEvent(() => setFocus((s) => (active ? ++s : 0)));\n    const updateHistory = useEvent(() => historyStore.forceChange(ID));\n    const canUndo = useEvent(state.canUndo);\n    const canRedo = useEvent(state.canRedo);\n    const undo = useEvent(state.undo);\n    const redo = useEvent(state.redo);\n\n    useLayoutEffect(onFocus, [active]);\n\n    useLayoutEffect(() => {\n        if (!hasFocus) {\n            historyStore.reset(ID);\n        } else {\n            historyStore.setState({ id: ID, canUndo, canRedo, undo, redo });\n        }\n    }, [hasFocus]);\n\n    useLayoutEffect(updateHistory, deps);\n\n    useEffect(() => () => historyStore.reset(ID), []);\n\n    return [updateHistory, onFocus] as const;\n};\n\nconst ELEMENTS_WITH_OWN_HISTORY = new Set([\"INPUT\", \"TEXTAREA\"]);\nconst hasOwnHistory = (target: HTMLElement | null) =>\n    target && (ELEMENTS_WITH_OWN_HISTORY.has(target.tagName) || target.isContentEditable);\n\nexport function useUndoRedoKeydown(undo: () => void, redo: () => void) {\n    const onUndo = useEvent(undo);\n    const onRedo = useEvent(redo);\n\n    return useEvent((e: React.KeyboardEvent | KeyboardEvent) => {\n        if (e.defaultPrevented) return;\n        const key = e.key;\n        if (key !== \"z\" && key !== \"y\") return;\n        if (!checkMeta(e)) return;\n        if (hasOwnHistory(e.target as HTMLElement | null)) return;\n        if (key === \"z\") {\n            e.preventDefault();\n            if (e.shiftKey) onRedo();\n            else onUndo();\n        } else if (key === \"y\" && !isMac && !e.shiftKey) {\n            e.preventDefault();\n            onRedo();\n        }\n    });\n}\n\nconst useUndo = () => useHistoryStoreSelector((state) => state.undo);\nconst useRedo = () => useHistoryStoreSelector((state) => state.redo);\n\nexport function useGlobalUndoRedo() {\n    const undo = useUndo();\n    const redo = useRedo();\n    const onMaybeUndoRedo = useUndoRedoKeydown(undo, redo);\n    useEffect(() => {\n        window.addEventListener(\"keydown\", onMaybeUndoRedo);\n        return () => {\n            window.removeEventListener(\"keydown\", onMaybeUndoRedo);\n        };\n    }, [onMaybeUndoRedo]);\n}\n","import React, { createContext, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useDispatch, useSelector, useStore } from \"react-redux\";\nimport { faPaperPlane } from \"@fortawesome/free-regular-svg-icons/faPaperPlane\";\nimport { faArrowUpFromSquare, faCode as faHtmlCode, faSidebar } from \"@fortawesome/pro-light-svg-icons\";\nimport { faBrowser } from \"@fortawesome/pro-light-svg-icons/faBrowser\";\nimport { faCheckSquare } from \"@fortawesome/pro-light-svg-icons/faCheckSquare\";\nimport { faObjectGroup } from \"@fortawesome/pro-light-svg-icons/faObjectGroup\";\nimport { faSquare } from \"@fortawesome/pro-light-svg-icons/faSquare\";\nimport { faAlignLeft } from \"@fortawesome/pro-regular-svg-icons/faAlignLeft\";\nimport { faColumns } from \"@fortawesome/pro-regular-svg-icons/faColumns\";\nimport { faRedo } from \"@fortawesome/pro-regular-svg-icons/faRedo\";\nimport { faUndo } from \"@fortawesome/pro-regular-svg-icons/faUndo\";\nimport { faCode, faEllipsisV } from \"@fortawesome/pro-solid-svg-icons\";\nimport { faCandleHolder } from \"@fortawesome/pro-solid-svg-icons/faCandleHolder\";\nimport { faChevronDown } from \"@fortawesome/pro-solid-svg-icons/faChevronDown\";\nimport { faPlus } from \"@fortawesome/pro-solid-svg-icons/faPlus\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { defaults, isUndefined, omitBy } from \"lodash-es\";\nimport { Breadcrumb, CreatingObject, EditPath } from \"@designer/shared-types\";\nimport { CodeToolsButton, CodeToolsPane } from \"@/analysis/CodeToolsPane\";\nimport { codeToolsPane as codeToolsState } from \"@/analysis/code-tools-state\";\nimport { getTyAnalysisEnabled } from \"@/analysis/ide-analysis\";\nimport { pythonCodeMenuItems } from \"@/code_mirror/PythonCodeMenu\";\nimport { JumpRequest, jumpRequestAtom } from \"@/code_mirror/utils/method_finder\";\nimport MobileFormToolbar from \"@/components/mobile-ide/MobileFormToolbar\";\nimport { Button } from \"@/components/reusable/Button\";\nimport DropdownMenu, { MenuItem } from \"@/components/reusable/DropdownMenu\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { useTooltip } from \"@/components/reusable/Tooltip.tsx\";\nimport { useFileDragOverNewFormEditor } from \"@/components/sidebar/CodeNavDragging\";\nimport CodeSnippets, { SnippetState } from \"@/components/tabs/code/CodeSnippets\";\nimport { cacheView, getAppId, getAppRuntimeVersion, migrateToRuntimeV3 } from \"@/controllers/app\";\nimport {\n    notifyUpdatedCodeItem,\n    syncHtmlFormAfterDesignerMutation,\n    toggleIsLayout,\n    useUpdateCustomComponent,\n} from \"@/controllers/app/code\";\nimport { componentYamlTypesReferToSameForm } from \"@/controllers/app/form-spec-readers\";\nimport {\n    getAllCustomLayouts,\n    getDesignerPanelDocked,\n    navigateToEditingForm,\n    setDesignerPanelDocked,\n    setPanelSectionExpanded,\n} from \"@/controllers/designer\";\nimport { setSplitCodeEditorRatio } from \"@/controllers/ide\";\nimport { getInTutorialMode, resetTutorial } from \"@/controllers/ideTutorial\";\nimport type { tutorialStepKeys } from \"@/controllers/ideTutorial\";\nimport { modal } from \"@/controllers/modals\";\nimport { getRunMode } from \"@/controllers/runner\";\nimport { updateCodeTabPrefs, useWrapWithPersistTab } from \"@/controllers/tabs\";\nimport { getUserTabSize } from \"@/controllers/user\";\nimport { getIsPySpace, recordActivity } from \"@/controllers/util\";\nimport { darkIcons, icons, useComponentIconSrc } from \"@/data/componentIcons\";\nimport { navigate } from \"@/router/navigation\";\nimport { useMinPixelsToSplit, useRemToPixels } from \"@/theme/ThemeProvider\";\nimport { cx, useIsDark } from \"@/theme/styles\";\nimport { AnvilDispatch, CodePath, Conflicts, EditHistory, FormItemYaml, FormTab, FullView, State } from \"@/types\";\nimport { EMPTY_ARRAY } from \"@/util\";\nimport { useExternalState } from \"@/util/external-state\";\nimport { ExternalStore, useStoreSelector } from \"@/util/external-store\";\nimport { createContextHook, useMemoiseObject, useResizeObserver, useStateWithCustomUpdate } from \"@/util/hooks\";\nimport { ImageWithRetry } from \"@/util/hooks/assets\";\nimport { useIsSmallScreen } from \"@/util/hooks/use-media-query\";\nimport { useIsMobileIde } from \"@/util/hooks/use-mobile-ide\";\nimport useEvent from \"@/util/useEventCallback\";\nimport TabToolbar from \"../TabToolbar\";\nimport { ConflictNavigator } from \"./ConflictNavigator\";\nimport Designer from \"./Designer\";\nimport { FormFormatButton } from \"./FormFormatButton\";\nimport { useHistoryStore } from \"./History\";\nimport { useEditHtmlTemplateHtmlProperty } from \"./designer/features/use-edit-html\";\nimport { ShortClassName } from \"./designer/helpers\";\nimport { RpcContext, useRpcContext, useRpcState, useRpcView } from \"./designer/rpc\";\nimport { useFormEditorUsage } from \"./useFormEditorUsage\";\nimport {\n    DEFAULT_VIEW,\n    FormEditorViewPreset,\n    SingleFormEditorViewMode,\n    VIEW_PRESETS,\n    createPresetView,\n    createSingleView,\n    getNumViews,\n    getPreferredSingleViewMode,\n    normalizeFormEditorView,\n    useEnsureFormEditorViewNormalized,\n    viewMatchesPreset,\n    viewMatchesSingleMode,\n} from \"./useViewModes\";\n\nconst FORM_EDITOR_VIEW_CONTROLS_MIN_WIDTH_REM = 85;\n\nconst BreadcrumbNavLink = ({ b }: { b: Breadcrumb[number] }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { topLevelFormClassName, tab } = useFormEditorContext();\n    const onClick = useEvent(() => {\n        dispatch(navigateToEditingForm(topLevelFormClassName, b.editPath, b.className, tab));\n    });\n\n    return (\n        <LinkInternal className=\"px-2 font-mono font-semibold\" onClick={onClick}>\n            <ShortClassName fullName={b.className} />\n        </LinkInternal>\n    );\n};\n\nconst BreadcrumbNav = () => {\n    const rpc = useRpcContext();\n    let breadcrumb = useRpcState(rpc, \"breadcrumb\");\n    const { selectedBreadcrumbRef, hiddenDesigner } = useFormEditorContext();\n\n    if (hiddenDesigner) {\n        // if we're not in design view then only show ourselves in the breadcrumb\n        breadcrumb = breadcrumb.length ? [breadcrumb.at(-1)!] : [];\n    }\n\n    return (\n        <div className=\"flex min-w-0 gap-4 overflow-x-auto\">\n            <div className={cx(\"dark:text-white\")}>\n                {breadcrumb.map((b, i) => (\n                    <React.Fragment key={i}>\n                        {i > 0 && <span className=\"\">/</span>}\n                        {i < breadcrumb.length - 1 ? (\n                            <BreadcrumbNavLink b={b} />\n                        ) : (\n                            <ShortClassName fullName={b.className} className={\"px-2 font-mono font-bold\"} />\n                        )}\n                    </React.Fragment>\n                ))}\n            </div>\n            <div className={cx(\"dark:text-white\", { invisible: hiddenDesigner })} ref={selectedBreadcrumbRef} />\n        </div>\n    );\n};\n\nconst useUndoRedo = () => {\n    const historyStore = useHistoryStore();\n\n    const onUndo = useEvent(() => {\n        historyStore.undo();\n    });\n\n    const onRedo = useEvent(() => {\n        historyStore.redo();\n    });\n\n    const [canRedo, setCanRedo] = useState(false);\n    const [canUndo, setCanUndo] = useState(false);\n\n    useLayoutEffect(() => {\n        setCanRedo(historyStore.canRedo());\n        setCanUndo(historyStore.canUndo());\n    }, [historyStore.lastUpdated]);\n\n    return { canUndo, canRedo, onUndo, onRedo };\n};\n\ninterface NewFormEditorProps {\n    tab: FormTab;\n    selected: boolean;\n    form: FormItemYaml;\n    conflicts?: Conflicts;\n    editHistory: EditHistory;\n    view?: FullView;\n}\n\nexport type FormHtmlPropertyType = null | { type: \"inline\" } | { type: \"asset\"; asset: string };\ntype CreatingObjectGrabPosition = { x: number | null; y: number | null };\n\n/**\n * Controls how an HTML form is synchronized after in-memory YAML changes.\n *\n * By default this only updates `serialized_html`, which keeps the HTML editor\n * current after property, event, and data-binding changes. With\n * `structural: true`, serialization may also reparse and canonicalize container\n * HTML, components, and slots after structural designer actions.\n */\nexport interface HtmlFormMutationSyncOptions {\n    /** The mutation may affect structure, such as changes that require dropzones to be reparsed and cleaned up. */\n    structural?: boolean;\n    /** Force a designer refresh even if the sync reports no structural change. */\n    forceRefresh?: boolean;\n    debugContext?: {\n        operation?: string;\n        eventContext?: unknown;\n        afterMutationState?: unknown;\n    };\n}\n\nexport type SyncHtmlFormAfterMutation = (options?: HtmlFormMutationSyncOptions) => Promise<void>;\n\nexport interface FormEditorContextData {\n    tab: FormTab;\n    topLevelFormClassName: string;\n    editPath: EditPath;\n    editingForm: FormItemYaml;\n    editingFormClassName: string;\n    editingFormCodePath: CodePath;\n    creatingObject: CreatingObject | null;\n    setCreatingObject: (creatingObject: CreatingObject | null, grabPosition?: CreatingObjectGrabPosition) => void;\n    setFormHtmlPropertyType: React.Dispatch<React.SetStateAction<FormHtmlPropertyType>>;\n    onSetHtmlView: (show: boolean) => void;\n    onSetHtmlPropertyView: (show: boolean) => void;\n    onRequestJumpToCode: (jumpRequest: Omit<JumpRequest, \"navTarget\">) => void;\n    requestReload: number;\n    selectedBreadcrumbRef: React.MutableRefObject<HTMLDivElement | null>;\n    displaySidePanels: boolean;\n    showOverlayPanel: null | \"toolbox\" | \"properties\";\n    setShowOverlayPanel: (showOverlayPanel: null | \"toolbox\" | \"properties\") => void;\n    inSplitView: boolean;\n    preventDocking: boolean;\n    hiddenDesigner: boolean;\n    allowSlots: boolean;\n    designerOverlayDiv: React.MutableRefObject<HTMLDivElement | null>;\n    snippetState: SnippetState;\n    setSnippetState: React.Dispatch<React.SetStateAction<SnippetState>>;\n    bindingView: undefined | string | false;\n    resetBindingView: () => void;\n    grabbingFile: boolean;\n    draggingFileDropRef: React.RefCallback<HTMLElement | null>;\n    syncHtmlFormAfterMutation: SyncHtmlFormAfterMutation;\n    preferSingleSections: boolean;\n    setPreferSingleSections: React.Dispatch<React.SetStateAction<boolean>>;\n    skinnySidePanel: boolean;\n    setSkinnySidePanel: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\nexport const FormEditorContext = createContext<FormEditorContextData | null>(null);\n\nexport const useFormEditorContext = createContextHook(FormEditorContext, \"FormEditor\");\n\nexport const missingFormClasses = new ExternalStore<Record<CodePath, boolean>>({});\n\nexport const GrabComponentPortal = ({\n    creatingObject,\n    initialX,\n    initialY,\n}: {\n    creatingObject: CreatingObject;\n    initialX: number | null;\n    initialY: number | null;\n}) => {\n    const [mousePosition, setMousePosition] = useState<{ x: number | null; y: number | null }>({\n        x: initialX,\n        y: initialY,\n    });\n\n    useLayoutEffect(() => {\n        const updateMousePosition = (e: MouseEvent | PointerEvent) => {\n            setMousePosition({ x: e.clientX, y: e.clientY });\n        };\n        document.addEventListener(\"pointermove\", updateMousePosition);\n        document.addEventListener(\"mousemove\", updateMousePosition);\n        return () => {\n            document.removeEventListener(\"pointermove\", updateMousePosition);\n            document.removeEventListener(\"mousemove\", updateMousePosition);\n        };\n    }, []);\n\n    const top = mousePosition.y === null ? null : mousePosition.y + 5;\n    const left = mousePosition.x === null ? null : mousePosition.x + 5;\n    const rpc = useRpcContext();\n\n    useEffect(() => {\n        rpc.raiseEvent(\"setPropagateMouseEvents\", true);\n        return () => {\n            rpc.raiseEvent(\"setPropagateMouseEvents\", false);\n        };\n    }, [rpc]);\n\n    const preview =\n        creatingObject.type === \"component\"\n            ? creatingObject.toolboxItem\n            : {\n                  icon: { light: icons[\"LayoutSlot\"], dark: darkIcons[\"LayoutSlot\"] },\n                  title: \"Slot\",\n                  slot: true as const,\n              };\n    const previewSrc = useComponentIconSrc(preview);\n\n    return (\n        top !== null &&\n        left !== null &&\n        createPortal(\n            <div\n                style={{ top: top, left: left }}\n                className={\n                    \"pointer-events-none fixed top-0 left-0 z-[2000] grid h-fit w-fit min-w-[98px] items-center justify-center gap-4 rounded-lg border-2 border-sectionborder bg-light-bg2 p-2 opacity-50\"\n                }>\n                <ImageWithRetry className=\"m-auto h-[30px] w-[30px] rounded-lg\" src={previewSrc} visible={true} />\n                <p className={\"text-xl\"}>{preview.title}</p>\n            </div>,\n            document.body\n        )\n    );\n};\n\nconst NewFormEditor = ({\n    tab,\n    selected,\n    form,\n    conflicts,\n    view: requestedView = DEFAULT_VIEW,\n    editHistory,\n}: NewFormEditorProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const runtimeVersion = useSelector(getAppRuntimeVersion);\n    const analysisEnabled = useSelector(getTyAnalysisEnabled);\n    const appId = useSelector(getAppId);\n    const [codeToolsPane, setCodeToolsPane] = useExternalState(codeToolsState);\n    const [codeToolsContainer, setCodeToolsContainer] = useState<HTMLDivElement | null>(null);\n    const customLayouts = useSelector(getAllCustomLayouts);\n    const appConfig = useSelector((state: State) => state.app?.config);\n    const dependencyCode = useSelector((state: State) => state.app?.dependencyCode);\n    const designerPanelDocked = useSelector(getDesignerPanelDocked);\n    const preventDocking = useSelector<State, boolean>((state) => getRunMode(state) === \"INLINE\");\n    const isPySpace = useSelector(getIsPySpace);\n    const inTutorialMode = useSelector(getInTutorialMode);\n\n    const topLevelFormClassName = tab.navTarget.topLevelFormClassName || form.class_name;\n    const rpc = useRpcView(tab, selected, form);\n    const isDark = useIsDark();\n    //const canUseClassic = !isPySpace && runtimeVersion < 3;\n    const canUseClassic = false;\n    const splitMinWidth = useMinPixelsToSplit();\n    const viewControlsMinWidth = useRemToPixels(FORM_EDITOR_VIEW_CONTROLS_MIN_WIDTH_REM);\n    const isSmallScreen = useIsSmallScreen();\n    const isMobileIde = useIsMobileIde();\n    const canUseSplitView = !isSmallScreen;\n    const formEditorRef = useRef<HTMLDivElement>(null);\n    const rightToolbarControlsRef = useRef<HTMLDivElement>(null);\n    const [viewControlsAreNarrow, setViewControlsAreNarrow] = useState(false);\n    const updateViewControlsWidth = useEvent(() => {\n        const formEditor = formEditorRef.current;\n        if (!formEditor) return;\n        const rightToolbarControlsWidth = rightToolbarControlsRef.current?.offsetWidth ?? 0;\n        setViewControlsAreNarrow(formEditor.offsetWidth - rightToolbarControlsWidth < viewControlsMinWidth);\n    });\n\n    useLayoutEffect(() => {\n        updateViewControlsWidth();\n    }, [updateViewControlsWidth, viewControlsMinWidth]);\n    useResizeObserver(formEditorRef, updateViewControlsWidth);\n    useResizeObserver(rightToolbarControlsRef, updateViewControlsWidth);\n\n    const useCompactViewControls = !canUseSplitView || viewControlsAreNarrow;\n\n    const [requestReload, setRequestReload] = useState<number>(0);\n\n    const [jumpRequest, setJumpRequest] = useExternalState(jumpRequestAtom);\n    const onRequestJumpToCode = useEvent((jumpRequest: Omit<JumpRequest, \"navTarget\">) => {\n        setJumpRequest({ ...jumpRequest, navTarget: tab.navTarget });\n        if (!canUseSplitView || (formEditorRef?.current?.offsetWidth || 0) < splitMinWidth) {\n            setView(\n                {\n                    ...view,\n                    design: false,\n                    code: view.code || lastCodeView || true,\n                    html: false,\n                    htmlProperty: false,\n                    focus: \"code\",\n                },\n                false\n            );\n        } else {\n            if (!view.code) {\n                setView(\n                    {\n                        ...view,\n                        design: true,\n                        code: view.code || lastCodeView || true,\n                        html: false,\n                        htmlProperty: false,\n                    },\n                    false\n                );\n            }\n        }\n    });\n\n    const { showCodeSnippets, showDesignerToolbox } = tab?.codeTabPrefs || {};\n    const [showSnippetOverlay, setShowSnippetOverlay] = useState(false);\n\n    const [propertiesPanelTooltip, propertiesPanelTooltipRef] = useTooltip(\n        `${designerPanelDocked ? \"Hide\" : \"Show\"} Properties Panel`,\n        \"left\"\n    );\n    const [codeSnippetsTooltip, codeSnippetsTooltipRef] = useTooltip(\n        `${preventDocking ? \"View\" : showCodeSnippets ? \"Hide\" : \"Show\"} Code Snippets`,\n        \"left\"\n    );\n\n    // TODO - will need to depend on client width\n    const [lastCodeView, setLastCodeView] = useState(requestedView.code);\n    const wrapWithPersist = useWrapWithPersistTab(tab);\n    const store = useStore<State>();\n\n    // CodeTab component is responsible for passing us the form to us\n    // if the topLevel class_name changes this component will be re-rendered (the tab is keyed by the tab.codePath)\n    const editingFormCodePath = useRpcState(rpc, \"editingFormCodePath\");\n    const editingForm = useRpcState(rpc, \"editingForm\") ?? form;\n    const editingFormClassName = useRpcState(rpc, \"editingFormClassName\");\n    const syncHtmlFormAfterMutation: SyncHtmlFormAfterMutation = useEvent(async (options = {}) => {\n        const result = syncHtmlFormAfterDesignerMutation(editingForm, store.getState(), {\n            debugContext: { codePath: editingFormCodePath, ...options.debugContext },\n            structural: options.structural === true,\n        });\n        dispatch(notifyUpdatedCodeItem(editingFormCodePath, null));\n        if (result.structuralHtmlChanged || options.forceRefresh) {\n            await rpc.call(\"refreshEditingForm\");\n        }\n    });\n    const [formHtmlPropertyType, setFormHtmlPropertyType] = useEditHtmlTemplateHtmlProperty(editingForm);\n\n    const htmlPropertyAvailable = !!formHtmlPropertyType;\n    const lastCodeViewBool = typeof lastCodeView === \"boolean\" ? lastCodeView : Boolean(lastCodeView);\n    const codeView = requestedView.code || lastCodeViewBool || true;\n    // Navigation can request a desktop split. Never render that split in a narrow viewport,\n    // even for the render before the normalization effect updates the tab.\n    const view = canUseSplitView\n        ? requestedView\n        : normalizeFormEditorView({\n              currentView: requestedView,\n              nextView: requestedView,\n              canUseSplitView: false,\n              codeView,\n              htmlPropertyAvailable,\n          });\n\n    const designerOverlayDiv = useRef<HTMLDivElement>(null);\n\n    const setView = wrapWithPersist(\n        useEvent((newView: FullView, saveToCache = true) => {\n            newView = normalizeFormEditorView({\n                currentView: view,\n                nextView: newView,\n                codeView,\n                canUseSplitView,\n                htmlPropertyAvailable,\n            });\n            if (newView.html && !view.html) {\n                dispatch(\n                    recordActivity(\"openHtmlFormTemplate\", {\n                        codePath: editingFormCodePath,\n                        className: editingForm.class_name,\n                        fileFormat: editingForm.save_as_html ? \"html\" : \"yaml\",\n                    })\n                );\n            }\n            if (canUseSplitView && getNumViews(view) <= 1 && getNumViews(newView) > 1) {\n                dispatch(setSplitCodeEditorRatio(0.5));\n            }\n            if (saveToCache) {\n                const viewToCache = { ...newView };\n                queueMicrotask(() => dispatch(cacheView(tab.navTarget.codePath, viewToCache)));\n            }\n            setLastCodeView(view.code || lastCodeView);\n            dispatch(\n                navigate({ ...tab.navTarget, view: newView, essentialView: undefined, refocusView: Math.random() })\n            );\n            if (selected && newView.design && getNumViews(newView, \"design\") === 0) {\n                queueMicrotask(() => designerOverlayDiv.current?.focus());\n            }\n        })\n    );\n\n    const setSingleViewMode = useEvent((mode: SingleFormEditorViewMode, saveToCache = true) => {\n        setShowOverlayPanel(null);\n        setView(createSingleView(mode, codeView), saveToCache);\n    });\n\n    const setPresetView = useEvent((preset: FormEditorViewPreset, saveToCache = true) => {\n        setShowOverlayPanel(null);\n        setView(createPresetView(view, preset, codeView), saveToCache);\n    });\n\n    const toggleViewMode = useEvent((mode: \"design\" | \"code\" | \"html\", saveToCache = true) => {\n        setShowOverlayPanel(null);\n        if (view[mode]) {\n            if (getNumViews(view) === 1) return;\n            const nextView = { ...view, [mode]: false } as FullView;\n            if (nextView.focus === mode) {\n                nextView.focus = getPreferredSingleViewMode(nextView, htmlPropertyAvailable);\n            }\n            setView(nextView, saveToCache);\n            return;\n        }\n\n        const nextView = { ...view, [mode]: mode === \"code\" ? codeView : true, focus: mode } as FullView;\n        if (mode === \"html\") nextView.htmlProperty = false;\n        setView(nextView, saveToCache);\n    });\n\n    useEnsureFormEditorViewNormalized({\n        currentView: requestedView,\n        codeView,\n        canUseSplitView,\n        htmlPropertyAvailable,\n        setView,\n    });\n\n    const is3ViewMode = viewMatchesPreset(view, VIEW_PRESETS.designCodeHtml);\n\n    const formClassIsMissing = useStoreSelector(missingFormClasses, (s) => s[editingFormCodePath]);\n\n    const onSetHtmlView = useEvent((show: boolean, options?: { addToCurrentView?: boolean }) => {\n        //todo: maybe save this to cache\n        setShowOverlayPanel(null);\n        if (show) {\n            if (!canUseSplitView) {\n                setSingleViewMode(\"html\", false);\n                return;\n            }\n            setView(\n                { ...view, html: true, code: options?.addToCurrentView ? view.code : false, focus: \"html\" } as FullView,\n                false\n            );\n        } else {\n            // When disabling html, preserve focus if it's not html, otherwise clear it\n            const newView = { ...view, html: false };\n            if (view.focus === \"html\") {\n                delete (newView as FullView).focus;\n            }\n            setView(newView, false);\n        }\n    });\n\n    const onSetHtmlPropertyView = useEvent((show: boolean, options?: { addToCurrentView?: boolean }) => {\n        //todo: maybe save this to cache\n        setShowOverlayPanel(null);\n        if (show) {\n            if (!canUseSplitView) {\n                setSingleViewMode(\"htmlProperty\", false);\n                return;\n            }\n            setView(\n                {\n                    ...view,\n                    htmlProperty: true,\n                    code: options?.addToCurrentView ? view.code : false,\n                    focus: \"htmlProperty\",\n                } as FullView,\n                false\n            );\n        } else {\n            // When disabling htmlProperty, preserve focus if it's not htmlProperty, otherwise clear it\n            const newView = { ...view, htmlProperty: false };\n            setView(newView, false);\n        }\n    });\n\n    // reset the binding view only after we've focused the property editor\n    const bindingView =\n        view.design && Array.isArray(view.design) && view.design[0] === \"binding\" && typeof view.design[1] === \"string\"\n            ? view.design[1]\n            : false;\n    const resetBindingView = useEvent(() => {\n        if (!bindingView) return;\n        setView({ ...view, design: true, focus: \"design\" } as FullView, false);\n    });\n\n    const isReady = useRpcState(rpc, \"ready\");\n    const selectedObjects = useRpcState(rpc, \"selection\");\n\n    const bindingIsSelected = () => {\n        if (typeof bindingView !== \"string\") return false;\n        const [componentName, prop] = bindingView.split(\".\");\n        if (selectedObjects.length !== 1) return false;\n        const selectedObject = selectedObjects[0];\n        if (selectedObject.type !== \"component\") return false;\n        return selectedObject.data.name === componentName;\n    };\n\n    const [preferSingleSections, setPreferSingleSections] = useState(false);\n    const [skinnySidePanel, setSkinnySidePanel] = useState(false);\n\n    useEffect(() => {\n        if (typeof bindingView !== \"string\") return;\n        const [componentName, prop] = bindingView.split(\".\");\n        if (bindingIsSelected()) {\n            if (designerPanelDocked) {\n                dispatch(setPanelSectionExpanded(tab, \"properties\", true, preferSingleSections));\n            } else {\n                setShowOverlayPanel(\"properties\");\n            }\n        } else if (isReady) {\n            rpc.raiseEvent(\"select\", { type: \"component\", data: { name: componentName ?? \"\" } });\n        }\n    }, [bindingView, selectedObjects, editingForm, preferSingleSections]);\n\n    const [snippetState, setSnippetState] = useState<SnippetState>({\n        properties: {},\n        showAll: false,\n        expandedKeys: {},\n    });\n\n    // Use the editor usage hook\n    const {\n        moduleEditor,\n        codeEditorView,\n        htmlTemplateEditorView,\n        htmlPropertyEditorView,\n        htmlTemplateEditor,\n        htmlTemplateEditorResizePanel,\n        htmlPropertyEditor,\n        htmlPropertyEditorResizePanel,\n        combinedDesignRightPane,\n        codeViewSnippetPanel,\n    } = useFormEditorUsage({\n        tab,\n        selected,\n        view,\n        formEditorRef,\n        editingForm,\n        editingFormCodePath,\n        formHtmlPropertyType,\n        editHistory,\n        conflicts,\n        rpc,\n        is3ViewMode: is3ViewMode || false,\n    });\n\n    /** @todo - implement this */\n    const [darkMode, _setDarkMode] = useState(false);\n\n    const setDarkMode = useCallback(\n        (enableDarkMode: boolean) => {\n            _setDarkMode(enableDarkMode);\n            // @ts-ignore Not supported yet.\n            rpc.raiseEvent(\"enableDarkMode\", enableDarkMode);\n        },\n        [rpc]\n    );\n\n    const selectedBreadcrumbRef = useRef<HTMLDivElement | null>(null);\n\n    const [creatingObject, _setCreatingObject] = useState<null | CreatingObject>(null);\n    const [initialGrabPosition, setInitialGrabPosition] = useState<CreatingObjectGrabPosition>({ x: null, y: null });\n    const setCreatingObject = useCallback(\n        (object: CreatingObject | null, { x, y }: CreatingObjectGrabPosition = { x: null, y: null }) => {\n            setShowOverlayPanel(null);\n            _setCreatingObject(object);\n            // Slight hack to get this in there first, so that the drop zones are right in templates that dynamically size drop zones\n            rpc.raiseEvent(\"setHighlight\", !!object);\n            rpc.raiseEvent(\"setCreatingObject\", object);\n            setInitialGrabPosition({ x, y });\n        },\n        [rpc]\n    );\n\n    const onOpenCustomComponentModal = useEvent(() => {\n        dispatch(modal(\"customcomponent\", { codePath: editingFormCodePath }));\n    });\n\n    const updateCustomComponent = useUpdateCustomComponent(editingFormCodePath, editingForm, conflicts);\n\n    const onToggleCustomComponent = useEvent(() => {\n        if (editingForm) {\n            const isCustomComponent = editingForm.custom_component;\n            updateCustomComponent({ custom_component: !isCustomComponent }, \"Set custom component\");\n            // the above doesn't trigger a re-render but we need it to\n            rpc.raiseEvent(\"refreshEditingForm\");\n        }\n    });\n\n    const onToggleLayout = useEvent(async () => {\n        if (runtimeVersion < 3 && !(await dispatch(migrateToRuntimeV3(false)))) {\n            return;\n        }\n        if (editingForm) {\n            await dispatch(toggleIsLayout(editingFormCodePath, editingForm, !editingForm.slots));\n            // the above doesn't trigger a re-render but we need it to\n            rpc.raiseEvent(\"refreshEditingForm\");\n        }\n    });\n\n    const onChooseLayout = useEvent(async () => {\n        // dispatch(alert(\"Choose form layout\", \"Not yet implemented\")); // TODO: Implement this!\n        const result = await dispatch(\n            modal(\"chooseFormType\", {\n                layoutForFormClassName: form.class_name,\n                currentLayoutType: form.layout?.type,\n                currentLayout: form.layout,\n            })\n        );\n        if (result?.form.layout) {\n            const { form_event_bindings, properties, event_bindings } = editingForm?.layout ?? {};\n            const copyProps = omitBy({ form_event_bindings, properties, event_bindings }, isUndefined);\n\n            editingForm!.layout = defaults({}, result.form.layout, copyProps);\n            syncHtmlFormAfterMutation({\n                debugContext: {\n                    operation: \"designer.chooseLayout\",\n                    eventContext: { layout: result.form.layout },\n                    afterMutationState: editingForm,\n                },\n            });\n            setRequestReload((s) => s + 1);\n        }\n    });\n\n    const isTopLevel = topLevelFormClassName === form.class_name;\n\n    // Original style buttons will be created after numViews is calculated\n\n    const formMenuItems = useMemo<MenuItem[]>(() => {\n        const items: MenuItem[] = [];\n\n        if (editingForm.layout && !canUseClassic) {\n            items.push([\"Choose layout...\", wrapWithPersist(onChooseLayout), faBrowser], <hr />);\n        }\n\n        items.push(\n            [\"Use as layout\", wrapWithPersist(onToggleLayout), editingForm?.slots ? faCheckSquare : faSquare],\n            [\n                \"Use as custom component\",\n                wrapWithPersist(onToggleCustomComponent),\n                editingForm?.custom_component ? faCheckSquare : faSquare,\n            ],\n            <hr />,\n            [\"Edit properties and events...\", wrapWithPersist(onOpenCustomComponentModal), faObjectGroup]\n        );\n\n        // Edit HTML menu item: show if we have HTML property\n        if (formHtmlPropertyType) {\n            items.push([\"Edit HTML Property\", wrapWithPersist(() => onSetHtmlPropertyView(true)), faCode]);\n        }\n\n        if (!isTopLevel && view.design) {\n            items.push([\n                \"Switch to standalone view\",\n                wrapWithPersist(() => dispatch(navigateToEditingForm(form.class_name, [], form.class_name, tab))),\n                faArrowUpFromSquare,\n            ]);\n        }\n\n        return items;\n    }, [\n        canUseClassic,\n        dispatch,\n        editingForm,\n        editingForm?.custom_component,\n        editingForm?.slots,\n        form.class_name,\n        formHtmlPropertyType,\n        isTopLevel,\n        onChooseLayout,\n        onOpenCustomComponentModal,\n        onSetHtmlView,\n        onToggleCustomComponent,\n        onToggleLayout,\n        tab,\n        view,\n        wrapWithPersist,\n    ]);\n\n    const undoRedo = useUndoRedo();\n\n    const [showOverlayPanel, setShowOverlayPanel] = useStateWithCustomUpdate<null | \"toolbox\" | \"properties\">(\n        null,\n        (v) => {\n            if (v === null) {\n                // refocus the designerOverlay so that keyboard events work as expected\n                // only works if the mouseDown event handler called e.preventDefault();\n                designerOverlayDiv.current?.focus();\n            }\n            return v;\n        }\n    );\n\n    // If we are code only we may need the designer layer in order to find out which form we are editing\n    // only if we have an editPath and the breadcrumb doesn't exist\n\n    const hiddenDesigner = !view.design;\n    const numViews = getNumViews(view);\n    const inSplitView = numViews > 1;\n    const codeToolsOverlay = preventDocking || inSplitView || useCompactViewControls;\n    const showCodeOverlay =\n        selected &&\n        (analysisEnabled\n            ? codeToolsOverlay && codeToolsPane.appId === appId && codeToolsPane.open\n            : showSnippetOverlay);\n    const onCloseCodeOverlay = useEvent(() => {\n        if (analysisEnabled) setCodeToolsPane({ ...codeToolsPane, open: false });\n        else setShowSnippetOverlay(false);\n        codeEditorView?.focus();\n    });\n    // Keep the editor subscription while its contents move between the dock and overlay.\n    const codeToolsPanel = analysisEnabled && codeEditorView && !isPySpace && (\n        <CodeToolsPane\n            view={codeEditorView}\n            codePath={editingFormCodePath}\n            selected={selected}\n            form={editingForm}\n            docked={!codeToolsOverlay}\n            container={codeToolsContainer}\n        />\n    );\n    const designer = <Designer tab={tab} selected={selected} />;\n\n    const { splitViewMenuItems, isSplitPresetActive, viewMenuItems } = useMemo(() => {\n        let active = false;\n        const splitItem = (label: string, preset: FormEditorViewPreset): MenuItem => {\n            const selected = viewMatchesPreset(view, preset);\n            active ||= selected;\n            return [label, () => setPresetView(preset), selected ? faCheckSquare : faSquare];\n        };\n        const viewItem = (label: string, mode: SingleFormEditorViewMode): MenuItem => [\n            label,\n            () => setSingleViewMode(mode),\n            viewMatchesSingleMode(view, mode) ? faCheckSquare : faSquare,\n        ];\n\n        const splitItems: MenuItem[] = [splitItem(\"Design + Code\", VIEW_PRESETS.codeDesign)];\n\n        splitItems.push(\n            splitItem(\"Design + HTML\", VIEW_PRESETS.designHtml),\n            splitItem(\"Code + HTML\", VIEW_PRESETS.codeHtml),\n            splitItem(\"Design + Code + HTML\", VIEW_PRESETS.designCodeHtml)\n        );\n\n        if (htmlPropertyAvailable) {\n            splitItems.push(splitItem(\"Design + HTML Template\", VIEW_PRESETS.designHtmlTemplate));\n        }\n\n        const viewItems: MenuItem[] = [viewItem(\"Design\", \"design\"), viewItem(\"Code\", \"code\")];\n\n        viewItems.push(viewItem(\"HTML\", \"html\"));\n\n        if (htmlPropertyAvailable) {\n            viewItems.push(viewItem(\"HTML Template\", \"htmlProperty\"));\n        }\n\n        return {\n            splitViewMenuItems: splitItems,\n            isSplitPresetActive: active,\n            viewMenuItems: viewItems,\n        };\n    }, [htmlPropertyAvailable, view]);\n\n    const compactViewMenuItems: MenuItem[] = canUseSplitView\n        ? [...viewMenuItems, <hr />, ...splitViewMenuItems]\n        : viewMenuItems;\n\n    // We are fairly sure customLayouts is the list of all the layouts since even those in code will be registered with\n    // IDE, but if this isn't true then we will have to show the invalid layouts banner only when the form actually\n    // fails to instantiate... but that's more troublesome to do so we'll cross that bridge if we get there.\n    const isValidCustomLayout = useMemo(() => {\n        const type = form.layout?.type;\n        if (form.layout === undefined) {\n            return true;\n        }\n        return customLayouts.some(({ layout }) =>\n            componentYamlTypesReferToSameForm(type, layout.type, {\n                appPackageName: appConfig?.package_name,\n                dependencies: appConfig?.dependencies,\n                dependencyIds: appConfig?.dependency_ids,\n                dependencyCode,\n            })\n        );\n    }, [appConfig, customLayouts, dependencyCode, form.layout]);\n\n    const [{ isOver: grabbingFile }, draggingFileDropRef] = useFileDragOverNewFormEditor(rpc, {\n        setCreatingObject,\n        creatingObject,\n    });\n\n    const formEditorContext = useMemoiseObject<FormEditorContextData>({\n        tab,\n        topLevelFormClassName,\n        editPath: tab.navTarget.editingPath || (EMPTY_ARRAY as unknown as EditPath),\n        editingForm,\n        editingFormClassName,\n        editingFormCodePath,\n        creatingObject,\n        setCreatingObject,\n        setFormHtmlPropertyType,\n        onSetHtmlView,\n        onSetHtmlPropertyView,\n        onRequestJumpToCode,\n        requestReload,\n        selectedBreadcrumbRef,\n        displaySidePanels: designerPanelDocked && !isMobileIde,\n        showOverlayPanel,\n        setShowOverlayPanel,\n        inSplitView,\n        preventDocking,\n        hiddenDesigner,\n        allowSlots: !canUseClassic && !!editingForm?.slots,\n        designerOverlayDiv,\n        snippetState,\n        setSnippetState,\n        bindingView,\n        resetBindingView,\n        grabbingFile,\n        draggingFileDropRef,\n        syncHtmlFormAfterMutation,\n        preferSingleSections,\n        setPreferSingleSections,\n        skinnySidePanel,\n        setSkinnySidePanel,\n    });\n\n    useEffect(() => {\n        if (isPySpace) dispatch(setDesignerPanelDocked(true));\n    }, [isPySpace]);\n\n    return (\n        <FormEditorContext.Provider value={formEditorContext}>\n            <RpcContext.Provider value={rpc}>\n                {selected && creatingObject && !grabbingFile && (\n                    <GrabComponentPortal\n                        creatingObject={creatingObject}\n                        initialX={initialGrabPosition.x}\n                        initialY={initialGrabPosition.y}\n                    />\n                )}\n                <div\n                    ref={formEditorRef}\n                    className={cx(\"flex h-full min-w-0 flex-col overflow-hidden\", creatingObject && \"!cursor-grabbing\")}\n                    onKeyDown={(event) => {\n                        if (showCodeOverlay && event.key === \"Escape\" && !event.defaultPrevented) {\n                            event.preventDefault();\n                            onCloseCodeOverlay();\n                        }\n                    }}>\n                    {isMobileIde && selected && (\n                        <MobileFormToolbar\n                            viewMode={getPreferredSingleViewMode(view, htmlPropertyAvailable)}\n                            htmlPropertyAvailable={htmlPropertyAvailable}\n                            setViewMode={setSingleViewMode}\n                            showToolbox={showOverlayPanel === \"toolbox\"}\n                            toggleToolbox={() => {\n                                setCreatingObject(null);\n                                setShowOverlayPanel(showOverlayPanel === \"toolbox\" ? null : \"toolbox\");\n                            }}\n                            undoRedo={undoRedo}\n                            formMenuItems={formMenuItems}\n                            codeMenuItems={\n                                view.code && codeEditorView\n                                    ? pythonCodeMenuItems(codeEditorView, { isForm: true })\n                                    : undefined\n                            }\n                        />\n                    )}\n                    {!isPySpace && !isMobileIde && (\n                        <TabToolbar className={cx(\"flex justify-between! gap-4\")}>\n                            <div className={cx(\"flex min-w-0\", \"gap-4\")}>\n                                {!isPySpace && (\n                                    <>\n                                        {useCompactViewControls ? (\n                                            <DropdownMenu\n                                                render={(showMenu: any, anchor: any) => (\n                                                    <div>\n                                                        <Button\n                                                            size={\"small\"}\n                                                            variant={\"highlight2\"}\n                                                            onClick={(e) => showMenu(null, e.currentTarget)}>\n                                                            View\n                                                            <FontAwesomeIcon className={\"ml-2\"} icon={faChevronDown} />\n                                                        </Button>\n                                                        {anchor}\n                                                    </div>\n                                                )}\n                                                align={\"left\"}\n                                                items={() => compactViewMenuItems}\n                                            />\n                                        ) : (\n                                            <>\n                                                <Button\n                                                    size={\"small\"}\n                                                    variant={view.design ? \"highlight2\" : \"outlined\"}\n                                                    aria-pressed={Boolean(view.design)}\n                                                    title=\"Shift-click to toggle this view\"\n                                                    titlePosition=\"bottom\"\n                                                    titleDelay\n                                                    onClick={(e) =>\n                                                        e.shiftKey\n                                                            ? toggleViewMode(\"design\")\n                                                            : setPresetView(VIEW_PRESETS.design)\n                                                    }\n                                                    icon={faPaperPlane}>\n                                                    Design\n                                                </Button>\n                                                <Button\n                                                    size={\"small\"}\n                                                    variant={view.code ? \"highlight2\" : \"outlined\"}\n                                                    aria-pressed={Boolean(view.code)}\n                                                    title=\"Shift-click to toggle this view\"\n                                                    titlePosition=\"bottom\"\n                                                    titleDelay\n                                                    onClick={(e) =>\n                                                        e.shiftKey\n                                                            ? toggleViewMode(\"code\")\n                                                            : setPresetView(VIEW_PRESETS.code)\n                                                    }\n                                                    icon={faAlignLeft}>\n                                                    Code\n                                                </Button>\n                                                <Button\n                                                    size={\"small\"}\n                                                    variant={view.html ? \"highlight2\" : \"outlined\"}\n                                                    aria-pressed={Boolean(view.html)}\n                                                    title=\"Shift-click to toggle this view\"\n                                                    titlePosition=\"bottom\"\n                                                    titleDelay\n                                                    onClick={(e) =>\n                                                        e.shiftKey ? toggleViewMode(\"html\") : setSingleViewMode(\"html\")\n                                                    }\n                                                    icon={faHtmlCode}>\n                                                    HTML\n                                                </Button>\n                                                <DropdownMenu\n                                                    render={(showMenu: any, anchor: any) => (\n                                                        <div>\n                                                            <Button\n                                                                size={\"small\"}\n                                                                variant={\n                                                                    isSplitPresetActive ? \"highlight2\" : \"outlined\"\n                                                                }\n                                                                onClick={(e) => showMenu(null, e.currentTarget)}\n                                                                icon={faColumns}>\n                                                                Split\n                                                                <FontAwesomeIcon\n                                                                    className={\"ml-2\"}\n                                                                    icon={faChevronDown}\n                                                                />\n                                                            </Button>\n                                                            {anchor}\n                                                        </div>\n                                                    )}\n                                                    align={\"left\"}\n                                                    items={() => splitViewMenuItems}\n                                                />\n                                            </>\n                                        )}\n                                        <DropdownMenu\n                                            render={(showMenu: any, anchor: any) => (\n                                                <div>\n                                                    <Button\n                                                        size={\"small\"}\n                                                        variant={\"outlined\"}\n                                                        onClick={(e) => showMenu(null, e.currentTarget)}>\n                                                        <FontAwesomeIcon fixedWidth icon={faEllipsisV} />\n                                                    </Button>\n                                                    {anchor}\n                                                </div>\n                                            )}\n                                            align={\"left\"}\n                                            items={() => formMenuItems}\n                                        />\n                                    </>\n                                )}\n\n                                <Button\n                                    size=\"small\"\n                                    variant=\"outlined\"\n                                    onClick={undoRedo.onUndo}\n                                    disabled={!undoRedo.canUndo}>\n                                    <FontAwesomeIcon fixedWidth icon={faUndo} />\n                                </Button>\n                                <Button\n                                    size=\"small\"\n                                    variant=\"outlined\"\n                                    onClick={undoRedo.onRedo}\n                                    disabled={!undoRedo.canRedo}>\n                                    <FontAwesomeIcon fixedWidth icon={faRedo} />\n                                </Button>\n                                {((inSplitView && !hiddenDesigner) ||\n                                    ((!designerPanelDocked || preventDocking) && view.design)) && (\n                                    <Button\n                                        small\n                                        variant={\"primary\"}\n                                        onClick={() => {\n                                            setCreatingObject(null);\n                                            setShowOverlayPanel(showOverlayPanel === \"toolbox\" ? null : \"toolbox\");\n                                        }}\n                                        icon={faPlus}>\n                                        Add Component\n                                    </Button>\n                                )}\n                                <BreadcrumbNav />\n                            </div>\n                            <div ref={rightToolbarControlsRef} className=\"flex shrink-0 items-center gap-4\">\n                                {/*{!collapseComponents && <div className=\"font-semibold whitespace-nowrap\">Add Component:</div>}*/}\n                                {/*{!collapseComponents && commonComponents}*/}\n                                {/*<DropdownMenu render={(showMenu:any, anchor:any) => <div>*/}\n                                {/*    <Button small variant={collapseComponents ? 'primary' : undefined} onClick={(e) => showMenu(null, e.currentTarget)}>{collapseComponents ? 'Add component' : 'More'}<FontAwesomeIcon className={'ml-2'} icon={faCaretDown}/></Button>*/}\n                                {/*    {anchor}*/}\n                                {/*</div>}*/}\n                                {/*              align={\"right\"}*/}\n                                {/*              items={() => moreComponents}*/}\n                                {/*              onSelectItem={(toolboxItem: ToolboxItem) => setCreatingObject({type: \"component\", toolboxItem})}*/}\n                                {/*/>*/}\n                                {/*{editingForm?.slots && !canUseClassic && (*/}\n                                {/*    <Button*/}\n                                {/*        small*/}\n                                {/*        variant={creatingObject?.type === \"slot\" ? \"secondary\" : undefined}*/}\n                                {/*        onClick={() =>*/}\n                                {/*            setCreatingObject(creatingObject?.type === \"slot\" ? null : { type: \"slot\" })*/}\n                                {/*        }>*/}\n                                {/*        Slot*/}\n                                {/*    </Button>*/}\n                                {/*)}*/}\n                                {/*<div ref={toolbarCanary} style={{width: 1, flexShrink: 100}} /> /!* Shrink this before anything else*!/*/}\n\n                                {canUseClassic && !isPySpace && (\n                                    <>\n                                        <LinkInternal\n                                            onClick={() => dispatch(modal(\"previewV3Designer\", {}))}\n                                            className={\"text-[1.0rem] font-semibold whitespace-nowrap text-primary\"}>\n                                            <FontAwesomeIcon icon={faCandleHolder} />{\" \"}\n                                            <span className={\"text-primary hover:underline\"}>Classic</span>\n                                        </LinkInternal>\n                                    </>\n                                )}\n\n                                {view.design && !view.code && !view.html && !view.htmlProperty && !preventDocking && (\n                                    <Button\n                                        ref={propertiesPanelTooltipRef}\n                                        small\n                                        variant={designerPanelDocked ? undefined : \"outlined\"}\n                                        onClick={() => dispatch(setDesignerPanelDocked(!designerPanelDocked))}>\n                                        <FontAwesomeIcon flip={\"horizontal\"} icon={faSidebar} />\n                                        <span className={\"ml-2\"}>Side Panel</span>\n                                        {propertiesPanelTooltip}\n                                    </Button>\n                                )}\n                                <FormFormatButton\n                                    targets={[\n                                        ...(view.code && codeEditorView\n                                            ? [{ view: codeEditorView, label: \"Format Python code\" }]\n                                            : []),\n                                        ...(view.html && htmlTemplateEditorView\n                                            ? [{ view: htmlTemplateEditorView, label: \"Format Form HTML\" }]\n                                            : []),\n                                        ...(view.htmlProperty && htmlPropertyEditorView\n                                            ? [{ view: htmlPropertyEditorView, label: \"Format HTML property\" }]\n                                            : []),\n                                    ]}\n                                />\n                                {view.code && !isPySpace && (\n                                    <>\n                                        <ConflictNavigator conflicts={conflicts} codePath={editingFormCodePath} />\n                                        {analysisEnabled ? (\n                                            <CodeToolsButton\n                                                defaultMode=\"snippets\"\n                                                menuItems={\n                                                    codeEditorView\n                                                        ? pythonCodeMenuItems(codeEditorView, { isForm: true })\n                                                        : undefined\n                                                }\n                                            />\n                                        ) : (\n                                            <Button\n                                                ref={codeSnippetsTooltipRef}\n                                                small\n                                                menuItems={\n                                                    codeEditorView\n                                                        ? pythonCodeMenuItems(codeEditorView, { isForm: true })\n                                                        : undefined\n                                                }\n                                                menuLabel=\"Python code tools\"\n                                                variant={\n                                                    !preventDocking && !view.design && showCodeSnippets\n                                                        ? undefined\n                                                        : \"outlined\"\n                                                }\n                                                onClick={() => {\n                                                    if (\n                                                        !view.design &&\n                                                        !view.html &&\n                                                        !view.htmlProperty &&\n                                                        !preventDocking\n                                                    ) {\n                                                        dispatch(\n                                                            updateCodeTabPrefs(tab, {\n                                                                showCodeSnippets: !showCodeSnippets,\n                                                            })\n                                                        );\n                                                    } else {\n                                                        setShowSnippetOverlay(true);\n                                                    }\n                                                }}>\n                                                <FontAwesomeIcon icon={faCode} />\n                                                <span className={\"ml-2\"}>Code tools</span>\n                                                {codeSnippetsTooltip}\n                                            </Button>\n                                        )}\n                                    </>\n                                )}\n                                {/*<FontAwesomeIcon icon={faSun}/>*/}\n                                {/*<LinkInternal onClick={() => setDarkMode(!darkMode)}*/}\n                                {/*              className={cx(`shrink-0 rounded-full group bg-white border-2 border-primary p-2 w-20 flex!`, darkMode && \"justify-end\")}>*/}\n                                {/*    <div className=\"w-5 h-5 bg-primary rounded-full group-hover:bg-primary-darker\" />*/}\n                                {/*</LinkInternal>*/}\n                                {/*<FontAwesomeIcon icon={faMoon}/>*/}\n                            </div>\n                        </TabToolbar>\n                    )}\n                    {!isValidCustomLayout && (\n                        <TabToolbar className={\"text-[#333]!] gap-2 bg-[#FFD]!\"}>\n                            This form's layout\n                            <span className={\"font-mono font-bold\"}>\n                                {form?.layout?.type?.startsWith(\"form:\")\n                                    ? form?.layout?.type?.substring(5)\n                                    : (form?.layout?.type ?? \"Unknown Layout\")}\n                            </span>{\" \"}\n                            could not be found.\n                            <Button small variant={\"secondary\"} className={\"ml-4\"} onClick={onChooseLayout}>\n                                Choose layout...\n                            </Button>\n                        </TabToolbar>\n                    )}\n                    {formClassIsMissing && (\n                        <TabToolbar className={\"text-[#333]!] gap-2 bg-[#FFD]!\"}>\n                            You have deleted the <span className={\"font-mono\"}>{editingFormClassName}</span> class,\n                            which Anvil needs. To continue,\n                            <Button\n                                small\n                                variant={\"secondary\"}\n                                className={\"ml-4\"}\n                                onClick={() => dispatch(resetTutorial())}>\n                                Reset the tutorial and try again.\n                            </Button>\n                        </TabToolbar>\n                    )}\n                    {codeToolsPanel}\n                    <div className={`relative flex h-0 grow flex-row hover:border-red-300`}>\n                        {/* Designer always in scope, but sets class to hidden if not in design view */}\n                        {designer}\n                        {view.design ? (\n                            <>{combinedDesignRightPane}</>\n                        ) : view.code && view.html ? (\n                            <>\n                                <div className=\"min-w-0 flex-1\">{moduleEditor}</div>\n                                {htmlTemplateEditorResizePanel}\n                            </>\n                        ) : view.code && view.htmlProperty ? (\n                            <>\n                                <div className=\"min-w-0 flex-1\">{moduleEditor}</div>\n                                {htmlPropertyEditorResizePanel}\n                            </>\n                        ) : (\n                            <>\n                                {view.code && (\n                                    <div\n                                        ref={analysisEnabled && !codeToolsOverlay ? setCodeToolsContainer : undefined}\n                                        className=\"flex min-w-0 flex-1\">\n                                        <div className=\"min-w-0 flex-1\">{moduleEditor}</div>\n                                        {!analysisEnabled &&\n                                            !preventDocking &&\n                                            showCodeSnippets &&\n                                            codeViewSnippetPanel}\n                                    </div>\n                                )}\n                                {view.html && <div className=\"min-w-0 flex-1\">{htmlTemplateEditor}</div>}\n                                {view.htmlProperty && <div className=\"min-w-0 flex-1\">{htmlPropertyEditor}</div>}\n                            </>\n                        )}\n                        {view.code && !isPySpace && (\n                            <>\n                                <div\n                                    className={cx(\n                                        \"pointer-events-none fixed top-0 left-0 z-12 h-full w-full bg-black opacity-0 transition-opacity duration-100 ease-in dark:bg-grey-2\",\n                                        { \"pointer-events-auto opacity-50\": showCodeOverlay }\n                                    )}\n                                    onClick={onCloseCodeOverlay}\n                                />\n\n                                {editingForm && (\n                                    <div\n                                        ref={analysisEnabled && codeToolsOverlay ? setCodeToolsContainer : undefined}\n                                        className={cx(\n                                            \"fixed top-0 h-full w-200 max-w-full border border-sectionborder bg-light-bg2 dark:border-dark-sectionborder dark:bg-dark-bg2\",\n                                            \"z-12 transition-[right] duration-100 ease-in\",\n                                            showCodeOverlay ? \"right-0\" : \"-right-200\"\n                                        )}>\n                                        {!analysisEnabled && showSnippetOverlay && <CodeSnippets form={editingForm} />}\n                                    </div>\n                                )}\n                            </>\n                        )}\n                    </div>\n                </div>\n            </RpcContext.Provider>\n        </FormEditorContext.Provider>\n    );\n};\n\nexport default NewFormEditor;\n","import { LEGACY_CUSTOM_COMPONENT_SPEC, PACKAGE_QUALIFIED_FORM_NAME } from \"@runtime/runner/component-spec-constants\";\nimport type { ToolboxItem, ToolboxItemComponent } from \"@designer/shared-types\";\nimport type { FormSpecWriterInput } from \"@/controllers/app/form-spec-writers\";\n\nexport const SYNTHETIC_MAIN_APP_PACKAGE = \"main_app_package\";\n\nexport interface ComponentYamlTypeConfig {\n    package_name?: string;\n    dependency_ids: Record<string, string>;\n}\n\nexport type DependencyStructureForYamlType = Record<string, { packageName?: string }>;\n\nexport interface ToolboxTypePackageContext {\n    appPackageName?: string;\n    dependenciesByPackageName: Map<string, { logicalDepId?: string }>;\n}\n\nexport interface NormalizeToolboxTypeOptions {\n    unknownPackage?: \"preserve\" | \"throw\";\n}\n\ninterface ToolboxFormSpecTarget {\n    appLocalFormName: string;\n    packageName?: string;\n    logicalDepId?: string;\n}\n\nexport type CustomComponentSpecForForm = (input: FormSpecWriterInput) => string;\n\n/**\n * Toolbox component types are already the YAML type to persist, except built-in\n * toolbox items include the `anvil.` prefix used for display/grouping.\n */\nexport const componentYamlTypeFromToolboxType = (toolboxType: string) => {\n    if (toolboxType.startsWith(\"anvil.\")) {\n        return toolboxType.substring(6);\n    }\n    return toolboxType;\n};\n\nconst formSpecTargetForPackageQualifiedToolboxType = (\n    toolboxType: string,\n    { appPackageName, dependenciesByPackageName }: ToolboxTypePackageContext,\n    { unknownPackage = \"throw\" }: NormalizeToolboxTypeOptions = {}\n): ToolboxFormSpecTarget | null => {\n    if (toolboxType.startsWith(\"anvil.\") || toolboxType.startsWith(\"form:\")) {\n        return null;\n    }\n\n    const packageMatch = toolboxType.match(PACKAGE_QUALIFIED_FORM_NAME);\n    if (!packageMatch) {\n        return null;\n    }\n    const [, packageName, appLocalFormName] = packageMatch;\n    const appPackageForToolboxTypes = appPackageName || SYNTHETIC_MAIN_APP_PACKAGE;\n    if (packageName === appPackageForToolboxTypes) {\n        return { appLocalFormName, packageName: appPackageName };\n    }\n\n    const dependency = dependenciesByPackageName.get(packageName);\n    if (dependency) {\n        return { appLocalFormName, packageName, logicalDepId: dependency.logicalDepId };\n    }\n\n    if (unknownPackage === \"throw\") {\n        throw new Error(`No such dependency package: ${packageName}`);\n    }\n    return null;\n};\n\nconst customComponentSpecForToolboxType = (\n    toolboxType: string,\n    packageContext: ToolboxTypePackageContext,\n    customComponentSpecForForm: CustomComponentSpecForForm,\n    options?: NormalizeToolboxTypeOptions\n) => {\n    const form = formSpecTargetForPackageQualifiedToolboxType(toolboxType, packageContext, options);\n    if (!form) {\n        return toolboxType;\n    }\n\n    return customComponentSpecForForm({\n        appLocalFormName: form.appLocalFormName,\n        packageName: form.packageName,\n        logicalDepId: form.logicalDepId,\n    });\n};\n\n/**\n * Authored toolbox sections use fully/package-qualified component names. This\n * is the contract for both user-authored anvil.yaml toolbox_sections, such as\n * Material 3's `m3._Components.Button`, and JS registerToolboxSection sections,\n * such as Mantine's `Mantine.ButtonGroup`.\n *\n * Convert package-qualified toolbox types to customComponentSpecs before drop\n * so the generic drop path does not need to guess what a dotted type means.\n */\nexport const normalizeToolboxItemComponentTypes = (\n    item: ToolboxItem,\n    packageContext: ToolboxTypePackageContext,\n    customComponentSpecForForm: CustomComponentSpecForForm,\n    options?: NormalizeToolboxTypeOptions\n): ToolboxItem => {\n    const componentWithCustomComponentSpecs = (component: ToolboxItemComponent): ToolboxItemComponent => ({\n        ...component,\n        type: customComponentSpecForToolboxType(component.type, packageContext, customComponentSpecForForm, options),\n        components: component.components?.map(componentWithCustomComponentSpecs),\n    });\n\n    const createForms =\n        item.createForms &&\n        Object.fromEntries(\n            Object.entries(item.createForms).map(([key, formSpec]) => [\n                key,\n                \"container\" in formSpec\n                    ? {\n                          ...formSpec,\n                          container: customComponentSpecForToolboxType(\n                              formSpec.container,\n                              packageContext,\n                              customComponentSpecForForm,\n                              options\n                          ),\n                      }\n                    : {\n                          ...formSpec,\n                          layout: customComponentSpecForToolboxType(\n                              formSpec.layout,\n                              packageContext,\n                              customComponentSpecForForm,\n                              options\n                          ),\n                      },\n            ])\n        );\n    const createFormsUpdate = createForms ? { createForms } : {};\n\n    if (\"component\" in item) {\n        return {\n            ...item,\n            ...createFormsUpdate,\n            component: componentWithCustomComponentSpecs(item.component),\n        };\n    }\n    return { ...item, ...createFormsUpdate };\n};\n\nexport const toolboxQualifiedNameFromComponentYamlType = (\n    componentYamlType: string,\n    appConfig: ComponentYamlTypeConfig,\n    dependencyStructure: DependencyStructureForYamlType\n) => {\n    const legacyMatch = componentYamlType.match(LEGACY_CUSTOM_COMPONENT_SPEC);\n    if (legacyMatch) {\n        const [, logicalDepId, appLocalFormName] = legacyMatch;\n        if (logicalDepId) {\n            const depAppId = appConfig.dependency_ids[logicalDepId];\n            const packageName = depAppId && dependencyStructure[depAppId]?.packageName;\n            // This conversion is only for toolbox/display names. If dependency\n            // package context is incomplete, keep the persisted YAML spec\n            // instead of inventing an invalid package-qualified name.\n            return packageName ? `${packageName}.${appLocalFormName}` : componentYamlType;\n        }\n        const appPackageName = appConfig.package_name || SYNTHETIC_MAIN_APP_PACKAGE;\n        return `${appPackageName}.${appLocalFormName}`;\n    }\n\n    if (componentYamlType.includes(\".\") && !componentYamlType.startsWith(\"anvil.\")) {\n        return componentYamlType;\n    }\n    if (componentYamlType.startsWith(\"anvil.\")) {\n        return componentYamlType;\n    }\n    return `anvil.${componentYamlType}`;\n};\n","import type { ComponentYaml, IdeRpcFunctions } from \"@designer/shared-types\";\nimport type { SlotTarget } from \"@runtime/runner/data\";\nimport type { FormItemYaml } from \"@/types\";\nimport type { UpdateComponentByNameInside } from \"../../DesignerHistory\";\nimport type { SyncHtmlFormAfterMutation } from \"../../NewFormEditor\";\nimport { findComponentByNameInTree } from \"../utils/component-tree\";\nimport { applyOtherLayoutUpdates } from \"../utils/other-layout-updates\";\nimport {\n    adjustChildIdxAndSlotsForInsertion,\n    adjustSlotsForDeletion,\n    resequenceSlotOrderForTarget,\n    slotDefsByTarget,\n} from \"../utils/slots\";\n\ninterface MoveObjectsInFormOptions {\n    editingForm: FormItemYaml;\n    objects: Parameters<IdeRpcFunctions[\"moveObjects\"]>[0];\n    target: Parameters<IdeRpcFunctions[\"moveObjects\"]>[1];\n    dropInfo: Parameters<IdeRpcFunctions[\"moveObjects\"]>[2];\n    updateComponentByNameInside: UpdateComponentByNameInside;\n    cleanupLayoutProperties: (componentName: string) => Promise<boolean>;\n    syncHtmlFormAfterMutation: SyncHtmlFormAfterMutation;\n}\n\n/**\n * Apply one designer move event to the editing form's component and slot YAML.\n * Objects come from the live designer, which filters out dropzones inside dragged objects.\n */\nexport const moveObjectsInForm = async ({\n    editingForm,\n    objects,\n    target,\n    dropInfo,\n    updateComponentByNameInside,\n    cleanupLayoutProperties,\n    syncHtmlFormAfterMutation,\n}: MoveObjectsInFormOptions) => {\n    const moveTarget =\n        target.type === \"component\"\n            ? ({ type: \"container\", name: target.name } as const)\n            : target.type === \"slot\"\n              ? ({ type: \"slot\", name: target.name } as const)\n              : undefined;\n    if (!moveTarget) {\n        console.warn(\"Tried to move objects into unsupported target type\", target.type);\n        return;\n    }\n    const sameTarget = (a: SlotTarget, b: SlotTarget) => a.type === b.type && a.name === b.name;\n    const selectedComponents = new Set(objects.filter((o) => o.type === \"component\").map((o) => o.name));\n\n    // Capture source positions before removal. Attach drop properties before sorting, since\n    // perComponentUpdates follows selection order, not sibling order.\n    const moving = objects\n        .map((object, i) => {\n            let source: SlotTarget;\n            let position: number;\n            if (object.type === \"component\") {\n                const component = findComponentByNameInTree(editingForm, object.name)!;\n                source = { type: component.parentType, name: component.parentName };\n                const slots = slotDefsByTarget(editingForm, source.type, source.name);\n                position = component.index + slots.filter((slot) => slot.index <= component.index).length;\n            } else {\n                const slot = editingForm.slots![object.name];\n                source = slot.target;\n                const slots = slotDefsByTarget(editingForm, source.type, source.name);\n                position = slot.index + slots.indexOf(slot);\n            }\n            return {\n                ...object,\n                source,\n                position,\n                layout_properties: (dropInfo.perComponentUpdates?.[i] ?? dropInfo).layout_properties,\n            };\n        })\n        .filter(({ source }) => {\n            // Move selected parents with their subtrees. Keep the original selection untouched.\n            let parent = source;\n            while (parent.type === \"container\" && parent.name !== \"\") {\n                if (selectedComponents.has(parent.name)) return false;\n                const component = findComponentByNameInTree(editingForm, parent.name)!;\n                parent = { type: component.parentType, name: component.parentName };\n            }\n            return true;\n        });\n    // Siblings retain YAML order; selections spanning different parents retain click order.\n    if (moving.length && moving.every((object) => sameTarget(object.source, moving[0].source))) {\n        moving.sort((a, b) => a.position - b.position);\n    }\n    let childIdx = dropInfo.minChildIdx ?? dropInfo.maxChildIdx;\n    // The designer measures the drop before removal, including selected objects before it.\n    if (childIdx !== undefined) {\n        const dropPosition = childIdx;\n        childIdx -= moving.filter(\n            (object) => sameTarget(object.source, moveTarget) && object.position < dropPosition\n        ).length;\n    }\n    const movedSlotNames = moving.filter((object) => object.type === \"slot\").map((object) => object.name);\n    const movedComponents: ComponentYaml[] = [];\n    const deletedFromContainers = new Set<string>();\n    const { slots_set_layout_properties } = dropInfo;\n\n    // Apply displaced-object updates while all components remain reachable by name.\n    applyOtherLayoutUpdates(editingForm, updateComponentByNameInside, dropInfo.otherLayoutUpdates);\n\n    // Remove every component before inserting any of them. This makes destination indices independent\n    // of the order in which same-target components are processed.\n    for (const object of moving) {\n        if (object.type !== \"component\") {\n            continue;\n        }\n        updateComponentByNameInside(\n            editingForm,\n            object.name,\n            (component, inArray, childIdx, parentName, parentType) => {\n                movedComponents.push({ ...component, layout_properties: object.layout_properties });\n                adjustSlotsForDeletion(childIdx, slotDefsByTarget(editingForm, parentType, parentName));\n                inArray.splice(childIdx, 1);\n                if (parentType === \"container\") {\n                    deletedFromContainers.add(parentName);\n                }\n            }\n        );\n    }\n\n    const siblingSlots = slotDefsByTarget(editingForm, moveTarget.type, moveTarget.name).filter(\n        (slot) => !movedSlotNames.some((name) => editingForm.slots![name] === slot)\n    );\n    const insertMovedComponents = (components: ComponentYaml[]) => {\n        // Convert the merged designer index to a component-array index once, then shift stationary\n        // destination slots by the full number of components being inserted.\n        const componentIdx = adjustChildIdxAndSlotsForInsertion(\n            \"component\",\n            childIdx,\n            siblingSlots,\n            movedComponents.length,\n            components.length\n        );\n        components.splice(componentIdx, 0, ...movedComponents);\n        return componentIdx;\n    };\n\n    let componentIdx: number;\n    if (moveTarget.type === \"container\") {\n        componentIdx = 0;\n        updateComponentByNameInside(editingForm, moveTarget.name, (component) => {\n            component.components ||= [];\n            componentIdx = insertMovedComponents(component.components);\n        });\n    } else {\n        const components = ((editingForm.components_by_slot ||= {})[moveTarget.name] ||= []);\n        componentIdx = insertMovedComponents(components);\n    }\n\n    // A slot at index N appears before component N. Counting preceding moved components therefore\n    // preserves mixed slot/component interleaving while both are written to separate YAML structures.\n    for (const object of moving) {\n        if (object.type === \"component\") {\n            componentIdx++;\n        } else {\n            const { layout_properties } = object;\n            Object.assign(editingForm.slots![object.name], {\n                target: moveTarget,\n                index: componentIdx,\n                set_layout_properties: slots_set_layout_properties\n                    ? Object.fromEntries(\n                          slots_set_layout_properties.map((property) => [property, layout_properties![property]])\n                      )\n                    : { ...layout_properties },\n            });\n        }\n    }\n    if (movedSlotNames.length > 0) {\n        resequenceSlotOrderForTarget(editingForm, {\n            target: moveTarget,\n            movedSlotNames,\n            mergedChildIdx: childIdx,\n        });\n    }\n    await syncHtmlFormAfterMutation({\n        structural: true,\n        forceRefresh: true,\n        debugContext: {\n            operation: \"designer.moveObjects\",\n            eventContext: { objects, target, dropInfo, deletedFromContainers: [...deletedFromContainers] },\n            afterMutationState: editingForm,\n        },\n    });\n    let cleanupChangedYaml = false;\n    for (const container of deletedFromContainers) {\n        cleanupChangedYaml = (await cleanupLayoutProperties(container)) || cleanupChangedYaml;\n    }\n    if (cleanupChangedYaml) {\n        // ColumnPanel cleanup can rewrite layout properties after the iframe\n        // rebuilds. This is serialize-only: it updates those layout\n        // attributes in `serialized_html` without reparsing structural YAML.\n        syncHtmlFormAfterMutation();\n    }\n};\n","import { EventDescription } from \"@designer/shared-types\";\nimport { ComponentYaml, EventBindingYaml } from \"@runtime/runner/data\";\nimport type { EventHandler } from \"@/code_mirror/autocompletions/types\";\nimport { JumpRequest } from \"@/code_mirror/utils/method_finder\";\nimport { getComponentOrContainerOrLayout, isWithLayoutFormEvent } from \"@/components/tabs/code/designer/utils\";\nimport type { CodePath, FormItemYaml } from \"@/types\";\n\n/**\n * Works out what jumping to a component's event handler should actually do — which method, whether it\n * already exists, and whether it is currently bound in YAML rather than by an `@handle` decorator.\n *\n * Pure on purpose. The designer calls this (via `useJumpToEventHandler`) and so does the \"Create Event\n * Handler\" widget in the code editor, which has no access to designer context. Keeping the decision in\n * one place means the two entry points can't disagree about which method a given event maps to.\n */\n\nexport interface ResolveEventHandlerArgs {\n    editingForm: FormItemYaml;\n    /** \"\" means the form itself. */\n    componentName: string;\n    event: EventDescription;\n    /** From `acStateStore.eventHandlers[className]` — handlers declared with an `@handle` decorator. */\n    formEventHandlers: EventHandler[];\n    className: string;\n    codePath: CodePath;\n}\n\nexport interface ResolvedEventHandler {\n    /** Ready to hand to `onRequestJumpToCode`. */\n    request: Omit<JumpRequest, \"navTarget\">;\n    /** The method already bound to this event, by either mechanism, if the event is bound at all. */\n    existingHandlerMethod?: string;\n    /** Method bound by an `@handle` decorator, if there is one. */\n    decoratedHandlerMethod?: string;\n    /** Method bound in YAML, if there is one. Callers that can write YAML should clear it once migrated to `@handle`. */\n    yamlHandlerMethod?: string;\n}\n\n/** Pure equivalent of the designer's `getComponentByName`, without the design-history plumbing. */\nexport function findComponentByName(form: FormItemYaml, name: string): ComponentYaml | FormItemYaml | undefined {\n    if (name === \"\") return form;\n\n    const walk = (components: ComponentYaml[] | undefined): ComponentYaml | undefined => {\n        for (const c of components ?? []) {\n            if (c.name === name) return c;\n            const found = walk(c.components);\n            if (found) return found;\n        }\n    };\n\n    if (form.components_by_slot) {\n        for (const components of Object.values(form.components_by_slot)) {\n            const found = walk(components);\n            if (found) return found;\n        }\n        return undefined;\n    }\n    return walk(form.components);\n}\n\n/** The YAML `event_bindings` / `form_event_bindings` entry for this event, if there is one. */\nexport function getYamlEventBinding(\n    editingForm: FormItemYaml,\n    componentName: string,\n    eventName: string\n): string | undefined {\n    const component = findComponentByName(editingForm, componentName);\n    if (!component) return;\n    const resolved = getComponentOrContainerOrLayout(component as ComponentYaml, componentName);\n    if (!resolved) return;\n    const [c, isLayout] = resolved;\n    // getComponentOrContainerOrLayout keys off `\"container\" in c`, so a form carrying a present-but-undefined\n    // container (or layout) hands back undefined here. Reading bindings is not worth throwing over.\n    if (!c) return;\n    const key = isWithLayoutFormEvent(isLayout, eventName) ? \"form_event_bindings\" : \"event_bindings\";\n    const eventBindings: EventBindingYaml = (c as any)[key] || {};\n    return eventBindings[eventName] || undefined;\n}\n\n/** The `@handle`-decorated method bound to this event, if there is one. */\nexport function getDecoratedEventHandler(\n    formEventHandlers: EventHandler[],\n    componentName: string,\n    eventName: string\n): string | undefined {\n    return formEventHandlers.find((h) => h.component === componentName && h.event === eventName)?.handler;\n}\n\nexport function resolveEventHandlerRequest({\n    editingForm,\n    componentName,\n    event,\n    formEventHandlers,\n    className,\n    codePath,\n}: ResolveEventHandlerArgs): ResolvedEventHandler {\n    const decoratedHandlerMethod = getDecoratedEventHandler(formEventHandlers, componentName, event.name);\n    const yamlHandlerMethod = getYamlEventBinding(editingForm, componentName, event.name);\n\n    // A decorator wins over a YAML binding: it's the modern form, and it's what the runtime honours.\n    const existingHandlerMethod = decoratedHandlerMethod ?? yamlHandlerMethod;\n    const method = existingHandlerMethod ?? `${componentName || \"form\"}_${event.name}`;\n\n    return {\n        existingHandlerMethod,\n        decoratedHandlerMethod,\n        yamlHandlerMethod,\n        request: {\n            method,\n            eventInYaml: yamlHandlerMethod !== undefined,\n            parameters: event.parameters ?? [],\n            commentCallWhen: event.description,\n            className,\n            codePath,\n            componentName,\n            eventName: event.name,\n        },\n    };\n}\n","import { Breadcrumb, DropZoneDTO, HoverObjectDTO, SelectedObjectDTO, ToolboxSection } from \"@designer/shared-types\";\nimport { CodePath, FormItemYaml } from \"@/types\";\nimport { CurrentBounds } from \"../types\";\n\nexport class RpcState {\n    readonly ready: number = 0;\n    readonly breadcrumb: Breadcrumb = [];\n    readonly selection: SelectedObjectDTO[] = [];\n    readonly hoverObject: HoverObjectDTO | null = null;\n    readonly appHeight: number = 0;\n    readonly dragging: boolean = false;\n    readonly dropZones: DropZoneDTO[] | null = [];\n    readonly objectBounds: CurrentBounds = {\n        component: {},\n        slot: {},\n        section: {},\n        slotTemplateSection: {},\n    };\n    readonly editFormBounds: DOMRect | undefined;\n    readonly orphanedObjects: [string[], string[]] = [[], []];\n    readonly codeDeps: CodePath[] = [];\n    readonly assetDeps: CodePath[] = [];\n    readonly jsToolboxSections: ToolboxSection[] = [];\n    // initialized in useRpc()\n    readonly editingFormCodePath: CodePath = \"forms/$UNKNOWN\";\n    readonly editingFormClassName: string = \"$UNKNOWN\";\n    readonly editingForm: FormItemYaml | null = null;\n}\n","import type { ComponentYaml } from \"@designer/shared-types\";\nimport type { FormItemYaml } from \"@/types\";\n\nexport type ComponentTreeUpdater = (\n    component: ComponentYaml,\n    containingArray: ComponentYaml[],\n    index: number,\n    parentName: string,\n    parentType: \"container\" | \"slot\"\n) => void;\n\nexport type ComponentPredicate = (component: ComponentYaml) => boolean;\n\ninterface ComponentLocation {\n    component: ComponentYaml;\n    containingArray: ComponentYaml[];\n    index: number;\n    parentName: string;\n    parentType: \"container\" | \"slot\";\n}\n\nexport const updateComponentInTree = (\n    form: FormItemYaml,\n    predicate: ComponentPredicate,\n    update: ComponentTreeUpdater\n) => {\n    const walk = (components: ComponentYaml[], parentName: string, parentType: \"container\" | \"slot\") => {\n        for (const [index, component] of components.entries()) {\n            if (predicate(component)) {\n                update(component, components, index, parentName, parentType);\n                return true;\n            }\n            if (component.components && walk(component.components, component.name, \"container\")) {\n                return true;\n            }\n        }\n    };\n\n    if (form.components_by_slot) {\n        for (const [slotName, components] of Object.entries(form.components_by_slot)) {\n            if (walk(components, slotName, \"slot\")) {\n                return true;\n            }\n        }\n        return;\n    }\n    return walk(form.components ?? [], \"\", \"container\");\n};\n\nexport const updateComponentByNameInTree = (form: FormItemYaml, name: string, update: ComponentTreeUpdater) => {\n    if (name === \"\") {\n        update(form as unknown as ComponentYaml, [], -1, \"\", \"container\");\n        return true;\n    }\n    return updateComponentInTree(form, (component) => component.name === name, update);\n};\n\nexport const findComponentByNameInTree = (form: FormItemYaml, name: string): ComponentLocation | null => {\n    let found: ComponentLocation | null = null;\n    updateComponentByNameInTree(form, name, (component, containingArray, index, parentName, parentType) => {\n        found = { component, containingArray, index, parentName, parentType };\n    });\n    return found;\n};\n","import { ComponentYaml, FormContainerYaml, FormLayoutYaml } from \"@runtime/runner/data\";\n\nexport const getComponentOrContainerOrLayout = (\n    c: ComponentYaml | undefined,\n    componentName: string\n): [ComponentYaml | FormContainerYaml, false] | [FormLayoutYaml, true] | undefined => {\n    if (c) {\n        if (componentName === \"\") {\n            if (\"container\" in c) {\n                return [c.container! as FormContainerYaml, false];\n            } else if (\"layout\" in c) {\n                return [c.layout! as FormLayoutYaml, true];\n            }\n        }\n        return [c as ComponentYaml, false];\n    }\n    return undefined;\n};\n\nexport const isWithLayoutFormEvent = (isLayout: boolean, eventName: string) => {\n    return isLayout && (eventName === \"refreshing_data_bindings\" || eventName === \"show\" || eventName === \"hide\");\n};\n\nexport const getErrorObject = (error: unknown): { error: string } => {\n    let errorMessage: string;\n    if (error instanceof Error) {\n        errorMessage = error.message;\n    } else if (error !== null && typeof error === \"object\" && \"error\" in error) {\n        const { error: innerError } = error;\n        errorMessage = String(innerError);\n    } else {\n        errorMessage = String(error);\n    }\n    errorMessage ||= \"Unknown Error\";\n\n    return { error: errorMessage };\n};\n","import { ComponentYaml } from \"@designer/shared-types\";\nimport { FormItemYaml } from \"@/types\";\n\nexport const getAllComponentNames = (insideComponent: FormItemYaml | ComponentYaml): string[] => {\n    const names: string[] = [];\n    if (insideComponent.name) {\n        names.push(insideComponent.name);\n    }\n    for (const c of insideComponent?.components || []) {\n        names.push(...getAllComponentNames(c));\n    }\n    for (const cs of Object.values((insideComponent as FormItemYaml)?.components_by_slot || {})) {\n        for (const c of cs) {\n            names.push(...getAllComponentNames(c));\n        }\n    }\n    return names;\n};\n\nexport interface NameOptions {\n    isCopy?: boolean;\n}\n\nfunction splitNameRootAndIndex(str: string) {\n    const match = str.match(/^(.*)_([0-9]+)$/);\n\n    if (!match) {\n        return { root: str };\n    }\n\n    return {\n        root: match[1],\n        index: parseInt(match[2], 10),\n    };\n}\n\nexport const getNewComponentName = (\n    editingForm: FormItemYaml,\n    nameRoot: string,\n    otherNamesToAvoid?: string[],\n    { isCopy = false }: NameOptions = {}\n) => {\n    const allNames = getAllComponentNames(editingForm).concat(otherNamesToAvoid || []);\n    const exists = (name: string) => allNames.includes(name);\n\n    const { root, index } = splitNameRootAndIndex(nameRoot);\n\n    if (isCopy && !exists(nameRoot)) {\n        return nameRoot;\n    }\n\n    let n = index !== undefined && Number.isInteger(index) ? index + 1 : isCopy ? 2 : 1;\n    let name = root + \"_\" + n;\n\n    while (exists(name)) {\n        n += 1;\n        name = root + \"_\" + n;\n    }\n    return name;\n};\n\nexport const getNewSlotName = (editingForm: FormItemYaml, nameRoot: string, preferRaw = false) => {\n    const exists = (name: string) => name in (editingForm.slots || {});\n    if (preferRaw && !exists(nameRoot)) {\n        return nameRoot;\n    }\n    let idx = preferRaw ? 2 : 1;\n    while (exists(`${nameRoot}_${idx}`)) {\n        idx++;\n    }\n    return `${nameRoot}_${idx}`;\n};\n","import type { DropInfo } from \"@runtime/components/Component\";\nimport type { FormItemYaml } from \"@/types\";\nimport type { UpdateComponentByNameInside } from \"../../DesignerHistory\";\n\nexport const applyOtherLayoutUpdates = (\n    editingForm: FormItemYaml,\n    updateComponentByNameInside: UpdateComponentByNameInside,\n    otherLayoutUpdates: DropInfo[\"otherLayoutUpdates\"]\n) => {\n    for (const update of otherLayoutUpdates || []) {\n        if (update.type === \"component\") {\n            updateComponentByNameInside(editingForm, update.name, (c) => {\n                c.layout_properties = { ...(c.layout_properties || {}), ...(update.layout_properties || {}) };\n            });\n        } else if (update.type === \"slot\") {\n            const slot = editingForm.slots?.[update.name];\n            if (slot) {\n                slot.set_layout_properties = {\n                    ...(slot.set_layout_properties || {}),\n                    ...(update.layout_properties || {}),\n                };\n            }\n        }\n    }\n};\n","import { SlotDefYaml } from \"@designer/shared-types\";\nimport type { SlotTarget } from \"@runtime/runner/data\";\nimport { compareNamedSlotDefs as compareSlotDefs } from \"@runtime/runner/slot-ordering\";\nimport { FormItemYaml } from \"@/types\";\n\nexport { compareSlotDefs };\n\n/**\n * Rewrites slot_order for one target's sibling slots so the persisted order matches the\n * user's requested drop position instead of the slots object's key history.\n *\n * We use the existing sorted sibling order as the baseline, insert the moved slot at the merged\n * drop index, then renumber the whole target group densely from 0.\n */\nexport const resequenceSlotOrderForTarget = (\n    editingForm: FormItemYaml,\n    {\n        target,\n        movedSlotNames,\n        mergedChildIdx,\n    }: {\n        target: SlotTarget;\n        movedSlotNames: string[];\n        mergedChildIdx: number | undefined;\n    }\n) => {\n    const slots = editingForm.slots || {};\n    const movedSlots: [string, SlotDefYaml][] = movedSlotNames.flatMap((name) =>\n        slots[name] ? [[name, slots[name]]] : []\n    );\n    if (movedSlots.length === 0) {\n        return;\n    }\n    const movedSlotNameSet = new Set(movedSlotNames);\n\n    const peers = Object.entries(slots)\n        .filter(\n            ([name, slot]) =>\n                !movedSlotNameSet.has(name) && slot.target.type === target.type && slot.target.name === target.name\n        )\n        .sort(compareSlotDefs);\n\n    // Component insertion may already have shifted peers at or after the drop to higher indices.\n    // Those peers remain after the same boundary; peers before it are unchanged, so this comparison\n    // finds the same insertion point before or after that shift.\n    const insertionPoint = mergedChildIdx ?? Number.MAX_SAFE_INTEGER;\n    let insertAt = peers.length;\n    for (const [idx, [, slot]] of peers.entries()) {\n        const virtualPosition = slot.index + idx;\n        if (virtualPosition >= insertionPoint) {\n            insertAt = idx;\n            break;\n        }\n    }\n\n    peers.splice(insertAt, 0, ...movedSlots);\n    for (const [idx, [name]] of peers.entries()) {\n        slots[name].slot_order = idx;\n    }\n};\n\nexport const adjustChildIdxAndSlotsForInsertion = (\n    insertingType: \"component\" | \"slot\",\n    childIdx: number | undefined,\n    slots: SlotDefYaml[],\n    nInserting = 1,\n    maxIdx: number\n) => {\n    // We're about to insert at childIdx in a YAML component list (components in a container or slot) including the supplied slots.\n    // This requires two adjustments: to childIdx, and to the slots (if we're inserting a component).\n    // 1. childIdx was computed from a YAML carrier that included slot placeholders, but to modify the YAML we're\n    // indexing an array that doesn't include them. So we decrement childIdx for every placeholder it's passed.\n    // 2. Every slot *after* the insertion index needs its index increased by nInserting, because it's\n    // moved along in the table. [Only do this if we're inserting a component. Slots don't move other slots along.]\n\n    if (childIdx === undefined) {\n        return maxIdx;\n    }\n\n    for (const slot of slots) {\n        if (slot.index < childIdx) {\n            childIdx--;\n        } else if (slot.index >= childIdx) {\n            if (insertingType === \"component\") {\n                slot.index += nInserting;\n            }\n        }\n    }\n    return Math.min(childIdx, maxIdx);\n};\n\nexport const adjustSlotsForDeletion = (listIdx: number, slotsInList: SlotDefYaml[]) => {\n    for (const slot of slotsInList) {\n        if (slot.index > listIdx) {\n            slot.index--;\n        }\n    }\n};\n\nexport const slotDefsByTarget = (editingForm: FormItemYaml, targetType: \"container\" | \"slot\", targetName: string) =>\n    !editingForm.slots\n        ? []\n        : Object.entries(editingForm.slots)\n              .filter(([_name, { target }]) => target.type === targetType && target.name === targetName)\n              .sort(compareSlotDefs)\n              .map(([name, slot]) => slot);\n\n/** Preserve the displayed sibling order before changing the legacy name tie-breaker. */\nexport const renameSlot = (form: FormItemYaml, oldName: string, newName: string) => {\n    const slots = form.slots!;\n    const slot = slots[oldName];\n    Object.entries(slots)\n        .filter(([, sibling]) => sibling.target.type === slot.target.type && sibling.target.name === slot.target.name)\n        .sort(compareSlotDefs)\n        .forEach(([, sibling], index) => {\n            sibling.slot_order = index;\n        });\n    delete slots[oldName];\n    slots[newName] = slot;\n};\n","import React, { Fragment, useEffect, useRef } from \"react\";\nimport { flexRender } from \"@tanstack/react-table\";\nimport { cx } from \"@/theme/styles\";\nimport { TRow, TTable } from \"./types\";\n\nexport const FIXED_HEIGHT = 3.5;\n\nconst useFlashRow = (row: TRow, ref: React.MutableRefObject<HTMLDivElement>) => {\n    useEffect(() => {\n        if (!row.original._isNew) return;\n        const div = ref.current;\n        const flash = div.animate({ backgroundColor: [\"rgba(255,255,0,0.5)\", \"\"] }, { duration: 1000 });\n        const onfinish = () => {\n            delete row.original._isNew;\n        };\n        flash.onfinish = onfinish;\n        flash.play();\n        return onfinish;\n    }, []);\n};\n\nconst RowEl = ({ row, table, index }: { table: TTable; row: TRow; index: number }) => {\n    const { getRowSize, readonly, multiple, updateSelectedRows } = table.options.meta!;\n\n    const rowDivRef = useRef<HTMLDivElement>(null!);\n    const onClick = () => {\n        if (!readonly) return;\n        updateSelectedRows({ row, additive: !!multiple, inclusive: false }, { table });\n    };\n    useFlashRow(row, rowDivRef);\n    const isSelected = row.getIsSelected();\n\n    return (\n        <div\n            ref={rowDivRef}\n            key={row.id}\n            role=\"row\"\n            style={{\n                gridTemplateColumns: \"var(--template-columns)\",\n                // gridTemplateRows: height + \"px\",\n                gridTemplateRows: FIXED_HEIGHT + \"rem\",\n                // boxShadow: isSelected ? \"inset 0 0 0 2px #1BB0EE\" : \"\",\n            }}\n            onClick={onClick}\n            className={cx(\"relative grid divide-x divide-slate-200 dark:divide-dark-bg4\", {\n                \"bg-slate-100 dark:bg-dark-bg2\": !!(index % 2),\n                \"bg-primary-50/40 dark:bg-primary-700/50\": isSelected,\n                // [classes.flash]: row.original._isNew\n                // \"before:absolute before:inset-0 before:h-full before:w-full before:border-2 before:border-primary\":\n                // isSelected,\n                // \"ring-2! ring-inset! ring-primary!\": isSelected,\n            })}>\n            {row.getVisibleCells().map((cell) => (\n                <Fragment key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</Fragment>\n            ))}\n        </div>\n    );\n};\n\ninterface TableBodyProps {\n    table: TTable;\n}\n\nexport const TableBody = ({ table }: TableBodyProps) => {\n    const { rows } = table.getRowModel();\n    const { tableBodyRef, rowVirtualizer } = table.options.meta!;\n\n    const { getVirtualItems, getTotalSize } = rowVirtualizer;\n    const virtualRows = getVirtualItems();\n    const totalSize = getTotalSize();\n    const paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0;\n    const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows?.at(-1)?.end || 0) : 0;\n\n    return (\n        <div ref={tableBodyRef} role=\"grid\" data-table-body style={{ paddingTop, paddingBottom }}>\n            <div\n                className={cx(\"divide-y divide-slate-200 border-slate-200 dark:divide-dark-bg4 dark:border-dark-bg4\", {\n                    \"border-r border-b border-l\": !!virtualRows.length,\n                })}>\n                {virtualRows.map((virtualRow) => {\n                    const row = rows[virtualRow.index];\n                    return <RowEl key={row.id} row={row} table={table} index={virtualRow.index} />;\n                })}\n            </div>\n        </div>\n    );\n};\n\nexport default TableBody;\n","import React, { Fragment } from \"react\";\nimport { flexRender } from \"@tanstack/react-table\";\nimport { FIXED_HEIGHT } from \"./TableBody\";\nimport { TTable } from \"./types\";\n\nexport const TableFooter = ({ table }: { table: TTable }) => {\n    return (\n        <div className=\"sticky bottom-0 z-2 mt-2 bg-slate-100 dark:bg-dark-bg2\">\n            {table.getFooterGroups().map((footerGroup) => {\n                return (\n                    <div\n                        key={footerGroup.id}\n                        role=\"row\"\n                        className=\"grid divide-x divide-slate-200 border border-slate-200 dark:divide-dark-bg4 dark:border-dark-bg4\"\n                        style={{\n                            gridTemplateColumns: \"var(--template-columns)\",\n                            gridTemplateRows: FIXED_HEIGHT + \"rem\",\n                        }}>\n                        {footerGroup.headers.map((header) => (\n                            <Fragment key={header.id}>\n                                {header.isPlaceholder\n                                    ? null\n                                    : flexRender(header.column.columnDef.footer, header.getContext())}\n                            </Fragment>\n                        ))}\n                    </div>\n                );\n            })}\n        </div>\n    );\n};\n","import React, { Fragment } from \"react\";\nimport { flexRender } from \"@tanstack/react-table\";\nimport { TTable } from \"./types\";\n\nexport const TableHead = ({ table }: { table: TTable }) => {\n    return (\n        <div className=\"sticky top-0 z-2\">\n            {table.getHeaderGroups().map((headerGroup) => (\n                <div\n                    key={headerGroup.id}\n                    role=\"row\"\n                    className=\"grid divide-x divide-slate-200 border-r border-b border-l border-slate-200 bg-slate-100 dark:divide-dark-bg4 dark:border-dark-bg4 dark:bg-dark-bg2\"\n                    style={{ gridTemplateColumns: \"var(--template-columns)\", gridTemplateRows: \"6rem\" }}>\n                    {headerGroup.headers.map((header) => (\n                        <Fragment key={header.id}>\n                            {flexRender(header.column.columnDef.header, header.getContext())}\n                        </Fragment>\n                    ))}\n                </div>\n            ))}\n        </div>\n    );\n};\n\nexport default TableHead;\n","import React, { useCallback, useMemo, useReducer, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport {\n    IconDefinition,\n    faAngleDown,\n    faArrowUpArrowDown,\n    faBan,\n    faBarsFilter,\n    faDownload,\n    faEllipsisV,\n    faEye,\n    faPen,\n    faPlus,\n    faRefresh,\n    faTableColumns,\n    faTimesCircle,\n    faTrashAlt,\n} from \"@fortawesome/pro-light-svg-icons\";\nimport { faWindowMaximize } from \"@fortawesome/pro-regular-svg-icons/faWindowMaximize\";\nimport { faCaretLeft, faCaretRight, faWindowRestore } from \"@fortawesome/pro-solid-svg-icons\";\nimport UpgradeBadge from \"@/components/reusable/UpgradeBadge.tsx\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { sortBy, startCase } from \"lodash-es\";\nimport { deleteAllRows, getTableDownloadUrl, updateTableAccess } from \"@/api/tables\";\nimport { SortModalContent } from \"@/components/modals/database/SortModal\";\nimport { Button, ButtonProps } from \"@/components/reusable/Button\";\nimport DropdownMenu, { MenuItems } from \"@/components/reusable/DropdownMenu\";\nimport { CheckBox } from \"@/components/reusable/Forms\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport { NodeRenamer } from \"@/components/reusable/NavNodeRenamer\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@/components/reusable/Popover\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { invalidateTableSchema } from \"@/controllers/app/autocompleter\";\nimport {\n    accessFromTable,\n    supportsIndexing,\n    getDebugEnvironmentTableMapping,\n    ingestOldIDESchemaUpdate, openTableIndexesModal,\n} from \"@/controllers/db\";\nimport { modal } from \"@/controllers/modals\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { Access, CurrentTable, Table, TableMapping } from \"@/types/database\";\nimport { getRandomString } from \"@/util\";\nimport { useMergeRefs, useResizeObserver, useStateWithReset } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport TabToolbar from \"../TabToolbar\";\nimport { useDeleteCells } from \"./cells/Cell\";\nimport { useInsertColumn } from \"./columns/AddColumn\";\nimport { useDeleteRows } from \"./columns/SelectColumn\";\nimport { useDeleteCols } from \"./header/DraggableColumnHeader\";\nimport { HeaderInfo, TMeta, TTable } from \"./types\";\nimport { getFeatures } from \"@/controllers/ide.ts\";\nimport { getAllTableMappings } from \"@/controllers/app\";\nimport { getCurrentTabId, getTabs } from \"@/controllers/tabs.ts\";\nimport { faListOl } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faRectangleHistory, faRectangleHistoryCirclePlus } from \"@fortawesome/pro-regular-svg-icons\";\nimport Link from \"@/components/reusable/Link.tsx\";\n\nexport interface ToolbarProps {\n    table: TTable;\n    options?: { pythonName?: boolean };\n}\n\ninterface ToolbarButtonProps extends ButtonProps {\n    text?: null | string;\n    icon: IconDefinition;\n    tooltip?: string;\n    children?: React.ReactNode;\n}\n\nconst ToolbarButton = ({ ref, text = null, tooltip, className, icon, children, ...props }: ToolbarButtonProps) => {\n    const [tip, anchorRef] = useTooltip(tooltip, \"bottom\", { delay: true });\n    const btnRef = useMergeRefs(ref, anchorRef);\n    return (\n        <Button\n            className={cx(\"font-medium!\", className)}\n            ref={btnRef}\n            size=\"small\"\n            icon={text ? icon : undefined}\n            {...props}>\n            {text ? <span className=\"truncate text-ellipsis\">{text}</span> : null}\n            {text ? null : <FontAwesomeIcon icon={icon} />}\n            {children}\n            {tip}\n        </Button>\n    );\n};\n\nconst accessLevel = {\n    none: 0,\n    search: 1,\n    full: 2,\n} as const;\n\nconst items = {\n    client: [\n        { level: \"none\", icon: faBan, text: \"Client code has no access to this table\" },\n        { level: \"search\", icon: faEye, text: \"Client code can search this table\" },\n        { level: \"full\", icon: faPen, text: \"Client code can search, edit and delete\" },\n    ],\n    server: [\n        { level: \"none\", icon: faBan, text: \"Server code has no access to this table\" },\n        { level: \"search\", icon: faEye, text: \"Server code can search this table\" },\n        { level: \"full\", icon: faPen, text: \"Server code can search, edit and delete\" },\n    ],\n} as const;\n\nconst getAccessMenuItems = (type: \"client\" | \"server\", access: Access) => {\n    const selected = items[type][accessLevel[access]];\n    return [items[type], selected] as const;\n};\n\nconst Permissions = ({ type, meta }: { type: \"client\" | \"server\"; meta: TMeta }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { appId, tableMappingId, tableMapping, currentTable } = meta!;\n    const access = currentTable[type];\n    const [itemDescriptors, selected] = getAccessMenuItems(type, access);\n\n    const onSelect = useEvent(async (level: Access) => {\n        const update = { ...currentTable, [type]: level } as CurrentTable;\n        await updateTableAccess(accessFromTable(appId, tableMapping, update));\n        await dispatch(ingestOldIDESchemaUpdate(currentTable.id, \"updateAccess\", { ...update, tableMappingId }));\n        dispatch(invalidateTableSchema(tableMappingId));\n    });\n\n    const menuItems = useCallback(\n        () => [...itemDescriptors.map(({ text, icon, level }) => [text, () => onSelect(level), icon])] as MenuItems,\n        []\n    );\n    // const variant = type === \"client\" ? \"primary\" : \"secondary\";\n    return (\n        <DropdownMenu\n            align=\"right\"\n            render={(showMenu, anchor) => (\n                <div>\n                    <Button\n                        variant=\"outlined\"\n                        icon={selected.icon}\n                        onClick={(e) => showMenu(null, e.currentTarget)}\n                        small>\n                        <div className=\"flex gap-2 truncate text-ellipsis\">\n                            {startCase(type)}\n                            <FontAwesomeIcon icon={faAngleDown} />\n                        </div>\n                    </Button>\n                    {anchor}\n                </div>\n            )}\n            items={menuItems}\n        />\n    );\n};\n\nconst toSafePythonName = (proposedName: string, tableMapping: TableMapping, currentTable: CurrentTable) => {\n    const baseName = proposedName\n        .replace(/[^A-z0-9]/g, \"_\")\n        .replace(/^[0-9]/, \"_$&\")\n        .toLowerCase();\n\n    let name = baseName;\n    let nameN = 2;\n\n    const alreadyExists = (name: string) => {\n        for (const t of tableMapping.tables) {\n            if (t.python_name === name && t !== currentTable) {\n                return true;\n            }\n        }\n        return false;\n    };\n\n    while (alreadyExists(name)) {\n        name = baseName + \"_\" + nameN++;\n    }\n    return name;\n};\n\nconst PythonName = ({ meta }: { meta: TMeta }) => {\n    const { appId, currentTable, tableMapping, tableMappingId } = meta;\n    const dispatch = useDispatch<AnvilDispatch>();\n    const [nameBuffer, setNameBuffer] = useStateWithReset(currentTable.python_name);\n    const [key, setKey] = useReducer(() => getRandomString(), \"init-key\");\n\n    const onSave = useEvent(async (name: string) => {\n        const pythonName = toSafePythonName(name, tableMapping!, currentTable);\n        if (pythonName === nameBuffer) {\n            // otherwise the NodeRenamer won't rerender since the name hasn't changed\n            setKey();\n        } else {\n            setNameBuffer(pythonName);\n            const update = { ...currentTable, python_name: pythonName } as CurrentTable;\n            await updateTableAccess(accessFromTable(appId, tableMapping, update));\n            await dispatch(ingestOldIDESchemaUpdate(currentTable.id, \"updateAccess\", { ...update, tableMappingId }));\n            dispatch(invalidateTableSchema(tableMappingId));\n        }\n    });\n\n    const onCancel = useEvent(() => {\n        setNameBuffer(currentTable.python_name);\n    });\n\n    return (\n        <div className=\"flex items-center justify-end p-3 font-mono select-all dark:text-white\">\n            <div>app_tables.</div>\n            <NodeRenamer\n                small\n                autoFocus={false}\n                key={key}\n                name={nameBuffer}\n                onRename={onSave}\n                onCancel={onCancel}\n                className={\"min-w-32\"}\n            />\n        </div>\n    );\n};\n\nconst DeleteButton = ({ table }: ToolbarProps) => {\n    const { footerId, isSomeCellSelected, isSomeColSelected, selectedCells, selectedCols } = table.options.meta!;\n    const hasSelectedRows = table.getIsSomeRowsSelected();\n    const hasSelectedCells = isSomeCellSelected() && selectedCells[0].row !== footerId;\n    const hasSelectedCols = isSomeColSelected();\n\n    const deleteSelectedRows = useDeleteRows(table);\n    const deleteSelectedCols = useDeleteCols(table);\n    const deleteSelectedCells = useDeleteCells(table);\n\n    const onDeleteClick = useEvent(async () => {\n        if (hasSelectedRows) {\n            deleteSelectedRows();\n        } else if (hasSelectedCols) {\n            deleteSelectedCols();\n        } else if (hasSelectedCells) {\n            deleteSelectedCells();\n        }\n    });\n\n    const hasSelected = hasSelectedCells || hasSelectedCols || hasSelectedRows;\n\n    const getPrefix = (type: string) => (type === \"cell\" ? \"Clear\" : \"Delete\");\n\n    const getToolTip = (type: string, total: number) => `${getPrefix(type)} ${total} ${type}${total > 1 ? \"s\" : \"\"}`;\n\n    const deleteTooltip = hasSelectedCells\n        ? getToolTip(\"cell\", selectedCells.length)\n        : hasSelectedCols\n          ? getToolTip(\"column\", selectedCols.length)\n          : hasSelectedRows\n            ? getToolTip(\"row\", table.getSelectedRowModel().rows.length)\n            : \"Nothing selected\";\n\n    return hasSelected ? (\n        <>\n            <ToolbarButton text={deleteTooltip} onClick={onDeleteClick} icon={faTrashAlt} variant=\"danger\" />\n            <div className={\"min-w-4 grow\"} />\n        </>\n    ) : null;\n};\n\nconst Sort = ({ table }: { table: TTable }) => {\n    const meta = table.options.meta!;\n    const { columnSorting } = meta;\n    const numSorts = columnSorting.length;\n    return (\n        <Popover>\n            <PopoverTrigger asChild>\n                <ToolbarButton\n                    preventDefaultClick={false}\n                    icon={faArrowUpArrowDown}\n                    text={\"Sort\"}\n                    variant={numSorts ? \"highlight2\" : undefined}>\n                    {numSorts ? (\n                        <span className=\"ml-4 rounded-md border border-white px-2 py-1 dark:border-black\">\n                            {numSorts}\n                        </span>\n                    ) : null}\n                </ToolbarButton>\n            </PopoverTrigger>\n            <PopoverContent className=\"max-h-[50vh] w-fit overflow-y-auto\">\n                <SortModalContent table={table} />\n            </PopoverContent>\n        </Popover>\n    );\n};\n\nconst Filter = ({ table }: { table: TTable }) => {\n    const { tableId } = table.options.meta!;\n    // const sortArray = useSelector((state) => getSort(state, tableId));\n    const numFilters = 1;\n    const onClick = useEvent(() => {});\n    return (\n        <ToolbarButton onClick={onClick} icon={faBarsFilter} text={\"Filter\"} tooltip=\"Filter data\">\n            {numFilters ? <span className=\"ml-4 rounded-md border border-white px-2 py-1\">{numFilters}</span> : null}\n        </ToolbarButton>\n    );\n};\n\nexport const HiddenColumnsContent = ({ table }: { table: TTable }) => {\n    const { currentTable } = table.options.meta!;\n    const { columns } = currentTable;\n    const columnOrderedByName = useMemo(() => {\n        const colNames = Object.entries(columns).map(([colId, { name }]) => ({ colId, name }));\n        return sortBy(colNames, [\"name\"]);\n    }, [currentTable]);\n    return (\n        <div className=\"flex min-w-96 flex-col gap-4\">\n            <div className=\"flex w-full items-center justify-center gap-4\">\n                <Button small className=\"font-medium\" onClick={() => table.toggleAllColumnsVisible()}>\n                    {table.getIsAllColumnsVisible() ? \"Hide All\" : \"Show All\"}\n                </Button>\n            </div>\n            <div className=\"flex flex-col gap-4\">\n                {columnOrderedByName.map(({ colId, name }) => {\n                    const column = table.getColumn(colId);\n                    if (!column) return null;\n                    const checked = column.getIsVisible();\n                    const onChange = () => {\n                        column.toggleVisibility();\n                    };\n                    // TODO - maybe show the type here\n                    return (\n                        <CheckBox key={colId} className=\"text-lg font-medium\" onChange={onChange} checked={checked}>\n                            {name}\n                        </CheckBox>\n                    );\n                })}\n            </div>\n        </div>\n    );\n};\n\nconst HiddenColumns = ({ table }: { table: TTable }) => {\n    const { hiddenColumns } = table.options.meta!;\n    const numHidden = Object.values(hiddenColumns).filter((v) => !v).length;\n\n    return (\n        <Popover>\n            <PopoverTrigger asChild>\n                <ToolbarButton\n                    preventDefaultClick={false}\n                    icon={faTableColumns}\n                    text={numHidden ? \"Hidden\" : \"Columns\"}\n                    variant={numHidden ? \"highlight2\" : undefined}>\n                    {numHidden ? (\n                        <span className=\"ml-4 rounded-md border border-white px-2 py-1 dark:border-black\">\n                            {numHidden}\n                        </span>\n                    ) : null}\n                </ToolbarButton>\n            </PopoverTrigger>\n            <PopoverContent className=\"max-h-[50vh] w-fit overflow-y-auto\">\n                <HiddenColumnsContent table={table} />\n            </PopoverContent>\n        </Popover>\n    );\n};\n\nconst TableIndexes = ({ table }: { table: Table }) => {\n    const features = useSelector(getFeatures);\n    const tableMappings = useSelector(getAllTableMappings);\n    const tabs = useSelector(getTabs);\n    const currentTabId = useSelector(getCurrentTabId);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const [currentTable, tableMappingId] = useMemo(() => {\n        const tab = tabs.find((tab) => tab.id === currentTabId);\n        const navTarget = tab?.navTarget;\n\n        if (!navTarget || navTarget.type !== \"DB_TABLE\") {\n            return [undefined, undefined] as const;\n        }\n\n        const tableMappingId = navTarget.tableMappingId;\n\n        const mapping = tableMappings?.find((m) => m.table_mapping_id === tableMappingId);\n        const mappingTables = mapping?.tables || [];\n\n        const currentTableIndex = mappingTables.findIndex((t) => t.id === navTarget.tableId);\n\n        return [mappingTables[currentTableIndex], tableMappingId] as const;\n    }, [tableMappings, tabs, currentTabId]);\n\n    const onClick = useEvent(() => {\n\n        if (supportsIndexing(features, currentTable!)){\n            dispatch(openTableIndexesModal(tableMappingId, currentTable!));\n        } else {\n            dispatch(modal(\"upgradePrompt\", { featureId: currentTable!.split ? \"db-indexes-split\" : \"db-indexes\" }));\n        }\n    });\n    //not putting upgrade badge here cuz it's too huge for this button.\n    return (<ToolbarButton icon={faListOl} onClick={onClick} text={\"Table Indexes\"}/>);\n};\n\nconst Reset = ({ table }: { table: TTable }) => {\n    const { columnSorting, setColumnSorting, hiddenColumns, setHiddenColumns } = table.options.meta!;\n    const hasSortedFields = !!columnSorting.length;\n    const hasHiddenColumns = !!Object.values(hiddenColumns).filter((v) => !v).length;\n    const onClick = useEvent(() => {\n        setColumnSorting([]);\n        setHiddenColumns({});\n    });\n\n    return hasSortedFields || hasHiddenColumns ? (\n        <ToolbarButton onClick={onClick} icon={faTimesCircle} variant=\"hidden\" text=\"Reset\" />\n    ) : null;\n};\n\nconst ExtraMenuOptions = ({ table }: ToolbarProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { appId, tableMappingId, tableId, onRefresh, currentTable } = table.options.meta!;\n\n    const onDeleteAllRows = useEvent(async () => {\n        const c = await dispatch(modal(\"deleteAllRows\", { tableName: currentTable.name }));\n        if (c) {\n            await deleteAllRows(appId, tableMappingId, tableId);\n            onRefresh();\n        }\n    });\n\n    const onDownload = useEvent(async () => {\n        window.open(getTableDownloadUrl(appId, tableMappingId, tableId));\n    });\n\n    const onInsertColumn = useInsertColumn({ table } as HeaderInfo);\n\n    const menuItems = useCallback(\n        (): MenuItems => [\n            [\"Insert column\", onInsertColumn, faPlus],\n            [\"Download as CSV\", onDownload, faDownload],\n            [\"Delete all rows\", onDeleteAllRows, faTrashAlt],\n        ],\n        []\n    );\n\n    return (\n        <DropdownMenu\n            render={(showMenu, anchor) => (\n                <div>\n                    <ToolbarButton\n                        onClick={(e) => showMenu(null, e.currentTarget)}\n                        icon={faEllipsisV}\n                        variant=\"outlined\"\n                    />\n                    {anchor}\n                </div>\n            )}\n            items={menuItems}\n        />\n    );\n};\n\nconst Separator = () => {\n    return <div className=\"mx-8 h-1/2 border-l border-light-bg4 dark:border-dark-bg3\" />;\n};\n\nexport function Toolbar({ table, options = {} }: ToolbarProps) {\n    const meta = table.options.meta!;\n    const { pythonName = true } = options;\n    const { onRefresh, readonly, currentTable } = meta;\n\n    const containerRef = useRef<HTMLDivElement>(null);\n\n    const [canScrollLeft, setCanScrollLeft] = useState(false);\n    const [canScrollRight, setCanScrollRight] = useState(false);\n\n    const checkScrollDirections = useEvent(() => {\n        if (!containerRef.current) return;\n        const containerWidth = containerRef.current.offsetWidth;\n        const contentWidth = containerRef.current.scrollWidth;\n        const scrollLeft = containerRef.current.scrollLeft;\n\n        setCanScrollRight(scrollLeft < contentWidth - containerWidth - 1);\n        setCanScrollLeft(scrollLeft > 0);\n    });\n\n    const onScrollClick = useEvent((delta: number) => {\n        const container = containerRef.current;\n        if (!container) return;\n        const containerWidth = container.offsetWidth;\n        const scrollLeft = container.scrollLeft;\n\n        const newScrollPosition = scrollLeft + (delta * containerWidth) / 2;\n\n        container.scroll({\n            left: newScrollPosition,\n            behavior: \"smooth\",\n        });\n    });\n\n    useResizeObserver(containerRef, () => {\n        checkScrollDirections();\n    });\n\n    const canScroll = canScrollLeft || canScrollRight;\n    const isSplit = !!meta.currentTable.split;\n    const [storageModeTooltip, storageModeTooltipAnchorRef] = useTooltip(\n        `This table uses ${isSplit ? \"Faster\" : \"Legacy\"} Storage mode. Click to learn more.`,\n        \"bottom\",\n        { delay: 0 }\n    );\n\n    return (\n        <TabToolbar>\n            {canScroll && (\n                <Button size={\"small\"} className={\"mr-1\"} disabled={!canScrollLeft} onClick={() => onScrollClick(-1)}>\n                    <FontAwesomeIcon icon={faCaretLeft} />\n                </Button>\n            )}\n\n            <div\n                ref={containerRef}\n                style={{ scrollbarWidth: \"none\" }}\n                className={\"flex h-full grow items-center overflow-x-auto scrollbar:hidden\"}\n                onScroll={checkScrollDirections}>\n                <div className=\"flex items-center gap-4\">\n                    <ToolbarButton\n                        onClick={onRefresh}\n                        icon={faRefresh}\n                        variant=\"outlined\"\n                        tooltip=\"Refresh data\"\n                        text=\"Refresh\"\n                    />\n                    {!readonly && <ExtraMenuOptions table={table} />}\n                </div>\n                <Separator />\n                <div className=\"flex items-center gap-4\">\n                    <Sort table={table} />\n                    {/* <Filter table={table} /> */}\n                    <HiddenColumns table={table} />\n                    <TableIndexes table={currentTable} />\n                    <Reset table={table} />\n                </div>\n                <Separator />\n                <Link ref={storageModeTooltipAnchorRef} className=\"flex items-center gap-4\" to={\"/docs/data-tables/faster-storage\"} target=\"_blank\">\n                    {storageModeTooltip}\n                    <FontAwesomeIcon\n                        fixedWidth\n                        className={\"opacity-80 text-[1.6rem]\"}\n                        icon={meta.currentTable.split ? faRectangleHistoryCirclePlus : faRectangleHistory}\n                    />\n                </Link>\n                <Separator />\n\n                <div className=\"flex grow items-center gap-4\">\n                    {!readonly && (\n                        <>\n                            <DeleteButton table={table} />\n                            <div className={\"grow\"} />\n                            <div className={\"flex items-center gap-4\"}>\n                                <div className=\"flex items-center\">\n                                    <p className={\"text-[1.2rem] font-semibold text-light-bg7\"}>Permissions</p>\n                                    <HelpLink\n                                        inline={true}\n                                        url=\"docs/data-tables/data-security#permissions\"\n                                        className=\"ml-2\"\n                                    />\n                                </div>\n\n                                <Permissions type=\"client\" meta={meta} />\n                                <Permissions type=\"server\" meta={meta} />\n                            </div>\n                            {pythonName && <PythonName meta={meta} />}\n                        </>\n                    )}\n                </div>\n            </div>\n\n            {canScroll && (\n                <Button size={\"small\"} className={\"ml-1\"} disabled={!canScrollRight} onClick={() => onScrollClick(1)}>\n                    <FontAwesomeIcon icon={faCaretRight} />\n                </Button>\n            )}\n        </TabToolbar>\n    );\n}\n\nexport default Toolbar;\n","import React, { InputHTMLAttributes, useEffect, useLayoutEffect, useRef } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { useDispatch } from \"react-redux\";\nimport { faEdit, faLink, faSquare, faTrashAlt } from \"@fortawesome/pro-light-svg-icons\";\nimport { faCheckSquare, faTimes } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { format, parseISO } from \"date-fns\";\nimport { deleteMedia, getTableRow, updateTableRow } from \"@/api/tables\";\nimport DropdownMenu, { MenuItems, ShowMenuCallback } from \"@/components/reusable/DropdownMenu\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { confirmWithCheckBox } from \"@/controllers/modals\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { ColumnSpec } from \"@/types/database\";\nimport { checkMeta } from \"@/util\";\nimport useEffectEvent from \"@/util/useEffectEvent\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { useLongPress } from \"@/util/useLongPress\";\nimport { AnvilRow, CellInfo, TTable } from \"../types\";\nimport EditingCell, { isoToDateAndOffset } from \"./EditingCell\";\nimport { MediaCell } from \"./MediaCell\";\n\nexport const useDeleteCells = (table: TTable) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const { appId, tableId, tableMappingId, selectedCells, refocus } = table.options.meta!;\n\n    const queryKey = [\"table-data\", { appId, tableId }, \"page-data\"];\n    const queryClient = useQueryClient();\n\n    type ChangedRows = Record<string, { row: AnvilRow; updater: () => Promise<void> }>;\n\n    const { mutate } = useMutation({\n        mutationFn({ changedRows }: { changedRows: ChangedRows }) {\n            return Promise.all(Object.values(changedRows).map(({ updater }) => updater()));\n        },\n        onMutate({ changedRows }) {\n            const prevData = queryClient.getQueriesData({ queryKey });\n            const rowIds = Object.keys(changedRows).map(Number);\n            queryClient.setQueriesData({ queryKey }, (prev: any) => {\n                const pages = prev.pages;\n                const newPages = pages.map((pageData: any) => {\n                    const newRows = pageData.rows.map((row: any) =>\n                        !rowIds.includes(row.id) ? row : changedRows[row.id].row\n                    );\n                    return { ...pageData, rows: newRows };\n                });\n                return { ...prev, pages: newPages };\n            });\n            return { prevData };\n        },\n        onError() {\n            // could reset the query data here\n        },\n        onSettled(data, error, { changedRows }) {\n            // update any row cache\n            Object.keys(changedRows).forEach((rowId) => {\n                queryClient.invalidateQueries({\n                    queryKey: [\"table-data\", { appId, tableId }, \"row-data\", Number(rowId)],\n                });\n            });\n        },\n    });\n\n    const onDeleteCells = useEvent(async () => {\n        const cellIdentifier = selectedCells.length > 1 ? \"these cells\" : \"this cell\";\n        const c = await dispatch(\n            confirmWithCheckBox(\n                \"Clear data?\",\n                `Are you sure you want to clear the content of ${cellIdentifier}?`,\n                `Yes, I want to clear the data from ${cellIdentifier}. I know I cannot undo this action.`,\n                \"Clear\",\n                \"Cancel\"\n            )\n        );\n        if (!c) return refocus(); // refocuses the view\n        const changedRows: ChangedRows = {};\n        for (const { row: rowId, col: colId } of selectedCells) {\n            const type = table.getColumn(colId)?.columnDef.meta?.original?.type;\n            const original = table.getRow(rowId).original;\n            const row = { ...original, [colId]: null };\n            if (type === \"media\") {\n                changedRows[rowId] = { row, updater: () => deleteMedia(appId, tableMappingId, tableId, rowId, colId) };\n            } else {\n                changedRows[rowId] = { row, updater: () => updateTableRow(appId, tableMappingId, tableId, rowId, row) };\n            }\n        }\n        mutate({ changedRows });\n    });\n    return onDeleteCells;\n};\n\nexport const CellCheckbox = (props: InputHTMLAttributes<HTMLInputElement>) => (\n    <input className=\"border-white accent-primary-darker\" type=\"checkbox\" {...props} />\n);\n\nexport const NullCell = ({ children }: React.PropsWithChildren) => (\n    <i className=\"w-full text-center font-mono text-slate-400\">{children || \"None\"}</i>\n);\n\ninterface CellDataProps {\n    info: CellInfo;\n    type: ColumnSpec[\"type\"];\n}\n\nconst LINKED_COLUMNS = [\"string\", \"number\", \"bool\", \"date\", \"datetime\"];\n\nconst LinkedRowBadge = ({ children, onDelete }: React.PropsWithChildren<{ onDelete?: () => void }>) => {\n    return (\n        <div className=\"flex cursor-auto items-center gap-2 truncate overflow-hidden rounded-md border border-primary bg-primary px-2 text-lg text-white dark:bg-primary-700\">\n            <FontAwesomeIcon icon={faLink} fixedWidth />\n            <span className=\"truncate\">{children}</span>\n            {onDelete && (\n                <LinkInternal onClick={onDelete}>\n                    <FontAwesomeIcon icon={faTimes} fixedWidth />\n                </LinkInternal>\n            )}\n        </div>\n    );\n};\n\nexport const RowLinkSingle = ({ value, info, onDelete }: { value: any; info: CellInfo; onDelete?: () => void }) => {\n    const { id } = value;\n    const { appId, tableMappingId } = info.table.options.meta!;\n    const { namedColId } = info.column.columnDef.meta!;\n    const [tableId, rowId] = id.slice(1, -1).split(\",\").map(Number) as [number, number];\n\n    const { data, isLoading, isError } = useQuery({\n        queryKey: [\"table-data\", { appId, tableId, tableMappingId }, \"row-data\", rowId] as const,\n        queryFn: () => {\n            return getTableRow(appId, tableMappingId, tableId, rowId);\n        },\n        retryDelay: 200,\n        refetchOnWindowFocus: false,\n        enabled: !!appId,\n    });\n\n    if (isError) return <LinkedRowBadge onDelete={onDelete}>Unknown Row</LinkedRowBadge>;\n    if (isLoading) return <LinkedRowBadge onDelete={onDelete}>Loading...</LinkedRowBadge>;\n\n    return (\n        <LinkedRowBadge onDelete={onDelete}>\n            {namedColId ? String(data?.[namedColId] ?? \"\\u00A0\") : \"Unnamed Row\"}\n        </LinkedRowBadge>\n    );\n};\n\nexport const RowLink = ({ value, info }: { value: any; info: CellInfo }) => {\n    return (\n        <div className=\"flex w-full items-center gap-2 overflow-hidden\">\n            {Array.isArray(value) ? (\n                value.length ? (\n                    value.map((val: any, i) => <RowLinkSingle key={i} value={val} info={info} />)\n                ) : (\n                    <NullCell>Empty List</NullCell>\n                )\n            ) : (\n                <RowLinkSingle value={value} info={info} />\n            )}\n        </div>\n    );\n};\n\nconst shortenString = (s: string) => (s.length < 100 ? s : s.slice(0, 100) + \"…\");\n\nconst JsonCell = React.memo(({ value }: { value: any }) => {\n    const s = JSON.stringify(value);\n    return <span className=\"truncate font-mono\">{shortenString(s)}</span>;\n});\nJsonCell.displayName = \"JsonCell\";\n\nconst StringCell = React.memo(({ value }: { value: any }) => {\n    return <div className=\"line-clamp-1 w-full break-words whitespace-pre-line\">{shortenString(value)}</div>;\n});\nStringCell.displayName = \"StringCell\";\n\nfunction CellData({ info, type }: CellDataProps) {\n    let val = info.getValue();\n    if (val === undefined) {\n        // might happen when adding a new column\n        val = null;\n        info.row.original[info.column.id] = null;\n    }\n\n    if (val === null) {\n        return type === \"media\" ? <MediaCell info={info} value={val} /> : <NullCell />;\n    }\n    switch (type) {\n        case \"number\":\n            return <span className=\"block w-full text-right\">{val}</span>;\n        case \"bool\":\n            return (\n                <div className=\"@container flex w-full items-center justify-center\">\n                    <FontAwesomeIcon\n                        fixedWidth\n                        className={\"text-4xl text-slate-400\"}\n                        icon={val ? faCheckSquare : faSquare}\n                    />\n                    <div className={\"ml-4 w-[3rem] text-slate-400 @max-[10rem]:hidden\"}>{val ? \"True\" : \"False\"}</div>\n                </div>\n            );\n        case \"string\":\n            return <StringCell value={val} />;\n        case \"date\":\n            return <span className=\"w-full truncate\">{format(new Date(parseISO(val)), \"dd MMM yyyy\")}</span>;\n        case \"datetime\":\n            const { value: date, offset } = isoToDateAndOffset(val);\n            return <span className=\"w-full truncate\">{format(date, `dd MMM yyyy, HH:mm:ss.SSS '${offset}'`)}</span>;\n        case \"media\":\n            return <MediaCell value={val} info={info} />;\n        case \"liveObject\":\n        case \"liveObjectArray\":\n            return <RowLink value={val} info={info} />;\n        default:\n            return <JsonCell value={val} />;\n    }\n}\n\nexport function CellInner({ info, type, showMenu }: CellProps & { showMenu: ShowMenuCallback }) {\n    const {\n        updateSelectedCells,\n        isCellSelected,\n        isEditingCell,\n        resetSelected,\n        readonly,\n        isColSelected,\n        tableContainerRef,\n        focusValue,\n    } = info.table.options.meta!;\n\n    const onUpdateSelectedCell = (a: Parameters<typeof updateSelectedCells>[0]) => updateSelectedCells(a, info);\n\n    const isLoadedRef = useRef(false);\n    const isSelected = isCellSelected(info.cell) && !readonly;\n    const isEditing = isEditingCell(info.cell) && !readonly;\n    const isMedia = type === \"media\";\n\n    const colId = info.column.id;\n    const rowId = info.row.id;\n\n    const onClick: React.MouseEventHandler<HTMLDivElement> = useEvent((e) => {\n        if (readonly || isEditing) return;\n        onUpdateSelectedCell({\n            cell: { row: rowId, col: colId, edit: false },\n            additive: checkMeta(e),\n            inclusive: e.shiftKey,\n        });\n    });\n\n    const cellRef = useRef<HTMLDivElement>(null!);\n\n    const focusCellEffect = useEffectEvent(() => {\n        if (isSelected && !isEditing) {\n            cellRef.current.focus({ preventScroll: !isLoadedRef.current });\n            if (info.row.index === 0 && tableContainerRef.current) {\n                // sometimes the top row is hidden behind the sticky header\n                tableContainerRef.current.scrollTop = 0;\n            }\n        }\n    });\n\n    useLayoutEffect(() => {\n        focusCellEffect();\n    }, [isSelected, isEditing, focusValue]);\n\n    useEffect(() => {\n        isLoadedRef.current = true;\n    }, []);\n\n    const onDeleteCells = useDeleteCells(info.table);\n\n    const onKeyDown: React.KeyboardEventHandler<HTMLDivElement> = useEvent((e) => {\n        // todo - do we always want to prevent default here? possibly not\n        if (readonly || isEditing) return;\n        if (e.defaultPrevented) return;\n\n        switch (e.key) {\n            case \"ArrowUp\": {\n                e.preventDefault();\n                return onUpdateSelectedCell({ dir: \"up\" });\n            }\n            case \"ArrowDown\": {\n                e.preventDefault();\n                return onUpdateSelectedCell({ dir: \"down\" });\n            }\n            case \"ArrowLeft\": {\n                e.preventDefault();\n                return onUpdateSelectedCell({ dir: \"left\" });\n            }\n            case \"ArrowRight\": {\n                e.preventDefault();\n                return onUpdateSelectedCell({ dir: \"right\" });\n            }\n            case \"Enter\": {\n                e.preventDefault();\n                return onEditMode();\n            }\n            case \"Tab\": {\n                e.preventDefault();\n                if (e.shiftKey) {\n                    return onUpdateSelectedCell({ dir: \"left\", edit: true });\n                } else {\n                    return onUpdateSelectedCell({ dir: \"right\", edit: true });\n                }\n            }\n            case \"Escape\": {\n                e.preventDefault();\n                return resetSelected(info);\n            }\n            case \"Delete\":\n            case \"Backspace\": {\n                e.preventDefault();\n                return onDeleteCells();\n            }\n        }\n    });\n\n    const onEditMode = useEvent(() => {\n        if (readonly) return;\n        if (!isEditing) {\n            onUpdateSelectedCell({ cell: { row: rowId, col: colId, edit: true } });\n        }\n    });\n\n    const colIsSelected = isColSelected(colId);\n    const isLastRow = colIsSelected && info.table.getRowModel().rows.at(-1) === info.row;\n\n    const onContextMenu = useEvent((e: React.MouseEvent | React.TouchEvent | MouseEvent | TouchEvent) => {\n        e.preventDefault();\n        if (readonly) return;\n        if (!isCellSelected(info.cell)) {\n            flushSync(() => {\n                onUpdateSelectedCell({ cell: { row: rowId, col: colId }, inclusive: false, additive: false });\n            });\n        }\n        showMenu(e, cellRef.current);\n    });\n    const longPressProps = useLongPress(onContextMenu);\n\n    return (\n        <div\n            ref={cellRef}\n            role=\"gridcell\"\n            className={cx(\"relative flex flex-1 items-center\", {\n                \"cursor-pointer\": !isEditing && !isMedia,\n                \"truncate p-2\": !isEditing,\n                \"bg-primary-50/40 dark:bg-primary-700/50\": (isSelected && !isEditing) || colIsSelected,\n                \"\": (isSelected && !isEditing) || colIsSelected,\n                // \"before:absolute before:inset-0 before:h-full before:w-full before:border-2 before:border-primary\":\n                //     isSelected && !isEditing,\n                // \"bg-primary-50\": // before:absolute before:inset-0 before:h-full before:w-full before:border-l-2 before:border-r-2 before:border-primary\":\n                //     colIsSelected,\n                \"before:border-b-2\": colIsSelected && isLastRow,\n            })}\n            onClick={onClick}\n            onContextMenu={onContextMenu}\n            {...longPressProps}\n            onDoubleClick={onEditMode}\n            tabIndex={0}\n            onKeyDownCapture={onKeyDown}>\n            {isEditing ? <EditingCell info={info} type={type} /> : <CellData info={info} type={type} />}\n        </div>\n    );\n}\n\ninterface CellProps {\n    info: CellInfo;\n    type: ColumnSpec[\"type\"];\n}\n\nexport function Cell({ info, type }: CellProps) {\n    const { selectedCells, updateSelectedCells } = info.table.options.meta!;\n    const onDelete = useDeleteCells(info.table);\n    const numCells = selectedCells.length;\n    const items: MenuItems = [[`Clear ${numCells} cell${numCells > 1 ? \"s\" : \"\"}`, () => onDelete(), faTrashAlt]];\n    if (numCells === 1) {\n        items.push([\n            \"Edit Cell\",\n            () => {\n                updateSelectedCells({ cell: { row: info.row.id, col: info.column.id, edit: true } }, info);\n            },\n            faEdit,\n        ]);\n    }\n\n    return (\n        <DropdownMenu\n            render={(showMenu) => <CellInner info={info} type={type} showMenu={showMenu} />}\n            items={() => items}\n        />\n    );\n}\n\nexport default Cell;\n","import React, { useEffect, useLayoutEffect, useReducer, useRef, useState } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { useDispatch } from \"react-redux\";\nimport { faArrowsMaximize } from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { format, parseISO } from \"date-fns\";\nimport { updateTableRow } from \"@/api/tables\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { TextArea, TextBox } from \"@/components/reusable/Forms\";\nimport { DatePicker, DateTimePickerWithOffset } from \"@/components/reusable/datepicker\";\nimport { Offset } from \"@/components/reusable/datepicker/OffsetPicker\";\nimport { markUnsaved } from \"@/controllers/app\";\nimport { alert, modal } from \"@/controllers/modals\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { ColumnSpec } from \"@/types/database\";\nimport { useEffectAsync, usePartialReducer, useResizeObserverTimeout } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport type { AnvilRow, CellInfo, HeaderInfo, TInfo } from \"../types\";\nimport { NullCell, RowLink } from \"./Cell\";\nimport { FooterEditingProps } from \"./FooterEditCell\";\nimport LazyJsonEditor from \"./LazyJsonEditor\";\nimport { MediaCell } from \"./MediaCell\";\n\nconst useSetCachedEditState = <T extends { current: any }>(info: TInfo, ref: T, get: (v: T[\"current\"]) => any) => {\n    const { setCachedEditState } = info.table.options.meta!;\n    useEffect(() => {\n        const current = ref.current;\n        return () => {\n            setCachedEditState(get(current));\n        };\n    });\n};\n\nconst useInputKeyDown = (info: CellInfo, onSave: (cb?: () => void) => void, value?: any) => {\n    const { updateSelectedCells } = info.table.options.meta!;\n\n    const onKeyDown: React.KeyboardEventHandler = useEvent((e) => {\n        switch (e.key) {\n            case \"Tab\": {\n                e.preventDefault();\n                let cb;\n                if (e.shiftKey) {\n                    cb = () => updateSelectedCells({ dir: \"left\", edit: true }, info);\n                } else {\n                    cb = () => updateSelectedCells({ dir: \"right\", edit: true }, info);\n                }\n                onSave(cb);\n                break;\n            }\n            case \"Enter\": {\n                if (e.shiftKey) {\n                    e.stopPropagation();\n                    // todo;\n                    return;\n                } else {\n                    e.preventDefault();\n                    onSave(() => updateSelectedCells({ dir: \"down\", edit: true }, info));\n                }\n                break;\n            }\n            case \"Backspace\":\n            case \"Delete\": {\n                e.stopPropagation();\n                break;\n            }\n            case \"Escape\": {\n                updateSelectedCells({ edit: false }, info);\n                break;\n            }\n        }\n    });\n\n    return onKeyDown;\n};\n\nexport interface Variables {\n    info: TInfo;\n    data: AnvilRow;\n}\n\nexport const useUpdateRowMutation = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const queryClient = useQueryClient();\n    const getQueryKeyParts = (info: TInfo) => {\n        const { appId, tableMappingId, tableId } = info.table.options.meta!;\n        return [\"table-data\", { appId, tableId }] as const;\n    };\n\n    return useMutation({\n        mutationFn({ data, info }: Variables) {\n            const { appId, tableMappingId, tableId } = info.table.options.meta!;\n            const rowId = data.id;\n            return updateTableRow(appId, tableMappingId, tableId, rowId, data);\n        },\n        onMutate({ data, info }) {\n            const { appId, tableMappingId, tableId } = info.table.options.meta!;\n            const key = \"update-row-\" + data.id;\n            const markSaved = dispatch(markUnsaved(key));\n            const rowId = data.id;\n            const queryKey = [...getQueryKeyParts(info), \"page-data\"];\n            const prevData = queryClient.getQueriesData({ queryKey });\n            queryClient.setQueriesData({ queryKey }, (prev: any) => {\n                const { pages } = prev;\n                const newPages = pages.map((pageData: any) => {\n                    const newRows = pageData.rows.map((row: any) => (row.id !== rowId ? row : data));\n                    return { ...pageData, rows: newRows };\n                });\n                return { ...prev, pages: newPages };\n            });\n            return { prevData, markSaved };\n        },\n        onError(e: Error, variables: Variables, context) {\n            let msg = `Could not save row: ${e.message ?? \"Unknown error\"}`;\n            if (e.message?.includes(\"quota\")) {\n                msg += \"\\n\\nPlease see https://anvil.works/pricing for information about Data Tables quotas.\";\n            }\n            dispatch(alert(\"Save failed\", msg));\n            context?.prevData.forEach(([queryKey, queryData]) => {\n                queryClient.setQueryData(queryKey, queryData);\n            });\n        },\n        onSettled(res, error, { data, info }, context) {\n            // invalidate any linked rows\n            queryClient.invalidateQueries({\n                queryKey: [...getQueryKeyParts(info), \"row-data\", data.id],\n            });\n            context?.markSaved();\n        },\n    });\n};\n\nexport const useOnSaveOnBlur = <T,>(info: CellInfo, value: T, convert = (x: T): any => x, isEqual = Object.is) => {\n    const { row, column } = info;\n    const { updateSelectedCells } = info.table.options.meta!;\n\n    const mutation = useUpdateRowMutation();\n\n    const onSave = useEvent(async (onSettled?: () => void) => {\n        const data = row.original;\n        const prev = data[column.id];\n        const convertedValue = convert(value);\n        if (isEqual(prev, convertedValue)) {\n            return onSettled?.();\n        }\n        const newData = { ...data, [column.id]: convertedValue };\n        mutation.mutate({ data: newData, info }, { onSettled });\n    });\n\n    const onBlur = useEvent(() => {\n        // const { relatedTarget } = e;\n        // if (!relatedTarget) return;\n        // if ((relatedTarget as HTMLElement).dataset?.rowResizer != null) return;\n        onSave(() => updateSelectedCells({ edit: false }, info));\n    });\n\n    return { onSave, onBlur };\n};\n\nexport const useAutoFocus = <T extends HTMLInputElement | HTMLTextAreaElement>() => {\n    const inputRef = useRef<T>(null!);\n\n    useEffect(() => {\n        inputRef.current.focus();\n        inputRef.current.select();\n    }, []);\n\n    return inputRef;\n};\n\nexport interface CellEditingProps {\n    type: \"cell\";\n    info: CellInfo;\n    value: any;\n    useOnSaveOnBlur: typeof useOnSaveOnBlur;\n    useInputKeyDown: typeof useInputKeyDown;\n}\n\nexport type EditingProps = CellEditingProps | FooterEditingProps;\n\nexport const useResizableEditingCellRef = (\n    info: TInfo,\n    ref: React.RefObject<HTMLElement | null>,\n    type: \"footer\" | \"cell\"\n) => {\n    const { tableContainerRef, tableBodyRef } = info.table.options.meta!;\n\n    useLayoutEffect(() => {\n        return () => {\n            tableContainerRef.current?.style.removeProperty(\"margin-right\");\n            tableBodyRef.current?.style.removeProperty(\"margin-bottom\");\n        };\n    }, []);\n\n    useResizeObserverTimeout(ref, () => {\n        if (type === \"footer\") return;\n        const tableBody = tableBodyRef.current;\n        const tableContainer = tableContainerRef.current;\n        const el = ref.current;\n        if (!el || !tableContainer || !tableBody) return;\n        const { bottom: tableBottom } = tableBody.getBoundingClientRect();\n        const { right: tableContainerRight } = tableContainer.getBoundingClientRect();\n        const { bottom: cellBottom, right: cellRight } = el.getBoundingClientRect();\n        const marginBottomRequired = cellBottom - tableBottom;\n        const paddingRightRequired = cellRight - tableContainerRight;\n        if (marginBottomRequired > 0) {\n            tableBody.style.marginBottom = marginBottomRequired + \"px\";\n            tableContainer.scrollTop = tableContainer.scrollHeight;\n        } else {\n            tableBody.style.marginBottom = \"\";\n        }\n        if (paddingRightRequired > 0) {\n            tableContainer.style.paddingRight = paddingRightRequired + \"px\";\n            tableContainer.scrollLeft = tableContainer.scrollWidth;\n        } else {\n            tableContainer.style.paddingRight = \"\";\n        }\n    });\n};\n\nexport const TextEditor = ({ type, info, useInputKeyDown, useOnSaveOnBlur, value: dataValue }: EditingProps) => {\n    const { getCachedEditState, updateSelectedCells } = info.table.options.meta!;\n    const [value, setValue] = useState(getCachedEditState() ?? dataValue ?? \"\");\n\n    const onChange: React.ChangeEventHandler<HTMLTextAreaElement> = useEvent((e) => {\n        setValue(e.target.value);\n    });\n\n    const { onSave, onBlur } = useOnSaveOnBlur(info as any, value);\n    const inputRef = useAutoFocus<HTMLTextAreaElement>();\n    const onKeyDown = useInputKeyDown(info as any, onSave, value);\n    const [expanded, setExpanded] = useState(false);\n\n    useSetCachedEditState(info, inputRef, (el) => el?.value);\n\n    useResizableEditingCellRef(info, inputRef, type);\n    const expandRef = useRef<HTMLDivElement>(null);\n\n    useLayoutEffect(() => {\n        if (type === \"footer\") return;\n        const inputEl = inputRef.current;\n        if (!inputEl) return;\n        const height = inputEl.offsetHeight;\n        inputEl.style.height = \"0px\";\n        const newHeight = inputEl.scrollHeight;\n        if (newHeight <= height) {\n            inputEl.style.height = \"100%\";\n        } else {\n            inputEl.style.height = Math.min(newHeight, 200) + 5 + \"px\";\n        }\n    }, []);\n\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const onExpand = async () => {\n        setExpanded(true);\n\n        const selection = { start: inputRef.current.selectionStart, end: inputRef.current.selectionEnd };\n        if (selection.start === 0 && selection.end === inputRef.current.value.length) {\n            selection.end = 0;\n        }\n        const state = { value, selection };\n        const { height, width } = inputRef.current.getBoundingClientRect();\n        const modalReturn = await dispatch(modal(\"dbTextEditor\", { state }));\n        if (modalReturn === undefined) {\n            flushSync(() => {\n                setExpanded(false);\n                setValue(state.value);\n            });\n            inputRef.current.style.height = height + \"px\";\n            inputRef.current.style.width = width + \"px\";\n            inputRef.current.focus();\n            inputRef.current.setSelectionRange(state.selection.start, state.selection.end);\n        } else if (modalReturn === false) {\n            updateSelectedCells({ edit: false }, info);\n        } else {\n            flushSync(() => {\n                setValue(state.value);\n            });\n            onBlur();\n        }\n    };\n\n    const ref = useRef<HTMLDivElement>(null);\n\n    const onBlurIfExpanded: React.FocusEventHandler<HTMLDivElement> = useEvent((e) => {\n        if (expanded) return;\n        const relatedTarget = e.relatedTarget as HTMLElement | null;\n        if (!relatedTarget) return;\n        if (ref.current?.contains(relatedTarget)) return;\n        onBlur();\n    });\n\n    const TA = !expanded && (\n        <div className=\"relative h-full w-fit min-w-full\" onBlur={onBlurIfExpanded}>\n            {type === \"cell\" && (\n                <div ref={expandRef} className=\"absolute top-0 right-0 z-2\">\n                    <Button\n                        className=\"h-8! text-xs!\"\n                        linkClassName=\"rounded-sm! text-xs!\"\n                        small\n                        onClick={onExpand}\n                        variant=\"hidden\">\n                        <FontAwesomeIcon icon={faArrowsMaximize} fixedWidth />\n                    </Button>\n                </div>\n            )}\n            <TextArea\n                className={cx(\"min-h-full min-w-full px-4! py-2! text-lg!\", {\n                    \"resize-none\": type === \"footer\",\n                    resize: type === \"cell\",\n                })}\n                style={{ height: \"100%\" }}\n                rows={1}\n                ref={inputRef}\n                onKeyDown={onKeyDown}\n                onChange={onChange}\n                value={value}\n            />\n        </div>\n    );\n\n    return (\n        <div ref={ref} className=\"relative flex h-full w-full\">\n            {type === \"cell\" ? <div className=\"absolute top-0 left-0 z-1 h-full w-full\">{TA}</div> : TA}\n        </div>\n    );\n};\n\nexport const NumberEditor = ({ info, useInputKeyDown, useOnSaveOnBlur, value: dataValue }: EditingProps) => {\n    const { getCachedEditState } = info.table.options.meta!;\n    const [value, setValue] = useState(getCachedEditState() ?? dataValue ?? \"\");\n    const onChange: React.ChangeEventHandler<HTMLInputElement> = useEvent((e) => {\n        setValue(e.target.value);\n    });\n\n    const { onSave, onBlur } = useOnSaveOnBlur(info as any, value, (v: string) => {\n        const x = Number.parseFloat(v);\n        return isNaN(x) ? null : x;\n    });\n    const inputRef = useAutoFocus<HTMLInputElement>();\n    useSetCachedEditState(info, inputRef, (el) => el?.value);\n    const onKeyDown = useInputKeyDown(info as any, onSave, value);\n\n    return (\n        <TextBox\n            className=\"py-2! pr-2! pl-4! accent-primary\"\n            style={{ height: \"100%\" }}\n            ref={inputRef}\n            onKeyDown={onKeyDown}\n            onChange={onChange}\n            onBlur={onBlur}\n            value={value}\n            type=\"number\"\n        />\n    );\n};\n\nexport const BoolEditor = ({ info, useInputKeyDown, useOnSaveOnBlur, value: dataValue }: EditingProps) => {\n    const { getCachedEditState } = info.table.options.meta!;\n    const [value, setValue] = useState(getCachedEditState() ?? dataValue ?? false);\n\n    const onChange: React.ChangeEventHandler<HTMLInputElement> = useEvent((e) => {\n        setValue(e.target.checked);\n    });\n\n    const { onSave, onBlur: onBlur_ } = useOnSaveOnBlur(info as any, value);\n    const inputRef = useAutoFocus<HTMLInputElement>();\n    const onKeyDown = useInputKeyDown(info as any, onSave, value);\n    const onBlur: React.FocusEventHandler<HTMLDivElement> = useEvent((e) => {\n        if (e.relatedTarget === e.currentTarget) return;\n        if (e.currentTarget?.contains(e.relatedTarget)) return;\n        onBlur_();\n    });\n\n    useSetCachedEditState(info, inputRef, (el) => el?.checked);\n\n    return (\n        <div className=\"@container flex w-full items-center justify-center\" tabIndex={0} onBlur={onBlur}>\n            <div className=\"flex items-center rounded-sm focus-within:outline! focus-within:outline-2! focus-within:outline-offset-2! focus-within:outline-primary!\">\n                <input\n                    className=\"m-0! h-8 w-8 accent-primary-darker\"\n                    ref={inputRef}\n                    onKeyDown={onKeyDown}\n                    onChange={onChange}\n                    checked={value}\n                    type=\"checkbox\"\n                />\n            </div>\n            <div className={\"ml-4 w-[3rem] pl-2 text-slate-400 @max-[10rem]:hidden\"}>{value ? \"True\" : \"False\"}</div>\n        </div>\n    );\n};\n\nexport const DateEditor = ({ info, useOnSaveOnBlur, value: dataValue }: EditingProps) => {\n    const { updateSelectedCells } = info.table.options.meta!;\n\n    const { getCachedEditState } = info.table.options.meta!;\n    const valueRef = useRef<Date | null>(null);\n\n    const [value, setValue] = useReducer(\n        (prev: Date | null, v: Date | null) => {\n            valueRef.current = v;\n            return v;\n        },\n        null,\n        () => {\n            const v = getCachedEditState() ?? dataValue;\n            return v ? new Date(parseISO(v)) : null;\n        }\n    );\n\n    useSetCachedEditState(info, valueRef, (v) => v);\n\n    const onChange = useEvent((d: Date | null) => setValue(d));\n    const { onBlur } = useOnSaveOnBlur(info as any, value, (v: Date | null) => (v ? format(v, \"yyyy-MM-dd\") : null));\n    const onCancel = useEvent(() => {\n        updateSelectedCells({ edit: false }, info);\n    });\n\n    return (\n        <div className=\"h-full w-full\">\n            <DatePicker\n                showIcon={false}\n                format=\"dd MMM yyyy\"\n                onChange={onChange}\n                onConfirm={onBlur}\n                value={value}\n                defaultOpen\n                onCancel={onCancel}\n            />\n        </div>\n    );\n};\n\ntype ValueOffset = { value: Date | null; offset: Offset };\n\nconst INIT_OFFSET: ValueOffset = { value: null, offset: \"+00:00\" };\n\nexport const isoToDateAndOffset = (iso: string) => {\n    const offset = `${iso.slice(-5, -2)}:${iso.slice(-2)}`;\n    const dateStr = iso.slice(0, -5);\n    return { value: new Date(dateStr), offset };\n};\n\nexport const DateTimeEditor = ({ info, useOnSaveOnBlur, value: dataValue }: EditingProps) => {\n    const { updateSelectedCells, getCachedEditState } = info.table.options.meta!;\n\n    const valueRef = useRef<ValueOffset | undefined>(undefined);\n\n    const [valueOffset, updateValueOffset] = usePartialReducer<ValueOffset, null>(null, (_: null) => {\n        const cached = getCachedEditState();\n        if (cached) {\n            return cached;\n        }\n        if (!dataValue) {\n            return INIT_OFFSET;\n        }\n        return isoToDateAndOffset(dataValue);\n    });\n    const { value, offset } = valueOffset;\n\n    useEffect(() => {\n        valueRef.current = valueOffset;\n    }, [valueOffset]);\n\n    useSetCachedEditState(info, valueRef, (v) => v);\n\n    const onChange = useEvent((d: Date | null) => updateValueOffset({ value: d }));\n    const onOffsetChange = useEvent((offset: Offset) => updateValueOffset({ offset }));\n    const { onBlur } = useOnSaveOnBlur(info as any, { value, offset }, ({ value, offset }) =>\n        value ? format(value, `yyyy-MM-dd HH:mm:ss.SSSSSS'${offset.replace(\":\", \"\")}'`) : null\n    );\n    const onCancel = useEvent(() => {\n        updateSelectedCells({ edit: false }, info);\n    });\n\n    return (\n        <div className=\"h-full w-full\">\n            <DateTimePickerWithOffset\n                showIcon={false}\n                format=\"dd MMM yyyy, HH:mm:ss.SSS\"\n                onOffsetChange={onOffsetChange}\n                offset={offset}\n                onChange={onChange}\n                onConfirm={onBlur}\n                onCancel={onCancel}\n                value={value}\n                defaultOpen\n            />\n        </div>\n    );\n};\n\nexport interface RowLinkEditorProps {\n    info: CellInfo | HeaderInfo;\n    value: any;\n    multiple?: boolean;\n    getData(result: any): any;\n    mutation: { mutate(variables: Variables): void };\n}\n\nexport const RowLinkEditorCommon = ({\n    info,\n    mutation,\n    getData,\n    children,\n    value,\n    multiple,\n}: React.PropsWithChildren<RowLinkEditorProps>) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const loaded = useRef(false);\n    const { updateSelectedCells, isEditingLinkedRow, setIsEditingLinkedRow } = info.table.options.meta!;\n\n    // probably not the best way to do this\n    useEffectAsync(async () => {\n        if (loaded.current) return;\n        if (isEditingLinkedRow) return;\n        loaded.current = true;\n        setIsEditingLinkedRow(true);\n        let result = await dispatch(modal(\"dbAddLinkedRow\", { info, value, multiple }));\n        updateSelectedCells({ edit: false }, info);\n        setIsEditingLinkedRow(false);\n        if (result) {\n            if (!multiple && Array.isArray(result)) {\n                // empty array signals selection removal\n                result = result[0] ?? null;\n            }\n            const data = getData(result);\n            mutation.mutate({ data, info });\n        }\n    }, []);\n\n    return <>{children}</>;\n};\n\nconst RowLinkEditor = ({ info, value, multiple }: { info: CellInfo; value: any; multiple?: boolean }) => {\n    const { row, column } = info;\n    const mutation = useUpdateRowMutation();\n\n    const getData = (result: any) => {\n        const data = row.original;\n        return { ...data, [column.id]: result };\n    };\n\n    return (\n        <RowLinkEditorCommon info={info} value={value} getData={getData} mutation={mutation} multiple={multiple}>\n            <div className=\"flex w-full items-center truncate p-2\">\n                {value ? <RowLink value={value} info={info} /> : <NullCell />}\n            </div>\n        </RowLinkEditorCommon>\n    );\n};\n\nexport function EditingCell({ info, type }: { info: CellInfo; type: ColumnSpec[\"type\"] }) {\n    const value = info.getValue();\n    switch (type) {\n        case \"string\":\n            return (\n                <TextEditor\n                    type=\"cell\"\n                    info={info}\n                    value={value}\n                    useOnSaveOnBlur={useOnSaveOnBlur}\n                    useInputKeyDown={useInputKeyDown}\n                />\n            );\n        case \"number\":\n            return (\n                <NumberEditor\n                    type=\"cell\"\n                    info={info}\n                    value={value}\n                    useOnSaveOnBlur={useOnSaveOnBlur}\n                    useInputKeyDown={useInputKeyDown}\n                />\n            );\n        case \"date\":\n            return (\n                <DateEditor\n                    type=\"cell\"\n                    info={info}\n                    value={value}\n                    useOnSaveOnBlur={useOnSaveOnBlur}\n                    useInputKeyDown={useInputKeyDown}\n                />\n            );\n        case \"simpleObject\":\n            return (\n                <LazyJsonEditor\n                    type=\"cell\"\n                    info={info}\n                    value={value}\n                    useOnSaveOnBlur={useOnSaveOnBlur}\n                    useInputKeyDown={useInputKeyDown}\n                />\n            );\n        case \"bool\":\n            return (\n                <BoolEditor\n                    type=\"cell\"\n                    info={info}\n                    value={value}\n                    useOnSaveOnBlur={useOnSaveOnBlur}\n                    useInputKeyDown={useInputKeyDown}\n                />\n            );\n        case \"datetime\":\n            return (\n                <DateTimeEditor\n                    type=\"cell\"\n                    info={info}\n                    value={value}\n                    useOnSaveOnBlur={useOnSaveOnBlur}\n                    useInputKeyDown={useInputKeyDown}\n                />\n            );\n        case \"media\":\n            return <MediaCell info={info} value={value} />;\n        case \"liveObject\":\n        case \"liveObjectArray\":\n            return <RowLinkEditor info={info} value={value} multiple={type === \"liveObjectArray\"} />;\n        default:\n            return <div>{value}</div>;\n    }\n}\n\nexport default EditingCell;\n","import React, { InputHTMLAttributes, useEffect, useReducer, useRef } from \"react\";\nimport { faSquare } from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { cx } from \"@/theme/styles\";\nimport { ColType, ColumnSpec } from \"@/types/database\";\nimport { getRandomString } from \"@/util\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { HeaderInfo } from \"../types\";\nimport FooterEditCell from \"./FooterEditCell\";\nimport { MediaFooterCell } from \"./MediaCell\";\n\nconst FooterReducer = (_prev: string, id = \"\") => id || getRandomString();\nconst INIT_FOOTER_ID = getRandomString();\nexport const useFooterId = () => {\n    const [footerId, updateFooterId] = useReducer(FooterReducer, INIT_FOOTER_ID) as [string, (id?: string) => void];\n    return { footerId, updateFooterId } as const;\n};\n\nexport const CellCheckbox = React.forwardRef<HTMLInputElement, InputHTMLAttributes<HTMLInputElement>>((props, ref) => (\n    <input className=\"border-white accent-primary-darker\" ref={ref} type=\"checkbox\" {...props} />\n));\n\nCellCheckbox.displayName = \"CellCheckbox\";\n\nexport const NullCell = () => <i className=\"w-full\"></i>;\n\ninterface CellDataProps {\n    info: HeaderInfo;\n    type: ColumnSpec[\"type\"];\n}\n\nfunction CellData({ info, type }: CellDataProps) {\n    switch (type) {\n        case \"media\":\n            return <MediaFooterCell info={info} />;\n        default:\n            return <NullCell />;\n    }\n}\n\nexport function FooterCell({ info, type }: { info: HeaderInfo; type: ColType }) {\n    const { updateSelectedCells, isCellSelected, isEditingCell, resetSelected, footerId } = info.table.options.meta!;\n\n    const onUpdateSelectedCell = (a: Parameters<typeof updateSelectedCells>[0]) => updateSelectedCells(a, info);\n\n    const rowId = footerId;\n    const cell = { row: { id: rowId }, column: info.column };\n    const isSelected = isCellSelected(cell);\n    const isMedia = type === \"media\";\n    const isEditing = isEditingCell(cell) && !isMedia;\n\n    const colId = info.column.id;\n\n    const onClick: React.MouseEventHandler<HTMLDivElement> = useEvent((e) => {\n        if (isEditing) return;\n        onUpdateSelectedCell({\n            cell: { row: rowId, col: colId, edit: true },\n        });\n    });\n\n    const cellRef = useRef<HTMLDivElement>(null!);\n\n    const onKeyDown: React.KeyboardEventHandler<HTMLDivElement> = useEvent((e) => {\n        if (isEditing) return;\n        if (e.defaultPrevented) return;\n        e.preventDefault();\n\n        switch (e.key) {\n            case \"ArrowUp\": {\n                e.preventDefault();\n                return onUpdateSelectedCell({ dir: \"up\" });\n            }\n            case \"ArrowDown\": {\n                e.preventDefault();\n                return onUpdateSelectedCell({ dir: \"down\" });\n            }\n            case \"ArrowLeft\": {\n                e.preventDefault();\n                return onUpdateSelectedCell({ dir: \"left\" });\n            }\n            case \"ArrowRight\": {\n                e.preventDefault();\n                return onUpdateSelectedCell({ dir: \"right\" });\n            }\n            case \"Enter\": {\n                e.preventDefault();\n                return onEditMode();\n            }\n            case \"Tab\": {\n                e.preventDefault();\n                if (e.shiftKey) {\n                    return onUpdateSelectedCell({ dir: \"left\", edit: true });\n                } else {\n                    return onUpdateSelectedCell({ dir: \"right\", edit: true });\n                }\n            }\n            case \"Escape\": {\n                e.preventDefault();\n                return resetSelected(info);\n            }\n        }\n    });\n\n    const onEditMode = useEvent(() => {\n        if (!isEditing) {\n            onUpdateSelectedCell({ cell: { row: rowId, col: colId, edit: true } });\n        }\n    });\n\n    useEffect(() => {\n        if (!isEditing && isSelected) {\n            cellRef.current.focus();\n        }\n    }, [isEditing, isSelected]);\n\n    return (\n        <div\n            ref={cellRef}\n            key={footerId}\n            role=\"gridcell\"\n            className={cx(\"relative flex items-center\", {\n                \"cursor-pointer\": !isEditing && !isMedia,\n                \"truncate p-2\": !isEditing,\n                \"bg-primary-50 dark:bg-primary-800\": isSelected && !isEditing,\n                // \"before:absolute before:inset-0 before:h-full before:w-full before:border-2 before:border-primary\":\n                //     isSelected && !isEditing,\n            })}\n            onClickCapture={onClick}\n            tabIndex={0}\n            onKeyDownCapture={onKeyDown}>\n            {isEditing ? <FooterEditCell info={info} type={type} /> : <CellData info={info} type={type} />}\n        </div>\n    );\n}\n\nexport default FooterCell;\n","import React from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { addTableRow } from \"@/api/tables\";\nimport { alert } from \"@/controllers/modals\";\nimport { AnvilDispatch } from \"@/types\";\nimport { ColumnSpec } from \"@/types/database\";\nimport { getRandomString } from \"@/util\";\nimport useEvent from \"@/util/useEventCallback\";\nimport type { AnvilRow, HeaderInfo } from \"../types\";\nimport { BoolEditor, DateEditor, DateTimeEditor, NumberEditor, RowLinkEditorCommon, TextEditor } from \"./EditingCell\";\nimport { LazyJsonFooterEditor } from \"./LazyJsonEditor\";\nimport { MediaFooterCell } from \"./MediaCell\";\n\nconst useInputKeyDown = (info: HeaderInfo, onSave: (cb?: () => void) => void, value?: any) => {\n    const { updateSelectedCells, updateFooterId } = info.table.options.meta!;\n    const { column } = info;\n\n    const onKeyDown: React.KeyboardEventHandler = useEvent((e) => {\n        switch (e.key) {\n            case \"Tab\": {\n                e.preventDefault();\n                let cb;\n                if (e.shiftKey) {\n                    cb = () => updateSelectedCells({ dir: \"left\", edit: true }, info);\n                } else {\n                    cb = () => updateSelectedCells({ dir: \"right\", edit: true }, info);\n                }\n                if (value) {\n                    onSave(cb);\n                } else {\n                    cb();\n                }\n                break;\n            }\n            case \"Enter\": {\n                if (e.shiftKey) {\n                    e.stopPropagation();\n                    // todo;\n                    return;\n                } else {\n                    e.preventDefault();\n                    if (value) {\n                        onSave(() => {\n                            const newFooterId = getRandomString();\n                            updateFooterId(newFooterId);\n                            updateSelectedCells({ cell: { row: newFooterId, col: column.id, edit: true } }, info);\n                        });\n                    }\n                }\n                break;\n            }\n            case \"Backspace\":\n            case \"Delete\": {\n                e.stopPropagation();\n                break;\n            }\n            case \"Escape\": {\n                updateSelectedCells({ edit: false }, info);\n                break;\n            }\n            case \"ArrowUp\": {\n                if (value) return;\n                updateSelectedCells({ dir: \"up\" }, info);\n                e.preventDefault();\n                break;\n            }\n            case \"ArrowLeft\": {\n                if (value) return;\n                updateSelectedCells({ dir: \"left\" }, info);\n                break;\n            }\n            case \"ArrowRight\": {\n                if (value) return;\n                updateSelectedCells({ dir: \"right\" }, info);\n                break;\n            }\n        }\n    });\n\n    return onKeyDown;\n};\n\ninterface Variables {\n    data: Omit<AnvilRow, \"id\">;\n}\n\nexport const useAddRowMutation = (info: HeaderInfo) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const {\n        appId,\n        tableMappingId,\n        tableId,\n        updateSelectedCells,\n        footerId,\n        updateFooterId,\n        hasNextPage,\n        tableContainerRef,\n    } = info.table.options.meta!;\n\n    const queryClient = useQueryClient();\n    const queryKey = [\"table-data\", { appId, tableId }, \"page-data\"];\n\n    return useMutation({\n        mutationFn({ data }: Variables) {\n            return addTableRow(appId, tableMappingId, tableId, data) as Promise<AnvilRow>;\n        },\n        onError(e: Error) {\n            let msg = `Could not save row: ${e.message ?? \"Unknown error\"}`;\n            if (e.message?.includes(\"quota\")) {\n                msg += \"\\n\\nPlease see https://anvil.works/pricing for information about Data Tables quotas.\";\n            }\n            dispatch(alert(\"Save failed\", msg));\n        },\n        onSuccess(row) {\n            updateFooterId();\n            row._isNew = true;\n            queryClient.setQueriesData({ queryKey }, (prev: any) => {\n                const pages = prev.pages;\n                if (hasNextPage) {\n                    return { ...prev, pages: [{ rows: [row] }, ...pages] };\n                } else {\n                    return { ...prev, pages: [...pages, { rows: [row] }] };\n                }\n            });\n            updateSelectedCells({ rowIdChange: [footerId, String(row.id)] }, info);\n            setTimeout(() => {\n                if (hasNextPage) {\n                    tableContainerRef.current.scrollTop = 0;\n                } else {\n                    tableContainerRef.current.scrollTop = tableContainerRef.current.scrollHeight;\n                }\n            });\n        },\n    });\n};\n\nexport const useOnSaveOnBlur = <T,>(info: HeaderInfo, value: T, convert = (x: T): any => x) => {\n    const { column } = info;\n    const { updateSelectedCells, resetSelected } = info.table.options.meta!;\n\n    const mutation = useAddRowMutation(info);\n\n    const onSave = useEvent(async (onSettled?: () => void) => {\n        const convertedValue = convert(value);\n        if (!convertedValue) return;\n        const data = { [column.id]: convertedValue } as AnvilRow;\n        mutation.mutate({ data }, { onSettled });\n    });\n\n    const onBlur = useEvent(() => {\n        if (!convert(value)) return resetSelected();\n        onSave(() => updateSelectedCells({ edit: false }, info));\n    });\n\n    return { onSave, onBlur } as const;\n};\n\nexport interface FooterEditingProps {\n    type: \"footer\";\n    info: HeaderInfo;\n    value: any;\n    useOnSaveOnBlur: typeof useOnSaveOnBlur;\n    useInputKeyDown: typeof useInputKeyDown;\n}\n\nconst RowLinkEditor = ({ info, multiple }: { info: HeaderInfo; multiple?: boolean }) => {\n    const { column } = info;\n    const mutation = useAddRowMutation(info);\n\n    const getData = (result: any) => {\n        return { [column.id]: result };\n    };\n\n    return <RowLinkEditorCommon info={info} value={null} getData={getData} mutation={mutation} multiple={multiple} />;\n};\n\nexport function FooterEditCell({ info, type }: { info: HeaderInfo; type: ColumnSpec[\"type\"] }) {\n    switch (type) {\n        case \"string\":\n            return (\n                <TextEditor\n                    type=\"footer\"\n                    info={info}\n                    value={\"\"}\n                    useOnSaveOnBlur={useOnSaveOnBlur}\n                    useInputKeyDown={useInputKeyDown}\n                />\n            );\n        case \"number\":\n            return (\n                <NumberEditor\n                    type=\"footer\"\n                    info={info}\n                    value={null}\n                    useOnSaveOnBlur={useOnSaveOnBlur}\n                    useInputKeyDown={useInputKeyDown}\n                />\n            );\n        case \"date\":\n            return (\n                <DateEditor\n                    type=\"footer\"\n                    info={info}\n                    value={null}\n                    useOnSaveOnBlur={useOnSaveOnBlur}\n                    useInputKeyDown={useInputKeyDown}\n                />\n            );\n        case \"simpleObject\":\n            return (\n                <LazyJsonFooterEditor\n                    type=\"footer\"\n                    info={info}\n                    value={undefined}\n                    useOnSaveOnBlur={useOnSaveOnBlur}\n                    useInputKeyDown={useInputKeyDown}\n                />\n            );\n        case \"bool\":\n            return (\n                <BoolEditor\n                    type=\"footer\"\n                    info={info}\n                    value={false}\n                    useOnSaveOnBlur={useOnSaveOnBlur}\n                    useInputKeyDown={useInputKeyDown}\n                />\n            );\n        case \"datetime\":\n            return (\n                <DateTimeEditor\n                    type=\"footer\"\n                    info={info}\n                    value={false}\n                    useOnSaveOnBlur={useOnSaveOnBlur}\n                    useInputKeyDown={useInputKeyDown}\n                />\n            );\n        case \"media\":\n            return <MediaFooterCell info={info} />;\n        case \"liveObject\":\n        case \"liveObjectArray\":\n            return <RowLinkEditor info={info} multiple={type === \"liveObjectArray\"} />;\n        default:\n            return <div></div>;\n    }\n}\n\nexport default FooterEditCell;\n","import { lazyComponent } from \"@/util/lazy\";\nimport type JsonEditor from \"./JsonEditor\";\n\nexport const LazyJsonEditor = lazyComponent<typeof JsonEditor>(() => import(\"./JsonEditor\"));\n\nexport const LazyJsonFooterEditor = lazyComponent<typeof JsonEditor>(() => import(\"./JsonEditor\"), \"JSONFooterEditor\");\n\nexport default LazyJsonEditor;\n","import React, { useRef } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport {\n    faDownload,\n    faFile,\n    faFileCode,\n    faFileCsv,\n    faFileExcel,\n    faFileImage,\n    faFilePdf,\n    faFileText,\n    faUpload,\n} from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { addTableRow, getMediaDownloadUrl, uploadMedia } from \"@/api/tables\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport { updateGlobalLoadingIndicator } from \"@/controllers/app\";\nimport { blockNavigation, unblockNavigation } from \"@/controllers/ide\";\nimport { alert } from \"@/controllers/modals\";\nimport { AnvilDispatch } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { AnvilRow, CellInfo, HeaderInfo } from \"../types\";\nimport { NullCell } from \"./Cell\";\nimport { useAddRowMutation } from \"./FooterEditCell\";\n\nfunction typeToIcon(type: string, name: string) {\n    switch (type) {\n        case \"image/png\":\n        case \"image/jpeg\":\n        case \"image/gif\":\n            return faFileImage;\n        case \"text/plain\":\n            return faFileText;\n        case \"text/html\":\n            return faFileCode;\n        case \"application/pdf\":\n            return faFilePdf;\n    }\n\n    if (/\\.xlsx?$/.test(name)) {\n        return faFileExcel;\n    } else if (/\\.(csv)$/.test(name)) {\n        return faFileCsv;\n    }\n\n    return faFile;\n}\n\ninterface Variables {\n    data: AnvilRow;\n    file: File;\n    aborter: AbortController;\n}\n\ninterface MediaUploadButtonProps {\n    info: CellInfo | HeaderInfo;\n    getRowData: () => Promise<AnvilRow> | AnvilRow;\n}\n\nconst MediaUploadButton = ({ getRowData, info }: MediaUploadButtonProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const { column } = info;\n    const { appId, tableMappingId, tableId, updateSelectedCells } = info.table.options.meta!;\n    const fileLoaderRef = useRef<HTMLInputElement>(null!);\n\n    const onClick = useEvent(() => {\n        fileLoaderRef.current.click();\n    });\n\n    const queryClient = useQueryClient();\n\n    const mutation = useMutation({\n        mutationFn({ file, aborter, data }: Variables) {\n            return uploadMedia(appId, tableMappingId, tableId, data.id, column.id, file, null, (percentUploaded) => {\n                dispatch(updateGlobalLoadingIndicator(`Uploading: ${Math.round(percentUploaded)}%`));\n            });\n        },\n        onMutate({ aborter }) {\n            dispatch(updateGlobalLoadingIndicator(true));\n            dispatch(\n                blockNavigation(\"fileUpload\", () => {\n                    aborter.abort();\n                    console.log(\"abort!\", aborter.signal.aborted);\n                })\n            );\n        },\n        onSettled({ error }, _e, { data, file, aborter }) {\n            dispatch(updateGlobalLoadingIndicator(false));\n            dispatch(unblockNavigation(\"fileUpload\"));\n            if (error) {\n                dispatch(alert(\"Upload failed\", error));\n            } else if (aborter.signal.aborted) {\n                // pass\n            } else {\n                const rowId = data.id;\n                const newRow = { ...data, [column.id]: { name: file.name, content_type: file.type } };\n                queryClient.setQueriesData(\n                    { queryKey: [\"table-data\", { appId, tableId }, \"page-data\"] },\n                    (prevData: any) => {\n                        const pages = prevData.pages;\n                        const newPages = pages.map((pageData: any) => {\n                            const { rows } = pageData;\n                            const newRows = rows.map((row: AnvilRow) => (row.id !== rowId ? row : newRow));\n                            return { ...pageData, rows: newRows };\n                        });\n                        return { ...prevData, pages: newPages };\n                    }\n                );\n                queryClient.invalidateQueries({\n                    queryKey: [\"table-data\", { appId, tableId }, \"row-data\", rowId],\n                });\n            }\n        },\n    });\n\n    const onChange: React.ChangeEventHandler<HTMLInputElement> = useEvent(async (e) => {\n        updateSelectedCells({ edit: false }, info);\n        const file = e.target.files?.[0];\n        if (file == null) return;\n        const aborter = new AbortController();\n        const rowData = await getRowData();\n        mutation.mutate({ file, aborter, data: rowData });\n    });\n\n    return (\n        <Button\n            small\n            variant=\"hidden\"\n            onClick={onClick}\n            className=\"absolute right-0 flex-1\"\n            preventDefaultClick={false}>\n            <FontAwesomeIcon icon={faUpload} fixedWidth />\n            <input ref={fileLoaderRef} className=\"hidden\" type=\"file\" onChange={onChange}></input>\n        </Button>\n    );\n};\n\nexport const MediaUpload = ({ info }: { info: CellInfo }) => {\n    const { row } = info;\n    const getRowData = useEvent(() => row.original);\n    return <MediaUploadButton info={info} getRowData={getRowData} />;\n};\n\nexport const MediaUploadFooter = ({ info }: { info: HeaderInfo }) => {\n    const { mutateAsync } = useAddRowMutation(info);\n    const getRowData = useEvent(() => mutateAsync({ data: {} }));\n    return <MediaUploadButton info={info} getRowData={getRowData} />;\n};\n\ninterface MediaCellProps {\n    value: { name: string; content_type: string; downloadUrl: string };\n    info: CellInfo;\n}\n\nconst MediaBadge = ({ value, info }: MediaCellProps) => {\n    const { row, column } = info;\n    const { appId, tableMappingId, tableId } = info.table.options.meta!;\n    const { name, content_type: type } = value;\n    const icon = typeToIcon(type, name);\n    const [tooltip, ref] = useTooltip(`${name} (${type})`, \"top\", { delay: true });\n\n    const onDownload = () => {\n        window.open(getMediaDownloadUrl(appId, tableMappingId, tableId, row.id, column.id));\n    };\n    return (\n        <div\n            ref={ref}\n            className=\"mr-12 flex cursor-auto items-center gap-2 truncate overflow-hidden rounded-md border border-secondary bg-secondary-300 p-1 px-2 text-base dark:bg-secondary-700\">\n            <FontAwesomeIcon icon={icon} fixedWidth />\n            <span className=\"truncate\">{name}</span>\n            <span className=\"truncate text-xs\">{`(${type})`}</span>\n            <LinkInternal onClick={onDownload}>\n                <FontAwesomeIcon icon={faDownload} fixedWidth />\n            </LinkInternal>\n            {tooltip}\n        </div>\n    );\n};\n\nexport const MediaCell = ({ value, info }: MediaCellProps) => {\n    return (\n        <div className=\"relative flex w-full items-center\">\n            {value ? <MediaBadge value={value} info={info} /> : <NullCell />}\n            <MediaUpload info={info} />\n        </div>\n    );\n};\n\nexport const MediaFooterCell = ({ info }: { info: HeaderInfo }) => {\n    return (\n        <div className=\"relative flex h-full w-full items-center\">\n            <MediaUploadFooter info={info} />\n        </div>\n    );\n};\n","import React from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faPlus } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { sortBy } from \"lodash-es\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { addTableColumn } from \"@/controllers/db\";\nimport { modal } from \"@/controllers/modals\";\nimport { claimAchievement } from \"@/controllers/user.ts\";\nimport { AnvilDispatch } from \"@/types\";\nimport { ColumnSpec } from \"@/types/database\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { HeaderInfo, TColumnDef, TTable } from \"../types\";\n\nexport const ADD_ID = \"$add-column\";\nexport const ADD_COLUMN_WIDTH = 50;\nexport const ADD_COLUMN_WIDTH_EMPTY = 50;\n\nconst getNewOrder = (colId: string, table: TTable) => {\n    const { columnOrder } = table.getState();\n    let colIndex = columnOrder.indexOf(colId);\n    if (colIndex === -1) {\n        colIndex = columnOrder.length;\n    }\n    const prevColId = columnOrder[colIndex - 1];\n    const prevCol = table.getColumn(prevColId)?.columnDef.meta?.original;\n    const currCol = table.getColumn(colId)?.columnDef.meta?.original;\n    const prevColOrder = prevCol ? (prevCol.admin_ui?.order ?? 0) : (currCol?.admin_ui?.order ?? 0) - 2;\n    const currColOrder = currCol ? (currCol.admin_ui?.order ?? 0) : (prevCol?.admin_ui?.order ?? 0) + 2;\n    const order = (prevColOrder + currColOrder) / 2;\n    return order;\n};\n\nexport const useInsertColumn = (info: HeaderInfo) => {\n    const { table, column } = info;\n    const { tableId, tableMappingId, tableMapping, tableContainerRef } = info.table.options.meta!;\n    const { columnOrder } = table.getState();\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    return useEvent(async () => {\n        const order = getNewOrder(column?.id, table);\n\n        const columnSpecs = table\n            .getAllColumns()\n            .map((col) => col.columnDef.meta?.original)\n            .filter(Boolean) as ColumnSpec[];\n\n        const columnNames = columnSpecs.map(({ name }) => name);\n        const targets: [string, string][] = sortBy(tableMapping?.tables ?? [], [\"name\"]).map(\n            ({ name, python_name }) => [name, python_name]\n        );\n\n        let i = columnNames.length + 1;\n        let name = `Column${i}`;\n        while (columnNames.includes(name)) {\n            name = `Column${++i}`;\n        }\n        const colSpec: Pick<ColumnSpec, \"name\" | \"admin_ui\" | \"client_hidden\"> = {\n            admin_ui: { width: 200, order },\n            name,\n            client_hidden: false,\n        };\n        const maybeColSpec = await dispatch(modal(\"dbAddCol\", { info, colSpec, targets }));\n        if (!maybeColSpec) return;\n        let newName = maybeColSpec.name;\n        const baseName = newName;\n        i = 1;\n        while (columnNames.includes(newName)) {\n            newName = `${baseName}_${++i}`;\n        }\n        maybeColSpec.name = newName;\n        await dispatch(addTableColumn(tableMappingId, tableId, maybeColSpec));\n        dispatch(claimAchievement(\"addedDataTableColumn\")); // No await\n        if (columnOrder.indexOf(column?.id) === -1) {\n            setTimeout(() => {\n                tableContainerRef.current.scrollLeft = tableContainerRef.current.scrollWidth;\n            });\n        }\n    });\n};\n\nconst AddColumnHeaderCell = (info: HeaderInfo) => {\n    const { header, table } = info;\n    const onClick = useInsertColumn(info);\n    const emptyColumns = !table.getState().columnOrder.length;\n\n    return (\n        <div role=\"columnheader\" className=\"cursor-pointer text-center font-medium\" style={{ width: \"fit-content\" }}>\n            <div className=\"flex h-full w-full items-center justify-center p-2\">\n                <Button variant=\"hidden\" onClick={onClick}>\n                    <div className=\"flex items-center gap-4\">\n                        <FontAwesomeIcon icon={faPlus} />\n                        {emptyColumns && \"New column\"}\n                    </div>\n                </Button>\n            </div>\n        </div>\n    );\n};\n\nexport const AddColumnDef: TColumnDef = {\n    id: ADD_ID,\n    size: ADD_COLUMN_WIDTH,\n    header: (props) => <AddColumnHeaderCell {...props} />,\n    cell: (info) => <div role=\"gridcell\" />,\n    footer: (info) => <div role=\"gridcell\" />,\n};\n","import React, { useMemo } from \"react\";\nimport { ColumnOrderState, createColumnHelper } from \"@tanstack/react-table\";\nimport type { CurrentTable, TableMapping } from \"@/types/database\";\nimport { useStateWithReset } from \"@/util/hooks\";\nimport Cell from \"../cells/Cell\";\nimport FooterCell from \"../cells/FooterCell\";\nimport { ColumnHeader, ReadOnlyColumnHeader } from \"../header/ColumnHeader\";\nimport DraggableColumnHeader from \"../header/DraggableColumnHeader\";\nimport type { AnvilRow } from \"../types\";\nimport { AddColumnDef } from \"./AddColumn\";\nimport { ROW_MENU_ID, SELECT_ID, SelectMultiple, SelectRow, SelectSingle } from \"./SelectColumn\";\n\nconst LINKED_COLUMNS = [\"string\", \"number\", \"bool\", \"date\", \"datetime\"];\n\nconst getNamedColId = (tableMapping: TableMapping | undefined, tableId: number) => {\n    const table = tableMapping?.tables.find(({ id }) => id === tableId);\n    if (!table) return;\n    const cols = Object.entries(table.columns).sort(\n        (a, b) => (a[1].admin_ui?.order ?? 0) - (b[1].admin_ui?.order ?? 0)\n    );\n    for (const [colId, { type }] of cols) {\n        if (LINKED_COLUMNS.includes(type)) {\n            return colId;\n        }\n    }\n};\n\nexport const useColumns = (\n    currentTable: CurrentTable,\n    tableMapping: TableMapping | undefined,\n    { readonly, multiple }: { readonly?: boolean; multiple?: boolean }\n) => {\n    return useMemo(() => {\n        const HeaderWrapper = readonly ? ReadOnlyColumnHeader : DraggableColumnHeader;\n\n        const columnHelper = createColumnHelper<AnvilRow>();\n\n        const columnDefs = Object.entries(currentTable.columns ?? {}).map(([id, original]) => {\n            const { name, type, admin_ui } = original;\n\n            let namedColId;\n            if (type === \"liveObject\" || type === \"liveObjectArray\") {\n                namedColId = getNamedColId(tableMapping, original.table_id);\n            }\n\n            const accessor = columnHelper.accessor((row: any) => row[id], {\n                id,\n                cell: (info) => <Cell type={type} info={info} />,\n                footer: (info) => <FooterCell type={type} info={info} />,\n                header: (info) => (\n                    <HeaderWrapper info={info}>\n                        <ColumnHeader name={name} type={type} info={info} />\n                    </HeaderWrapper>\n                ),\n                size: admin_ui?.width ?? 200,\n                minSize: 50,\n                meta: { original, namedColId },\n            });\n            return accessor;\n        });\n\n        const columns = [];\n\n        if (!readonly) {\n            columns.push(SelectRow);\n        } else if (multiple) {\n            columns.push(SelectMultiple);\n        } else {\n            columns.push(SelectSingle);\n        }\n\n        columns.push(...columnDefs);\n\n        if (!readonly) {\n            columns.push(AddColumnDef);\n        }\n\n        return columns;\n    }, [currentTable.columns]);\n};\n\nexport const reorderColumn = (\n    draggedColumnId: string,\n    targetColumnId: string,\n    columnOrder: string[]\n): ColumnOrderState => {\n    columnOrder.splice(\n        columnOrder.indexOf(targetColumnId),\n        0,\n        columnOrder.splice(columnOrder.indexOf(draggedColumnId), 1)[0] as string\n    );\n    return [...columnOrder];\n};\n\nexport const useColumnOrder = (currentTable: CurrentTable) => {\n    const currentColumnOrder = useMemo(\n        () =>\n            Object.entries(currentTable.columns ?? {})\n                .sort((itemA, itemB) => (itemA[1].admin_ui?.order ?? 0) - (itemB[1].admin_ui?.order ?? 0))\n                .map(([id]) => id),\n        [currentTable.columns]\n    );\n\n    const [columnOrder, setColumnOrder] = useStateWithReset<ColumnOrderState>(currentColumnOrder);\n    return [columnOrder, setColumnOrder] as const;\n};\n\nexport const columnPinning = { left: [SELECT_ID, ROW_MENU_ID] };\n","import React from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faChevronDown, faTrashAlt } from \"@fortawesome/pro-light-svg-icons\";\nimport { faPlus } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { deleteTableRow } from \"@/api/tables\";\nimport { Button } from \"@/components/reusable/Button\";\nimport DropdownMenu, { MenuItems } from \"@/components/reusable/DropdownMenu\";\nimport { CheckBox, RadioButton } from \"@/components/reusable/Forms\";\nimport { alert, confirmWithCheckBox } from \"@/controllers/modals\";\nimport { AnvilDispatch } from \"@/types\";\nimport { checkMeta, noop } from \"@/util\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { AnvilRow, CellInfo, TColumnDef, TTable } from \"../types\";\n\nexport const SELECT_ID = \"$$select-column\";\nexport const ROW_MENU_ID = \"$$rowmenu-column\";\nexport const SELECT_WIDTH = 30;\n\n// we don't use the row resizer anymore\n// const useStyles = makeStyles()(() => ({\n//     resizer: {\n//         position: \"absolute\",\n//         right: 0,\n//         bottom: 0,\n//         width: \"100%\",\n//         height: 5,\n//         background: \"rgba(0, 0, 0, 0.5)\",\n//         cursor: \"row-resize\",\n//         userSelect: \"none\",\n//         touchAction: \"none\",\n//         opacity: 0,\n//         \"&:hover\": {\n//             opacity: 1,\n//         },\n//     },\n// }));\n\nexport interface RowSizingInfoState {\n    startOffset: null | number;\n    startSize: null | number;\n    deltaOffset: null | number;\n    deltaPercentage: null | number;\n    isResizing: boolean;\n    // columnSizingStart: [string, number][]\n}\n\nconst confirmDelete = (rowSelection: number[]) => {\n    const numRows = rowSelection.length;\n\n    let title: string, rowIdentifier: string;\n    if (numRows === 1) {\n        title = \"Delete row?\";\n        rowIdentifier = \"this row\";\n    } else {\n        title = \"Delete rows?\";\n        rowIdentifier = \"these rows\";\n    }\n\n    const message = `Are you sure you want to delete ${rowIdentifier}?`;\n    const confirmMessage = `Yes, I want to delete ${rowIdentifier}. I know I cannot undo this action.`;\n    return confirmWithCheckBox(title, message, confirmMessage, \"Delete\", \"Cancel\");\n};\n\nexport const useDeleteRows = (table: TTable) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { appId, tableMappingId, tableId, resetSelected } = table.options.meta!;\n    const queryClient = useQueryClient();\n    const queryKey = [\"table-data\", { appId, tableId }] as const;\n    const deleteRowMutation = useMutation({\n        mutationFn({ rowIds }: { rowIds: number[] }) {\n            return Promise.allSettled(rowIds.map((id) => deleteTableRow(appId, tableMappingId, tableId, id)));\n        },\n        onMutate({ rowIds }) {\n            queryClient.cancelQueries({ queryKey });\n            queryClient.setQueriesData({ queryKey }, (prev: any) => {\n                const pages = prev.pages;\n                if (!pages) return;\n                const newPages = pages.map((pageData: any) => {\n                    const { rows } = pageData;\n                    const newRows = (rows as AnvilRow[]).filter(({ id }) => !rowIds.includes(id));\n                    if (newRows.length === rows.length) return pageData;\n                    return { ...pageData, rows: newRows };\n                });\n                return { ...prev, pages: newPages };\n            });\n            resetSelected({ table } as CellInfo);\n        },\n        onSettled(results) {\n            queryClient.invalidateQueries({ queryKey });\n\n            if (Array.isArray(results)) {\n                const failed = results.filter((r) => r.status === \"rejected\");\n                const numFailed = failed.length;\n                if (numFailed > 0) {\n                    const errorMessages = failed.map((f) => (f.reason?.message ? f.reason.message : String(f.reason)));\n                    dispatch(\n                        alert(\n                            numFailed > 1 ? \"Some rows failed to delete\" : \"Row failed to delete\",\n                            `${numFailed} row${numFailed > 1 ? \"s\" : \"\"} could not be deleted.\\nError: ${\n                                errorMessages[0]\n                            }`\n                        )\n                    );\n                }\n            }\n        },\n    });\n    const onDelete = useEvent(async () => {\n        const rowSelection = table.getState().rowSelection;\n        const rowIds = Object.keys(rowSelection).map(Number);\n        const c = await dispatch(confirmDelete(rowIds));\n        if (!c) return;\n        deleteRowMutation.mutate({ rowIds });\n    });\n    return onDelete;\n};\n\ninterface SelectRowCellInnerProps {\n    info: CellInfo;\n    showMenu: (e?: React.MouseEvent | null, target?: any) => void;\n    anchor: React.ReactNode;\n    onDelete: () => void;\n}\nconst SelectRowCellInner = ({ info, showMenu, anchor, onDelete }: SelectRowCellInnerProps) => {\n    const { row, cell } = info;\n    // const { updateSelectedRows, getRowResizeHandler, getRowSize, getIsRowResizing, setRowSizing, resetSelected } =\n    //     info.table.options.meta!;\n    // const { classes } = useStyles();\n    const { updateSelectedRows, resetSelected } = info.table.options.meta!;\n\n    const onClick: React.MouseEventHandler<HTMLDivElement> = useEvent((e) => {\n        updateSelectedRows({ row, additive: checkMeta(e), inclusive: e.shiftKey }, info);\n    });\n\n    const onContextMenu = useEvent((e: React.MouseEvent<HTMLDivElement>) => {\n        e.preventDefault();\n        if (!row.getIsSelected()) {\n            updateSelectedRows({ row, additive: false, inclusive: false }, info);\n        }\n        showMenu(e, e.currentTarget);\n    });\n\n    const onClickDD: React.MouseEventHandler<HTMLDivElement> = useEvent((e) => {\n        onClick(e);\n        showMenu(null, e.currentTarget);\n    });\n\n    const onKeyDown: React.KeyboardEventHandler<HTMLDivElement> = useEvent((e) => {\n        switch (e.key) {\n            case \"Delete\":\n            case \"Backspace\":\n                e.preventDefault();\n                onDelete();\n                break;\n            case \"Escape\":\n                resetSelected(info);\n                break;\n        }\n    });\n\n    // const isResizing = getIsRowResizing(row);\n\n    return (\n        <div\n            role=\"gridcell\"\n            className=\"relative cursor-pointer truncate p-2\"\n            onClick={onClick}\n            tabIndex={0}\n            onContextMenu={onContextMenu}\n            onKeyDown={onKeyDown}>\n            <Button variant=\"hidden\" small onClick={onClickDD}>\n                <FontAwesomeIcon icon={faChevronDown} fixedWidth className=\"text-center\" />\n                {anchor}\n            </Button>\n            {/* <div\n        data-row-resizer=\"\"\n        className={cx(classes.resizer, { \"bg-primary-400! opacity-100!\": isResizing })}\n        onMouseDown={getRowResizeHandler(row)}\n        onTouchStart={getRowResizeHandler(row)}\n        onDoubleClick={() => setRowSizing((old) => omit(old, row.id))}\n    /> */}\n        </div>\n    );\n};\n\nconst SelectRowCell = ({ info }: { info: CellInfo }) => {\n    const onDelete = useDeleteRows(info.table);\n    const numRows = info.table.getSelectedRowModel().rows.length;\n    const { menuItems } = info.table.options.meta!;\n\n    const items = () => {\n        const deleteItem: MenuItems[number] = [\n            `Delete ${numRows} row${numRows > 1 ? \"s\" : \"\"}`,\n            () => onDelete(),\n            faTrashAlt,\n        ];\n        if (numRows > 1) {\n            return [deleteItem];\n        }\n        const rv = menuItems?.(info) ?? [];\n        if (rv.length) {\n            rv.push(<hr />);\n        }\n        rv.push(deleteItem);\n        return rv;\n    };\n\n    return (\n        <DropdownMenu\n            render={(showMenu, anchor) => (\n                <SelectRowCellInner info={info} showMenu={showMenu} anchor={anchor} onDelete={onDelete} />\n            )}\n            items={items}\n        />\n    );\n};\n\nconst SelectLinkRow = ({ info, multiple }: { info: CellInfo; multiple?: boolean }) => {\n    // const { row, cell } = info;\n    // const { getRowSize } = info.table.options.meta!;\n\n    const onClick: React.MouseEventHandler<HTMLDivElement> = useEvent((e) => {\n        e.stopPropagation();\n    });\n\n    const isSelected = info.row.getIsSelected();\n\n    return (\n        <div\n            role=\"gridcell\"\n            className=\"flex h-full w-full cursor-pointer items-center justify-center pl-2\"\n            tabIndex={0}>\n            {multiple ? (\n                <CheckBox checked={isSelected} onClick={onClick} onChange={noop} />\n            ) : (\n                <RadioButton checked={isSelected} onClick={onClick} onChange={noop} />\n            )}\n        </div>\n    );\n};\n\nconst id = SELECT_ID;\nconst header = () => <div role=\"columnheader\" />;\nconst size = SELECT_WIDTH;\n\nexport const SelectRow: TColumnDef = {\n    id,\n    size,\n    header,\n    cell: (info) => <SelectRowCell info={info} />,\n    footer: (info) => (\n        <div role=\"gridcell\" className=\"flex items-center justify-center text-primary\">\n            <FontAwesomeIcon icon={faPlus} fixedWidth className=\"text-center\" />\n        </div>\n    ),\n};\n\nexport const SelectSingle: TColumnDef = {\n    id,\n    size,\n    header,\n    cell: (info) => <SelectLinkRow info={info} />,\n};\n\nexport const SelectMultiple: TColumnDef = {\n    id,\n    size,\n    header,\n    cell: (info) => <SelectLinkRow info={info} multiple />,\n};\n","import { useCallback, useMemo } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { canSort, getSort, updateSort } from \"@/controllers/db_new\";\nimport { AnvilDispatch, State } from \"@/types\";\nimport { CurrentTable, TableMappingId } from \"@/types/database\";\nimport useEvent from \"@/util/useEventCallback\";\n\nexport const useColumnSorting = (tableMappingId: TableMappingId, currentTable: CurrentTable) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { id: tableId, columns = {} } = currentTable;\n\n    const uiSortPrefs = useSelector((state: State) => getSort(state, tableId));\n\n    const columnSorting = useMemo(() => {\n        return uiSortPrefs\n            .map(({ colId, ascending }) => {\n                const colSpec = columns[colId];\n                if (!colSpec) return; // stale\n                const { type } = columns[colId];\n                if (!canSort(type)) return; // also stale\n                return { colId, ascending };\n            })\n            .filter(Boolean);\n    }, [uiSortPrefs, currentTable]);\n\n    const setColumnSorting = useCallback(\n        (sortArray: ReturnType<typeof getSort>) => {\n            dispatch(updateSort(tableMappingId, tableId, sortArray));\n        },\n        [tableId]\n    );\n    const updateColumnSorting = useEvent((colId: string, ascending: boolean) => {\n        const index = columnSorting.findIndex(({ colId: id }) => id === colId);\n        if (index === -1) {\n            setColumnSorting([...columnSorting, { colId, ascending }]);\n        } else if (columnSorting[index].ascending === ascending) {\n            // no op\n        } else {\n            setColumnSorting([\n                ...columnSorting.slice(0, index),\n                { colId, ascending },\n                ...columnSorting.slice(index + 1),\n            ]);\n        }\n    });\n\n    const removeColumnSorting = useEvent((colId: string) => {\n        const newColumnSorting = columnSorting.filter(({ colId: id }) => id !== colId);\n        if (newColumnSorting.length === columnSorting.length) return;\n        setColumnSorting(newColumnSorting);\n    });\n\n    return { columnSorting, setColumnSorting, updateColumnSorting, removeColumnSorting } as const;\n};\n","import { useCallback, useMemo, useRef } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport type { OnChangeFn, VisibilityState } from \"@tanstack/react-table\";\nimport { HiddenColumns, getHiddenColumns, updateHiddenColumns as updateHiddenColumns_ } from \"@/controllers/db_new\";\nimport { AnvilDispatch, State } from \"@/types\";\nimport { CurrentTable, TableMappingId } from \"@/types/database\";\nimport useEvent from \"@/util/useEventCallback\";\n\nexport const useHiddenColumns = (tableMappingId: TableMappingId, currentTable: CurrentTable) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { id: tableId, columns } = currentTable;\n\n    const uiHiddenPrefs = useSelector((state: State) => getHiddenColumns(state, tableId));\n\n    const hiddenColumns = useMemo(() => {\n        const rv: HiddenColumns = {};\n        for (const colId in columns) {\n            rv[colId] = uiHiddenPrefs[colId] ?? true;\n        }\n        return rv;\n    }, [uiHiddenPrefs, currentTable]);\n\n    const prevHiddenColumns = useRef<VisibilityState>(hiddenColumns);\n    prevHiddenColumns.current = hiddenColumns;\n\n    const setHiddenColumns: OnChangeFn<VisibilityState> = useCallback(\n        (hiddenColumns: VisibilityState | ((v: VisibilityState) => VisibilityState)) => {\n            let hiddenColumnState: VisibilityState;\n            if (typeof hiddenColumns === \"function\") {\n                hiddenColumnState = hiddenColumns(prevHiddenColumns.current);\n            } else {\n                hiddenColumnState = hiddenColumns;\n            }\n            dispatch(updateHiddenColumns_(tableMappingId, tableId, hiddenColumnState));\n        },\n        [tableId]\n    );\n\n    const updateHiddenColumns = useEvent((colId: string, visible: boolean) => {\n        const updatedHiddenColumns = { ...hiddenColumns };\n        if (visible) {\n            delete updatedHiddenColumns[colId];\n        } else {\n            updatedHiddenColumns[colId] = false;\n        }\n        setHiddenColumns(updatedHiddenColumns);\n    });\n\n    const resetHiddenColumns = useEvent(() => {\n        setHiddenColumns({});\n    });\n\n    return { hiddenColumns, setHiddenColumns, updateHiddenColumns, resetHiddenColumns } as const;\n};\n","import { useCallback, useReducer, useRef, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { getHiddenColumns } from \"@/controllers/db_new\";\nimport { State } from \"@/types\";\nimport { TableId } from \"@/types/database\";\nimport { useActionOnStateChange } from \"@/util/hooks\";\nimport { TCell, TRow, TTable } from \"../types\";\n\ntype TInfo = { table: TTable };\n\ntype rowId = string;\ntype colId = string;\ntype CellId = { row: rowId; col: colId; edit?: boolean };\n\ntype CellState = CellId[];\ntype ColState = colId[];\nexport interface SelectedState {\n    cells: CellState;\n    cols: ColState;\n    rowAnchorId: rowId;\n    colAnchorId: colId;\n}\n\nconst INIT_SELECTED_STATE: SelectedState = {\n    cells: [],\n    cols: [],\n    rowAnchorId: \"\",\n    colAnchorId: \"\",\n};\n\nexport type SelectedPayload = CellPayload | RowPayload | ColPayload | Reset;\n\nexport type MoveCellAction = {\n    dir: \"left\" | \"right\" | \"up\" | \"down\";\n    edit?: boolean;\n};\n\nexport type CellSelectedAction =\n    | MoveCellAction\n    | { edit: boolean }\n    | { cell: CellId; additive?: boolean; inclusive?: boolean }\n    | { rowIdChange: [string, string] };\n\nexport type ColSelectedAction = {\n    col: colId;\n    additive: boolean;\n    inclusive: boolean;\n};\n\nexport type RowSelectedAction = {\n    row: TRow;\n    additive: boolean;\n    inclusive: boolean;\n};\n\ntype Reset = {\n    type: \"reset\";\n    action?: any;\n    info?: any;\n};\n\ntype CellPayload = {\n    type: \"cell\";\n    action: CellSelectedAction;\n    info: TInfo;\n};\n\ntype RowPayload = {\n    type: \"row\";\n    action: RowSelectedAction;\n    info: TInfo;\n};\n\ntype ColPayload = {\n    type: \"col\";\n    action: ColSelectedAction;\n    info: TInfo;\n};\n\nexport type SelectedReducer = React.Dispatch<SelectedPayload>;\n\n// because Media Cells are never editable\n\nconst KNOWN_TYPES = [\n    \"bool\",\n    \"string\",\n    \"media\",\n    \"liveObject\",\n    \"liveObjectArray\",\n    \"number\",\n    \"date\",\n    \"datetime\",\n    \"simpleObject\",\n];\n\nconst canEdit = (colId: string, info: TInfo) => {\n    const type = info.table.getColumn(colId)?.columnDef.meta?.original?.type ?? \"UNKNOWN\";\n    return KNOWN_TYPES.includes(type) && type !== \"media\";\n};\n\nconst moveCellSelection = (state: SelectedState, action: MoveCellAction, info: TInfo): SelectedState => {\n    const { rowAnchorId: currRowId, colAnchorId: currColId } = state;\n    if (!currColId || !currRowId) return state;\n    const { dir, edit } = action;\n\n    const columnOrder = info.table.getState().columnOrder;\n    const colIdx = columnOrder.indexOf(currColId);\n\n    let rowId = currRowId;\n    let colId = currColId;\n    const { footerId, hasNextPage, tableContainerRef } = info.table.options.meta!;\n\n    switch (dir) {\n        case \"left\": {\n            let idx = 1;\n            let nextId;\n            while ((nextId = columnOrder[colIdx - idx++]) != null) {\n                const column = info.table.getColumn(nextId);\n                if (column?.getIsVisible()) {\n                    colId = nextId;\n                    break;\n                }\n            }\n            break;\n        }\n        case \"right\": {\n            let idx = 1;\n            let nextId;\n            while ((nextId = columnOrder[colIdx + idx++]) != null) {\n                const column = info.table.getColumn(nextId);\n                if (column?.getIsVisible()) {\n                    colId = nextId;\n                    break;\n                }\n            }\n            break;\n        }\n        case \"up\": {\n            if (rowId === footerId) {\n                if (hasNextPage) {\n                    rowId = info.table.getRowModel().rows.at(0)?.id ?? rowId;\n                    tableContainerRef.current.scrollTop = 0;\n                } else {\n                    rowId = info.table.getRowModel().rows.at(-1)?.id ?? rowId;\n                    tableContainerRef.current.scrollTop = tableContainerRef.current.scrollHeight;\n                }\n            } else {\n                const nextRowIdx = info.table.getRow(rowId).index - 1;\n                rowId = info.table.getRowModel().rows[nextRowIdx]?.id ?? rowId;\n            }\n            break;\n        }\n        case \"down\": {\n            if (rowId === footerId) {\n                break;\n            }\n            const nextRowIdx = info.table.getRow(rowId).index + 1;\n            rowId = info.table.getRowModel().rows[nextRowIdx]?.id ?? rowId;\n            if (rowId === currRowId) {\n                rowId = footerId;\n            }\n            break;\n        }\n    }\n\n    let isEditMode = edit && canEdit(colId, info);\n    if (rowId === footerId) {\n        isEditMode = true;\n    }\n\n    return {\n        ...INIT_SELECTED_STATE,\n        cells: [{ row: rowId, col: colId, edit: isEditMode }],\n        rowAnchorId: rowId,\n        colAnchorId: colId,\n    };\n};\n\nconst getSelectedCols = (info: TInfo, col: colId, colAnchorId: colId) => {\n    const colOrder = info.table.getState().columnOrder;\n    const rv: string[] = [];\n    let start = colOrder.indexOf(colAnchorId);\n    let end = colOrder.indexOf(col);\n    if (start > end) [start, end] = [end, start];\n    for (let i = start; i <= end; i++) {\n        const colId = colOrder[i];\n        const column = info.table.getColumn(colId);\n        if (!column?.getIsVisible()) continue;\n        rv.push(colId);\n    }\n    return rv;\n};\n\nconst getSelectedRows = (info: TInfo, row: rowId, rowAnchorId: rowId) => {\n    const rowAnchor = info.table.getRow(rowAnchorId);\n    const uiRow = info.table.getRow(row);\n    const start = Math.min(uiRow.index, rowAnchor.index);\n    const end = Math.max(uiRow.index, rowAnchor.index);\n    const { rows: uiRows } = info.table.getRowModel();\n    const toSelectUiRows = uiRows.slice(start, end + 1);\n    return toSelectUiRows.map(({ id }) => id);\n};\n\nconst cellSelectedReducer = (state: SelectedState, action: CellSelectedAction, info: TInfo): SelectedState => {\n    info.table.resetRowSelection();\n\n    if (\"dir\" in action) {\n        return moveCellSelection(state, action, info);\n    } else if (\"edit\" in action) {\n        let { edit } = action;\n        const [{ row, col }] = state.cells;\n        edit &&= canEdit(col, info);\n        return { ...INIT_SELECTED_STATE, cells: [{ row, col, edit }], rowAnchorId: row, colAnchorId: col };\n    } else if (\"rowIdChange\" in action) {\n        const [prevId, newId] = action.rowIdChange;\n        const { rowAnchorId, cells, colAnchorId } = state;\n        if (rowAnchorId !== prevId) {\n            return state;\n        }\n        const newCells = cells.map((cell) => {\n            if (cell.row === prevId) {\n                return { ...cell, row: newId };\n            }\n            return cell;\n        });\n        return { ...INIT_SELECTED_STATE, cells: newCells, rowAnchorId: newId, colAnchorId };\n    }\n\n    const { cell, additive, inclusive } = action;\n    const { cells, colAnchorId, rowAnchorId } = state;\n\n    if (inclusive) {\n        if (!colAnchorId || !rowAnchorId) {\n            return { ...INIT_SELECTED_STATE, cells: [cell], colAnchorId: cell.col, rowAnchorId: cell.row };\n        }\n        const newSelectedCols = getSelectedCols(info, cell.col, colAnchorId);\n        const newSelectedRows = getSelectedRows(info, cell.row, rowAnchorId);\n\n        const newSelectedCells = [];\n\n        for (const row of newSelectedRows) {\n            for (const col of newSelectedCols) {\n                newSelectedCells.push({ row, col });\n            }\n        }\n        return { ...INIT_SELECTED_STATE, rowAnchorId, colAnchorId, cells: newSelectedCells };\n    } else if (additive) {\n        const { row: rowId, col: colId } = cell;\n        const selectedIdx = cells.findIndex(({ row, col }) => rowId === row && colId === col);\n        const selected = selectedIdx !== -1;\n        let newSelectedCells;\n        if (selected) {\n            newSelectedCells = [...cells.slice(0, selectedIdx), ...cells.slice(selectedIdx + 1)];\n        } else {\n            newSelectedCells = [...cells, { row: rowId, col: colId }];\n        }\n        return {\n            ...INIT_SELECTED_STATE,\n            cells: newSelectedCells,\n            colAnchorId: selected ? \"\" : colId,\n            rowAnchorId: selected ? \"\" : rowId,\n        };\n    } else {\n        const { col } = cell;\n        const footerId = info.table.options.meta!.footerId;\n        if (cell.row === footerId) {\n            cell.edit = true;\n        } else {\n            cell.edit &&= canEdit(col, info);\n        }\n        return { ...INIT_SELECTED_STATE, cells: [cell], colAnchorId: cell.col, rowAnchorId: cell.row };\n    }\n};\n\nconst colSelectedReducer = (state: SelectedState, { col, additive, inclusive }: ColSelectedAction, info: TInfo) => {\n    const { cols: selectedCols, colAnchorId } = state;\n\n    if (inclusive) {\n        if (!colAnchorId) {\n            return { ...INIT_SELECTED_STATE, cols: [col], colAnchorId: col };\n        }\n        const newSelectedCols = getSelectedCols(info, col, colAnchorId);\n        return { ...INIT_SELECTED_STATE, colAnchorId, cols: newSelectedCols };\n    } else if (additive) {\n        const selected = selectedCols.includes(col);\n        let newSelectedCols;\n        if (selected) {\n            newSelectedCols = selectedCols.filter((colId) => colId !== col);\n        } else {\n            newSelectedCols = [...selectedCols, col];\n        }\n        return { ...INIT_SELECTED_STATE, cols: newSelectedCols, colAnchorId: selected ? \"\" : col };\n    } else {\n        return { ...INIT_SELECTED_STATE, cols: [col], colAnchorId: col };\n    }\n};\n\nconst rowSelectedReducer = (state: SelectedState, { row, additive, inclusive }: RowSelectedAction, info: TInfo) => {\n    const { rowAnchorId } = state;\n    if (inclusive) {\n        if (!rowAnchorId) {\n            row.toggleSelected(true);\n            return { ...INIT_SELECTED_STATE, rowAnchorId: row.id };\n        }\n        const { rows: selectedUiRows } = info.table.getSelectedRowModel();\n        const rowAnchor = info.table.getRow(rowAnchorId);\n        const start = Math.min(row.index, rowAnchor.index);\n        const end = Math.max(row.index, rowAnchor.index);\n        const { rows: uiRows } = info.table.getRowModel();\n        const toSelectUiRows = uiRows.slice(start, end + 1);\n        const toSelectedIds = toSelectUiRows.map(({ id }) => id);\n        const toToggle = selectedUiRows.filter((row) => !toSelectedIds.includes(row.id));\n        toToggle.forEach((row) => row.toggleSelected(false));\n        toSelectUiRows.forEach((row) => row.toggleSelected(true));\n        return { ...INIT_SELECTED_STATE, rowAnchorId };\n    } else if (additive) {\n        const selected = row.getIsSelected();\n        row.toggleSelected(!selected);\n        return { ...INIT_SELECTED_STATE, rowAnchorId: selected ? \"\" : row.id };\n    } else {\n        const { rows: uiRows } = info.table.getSelectedRowModel();\n        uiRows.forEach((uiRow) => {\n            uiRow.id !== row.id && uiRow.toggleSelected(false);\n        });\n        row.toggleSelected(true);\n        return { ...INIT_SELECTED_STATE, rowAnchorId: row.id };\n    }\n};\n\ntype PartialCell = {\n    row: { id: TCell[\"row\"][\"id\"] };\n    column: { id: TCell[\"column\"][\"id\"] };\n};\n\nexport const useSelected = (tableId: TableId) => {\n    const cachedEditStateRef = useRef<any>(undefined);\n    const getCachedEditState = () => cachedEditStateRef.current;\n    const setCachedEditState = (v: any) => (cachedEditStateRef.current = v);\n\n    const [{ cells: selectedCells, cols: selectedCols }, selectedDispatch] = useReducer(\n        (state: SelectedState, { type, action, info }: SelectedPayload) => {\n            cachedEditStateRef.current = undefined;\n            if (type === \"row\") return rowSelectedReducer(state, action, info);\n            info?.table.resetRowSelection();\n            switch (type) {\n                case \"reset\":\n                    return INIT_SELECTED_STATE;\n                case \"cell\":\n                    const s = cellSelectedReducer(state, action, info);\n                    return s;\n                case \"col\":\n                    return colSelectedReducer(state, action, info);\n            }\n        },\n        INIT_SELECTED_STATE\n    );\n\n    const uiHiddenPrefs = useSelector((state: State) => getHiddenColumns(state, tableId));\n    useActionOnStateChange(uiHiddenPrefs, () => {\n        // a bit lazy maybe but sensible enough - we don't want hidden columns to be selected\n        selectedDispatch({ type: \"reset\" });\n    });\n\n    const updateSelectedCells = useCallback(\n        (action: CellSelectedAction, info: TInfo) => selectedDispatch({ type: \"cell\", action, info }),\n        []\n    );\n\n    const updateSelectedCols = useCallback(\n        (action: ColSelectedAction, info: TInfo) => selectedDispatch({ type: \"col\", action, info }),\n        []\n    );\n\n    const updateSelectedRows = useCallback(\n        (action: RowSelectedAction, info: TInfo) => selectedDispatch({ type: \"row\", action, info }),\n        []\n    );\n\n    const resetSelected = useCallback((info?: TInfo) => selectedDispatch({ type: \"reset\", info }), []);\n\n    const isColSelected = useCallback((colId: colId) => selectedCols.includes(colId), [selectedCols]);\n\n    const isCellSelected = useCallback(\n        (cell: PartialCell) => selectedCells.some(({ row, col }) => cell.row.id === row && cell.column.id === col),\n        [selectedCells]\n    );\n\n    const isEditingCell = useCallback(\n        (cell: PartialCell) =>\n            selectedCells.length === 1 &&\n            selectedCells[0].row === cell.row.id &&\n            selectedCells[0].col === cell.column.id &&\n            selectedCells[0].edit,\n        [selectedCells]\n    );\n\n    const isSomeColSelected = useCallback(() => !!selectedCols.length, [selectedCols]);\n\n    const isSomeCellSelected = useCallback(() => {\n        const numSelected = selectedCells.length;\n        if (numSelected !== 1) return !!numSelected;\n        return !selectedCells[0].edit;\n    }, [selectedCells]);\n\n    // a bit of a hack for linked rows, to stop them firing off a modal several times if they are remounted\n    const [isEditingLinkedRow, setIsEditingLinkedRow] = useState(false);\n\n    return {\n        selectedCells,\n        selectedCols,\n        isSomeColSelected,\n        isSomeCellSelected,\n        isEditingLinkedRow,\n        setIsEditingLinkedRow,\n        updateSelectedCells,\n        updateSelectedCols,\n        updateSelectedRows,\n        resetSelected,\n        isColSelected,\n        isCellSelected,\n        isEditingCell,\n        cachedEditStateRef,\n        getCachedEditState,\n        setCachedEditState,\n    };\n};\n","import { useCallback, useRef, useState } from \"react\";\nimport { TRow } from \"../types\";\n\nconst DEFAULT_HEIGHT = 40;\n\nexport interface RowSizingInfoState {\n    startOffset: null | number;\n    startSize: null | number;\n    deltaOffset: null | number;\n    deltaPercentage: null | number;\n    isResizingRow: false | string;\n}\n\nconst INIT_ROW_SIZING_STATE = {\n    startOffset: null,\n    startSize: null,\n    deltaOffset: null,\n    deltaPercentage: null,\n    isResizingRow: false,\n} as const;\n\nconst isTouchStartEvent = (e: any) => e?.type === \"touchstart\";\n\nexport function useRowResizing() {\n    const [rowSizingInfoState, setRowSizingInfoState] = useState<RowSizingInfoState>(INIT_ROW_SIZING_STATE);\n\n    const [rowSizing, setRowSizing] = useState<Record<string, number>>({});\n    const rowSizingRef = useRef(rowSizing);\n    rowSizingRef.current = rowSizing;\n\n    const getRowHeight = useCallback((row: TRow) => {\n        return rowSizingRef.current[row.id] ?? DEFAULT_HEIGHT;\n    }, []);\n\n    const getRowSize = useCallback((row: TRow) => {\n        return getRowHeight(row) + \"px\";\n    }, []);\n\n    const getIsRowResizing = useCallback(\n        (row: TRow) => {\n            return rowSizingInfoState.isResizingRow === row.id;\n        },\n        [rowSizingInfoState]\n    );\n\n    const getRowResizeHandler = useCallback((row: TRow) => {\n        return (e: any) => {\n            e?.persist?.();\n            if (isTouchStartEvent(e) && e.touches && e.touches.length > 1) return;\n\n            const startSize = getRowHeight(row);\n            const clientY = isTouchStartEvent(e) ? Math.round(e.touches[0].clientY) : e.clientY;\n\n            const updateOffset = (eventType: \"move\" | \"end\", clientYPos?: number) => {\n                if (typeof clientYPos !== \"number\") return;\n\n                setRowSizingInfoState((old) => {\n                    const deltaOffset = clientYPos - (old?.startOffset ?? 0);\n                    const deltaPercentage = Math.max(deltaOffset / (old?.startSize ?? 0), -0.999999);\n                    const newHeight = (old.startSize ?? 0) + deltaOffset;\n                    setRowSizing((old) => ({ ...old, [row.id]: Math.max(40, newHeight) }));\n                    return {\n                        ...old,\n                        deltaOffset,\n                        deltaPercentage,\n                    };\n                });\n            };\n            const onMove = (clientYPos?: number) => updateOffset(\"move\", clientYPos);\n\n            const onEnd = (clientYPos?: number) => {\n                updateOffset(\"end\", clientYPos);\n                setRowSizingInfoState((old) => ({\n                    ...old,\n                    isResizingRow: false,\n                    startOffset: null,\n                    startSize: null,\n                    deltaOffset: null,\n                    deltaPercentage: null,\n                }));\n            };\n\n            const mouseEvents = {\n                moveHandler: (e: MouseEvent) => onMove(e.clientY),\n                upHandler: (e: MouseEvent) => {\n                    document.removeEventListener(\"mousemove\", mouseEvents.moveHandler);\n                    document.removeEventListener(\"mouseup\", mouseEvents.upHandler);\n                    onEnd(e.clientY);\n                },\n            };\n\n            const touchEvents = {\n                moveHandler: (e: TouchEvent) => {\n                    if (e.cancelable) {\n                        e.preventDefault();\n                        e.stopPropagation();\n                    }\n                    onMove(e.touches[0].clientY);\n                    return false;\n                },\n                upHandler: (e: TouchEvent) => {\n                    document.removeEventListener(\"touchmove\", touchEvents.moveHandler);\n                    document.removeEventListener(\"touchend\", touchEvents.upHandler);\n                    if (e.cancelable) {\n                        e.preventDefault();\n                        e.stopPropagation();\n                    }\n                    onEnd(e.touches[0]?.clientY);\n                },\n            };\n\n            if (isTouchStartEvent(e)) {\n                document.addEventListener(\"touchmove\", touchEvents.moveHandler, { passive: true });\n                document.addEventListener(\"touchend\", touchEvents.upHandler, { passive: true });\n            } else {\n                document.addEventListener(\"mousemove\", mouseEvents.moveHandler, { passive: true });\n                document.addEventListener(\"mouseup\", mouseEvents.upHandler, { passive: true });\n            }\n\n            setRowSizingInfoState((old) => ({\n                ...old,\n                startOffset: clientY,\n                startSize,\n                deltaOffset: 0,\n                deltaPercentage: 0,\n                isResizingRow: row.id,\n            }));\n        };\n    }, []);\n\n    return {\n        rowSizingInfoState,\n        getRowSize,\n        // getRowHeight,\n        getRowResizeHandler,\n        getIsRowResizing,\n        setRowSizing,\n    };\n}\n","import React, { useCallback, useMemo, useReducer } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport {\n    faArrowDownLong,\n    faArrowDownZA,\n    faArrowUpAZ,\n    faArrowUpArrowDown,\n    faArrowUpLong,\n    faEyeSlash,\n    faICursor,\n    faPlus,\n    faSlash,\n    faTrash,\n    faTrashAlt,\n    faListOl,\n} from \"@fortawesome/pro-light-svg-icons\";\nimport { faChevronDown, faUser, faUserSlash } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { startCase } from \"lodash-es\";\nimport { Button } from \"@/components/reusable/Button\";\nimport DropdownMenu, { MenuItem, MenuItems, type ShowMenuCallback } from \"@/components/reusable/DropdownMenu\";\nimport { CheckBox } from \"@/components/reusable/Forms\";\nimport { HelpLink } from \"@/components/reusable/HelpLink\";\nimport { NodeRenamer } from \"@/components/reusable/NavNodeRenamer\";\nimport { Text } from \"@/components/reusable/Text\";\nimport UpgradeBadge from \"@/components/reusable/UpgradeBadge.tsx\";\nimport { getIndexKey } from \"@/components/tabs/SchemaTab\";\nimport { supportsIndexing, openTableIndexesModal } from \"@/controllers/db.ts\";\nimport { modifyIndex, updateCol } from \"@/controllers/db_new\";\nimport { getFeatures } from \"@/controllers/ide\";\nimport { alert, confirm, modal } from \"@/controllers/modals\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch, User } from \"@/types\";\nimport { ColType, ColumnSpec, IndexTypes, LiveObjectColumn, Table } from \"@/types/database\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { useInsertColumn } from \"../columns/AddColumn\";\nimport { HeaderInfo } from \"../types\";\nimport { useDeleteCols, useEditColumn } from \"./DraggableColumnHeader\";\nimport { faPencil } from \"@fortawesome/pro-light-svg-icons/faPencil\";\n\nconst sortable: ColType[] = [\"number\", \"date\", \"datetime\", \"string\", \"bool\"];\n\nconst canSort = (type: ColType) => sortable.includes(type);\n\ninterface TIndex {\n    name: string;\n    type: IndexTypes;\n    colTypes: ColType[];\n}\n\nexport const getAvailableIndexTypesForSingleColumn = (colType: ColType, table: Table) => {\n    const indexTypes: TIndex[] = [\n        { name: \"Lookup and Range queries\", type: \"b_tree\", colTypes: [\"string\", \"number\", \"date\", \"datetime\"] },\n        { name: \"Pattern matching\", type: \"trigram\", colTypes: [\"string\"] },\n        { name: \"Full-text search\", type: \"full_text\", colTypes: [\"string\"] },\n    ];\n    if (table?.split) {\n        indexTypes.unshift({ name: \"Lookup\", type: \"b_tree\", colTypes: [\"liveObject\", \"liveObjectArray\"] });\n    }\n    return indexTypes.filter((indexType) => indexType.colTypes.includes(colType));\n};\n\nconst hasSingleColumnIndex = (currentTable: Table, colId: string, type: IndexTypes) => {\n    const lookForIndex = { type, columns: [colId] };\n    const lookForKey = getIndexKey(lookForIndex);\n    const existingIndex = currentTable.all_indexes.find((index) => getIndexKey(index) === lookForKey);\n    return !!existingIndex;\n};\n\nconst isInAnyCompoundIndex = (currentTable: Table, colId: string) => {\n    return currentTable.all_indexes.some((index) => index.columns.includes(colId) && index.columns.length > 1);\n};\n\nconst getTableName = (colSpec: LiveObjectColumn, info: HeaderInfo) => {\n    const { tableMapping } = info.table.options.meta!;\n    const { table_id } = colSpec;\n    return tableMapping?.tables.find(({ id }) => id === table_id)?.name ?? \"Unknown\";\n};\n\nexport const getUiType = (type: ColType, colSpec: ColumnSpec, info: HeaderInfo) => {\n    switch (type) {\n        case \"string\":\n            return \"Text\";\n        case \"datetime\":\n            return \"Date and Time\";\n        case \"bool\":\n            return \"True/False\";\n        case \"liveObject\":\n            return getTableName(colSpec as LiveObjectColumn, info) + \" Row\";\n        case \"liveObjectArray\":\n            return getTableName(colSpec as LiveObjectColumn, info) + \" Rows\";\n        // case \"link_multiple\":\n        //     return (colSpec as LinkColumn).target + \" Rows\";\n        // case \"link_single\":\n        //     return (colSpec as LinkColumn).target + \" Row\";\n        default:\n            return startCase(type);\n    }\n};\n\nexport const ReadOnlyColumnHeader = ({ info, children }: React.PropsWithChildren<{ info: HeaderInfo }>) => (\n    <div role=\"columnheader\" className=\"sticky cursor-pointer truncate p-3 font-normal\">\n        {children}\n    </div>\n);\n\ninterface ColumnHeaderProps {\n    info: HeaderInfo;\n    name: string;\n    type: ColType;\n}\n\ninterface IndexMenuItemProps {\n    info: HeaderInfo;\n    indexType: TIndex;\n    validPlan: boolean;\n    colSpec: ColumnSpec;\n    hideMenu: () => void;\n}\n\nconst IndexMenuItem = ({ info, indexType, validPlan, hideMenu, colSpec }: IndexMenuItemProps) => {\n    const { tableMappingId, tableId, currentTable } = info.table.options.meta!;\n    const colId = info.column.id;\n\n    const dispatch = useDispatch<AnvilDispatch>();\n    const checked = hasSingleColumnIndex(currentTable, colId, indexType.type);\n    const onChange = useEvent(async () => {\n        hideMenu();\n        if (!validPlan) {\n            return dispatch(\n                modal(\"upgradePrompt\", { featureId: currentTable.split ? \"db-indexes-split\" : \"db-indexes\" })\n            );\n        }\n        if (checked) {\n            if (\n                await dispatch(\n                    confirm(\n                        \"Remove index?\",\n                        `Are you sure you want to remove the ${indexType.name} index from column '${colSpec.name}'? Updating indexes may take some time${currentTable.split ? \"\" : \", and will block all writes to your tables until complete\"}.`\n                    )\n                )\n            ) {\n                dispatch(modifyIndex(tableMappingId, tableId, { type: indexType.type, columns: [colId] }, \"delete\"));\n            }\n        } else {\n            if (\n                await dispatch(\n                    confirm(\n                        \"Create index?\",\n                        `Are you sure you want to create a ${indexType.name} index on column '${colSpec.name}'? Updating indexes may take some time${currentTable.split ? \"\" : \", and will block all writes to your tables until complete\"}.`\n                    )\n                )\n            ) {\n                dispatch(modifyIndex(tableMappingId, tableId, { type: indexType.type, columns: [colId] }, \"create\"));\n            }\n        }\n    });\n    return (\n        <div className=\"flex items-center justify-between gap-4 px-2 py-3 hover:bg-light-bg4 dark:hover:bg-dark-bg7\">\n            <CheckBox\n                style={{ color: \"inherit\", fontWeight: \"inherit\", lineHeight: \"inherit\" }}\n                className={cx({ \"opacity-50!\": !validPlan })}\n                checked={checked}\n                onChange={onChange}>\n                {indexType.name}\n            </CheckBox>\n\n            <HelpLink inline url={`/doc#tables_index_${indexType.type}`} className=\"ml-auto\" />\n        </div>\n    );\n};\n\nconst useItems = ({\n    info,\n    type,\n    setRenaming,\n}: Pick<ColumnHeaderProps, \"info\" | \"type\"> & { setRenaming: (v: boolean) => void }) => {\n    const features = useSelector(getFeatures);\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const {\n        tableMappingId,\n        updateColumnSorting,\n        readonly,\n        updateHiddenColumns,\n        columnSorting,\n        removeColumnSorting,\n        currentTable,\n    } = info.table.options.meta!;\n    const colSpec = info.column.columnDef.meta!.original!;\n\n    const onInsertColumn = useInsertColumn(info);\n    const onDeleteColumn = useDeleteCols(info.table);\n    const onEditColumn = useEditColumn();\n    const colId = info.column.id;\n    const currentlySorted = columnSorting.find(({ colId: id }) => colId === id);\n    const validPlan = supportsIndexing(features, currentTable!);\n\n    const maybeOpenTableIndexesModal = useCallback(() => {\n        if (validPlan) {\n            dispatch(openTableIndexesModal(tableMappingId, currentTable));\n        } else {\n            dispatch(modal(\"upgradePrompt\", { featureId: currentTable.split ? \"db-indexes-split\" : \"db-indexes\" }));\n        }\n    }, [validPlan, dispatch, tableMappingId, currentTable]);\n\n    const isInAnIndex = useMemo(\n        () => currentTable.all_indexes.some((index) => index.columns.indexOf(colId) !== -1),\n        [currentTable.all_indexes, colId]\n    );\n\n    return useCallback(\n        (selectItem: any, hideMenu: () => void) => {\n            const items: MenuItems = [];\n            if (canSort(type)) {\n                const ascending: MenuItem = [\"Sort Ascending\", () => updateColumnSorting(colId, true), faArrowUpAZ];\n                const descending: MenuItem = [\n                    \"Sort Descending\",\n                    () => updateColumnSorting(colId, false),\n                    faArrowDownZA,\n                ];\n                const mkClear = (ascending: boolean): MenuItem => [\n                    \"Clear Sort\",\n                    () => removeColumnSorting(colId),\n                    <div className=\"fa-layers\">\n                        <FontAwesomeIcon icon={ascending ? faArrowUpAZ : faArrowDownZA} fixedWidth />\n                        <FontAwesomeIcon icon={faSlash} fixedWidth />\n                    </div>,\n                ];\n\n                if (!currentlySorted) {\n                    items.push(ascending, descending);\n                } else if (currentlySorted.ascending) {\n                    items.push(descending, mkClear(currentlySorted.ascending));\n                } else {\n                    items.push(ascending, mkClear(currentlySorted.ascending));\n                }\n            }\n            if (readonly) return items;\n            if (items.length) items.push(<hr />);\n            items.push(\n                [\"Rename\", () => setRenaming(true), faICursor],\n                [\"Hide Column\", () => updateHiddenColumns(colId, false), faEyeSlash],\n                [\"Insert Column\", () => onInsertColumn(), faPlus],\n                [\"Delete Column\", () => onDeleteColumn([colId]), faTrash]\n            );\n            if (currentTable.split) {\n                if (colSpec.type === \"liveObject\") {\n                    items.push([\"Edit Column...\", () => onEditColumn(info), faPencil]);\n                }\n                items.push(<hr />);\n                items.push([\n                    isInAnIndex\n                        ? <>Manage Indexes <span className=\"font-mono\">({currentTable.all_indexes.length})</span></>\n                        : \"Add Index\",\n                    () => maybeOpenTableIndexesModal(),\n                    faListOl,\n                ]);\n            }\n            else {\n                const availableIndexTypes = getAvailableIndexTypesForSingleColumn(type, currentTable!);\n                if (availableIndexTypes.length > 0) {\n                    if (items.length) items.push(<hr />);\n                    const validPlan = supportsIndexing(features, currentTable!);\n                    items.push(<Text level={3}>Optimise for...</Text>);\n                    items.push(\n                        ...availableIndexTypes.map((indexType) => (\n                            <IndexMenuItem\n                                key={indexType.type}\n                                validPlan={validPlan}\n                                indexType={indexType}\n                                hideMenu={hideMenu}\n                                colSpec={colSpec}\n                                info={info}\n                            />\n                        ))\n                    );\n                }\n            }\n            return items;\n        }, [type, updateColumnSorting, currentlySorted, readonly, updateHiddenColumns, onInsertColumn, onDeleteColumn, currentTable, isInAnIndex, maybeOpenTableIndexesModal]\n    );\n};\n\nconst ColumnDropDown = ({ info, type, setRenaming }: ColumnHeaderProps & { setRenaming: (v: boolean) => void }) => {\n    const items = useItems({ info, type, setRenaming });\n\n    return (\n        <DropdownMenu\n            render={(showMenu, anchor) => {\n                return (\n                    <Button variant=\"hidden\" small onClick={(e) => showMenu(null, e.currentTarget)}>\n                        <FontAwesomeIcon icon={faChevronDown} fixedWidth />\n                        {anchor}\n                    </Button>\n                );\n            }}\n            items={items}\n        />\n    );\n};\n\ninterface ColumnHeaderInnerProps extends ColumnHeaderProps {\n    showMenu: ShowMenuCallback;\n    renaming: boolean;\n    setRenaming(v: boolean): void;\n}\n\nconst ColumnHeaderInner = ({ renaming, setRenaming, info, name, type, showMenu }: ColumnHeaderInnerProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const {\n        tableMappingId,\n        tableId,\n        readonly,\n        isColSelected,\n        updateSelectedCols,\n        columnSorting,\n        updateColumnSorting,\n        removeColumnSorting,\n    } = info.table.options.meta!;\n    const colId = info.column.id;\n    const colSpec = info.column.columnDef.meta!.original!;\n\n    const onSaveName = useEvent((name: string) => {\n        if (info.table.getAllColumns().some((c) => c.columnDef.meta?.original?.name === name)) {\n            return dispatch(alert(\"Duplicate Column Name\", `'${name}' already exists in this table`));\n        }\n        const updatedColSpec = { ...colSpec, name };\n        dispatch(updateCol(tableMappingId, tableId, colId, updatedColSpec));\n    });\n\n    const uiTypName = getUiType(type, colSpec, info).toLowerCase();\n\n    const onContextMenu: React.MouseEventHandler<HTMLDivElement> = useEvent((e) => {\n        e.preventDefault();\n        if (renaming) return;\n        if (readonly) return;\n        if (!isColSelected(colId)) {\n            updateSelectedCols({ col: colId, inclusive: false, additive: false }, info);\n        }\n        showMenu(e, e.currentTarget);\n    });\n\n    const colSorting = useMemo(() => {\n        return columnSorting.find(({ colId: id }) => colId == id);\n    }, [columnSorting]);\n\n    const sortable = canSort(colSpec.type);\n    const clientHidden = colSpec.client_hidden ?? false;\n\n    const onColumnSortingClick = useEvent(() => {\n        if (colSorting?.ascending) {\n            updateColumnSorting(colId, false);\n        } else if (colSorting) {\n            removeColumnSorting(colId);\n        } else if (sortable) {\n            updateColumnSorting(colId, true);\n        }\n    });\n\n    const stopPropagation = useEvent((e: any) => {\n        e.stopPropagation();\n    });\n\n    return (\n        <div\n            className=\"flex flex-col\"\n            onDoubleClick={() => setRenaming(true)}\n            onBlur={() => setRenaming(false)}\n            onContextMenu={onContextMenu}\n            onKeyDown={stopPropagation}>\n            {renaming ? (\n                <NodeRenamer\n                    small\n                    className=\"h-full! bg-white! px-2! py-1! text-xl! dark:bg-black!\"\n                    name={name}\n                    onRename={(name) => {\n                        setRenaming(false);\n                        onSaveName(name);\n                    }}\n                    onCancel={() => {\n                        setRenaming(false);\n                    }}\n                />\n            ) : (\n                <>\n                    <span className=\"truncate text-xl font-semibold\">{name}</span>\n                    <div className=\"flex items-center\">\n                        <span className=\"truncate text-lg font-light\">{uiTypName}</span>\n                        <div className=\"ml-auto flex items-center\" onDoubleClick={stopPropagation}>\n                            <Button\n                                small\n                                title={clientHidden ? \"Client Hidden\" : \"Client Visible\"}\n                                variant=\"hidden\"\n                                onClick={() => {\n                                    const original = info.table.getColumn(colId)?.columnDef.meta?.original;\n                                    if (!original) return;\n                                    dispatch(\n                                        updateCol(tableMappingId, tableId, colId, {\n                                            ...colSpec,\n                                            client_hidden: !clientHidden,\n                                        })\n                                    );\n                                }}>\n                                <FontAwesomeIcon\n                                    className={cx({ \"text-primary\": !clientHidden })}\n                                    icon={clientHidden ? faUserSlash : faUser}\n                                    fixedWidth\n                                />\n                            </Button>\n\n                            {(colSorting || sortable) && (\n                                <Button small variant=\"hidden\" onClick={onColumnSortingClick}>\n                                    <FontAwesomeIcon\n                                        className={cx({ \"text-primary\": !!colSorting })}\n                                        icon={\n                                            colSorting?.ascending\n                                                ? faArrowUpLong\n                                                : colSorting\n                                                    ? faArrowDownLong\n                                                    : faArrowUpArrowDown\n                                        }\n                                        fixedWidth\n                                    />\n                                </Button>\n                            )}\n                            <ColumnDropDown info={info} setRenaming={setRenaming} type={type} name={name} />\n                        </div>\n                    </div>\n                </>\n            )}\n        </div>\n    );\n};\n\nexport const ColumnHeader = ({ info, name, type }: ColumnHeaderProps) => {\n    const { selectedCols, readonly, setHiddenColumns } = info.table.options.meta!;\n    const onDelete = useDeleteCols(info.table);\n    const numCols = selectedCols.length;\n\n    const [renaming, setRenaming] = useReducer((_prev: boolean, value: boolean) => {\n        if (readonly) return false;\n        return value;\n    }, false);\n\n    const allItems = useItems({ info, type, setRenaming });\n\n    const items = (selectItem: any, hideMenu: () => void): MenuItems => {\n        if (numCols > 1) {\n            return [\n                [\n                    `Hide ${numCols} column${numCols > 1 ? \"s\" : \"\"}`,\n                    () =>\n                        setHiddenColumns((prev) => ({\n                            ...prev,\n                            ...Object.fromEntries(selectedCols.map((colId) => [colId, false])),\n                        })),\n                    faEyeSlash,\n                ],\n                [`Delete ${numCols} column${numCols > 1 ? \"s\" : \"\"}`, () => onDelete(), faTrashAlt],\n            ];\n        }\n        return allItems(selectItem, hideMenu);\n    };\n\n    return (\n        <DropdownMenu\n            render={(showMenu, anchor) => (\n                <ColumnHeaderInner\n                    info={info}\n                    type={type}\n                    name={name}\n                    showMenu={showMenu}\n                    renaming={renaming}\n                    setRenaming={setRenaming}\n                />\n            )}\n            items={items}\n        />\n    );\n};\n","import React, { useRef } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { ColumnOrderState } from \"@tanstack/react-table\";\nimport { deleteTableCol } from \"@/api/tables\";\nimport { invalidateTableSchema } from \"@/controllers/app/autocompleter\";\nimport { ingestOldIDESchemaUpdate, updateCol } from \"@/controllers/db\";\nimport {confirmWithCheckBox, modal} from \"@/controllers/modals\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { ColumnSpec } from \"@/types/database\";\nimport { checkMeta } from \"@/util\";\nimport { useDrag, useDrop } from \"@/util/dnd\";\nimport { useMergeRefs } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { reorderColumn } from \"../columns/Columns\";\nimport { HeaderInfo, TColumn, TTable } from \"../types\";\n\nconst useStyles = makeStyles()(() => ({\n    resizer: {\n        position: \"absolute\",\n        right: 0,\n        top: 0,\n        height: \"100%\",\n        width: 5,\n        background: \"rgba(0, 0, 0, 0.5)\",\n        cursor: \"col-resize\",\n        userSelect: \"none\",\n        touchAction: \"none\",\n        opacity: 0,\n        \"&:hover\": {\n            opacity: 1,\n        },\n    },\n}));\n\nconst confirmDelete = (table: TTable, selectedCols: string[]) => {\n    const numCols = selectedCols.length;\n\n    let title: string, columnIdentifier: string;\n    if (numCols === 1) {\n        const column = table.getColumn(selectedCols[0])?.columnDef.meta?.original?.name;\n        title = \"Delete column?\";\n        columnIdentifier = `the column '${column}'`;\n    } else {\n        title = \"Delete columns?\";\n        columnIdentifier = \"these columns\";\n    }\n    const message = `Are you sure you want to delete ${columnIdentifier}?`;\n    const confirmMessage = `Yes, I want to delete ${columnIdentifier}. I know I cannot undo this action.`;\n    return confirmWithCheckBox(title, message, confirmMessage, \"Delete\", \"Cancel\");\n};\n\nexport const useDeleteCols = (table: TTable) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const onDelete = useEvent(async (selectedCols?: string[]) => {\n        if (!selectedCols) {\n            ({ selectedCols } = table.options.meta!);\n        }\n        const c = await dispatch(confirmDelete(table, selectedCols));\n        if (!c) return;\n        const { appId, tableMappingId, tableId, resetSelected } = table.options.meta!;\n        resetSelected();\n        await dispatch(ingestOldIDESchemaUpdate(tableId, \"deleteCols\", { colIds: selectedCols, tableMappingId }));\n        dispatch(invalidateTableSchema(tableMappingId));\n        await Promise.all(selectedCols.map((colId) => deleteTableCol(appId, tableMappingId, tableId, colId)));\n    });\n    return onDelete;\n};\n\nexport const useEditColumn = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const onEdit = useEvent(async (info: HeaderInfo) => {\n        const tableMappingId = info.table.options.meta!.tableMappingId;\n        const tableId = info.table.options.meta!.tableId;\n        const colId = info.header.column.id;\n        const colSpec = info.header.column.columnDef.meta?.original!;\n        const newColSpec = await dispatch(modal(\"dbEditCol\", { colSpec, info}));\n        if (newColSpec) {\n            dispatch(updateCol(tableMappingId, tableId, colId, newColSpec));\n        }\n\n    });\n    return onEdit;\n};\n\nconst getNewOrder = (colId: string, columnOrder: ColumnOrderState, table: TTable) => {\n    const colIndex = columnOrder.indexOf(colId);\n    const prevColId = columnOrder[colIndex - 1];\n    const nextColId = columnOrder[colIndex + 1];\n    const prevCol = table.getColumn(prevColId)?.columnDef.meta?.original;\n    const nextCol = table.getColumn(nextColId)?.columnDef.meta?.original;\n    const prevColOrder = prevCol ? (prevCol.admin_ui?.order ?? 0) : (nextCol?.admin_ui?.order ?? 0) - 2;\n    const nextColOrder = nextCol ? (nextCol.admin_ui?.order ?? 0) : (prevCol?.admin_ui?.order ?? 0) + 2;\n    const order = (prevColOrder + nextColOrder) / 2;\n    return order;\n};\n\nconst fixedTypes = [\"media\", \"liveObject\", \"liveObjectArray\"];\n\nconst useDoubleClickResize = ({ table, column }: HeaderInfo) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const { rowVirtualizer, selectedCols, isColSelected, tableMappingId, tableId } = table.options.meta!;\n    const colId = column.id;\n\n    const onDoubleClick = useEvent(() => {\n        const { rows } = table.getRowModel();\n        const { getVirtualItems } = rowVirtualizer;\n        const span = document.createElement(\"span\");\n        document.body.appendChild(span);\n\n        let maxWidth = 50;\n        const measureText = (text: string) => {\n            span.textContent = text;\n            const currentWidth = span.clientWidth;\n            if (currentWidth > maxWidth) {\n                maxWidth = currentWidth;\n            }\n        };\n\n        const colIds = isColSelected(colId) ? selectedCols : [colId];\n        const newWidths: { [colId: string]: number } = {};\n\n        const dispatchUpdates: [string, Partial<ColumnSpec>][] = [];\n        const addDispatch = (colId: string, { admin_ui }: ColumnSpec, newWidth: number) => {\n            if (admin_ui?.width === newWidth) return;\n            dispatchUpdates.push([colId, { admin_ui: { width: newWidth } }]);\n        };\n\n        for (const colId of colIds) {\n            maxWidth = 50;\n            const original = table.getColumn(colId)?.columnDef.meta?.original;\n            if (!original) continue;\n            const { name, type } = original;\n            if (fixedTypes.includes(type)) {\n                newWidths[colId] = 200;\n                addDispatch(colId, original, 200);\n                continue;\n            }\n            span.className = \"absolute invisible inset-0 w-fit whitespace-pre-wrap p-4 text-xl font-semibold\";\n            measureText(name);\n            span.className =\n                \"text-lg absolute invisible inset-0 w-fit whitespace-pre-wrap p-2\" +\n                (type === \"simpleObject\" ? \" font-mono p-4\" : \"\");\n\n            for (const { index } of getVirtualItems()) {\n                const row = rows[index];\n                const value = row.getValue(colId);\n                measureText(String(JSON.stringify(value ?? \"None\")));\n                if (maxWidth > 200) {\n                    maxWidth = 200;\n                    break;\n                }\n            }\n            newWidths[colId] = maxWidth;\n            addDispatch(colId, original, maxWidth);\n        }\n\n        span.remove();\n        table.setColumnSizing((old) => ({ ...old, ...newWidths }));\n\n        for (const update of dispatchUpdates) {\n            dispatch(updateCol(tableMappingId, tableId, ...update));\n        }\n    });\n\n    return onDoubleClick;\n};\n\nexport const DraggableColumnHeader = ({ info, children }: { info: HeaderInfo; children: React.ReactNode }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const {\n        header,\n        table,\n        header: { column },\n        table: { getState, setColumnOrder },\n    } = info;\n    const { tableMappingId, tableId, updateSelectedCols, isColSelected, resetSelected, selectedCols } =\n        table.options.meta!;\n    const { columnOrder } = getState();\n    const { classes } = useStyles();\n\n    const [{ canDrop, isOver }, dropRef] = useDrop({\n        accept: \"column\",\n        onDrop: (draggedColumn: TColumn) => {\n            const newColumnOrder = reorderColumn(draggedColumn.id, column.id, columnOrder);\n            const meta = table.getColumn(draggedColumn.id)?.columnDef.meta;\n            if (!meta?.original) return;\n            const order = getNewOrder(draggedColumn.id, newColumnOrder, table);\n            dispatch(updateCol(tableMappingId, tableId, draggedColumn.id, { admin_ui: { order } }));\n        },\n        dropEffect: \"move\",\n    });\n\n    const [{ isDragging }, dragRef, previewRef] = useDrag({\n        item: column,\n        type: \"column\",\n    });\n\n    const onSizeChange = useEvent((width: number) => {\n        // did we change the size?\n        const original = table.getColumn(column.id)?.columnDef.meta?.original;\n        if (!original) return;\n        if (width === original.admin_ui?.width) return;\n\n        const colIds = isColSelected(column.id) ? selectedCols : [column.id];\n        const newWidths: { [colId: string]: number } = {};\n\n        for (const colId of colIds) {\n            const original = table.getColumn(colId)?.columnDef.meta?.original;\n            if (!original) continue;\n            if (width === original.admin_ui?.width) continue;\n            newWidths[colId] = width;\n            dispatch(updateCol(tableMappingId, tableId, column.id, { admin_ui: { width } }));\n        }\n        table.setColumnSizing((old) => ({ ...old, ...newWidths }));\n    });\n\n    const onClick: React.MouseEventHandler = useEvent((e) => {\n        if (e.target === dragHandleRef.current) return;\n        updateSelectedCols({ col: column.id, inclusive: e.shiftKey, additive: checkMeta(e) }, info);\n    });\n\n    const onDeleteColumns = useDeleteCols(table);\n    const onDoubleClick = useDoubleClickResize(info);\n\n    const onKeyDown: React.KeyboardEventHandler = useEvent((e) => {\n        switch (e.key) {\n            case \"Escape\":\n                e.preventDefault();\n                resetSelected(info);\n                break;\n            case \"Backspace\":\n            case \"Delete\":\n                e.preventDefault();\n                onDeleteColumns();\n                break;\n        }\n    });\n\n    const isSelected = isColSelected(column.id);\n\n    const headRef = useMergeRefs(previewRef, dropRef);\n    const dragHandleRef = useRef<HTMLDivElement>(null!);\n\n    return (\n        <div\n            role=\"columnheader\"\n            className={cx(\"relative cursor-pointer truncate bg-slate-100 p-3 font-normal dark:bg-dark-bg2\", {\n                \"bg-primary-100 dark:bg-primary-700\": canDrop && isOver,\n                \"bg-primary-50/40 dark:bg-primary-700/50\": isSelected, // && !isEditing,\n                // \"border-b-primary before:absolute before:inset-0 before:h-full before:w-full before:border-2 before:border-primary\":\n                //     isSelected,\n            })}\n            ref={headRef}\n            onClick={onClick}\n            tabIndex={0}\n            onKeyDown={onKeyDown}>\n            <div ref={dragRef} style={{ opacity: isDragging ? 0 : 1 }}>\n                {children}\n                {/* {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                <button ref={dragRef}>🟰</button> */}\n            </div>\n            <div\n                ref={dragHandleRef}\n                onClick={(e) => e.stopPropagation()}\n                className={cx(classes.resizer, { \"bg-primary-400! opacity-100!\": header.column.getIsResizing() })}\n                onMouseDown={header.getResizeHandler()}\n                onMouseUp={() => onSizeChange(header.getSize())}\n                onTouchStart={header.getResizeHandler()}\n                onTouchEnd={() => onSizeChange(header.getSize())}\n                onDoubleClick={onDoubleClick}\n            />\n        </div>\n    );\n};\n\nexport default DraggableColumnHeader;\n","import React from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faTrash } from \"@fortawesome/free-solid-svg-icons\";\nimport { faEdit } from \"@fortawesome/free-solid-svg-icons/faEdit\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { modal } from \"@/controllers/modals\";\nimport { deleteScheduledTaskWithModal, useFormatTimeSpec } from \"@/controllers/scheduledtasks\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { AnvilDispatch, ScheduledTask } from \"@/types\";\nimport useEvent from \"@/util/useEventCallback\";\nimport ScheduledTaskLastRunInfo from \"./ScheduledTaskLastRunInfo\";\n\nconst useStyles = makeStyles<void, \"editTask\">()((theme, _props, classes) => ({\n    taskView: {\n        display: \"flex\",\n        alignItems: \"baseline\",\n        padding: \"1rem\",\n        \"&:hover\": {\n            background: theme.scheduledTasks.item.hoverBackground.toString(),\n        },\n        \"&:active\": {\n            background: theme.scheduledTasks.item.activeBackground.toString(),\n        },\n        [`&:not(:hover) .${classes.editTask}`]: {\n            display: \"none\",\n        },\n    },\n    editTask: {},\n}));\n\nconst ScheduledTaskItem = ({ task }: { task: ScheduledTask }) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const { classes } = useStyles();\n\n    const onDelete = useEvent(() => {\n        dispatch(deleteScheduledTaskWithModal(task));\n    });\n\n    const onEdit = useEvent(() => dispatch(modal(\"scheduledTask\", { task })));\n\n    const formatTimeSpec = useFormatTimeSpec(task.time_spec);\n\n    return (\n        <div>\n            <div className={classes.taskView}>\n                <div className=\"flex-[0_1_auto]\">\n                    <LinkInternal onClick={onDelete}>\n                        <FontAwesomeIcon className=\"hover:text-danger\" icon={faTrash} />\n                    </LinkInternal>\n                </div>\n                <LinkInternal className=\"flex-[1_0_auto]\" onClick={onEdit}>\n                    <div className=\"flex flex-[1_0_auto] gap-5\">\n                        <span className=\"pl-4\">\n                            Run <span className=\"text-secondary\">{task.task_name} </span>\n                            <span>{formatTimeSpec}&nbsp;</span>\n                        </span>\n                        <LinkInternal onClick={onEdit}>\n                            <FontAwesomeIcon className={cx(classes.editTask)} icon={faEdit} />\n                        </LinkInternal>\n                        <ScheduledTaskLastRunInfo className={classes.editTask} simpleOnly task={task} />\n                    </div>\n                </LinkInternal>\n            </div>\n        </div>\n    );\n};\n\nexport default ScheduledTaskItem;\n","import React, { useCallback, useState } from \"react\";\nimport { connect, useSelector } from \"react-redux\";\nimport { faPlus } from \"@fortawesome/free-solid-svg-icons\";\nimport { faCheck } from \"@fortawesome/pro-light-svg-icons/faCheck\";\nimport { faExternalLinkAlt } from \"@fortawesome/pro-light-svg-icons/faExternalLinkAlt\";\nimport { faTimes } from \"@fortawesome/pro-light-svg-icons/faTimes\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useQueries, useQueryClient } from \"@tanstack/react-query\";\nimport { getScheduledTaskInfo, restartScheduledTasks } from \"@/api\";\nimport { EnvironmentHeaderTemplate } from \"@/components/modals/environments/EnvironmentHeaderTemplate\";\nimport { EnvironmentScheduledTaskConfig } from \"@/components/modals/environments/EnvironmentScheduledTaskConfig\";\nimport { Accordion } from \"@/components/reusable/Accordion\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { ModalButton } from \"@/components/reusable/SharedComponents\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport UpgradeBadge from \"@/components/reusable/UpgradeBadge\";\nimport { getAppId, getAppIsPyspace } from \"@/controllers/app\";\nimport { getCurrentBranch } from \"@/controllers/app/history\";\nimport {\n    createDefaultEnvironment,\n    getCategorisedEnvironments,\n    saveEnvironment,\n    setSelectedEnvironmentId,\n} from \"@/controllers/environments\";\nimport { getUser } from \"@/controllers/ide\";\nimport { modal } from \"@/controllers/modals\";\nimport { getScheduledTasks } from \"@/controllers/scheduledtasks\";\nimport { useUpdateTabTitle } from \"@/controllers/tabs\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport type { AnvilConnectedProps, AppEnvironment, ScheduledTask, State } from \"@/types\";\nimport type { BasicTab } from \"@/types/tabs\";\nimport { useFeatureSupported } from \"@/util/features\";\nimport useEvent from \"@/util/useEventCallback\";\nimport ScheduledTaskItem from \"./ScheduledTaskItem\";\n\nconst useStyles = makeStyles()((theme) => ({\n    root: {\n        padding: \"0.5rem 2rem\",\n        color: theme.scheduledTasks.color.toString(),\n        \"& a\": {\n            color: theme.palette.grey2.toString(),\n            textDecoration: \"underline\",\n        },\n        \"& hr\": {\n            borderTop: \"1px solid \" + theme.scheduledTasks.border.toString(),\n        },\n        maxWidth: \"100rem\",\n    },\n    paddingTop10: {\n        paddingTop: \"1rem\",\n    },\n}));\n\nconst newTask: Omit<ScheduledTask, \"job_id\"> = {\n    task_name: \"\",\n    time_spec: {\n        n: 10,\n        every: \"minute\",\n        at: {\n            hour: 3,\n            minute: 0,\n        },\n    },\n};\n\nconst connector = connect((state: State) => ({\n    branch: getCurrentBranch(state),\n    scheduledTasks: getScheduledTasks(state),\n    environments: getCategorisedEnvironments(state),\n}));\n\ntype ScheduledTasksTabProps = AnvilConnectedProps<typeof connector> & {\n    tab: BasicTab;\n};\n\nconst ScheduledTasksTab = ({ tab, scheduledTasks, dispatch, environments, branch }: ScheduledTasksTabProps) => {\n    const { classes } = useStyles();\n    const appId = useSelector(getAppId);\n    const user = useSelector(getUser);\n    const isPyspace = useSelector(getAppIsPyspace);\n    const supportsScheduledTasks = useFeatureSupported(\"scheduled-tasks\");\n    const scheduledTasksNotEnabled = !isPyspace && !!user && !supportsScheduledTasks;\n    const queryClient = useQueryClient();\n\n    useUpdateTabTitle(tab, \"Scheduled Tasks\");\n\n    // Query all task infos to detect suspension — shares cache with per-task ScheduledTaskLastRunInfo queries\n    const taskInfoResults = useQueries({\n        queries: (scheduledTasks ?? []).map((task) => ({\n            queryKey: [\"task-info\", appId, task.job_id],\n            queryFn: () => getScheduledTaskInfo(appId!, task.job_id),\n            enabled: !!appId,\n        })),\n    });\n    const anySuspended = taskInfoResults.some((r) => r.data?.some((info) => info.suspended_at));\n\n    const onReactivate = useEvent(async () => {\n        await restartScheduledTasks(appId!);\n        await queryClient.invalidateQueries({ queryKey: [\"task-info\", appId] });\n    });\n\n    const onAddTask = useCallback(() => {\n        dispatch(modal(\"scheduledTask\", { task: newTask }));\n    }, []);\n\n    const [selectedEnvId, setSelectedEnvId] = useState<AppEnvironment[\"env_id\"] | null>(null);\n\n    const selectEnvironment = useCallback(\n        async ({ env_id }: AppEnvironment) => {\n            if (selectedEnvId === env_id) {\n                setSelectedEnvId(null);\n            } else {\n                setSelectedEnvId(env_id);\n            }\n        },\n        [selectedEnvId]\n    );\n\n    const gotoEnvironment = useCallback(async (envId: AppEnvironment[\"env_id\"]) => {\n        await dispatch(setSelectedEnvironmentId(envId));\n        dispatch(modal(\"environments\", {}));\n    }, []);\n\n    const enableScheduledTasks = useCallback(async () => {\n        if (environments.sorted.length === 0) {\n            await dispatch(createDefaultEnvironment());\n        } else {\n            await dispatch(saveEnvironment(environments.sorted[0], { run_scheduled_tasks: true }));\n        }\n    }, [environments]);\n\n    let environmentsUi: React.ReactNode;\n    if (\n        branch &&\n        (environments.sorted.length === 0 ||\n            (environments.sorted.length === 1 && !environments.sorted[0].run_scheduled_tasks))\n    ) {\n        environmentsUi = (\n            <>\n                <Heading>Scheduled tasks are disabled</Heading>\n                <Button variant={\"secondary\"} onClick={enableScheduledTasks}>\n                    Enable Scheduled Tasks\n                </Button>\n            </>\n        );\n    } else if (branch && environments.sorted.length === 1) {\n        const env = environments.sorted[0];\n        // We know scheduled tasks are enabled, because otherwise we'd be in the clause above.\n        if (env.version?.ref === `refs/heads/${branch}`) {\n            environmentsUi = (\n                <Text level={2}>\n                    Scheduled Tasks are running from the <code>{branch}</code> branch, which you are currently editing.\n                    Any changes you make here will take effect immediately.\n                </Text>\n            );\n        } else if (env.version?.ref && env.version.ref !== `refs/heads/${branch}`) {\n            environmentsUi = (\n                <Text level={2}>\n                    Scheduled Tasks are currently running on the <code>{env.version.ref.substring(11)}</code> branch.\n                    Changes you make here won’t take effect until they are merged from your current branch{\" \"}\n                    <code>{branch}</code> into <code>{env.version.ref.substring(11)}</code>.\n                </Text>\n            );\n        } else if (!env.version?.ref) {\n            environmentsUi = (\n                <Text level={2}>\n                    Scheduled Tasks are currently running on an old version of your app. Changes you make here will have\n                    no effect until your environments are updated.\n                </Text>\n            );\n        }\n    } else if (environments.sorted.length > 1) {\n        environmentsUi = (\n            <>\n                <Heading level={2}>App Environments</Heading>\n                <Accordion\n                    items={environments.sorted}\n                    keyName={\"env_id\"}\n                    expandedKeys={selectedEnvId == null ? {} : { [selectedEnvId]: true }}\n                    onToggle={selectEnvironment}\n                    renderHeader={(env: AppEnvironment, idx: number, isExpanded: boolean) => (\n                        <EnvironmentHeaderTemplate\n                            title={env.description}\n                            subtitle={\n                                env.version?.ref ? (\n                                    <>\n                                        Loads the <code>{env.version.ref.substring(11)}</code> branch of this app\n                                    </>\n                                ) : (\n                                    `Loads a specific version of this app`\n                                )\n                            }\n                            actions={\n                                isExpanded && [\n                                    [faExternalLinkAlt, \"Edit environment...\", () => gotoEnvironment(env.env_id)],\n                                ]\n                            }\n                            flags={\n                                <div className={cx(env.run_scheduled_tasks && \"present\")}>\n                                    Run Scheduled Tasks{\" \"}\n                                    <FontAwesomeIcon fixedWidth icon={env.run_scheduled_tasks ? faCheck : faTimes} />\n                                </div>\n                            }\n                        />\n                    )}\n                    renderBody={(env: AppEnvironment, idx: number) => (\n                        <div className=\"p-6\">\n                            <EnvironmentScheduledTaskConfig env={env} />\n                            {branch && env.version?.ref && env.version.ref === `refs/heads/${branch}` && (\n                                <Text level={3}>\n                                    Changes you make to Scheduled Task configuration will take effect in this\n                                    environment immediately.\n                                </Text>\n                            )}\n                            {branch && env.version?.ref && env.version.ref !== `refs/heads/${branch}` && (\n                                <Text level={3}>\n                                    Changes you make to Scheduled Task configuration will only take effect when you\n                                    merge your current branch <code>{branch}</code> into{\" \"}\n                                    <code>{env.version.ref.substring(11)}</code>.\n                                </Text>\n                            )}\n                            {branch && !env.version?.ref && (\n                                <Text level={3}>\n                                    Changes you make to Scheduled Task configuration will not affect this environment.\n                                </Text>\n                            )}\n                        </div>\n                    )}\n                />\n            </>\n        );\n    }\n\n    return (\n        <div className={classes.root}>\n            <h1 className={\"my-6 text-5xl font-medium\"}>Scheduled Tasks</h1>\n            {scheduledTasksNotEnabled ? (\n                <div className=\"my-4 flex items-center gap-4 rounded border border-danger bg-danger/10 p-4\">\n                    <Text level={2} className=\"flex-1 text-danger\">\n                        Scheduled tasks are unavailable for this app.\n                    </Text>\n                    <Button\n                        variant=\"secondary\"\n                        onClick={() => dispatch(modal(\"upgradePrompt\", { featureId: \"scheduled-tasks\" }))}>\n                        Enable Scheduled Tasks <UpgradeBadge feature=\"scheduled-tasks\" />\n                    </Button>\n                </div>\n            ) : (\n                anySuspended && (\n                    <div className=\"my-4 flex items-center gap-4 rounded border border-danger bg-danger/10 p-4\">\n                        <Text level={2} className=\"flex-1 text-danger\">\n                            Scheduled tasks are currently suspended for this app.\n                        </Text>\n                        <Button variant=\"secondary\" onClick={onReactivate}>\n                            Activate\n                        </Button>\n                    </div>\n                )\n            )}\n\n            {!scheduledTasks || (scheduledTasks.length === 0 && <p>There are no Scheduled Tasks to show</p>)}\n            {scheduledTasks?.map((task) => (\n                <ScheduledTaskItem key={task.job_id} task={task} />\n            ))}\n            {!scheduledTasksNotEnabled && (\n                <div className={classes.paddingTop10}>\n                    <ModalButton variant={\"primary\"} onClick={onAddTask} icon={faPlus}>\n                        Add Task\n                    </ModalButton>\n                </div>\n            )}\n            <hr />\n\n            {!scheduledTasksNotEnabled && environmentsUi}\n\n            {/*<h3 className={\"text-4xl font-medium mt-10 mb-5\"}>Environments with Scheduled Tasks Enabled</h3>*/}\n            {/*{scheduledTaskEnvs && scheduledTaskEnvs.length ? (*/}\n            {/*    <>*/}\n            {/*        <p>*/}\n            {/*            <i>*/}\n            {/*                You are currently editing branch <code>{branch}</code>. The following environments have*/}\n            {/*                scheduled tasks enabled:*/}\n            {/*            </i>*/}\n            {/*        </p>*/}\n            {/*        <ul style={{ display: \"block\" }}>*/}\n            {/*            {scheduledTaskEnvs?.map((env) => (*/}\n            {/*                <li style={{ listStyle: \"inside\" }} key={env.env_id}>*/}\n            {/*                    {env.description}*/}\n            {/*                </li>*/}\n            {/*            ))}*/}\n            {/*        </ul>*/}\n            {/*    </>*/}\n            {/*) : (*/}\n            {/*    <p>*/}\n            {/*        <i>*/}\n            {/*            You are currently editing branch <code>{branch}</code> and have no environments with scheduled*/}\n            {/*            tasks enabled*/}\n            {/*        </i>*/}\n            {/*    </p>*/}\n            {/*)}*/}\n            {/*<div>*/}\n            {/*    <ModalButton*/}\n            {/*        variant={\"primary\"}*/}\n            {/*        onClick={() => dispatch(modal(\"environments\", {}))}*/}\n            {/*        icon={faSlidersH}>*/}\n            {/*        Configure Environments*/}\n            {/*    </ModalButton>*/}\n            {/*</div>*/}\n        </div>\n    );\n};\n\nexport default connector(ScheduledTasksTab) as typeof ScheduledTasksTab;\n","import React, { useLayoutEffect, useMemo, useRef } from \"react\";\nimport { connect, useDispatch } from \"react-redux\";\nimport { faChevronRight } from \"@fortawesome/free-solid-svg-icons/faChevronRight\";\nimport moment from \"moment\";\nimport \"moment-timezone\";\nimport type { BindingError } from \"@runtime/runner/error-handling\";\nimport { getApp } from \"@/controllers/app\";\nimport { getCodeNames, getInPlaceEditTarget } from \"@/controllers/app/code\";\nimport { NavTarget } from \"@/router/navTypes\";\nimport { navigate } from \"@/router/navigation\";\nimport { cx, makeStyles } from \"@/theme/styles\";\nimport { AnvilConnectedProps, AnvilDispatch, CodePath, State } from \"@/types\";\nimport { SessionErrorTraceEntry, SessionEvent, SessionProps } from \"@/types/sessions\";\nimport { useCopyAllKeyBinding } from \"@/util/hooks/global-key-bindings\";\nimport { LinkInternal } from \"../../reusable/LinkInternal\";\nimport { BottomPanelToolbarButton } from \"../../reusable/SharedComponents\";\nimport { Text } from \"../../reusable/Text\";\n\nconst useStyles = makeStyles()((theme) => ({\n    eventList: {\n        display: \"inline-flex\",\n        flexDirection: \"column\",\n        marginLeft: \"-3.5rem\",\n        marginRight: \"-1rem\",\n        minWidth: \"calc(100% + 4.5rem)\",\n    },\n    logEvent: {\n        paddingLeft: \"3.5rem\",\n        paddingRight: \"1rem\",\n    },\n    logEventOutput: {\n        whiteSpace: \"pre\",\n        fontSize: theme.appSessions.fontSize,\n        fontFamily: '\"Source Code Pro\", monospace',\n        color: theme.appSessions.color.toString(),\n    },\n    serverEvent: {\n        paddingLeft: \"calc(3.5rem - 3px)\",\n        borderLeft: \"3px solid \" + \"#ffa640\",\n        //background: '#ffa6402e',\n    },\n    clientEvent: {\n        paddingLeft: \"calc(3.5rem - 3px)\",\n        borderLeft: \"3px solid \" + \"#1BB0EE\",\n    },\n    errorEvent: {\n        color: theme.appSessions.errorEvent.color.toString(),\n    },\n    itemLink: {\n        textDecoration: \"underline\",\n    },\n    snippetMatch: {\n        background: \"yellow\",\n    },\n    bindingAlert: {\n        color: theme.liveOutput.alert.color.toString(),\n        backgroundColor: theme.liveOutput.alert.bgColor.toString(),\n        borderColor: theme.liveOutput.alert.border.toString(),\n        \"& code\": {\n            fontWeight: \"bold\",\n        },\n    },\n    bindingLink: {\n        color: theme.liveOutput.link.color.toString(),\n        borderBottom: \"1px dotted\",\n        \"& code\": {\n            color: theme.liveOutput.link.color.toString(),\n        },\n        \"&:hover\": {\n            borderBottom: \"1px solid\",\n            cursor: \"pointer\",\n        },\n    },\n    bindingCode: {\n        backgroundColor: \"transparent !important\",\n        color: theme.liveOutput.codeColor.toString(),\n    },\n    bindingCodeHighlight: {\n        backgroundColor: theme.liveOutput.codeHighlightBg.toString(),\n        color: theme.liveOutput.codeColor.toString(),\n    },\n}));\n\nconst connector = connect((state: State) => ({\n    app: getApp(state),\n    allCodeNames: getCodeNames(state),\n}));\n\ntype ErrorEventProps = AnvilConnectedProps<typeof connector> & {\n    event: SessionEvent;\n    className?: string;\n    classes: Record<string, string>;\n};\n\nconst ErrorEvent = connector(({ app, dispatch, allCodeNames, event, className, classes }: ErrorEventProps) => {\n    const navigateToBinding = ({ binding: { component_name, property } }: BindingError, codePath: CodePath) => {\n        const target: NavTarget = {\n            type: \"CODE\",\n            codePath,\n            view: { design: [\"binding\", `${component_name}.${property}`] },\n            ...getInPlaceEditTarget(app, codePath),\n        };\n        dispatch(navigate(target));\n    };\n\n    const err = useMemo(() => {\n        const data = event.d || {};\n        const e = {\n            type: data.type,\n            message: `${data.message}`, // Ensure err.message is a string, because we've seen it arrive as a full Skulpt object (with $mangled, v, etc). No idea how.\n            bindingErrors: data.bindingErrors,\n            trace: [] as SessionErrorTraceEntry[],\n        };\n\n        for (const frame of data.trace || []) {\n            const match = (frame[0] || \"\").match(/^(?:anvil-app-modules\\/|app\\/|\\/|C:\\/)?(.+?)(\\/__init__)?\\.py$/);\n            let itemName = match && match[1].replace(/\\//g, \".\");\n            const appPackageName = app?.config.package_name || \"main_app_package\";\n            let codeItem = null;\n            if (itemName && itemName.startsWith(appPackageName + \".\")) {\n                itemName = itemName.substr(appPackageName.length + 1);\n                const jumpToMatch = match?.[1]?.match(/^(?:.+?)\\/(.+?)(\\/__init__)?$/);\n                const codePath = jumpToMatch?.[1]?.replace(/\\//g, \".\");\n                codeItem = codePath ? allCodeNames[codePath] : null;\n            } else if (itemName && allCodeNames[itemName]) {\n                // this is slightly janky to cope with the fact that scripts just show up as 'Script.py'\n                codeItem = allCodeNames[itemName];\n            }\n\n            if (frame[0] === \"<rpc>\") {\n                e.trace.push({\n                    internalRPC: true,\n                });\n            } else {\n                e.trace.push({\n                    itemName: itemName,\n                    filename: frame[0],\n                    line: frame[1] == null ? undefined : frame[1] - 1,\n                    codeItem: codeItem,\n                    itemTarget:\n                        codeItem && frame[1] != null\n                            ? {\n                                  type: \"CODE\",\n                                  codePath: codeItem.codePath,\n                                  essentialView: { code: [frame[1], 0] },\n                              }\n                            : undefined,\n                });\n            }\n        }\n        return e;\n    }, [event, allCodeNames]);\n\n    return (\n        <div className={cx(\"select-text\", className)}>\n            <div>\n                {err.type}: {err.message}\n            </div>\n            {err.bindingErrors?.map((b, i) => {\n                const bindingDescription = (\n                    <>\n                        <code className={classes.bindingCode}>{b.binding.property}</code> of{\" \"}\n                        <code className={classes.bindingCode}>{b.binding.component_name || b.formName}</code>\n                    </>\n                );\n                const codePath = allCodeNames[b.formName]?.codePath;\n                return (\n                    <div key={i} className={cx(\"my-1 rounded border px-4 py-3\", classes.bindingAlert)}>\n                        Error binding{\" \"}\n                        {codePath ? (\n                            <LinkInternal\n                                className={classes.bindingLink}\n                                onClick={() => navigateToBinding(b, codePath)}>\n                                {bindingDescription}\n                            </LinkInternal>\n                        ) : (\n                            bindingDescription\n                        )}{\" \"}\n                        to <code className={classes.bindingCode}>{b.binding.code}</code>:{\" \"}\n                        <code className={cx(\"rounded\", classes.bindingCodeHighlight)}>{b.message}</code>\n                    </div>\n                );\n            })}\n            {err.trace?.map((t, i) => (\n                <div key={i}>\n                    {t.internalRPC ? (\n                        <code>&lt;running on the server&gt;</code>\n                    ) : (\n                        <>\n                            {t.line != null && (\n                                <>\n                                    {i === 0 ? \"at \" : \"called from \"}\n                                    {t.codeItem ? (\n                                        <span>\n                                            <LinkInternal\n                                                className={classes.itemLink}\n                                                onClick={() => t.itemTarget && dispatch(navigate(t.itemTarget))}>\n                                                {t.itemName}, line {t.line + 1}\n                                            </LinkInternal>\n                                        </span>\n                                    ) : (\n                                        <span>\n                                            {t.filename}, line {t.line + 1}\n                                        </span>\n                                    )}\n                                </>\n                            )}\n                        </>\n                    )}\n                </div>\n            ))}\n        </div>\n    );\n});\n\nconst MatchEvent = ({ event, ref }: { event: SessionEvent; ref: React.Ref<HTMLSpanElement> }) => {\n    const { classes } = useStyles();\n    // TODO: Need to truncate log_text if it's very long. We truncate to 100000 chars if we're not matching.\n    const { log_text: logText = \"\", match_start: matchStart = 0, match_len: matchLen = 0 } = event;\n    const matchEnd = matchStart + matchLen;\n\n    return (\n        <>\n            {logText.slice(0, matchStart)}\n            <span ref={ref} className={classes.snippetMatch}>\n                {logText.slice(matchStart, matchEnd)}\n            </span>\n            {logText.slice(matchEnd)}\n        </>\n    );\n};\n\nconst humanizeDuration = (duration: moment.Duration) => {\n    const units = [\n        { label: \"d\", value: duration.days() },\n        { label: \"h\", value: duration.hours() },\n        { label: \"m\", value: duration.minutes() },\n        { label: \"s\", value: duration.seconds() },\n        { label: \"ms\", value: duration.milliseconds() },\n    ];\n\n    return units\n        .filter((unit) => unit.value > 0)\n        .map((unit) => `${unit.value}${unit.label}`)\n        .join(\" \")\n        .trim();\n};\n\n/** Convert a raw log-firehose websocket event into the compact shape LogEvent renders */\nexport const compressEvent = ({ type, timestamp, log_text, data }: any): SessionEvent =>\n    ({\n        tp: type,\n        tm: timestamp,\n        d: data,\n        log_text,\n    } as SessionEvent);\n\ninterface LogEventProps {\n    session: SessionProps;\n    event: SessionEvent;\n    isOpen: boolean;\n}\n\nexport const LogEvent = ({ session, event, isOpen }: LogEventProps) => {\n    const { classes } = useStyles();\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const matchRef = useRef<HTMLSpanElement | null>(null);\n\n    useLayoutEffect(() => {\n        if (isOpen && matchRef.current) {\n            setTimeout(() => {\n                matchRef.current?.scrollIntoView();\n            }, 100);\n        }\n    }, [isOpen]);\n\n    const onServer = event.tp === \"print\" || event.tp === \"err\";\n    switch (event.tp) {\n        case \"print\":\n        case \"client_print\":\n            // Log text is sometimes huge. This is a very blunt hammer to truncate it and prevent thousands (millions?) of consecutive newlines, which can blow up the browser.\n            // TODO: Fix this properly.\n            return (\n                <div\n                    className={cx(\n                        \"select-text\",\n                        classes.logEvent,\n                        classes.logEventOutput,\n                        onServer ? classes.serverEvent : classes.clientEvent\n                    )}>\n                    {session.match_event === event ? (\n                        <MatchEvent event={event} ref={matchRef} />\n                    ) : (\n                        (event.log_text || \"\").substring(0, 100000).replaceAll(/\\n+/g, \"\\n\")\n                    )}\n                </div>\n            );\n\n        case \"err\":\n        case \"client_err\":\n            return (\n                <ErrorEvent\n                    event={event}\n                    className={cx(\n                        classes.logEvent,\n                        classes.logEventOutput,\n                        onServer ? classes.serverEvent : classes.clientEvent,\n                        classes.errorEvent\n                    )}\n                    classes={classes}\n                />\n            );\n\n        case \"background_task_ended\":\n            // There are two conflicting session types that arrive here.\n            // One is the session row from the app logs DB, and the other is the \"SESSION_START\" event object (which arrives here via scriptRuns).\n            // We should fix this, but for now just cope with either type.\n            const startTime = moment.utc(session.start_time ?? session.timestamp);\n            const endTime = moment.utc(event.tm);\n            const duration = moment.duration(endTime.diff(startTime));\n\n            return (\n                <Text narrow level={2} className={cx(classes.logEvent)}>\n                    {session.data?.scheduled_task\n                        ? \"Scheduled task\"\n                        : session.data?.func?.startsWith(\"task:script:\")\n                          ? \"Script execution\"\n                          : \"Background task\"}{\" \"}\n                    ended ({event.d?.status?.replace(\"threw \", \"failed \")}after {humanizeDuration(duration)}) at{\" \"}\n                    {endTime.tz(moment.tz.guess()).format(\"HH:mm:ss z [on] ddd Do MMM YYYY\")}\n                </Text>\n            );\n\n        case \"uplink_register\":\n            return (\n                <Text narrow level={1} className={cx(classes.logEvent)}>\n                    Uplink function registered: <code className={\"select-text\"}>{event.d?.func}</code>\n                </Text>\n            );\n\n        case \"background_task_launched\": {\n            // Deliberately looks like the collapsed version of the runner's inline BG-task\n            // widget (RunnerBgTaskWidget) - minus the live controls, obviously.\n            const launched = (event.d ?? {}) as { task_id?: string; session_id?: string; task_name?: string };\n            return (\n                <div className={cx(classes.logEvent, \"my-1\")}>\n                    <span className=\"inline-flex max-w-full items-center gap-3 rounded border border-sectionborder px-3 py-1 dark:border-dark-sectionborder\">\n                        {/* One inline text run (like SessionDescription's \"Background Task <code>\"),\n                            so the task name sits on the same baseline as the label */}\n                        <Text narrow level={2} className=\"min-w-0 truncate\">\n                            <span className=\"italic\">Launched task</span>{\" \"}\n                            <code className=\"select-text\">{(launched.task_name || \"\").replace(/^task:/, \"\")}</code>\n                        </Text>\n                        {launched.session_id && (\n                            <BottomPanelToolbarButton\n                                small\n                                className=\"shrink-0\"\n                                iconRight\n                                icon={faChevronRight}\n                                onClick={() =>\n                                    dispatch(\n                                        navigate({\n                                            type: \"SESSION\",\n                                            sessionId: launched.session_id!,\n                                            displayMode: \"LOGS\",\n                                        })\n                                    )\n                                }>\n                                Logs\n                            </BottomPanelToolbarButton>\n                        )}\n                    </span>\n                </div>\n            );\n        }\n\n        case \"log_truncated\":\n            return (\n                <Text narrow level={2} className={cx(classes.logEvent)}>\n                    Further output not stored. To increase your logging limit, please contact{\" \"}\n                    <a href=\"support@anvil.works\">support@anvil.works</a>.\n                </Text>\n            );\n\n        case \"session_started\": // Currently only generated synthetically, and only in pyspace\n            return (\n                <Text narrow level={2} className={cx(classes.logEvent)}>\n                    {session.data?.scheduled_task\n                        ? \"Scheduled task\"\n                        : session.data?.func\n                          ? session.data?.func?.startsWith(\"task:script:\")\n                              ? \"Script execution\"\n                              : \"Background task\"\n                          : \"Session\"}{\" \"}\n                    started at {moment.utc(event.tm).tz(moment.tz.guess()).format(\"HH:mm:ss z [on] ddd Do MMM YYYY\")}\n                </Text>\n            );\n\n        case \"session_ended\":\n            return (\n                <Text narrow level={2} className={cx(classes.logEvent)}>\n                    Session ended at{\" \"}\n                    {moment.utc(event.tm).tz(moment.tz.guess()).format(\"HH:mm:ss z [on] ddd Do MMM YYYY\")}\n                </Text>\n            );\n\n        case \"import_time\":\n            return null;\n\n        default:\n            return (\n                <Text narrow level={3}>\n                    Unknown event type: {event.tp}\n                </Text>\n            );\n    }\n};\n\nconst LogImportSummary = ({ callCount, events }: { callCount?: number; events: SessionEvent[] }) => {\n    const { classes } = useStyles();\n    const importEvent = events.find((env) => env.tp === \"import_time\");\n    if (importEvent) {\n        const totalImportDuration =\n            importEvent.d?.importDuration == 0\n                ? \"less than 1\"\n                : (importEvent.d?.importDuration ?? 0) * (callCount ?? 0);\n        return (\n            <Text narrow level={2} className={cx(classes.logEvent)}>\n                Total import time: {totalImportDuration} ms ({callCount} server calls)\n            </Text>\n        );\n    } else {\n        return null;\n    }\n};\n\nexport const EventData = ({ session, isOpen }: { session: SessionProps; isOpen: boolean }) => {\n    const { classes } = useStyles();\n    const ref = useRef<HTMLDivElement | null>(null);\n    const onCopyAll = useCopyAllKeyBinding(ref as React.RefObject<HTMLElement>);\n\n    return (\n        <div tabIndex={0} ref={ref} onKeyDown={onCopyAll} className={classes.eventList}>\n            {session.event_data?.map((evt) => (\n                <LogEvent key={evt.tm} session={session} event={evt} isOpen={isOpen} />\n            )) || null}\n            {<LogImportSummary callCount={session.call_count} events={session.event_data} />}\n        </div>\n    );\n};\n","import React, { useId, useState } from \"react\";\nimport { faChevronRight } from \"@fortawesome/pro-regular-svg-icons/faChevronRight\";\nimport { faCircleExclamation } from \"@fortawesome/pro-regular-svg-icons/faCircleExclamation\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { useTooltip } from \"@/components/reusable/Tooltip\";\nimport type { DependencyGraph, DependencyTreeEdge, DependencyVersionSpec, IDEDependencyCode } from \"@/types\";\nimport { hasDependencyErrors } from \"./dependency-tree\";\n\nconst DEPENDENCY_INDENT_REM = 2.3;\n\nexport function DependencyExpandButton({\n    name,\n    expanded,\n    canExpand,\n    controls,\n    onToggle,\n}: {\n    name: string;\n    expanded: boolean;\n    canExpand: boolean;\n    controls: string;\n    onToggle: () => void;\n}) {\n    if (!canExpand) return <span aria-hidden=\"true\" className=\"w-[2rem] shrink-0\" />;\n\n    return (\n        <Button\n            variant=\"hidden\"\n            small\n            isIconButton\n            className=\"h-[2rem]! w-[2rem] shrink-0\"\n            linkClassName=\"w-full! border-0! p-0!\"\n            title={`${expanded ? \"Hide\" : \"Show\"} dependencies of ${name}`}\n            aria-label={`Dependencies of ${name}`}\n            aria-expanded={expanded}\n            aria-controls={controls}\n            onClick={onToggle}\n            onKeyDown={(event) => {\n                if (event.key === \"Enter\" || event.key === \" \") {\n                    event.preventDefault();\n                    onToggle();\n                }\n            }}>\n            <FontAwesomeIcon icon={faChevronRight} fixedWidth rotation={expanded ? 90 : undefined} />\n        </Button>\n    );\n}\n\nexport function DependencyErrorWarning({ name }: { name: string }) {\n    const [tooltip, tooltipRef] = useTooltip(\"A nested dependency has an error. Expand to see more.\");\n    return (\n        <span\n            ref={tooltipRef}\n            role=\"img\"\n            aria-label={`Error in dependencies of ${name}`}\n            className=\"inline-flex shrink-0 items-center text-sm text-danger\">\n            <FontAwesomeIcon icon={faCircleExclamation} />\n            {tooltip}\n        </span>\n    );\n}\n\nfunction versionLabel(version: DependencyVersionSpec | undefined): string {\n    if (version && \"branch\" in version) return version.branch;\n    if (version && \"version_tag\" in version) return version.version_tag;\n    if (version && \"dev\" in version && version.dev) return \"master\";\n    return \"Published\";\n}\n\nexport function DependencyChildren({\n    children,\n    dependencyCode,\n    dependencyGraph,\n    ancestors,\n    depth = 1,\n}: {\n    children: DependencyTreeEdge[];\n    dependencyCode: IDEDependencyCode;\n    dependencyGraph: DependencyGraph;\n    ancestors: string[];\n    depth?: number;\n}) {\n    return children.map((child) => (\n        <DependencyChild\n            key={child.dep_id}\n            dep={child}\n            dependencyCode={dependencyCode}\n            dependencyGraph={dependencyGraph}\n            ancestors={ancestors}\n            depth={depth}\n        />\n    ));\n}\n\nfunction DependencyChild({\n    dep,\n    dependencyCode,\n    dependencyGraph,\n    ancestors,\n    depth,\n}: {\n    dep: DependencyTreeEdge;\n    dependencyCode: IDEDependencyCode;\n    dependencyGraph: DependencyGraph;\n    ancestors: string[];\n    depth: number;\n}) {\n    const [expanded, setExpanded] = useState(false);\n    // Mount child rows on first expansion; keep them mounted when collapsed so\n    // closing can animate and nested rows keep their expansion state.\n    const [hasOpened, setHasOpened] = useState(false);\n    const childrenId = useId();\n    const code = dependencyCode[dep.app_id];\n    const children = dependencyGraph[dep.app_id];\n    const name = code?.name || dep.resolution_hints?.name || dep.app_id;\n    const repeated = ancestors.includes(dep.app_id);\n    // A version conflict can replace a dependency's loaded code with an error.\n    // We keep the children read before that conflict, stored per app rather than\n    // per version. A v2 row may therefore show children read from v1 if the\n    // conflict prevented us from loading v2.\n    const canExpand = !repeated && !!children?.length;\n    const hasChildErrors = canExpand && children!.some((child) =>\n        hasDependencyErrors(child.app_id, dependencyCode, dependencyGraph)\n    );\n\n    return (\n        <>\n            <div className=\"col-span-full grid min-w-0 grid-cols-1 items-center gap-3 border-b border-sectionborder bg-light-bg2/50 px-4 py-2 text-[1.4rem] leading-normal last:border-b-0 @min-[640px]/dependencies:grid-cols-subgrid dark:border-dark-sectionborder dark:bg-dark-bg3/50\">\n                <div className=\"relative flex min-w-0 items-center gap-2\" style={{ paddingLeft: `${depth * DEPENDENCY_INDENT_REM}rem` }}>\n                    <span\n                        aria-hidden=\"true\"\n                        className=\"pointer-events-none absolute top-1/2 z-10 hidden @min-[640px]/dependencies:block border-t border-light-bg5 dark:border-dark-bg7\"\n                        style={{ left: `${(depth - 1) * DEPENDENCY_INDENT_REM + 1}rem`, width: `${canExpand ? 1.2 : 3.3}rem` }}\n                    />\n                    <DependencyExpandButton\n                        name={name}\n                        expanded={expanded}\n                        canExpand={canExpand}\n                        controls={childrenId}\n                        onToggle={() => {\n                            setHasOpened(true);\n                            setExpanded((value) => !value);\n                        }}\n                    />\n                    <div className=\"min-w-0 [overflow-wrap:anywhere] select-text\">\n                        <div className=\"flex min-w-0 items-center gap-2\">\n                            <div title={name} className=\"min-w-0 truncate leading-normal\">\n                                {name}\n                            </div>\n                            {hasChildErrors && !expanded && (\n                                <DependencyErrorWarning name={name} />\n                            )}\n                        </div>\n                        {repeated && (\n                            <div className=\"text-sm leading-normal text-light-grey1 dark:text-dark-bg7\">Already shown above</div>\n                        )}\n                    </div>\n                </div>\n                <div className=\"min-w-0 [overflow-wrap:anywhere] select-text\">\n                    <span className=\"mb-2 block font-semibold @min-[640px]/dependencies:hidden\">Version</span>\n                    {versionLabel(dep.version)}\n                </div>\n                <div className=\"min-w-0 [overflow-wrap:anywhere] select-text\">\n                    <span className=\"mb-2 block font-semibold @min-[640px]/dependencies:hidden\">Package Name</span>\n                    <code className=\"bg-transparent! p-0! text-light-fg1! dark:text-dark-fg1!\">\n                        {code?.package_name || dep.resolution_hints?.package_name}\n                    </code>\n                </div>\n                <div />\n                {code?.error && (\n                    <div\n                        className=\"col-span-full flex min-w-0 items-start gap-2 rounded border-l-2 border-danger bg-danger/5 px-3 py-2 text-sm leading-normal [overflow-wrap:anywhere]\"\n                        style={{ marginLeft: `${depth * DEPENDENCY_INDENT_REM + 2.5}rem` }}>\n                        <FontAwesomeIcon icon={faCircleExclamation} className=\"mt-1 shrink-0 text-danger\" />\n                        <div>{code.error}</div>\n                    </div>\n                )}\n            </div>\n            {canExpand && (\n                <div\n                    id={childrenId}\n                    role=\"group\"\n                    aria-label={`Dependencies of ${name}`}\n                    aria-hidden={!expanded}\n                    inert={!expanded}\n                    className=\"relative col-span-full grid grid-cols-subgrid\">\n                    <span\n                        aria-hidden=\"true\"\n                        className=\"pointer-events-none absolute top-0 bottom-0 z-10 hidden @min-[640px]/dependencies:block border-l border-light-bg5 dark:border-dark-bg7\"\n                        style={{ left: `${depth * DEPENDENCY_INDENT_REM + 2}rem` }}\n                    />\n                    <Expander\n                        isOpen={expanded}\n                        className=\"col-span-full grid grid-cols-subgrid\"\n                        innerClassName=\"col-span-full grid grid-cols-subgrid\">\n                        {hasOpened && (\n                            <DependencyChildren\n                                children={children!}\n                                dependencyCode={dependencyCode}\n                                dependencyGraph={dependencyGraph}\n                                ancestors={[...ancestors, dep.app_id]}\n                                depth={depth + 1}\n                            />\n                        )}\n                    </Expander>\n                </div>\n            )}\n        </>\n    );\n}\n","import React from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { InputLabel } from \"@/components/reusable/Forms\";\nimport { useSaveIndicator } from \"@/components/reusable/SaveIndicator\";\nimport UpgradeBadge from \"@/components/reusable/UpgradeBadge\";\nimport { getAppRuntimeOptions, updateAppConfig } from \"@/controllers/app\";\nimport { modal } from \"@/controllers/modals\";\nimport type { AnvilDispatch } from \"@/types\";\nimport { useFeatureSupported } from \"@/util/features\";\nimport useEvent from \"@/util/useEventCallback\";\n\nconst PersistentServerSetting = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const runtimeOptions = useSelector(getAppRuntimeOptions);\n    const supported = useFeatureSupported(\"persistent-server\");\n    const [saveIndicator, setSaved] = useSaveIndicator();\n    const onChange = useEvent(async (event: React.ChangeEvent<HTMLInputElement>) => {\n        const checked = event.target.checked;\n        if (checked && !supported) {\n            await dispatch(modal(\"upgradePrompt\", { featureId: \"persistent-server\" }));\n            return;\n        }\n        setSaved(false);\n        await dispatch(updateAppConfig([\"runtime_options\", \"server_persist\"], checked));\n        setSaved(true);\n    });\n    return (\n        <div className=\"my-6 flex flex-wrap items-center justify-between gap-4\">\n            <InputLabel\n                subtitleClasses=\"font-normal!\"\n                title={\n                    <>\n                        Persistent Server <UpgradeBadge feature=\"persistent-server\" />\n                    </>\n                }\n                subtitle=\"When enabled, server modules stay loaded between calls.\"\n            />\n            <div className=\"flex shrink-0 items-center gap-2\">\n                {saveIndicator}\n                <label className=\"relative inline-flex cursor-pointer items-center\">\n                    <input\n                        type=\"checkbox\"\n                        role=\"switch\"\n                        aria-label=\"Persistent Server\"\n                        className=\"peer sr-only\"\n                        checked={!!runtimeOptions?.server_persist}\n                        onChange={onChange}\n                    />\n                    <span className=\"h-10 w-20 rounded-full border border-sectionborder bg-light-bg2 p-1 peer-checked:bg-primary peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-primary dark:border-dark-sectionborder dark:bg-dark-bg3 peer-checked:[&>span]:translate-x-10 peer-checked:[&>span]:bg-white\">\n                        <span className=\"block size-7 rounded-full bg-light-bg5 transition-transform dark:bg-dark-bg7\" />\n                    </span>\n                </label>\n            </div>\n        </div>\n    );\n};\n\nexport default PersistentServerSetting;\n","const normalisePackageName = (name: string) => name.toLowerCase().replace(/[-_.]+/g, \"-\");\n\nconst packageNameFromRequirement = (requirement: string): string | null => {\n    // Strip pip comments, but preserve URL fragments such as #egg=scipy.\n    requirement = requirement.replace(/(^|\\s+)#.*$/, \"\").trim();\n    const eggFragment = /[#&]egg=([A-Za-z0-9][A-Za-z0-9._-]*)/i.exec(requirement);\n    if (eggFragment) return normalisePackageName(eggFragment[1]);\n\n    const match = /^\\s*([A-Za-z0-9][A-Za-z0-9._-]*)(?:\\[[^\\]]+\\])?(?=\\s*(?:@|===|==|~=|!=|<=|>=|<|>|;|\\(|$))/.exec(\n        requirement\n    );\n    return match ? normalisePackageName(match[1]) : null;\n};\n\nexport const mergeMigrationRequirements = (requirements: string | undefined, migrationRequirements: string[]) => {\n    if (migrationRequirements.length === 0) {\n        return requirements ?? \"\";\n    }\n\n    const existing = requirements ?? \"\";\n    // Inspect logical lines without rewriting the user's original requirements.\n    const existingLines = existing.replace(/\\\\\\r?\\n/g, \"\").split(/\\r?\\n/);\n    const packageNames = new Set(\n        existingLines.map(packageNameFromRequirement).filter((name): name is string => !!name)\n    );\n    const directives = new Set(existingLines.map((line) => line.trim()).filter((line) => line.startsWith(\"-\")));\n    const missing = migrationRequirements.filter((requirement) => {\n        const packageName = packageNameFromRequirement(requirement);\n        if (packageName) {\n            if (packageNames.has(packageName)) return false;\n            packageNames.add(packageName);\n            return true;\n        }\n\n        const directive = requirement.trim();\n        if (directives.has(directive)) return false;\n        directives.add(directive);\n        return true;\n    });\n\n    if (missing.length === 0) return existing;\n    const newline = existing.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n    const separator = existing.length === 0 || existing.endsWith(\"\\n\") ? \"\" : newline;\n    return `${existing}${separator}${missing.join(newline)}`;\n};\n","import React, { useEffect, useRef, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faChevronRight } from \"@fortawesome/pro-regular-svg-icons/faChevronRight\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { Expander } from \"@/components/reusable/Expander\";\nimport { useSaveIndicator } from \"@/components/reusable/SaveIndicator\";\nimport { Heading } from \"@/components/reusable/Text\";\nimport { getAppId, getAppRuntimeOptions, promptIfRuntimeMissing, updateAppConfig } from \"@/controllers/app\";\nimport { reloadAppConfig } from \"@/controllers/app/autocompleter\";\nimport { confirmAndMigrateApp, hasLegacyEnvironments } from \"@/controllers/environments\";\nimport { getUser } from \"@/controllers/ide\";\nimport { confirm, modal } from \"@/controllers/modals\";\nimport { getCustomPackagesAvailable } from \"@/controllers/user\";\nimport { recordActivity } from \"@/controllers/util\";\nimport { useIsPySpace } from \"@/theme/styles\";\nimport type { AnvilDispatch, AppId, RuntimeOptions, RuntimeServerSpec } from \"@/types\";\nimport type { PythonEnvironment, ServerRuntime, User } from \"@/types/user\";\nimport { useFeatureSupported } from \"@/util/features\";\nimport { useStateWithReset } from \"@/util/hooks\";\nimport useEvent from \"@/util/useEventCallback\";\nimport PersistentServerSetting from \"./PersistentServerSetting\";\nimport InstallScriptsSettings from \"./python-environment/InstallScriptsSettings\";\nimport PythonEnvironmentSelector from \"./python-environment/PythonEnvironmentSelector\";\nimport { mergeMigrationRequirements } from \"./python-environment/migration\";\nimport OtherRuntimeSettings from \"./python-version/OtherRuntimeSettings\";\nimport PackageRequirementsEditor from \"./python-version/PackageRequirementsEditor\";\nimport RuntimeBuildStatus from \"./python-version/RuntimeBuildStatus\";\nimport useStyles from \"./styles\";\n\nconst packageCompatibilityWarning =\n    \"Your packages and install scripts will be kept. Check that they are compatible with the selected Python version.\";\n\ntype LoadedConfigProps = {\n    appId: AppId;\n    user: User;\n    runtimeOptions: RuntimeOptions;\n};\n\nconst PythonAndPackagesConfigLoaded = ({ appId, user, runtimeOptions }: LoadedConfigProps) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const customPackagesAvailable = useSelector(getCustomPackagesAvailable);\n    const hasLegacyAppEnvironments = useSelector(hasLegacyEnvironments);\n    const enableScripts = useFeatureSupported(\"downlink-scripts\");\n    const isPySpace = useIsPySpace();\n    const { classes } = useStyles();\n\n    const [clientVersion, setClientVersion] = useState<RuntimeOptions[\"client_version\"]>(runtimeOptions.client_version);\n    const [serverSpec, setServerSpec] = useStateWithReset<RuntimeServerSpec | null | undefined>(\n        runtimeOptions.server_spec\n    );\n    const [migrating, setMigrating] = useState(false);\n    const [selectionError, setSelectionError] = useState<string>();\n\n    const [clientSaveIndicator, setClientSaved] = useSaveIndicator();\n    const [serverSaveIndicator, setServerSaved] = useSaveIndicator();\n    const [requirementsSaveIndicator, setRequirementsSaved] = useSaveIndicator();\n\n    const updateClientVersion = useEvent(async (event: React.ChangeEvent<HTMLSelectElement>) => {\n        const value = event.target.value;\n        if (\n            value === \"2\" &&\n            clientVersion !== \"2\" &&\n            !(await dispatch(\n                confirm(\n                    \"Use Python 2 for client code?\",\n                    \"Python 2 is deprecated. Use Python 3 for new apps. Switching versions may require changes to your client code.\",\n                    \"Use Python 2\",\n                    \"Cancel\"\n                )\n            ))\n        )\n            return;\n        setClientVersion(value as RuntimeOptions[\"client_version\"]);\n        setClientSaved(false);\n        await dispatch(updateAppConfig([\"runtime_options\", \"client_version\"], value));\n        setClientSaved(true);\n    });\n\n    const onSavedCallbacks = useRef<Array<() => void>>([]);\n    const updateServerSpec = useEvent((update: Partial<RuntimeServerSpec>, onSaved: () => void) => {\n        setServerSpec((current) => ({ ...(current ?? {}), ...update }));\n        onSavedCallbacks.current = [...onSavedCallbacks.current, onSaved];\n    });\n\n    const updateRequirements = useEvent((requirements: string) => {\n        setRequirementsSaved(false);\n        updateServerSpec({ requirements }, () => setRequirementsSaved(true));\n    });\n\n    const updatePreInstallScript = useEvent((pre_install_script: string) => {\n        setRequirementsSaved(false);\n        updateServerSpec({ pre_install_script }, () => setRequirementsSaved(true));\n    });\n\n    const updatePostInstallScript = useEvent((post_install_script: string) => {\n        setRequirementsSaved(false);\n        updateServerSpec({ post_install_script }, () => setRequirementsSaved(true));\n    });\n\n    const serverSpecTimeout = useRef<number | undefined>(undefined);\n    const serverSpecInitialised = useRef(false);\n    useEffect(() => {\n        if (serverSpecTimeout.current) clearTimeout(serverSpecTimeout.current);\n        if (!serverSpecInitialised.current) {\n            serverSpecInitialised.current = true;\n            return;\n        }\n        if (serverSpec === runtimeOptions.server_spec) {\n            return;\n        }\n        serverSpecTimeout.current = setTimeout(async () => {\n            const callbacks = onSavedCallbacks.current;\n            onSavedCallbacks.current = [];\n            await dispatch(updateAppConfig([\"runtime_options\", \"server_spec\"], serverSpec));\n            for (const callback of callbacks) callback();\n        }, 500);\n    }, [dispatch, runtimeOptions.server_spec, serverSpec]);\n\n    const catalog = user.python_environment_catalog ?? [];\n    const environment = catalog.find((candidate) => candidate.base === serverSpec?.base);\n    const sourceImage = catalog.find(\n        (candidate) => candidate.base === (serverSpec?.base ?? runtimeOptions.server_spec_disabled?.base)\n    );\n    const editable = isPySpace || !!serverSpec?.base;\n    const managedRuntimes = user.server_runtimes.filter(\n        (runtime) => (runtime.available || runtime.id === \"python3-full\") && !runtime.id.endsWith(\"-sandbox\")\n    );\n    const usingManagedRuntime = !serverSpec?.base;\n    // App storage represents an inactive server_spec as {}, not necessarily null.\n    const previousImageSpec = serverSpec?.base ? serverSpec : runtimeOptions.server_spec_disabled;\n    const hasCustomPackagesOrScripts = [\n        previousImageSpec?.requirements,\n        previousImageSpec?.pre_install_script,\n        previousImageSpec?.post_install_script,\n    ].some((value) => value?.trim());\n    const switchManagedRuntime = useEvent(async (runtime: ServerRuntime) => {\n        setSelectionError(undefined);\n        setMigrating(true);\n        try {\n            // Full Python uses its own installed packages, not this image's requirements or scripts.\n            // Warn when leaving saved customisations, a known bundle, or an unknown bundle.\n            // migration_requirements: [] means no bundle; missing metadata does not mean empty.\n            if (\n                !usingManagedRuntime &&\n                (hasCustomPackagesOrScripts ||\n                    sourceImage?.migration_requirements?.length ||\n                    sourceImage?.migration_requirements === undefined) &&\n                !(await dispatch(\n                    confirm(\n                        `Switch to ${runtime.name}?`,\n                        \"Your image requirements and install scripts will be saved for when you switch back, but will not be used by this runtime. Its installed packages may be different. Check that your app works after switching.\",\n                        \"Switch Python version\",\n                        \"Cancel\"\n                    )\n                ))\n            )\n                return;\n            if (!(await dispatch(promptIfRuntimeMissing(runtime.id)))) return;\n            clearTimeout(serverSpecTimeout.current);\n            const callbacks = onSavedCallbacks.current;\n            onSavedCallbacks.current = [];\n            setServerSaved(false);\n            await dispatch(\n                updateAppConfig([\"runtime_options\"], {\n                    ...runtimeOptions,\n                    server_version: runtime.id,\n                    server_spec: null,\n                    server_spec_disabled: previousImageSpec,\n                })\n            );\n            await dispatch(reloadAppConfig());\n            for (const callback of callbacks) callback();\n            setServerSaved(true);\n        } catch (error) {\n            setSelectionError((error as { message?: string })?.message ?? \"Could not change the Python runtime.\");\n        } finally {\n            setMigrating(false);\n        }\n    });\n\n    const saveEnvironment = useEvent(async (nextSpec: RuntimeServerSpec) => {\n        clearTimeout(serverSpecTimeout.current);\n        const callbacks = onSavedCallbacks.current;\n        onSavedCallbacks.current = [];\n        setServerSaved(false);\n        await dispatch(updateAppConfig([\"runtime_options\", \"server_spec\"], nextSpec));\n        await dispatch(reloadAppConfig());\n        for (const callback of callbacks) callback();\n        setServerSaved(true);\n    });\n\n    const selectEnvironment = useEvent(async (target: PythonEnvironment) => {\n        setSelectionError(undefined);\n        const applyChange = async () => {\n            setMigrating(true);\n            try {\n                const previousSpec = previousImageSpec ?? {};\n                const bundledRequirements = sourceImage?.migration_requirements ?? [];\n                const unknownBundle = !!previousSpec.base && sourceImage?.migration_requirements === undefined;\n                const title = target.title;\n                const warning = bundledRequirements.length\n                    ? `The ${sourceImage!.title} image includes bundled packages. These will become explicit requirements and may install newer versions. Your explicit version pins and install scripts will be preserved. Check that your app works with the new Python version.`\n                    : unknownBundle\n                      ? \"The packages bundled in your current image are unknown and cannot be copied automatically. Your saved requirements and install scripts will be kept. Add any other packages your app needs after switching.\"\n                      : usingManagedRuntime\n                        ? \"Packages installed in your managed runtime are not copied into this image. Your saved image requirements and install scripts will be preserved. Add any other packages your app needs after switching.\"\n                        : packageCompatibilityWarning;\n\n                if (\n                    (bundledRequirements.length > 0 || unknownBundle || hasCustomPackagesOrScripts) &&\n                    !(await dispatch(confirm(`Switch to ${title}?`, warning, \"Switch Python version\", \"Cancel\")))\n                )\n                    return;\n                if (hasLegacyAppEnvironments && !(await dispatch(confirmAndMigrateApp()))) return;\n\n                const nextSpec = { ...previousSpec, base: target.base };\n                if (bundledRequirements.length) {\n                    nextSpec.requirements = mergeMigrationRequirements(previousSpec.requirements, bundledRequirements);\n                }\n                await saveEnvironment(nextSpec);\n                if (bundledRequirements.length || usingManagedRuntime) {\n                    dispatch(\n                        recordActivity(\"migratePythonEnvironment\", {\n                            oldRuntime: runtimeOptions.server_version ?? null,\n                            oldBase: previousSpec.base ?? null,\n                            targetPythonVersion: target.python_version,\n                        })\n                    );\n                }\n            } catch (error) {\n                setSelectionError(\n                    (error as { message?: string })?.message ??\n                        \"Could not change the Python environment. Please try again.\"\n                );\n            } finally {\n                setMigrating(false);\n            }\n        };\n        if (customPackagesAvailable) await applyChange();\n        else await dispatch(modal(\"upgradePrompt\", { featureId: \"custom-packages\", onStartTrial: applyChange }));\n    });\n\n    const advancedOptionsInDefaultState =\n        clientVersion == \"3\" && !serverSpec?.pre_install_script && !serverSpec?.post_install_script;\n    const [showAdvanced, setShowAdvanced] = useState(!advancedOptionsInDefaultState);\n\n    const currentEnvironment = serverSpec?.base\n        ? serverSpec.base\n        : (user.server_runtimes.find((runtime) => runtime.id === runtimeOptions.server_version)?.name ??\n          runtimeOptions.server_version ??\n          \"Python\");\n\n    return (\n        <div\n            className={\n                isPySpace\n                    ? `${classes.settingsRoot} @container/dependencies`\n                    : \"@container/dependencies min-h-full  text-light-fg1 dark:bg-dark-bg1 dark:text-dark-fg1\"\n            }>\n            <div\n                className={\n                    isPySpace ? classes.appSettings : \"w-full max-w-[76rem] px-6 py-6 @min-[640px]/dependencies:px-16\"\n                }>\n                {!isPySpace && <Heading level={1}>Python Dependencies</Heading>}\n                {!isPySpace && (\n                    <PythonEnvironmentSelector\n                        current={environment}\n                        currentLabel={currentEnvironment}\n                        currentRuntime={usingManagedRuntime ? runtimeOptions.server_version : undefined}\n                        currentRuntimeDeprecated={\n                            usingManagedRuntime &&\n                            user.server_runtimes.find((runtime) => runtime.id === runtimeOptions.server_version)\n                                ?.deprecated\n                        }\n                        changing={migrating}\n                        environments={catalog.filter((image) => image.available)}\n                        runtimes={managedRuntimes}\n                        saveIndicator={serverSaveIndicator}\n                        onChange={(selected) => void selectEnvironment(selected)}\n                        onRuntimeChange={(selected) => void switchManagedRuntime(selected)}\n                        selectClassName={\"[&>div]:border!\"}\n                    />\n                )}\n                {selectionError && (\n                    <div role=\"alert\" className=\"my-3 text-red-700 dark:text-red-300\">\n                        {selectionError}\n                    </div>\n                )}\n                <PackageRequirementsEditor\n                    enabled={editable && user.ideConfig.customPackageInstallation}\n                    isPySpace={isPySpace}\n                    serverSpec={serverSpec}\n                    saveIndicator={requirementsSaveIndicator}\n                    onRequirementsChange={updateRequirements}\n                />\n                {serverSpec && !usingManagedRuntime && !migrating && (\n                    <RuntimeBuildStatus appId={appId} runtimeSpec={serverSpec} />\n                )}\n                {!isPySpace && (\n                    <>\n                        <button\n                            type=\"button\"\n                            className=\"my-6 flex items-center gap-4 border-0 bg-transparent p-0 text-[1.4rem] text-light-grey1 dark:text-dark-bg7\"\n                            aria-expanded={showAdvanced}\n                            onClick={() => setShowAdvanced((shown) => !shown)}>\n                            Advanced settings...\n                            <FontAwesomeIcon icon={faChevronRight} rotation={showAdvanced ? 90 : undefined} />\n                        </button>\n                        <div inert={!showAdvanced}>\n                            <Expander isOpen={showAdvanced}>\n                                {!usingManagedRuntime &&\n                                    serverSpec &&\n                                    (enableScripts ||\n                                        serverSpec.pre_install_script ||\n                                        serverSpec.post_install_script) && (\n                                        <InstallScriptsSettings\n                                            serverSpec={serverSpec}\n                                            readOnly={!enableScripts}\n                                            saveIndicator={requirementsSaveIndicator}\n                                            onPostInstallScriptChange={updatePostInstallScript}\n                                            onPreInstallScriptChange={updatePreInstallScript}\n                                        />\n                                    )}\n                                <OtherRuntimeSettings\n                                    clientVersion={clientVersion}\n                                    clientSaveIndicator={clientSaveIndicator}\n                                    runtimeVersion={runtimeOptions.version ?? 0}\n                                    onClientVersionChange={updateClientVersion}\n                                />\n                            </Expander>\n                        </div>\n                    </>\n                )}\n            </div>\n        </div>\n    );\n};\n\nconst PythonAndPackagesConfig = () => {\n    const appId = useSelector(getAppId);\n    const user = useSelector(getUser);\n    const runtimeOptions = useSelector(getAppRuntimeOptions) as RuntimeOptions | undefined;\n\n    if (!appId || !user || !runtimeOptions) {\n        throw new Error(\"PythonAndPackagesConfig missing required app/user/runtime state\");\n    }\n\n    return <PythonAndPackagesConfigLoaded key={appId} appId={appId} user={user} runtimeOptions={runtimeOptions} />;\n};\n\nexport default PythonAndPackagesConfig;\n","import type { DepConfigSchema } from \"@runtime/runner/data\";\nimport type { DependencyConfig } from \"@/types\";\n\nexport function hasDependencyConfiguration(schema: DepConfigSchema | undefined, config: DependencyConfig[\"config\"]) {\n    if (\n        [schema?.client, schema?.server].some((properties) =>\n            Object.values(properties ?? {}).some((property) => !property.hidden)\n        )\n    ) {\n        return true;\n    }\n    // Saved properties absent from the schema still need a way to be inspected and removed.\n    return Object.entries(config ?? {}).some(([type, properties]) =>\n        Object.keys(properties ?? {}).some((name) => !schema?.[type as keyof DepConfigSchema]?.[name])\n    );\n}\n","import type { DependencyGraph, IDEDependencyContent } from \"@/types\";\n\ntype DependencyCode = Record<string, Pick<IDEDependencyContent, \"error\">>;\n\n/** Check this app and its nested dependencies for errors, stopping if a dependency repeats. */\nexport function hasDependencyErrors(\n    appId: string,\n    dependencyCode: DependencyCode,\n    dependencyGraph: DependencyGraph\n): boolean {\n    const visited = new Set<string>();\n    function visit(id: string): boolean {\n        if (visited.has(id)) return false;\n        visited.add(id);\n        const dependency = dependencyCode[id];\n        return !!dependency?.error || !!dependencyGraph[id]?.some((child) => visit(child.app_id));\n    }\n    return visit(appId);\n}\n","import type { PythonImageLifecycle } from \"@/types/user\";\n\nexport const isPythonImageEndOfLife = (image: PythonImageLifecycle, now = new Date()) =>\n    !!image.end_of_life && now.getTime() >= Date.parse(`${image.end_of_life}T00:00:00Z`);\n","import { useQuery } from \"@tanstack/react-query\";\nimport * as api from \"@/api\";\nimport type { PyPiPackageVersion } from \"@/types\";\n\nconst asPackageCompletions = (value: unknown[]): string[] =>\n    value.filter((item): item is string => typeof item === \"string\");\n\nconst asPackageVersions = (value: unknown[]): PyPiPackageVersion[] =>\n    value.flatMap((item) =>\n        typeof item === \"object\" && item !== null && typeof (item as { version?: unknown }).version === \"string\"\n            ? [{ version: (item as { version: string }).version, date: (item as { date?: string }).date }]\n            : []\n    );\n\nexport const usePackageVersions = (packageName: string, { enabled }: { enabled: boolean }) =>\n    useQuery({\n        queryKey: [\"pypi-package-versions\", packageName],\n        queryFn: async () => asPackageVersions(await api.getPyPiPackageVersions(packageName)),\n        enabled: enabled && !!packageName,\n        retry: false,\n    });\n\nexport const usePackageCompletions = (prefix: string, { enabled }: { enabled: boolean }) =>\n    useQuery({\n        queryKey: [\"pypi-package-completions\", prefix],\n        queryFn: async () => asPackageCompletions(await api.autocompletePyPiPackage(prefix)),\n        enabled,\n        retry: false,\n    });\n","import type { PipPackageRequirement } from \"@/types\";\n\n// Requirements with markers, ranges, URLs, comments or pip options must stay in the raw editor.\nexport function parseSimpleRequirements(requirements: string): PipPackageRequirement[] | null {\n    if (!requirements.trim()) return [];\n    const packages: PipPackageRequirement[] = [];\n    for (const line of requirements.trim().split(\"\\n\")) {\n        const match = /^([A-Za-z0-9][A-Za-z0-9._-]*(?:\\[[A-Za-z0-9._,-]+\\])?)(?:==([^\\s;=]+))?$/.exec(line.trim());\n        if (!match) return null;\n        packages.push({ package: match[1], version: match[2] });\n    }\n    return packages;\n}\n\nexport function formatSimpleRequirements(packages: PipPackageRequirement[]): string {\n    return packages.map((p) => p.package + (p.version ? `==${p.version}` : \"\")).join(\"\\n\");\n}\n","import { makeStyles } from \"@/theme/styles\";\n\nexport default makeStyles()((theme) => ({\n    root: {\n        color: theme.text.p1.color.toString(),\n    },\n    config: {\n        padding: \"0.5rem 2rem\",\n        textAlign: \"center\",\n        color: theme.palette.fg1.hex(),\n    },\n    select: {\n        height: \"2.8rem\",\n        padding: \"0.3rem 1.2rem\",\n        fontSize: \"1.4rem\",\n        backgroundColor: theme.isDark ? theme.palette.bg3.hex() : theme.palette.bg2.hex(),\n        color: theme.palette.fg1.hex(),\n        border: \"1px solid \" + theme.palette.bg2.hex(),\n        borderRadius: 2,\n        marginBottom: \"1rem\",\n        \"& option\": {\n            height: \"3.4rem\",\n            padding: \"0.6rem 1.2rem\",\n            fontSize: \"1.4rem\",\n        },\n    },\n    danger: {\n        backgroundColor: theme.danger.hex(),\n        color: theme.hl4.hex(),\n    },\n    alignLeft: {\n        textAlign: \"left\",\n    },\n    warning: {\n        color: theme.hl4.hex(),\n        '& div[role=\"button\"]': {\n            color: theme.hl4.hex(),\n            textDecoration: \"underline\",\n        },\n    },\n    settingsRoot: {\n        display: \"flex\",\n        color: theme.palette.fg1.hex(),\n        background: theme.settings.rightBarBackground.toString(),\n        alignItems: \"stretch\",\n        height: \"100%\",\n    },\n    appSettings: {\n        padding: \"1rem 4rem\",\n        width: theme.isPySpace ? \"100%\" : \"60rem\",\n        borderRight: \"1px solid \" + theme.settings.separator.toString(),\n        background: theme.settings.background.toString(),\n    },\n    table: {\n        width: \"100%\",\n        fontSize: theme.table.fontSize,\n        fontWeight: theme.table.fontWeight,\n        borderTop: theme.table.thickBorder + \" solid \" + theme.table.borderColor.toString(),\n        borderBottom: theme.table.thickBorder + \" solid \" + theme.table.borderColor.toString(),\n        \"&>thead\": {\n            borderBottom: theme.table.thinBorder + \" solid \" + theme.table.borderColor.toString(),\n            \"&>tr>th\": {\n                fontWeight: theme.table.header.fontWeight,\n                border: \"none\",\n                padding: theme.table.verticalPadding + \" 0\",\n            },\n        },\n        \"&>tbody\": {\n            [`&>tr:first-of-type>td`]: {\n                paddingTop: theme.table.verticalPadding,\n            },\n            \"&>tr:last-child>td\": {\n                paddingBottom: theme.table.verticalPadding,\n            },\n            \"&>tr>td\": {\n                padding: \"0.5rem 0\",\n                border: \"none\",\n            },\n        },\n    },\n    pt10: {\n        paddingTop: \"1rem\",\n    },\n    btnGroupLeft: {\n        \"& [role=button]\": {\n            borderTopRightRadius: 0,\n            borderBottomRightRadius: 0,\n        },\n    },\n    btnGroupRight: {\n        \"& [role=button]\": {\n            borderBottomLeftRadius: 0,\n            borderTopLeftRadius: 0,\n        },\n    },\n    addPackageButton: {\n        height: \"2.2rem !important\",\n    },\n    removePackageButton: {\n        padding: \"0 0.5rem\",\n        opacity: 0.5,\n        \"&:hover\": {\n            opacity: 1,\n        },\n    },\n    helpLink: {\n        color: theme.palette.primary.toString() + \" !important\",\n        textDecoration: \"none !important\",\n        \"&:hover\": {\n            textDecoration: \"underline !important\",\n        },\n        marginLeft: \"2rem\",\n    },\n    focusedItem: {\n        background: theme.dropDownMenu.hoverBg.toString(),\n    },\n    notification: {\n        padding: \"1rem\",\n        borderRadius: \"4px\",\n        border: \"4px solid \" + theme.modal.notification.borderColor.toString(),\n        backgroundColor: theme.modal.notification.backgroundColor.toString(),\n        \"& h2\": {\n            color: theme.modal.notification.headingColor.toString(),\n        },\n    },\n}));\n","import React, { useRef } from \"react\";\nimport { useState } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faPencilAlt } from \"@fortawesome/free-solid-svg-icons/faPencilAlt\";\nimport { faTimes } from \"@fortawesome/free-solid-svg-icons/faTimes\";\nimport { faTrash } from \"@fortawesome/free-solid-svg-icons/faTrash\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { NavNodeRenamer } from \"@/components/reusable/NavNodeRenamer\";\nimport { useSaveIndicator } from \"@/components/reusable/SaveIndicator\";\nimport { CheckBox, ContentButton, ContentTextInput } from \"@/components/reusable/SharedComponents\";\nimport { markUnsaved } from \"@/controllers/app\";\nimport { addRoleComponent, deleteRole, deleteRoleComponent, updateRole } from \"@/controllers/app/theme\";\nimport { makeStyles } from \"@/theme/styles\";\nimport { cx } from \"@/theme/styles\";\nimport type { AnvilConnectedProps } from \"@/types\";\nimport type { ThemeRole } from \"@/types/app-theme-config\";\nimport useEvent from \"@/util/useEventCallback\";\n\nconst useStyles = makeStyles()((theme) => ({\n    root: {\n        margin: \"1rem 0\",\n        color: theme.roles.editRole.color.toString(),\n        backgroundColor: theme.roles.editRole.background.toString(),\n        border: \"1px solid \" + theme.roles.editRole.border.toString(),\n        borderRadius: 2,\n        \"& code\": {\n            color: theme.roles.editRole.codeColor.toString(),\n            background: \"none\",\n        },\n    },\n    title: {\n        backgroundColor: theme.roles.editRole.titleBackground.toString(),\n        padding: \"0 0.8rem\",\n    },\n    body: {\n        padding: \"1rem\",\n    },\n    component: {\n        backgroundColor: theme.roles.editRole.component.background.toString(),\n        border: \"1px solid \" + theme.roles.editRole.component.border.toString(),\n        padding: \"0.4rem 0.8rem\",\n        borderRadius: 2,\n        marginRight: \"1rem\",\n    },\n    marginTop: {\n        marginTop: \"1rem\",\n    },\n    width40: {\n        width: \"40%\",\n    },\n    checkbox: {\n        marginLeft: \"1rem\",\n    },\n}));\n\nconst connector = connect();\n\ntype EditRoleProps = AnvilConnectedProps<typeof connector> & {\n    role: ThemeRole;\n};\n\nconst EditRole = ({ role, dispatch }: EditRoleProps) => {\n    const { classes } = useStyles();\n\n    const [renamingRole, setRenamingRole] = useState(false);\n    const [roleName, setRoleName] = useState(role.name || \"\");\n    const [newComponentName, setNewComponentName] = useState(\"\");\n    const [displayInToolbox, setDisplayInToolbox] = useState(role.display_in_toolbox || false);\n    const [roleTitle, setRoleTitle] = useState(role.title || \"\");\n    const [saveTitleIndicator, setTitleSaved] = useSaveIndicator();\n    const [saveNameIndicator, setNameSaver] = useSaveIndicator();\n\n    const saveTimeoutRef = useRef<number | undefined>(undefined);\n\n    const onSaveDisplayTitle = useEvent(async (e: React.ChangeEvent<HTMLInputElement>) => {\n        const title = e.target.value;\n        setRoleTitle(title);\n        const saved = dispatch(markUnsaved(\"role-title\"));\n        setTitleSaved(false);\n        clearTimeout(saveTimeoutRef.current);\n        saveTimeoutRef.current = setTimeout(async () => {\n            await dispatch(updateRole(role, \"title\", title));\n            saved();\n            setTitleSaved(true);\n        }, 500);\n    });\n\n    const onRenaming = useEvent(async (name: string) => {\n        setRenamingRole(false);\n        if (name) {\n            setNameSaver(false);\n            await dispatch(updateRole(role, \"name\", name));\n            setNameSaver(true);\n            setRoleName(name);\n        }\n    });\n\n    const onDelete = useEvent(() => {\n        dispatch(deleteRole(role));\n    });\n\n    const onNewComponentNameChange = useEvent((e: React.ChangeEvent<HTMLInputElement>) =>\n        setNewComponentName(e.target.value)\n    );\n\n    const onAddNewComponent = useEvent(() => {\n        if (newComponentName) {\n            setNewComponentName(\"\");\n            dispatch(addRoleComponent(role, newComponentName));\n        }\n    });\n\n    const onDeleteComponent = useEvent((component: string) => {\n        dispatch(deleteRoleComponent(role, component));\n    });\n\n    const onRemoveAllComponents = useEvent(() => {\n        dispatch(updateRole(role, \"components\", null));\n    });\n\n    const onRestrictComponents = useEvent(() => {\n        dispatch(updateRole(role, \"components\", []));\n    });\n\n    const onDisplayInToolboxChange = useEvent((e: React.ChangeEvent<HTMLInputElement>) => {\n        const display = e.target.checked;\n        setDisplayInToolbox(display);\n        dispatch(updateRole(role, \"display_in_toolbox\", display));\n    });\n\n    return (\n        <div className={classes.root}>\n            <div className={cx(classes.title, \"flex items-center justify-between\")}>\n                {renamingRole ? (\n                    <NavNodeRenamer\n                        className={cx(classes.width40, \"text-xl!\")}\n                        name={roleName}\n                        onRename={onRenaming}\n                        onCancel={() => setRenamingRole(false)}></NavNodeRenamer>\n                ) : (\n                    <div>\n                        <LinkInternal icon={faPencilAlt} onClick={() => setRenamingRole(true)}>\n                            <code>\n                                <strong>{roleName}</strong>\n                            </code>\n                        </LinkInternal>\n                        {saveNameIndicator}\n                    </div>\n                )}\n                <LinkInternal onClick={onDelete} icon={faTrash} />\n            </div>\n            <div className={classes.body}>\n                {role.components && (\n                    <div>\n                        <p>This role can only be used with the following component types:</p>\n                        {role.components.map((component) => (\n                            <span key={JSON.stringify(component)} className={classes.component}>\n                                {component}&nbsp;\n                                <LinkInternal icon={faTimes} onClick={() => onDeleteComponent(component)} />\n                            </span>\n                        ))}\n                        <ContentTextInput\n                            className={classes.width40}\n                            placeholder={\"+ New component name\"}\n                            value={newComponentName || \"\"}\n                            onChange={onNewComponentNameChange}\n                            onBlur={onAddNewComponent}\n                            onEnter={onAddNewComponent}\n                        />\n                        <CheckBox\n                            className={classes.checkbox}\n                            text={\"Show in Toolbox\"}\n                            checked={displayInToolbox}\n                            onChange={onDisplayInToolboxChange}\n                        />\n                        <br />\n                        {displayInToolbox && (\n                            <div>\n                                Display Title:{\" \"}\n                                <ContentTextInput\n                                    className={classes.width40}\n                                    value={roleTitle}\n                                    onChange={onSaveDisplayTitle}\n                                />\n                                {saveTitleIndicator}\n                            </div>\n                        )}\n                        <ContentButton\n                            className={classes.marginTop}\n                            variant={\"primary\"}\n                            onClick={onRemoveAllComponents}>\n                            Allow for all components\n                        </ContentButton>\n                    </div>\n                )}\n                {!role.components && (\n                    <div>\n                        <p>This role can be used with any type of component.</p>\n                        <ContentButton variant={\"primary\"} onClick={onRestrictComponents}>\n                            Restrict\n                        </ContentButton>\n                    </div>\n                )}\n            </div>\n        </div>\n    );\n};\n\nexport default connector(EditRole);\n","import { AppItem } from \"@/types\";\nimport { queryClient } from \"@/util/queryClient\";\n\nexport const IDE_APP_LIST_QUERY_KEY = [\"ide-app-list\"] as const;\n\nexport const invalidateIdeAppListQueries = () => queryClient.invalidateQueries({ queryKey: IDE_APP_LIST_QUERY_KEY });\n\ntype AppListPage = {\n    apps?: AppItem[];\n    next_cursor?: string;\n};\n\ntype AppListQueryData = {\n    pages?: AppListPage[];\n    pageParams?: unknown[];\n};\n\nexport type IdeAppListSnapshot = ReturnType<typeof snapshotIdeAppListQueries>;\n\nexport const snapshotIdeAppListQueries = () => queryClient.getQueriesData({ queryKey: IDE_APP_LIST_QUERY_KEY });\n\nexport const restoreIdeAppListQueries = (snapshot: IdeAppListSnapshot) => {\n    snapshot.forEach(([queryKey, data]) => {\n        queryClient.setQueryData(queryKey, data);\n    });\n};\n\nexport const updateIdeAppListQueries = (transform: (app: AppItem) => AppItem | null) => {\n    queryClient.setQueriesData({ queryKey: IDE_APP_LIST_QUERY_KEY }, (previous) => {\n        const oldData = previous as AppListQueryData | undefined;\n        if (!oldData?.pages) return previous;\n\n        let changed = false;\n        const pages = oldData.pages.map((page) => {\n            const oldApps = page?.apps;\n            if (!oldApps) return page;\n            const nextApps = oldApps.map(transform).filter((app): app is AppItem => app !== null);\n            if (nextApps.length !== oldApps.length || nextApps.some((app, i) => app !== oldApps[i])) {\n                changed = true;\n                return { ...page, apps: nextApps };\n            }\n            return page;\n        });\n\n        return changed ? { ...oldData, pages } : previous;\n    });\n};\n\ntype OptimisticAppInput = Pick<AppItem, \"id\" | \"name\"> & Partial<AppItem>;\n\nconst matchesSearch = (query: string | undefined, name: string) => {\n    if (!query) return true;\n    return name.toLowerCase().includes(query);\n};\n\nconst shouldOptimisticallyInsert = (queryKey: unknown[], app: AppItem) => {\n    const options =\n        (queryKey?.[1] as\n            | {\n                  debouncedQuery?: string;\n                  owner?: \"All\" | \"Shared\" | \"Mine\";\n                  includePySpace?: boolean;\n                  sort?: \"name\" | \"date\";\n                  order?: \"asc\" | \"desc\";\n                  pageSize?: number;\n              }\n            | undefined) ?? {};\n\n    if (options.owner === \"Shared\" && app.owner) return false;\n    if (options.includePySpace === false && app.is_pyspace) return false;\n    if (!matchesSearch(options.debouncedQuery, app.name.toLowerCase())) return false;\n\n    // Only insert for date-desc views; other sort orders may place the app elsewhere.\n    const sort = options.sort ?? \"date\";\n    const order = options.order ?? \"desc\";\n    return sort === \"date\" && order === \"desc\";\n};\n\nconst APP_ITEM_DEFAULTS: Omit<AppItem, \"id\" | \"name\" | \"created\" | \"last_updated\"> = {\n    access_key: null,\n    alias: null,\n    clone_key: null,\n    dep_ids: null,\n    domain: null,\n    favourite: false,\n    git_path: null,\n    git_remotes: null,\n    organisation: null,\n    origin: null,\n    owner: true,\n    team_id: null,\n    uplink_secret: null,\n    user_id: null,\n    icon: null,\n    is_pyspace: false,\n};\n\nexport const insertIdeAppIntoListQueriesOptimistically = (input: OptimisticAppInput) => {\n    const now = new Date().toISOString();\n\n    const app: AppItem = {\n        ...APP_ITEM_DEFAULTS,\n        ...input,\n        created: now,\n        last_updated: now,\n        id: input.id,\n        name: input.name,\n    };\n\n    const snapshots = queryClient.getQueriesData({ queryKey: IDE_APP_LIST_QUERY_KEY });\n    snapshots.forEach(([queryKey, data]) => {\n        const oldData = data as AppListQueryData | undefined;\n        if (!oldData?.pages?.length) return;\n        if (!shouldOptimisticallyInsert(queryKey as unknown[], app)) return;\n\n        const firstPage = oldData.pages[0];\n        const oldApps = firstPage?.apps ?? [];\n        if (oldApps.some((listedApp) => listedApp.id === app.id)) return;\n\n        const options = ((queryKey as unknown[])?.[1] as { pageSize?: number } | undefined) ?? {};\n        const cappedApps = [app, ...oldApps];\n        const nextApps = typeof options.pageSize === \"number\" ? cappedApps.slice(0, options.pageSize) : cappedApps;\n\n        queryClient.setQueryData(queryKey, {\n            ...oldData,\n            pages: [{ ...firstPage, apps: nextApps }, ...oldData.pages.slice(1)],\n        });\n    });\n};\n","import type { DomNodeRef } from \"@anvil-works/form-template-parser\";\nimport { CustomComponentSpec } from \"@designer/shared-types\";\nimport {\n    getAnalysisEditors,\n    getAnalysisItems,\n    getPythonBackgroundTasks,\n    getTyAnalysisEnabled,\n    refreshPythonAppMetadata,\n} from \"@/analysis/ide-analysis\";\nimport type { PythonItemMetadata } from \"@/analysis/metadata\";\nimport type { AnalysisItem } from \"@/analysis/project\";\nimport type { Analysis, EventHandler, HttpEndpoint, Route } from \"@/code_mirror/autocompletions/types\";\nimport { getJsCustomComponents } from \"@/controllers/designer\";\nimport {\n    AnvilAsyncAction,\n    AppConfig,\n    AppId,\n    CodeItemType,\n    CodeItemYaml,\n    FormItemYaml,\n    IDEAppContentWithDeps,\n    IDEDependencyCode,\n} from \"@/types\";\nimport { TableMappingId } from \"@/types/database\";\nimport { User } from \"@/types/user\";\nimport { ExternalStore } from \"@/util/external-store\";\nimport { BackgroundWorker } from \"@/workers/rpc\";\nimport { HIDDEN_FORM } from \"./code\";\nimport { extractDomNodeRefs } from \"./html-form-parser\";\nimport { getAppConfig } from \"./index\";\n\nconst ac = new BackgroundWorker(() => {\n    return new Worker(new URL(\"@/workers/autocompleter/index.ts\", import.meta.url));\n});\n\nexport interface AutocompleteAnnotatedFormItemYaml extends FormItemYaml {\n    autocomplete_dom_node_refs?: DomNodeRef[];\n}\n\nlet currentAppId: AppId | undefined;\n\ntype DomNodeRefCacheEntry = {\n    fingerprint: string;\n    refs: DomNodeRef[];\n};\n\nconst domNodeRefCache = new Map<string, DomNodeRefCacheEntry>();\nconst DOM_NODE_AUTOCOMPLETE_LOG_STYLE = \"color: #0ea5e9; font-weight: 600\";\nconst DOM_NODE_TAG_ATTR_RE = /<([A-Za-z][^\\s/>]*)\\b[^>]*\\banvil:dom-node\\s*=\\s*([\"'])(.*?)\\2[^>]*>/g;\n\nconst domNodeRefCacheKey = (form: FormItemYaml): string =>\n    `${currentAppId ?? \"unknown-app\"}:${form.id ?? form.class_name}`;\n\nconst fingerprintDomNodeAttrs = (html: string): string => {\n    if (!html.includes(\"anvil:dom-node\")) {\n        return \"\";\n    }\n\n    const parts = [...html.matchAll(DOM_NODE_TAG_ATTR_RE)].map((match) => `${match[1].toLowerCase()}:${match[3]}`);\n\n    // If the cheap tag+attribute scan cannot summarize a string containing the\n    // attribute, fall back to the full HTML so we invalidate conservatively.\n    return parts.length ? parts.join(\"\\u0000\") : `${html.length}:${html}`;\n};\n\nconst collectDomNodeRefs = (html: string): DomNodeRef[] => {\n    const refs = new Map<string, DomNodeRef>();\n    for (const ref of extractDomNodeRefs(html)) {\n        if (!refs.has(ref.name)) {\n            refs.set(ref.name, ref);\n        }\n    }\n    return [...refs.values()];\n};\n\n/**\n * Adds autocomplete-only DOM node refs for main-app form analysis.\n *\n * We compute these refs lazily from the form's serialized HTML and cache them by\n * form identity plus HTML fingerprint, so repeated autocomplete requests don't\n * reparse the same template. Dependency forms intentionally do not go through\n * this path: dependency `self.dom_nodes[...]` completions are rarely useful, and\n * parsing every dependency form's HTML adds avoidable autocomplete startup work.\n */\nconst annotateFormForAutocomplete = async (form: FormItemYaml): Promise<AutocompleteAnnotatedFormItemYaml> => {\n    const serializedHtml = form.serialized_html ?? \"\";\n    const fingerprint = fingerprintDomNodeAttrs(serializedHtml);\n    const cacheKey = domNodeRefCacheKey(form);\n    const cached = domNodeRefCache.get(cacheKey);\n\n    if (cached?.fingerprint === fingerprint) {\n        return {\n            ...form,\n            autocomplete_dom_node_refs: cached.refs,\n        };\n    }\n\n    const refs = serializedHtml === \"\" ? [] : collectDomNodeRefs(serializedHtml);\n    domNodeRefCache.set(cacheKey, { fingerprint, refs });\n\n    return {\n        ...form,\n        autocomplete_dom_node_refs: refs,\n    };\n};\n\nexport const setApp__deprecated =\n    (appId: AppId, initialContent: IDEAppContentWithDeps, initialTableMappingId?: TableMappingId): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const startTime = performance.now();\n        const abFlags = getState().user?.ab ?? {};\n        currentAppId = appId;\n        domNodeRefCache.clear();\n        await ac.call(\"setApp__deprecated\", appId, initialContent, {}, abFlags, initialTableMappingId);\n        log.info(\"Background Autocompleter initialised with all app code in\", performance.now() - startTime, \"ms\");\n    };\n\ninterface StoredHttpEndpoint extends HttpEndpoint {\n    serverModuleName: string;\n}\n\ninterface StoredRoute extends Route {\n    serverModuleName: string;\n}\ninterface ACStateStore {\n    httpEndpoints: StoredHttpEndpoint[];\n    routes: StoredRoute[];\n    eventHandlers: Record<string, EventHandler[]>; // Form class name => EventHandlers\n}\n\nexport const acStateStore = new ExternalStore<ACStateStore>({\n    httpEndpoints: [],\n    routes: [],\n    eventHandlers: {},\n});\n\nconst updateHttpEndpointsAndRoutes = (serverModuleName: string, httpEndpoints: HttpEndpoint[], routes: Route[]) => {\n    acStateStore.updateState((s) => {\n        s.httpEndpoints = [\n            ...s.httpEndpoints.filter((e) => e.serverModuleName !== serverModuleName),\n            ...httpEndpoints.map((h) => ({ ...h, serverModuleName })),\n        ];\n        s.routes = [\n            ...s.routes.filter((e) => e.serverModuleName !== serverModuleName),\n            ...routes.map((r) => ({ ...r, serverModuleName })),\n        ];\n    });\n};\n\nconst updateEventHandlers = (formName: string, eventHandlers: EventHandler[]) => {\n    acStateStore.updateState((s) => {\n        s.eventHandlers[formName] = eventHandlers;\n    });\n};\n\nexport const updateItemMetadata = (\n    item: CodeItemYaml,\n    itemType: CodeItemType,\n    metadata: Pick<PythonItemMetadata, \"httpEndpoints\" | \"routes\" | \"eventHandlers\">\n) => {\n    if (itemType === \"server_module\" && item.name) {\n        updateHttpEndpointsAndRoutes(item.name, metadata.httpEndpoints, metadata.routes);\n    } else if (itemType === \"form\" && item.class_name) {\n        updateEventHandlers(item.class_name, metadata.eventHandlers);\n    }\n};\n\nexport const refreshItemMetadata = (): AnvilAsyncAction => async (dispatch) => {\n    try {\n        await dispatch(\n            refreshPythonAppMetadata((project, items) => {\n                const metadata: ACStateStore = { httpEndpoints: [], routes: [], eventHandlers: {} };\n                for (const item of items) {\n                    const source = project.sources[item.uri];\n                    if (source.codePath?.startsWith(\"forms/\")) {\n                        metadata.eventHandlers[source.label] = item.eventHandlers;\n                    } else if (source.codePath?.startsWith(\"server_modules/\")) {\n                        metadata.httpEndpoints.push(\n                            ...item.httpEndpoints.map((endpoint) => ({\n                                ...endpoint,\n                                serverModuleName: source.label,\n                            }))\n                        );\n                        metadata.routes.push(\n                            ...item.routes.map((route) => ({ ...route, serverModuleName: source.label }))\n                        );\n                    }\n                }\n                acStateStore.setState(metadata);\n            })\n        );\n    } catch (error) {\n        // Metadata is derived from the published app. Analyzer failure must\n        // not turn an already-applied edit into a failed mutation.\n        console.error(\"Python metadata refresh failed\", error);\n    }\n};\n\nexport const renameComponentEventHandlers = (formName: string, oldName: string, newName: string) => {\n    if (!oldName || oldName === newName) {\n        return;\n    }\n    acStateStore.updateState((s) => {\n        const handlers = s.eventHandlers[formName];\n        if (!handlers) return;\n        for (const handler of handlers) {\n            if (handler.component !== oldName) continue;\n            handler.component = newName;\n            if (handler.handler === `${oldName}_${handler.event}`) {\n                handler.handler = `${newName}_${handler.event}`;\n            }\n        }\n    });\n};\n\nexport const addEventHandler = (formName: string, component: string, event: string, handler: string) => {\n    acStateStore.updateState((state) => {\n        const handlersForForm = state.eventHandlers[formName] ?? (state.eventHandlers[formName] = []);\n        const existing = handlersForForm.find(\n            (existingHandler) => existingHandler.component === component && existingHandler.event === event\n        );\n        if (existing) {\n            existing.handler = handler;\n        } else {\n            handlersForForm.push({ component, event, handler });\n        }\n    });\n};\n\nexport const resetApp =\n    (\n        content: IDEAppContentWithDeps,\n        appConfig: AppConfig,\n        abFlags: User[\"ab\"],\n        dependencyCode: IDEDependencyCode,\n        appId: AppId,\n        tableMappingId?: TableMappingId\n    ): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        // TODO: Get rid of this\n        await dispatch(setApp__deprecated(appId, content, tableMappingId));\n        console.log(\"%c Autocompleter resetApp DONE\", \"color: hotpink\");\n        const { forms, modules, server_modules } = content;\n\n        const startTime = performance.now();\n\n        acStateStore.setState({\n            httpEndpoints: [],\n            routes: [],\n        });\n\n        // Modern mode retains fresh server registrations for scripts and REPLs.\n        if (!getTyAnalysisEnabled(getState())) await ac.call(\"resetCache\");\n        await ac.call(\"setAppConfig\", appConfig);\n        await ac.call(\"setABFlags\", abFlags);\n\n        const jsComponentDefinitions = getJsCustomComponents(getState());\n        if (jsComponentDefinitions?.length) {\n            await ac.call(\"provideJsComponentTypes\", jsComponentDefinitions);\n        }\n\n        await ac.call(\"parseDependencyCode\", dependencyCode);\n\n        if (getTyAnalysisEnabled(getState())) {\n            await dispatch(refreshItemMetadata());\n            return;\n        }\n\n        for (const sm of server_modules || []) {\n            const { httpEndpoints, routes } = await ac.call(\"analyseItem\", sm, \"serverModule\");\n            updateHttpEndpointsAndRoutes(sm.name, httpEndpoints, routes);\n        }\n        for (const m of modules || []) {\n            await ac.call(\"analyseItem\", m, \"module\");\n        }\n        for (const f of forms || []) {\n            const { eventHandlers } = await ac.call(\"analyseItem\", f, \"form\");\n            updateEventHandlers(f.class_name, eventHandlers);\n        }\n        for (const f of forms || []) {\n            await ac.call(\"analyseItem\", f, \"form\");\n        }\n        log.info(\"Background Autocompleter reset with all app code in\", performance.now() - startTime, \"ms\");\n    };\n\nexport const reloadAppConfig = (): AnvilAsyncAction => async (dispatch, getState, updateState) => {\n    const config = getAppConfig(getState());\n    await ac.call(\"setAppConfig\", config);\n};\n\nexport const provideJsCustomComponentsToAutocompleter =\n    (jsComponents: CustomComponentSpec[]): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) =>\n        await ac.call(\"provideJsComponentTypes\", jsComponents);\n\n// Ewwwwwwww\nconst typeToCamelCase = (type: string) => (type === \"server_module\" ? \"serverModule\" : type);\n\n/** Retained scripts, REPLs, bindings and tutorial requests read current app sources. */\nconst synchronizeLegacySources = (): AnvilAsyncAction<AnalysisItem[]> => async (dispatch, getState) => {\n    if (!getTyAnalysisEnabled(getState())) return [];\n    const state = getState();\n    if (!state.app) return [];\n    const items = getAnalysisItems(state);\n    const documents = new Map(\n        getAnalysisEditors(state.app.id).map(\n            ([view, registration]) => [registration.codePath, view.state.doc.toString()] as const\n        )\n    );\n    const current = items.map((source) => ({\n        ...source,\n        item: { ...source.item, code: documents.get(source.codePath) ?? source.item.code },\n    }));\n    await ac.call(\n        \"synchronizeAppSources\",\n        current.map(({ itemType, item }) => ({\n            itemType: typeToCamelCase(itemType),\n            item,\n        }))\n    );\n    return current;\n};\n\nexport const analyseItem =\n    (\n        item: CodeItemYaml,\n        itemType: CodeItemType,\n        autoComplete?: boolean,\n        lineNo?: number,\n        col?: number,\n        charIndex?: number,\n        identifier?: string\n    ): AnvilAsyncAction<Analysis> =>\n    async (dispatch, getState) => {\n        await dispatch(synchronizeLegacySources());\n        // don't analyse HIDDEN_FORM\n        if (itemType === \"form\" && item.class_name === HIDDEN_FORM.class_name) return {};\n        const publishLegacyMetadata = !getTyAnalysisEnabled(getState());\n        const itemForAutocomplete =\n            itemType === \"form\" ? await annotateFormForAutocomplete(item as FormItemYaml) : item;\n        const result = await ac.call(\n            \"analyseItem\",\n            itemForAutocomplete,\n            typeToCamelCase(itemType),\n            autoComplete,\n            lineNo,\n            col,\n            charIndex,\n            identifier\n        );\n        // Legacy parsing still supports isolated/script consumers. Its replies must\n        // not overwrite metadata owned by the current Python app snapshot.\n        if (publishLegacyMetadata && !getTyAnalysisEnabled(getState())) updateItemMetadata(item, itemType, result);\n        return result;\n    };\n\nexport const analyseIsolatedFormCode =\n    (\n        autoComplete: boolean,\n        lineNo: number,\n        col: number,\n        charIndex: number,\n        identifier: string,\n        formItem: CodeItemYaml,\n        code: string\n    ): AnvilAsyncAction<Analysis> =>\n    async (dispatch) => {\n        const sources = await dispatch(synchronizeLegacySources());\n        const owner = sources.find(\n            (source) => source.itemType === \"form\" && source.item.class_name === formItem.class_name\n        );\n        return await ac.call(\n            \"analyseIsolatedFormCode\",\n            autoComplete,\n            lineNo,\n            col,\n            charIndex,\n            identifier,\n            await annotateFormForAutocomplete((owner?.item ?? formItem) as FormItemYaml),\n            code\n        );\n    };\n\nexport const analyseReplCode =\n    (\n        code: string,\n        moduleItem: CodeItemYaml,\n        isServer?: boolean,\n        autoComplete?: boolean,\n        lineNo?: number,\n        col?: number,\n        charIndex?: number,\n        identifier?: string\n    ): AnvilAsyncAction<Analysis> =>\n    async (dispatch) => {\n        await dispatch(synchronizeLegacySources());\n        return await ac.call(\n            \"analyseReplCode\",\n            code,\n            moduleItem,\n            isServer,\n            autoComplete,\n            lineNo,\n            col,\n            charIndex,\n            identifier\n        );\n    };\n\nexport const deleteItem = async (itemType: CodeItemType, itemName: string) => {\n    await ac.call(\"deleteItem\", typeToCamelCase(itemType), itemName);\n    // Clear acStateStore entries for deleted items\n    if (itemType === \"server_module\") {\n        updateHttpEndpointsAndRoutes(itemName, [], []);\n    } else if (itemType === \"form\") {\n        updateEventHandlers(itemName, []);\n    }\n};\n\nexport const renameItem = async (itemType: CodeItemType, oldName: string, newName: string) =>\n    await ac.call(\"renameItem\", typeToCamelCase(itemType), oldName, newName);\n\nexport const invalidateTableSchema =\n    (newTableMappingId: TableMappingId): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        await ac.call(\"invalidateTableSchema\", newTableMappingId);\n    };\n\nexport const getDefinedBackgroundTasks =\n    (): AnvilAsyncAction<{ name: string; moduleName: string }[]> => async (dispatch, getState, updateState) => {\n        if (getTyAnalysisEnabled(getState())) return dispatch(getPythonBackgroundTasks());\n        return await ac.call(\"getDefinedBackgroundTasks\");\n    };\n\nexport const updateFormItemType =\n    (className: string, itemType?: FormItemYaml[\"item_type\"]): AnvilAsyncAction =>\n    async () => {\n        return await ac.call(\"updateFormItemType\", className, itemType);\n    };\n\nexport const parseDependencyCode = (depCode: IDEDependencyCode) => ac.call(\"parseDependencyCode\", depCode);\n","// Goal is that this file can be imported at both ends\nimport log from \"loglevel\";\nimport defer, { Deferred } from \"@/util/defer\";\n\nexport interface CustomWorker extends Worker {\n    registerFn(fnName: string, handler: HandlerFn): void;\n    call(fnName: string, ...args: any[]): Promise<any>;\n    postMessage(message: CallData | ResponseData): void;\n}\n\nexport interface CustomWorkerGlobalScope extends DedicatedWorkerGlobalScope {\n    registerFn(fnName: string, handler: HandlerFn): void;\n    call(fnName: string, ...args: any[]): Promise<any>;\n    postMessage(message: CallData | ResponseData): void;\n    SkGlobals: any;\n}\n\ntype CallId = `call-${number}`;\ntype HandlerFn = (...args: any[]) => Promise<any> | any;\ntype Handlers = { [handler: string]: HandlerFn };\ntype OutstandingCalls = { [callId: CallId]: Deferred<any> };\n\ninterface CallData {\n    type: \"CALL\";\n    callId: CallId;\n    fn: string;\n    args: any[];\n}\n\ninterface ResponseData {\n    type: \"RESPONSE\";\n    callId: CallId;\n    value?: any;\n    error?: string;\n}\n\nexport function initWorkerRPC(target: CustomWorker | CustomWorkerGlobalScope) {\n    let nextCallId = 0;\n    const outstandingCalls: OutstandingCalls = {};\n    const handlers: Handlers = {};\n\n    target.registerFn = (fnName: string, handler: HandlerFn) => {\n        handlers[fnName] = handler;\n    };\n\n    target.call = (fn: string, ...args: any[]): Promise<any> => {\n        const callId: CallId = `call-${nextCallId++}`;\n        target.postMessage({\n            type: \"CALL\",\n            callId,\n            fn,\n            args,\n        });\n        outstandingCalls[callId] = defer();\n        return outstandingCalls[callId].promise;\n    };\n\n    target.onmessage = async (m: MessageEvent<CallData | ResponseData>) => {\n        const { data } = m;\n        switch (data.type) {\n            case \"CALL\":\n                //log.debug(`RPC call ${data.callId}:`, data.fn, data.args);\n                const handler = handlers[data.fn];\n                let value, error;\n                if (!handler) {\n                    error = `No handler registered for '${data.fn}'`;\n                } else {\n                    try {\n                        value = await handler(...data.args);\n                    } catch (e) {\n                        error = String(e);\n                    }\n                }\n                try {\n                    target.postMessage({\n                        type: \"RESPONSE\",\n                        callId: data.callId,\n                        value,\n                        error,\n                    });\n                } catch (e) {\n                    console.error(e, \"Failed to post RPC response:\", value, error);\n                }\n                break;\n\n            case \"RESPONSE\":\n                const call = outstandingCalls[data.callId];\n                if (!call) {\n                    console.warn(`Got worker response for invalid call ${data.callId}`, data);\n                } else {\n                    if (data.error) {\n                        log.debug(`RPC error response ${data.callId}:`, data.error);\n                        call.reject(data.error);\n                    } else {\n                        //log.debug(`RPC response ${data.callId}:`, data.value);\n                        call.resolve(data.value);\n                    }\n                }\n        }\n    };\n}\n\nexport class BackgroundWorker {\n    private target: CustomWorker | null = null;\n    constructor(readonly workerConstructor: () => Worker) {}\n    ensureWorker() {\n        if (!this.target) {\n            this.target = this.workerConstructor() as CustomWorker;\n            initWorkerRPC(this.target);\n        }\n        return this.target;\n    }\n\n    call(fnName: string, ...args: any[]) {\n        const target = this.ensureWorker();\n        return target.call(fnName, ...args);\n    }\n}\n","import { useCallback } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { current } from \"immer\";\nimport { cloneDeep, dropRight, escapeRegExp, isEmpty, isEqual, last, nth, omit, remove } from \"lodash-es\";\nimport { createSelector } from \"reselect\";\nimport { ComponentYaml, EditPath, ToolboxSection } from \"@designer/shared-types\";\nimport { LayoutMetadata } from \"@runtime/runner/data\";\nimport { getAnalysisEditors, getTyAnalysisEnabled, requestPythonResourceRename } from \"@/analysis/ide-analysis\";\nimport { prepareModuleConversion } from \"@/analysis/module-conversion\";\nimport type { AnvilWorkspaceEdit } from \"@/analysis/workspace-edits\";\nimport { applyPythonRename, commitWorkspaceRename, loadWorkspaceRenameSources } from \"@/analysis/workspace-renames\";\nimport { type RuffTargetVersion, getRuffTargetVersion } from \"@/code_mirror/ruff/config\";\nimport { reformat } from \"@/code_mirror/ruff/reformat\";\nimport { findLogicalDepIdForDepAppId } from \"@/controllers/dependencies\";\nimport { GadgetState } from \"@/pyspace/gadget_editor/store/gadget-store\";\nimport { CodeNavTarget, NavTarget } from \"@/router/navTypes\";\nimport { navigate } from \"@/router/navigation\";\nimport { action } from \"@/store/editor-store\";\nimport {\n    AnvilAction,\n    AnvilAsyncAction,\n    AnvilDispatch,\n    AppPath,\n    AssetItemYaml,\n    Cache,\n    ChangedCodePath,\n    CodeItem,\n    CodeItemType,\n    CodeItemYaml,\n    CodeNavFileState,\n    CodeNavState,\n    CodePath,\n    CodeStructureType,\n    CodeTab,\n    ConflictType,\n    Conflicts,\n    EditHistory,\n    EditorPath,\n    ExtraFileStructureItem,\n    FileTreeItem,\n    FormDesignItem,\n    FormItem,\n    FormItemYaml,\n    FullView,\n    ModuleItemYaml,\n    RootStructure,\n    ScriptItemYaml,\n    ServerItemYaml,\n    State,\n    StructureItem,\n    TreeType,\n} from \"@/types\";\nimport {\n    AppCodeStructure,\n    AppConfig,\n    AppId,\n    AppState,\n    ConflictingItem,\n    DependencyStructureContent,\n    DependencyStructureItem,\n    ExtraFiles,\n    IDEDependencyCode,\n    StartupItemType,\n} from \"@/types/app\";\nimport { EMPTY_OBJECT } from \"@/util\";\nimport { findAssetPathConflict } from \"@/util/assetUploads\";\nimport { useRerender } from \"@/util/hooks\";\nimport { fileToBase64Content } from \"@/util/hooks/assets\";\nimport { getHasTables } from \"../db\";\nimport { getDebugEnvBreakpoints, setBreakpoints } from \"../debugger\";\nimport { getShowNewDesigner } from \"../designer\";\nimport { alert, confirm, modal, prompt } from \"../modals\";\nimport { getIsUplinkVisible, getServiceSpecs } from \"../services\";\nimport {\n    forceCloseTabs,\n    getCurrentTabId,\n    getTabByCodePath,\n    recentlyOpenedUpdater,\n    removeRecentlyOpened,\n    updateTab,\n} from \"../tabs\";\nimport { claimAchievement, getUserAutoImport, getUserCodeTemplates, getUserTabSize } from \"../user\";\nimport { defaultMinimalFormCode, defaultStandardFormCode } from \"../util\";\nimport * as autocompleter from \"./autocompleter\";\nimport {\n    canonicalizeFormSpecsInFormYaml,\n    renameLocalFormInCustomComponentSpec,\n    renameLocalFormInFormPropertySpec,\n} from \"./form-specs\";\nimport { confirmItemConflictsResolved } from \"./history\";\nimport {\n    type SerializeHtmlResult,\n    cacheRuntimeParsedHtmlFormYaml,\n    getRuntimeParsedHtmlFormYaml,\n    parseSerializedHtml,\n    serializeFormContainer,\n    serializeFormContainerWithResult,\n    serializeFormLayout,\n    serializeFormLayoutWithResult,\n} from \"./html-form-parser\";\nimport {\n    getApp,\n    getAppConfig,\n    getAppId,\n    getAppMetadata,\n    getAppStartupItem,\n    getEditorSequenceNumbers,\n    markAppPathUnsaved,\n    markAppPathsUnsaved,\n    updateAppConfig,\n    updateEditorSequenceAppPaths,\n} from \"./index\";\n\nconst DEBUG_HTML_PARSING = localStorage.getItem(\"anvilDebugHtmlParsing\") === \"true\";\ntype HtmlParsingDebugContext = {\n    codePath?: CodePath;\n    previousHistoryState?: FormDesignItem | null;\n    operation?: string;\n    eventContext?: unknown;\n    afterMutationState?: unknown;\n};\n\ntype HtmlParsingDebugOptions = {\n    debugContext?: HtmlParsingDebugContext;\n    suppressDebug?: boolean;\n    /**\n     * Serialize-only mode keeps `serialized_html` current. Structural mode also\n     * lets the HTML-form serializer reparse and write canonical container,\n     * component, and slot YAML.\n     */\n    structural?: boolean;\n};\n\ntype HtmlParsingDebugPayload = {\n    operation: string;\n    codePath?: CodePath;\n    previousHistoryState?: FormDesignItem | null;\n    eventContext?: unknown;\n    afterMutationState?: unknown;\n    afterSerializationState?: unknown;\n    serializedHtml?: string;\n    parsedResult?: unknown;\n    afterParseState?: unknown;\n    persistenceState?: unknown;\n};\n\nconst HTML_DEBUG_STYLE = \"color: #67e8f9; font-weight: 600;\";\n\nconst captureHtmlParsingDebugStack = () => {\n    try {\n        throw new Error(\"DEBUG_HTML_PARSING stack\");\n    } catch (error) {\n        return error instanceof Error ? error.stack : String(error);\n    }\n};\n\nconst stringifyHtmlParsingDebugValue = (value: unknown) => {\n    if (value === undefined || value === null) {\n        return \"unavailable\";\n    }\n    if (typeof value === \"string\") {\n        return value;\n    }\n    try {\n        return JSON.stringify(value, null, 2);\n    } catch (error) {\n        return `[Unable to stringify value: ${error instanceof Error ? error.message : String(error)}]`;\n    }\n};\n\nconst getPreviousHistoryState = (state: State, codePath?: CodePath, debugContext?: HtmlParsingDebugContext) => {\n    if (debugContext?.previousHistoryState !== undefined) {\n        return debugContext.previousHistoryState;\n    }\n    if (!codePath) {\n        return undefined;\n    }\n    return getCodeItemHistory(codePath, state)?.design?.done.at(-1);\n};\n\nconst logHtmlParsingDebug = (payload: HtmlParsingDebugPayload) => {\n    if (!DEBUG_HTML_PARSING) return;\n\n    const stack = captureHtmlParsingDebugStack();\n    const sections: [string, unknown][] = [\n        [\"Operation\", payload.operation],\n        [\"Code Path\", payload.codePath],\n        [\"Stack\", stack],\n        [\"Previous History State\", payload.previousHistoryState],\n    ];\n\n    if (payload.eventContext !== undefined) {\n        sections.push([\"Event Context\", payload.eventContext]);\n    }\n    if (payload.afterMutationState !== undefined) {\n        sections.push([\"After Mutation State\", payload.afterMutationState]);\n    }\n    if (payload.afterSerializationState !== undefined) {\n        sections.push([\"After Serialization State\", payload.afterSerializationState]);\n    }\n    if (payload.serializedHtml !== undefined) {\n        sections.push([\"Serialized HTML\", payload.serializedHtml]);\n    }\n    if (payload.parsedResult !== undefined) {\n        sections.push([\"Parsed Result\", payload.parsedResult]);\n    }\n    if (payload.afterParseState !== undefined) {\n        sections.push([\"After Parse State\", payload.afterParseState]);\n    }\n    if (payload.persistenceState !== undefined) {\n        sections.push([\"Persistence State\", payload.persistenceState]);\n    }\n\n    const copyJsonPayload = {\n        operation: payload.operation,\n        codePath: payload.codePath ?? null,\n        stack,\n        previousHistoryState: payload.previousHistoryState ?? null,\n        eventContext: payload.eventContext ?? null,\n        afterMutationState: payload.afterMutationState ?? null,\n        afterSerializationState: payload.afterSerializationState ?? null,\n        serializedHtml: payload.serializedHtml ?? null,\n        parsedResult: payload.parsedResult ?? null,\n        afterParseState: payload.afterParseState ?? null,\n        persistenceState: payload.persistenceState ?? null,\n    };\n\n    const message = [\n        `DEBUG_HTML_PARSING_COPY_JSON=${JSON.stringify(copyJsonPayload)}`,\n        // \"================ DEBUG_HTML_PARSING ================\",\n        // ...sections.map(\n        //     ([label, value]) =>\n        //         `---------------- ${label} ----------------\\n${stringifyHtmlParsingDebugValue(value)}`\n        // ),\n        // \"================ END DEBUG_HTML_PARSING ================\",\n    ].join(\"\\n\\n\");\n\n    console.log(\"%c\" + message, HTML_DEBUG_STYLE);\n};\n\nexport const logHtmlParsingMutationDebug = (payload: {\n    operation: string;\n    codePath?: CodePath;\n    eventContext?: unknown;\n    afterMutationState?: unknown;\n}) => {\n    logHtmlParsingDebug(payload);\n};\n\nlet _cacheKey = 0;\nlet _cache: Cache = {};\n\n/** Preflight original resource identities before the workspace rename publishes.\n * Cached item objects keep their identity and server ID. Old route keys become\n * redirects, while structure, tabs and saved native histories follow the item. */\nexport function prepareCodeResourceRenames(\n    resources: { codePath: CodePath; newCodePath: CodePath; before: string; after: string }[],\n    state: State\n) {\n    const appId = getAppId(state)!;\n    const structure = [...getForms(state), ...getModules(state), ...getServerModules(state)];\n    const entries = resources.map((resource) => {\n        const cached = getCachedCodeItem(resource.codePath, state);\n        const item = structure.find((item) => item.codePath === resource.codePath);\n        if (!item || item.fullName !== resource.before || !cached.item?.id || cached.deleted || cached.renamed)\n            throw new Error(\"A required resource identity changed. Retry rename.\");\n        if (\n            structure.some(\n                (item) =>\n                    (item.fullName === resource.after || item.fullName.startsWith(resource.after + \".\")) &&\n                    !resources.some((moving) => moving.codePath === item.codePath)\n            )\n        )\n            throw new Error(\"Resource rename destination is in use.\");\n        const destination = getCachedCodeItem(resource.newCodePath, state);\n        if (destination.item && !destination.deleted && !destination.renamed)\n            throw new Error(\"Resource rename destination is in use.\");\n        return {\n            resource,\n            entry: cached as CodeItem,\n            oldKey: getCacheKey([\"CODE\", resource.codePath], state),\n            newKey: getCacheKey([\"CODE\", resource.newCodePath], state),\n        };\n    });\n    return (state: State): NavTarget | undefined => {\n        let active: NavTarget | undefined;\n        for (const { resource, entry, oldKey, newKey } of entries) {\n            const item = [...getForms(state), ...getModules(state), ...getServerModules(state)].find(\n                (item) => item.codePath === resource.codePath\n            )!;\n            item.fullName = resource.after;\n            item.name = resource.after.split(\".\").pop()!;\n            item.codePath = resource.newCodePath;\n            state.itemCache[newKey] = _cacheKey++;\n            _cache[state.itemCache[newKey]] = entry;\n            _cache[state.itemCache[oldKey]] = {\n                itemType: entry.itemType,\n                item:\n                    entry.itemType === \"form\"\n                        ? { class_name: resource.before, code: \"\" }\n                        : { name: resource.before, code: \"\" },\n                deleted: true,\n                renamed: true,\n                redirect: newKey,\n            } as CodeItem;\n            if (state.viewCache[appId]?.[resource.codePath]) {\n                state.viewCache[appId][resource.newCodePath] = state.viewCache[appId][resource.codePath];\n                delete state.viewCache[appId][resource.codePath];\n            }\n            if (state.editHistory[oldKey]) {\n                state.editHistory[newKey] = state.editHistory[oldKey];\n                delete state.editHistory[oldKey];\n            }\n            delete state.unsavedAppPaths[JSON.stringify([\"CODE\", resource.codePath])];\n            const tabs = [...(state.editor.tabs ?? []), ...(state.editor.recentlyOpened[appId] ?? [])];\n            for (const tab of tabs) {\n                if (tab.navTarget.type !== \"CODE\" || tab.navTarget.codePath !== resource.codePath) continue;\n                tab.navTarget.codePath = resource.newCodePath;\n                tab.title = generateTitleFromCodeTabItem(tab as CodeTab, entry.item);\n                tab.forceReload = (tab.forceReload ?? 0) + 1;\n                if (tab.id === getCurrentTabId(state)) active = current(tab.navTarget)!;\n            }\n        }\n        return active;\n    };\n}\nexport const getCacheKey = (appPath: string[], state: State) => {\n    const appId = getAppId(state);\n    return JSON.stringify([appId, ...appPath]);\n};\n\nexport const itemTypeFromCodePath = (codePath: CodePath): CodeItemType => {\n    const [_, itemType] = codePath.match(/^([^/]*)s\\/(.*)/) ?? [];\n    return itemType as CodeItemType;\n};\n\nexport const classNameFromCodePath = (codePath: CodePath): string => {\n    return codePath.split(\"/\").pop() as string;\n};\n\nexport const describeAppPath = (appPath: string[]) => {\n    const [appPathType, ...appPathContent] = appPath;\n    switch (appPathType) {\n        case \"CODE\":\n            const [_, type, id] = appPathContent[0].match(/^(form|server_module|module|asset)s\\/(.*)$/) ?? [];\n            const typeName = { form: \"Form\", server_module: \"Server Module\", module: \"Module\", asset: \"Asset\" }[type];\n            return type && { type, id, typeName, name: id, appPath };\n\n        case \"SETTINGS\":\n            return { type: \"settings\", id: null, typeName: \"Settings\", appPath };\n\n        case \"file\":\n            return { type: \"file\", id: appPathContent[0], name: appPathContent[0], typeName: \"Other File\", appPath };\n    }\n};\n\nexport const generateItemId = () => {\n    return `${Date.now()}${Math.random() * 1e12}`;\n};\n\n// HIDDEN FORM is used but the FormEditor to preload the designer\nexport const HIDDEN_FORM = {\n    container: { type: \"HtmlTemplate\" },\n    components: [],\n    code: \"\",\n    is_package: true,\n    id: generateItemId(),\n    class_name: \" \", // if it's falsey then the designer doesn't load it, blank string so we don't have anything odd in the designer breadcrumb\n};\nconst HIDDEN_CODE_ITEM: CodeItem = { itemType: \"form\", item: HIDDEN_FORM };\nexport const HIDDEN_CODE_PATH = \"forms/ \";\n// Selector\nexport const getCachedCodeItem = (codePath: CodePath, state: State) => {\n    if (codePath === HIDDEN_CODE_PATH) return HIDDEN_CODE_ITEM;\n    // console.log(\"%cGETTING CACHED CODE ITEM\", \"color: blue;\", codePath);\n    const cacheKey = getCacheKey([\"CODE\", codePath], state);\n    const cache = getItemCache(state);\n    // this might return a cached renamed/deleted form - this will cause a blank tab with the correct name\n    return _cache[cache[cacheKey]] ?? (EMPTY_OBJECT as CodeItem | Partial<CodeItem>);\n};\n\nexport const clearCodeItemCache = (): AnvilAction => (dispatch, getState, updateState) => {\n    updateState((state) => {\n        state.itemCache = {};\n        _cache = {};\n        // Extra files keep their text history across versions, but resolved\n        // conflict context must end with the loaded version, just as it does in the item cache.\n        for (const history of Object.values(state.editHistory)) delete history.resolvedConflictMerge;\n    });\n};\n\n/**\n * Syncs cached (locally-edited) items back into initialCode, rebuilds codeStructure,\n * and clears cache only for items in the change set.\n *\n * This prevents local edits from being lost when an incremental update arrives\n * for unrelated items.\n */\nexport const rebuildCodeStructureAndSyncCache =\n    (changedCodePaths: Set<CodePath>): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ app, itemCache }) => {\n            if (!app) return;\n\n            syncCacheToInitialCode(app, itemCache, changedCodePaths);\n\n            app.codeStructure = buildCodeStructureFromInitialCode(app.initialCode, app.config.package_name, {\n                extraFiles: app.config.extra_files,\n            });\n\n            clearCacheForChangedPaths(itemCache, changedCodePaths);\n        });\n    };\n\nconst syncCacheToInitialCode = (app: AppState, itemCache: Record<string, number>, changedCodePaths: Set<CodePath>) => {\n    for (const [cacheKeyStr, cacheIdx] of Object.entries(itemCache)) {\n        const cached = _cache[cacheIdx];\n        if (!cached) continue;\n\n        const parsed = JSON.parse(cacheKeyStr);\n        const codePath = parsed[2] as CodePath;\n\n        // Server-changed paths are handled by applyIncrementalUpdate/clearCacheForChangedPaths\n        if (changedCodePaths.has(codePath)) continue;\n\n        const match = codePath.match(/^([^/]*)\\/(.*)/);\n        if (!match) continue;\n        const [, type, name] = match;\n\n        if (cached.deleted || cached.renamed) {\n            // Locally deleted or renamed item — remove the old entry from initialCode\n            // so buildCodeStructureFromInitialCode won't resurrect it as a ghost.\n            // For renames, the new-name cache entry will write the item separately.\n            removeDeletedItemFromInitialCode(app, type, name);\n            continue;\n        }\n\n        writeCachedItemToInitialCode(app, type, name, cached.item);\n    }\n};\n\nconst writeCachedItemToInitialCode = (app: AppState, type: string, name: string, item: CodeItemYaml) => {\n    // Clone to avoid Immer freezing the original _cache reference\n    const cloned = cloneDeep(item);\n    switch (type) {\n        case \"forms\": {\n            const idx = app.initialCode.forms?.findIndex((f) => f.class_name === name);\n            if (idx !== undefined && idx !== -1) {\n                app.initialCode.forms[idx] = cloned as FormItemYaml;\n            } else {\n                (app.initialCode.forms ??= []).push(cloned as FormItemYaml);\n            }\n            break;\n        }\n        case \"modules\": {\n            const idx = app.initialCode.modules?.findIndex((m) => m.name === name);\n            if (idx !== undefined && idx !== -1) {\n                app.initialCode.modules[idx] = cloned as ModuleItemYaml;\n            } else {\n                (app.initialCode.modules ??= []).push(cloned as ModuleItemYaml);\n            }\n            break;\n        }\n        case \"server_modules\": {\n            const idx = app.initialCode.server_modules?.findIndex((m) => m.name === name);\n            if (idx !== undefined && idx !== -1) {\n                app.initialCode.server_modules[idx] = cloned as ServerItemYaml;\n            } else {\n                (app.initialCode.server_modules ??= []).push(cloned as ServerItemYaml);\n            }\n            break;\n        }\n        case \"scripts\": {\n            const idx = app.initialCode.scripts?.findIndex((s) => s.name === name);\n            if (idx !== undefined && idx !== -1 && app.initialCode.scripts) {\n                app.initialCode.scripts[idx] = cloned as ScriptItemYaml;\n            } else {\n                (app.initialCode.scripts ??= []).push(cloned as ScriptItemYaml);\n            }\n            break;\n        }\n        case \"assets\": {\n            const idx = app.initialCode.theme?.assets?.findIndex((a) => a.name === name);\n            if (idx !== undefined && idx !== -1) {\n                app.initialCode.theme.assets[idx] = cloned as AssetItemYaml;\n            } else {\n                app.initialCode.theme ??= { assets: [] } as AppState[\"initialCode\"][\"theme\"];\n                (app.initialCode.theme.assets ??= []).push(cloned as AssetItemYaml);\n            }\n            break;\n        }\n    }\n};\n\nconst removeDeletedItemFromInitialCode = (app: AppState, type: string, name: string) => {\n    switch (type) {\n        case \"forms\":\n            remove(app.initialCode.forms ?? [], (f) => f.class_name === name);\n            break;\n        case \"modules\":\n            remove(app.initialCode.modules ?? [], (m) => m.name === name);\n            break;\n        case \"server_modules\":\n            remove(app.initialCode.server_modules ?? [], (m) => m.name === name);\n            break;\n        case \"scripts\":\n            remove(app.initialCode.scripts ?? [], (s) => s.name === name);\n            break;\n        case \"assets\":\n            remove(app.initialCode.theme?.assets ?? [], (a) => a.name === name);\n            break;\n    }\n};\n\nconst clearCacheForChangedPaths = (itemCache: Record<string, number>, changedCodePaths: Set<CodePath>) => {\n    for (const codePath of changedCodePaths) {\n        // Find matching cache keys for this code path\n        for (const [cacheKeyStr, cacheIdx] of Object.entries(itemCache)) {\n            const parsed = JSON.parse(cacheKeyStr);\n            if (parsed[2] === codePath) {\n                delete _cache[cacheIdx];\n                delete itemCache[cacheKeyStr];\n            }\n        }\n    }\n};\n\nconst CODE_ITEM_HISTORY_LENGTH = 50;\n\nconst getCodePathSequenceNumber = (state: State, codePath: CodePath) =>\n    getEditorSequenceNumbers(state)[JSON.stringify([\"CODE\", codePath])] ?? 0;\n\nconst updateSerializedHtmlWithResult = (\n    form: FormItemYaml,\n    state: State,\n    options: HtmlParsingDebugOptions = {}\n): SerializeHtmlResult => {\n    const { debugContext, structural = false, suppressDebug = false } = options;\n    const indentSize = getUserTabSize(state);\n    if (form.save_as_html) {\n        let result: SerializeHtmlResult;\n        if (form.layout) {\n            result = serializeFormLayoutWithResult(form, { indentSize, allowReparse: structural });\n        } else {\n            result = serializeFormContainerWithResult(form, { indentSize, allowReparse: structural });\n        }\n        const serializedHtml = result.html;\n        form.serialized_html = serializedHtml;\n        if (DEBUG_HTML_PARSING && !suppressDebug) {\n            logHtmlParsingDebug({\n                operation: \"updateSerializedHtml\",\n                codePath: debugContext?.codePath,\n                previousHistoryState: debugContext?.previousHistoryState,\n                afterSerializationState: form,\n                serializedHtml,\n            });\n        }\n\n        return { ...result, html: serializedHtml ?? \"\" };\n    }\n\n    // edit_as_html previews package-qualified specs in serialized_html without\n    // making that preview the YAML conversion point. Do not reparse the real\n    // cached form here: parsing can promote HTML nodes into mutable YAML, and\n    // that conversion belongs to setSaveAsHtml(true). Skipping reparse also\n    // skips cleanup of dead anvil-dropzones, but YAML-backed forms should not\n    // usually contain HTML-owned components before they are saved as HTML.\n    if (form.edit_as_html) {\n        const formForPreview = cloneDeep(form);\n        canonicalizeFormSpecsInFormYaml(formForPreview, state);\n        const previewResult = formForPreview.layout\n            ? serializeFormLayoutWithResult(formForPreview, { indentSize })\n            : serializeFormContainerWithResult(formForPreview, { indentSize });\n\n        const serializedHtml = previewResult.html;\n        form.serialized_html = serializedHtml;\n        if (DEBUG_HTML_PARSING && !suppressDebug) {\n            logHtmlParsingDebug({\n                operation: \"updateSerializedHtml\",\n                codePath: debugContext?.codePath,\n                previousHistoryState: debugContext?.previousHistoryState,\n                afterSerializationState: form,\n                serializedHtml,\n            });\n        }\n\n        return { html: serializedHtml ?? \"\", structuralHtmlChanged: false };\n    }\n\n    return { html: \"\", structuralHtmlChanged: false };\n};\n\nexport const updateSerializedHtml = (form: FormItemYaml, state: State, options: HtmlParsingDebugOptions = {}): string =>\n    updateSerializedHtmlWithResult(form, state, options).html;\n\n/**\n * Updates `serialized_html` after a designer-owned YAML mutation.\n * With `structural: true`, this may also reparse and mutate container,\n * component, and slot structure. The serializer reports that structural change\n * directly from the reparse path that performs the mutation.\n */\nexport const syncHtmlFormAfterDesignerMutation = (\n    form: FormItemYaml,\n    state: State,\n    options: HtmlParsingDebugOptions = {}\n): { serializedHtml: string; structuralHtmlChanged: boolean } => {\n    if (!form.save_as_html && !form.edit_as_html) {\n        return { serializedHtml: form.serialized_html ?? \"\", structuralHtmlChanged: false };\n    }\n\n    const { html: serializedHtml, structuralHtmlChanged } = updateSerializedHtmlWithResult(form, state, {\n        ...options,\n        suppressDebug: true,\n    });\n\n    if (DEBUG_HTML_PARSING) {\n        logHtmlParsingDebug({\n            operation: options.debugContext?.operation ?? \"syncHtmlFormAfterDesignerMutation\",\n            codePath: options.debugContext?.codePath,\n            eventContext: {\n                ...(typeof options.debugContext?.eventContext === \"object\" && options.debugContext.eventContext !== null\n                    ? options.debugContext.eventContext\n                    : {}),\n                structural: options.structural === true,\n                structuralHtmlChanged,\n            },\n            afterMutationState: options.debugContext?.afterMutationState,\n            afterSerializationState: form,\n            serializedHtml,\n        });\n    }\n\n    return { serializedHtml, structuralHtmlChanged };\n};\n\nexport const setSerializedFormHtml = (form: FormItemYaml, html: string, options: HtmlParsingDebugOptions = {}) => {\n    // Handle edit_as_html or save_as_html: inflate the HTML into designer view\n    if (form.edit_as_html || form.save_as_html) {\n        inflateHtmlFormYamlForDesigner(form, html, options);\n    }\n};\n\n/**\n * Takes a form and a serialized HTML and returns a designer view of the form\n * the form yaml can be either the original form or the designer view of the form\n *\n * note we mutate the form in place\n */\nexport const inflateHtmlFormYamlForDesigner = (\n    form: FormItemYaml,\n    serializedHtml: string,\n    { debugContext, suppressDebug = false }: HtmlParsingDebugOptions = {}\n): FormItemYaml => {\n    // Handle both save_as_html and edit_as_html modes\n    if (!form.save_as_html && !form.edit_as_html) {\n        return form;\n    }\n\n    form.serialized_html = serializedHtml ?? \"\";\n\n    const parsed = parseSerializedHtml(serializedHtml);\n\n    if (\"layout\" in parsed) {\n        form.layout = parsed.layout;\n        form.components_by_slot = parsed.components_by_slot;\n        delete form.container;\n        delete form.components;\n    } else {\n        form.container = parsed.container;\n        form.components = parsed.components;\n        delete form.layout;\n        delete form.components_by_slot;\n    }\n\n    // if we have slots use them\n    if (parsed.slots) {\n        form.slots = parsed.slots;\n    } else if (form.slots) {\n        // it's ok to override this because the only way to have slots in the frontmatter is if we are a layout with no slots\n        form.slots = {};\n    }\n\n    if (DEBUG_HTML_PARSING && !suppressDebug) {\n        logHtmlParsingDebug({\n            operation: \"inflateHtmlFormYamlForDesigner\",\n            codePath: debugContext?.codePath,\n            serializedHtml,\n            parsedResult: parsed,\n            afterParseState: form,\n        });\n    }\n\n    return form;\n};\n\n/**\n * Prepares a mutable cached form for the Designer by applying HTML-derived\n * structure, including Designer-only DOM node promotion. Storage loading has\n * already inflated HTML templates into normal form YAML; this only prepares the\n * cache copy that IDE/Designer tools will mutate.\n */\nconst prepareFormForDesigner = (form: FormItemYaml, state: State): void => {\n    if (form.save_as_html) {\n        inflateHtmlFormYamlForDesigner(form, form.serialized_html ?? \"\", { suppressDebug: false });\n    }\n\n    if (!form.save_as_html) {\n        // edit_as_html is preview-only. The HTML editor sees canonical\n        // package-qualified specs in serialized_html, but cached YAML keeps its\n        // existing spec strings and structure until setSaveAsHtml(true) parses\n        // the HTML back into YAML.\n        form.edit_as_html = true;\n        updateSerializedHtml(form, state, { suppressDebug: false });\n    } else if (form.edit_as_html) {\n        // shouldn't have an edit_as_html property as it's a designer only flag\n        delete form.edit_as_html;\n    }\n};\n\n/**\n * Takes a designer view of the HTML and sends this back to the server for storing as an html file\n * we need to remove the components and slots (unless we have empty slots)\n * and put back the html property once we've serialized the form to html\n */\nexport const deflateHtmlFormYamlForPersistence = (\n    form: FormItemYaml,\n    state: State,\n    options: HtmlParsingDebugOptions = {}\n): FormItemYaml => {\n    const { debugContext, suppressDebug = false } = options;\n    if (!form.save_as_html && !form.edit_as_html) {\n        return form;\n    }\n\n    // Always serialize from the current YAML. Cached serialized_html can be\n    // stale after customComponentSpec/formPropertySpec rewrites, package\n    // renames, or structural designer edits.\n    const serializedHtml = form.layout\n        ? serializeFormLayout(form, { indentSize: getUserTabSize(state) })\n        : serializeFormContainer(form, { indentSize: getUserTabSize(state) });\n\n    const deflated = cloneDeep(form);\n    deflated.serialized_html = serializedHtml;\n\n    // represented in the serialized html\n    delete deflated.container;\n    delete deflated.layout;\n    delete deflated.components_by_slot;\n    delete deflated.components;\n\n    if (form.slots && isEmpty(form.slots)) {\n        deflated.slots = {}; // this is a layout but doesn't have slots, so need to populate the frontmatter\n    } else {\n        // slots are inside the serialized html, so we don't need to save them in the yaml frontmatter\n        delete deflated.slots;\n    }\n\n    if (DEBUG_HTML_PARSING && !suppressDebug) {\n        logHtmlParsingDebug({\n            operation: \"deflateHtmlFormYamlForPersistence\",\n            codePath: debugContext?.codePath,\n            previousHistoryState: getPreviousHistoryState(state, debugContext?.codePath, debugContext),\n            afterSerializationState: form,\n            serializedHtml,\n            persistenceState: deflated,\n        });\n    }\n\n    return deflated;\n};\n\nexport const enqueueRecentCodeItem =\n    (codePath: CodePath, item: CodeItemYaml): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n        if (!appId) return;\n        updateState(({ viewCache, recentCodeItemCodePaths }) => {\n            remove(recentCodeItemCodePaths, (p) => p === codePath);\n            recentCodeItemCodePaths.unshift(codePath);\n            while (recentCodeItemCodePaths.length > CODE_ITEM_HISTORY_LENGTH) {\n                const popped = recentCodeItemCodePaths.pop();\n                if (popped && viewCache[appId]) {\n                    delete viewCache[appId][popped];\n                    if (isEmpty(viewCache[appId])) {\n                        delete viewCache[appId];\n                    }\n                }\n            }\n        });\n    };\n\n// doesn't need to be asynchronous, but in the future we would probably like to load this on demand\nexport const openCodeItem =\n    (codePath: CodePath): AnvilAsyncAction<CodeItem | null> =>\n    async (dispatch, getState, updateState) => {\n        if (codePath === HIDDEN_CODE_PATH) return HIDDEN_CODE_ITEM;\n\n        const cacheKey = getCacheKey([\"CODE\", codePath], getState());\n        const cache = getItemCache(getState());\n        const addToCache = (cacheKey: string, obj: CodeItem) => {\n            const _key = _cacheKey++;\n            _cache[_key] = obj;\n            updateState(({ itemCache }) => {\n                itemCache[cacheKey] = _key;\n            });\n            return obj;\n        };\n\n        const cachedItem = _cache[cache[cacheKey]];\n\n        if (cachedItem && (cachedItem.deleted || cachedItem.renamed)) {\n            return null;\n        } else if (cachedItem) {\n            // We might want to asynchronously refresh the item in the background here, then broadcast an update. Or not.\n            log.info(\"Loading item from cache:\", cacheKey);\n            return cachedItem;\n        } else {\n            // The item isn't already cached. Fetch, cache, and return it.\n            log.info(\"Fetching and caching item:\", cacheKey);\n            // Right now we load app items from app.code, which is actually already loaded. This won't always be the case.\n            const app = getApp(getState());\n            if (!app) {\n                throw new Error(\"App failed to load\");\n            }\n\n            // We used to remove cached items from app.initialCode, just to make sure we don't inadvertantly end up\n            // with several copies with different content. This slowed things down too much.\n\n            const [_, type, name] = codePath.match(/^([^/]*)\\/(.*)/) ?? [];\n            let itemType: CodeItemType, item: CodeItemYaml | undefined, conflictType: ConflictType | undefined;\n            switch (type) {\n                case \"forms\":\n                    itemType = \"form\";\n                    item = app.initialCode.forms.find((f) => f.class_name === name);\n                    //updateState(({app: {initialCode: {forms}}}) => { remove(forms, f => f.class_name === name)});\n                    conflictType = \"client_code\";\n                    break;\n                case \"modules\":\n                    itemType = \"module\";\n                    item = app.initialCode.modules.find((m) => m.name === name);\n                    //updateState(({app: {initialCode: {modules}}}) => { remove(modules, m => m.name === name)});\n                    conflictType = \"client_code\";\n                    break;\n                case \"server_modules\":\n                    itemType = \"server_module\";\n                    item = app.initialCode.server_modules.find((m) => m.name === name);\n                    //updateState(({app: {initialCode: {server_modules}}}) => { remove(server_modules, m => m.name === name)});\n                    conflictType = \"server_code\";\n                    break;\n                case \"scripts\":\n                    itemType = \"script\";\n                    item = app.initialCode.scripts?.find((s) => s.name === name);\n                    conflictType = \"script\";\n                    break;\n                case \"assets\":\n                    itemType = \"asset\";\n                    item = app.initialCode.theme.assets.find((a) => a.name === name);\n                    //updateState(({app: {initialCode: {theme: {assets}}}}) => { remove(assets, a => a.name === name)});\n                    conflictType = \"asset\";\n                    break;\n                default:\n                    throw new Error(`Could not open item of type '${type}'`);\n            }\n            if (!item) {\n                throw new Error(`Could not find ${itemType} '${name}'.`);\n            }\n            // Are there open conflicts on this item? Look for an element in conflicting_items that matches\n            // the type of conflict that would involve this item (nb conflict types don't map exactly to types of\n            // code item, because the conflict resolver, eg, can't always tell the difference between forms and modules)\n            const conflictIdx = app.conflicts?.conflicting_items.findIndex(\n                ({ item: [type, cname] }) => type === conflictType && cname === name\n            );\n            let conflicts: ConflictingItem | undefined;\n            if (conflictIdx !== undefined && conflictIdx !== -1) {\n                conflicts = app.conflicts!.conflicting_items[conflictIdx] as ConflictingItem;\n                // The master copy of this item's conflicts now moves to the item cache - delete it to avoid carrying\n                // stale state around.\n                updateState((state) => {\n                    state.app!.conflicts!.conflicting_items[conflictIdx] = {\n                        item: conflicts!.item,\n                        movedToItemCache: true,\n                    };\n                });\n            }\n            const cachedItem = cloneDeep(item);\n            if (itemType === \"form\") {\n                const state = getState();\n                cacheRuntimeParsedHtmlFormYaml(cachedItem as FormItemYaml, getCodePathSequenceNumber(state, codePath));\n                prepareFormForDesigner(cachedItem as FormItemYaml, state);\n            }\n            return addToCache(cacheKey, {\n                itemType,\n                item: cachedItem,\n                conflicts: cloneDeep(conflicts),\n            } as CodeItem);\n        }\n    };\n\n/**\n * Opens a same-app form in the shape expected by runtime custom component instantiation.\n *\n * `openCodeItem` prepares form YAML for Designer editing, which can promote DOM fragments into\n * child HtmlComponents. Passive forms loaded by the Designer RPC should instead keep those DOM\n * fragments owned by the root HTML container, matching runtime behavior.\n */\nexport const openRuntimeFormItem =\n    (codePath: CodePath): AnvilAsyncAction<FormItemYaml | undefined> =>\n    async (dispatch, getState) => {\n        const codeItem = await dispatch(openCodeItem(codePath));\n        if (codeItem === null) return undefined;\n        if (codeItem.itemType !== \"form\") {\n            throw new Error(`Expected ${codePath} to be a form.`);\n        }\n\n        return getRuntimeParsedHtmlFormYaml(codeItem.item, getCodePathSequenceNumber(getState(), codePath));\n    };\n\nexport const mutateItem =\n    (state: State, appPath: ChangedCodePath, f: (obj: CodeItem) => void): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const cacheKey = getCacheKey(appPath, state);\n        const itemCache = getItemCache(state);\n        f(_cache[itemCache[cacheKey]]);\n        dispatch(markAppPathUnsaved(appPath));\n    };\n\nexport const notifyUpdatedCodeItem = (codePath: CodePath, description?: string | null) =>\n    action((dispatch, getState, updateState) => {\n        if (codePath === HIDDEN_CODE_PATH) return 0;\n        return dispatch(markAppPathUnsaved([\"CODE\", codePath]));\n    });\n\nexport const updateCodeItem =\n    (\n        codePath: CodePath,\n        updatedItem: Partial<CodeItemYaml>,\n        updatedConflicts?: Conflicts,\n        description?: string,\n        saveCode = true,\n        saveRest = true\n    ): AnvilAsyncAction<number> =>\n    async (dispatch, getState, updateState) => {\n        //console.log(\"Update code item with conflicts:\", updatedConflicts);\n        if (codePath === HIDDEN_CODE_PATH) return 0;\n\n        const hasOpenConflicts = (conflicts?: Conflicts) => {\n            return (\n                conflicts &&\n                [conflicts.edits, conflicts.text_chunks, conflicts.components].find((l) => l && l.length !== 0)\n            );\n        };\n\n        const state = getState();\n        const cacheKey = getCacheKey([\"CODE\", codePath], state);\n        const itemCache = getItemCache(state);\n\n        const justResolvedLastConflict =\n            !hasOpenConflicts(updatedConflicts) && hasOpenConflicts(_cache[itemCache[cacheKey]]?.conflicts);\n        //console.log(\"Just resolved last conflict?\", !hasOpenConflicts(updatedConflicts), \"&&\", hasOpenConflicts(_cache[itemCache[cacheKey]].conflicts), \"->\", justResolvedLastConflict);\n\n        if (!(cacheKey in itemCache) || _cache[itemCache[cacheKey]].deleted || _cache[itemCache[cacheKey]].renamed) {\n            throw new Error(`Could not update item that hasn't been loaded: ${codePath}`);\n        }\n        // Can do this update without a dispatch, because _cache is not part of the state.\n        const { code, ...rest } = updatedItem;\n        if (saveRest) {\n            Object.assign(_cache[itemCache[cacheKey]].item, rest);\n        }\n        if (saveCode && typeof code === \"string\") {\n            _cache[itemCache[cacheKey]].item.code = code;\n        }\n        _cache[itemCache[cacheKey]].conflicts = updatedConflicts;\n\n        // Undo can reopen a code conflict after the submitter marked the whole\n        // file resolved. Restore the merge metadata and its central index too.\n        const cachedItem = _cache[itemCache[cacheKey]];\n        if (hasOpenConflicts(updatedConflicts) && cachedItem.resolvedConflictItem && cachedItem.resolvedConflictMerge) {\n            const conflictItem = cachedItem.resolvedConflictItem;\n            const merge = cachedItem.resolvedConflictMerge;\n            const restoringMerge = !state.app?.conflicts;\n            updateState((state) => {\n                const app = state.app!;\n                app.conflicts ??= { merge, conflicting_items: [] };\n                app.conflicts.conflicting_items.push({ item: conflictItem, movedToItemCache: true });\n            });\n            delete cachedItem.resolvedConflictItem;\n            delete cachedItem.resolvedConflictMerge;\n            if (restoringMerge) dispatch(markAppPathUnsaved([\"CONFLICTS\"]));\n        }\n\n        const seqNum = dispatch(markAppPathUnsaved([\"CODE\", codePath]));\n\n        if (justResolvedLastConflict) {\n            const state = getState();\n            const cacheKey = getCacheKey([\"CODE\", codePath], state);\n            const itemCache = getItemCache(state);\n            const cachedConflict = _cache[itemCache[cacheKey]]?.conflicts?.item;\n\n            if (cachedConflict) await dispatch(confirmItemConflictsResolved(cachedConflict));\n        }\n        return seqNum;\n    };\n\nexport const updateCodeStructureCustomComponent =\n    (codePath: CodePath, item: FormItemYaml): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        updateState(`Update custom component property`, (state) => {\n            const cacheKey = getCacheKey([\"CODE\", codePath], state);\n            const cacheItem = _cache[state.itemCache[cacheKey]].item as FormItemYaml;\n            const structureItemsByName = getCodeNames(state);\n            const structureItem = structureItemsByName[cacheItem[\"class_name\"]];\n            structureItem.customComponent = item.custom_component;\n            structureItem.toolboxItem = item.toolbox_item;\n            structureItem.layoutMetadata = item.layout_metadata;\n            structureItem.helpText = item.help_text;\n        });\n    };\n\nconst stateUpdateForceReloadAllForms = ({ editor: { tabs } }: State) => {\n    for (const t of tabs || []) {\n        if (t.navTarget.type === \"CODE\" && t.navTarget.codePath && t.itemType === \"form\") {\n            // @ts-ignore - has no real effect in the NewFormEditor\n            t.forceReloadForms = (t.forceReloadForms || 0) + 1;\n        }\n    }\n};\n\nconst stateUpdateForceReloadOpenTabs = ({ editor: { tabs } }: State, codePath: CodePath | null = null) => {\n    for (const t of tabs || []) {\n        if (codePath === null || (t.navTarget.type === \"CODE\" && t.navTarget.codePath === codePath)) {\n            t.forceReload = (t.forceReload || 0) + 1;\n        }\n    }\n};\n\nexport const forceReloadAllForms = (): AnvilAction => async (dispatch, getState, updateState) => {\n    updateState((state) => stateUpdateForceReloadAllForms(state));\n};\n\nexport const addCodeItem =\n    <T extends CodeItemType>(codePath: CodePath, itemType: T, item: CodeItemYaml<T>): AnvilAsyncAction<StructureItem> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n\n        // Put the new item into the cache\n        const cacheKey = getCacheKey([\"CODE\", codePath], state);\n\n        // Legacy mode fills its cache before the item is opened. Python reads\n        // the published app cache below, including unopened items.\n        if (!getTyAnalysisEnabled(getState()) && [\"form\", \"module\", \"server_module\"].includes(itemType)) {\n            dispatch(autocompleter.analyseItem(item, itemType));\n        }\n\n        let structureItem: StructureItem | undefined;\n\n        updateState(({ app, itemCache }) => {\n            if (!app) return;\n            if (cacheKey in itemCache) {\n                const existingCache = _cache[itemCache[cacheKey]];\n                if (!existingCache.deleted && !existingCache.renamed) {\n                    throw new Error(`Could not add item already in cache: ${codePath}`);\n                } else {\n                    // we're about to add an item where one was previously deleted\n                    // keep the id's the same - if the delete has not been saved then changing the ids invalidates the save see #3252\n                    item = { ...item, id: existingCache.item.id ?? item.id };\n                }\n            }\n            const cachedItem = cloneDeep(item);\n            if (itemType === \"form\") {\n                prepareFormForDesigner(cachedItem as FormItemYaml, state);\n            }\n\n            itemCache[cacheKey] = _cacheKey++;\n            _cache[itemCache[cacheKey]] = {\n                itemType: itemType,\n                item: cachedItem,\n            } as CodeItem;\n\n            // Put the new item into the code structure, so we don't have to load it from scratch\n            let root: RootStructure;\n            let structPath: string[];\n            switch (itemType) {\n                case \"form\": {\n                    const formItem = item as FormItemYaml;\n                    root = app.codeStructure.clientCode;\n                    structPath = formItem.class_name.split(\".\");\n\n                    structureItem = {\n                        name: structPath.pop()!,\n                        type: \"form\",\n                        id: formItem.id,\n                        isPackage: formItem.is_package,\n                        fullName: formItem.class_name,\n                        codePath: `forms/${formItem.class_name}`,\n                        customComponent: formItem.custom_component,\n                        toolboxItem: formItem.toolbox_item,\n                        helpText: formItem.help_text,\n                    };\n                    break;\n                }\n\n                case \"module\": {\n                    const moduleItem = item as ModuleItemYaml;\n                    root = app.codeStructure.clientCode;\n                    structPath = moduleItem.name.split(\".\");\n                    structureItem = {\n                        name: structPath.pop()!,\n                        type: \"module\",\n                        id: moduleItem.id,\n                        isPackage: moduleItem.is_package,\n                        fullName: moduleItem.name,\n                        codePath: `modules/${moduleItem.name}`,\n                    };\n                    break;\n                }\n\n                case \"server_module\": {\n                    const moduleItem = item as ModuleItemYaml;\n                    root = app.codeStructure.serverCode;\n                    structPath = moduleItem.name.split(\".\");\n                    structureItem = {\n                        name: structPath.pop()!,\n                        type: \"server_module\",\n                        id: moduleItem.id,\n                        isPackage: moduleItem.is_package,\n                        fullName: moduleItem.name,\n                        codePath: `server_modules/${moduleItem.name}`,\n                    };\n                    break;\n                }\n\n                case \"script\": {\n                    const scriptItem = item as ScriptItemYaml;\n                    root = app.codeStructure.scripts;\n                    structPath = [];\n                    structureItem = {\n                        name: scriptItem.name,\n                        type: \"script\",\n                        id: scriptItem.id,\n                        fullName: scriptItem.name,\n                        codePath: `scripts/${scriptItem.name}`,\n                    };\n                    break;\n                }\n\n                case \"asset\": {\n                    const assetItem = item as AssetItemYaml;\n                    root = app.codeStructure.assets;\n                    structPath = assetItem.name.split(\"/\");\n                    structureItem = {\n                        name: structPath.pop()!,\n                        type: \"asset\",\n                        id: assetItem.id,\n                        isPackage: assetItem.is_package,\n                        fullName: assetItem.name,\n                        codePath: `assets/${assetItem.name}`,\n                    };\n                    break;\n                }\n\n                default:\n                    throw new Error(`Cannot create items of type ${itemType} yet.`);\n            }\n            addToFileHierarchy(root, structureItem!, structPath);\n        });\n\n        if (!structureItem) {\n            throw new Error(\"undefined structure item\");\n        }\n\n        dispatch(markAppPathUnsaved([\"CODE\", codePath]));\n        if (getTyAnalysisEnabled(getState()) && [\"form\", \"module\", \"server_module\"].includes(itemType)) {\n            void dispatch(autocompleter.refreshItemMetadata());\n        }\n        return structureItem;\n    };\n\nconst structureRootByItemType = (structure: AppCodeStructure, type: StructureItem[\"type\"]) =>\n    ({\n        form: structure[\"clientCode\"],\n        module: structure[\"clientCode\"],\n        server_module: structure[\"serverCode\"],\n        asset: structure[\"assets\"],\n        folder: structure[\"assets\"],\n        script: structure[\"scripts\"],\n    })[type];\n\nconst CODE_TYPES = [\"form\", \"module\", \"server_module\"] as CodeStructureType[];\nconst isCodeItemType = (type: CodeStructureType): type is CodeItemType => CODE_TYPES.includes(type);\n\nexport const deleteCodeItem =\n    (item: StructureItem, requireConfirmation = false): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = getAppId(state)!;\n\n        if (\n            requireConfirmation &&\n            !(await dispatch(\n                confirm(\n                    \"Delete item?\",\n                    `Are you sure you want to delete ${item.fullName}?`,\n                    { text: \"Delete\", variant: \"danger\" },\n                    \"Cancel\"\n                )\n            ))\n        ) {\n            return;\n        }\n\n        const startupItemFullName = getAppStartupItem(state)?.module;\n        const possibleStartupItems: StructureItem[] = [];\n        const changes = {\n            codePaths: [] as CodePath[],\n            formNames: [] as string[],\n            changedAppPaths: [] as AppPath[],\n            autocompleter: [] as [CodeItemType, string][],\n            closeTabs: [] as CodeTab[],\n            recentlyOpenedTabs: [] as CodeTab[],\n            codeItems: [] as {\n                codePath: CodePath;\n                type: StructureItem[\"type\"];\n                fullName: string;\n                cacheKey: string | undefined;\n                id?: string;\n            }[],\n            startupItem: false,\n            assets: [] as string[],\n        };\n\n        const getDeleteItemStateChanges = async ({ id, codePath, type, fullName, children }: StructureItem) => {\n            let cacheKey: string | undefined;\n            // asset folders don't have codePaths\n            if (codePath) {\n                // we have to open the item in order to delete it - ok for now\n                await dispatch(openCodeItem(codePath));\n                cacheKey = getCacheKey([\"CODE\", codePath], state);\n                changes.codePaths.push(codePath);\n                changes.changedAppPaths.push([\"CODE\", codePath]);\n            }\n            changes.codeItems.push({ codePath, type, fullName, cacheKey, id });\n\n            const tab = getTabByCodePath(state, codePath);\n            if (tab) {\n                changes.closeTabs.push(tab as CodeTab);\n            } else {\n                changes.recentlyOpenedTabs.push({ navTarget: { type: \"CODE\", codePath, appId }, id: 0 });\n            }\n\n            if (isCodeItemType(type)) {\n                changes.autocompleter.push([type, fullName]);\n                if (fullName === startupItemFullName) {\n                    changes.startupItem = true;\n                }\n            }\n            if (type === \"asset\") {\n                changes.assets.push(fullName);\n            }\n            if (type === \"form\") {\n                changes.formNames.push(fullName);\n            }\n\n            for (const c of children ?? []) {\n                await getDeleteItemStateChanges(c);\n            }\n        };\n\n        await getDeleteItemStateChanges(item);\n\n        if (changes.startupItem) {\n            possibleStartupItems.push(...getForms(state), ...getModules(state));\n            changes.changedAppPaths.push([\"SETTINGS\", \"startup_form\"], [\"SETTINGS\", \"startup\"]);\n        }\n\n        dispatch(forceCloseTabs(...changes.closeTabs.map(({ id }) => id)));\n        dispatch(removeRecentlyOpened(...changes.closeTabs, ...changes.recentlyOpenedTabs));\n\n        updateState(({ app, itemCache, editHistory }) => {\n            if (!app) return;\n            const rootItem = changes.codeItems[0];\n            const root = structureRootByItemType(app.codeStructure, rootItem.type);\n            const rootCodePath = rootItem.codePath ?? getItemCodePath(rootItem.type, { name: rootItem.fullName });\n            // we should only have to do this on the first codeItem, since all other codeItems descend from this one\n            removeFromFileHierarchy(root, rootCodePath);\n\n            for (const { cacheKey, fullName, type, id } of changes.codeItems) {\n                if (cacheKey) {\n                    // Mark the item deleted in the cache\n                    let item;\n                    if (type === \"form\") {\n                        item = { class_name: fullName, id, code: \"\" };\n                    } else {\n                        item = { name: fullName, id, content: \"\" };\n                    }\n                    _cache[itemCache[cacheKey]] = {\n                        item,\n                        deleted: true,\n                        itemType: type,\n                    } as CodeItem;\n                    delete editHistory[cacheKey];\n                }\n            }\n\n            if (changes.startupItem) {\n                const newStartupItem = possibleStartupItems.find((i) => !changes.codePaths.includes(i.codePath));\n                if (newStartupItem) {\n                    delete app.config.startup_form;\n                    app.config.startup = {\n                        type: newStartupItem.type as StartupItemType,\n                        module: newStartupItem.fullName,\n                    };\n                } else {\n                    delete app.config.startup_form;\n                    delete app.config.startup;\n                }\n            }\n        });\n\n        // A deleted script's script_config entry (client-callable permissions) goes with it\n        const scriptConfig = getAppConfig(getState())?.script_config ?? {};\n        const deletedScriptNames = changes.codeItems.filter(({ type }) => type === \"script\").map((i) => i.fullName);\n        const newScriptConfig = omit(scriptConfig, deletedScriptNames);\n        if (!isEqual(newScriptConfig, scriptConfig)) {\n            await dispatch(updateAppConfig([\"script_config\"], newScriptConfig));\n        }\n\n        const updatedFormCodePaths: CodePath[] = [];\n\n        const updateYaml = async (f: CodeItem, updates: string[][]) => {\n            if (!updates.length) return;\n            const updatedFormItem = cloneDeep(f.item) as FormItemYaml;\n            for (const objPath of updates) {\n                let obj: any = updatedFormItem;\n                for (const p of dropRight(objPath)) {\n                    obj = obj[p];\n                }\n                const lastKey = last(objPath);\n                if (lastKey === undefined) {\n                    throw new Error(\"Bad path\");\n                }\n                delete obj[lastKey];\n            }\n            updatedFormCodePaths.push(`forms/${updatedFormItem.class_name}`);\n            await dispatch(updateCodeItem(`forms/${updatedFormItem.class_name}`, updatedFormItem, f.conflicts));\n        };\n\n        const updateAllForms = async (walk: (c: FormItemYaml, path?: string[]) => string[][]) => {\n            const allFormItems = await dispatch(loadAllForms());\n            for (const f of allFormItems) {\n                const updates = walk(f.item);\n                await updateYaml(f, updates);\n            }\n        };\n\n        if (changes.assets.length) {\n            const iconToFullName = (icon?: string) => icon?.replace(\"asset:\", \"\");\n            const checkToolboxIcon = (component: FormItemYaml, objectPath: string[] = []) => {\n                const updates: string[][] = [];\n                const { toolbox_item = {}, layout_metadata = {} } = component;\n                const { icon: toolboxIcon = {} } = toolbox_item;\n                const { thumbnail: layoutThumbnail } = layout_metadata;\n                const newToolboxIcon = { ...toolboxIcon };\n                const newLayoutMetaData = { ...layout_metadata };\n                const checkThumbnail = () => {\n                    const asset = iconToFullName(layoutThumbnail);\n                    if (asset && changes.assets.includes(asset)) {\n                        updates.push([...objectPath, \"layout_metadata\", \"thumbnail\"]);\n                        delete newLayoutMetaData.thumbnail;\n                        return true;\n                    }\n                };\n                const checkIcon = (theme: \"light\" | \"dark\") => {\n                    const icon = toolboxIcon[theme];\n                    const asset = iconToFullName(icon);\n                    if (asset && changes.assets.includes(asset)) {\n                        updates.push([...objectPath, \"toolbox_item\", \"icon\", theme]);\n                        delete newToolboxIcon[theme];\n                        return true;\n                    }\n                };\n                const hasThumbnail = checkThumbnail();\n                const hasLightIcon = checkIcon(\"light\");\n                const hasDarkIcon = checkIcon(\"dark\");\n                if (updates.length) {\n                    const newComponent = { ...component };\n                    if (hasLightIcon || hasDarkIcon) {\n                        newComponent.toolbox_item = { ...toolbox_item, icon: newToolboxIcon };\n                    }\n                    if (hasThumbnail) {\n                        newComponent.layout_metadata = { ...newLayoutMetaData };\n                    }\n                    dispatch(updateCodeStructureCustomComponent(getItemCodePath(\"form\", component), newComponent));\n                }\n                return updates;\n            };\n            await updateAllForms(checkToolboxIcon);\n        }\n        if (updatedFormCodePaths.length > 0) {\n            updateState((state) => {\n                stateUpdateForceReloadAllForms(state);\n                for (const p of updatedFormCodePaths) {\n                    stateUpdateForceReloadOpenTabs(state, p);\n                }\n            });\n        }\n\n        if (!getTyAnalysisEnabled(getState())) {\n            for (const [type, fullName] of changes.autocompleter) {\n                autocompleter.deleteItem(type, fullName);\n            }\n        }\n        dispatch(markAppPathsUnsaved(changes.changedAppPaths));\n        // TODO - if an open tab is in a nested edit state, we should change its navTarget.topLevelClassName to itself\n        // when the topLevelClassName was deleted\n        for (const formName of changes.formNames) {\n            dispatch(\n                clearInPlaceEditTarget(\n                    { type: \"CODE\", topLevelFormClassName: formName, codePath: `forms/${formName}` },\n                    []\n                )\n            );\n        }\n        const tabs = getState().editor.tabs;\n        for (const tab of tabs) {\n            if (tab.navTarget.type === \"CODE\") {\n                const topLevelFormClassName = tab.navTarget.topLevelFormClassName;\n                if (!topLevelFormClassName) continue;\n                if (changes.formNames.includes(topLevelFormClassName)) {\n                    dispatch(\n                        updateTab(tab, {\n                            navTarget: { ...tab.navTarget, topLevelFormClassName: undefined, editingPath: undefined },\n                        })\n                    );\n                }\n            }\n        }\n        if (getTyAnalysisEnabled(getState()) && changes.autocompleter.length) {\n            void dispatch(autocompleter.refreshItemMetadata());\n        }\n    };\n\nexport const duplicateForm =\n    (form: StructureItem): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const pkgPrefix = dropRight(form.fullName.split(\".\")).join(\".\");\n        const codeItem = await dispatch(openCodeItem(form.codePath));\n        if (codeItem === null) return;\n        await dispatch(addForm(codeItem.item as FormItemYaml, form.name, pkgPrefix, true, false, false));\n    };\n\nexport const renameCodeItem =\n    (item: StructureItem, name: string, options?: { subscribe(listener: () => void): () => void }): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        if (getTyAnalysisEnabled(getState()) && [\"form\", \"module\", \"server_module\"].includes(item.type)) {\n            if (!options) throw new Error(\"Resource rename requires its app store subscription.\");\n            const original = {\n                appId: getAppId(getState()),\n                codePath: item.codePath,\n                id: item.id,\n                fullName: item.fullName,\n            };\n            await dispatch(loadWorkspaceRenameSources());\n            const appId = getAppId(getState());\n            const current = [...getForms(getState()), ...getModules(getState()), ...getServerModules(getState())].find(\n                (item) => item.codePath === original.codePath\n            );\n            if (\n                !appId ||\n                appId !== original.appId ||\n                current?.id !== original.id ||\n                current?.fullName !== original.fullName\n            )\n                throw new Error(\"Original rename target changed. Retry rename.\");\n            const answer = await dispatch(\n                requestPythonResourceRename<AnvilWorkspaceEdit>(original.codePath, {\n                    newName: name,\n                    signal: new AbortController().signal,\n                })\n            );\n            if (!answer?.isCurrent()) throw new Error(\"App changed during rename. Retry rename.\");\n            await applyPythonRename(answer, { appId, dispatch, getState, subscribe: options.subscribe });\n            return;\n        }\n        const pathSep = item.type === \"asset\" || item.type === \"folder\" ? \"/\" : \".\";\n        const newFullName = [...dropRight(item.fullName.split(pathSep)), name].join(pathSep);\n        await dispatch(doFullRename(item, newFullName, name));\n    };\nexport const dropFileAndRestructure =\n    (file: StructureItem, target: Pick<StructureItem, \"fullName\">, rootName: string): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const { fullName: targetFullName } = target;\n        const confirmed = await dispatch(\n            confirm(\"Move File\", `Are you sure you want to move ${file.name} into ${targetFullName || rootName}`)\n        );\n        if (!confirmed) {\n            return;\n        }\n        if (targetFullName) {\n            const pathSep = file.type === \"asset\" || file.type === \"folder\" ? \"/\" : \".\";\n            await dispatch(doFullRename(file, targetFullName + pathSep + file.name, file.name));\n        } else {\n            await dispatch(doFullRename(file, file.name, file.name)); // we're moving it to parent directory\n        }\n    };\n\nconst checkNameClash =\n    (item: StructureItem, fullName: string, name: string): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const state = getState();\n        let match;\n        if (item.type === \"asset\") {\n            const appAssets = getAppAssets(state);\n            match = appAssets.find((a) => a.fullName === fullName);\n        } else if (item.type === \"folder\") {\n            const appAssetFolders = getAppAssets(state).map((a) => ({\n                name: a.fullName.substr(0, a.fullName.lastIndexOf(\"/\")),\n            }));\n            match = appAssetFolders.find((a) => a.name === fullName);\n        } else {\n            const allForms = getForms(state);\n            const allModules = getModules(state);\n            const allServerModules = getServerModules(state);\n            const allCodeItemNames = [...allForms, ...allModules, ...allServerModules];\n            match = allCodeItemNames.find((c) => c.fullName === fullName);\n        }\n        if (match) {\n            throw new Error(\"Name already exists. Please choose a different name.\");\n        }\n    };\n\n// We have already checked whether it is a valid python identifier\nconst doFullRename =\n    (item: StructureItem, fullName: string, name: string): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = getAppId(state);\n        if (!appId) return;\n        let oldLogo = getAppMetadata(state)?.logo_img ?? null;\n        if (oldLogo?.startsWith(\"asset:\")) {\n            oldLogo = oldLogo.replace(\"asset:\", \"\");\n        } else {\n            oldLogo = null;\n        }\n        let newLogo = oldLogo;\n\n        dispatch(checkNameClash(item, fullName, name));\n\n        // fix the ending of the asset name that was changed\n        if (item.type === \"asset\") {\n            const oldFullName = item.fullName;\n            if (!name.includes(\".\") && oldFullName.includes(\".\")) {\n                const ending = oldFullName.slice(oldFullName.lastIndexOf(\".\"));\n                name += ending;\n                fullName += ending;\n            }\n        }\n\n        const pathSep = item.type === \"asset\" || item.type === \"folder\" ? \"/\" : \".\";\n        const newPrefix = fullName;\n        const currentPrefix = item.fullName;\n        const matcher = new RegExp(`^${escapeRegExp(currentPrefix)}(${pathSep === \".\" ? \"\\\\.\" : \"/\"}.*)?$`);\n        let navTargetReplacement: NavTarget | null = null;\n        const oldToNewFullNames: Record<string, string> = {};\n\n        const cacheEntriesToRename: Record<string, { newFullName: string; itemType: CodeItemType }> = {};\n        const renameItemAndChildrenReturningChangedAppPaths = async (\n            { codePath, type, children, fullName }: StructureItem,\n            isParent?: boolean\n        ) => {\n            const appPath = [\"CODE\", codePath];\n            const cacheKey = getCacheKey(appPath, state);\n            const nameKey = type === \"form\" ? \"class_name\" : (\"name\" as const);\n\n            // Actually get the new names for this item\n            const oldFullName = fullName;\n            const newFullName = oldFullName.replace(matcher, `${newPrefix}$1`);\n            oldToNewFullNames[oldFullName] = newFullName;\n            const newName = last(newFullName.split(pathSep))!;\n\n            // update the logo name in the appConfig at the end of this function\n            // doing it now is too early since we haven't updated the names yet!\n            if (oldFullName === oldLogo) {\n                newLogo = newFullName;\n            }\n            if (oldFullName === newFullName) {\n                return [];\n            }\n            if (codePath) {\n                await dispatch(openCodeItem(codePath)); // We have to open the item in order to rename it. This is OK for now.\n            }\n\n            let codeItemsToUpdate = [{ codePath, oldFullName, newFullName, newName, nameKey, cacheKey, type } as const];\n\n            for (const child of children || []) {\n                if (matcher.test(child.fullName)) {\n                    codeItemsToUpdate = [\n                        ...codeItemsToUpdate,\n                        ...(await renameItemAndChildrenReturningChangedAppPaths(child)),\n                    ];\n                }\n            }\n\n            return codeItemsToUpdate;\n        };\n\n        const codeItemsToUpdate = await renameItemAndChildrenReturningChangedAppPaths(item, true);\n\n        const changedAppPaths: AppPath[] = [];\n        updateState((state) => {\n            const structureItemsByName = getCodeNames(state);\n            for (const { oldFullName, newFullName, newName, codePath, nameKey, cacheKey, type } of codeItemsToUpdate) {\n                const structureItem = structureItemsByName[oldFullName];\n                // Rename the item in the code structure, so we don't have to reload from scratch. Note that this is strictly a file rename, not a move. Moves are recrafted later.\n                structureItem.fullName = newFullName; //structureItem.fullName.replace(matcher, `${newPrefix}$1`);\n                structureItem.name = newName; //last(structureItem.fullName.split(pathSep));\n\n                if (type !== \"folder\" && codePath) {\n                    const itemCache = state.itemCache;\n                    if (!(cacheKey in itemCache)) {\n                        throw new Error(`Cannot rename item not in cache: ${cacheKey}`);\n                    }\n                    const cacheEntry = _cache[itemCache[cacheKey]];\n                    const cacheItem = cacheEntry.item;\n                    cacheEntriesToRename[oldFullName] = { newFullName, itemType: cacheEntry.itemType };\n\n                    if (!cacheItem.id) {\n                        // Renames rely on items being updated by ID. It's a bit ikky checking that here, but by the time we get to calculateUpdates, we don't know that this was a rename.\n                        throw new Error(\n                            `Cannot rename item without ID: ${cacheItem.class_name || cacheItem.name || cacheKey}`\n                        );\n                    }\n                    if (type === \"form\") {\n                        renameFormCode(cacheItem as FormItemYaml, oldFullName, newName, getAppConfig(state)!);\n                    }\n                    cacheItem[nameKey] = newFullName;\n                    const newCodePath = getItemCodePath(type, cacheItem);\n                    const newAppPath: ChangedCodePath = [\"CODE\", newCodePath];\n                    const newCacheKey = getCacheKey(newAppPath, state);\n                    itemCache[newCacheKey] = _cacheKey++;\n                    _cache[itemCache[newCacheKey]] = cacheEntry;\n\n                    if (state.viewCache[appId]?.[codePath]) {\n                        state.viewCache[appId][newCodePath] = state.viewCache[appId]?.[codePath];\n                        delete state.viewCache[appId]?.[codePath];\n                    }\n\n                    /**\n                     * Keep a reference to the old cachekey allows us to handle browser navigation\n                     * The tab title will be correct with an empty tab body\n                     * @todo possibly redirect to the new form on browser navigation\n                     */\n                    const item =\n                        type === \"form\" ? { class_name: oldFullName, code: \"\" } : { name: oldFullName, content: \"\" };\n                    _cache[itemCache[cacheKey]] = {\n                        itemType: type,\n                        item,\n                        deleted: true,\n                        renamed: true,\n                        redirect: newCacheKey,\n                    } as CodeItem;\n                    const itemEditHistory = state.editHistory[cacheKey];\n                    delete state.editHistory[cacheKey];\n                    if (itemEditHistory) {\n                        state.editHistory[newCacheKey] = itemEditHistory;\n                    }\n\n                    // Edit the item in the code structure\n                    structureItem.codePath = newCodePath;\n\n                    // Update any tabs that have this file open\n\n                    // the tab url might be in a nested state so use getTabByCodePath\n                    let tab = getTabByCodePath(state, codePath) as CodeTab | undefined;\n                    if (!tab) {\n                        // also check recently opened\n                        tab = state.editor.recentlyOpened[appId]?.find(\n                            (t) => t.navTarget.type === \"CODE\" && t.navTarget.codePath === codePath\n                        ) as CodeTab | undefined;\n                    }\n\n                    if (tab) {\n                        recentlyOpenedUpdater(state.editor.recentlyOpened[appId], tab, true);\n                        console.log(\"Found tab\", tab);\n                        tab.navTarget.codePath = newCodePath;\n                        tab.title = generateTitleFromCodeTabItem(tab, cacheItem);\n                        tab.forceReload = (tab.forceReload ?? 0) + 1;\n                        const currentTabId = getCurrentTabId(state); // Hmm. This selector is safe, but we shouldn't really be using a selector inside updateState.\n                        if (currentTabId === tab.id) {\n                            navTargetReplacement = current(tab.navTarget)!;\n                        }\n                    }\n                    changedAppPaths.push(newAppPath);\n                }\n            }\n        });\n\n        // Update startup item if required\n        const currentStartupItem = getAppStartupItem(getState());\n        const currentStartupModule = currentStartupItem?.module;\n        if (currentStartupModule && currentStartupModule in oldToNewFullNames) {\n            await dispatch(\n                setAppStartupItem({\n                    type: currentStartupItem.type,\n                    fullName: oldToNewFullNames[currentStartupModule],\n                })\n            );\n        }\n\n        // A renamed script's script_config entry (client-callable permissions) follows it\n        const scriptConfig = getAppConfig(getState())?.script_config ?? {};\n        const newScriptConfig = { ...scriptConfig };\n        for (const { type, oldFullName, newFullName } of codeItemsToUpdate) {\n            if (type === \"script\" && oldFullName in newScriptConfig) {\n                newScriptConfig[newFullName] = newScriptConfig[oldFullName];\n                delete newScriptConfig[oldFullName];\n            }\n        }\n        if (!isEqual(newScriptConfig, scriptConfig)) {\n            await dispatch(updateAppConfig([\"script_config\"], newScriptConfig));\n        }\n\n        type Path = (string | number)[];\n        type UpdatePath = [Path, any];\n        const appPackageName = getAppConfig(getState())?.package_name;\n        const renameCustomComponentSpecForLocalFormRename = (customComponentSpec?: string) =>\n            renameLocalFormInCustomComponentSpec(customComponentSpec, oldToNewFullNames, appPackageName);\n        const renameFormPropertySpecForLocalFormRename = (formPropertySpec?: string) =>\n            renameLocalFormInFormPropertySpec(formPropertySpec, oldToNewFullNames, appPackageName);\n\n        const updateYaml = async (f: CodeItem, updates: UpdatePath[]) => {\n            if (!updates.length) return;\n            const updatedFormItem = cloneDeep(f.item) as FormItemYaml;\n            for (const [objPath, newValue] of updates) {\n                let obj: any = updatedFormItem;\n                for (const p of dropRight(objPath)) {\n                    obj = obj[p];\n                }\n                const lastKey = last(objPath);\n                if (lastKey === undefined) {\n                    throw new Error(\"bad path\");\n                }\n                obj[lastKey] = newValue;\n            }\n            if (updatedFormItem.save_as_html || updatedFormItem.edit_as_html) {\n                const state = getState();\n                updatedFormItem.serialized_html = updateSerializedHtml(updatedFormItem, state);\n            }\n            updatedFormCodePaths.push(`forms/${f.item.class_name}`);\n            await dispatch(updateCodeItem(`forms/${f.item.class_name}`, updatedFormItem, f.conflicts));\n        };\n\n        const updateAllForms = async <T>(walk: (c: T, updates?: Path) => UpdatePath[]) => {\n            const allFormItems = await dispatch(loadAllForms());\n            for (const f of allFormItems) {\n                const updates = walk(f.item as T);\n                const renamedLayoutSpec = renameCustomComponentSpecForLocalFormRename(f.item.layout?.type);\n                if (renamedLayoutSpec) {\n                    updates.push([[\"layout\", \"type\"], renamedLayoutSpec]);\n                }\n                const renamedContainerSpec = renameCustomComponentSpecForLocalFormRename(f.item.container?.type);\n                if (renamedContainerSpec) {\n                    updates.push([[\"container\", \"type\"], renamedContainerSpec]);\n                }\n                await updateYaml(f, updates);\n            }\n        };\n\n        const updatedFormCodePaths: CodePath[] = [];\n        if (item.type === \"form\" || (item.type === \"module\" && item.isPackage)) {\n            // Local form renames preserve each existing spec shape: legacy\n            // customComponentSpec/formPropertySpec values stay legacy, and\n            // package-qualified values stay package-qualified. This traversal\n            // only finds YAML locations that can refer to the renamed local form.\n            const walk = (component: ComponentYaml | FormItemYaml, objectPath: Path = []) => {\n                let updates: UpdatePath[] = [];\n                let componentTypeName;\n                if (\"type\" in component) {\n                    const itemTemplate = component.properties?.[\"item_template\"];\n                    const renamedItemTemplate =\n                        component.type === \"RepeatingPanel\" && typeof itemTemplate === \"string\"\n                            ? renameFormPropertySpecForLocalFormRename(itemTemplate)\n                            : null;\n                    if (renamedItemTemplate) {\n                        updates.push([[...objectPath, \"properties\", \"item_template\"], renamedItemTemplate]);\n                    }\n                    if ((componentTypeName = renameCustomComponentSpecForLocalFormRename(component.type))) {\n                        updates.push([[...objectPath, \"type\"], componentTypeName]);\n                    }\n                }\n\n                let i = 0;\n                for (const c of component.components || []) {\n                    updates = [...updates, ...walk(c, [...objectPath, \"components\", i])];\n                    i++;\n                }\n\n                if (\"components_by_slot\" in component) {\n                    for (const [slot, slot_components] of Object.entries(component.components_by_slot || {})) {\n                        let i = 0;\n                        for (const c of slot_components) {\n                            updates = [...updates, ...walk(c, [...objectPath, \"components_by_slot\", slot, i])];\n                            i++;\n                        }\n                    }\n                }\n                if (\"slots\" in component) {\n                    for (const [slot, slotDef] of Object.entries(component.slots || {})) {\n                        if (slotDef.template) {\n                            updates = [\n                                ...updates,\n                                ...walk(slotDef.template, [...objectPath, \"slots\", slot, \"template\"]),\n                            ];\n                        }\n                    }\n                }\n\n                return updates;\n            };\n            await updateAllForms(walk);\n        }\n        if (item.type === \"asset\" || item.type === \"folder\") {\n            const iconToFullName = (icon?: string) => icon?.replace(\"asset:\", \"\");\n            const checkToolboxIcon = (component: FormItemYaml, objectPath: Path = []) => {\n                const updates: [Path, any][] = [];\n                const { toolbox_item = {}, layout_metadata = {} } = component;\n                const { icon: toolboxIcon = {} } = toolbox_item;\n                const { thumbnail: layoutThumbnail } = layout_metadata;\n                const newToolboxIcon = { ...toolboxIcon };\n                let newThumbnail = layoutThumbnail;\n                const checkThumbnail = () => {\n                    const asset = iconToFullName(layoutThumbnail);\n                    if (asset && asset in oldToNewFullNames) {\n                        newThumbnail = \"asset:\" + oldToNewFullNames[asset];\n                        updates.push([[...objectPath, \"layout_metadata\", \"thumbnail\"], newThumbnail]);\n                        return true;\n                    }\n                };\n                const checkIcon = (theme: \"light\" | \"dark\") => {\n                    const icon = toolboxIcon[theme];\n                    const asset = iconToFullName(icon);\n                    if (asset && asset in oldToNewFullNames) {\n                        const newIcon = \"asset:\" + oldToNewFullNames[asset];\n                        updates.push([[...objectPath, \"toolbox_item\", \"icon\", theme], newIcon]);\n                        newToolboxIcon[theme] = newIcon;\n                        return true;\n                    }\n                };\n                const hasLightIcon = checkIcon(\"light\");\n                const hasDarkIcon = checkIcon(\"dark\");\n                const hasThumbnail = checkThumbnail();\n\n                if (updates.length) {\n                    const newComponent = { ...component };\n                    if (hasLightIcon || hasDarkIcon) {\n                        newComponent.toolbox_item = { ...toolbox_item, icon: newToolboxIcon };\n                    }\n                    if (hasThumbnail) {\n                        newComponent.layout_metadata = { ...layout_metadata, thumbnail: newThumbnail };\n                    }\n                    dispatch(updateCodeStructureCustomComponent(getItemCodePath(\"form\", component), newComponent));\n                }\n                return updates;\n            };\n            await updateAllForms(checkToolboxIcon);\n        }\n\n        for (const [oldFullName, { newFullName, itemType }] of Object.entries(cacheEntriesToRename)) {\n            if ([\"form\", \"module\", \"server_module\"].indexOf(itemType) > -1) {\n                autocompleter.renameItem(itemType, oldFullName, newFullName);\n            }\n        }\n\n        if (navTargetReplacement) {\n            await dispatch(navigate(navTargetReplacement, true));\n        }\n\n        // graft the updated file dropped onto the correct place in the codeStructure\n        // by removing it and then adding it to the heirarchy\n        updateState((state) => {\n            if (!state.app) return;\n            const structureItemsByName = getCodeNames(state);\n            const structureItem = structureItemsByName[fullName];\n            const { type } = structureItem;\n            let { codePath } = structureItem;\n            // asset folders don't have codePaths\n            codePath ||= getItemCodePath(type, { name: fullName });\n\n            const root = structureRootByItemType(state.app.codeStructure, type);\n            if (removeFromFileHierarchy(root, codePath)) {\n                const namePrefix = `${type}s/`;\n                const splitCodePath = codePath.replace(namePrefix, \"\").split(pathSep);\n                splitCodePath.pop(); // remove the name\n                addToFileHierarchy(root, cloneDeep(structureItem), splitCodePath, namePrefix);\n            }\n        });\n\n        if (oldLogo !== newLogo) {\n            dispatch(updateAppConfig([\"metadata\", \"logo_img\"], \"asset:\" + newLogo));\n        }\n        if (updatedFormCodePaths.length > 0) {\n            updateState((state) => {\n                stateUpdateForceReloadAllForms(state);\n                for (const p of updatedFormCodePaths) {\n                    stateUpdateForceReloadOpenTabs(state, p);\n                }\n            });\n        }\n\n        dispatch(markAppPathsUnsaved(changedAppPaths));\n        // Invalidate old paths too. Mark the rename unsaved first so the designer waits for its save.\n        updateState(({ editor }) => {\n            for (const { codePath, type } of codeItemsToUpdate) {\n                if (codePath && type !== \"folder\") {\n                    updateEditorSequenceAppPaths(editor, [\"CODE\", codePath]);\n                }\n            }\n        });\n        const isNewDesigner = getShowNewDesigner(state);\n        // update the redirect urls\n        if ([\"form\", \"module\"].includes(item.type)) {\n            const oldNames = Object.keys(cacheEntriesToRename);\n\n            for (const [formName, { newFullName }] of Object.entries(cacheEntriesToRename)) {\n                dispatch(\n                    updateInPlaceEditTarget(\n                        { type: \"CODE\", topLevelFormClassName: formName, codePath: `forms/${formName}` },\n                        [],\n                        isNewDesigner ? { topLevelFormClassName: newFullName } : { codePath: `forms/${newFullName}` }\n                    )\n                );\n            }\n            if (isNewDesigner) {\n                const tabs = getState().editor.tabs;\n                for (const tab of tabs) {\n                    if (tab.navTarget.type === \"CODE\") {\n                        const topLevelFormClassName = tab.navTarget.topLevelFormClassName;\n                        if (!topLevelFormClassName) continue;\n                        if (oldNames.includes(topLevelFormClassName)) {\n                            dispatch(\n                                updateTab(tab, {\n                                    navTarget: {\n                                        ...tab.navTarget,\n                                        topLevelFormClassName: cacheEntriesToRename[topLevelFormClassName]?.newFullName,\n                                    },\n                                })\n                            );\n                        }\n                    }\n                }\n            }\n        }\n    };\n\nconst removeFromFileHierarchy = (root: RootStructure | StructureItem, codePath: CodePath) => {\n    const children = root.children ?? [];\n    for (let i = 0; i < children.length || 0; i++) {\n        const c = children[i];\n        const childCodePath = c.codePath || getItemCodePath(c.type as CodeItemType, { name: c.fullName });\n        if (childCodePath === codePath) {\n            children.splice(i, 1);\n            return true;\n        }\n        if (removeFromFileHierarchy(c, codePath)) {\n            return true;\n        }\n    }\n};\n\nconst addToFileHierarchy = (\n    root: RootStructure | StructureItem,\n    item: StructureItem,\n    [name, ...structurePath]: string[],\n    namePrefix = \"\"\n) => {\n    root.children = root.children || [];\n    if (!name) {\n        // Path is empty - add the item to this list\n        const existingItem = root.children.find((f) => f.name === item.name);\n        if (existingItem) {\n            Object.assign(existingItem, item);\n        } else {\n            root.children.push(item);\n        }\n    } else {\n        // Path isn't empty - walk down the path, creating folders as we go\n        let child = root.children.find((f) => f.name === name);\n        if (!child) {\n            child = { name, type: \"folder\", fullName: `${namePrefix}${name}` } as StructureItem;\n            root.children.push(child);\n            addToFileHierarchy(child, item, structurePath, `${namePrefix}${name}/`);\n        } else {\n            addToFileHierarchy(child, item, structurePath, `${namePrefix}${name}/`);\n        }\n    }\n};\n\nconst updateInCodeStructure =\n    (codeStructureItem: StructureItem, updater: (cs: StructureItem) => void) =>\n    ({ app }: State) => {\n        if (!app) return;\n        const { codeStructure } = app;\n        const walk = (structureItem: StructureItem | RootStructure) => {\n            if (!isRoot(structureItem) && structureItem.codePath === codeStructureItem.codePath) {\n                updater(structureItem);\n                return true;\n            }\n            for (const c of structureItem.children || []) {\n                if (walk(c)) {\n                    return true;\n                }\n            }\n        };\n        walk(codeStructure.clientCode);\n        walk(codeStructure.serverCode);\n        walk(codeStructure.assets);\n    };\n\nconst findInCodeStructure = <T = any>(\n    codeStructure: AppCodeStructure,\n    finder: (item: RootStructure | StructureItem) => boolean | undefined\n): StructureItem[] => {\n    const walkAndFind = (item: RootStructure | StructureItem): StructureItem[] => {\n        const items = [];\n        if (finder(item)) {\n            items.push(item as unknown as StructureItem);\n        }\n        for (const c of item.children || []) {\n            items.push(...walkAndFind(c));\n        }\n        return items;\n    };\n    const items = [];\n    for (const subStructure of [\"clientCode\", \"serverCode\", \"assets\"] as const) {\n        items.push(...walkAndFind(codeStructure[subStructure]));\n    }\n    return items;\n};\n\n// TODO: Call when creating components in new designer\nexport const setInPlaceEditTarget =\n    (codePath: CodePath, target: CodeNavTarget): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ app, editor }) => {\n            const codeStructure = app!.codeStructure;\n            const items = findInCodeStructure(codeStructure, (item) => (item as StructureItem).codePath === codePath);\n            const isNewDesigner = app!.config.runtime_options?.version === 3 || !editor.designer.showClassicDesigner;\n            if (items.length > 0) {\n                if (isNewDesigner) {\n                    // items[0].inPlaceEditV3 = target; // There will only be one.\n                } else {\n                    items[0].inPlaceEdit = target; // There will only be one.\n                }\n            }\n        });\n    };\n\nexport const getInPlaceEditTarget = (app: State[\"app\"], codePath: CodePath) => {\n    if (!app) return null;\n    const isNewDesigner = true;\n    const items = findInCodeStructure(app.codeStructure, (item) => (item as StructureItem).codePath === codePath);\n    if (items.length > 0) {\n        if (isNewDesigner) {\n            return items[0].inPlaceEditV3;\n        } else {\n            return items[0].inPlaceEdit;\n        }\n    }\n    return null;\n};\n\n// Returns true for [1,2,3,4], [1,2,3], but not the other way around.\nconst arrayMatchesPrefix = (arr: any[] | null | undefined, prefix: any[] | null | undefined) => {\n    if (!arr && !prefix) {\n        return true;\n    } else if (!prefix || !arr || arr.length < prefix.length) {\n        return false;\n    } else {\n        for (let i = 0; i < prefix!.length; i++) {\n            if (arr![i] !== prefix![i]) {\n                return false;\n            }\n        }\n        return true;\n    }\n};\n\n// TODO: Call this when renaming code items, and when changing RepeatingPanel item_templates in the new designer.\nexport const updateInPlaceEditTarget =\n    (\n        navTarget: CodeNavTarget,\n        targetEditingPathPrefix: EditPath,\n        navTargetUpdates: Partial<CodeNavTarget> | null = null\n    ): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ app, editor }) => {\n            const codeStructure = app!.codeStructure;\n            const isNewDesigner = app!.config.runtime_options?.version === 3 || !editor.designer.showClassicDesigner;\n            const items = findInCodeStructure(codeStructure, (item) =>\n                isNewDesigner\n                    ? (item as StructureItem).inPlaceEditV3?.topLevelFormClassName ===\n                          navTarget.topLevelFormClassName &&\n                      (!targetEditingPathPrefix ||\n                          arrayMatchesPrefix(\n                              (item as StructureItem).inPlaceEditV3?.editingPath,\n                              targetEditingPathPrefix\n                          ))\n                    : (item as StructureItem).inPlaceEdit &&\n                      (item as StructureItem).inPlaceEdit?.codePath === navTarget.codePath &&\n                      (!targetEditingPathPrefix ||\n                          arrayMatchesPrefix((item as StructureItem).inPlaceEdit?.editingPath, targetEditingPathPrefix))\n            );\n            for (const item of items) {\n                if (navTargetUpdates) {\n                    const newTargetEditingPathPrefix = navTargetUpdates.editingPath ?? [];\n                    if (isNewDesigner) {\n                        item.inPlaceEditV3 = {\n                            ...item.inPlaceEditV3!,\n                            ...navTargetUpdates,\n                            editingPath: [\n                                ...newTargetEditingPathPrefix,\n                                ...(item.inPlaceEditV3!.editingPath ?? []).slice(newTargetEditingPathPrefix.length),\n                            ],\n                        };\n                    } else {\n                        item.inPlaceEdit = {\n                            ...item.inPlaceEdit!,\n                            ...navTargetUpdates,\n                            editingPath: [\n                                ...newTargetEditingPathPrefix,\n                                ...(item.inPlaceEdit!.editingPath ?? []).slice(newTargetEditingPathPrefix.length),\n                            ],\n                        };\n                    }\n                } else {\n                    delete item.inPlaceEdit;\n                    delete item.inPlaceEditV3;\n                }\n            }\n        });\n    };\n\n// TODO: Call this when deleting RepeatingPanels in the new designer\nexport const clearInPlaceEditTarget = (navTarget: CodeNavTarget, targetEditingPathPrefix: EditPath): AnvilAction =>\n    updateInPlaceEditTarget(navTarget, targetEditingPathPrefix, null);\n\nconst getItemCodePath = (\n    type: CodeItemType | CodeStructureType,\n    { class_name, name }: Pick<CodeItemYaml, \"name\" | \"class_name\">\n) => {\n    return `${type}s/${class_name || name}` as CodePath;\n};\nconst asExtraDirectory = (entry: string | ExtraFiles | undefined): ExtraFiles | undefined =>\n    entry !== undefined && typeof entry !== \"string\" ? entry : undefined;\nconst buildExtraDirectory = (\n    files: ExtraFiles,\n    directoryPath: string,\n    options: {\n        label: string;\n        hideRootRequirements?: boolean;\n        defaultExpanded?: boolean;\n    }\n): ExtraFileStructureItem => {\n    const hasInitializer = typeof files[\"__init__.py\"] === \"string\";\n    const children: ExtraFileStructureItem[] = [];\n\n    for (const [name, content] of Object.entries(files)) {\n        if (name === \"__init__.py\" && typeof content === \"string\") {\n            continue;\n        }\n\n        if (options.hideRootRequirements && name === \"requirements.txt\" && typeof content === \"string\") {\n            continue;\n        }\n\n        const filePath = `${directoryPath}/${name}`;\n\n        if (typeof content !== \"string\") {\n            children.push(\n                buildExtraDirectory(content, filePath, {\n                    label: name,\n                })\n            );\n            continue;\n        }\n\n        children.push({\n            name: name.endsWith(\".py\") ? name.slice(0, -3) : name,\n            fullName: filePath,\n            id: `extra_files/${filePath}`,\n            type: \"extra_file\",\n            codePath: `extra_files/${filePath}`,\n        });\n    }\n\n    if (hasInitializer) {\n        return {\n            name: options.label,\n            fullName: directoryPath,\n            id: `extra_files/${directoryPath}`,\n            type: \"extra_file\",\n            isPackage: true,\n            codePath: `extra_files/${directoryPath}/__init__.py`,\n            defaultExpanded: options.defaultExpanded,\n            children,\n        };\n    }\n\n    // Existing plain-folder nodes also omit codePath.\n    return {\n        name: options.label,\n        fullName: directoryPath,\n        id: `extra_files/${directoryPath}`,\n        type: \"folder\",\n        defaultExpanded: options.defaultExpanded,\n        children,\n    };\n};\n\nexport const buildCodeStructureFromInitialCode = (\n    initialCode: AppState[\"initialCode\"],\n    appPackageName?: string,\n    { extraFiles }: { extraFiles?: ExtraFiles } = {}\n) => {\n    const clientCode: RootStructure = { name: \"Client Code\", root: true, children: [] };\n    const serverCode: RootStructure = { name: \"Server Code\", root: true, children: [] };\n    const scripts: RootStructure = { name: \"Scripts\", root: true, children: [] };\n    const assets: RootStructure = { name: \"Assets\", root: true, children: [] };\n    const serverTests: RootStructure<ExtraFileStructureItem> = { name: \"Server Tests\", root: true, children: [] };\n    const templateMatchesForm = (templateSpec: string | undefined, formClassName: string) => {\n        if (!templateSpec) return false;\n        return (\n            templateSpec === formClassName ||\n            (appPackageName ? templateSpec === `${appPackageName}.${formClassName}` : false)\n        );\n    };\n\n    for (const f of initialCode.forms || []) {\n        let redirectLinkForm = f;\n        let inPlaceEditFormEditingPath: string[] = [];\n        let inPlaceEditFormEditingPathV3: string[] = [];\n\n        const walk = (container: FormItemYaml | ComponentYaml): string | undefined => {\n            for (const component of container.components || []) {\n                if (\n                    component.type === \"RepeatingPanel\" &&\n                    templateMatchesForm(component.properties.item_template, redirectLinkForm.class_name)\n                )\n                    return component.name;\n                const childName = walk(component);\n                if (childName) return childName;\n            }\n        };\n\n        let i = 0; // Be absolutely certain that we don't end up in an infinite loop here.\n        while (i < 100) {\n            // Try to find a RepeatingPanel somewhere that uses this form as an item_template, and link to that instead.\n\n            const formsUsingTemplate = initialCode.forms\n                .map((h) => [h, walk(h)] as const)\n                .filter(([_, n]) => n)\n                .sort(([h], [g]) =>\n                    h.container?.type === g.container?.type ? 0 : h.container?.type === \"DataRowPanel\" ? 1 : -1\n                ) as [FormItemYaml, string][];\n\n            if (formsUsingTemplate.length > 0) {\n                const [newRedirectLinkForm, newRepeatingPanelName] = formsUsingTemplate[0];\n                if (newRedirectLinkForm.class_name === redirectLinkForm.class_name) {\n                    console.log(\"Redirect loop detected while building code structure.\");\n                    break;\n                }\n                redirectLinkForm = newRedirectLinkForm;\n                const repeatingPanelName = newRepeatingPanelName;\n                inPlaceEditFormEditingPath = [repeatingPanelName, ...inPlaceEditFormEditingPath];\n                inPlaceEditFormEditingPathV3 = [repeatingPanelName, \"item_template\", ...inPlaceEditFormEditingPathV3];\n            } else {\n                break;\n            }\n            i++;\n        }\n\n        const structurePath = f.class_name.split(\".\");\n        const name = structurePath.pop()!;\n\n        const codePath = getItemCodePath(\"form\", f);\n        const item: StructureItem = {\n            name,\n            type: \"form\",\n            isPackage: f.is_package,\n            fullName: f.class_name,\n            codePath,\n            id: f.id,\n            customComponent: f.custom_component,\n            toolboxItem: f.toolbox_item,\n            helpText: f.help_text,\n            layoutMetadata: f.layout_metadata,\n            isLayout: !!f.slots,\n        };\n        if (redirectLinkForm !== f) {\n            item.inPlaceEdit = {\n                type: \"CODE\",\n                codePath: getItemCodePath(\"form\", redirectLinkForm),\n                editingPath: inPlaceEditFormEditingPath,\n            };\n            item.inPlaceEditV3 = {\n                type: \"CODE\",\n                codePath: codePath,\n                editingPath: inPlaceEditFormEditingPathV3,\n                topLevelFormClassName: redirectLinkForm.class_name,\n            };\n        }\n        addToFileHierarchy(clientCode, item, structurePath);\n    }\n\n    for (const m of initialCode.modules || []) {\n        const structurePath = m.name.split(\".\");\n        const name = structurePath.pop()!;\n\n        const codePath = getItemCodePath(\"module\", m);\n        const item: StructureItem = {\n            name,\n            type: \"module\",\n            isPackage: m.is_package,\n            fullName: m.name,\n            codePath,\n            id: m.id,\n        };\n        addToFileHierarchy(clientCode, item, structurePath);\n    }\n\n    for (const s of initialCode.server_modules || []) {\n        const structurePath = s.name.split(\".\");\n        const name = structurePath.pop()!;\n\n        const item: StructureItem = {\n            name,\n            type: \"server_module\",\n            isPackage: s.is_package,\n            fullName: s.name,\n            codePath: getItemCodePath(\"server_module\", s),\n            id: s.id,\n        };\n        addToFileHierarchy(serverCode, item, structurePath);\n    }\n\n    for (const s of initialCode.scripts ?? []) {\n        const item: StructureItem = {\n            name: s.name,\n            type: \"script\",\n            fullName: s.name,\n            codePath: getItemCodePath(\"script\", s),\n            id: s.id,\n        };\n        addToFileHierarchy(scripts, item, []);\n    }\n\n    for (const a of initialCode.theme?.assets || []) {\n        // Don't split by \".\" as asset filenames have their full path e.g. theme.css\n        const structurePath = a.name.split(\"/\");\n        const name = structurePath.pop()!;\n\n        const item: StructureItem = {\n            name,\n            type: \"asset\",\n            isPackage: a.is_package,\n            fullName: a.name,\n            codePath: getItemCodePath(\"asset\", a),\n            id: a.id,\n        };\n\n        addToFileHierarchy(assets, item, structurePath);\n    }\n\n    const testsDirectory = asExtraDirectory(extraFiles?.tests);\n    const serverTestFiles = asExtraDirectory(testsDirectory?.server_tests);\n\n    if (serverTestFiles) {\n        const rootPath = \"tests/server_tests\";\n\n        const root = buildExtraDirectory(serverTestFiles, rootPath, {\n            label: \"server_tests\",\n        });\n\n        serverTests.children.push(...(root.children ?? []));\n\n        const initializer = serverTestFiles[\"__init__.py\"];\n\n        // Extra-file contents are base64 encoded. An empty file is \"\".\n        if (typeof initializer === \"string\" && initializer !== \"\") {\n            const initializerPath = `${rootPath}/__init__.py`;\n\n            serverTests.children.push({\n                name: \"__init__\",\n                fullName: initializerPath,\n                id: `extra_files/${initializerPath}`,\n                type: \"extra_file\",\n                codePath: `extra_files/${initializerPath}`,\n            });\n        }\n    }\n\n    return { clientCode, serverCode, scripts, assets, serverTests };\n};\n\nconst getDefaultItemName =\n    (nameRoot: string, fromTemplate = true): AnvilAction<string> =>\n    (dispatch, getState) => {\n        const state = getState();\n        const allForms = getForms(state);\n        const allModules = getModules(state);\n        const allServerModules = getServerModules(state);\n        const allAssets = getAppAssets(state);\n        const allAssetFolders = allAssets.map((a) => ({ name: nth(a.fullName.split(\"/\"), -2)! })) as StructureItem[];\n        const suffix = (fromTemplate ? 1 : \"_copy\") as string;\n        let i = suffix;\n        const allCodeItemNames: Record<string, StructureItem> = {};\n        for (const item of [...allForms, ...allModules, ...allServerModules, ...allAssets, ...allAssetFolders]) {\n            allCodeItemNames[item.name] = item;\n        }\n        while (`${nameRoot}${i}` in allCodeItemNames) {\n            i += suffix;\n        }\n        return `${nameRoot}${i}`;\n    };\n\nexport const setIsPackage =\n    (\n        codeStructureItem: StructureItem,\n        isPackage: boolean,\n        options: { subscribe(listener: () => void): () => void }\n    ): AnvilAsyncAction<void> =>\n    async (dispatch, getState) => {\n        const appId = getAppId(getState());\n        const codeItem = await dispatch(openCodeItem(codeStructureItem.codePath));\n        if (!appId || appId !== getAppId(getState()) || !codeItem) throw new Error(\"Conversion target changed.\");\n        const { item } = codeItem;\n        if (!!item.is_package === isPackage) return;\n        const code =\n            getAnalysisEditors(appId)\n                .find(([, registration]) => registration.codePath === codeStructureItem.codePath)?.[0]\n                .state.doc.toString() ?? item.code;\n        if (typeof code !== \"string\") throw new Error(\"Conversion requires Python source.\");\n        await commitWorkspaceRename(prepareModuleConversion(codeStructureItem.codePath, item, { isPackage, code }), {\n            appId,\n            dispatch,\n            getState,\n            subscribe: options.subscribe,\n        });\n    };\n\n/** Currently not used as a toggle */\nexport const setSaveAsHtml =\n    (codePath: CodePath, saveAsHtml?: boolean): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const codeItem = await dispatch(openCodeItem(codePath));\n        if (codeItem === null || codeItem.itemType !== \"form\") {\n            throw new Error(\"bad code path\");\n        }\n        const { item } = codeItem;\n        // Update the actual code item\n        if (saveAsHtml) {\n            let serializedHtml = item.serialized_html;\n            if (!serializedHtml) {\n                // Normal conversion comes from edit_as_html preview, which\n                // keeps serialized_html current. This fallback handles older or\n                // unusual callers that enable save_as_html before that preview\n                // has been generated.\n                item.edit_as_html = true;\n                serializedHtml = updateSerializedHtml(item, getState(), {\n                    debugContext: { codePath },\n                });\n            }\n            item.save_as_html = true;\n            delete item.edit_as_html;\n            item.serialized_html = serializedHtml;\n            inflateHtmlFormYamlForDesigner(item, serializedHtml, { debugContext: { codePath } });\n        } else {\n            item.save_as_html = saveAsHtml;\n            delete item.serialized_html;\n        }\n        dispatch(markAppPathUnsaved([\"CODE\", codePath]));\n    };\n\nexport const setIsLayout =\n    (formCodePath: CodePath, form: FormItemYaml, isLayout?: boolean): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        if (isLayout) {\n            form.slots = {};\n            dispatch(claimAchievement(\"setComponentAsLayout\"));\n        } else {\n            delete form.slots;\n        }\n        dispatch(notifyUpdatedCodeItem(formCodePath, null)); // TODO: Did we just resolve the last conflict?\n        const formNode = getForms(getState()).find((form) => form.codePath === formCodePath);\n        if (!formNode) return;\n        updateState(\n            updateInCodeStructure(formNode, (item) => {\n                item.isLayout = isLayout;\n            })\n        );\n    };\n\nexport const toggleIsLayout =\n    (formCodePath: CodePath, form: FormItemYaml, isLayout?: boolean): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        if (form.slots) {\n            if (\n                Object.keys(form.slots).length > 0 &&\n                !(await dispatch(\n                    confirm(\n                        \"Delete slots?\",\n                        \"If you disable using this form as a layout, existing slots will be deleted. Are you sure you wish to continue?\",\n                        \"Delete slots\",\n                        \"Cancel\"\n                    )\n                ))\n            ) {\n                return;\n            }\n            await dispatch(setIsLayout(formCodePath, form, false));\n        } else {\n            await dispatch(setIsLayout(formCodePath, form, true));\n        }\n    };\n\n// This is used to update layouts too, not just custom components.\nexport function useUpdateCustomComponent(codePath: CodePath, item?: FormItemYaml, conflicts?: Conflicts) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const rerender = useRerender();\n\n    const updateCustomComponent = useCallback(\n        (updatedItem: Partial<FormItemYaml>, msg?: string) => {\n            if (!item) return;\n            const updated = { ...item, ...updatedItem };\n\n            if (updatedItem[\"custom_component\"]) {\n                dispatch(claimAchievement(\"setComponentAsCustom\"));\n            }\n            if (\n                \"custom_component\" in updatedItem ||\n                \"toolbox_item\" in updatedItem ||\n                \"layout_metadata\" in updatedItem ||\n                \"help_text\" in updatedItem\n            ) {\n                dispatch(updateCodeStructureCustomComponent(codePath, updated));\n            }\n            dispatch(updateCodeItem(codePath, updated, conflicts, msg, false, true));\n            rerender();\n        },\n        [item, conflicts, codePath, dispatch, rerender]\n    );\n    return updateCustomComponent;\n}\n\nconst TEMPLATE_RE = /^from\\s+\\._anvil_designer\\s+import\\s+([^\\s]*)Template(\\s*)$/m;\n\nconst leaf = (name: string) => {\n    return name.split(\".\").at(-1)!;\n};\n\nexport function updateTemplateImport(form: FormItemYaml, oldName: string, newName: string, appConfig: AppConfig) {\n    oldName = leaf(oldName);\n    newName = leaf(newName);\n\n    const templateLine = `from ._anvil_designer import ${newName}Template`;\n    let found = false;\n    if (form.code) {\n        form.code = form.code.replace(TEMPLATE_RE, (match, templateName, spaces) => {\n            found = true;\n            return templateName === oldName ? templateLine + spaces : match;\n        });\n    }\n    if (!found && appConfig?.runtime_options.version >= 2) {\n        form.code = templateLine + \"\\n\" + form.code;\n    }\n}\n\nconst CLASS_DEF_RENAME = /^(\\s*)class\\s+([^\\s]+)\\s*\\((.*?)([^\\s]*)Template(.*?)\\):\\s*$/m;\n\nfunction renameFormCode(form: FormItemYaml, oldName: string, newName: string, appConfig: AppConfig) {\n    oldName = leaf(oldName);\n    newName = leaf(newName);\n    if (form.code) {\n        form.code = form.code.replace(\n            CLASS_DEF_RENAME,\n            (match, spaces, className, otherBases, templateName, otherArgs) => {\n                return className === oldName && templateName === oldName\n                    ? spaces + \"class \" + newName + \"(\" + otherBases + newName + \"Template\" + otherArgs + \"):\"\n                    : match;\n            }\n        );\n    }\n    updateTemplateImport(form, oldName, newName, appConfig);\n}\n\nconst removePrelude = (currentCode: string, prelude: string, breakpoints: number[]) => {\n    const idx = currentCode.indexOf(prelude + \"\\n\");\n    if (idx === -1) {\n        return { code: currentCode, breakpoints };\n    }\n    const numLines = prelude.split(\"\\n\").length;\n    const codeBefore = currentCode.substring(0, idx);\n    const codeAfter = currentCode.substring(idx + prelude.length + 1);\n    const newCode = codeBefore + codeAfter;\n    const numLinesBefore = codeBefore.split(\"\\n\").length;\n    const newBreakPoints = breakpoints.map((bp) => {\n        if (bp < numLinesBefore) {\n            return bp;\n        } else if (bp >= numLinesBefore && bp < numLinesBefore + numLines) {\n            return undefined;\n        }\n        return bp - numLines;\n    });\n\n    return { code: newCode, breakpoints: newBreakPoints.filter((bp) => bp !== undefined) };\n};\n\ntype Prelude = string | { client?: string; server?: string; form?: string };\n// NB: we could add module if we want but unnecessary for now\ntype PreludeKey = \"client\" | \"server\" | \"form\";\n\nconst getPrelude = (prelude: Prelude | undefined, subkey: PreludeKey) => {\n    if (!prelude) {\n        return undefined;\n    }\n    if (typeof prelude === \"string\") {\n        return prelude;\n    }\n    switch (subkey) {\n        case \"client\":\n            return prelude.client;\n        case \"server\":\n            return prelude.server;\n        case \"form\":\n            return prelude.form || prelude.client;\n    }\n};\n\nconst STAR_IMPORT = /(^|\\n)from anvil import \\*\\n/m;\nconst TEMPLATE_IMPORT = /(^|\\n)from\\s+\\._anvil_designer\\s+import\\s+[^\\s]*Template\\n/m;\n\nconst applyPrelude = function (\n    currentCode: string,\n    prelude: Prelude | undefined,\n    subkey: PreludeKey,\n    options: { remove?: boolean; breakpoints?: number[] } = {}\n) {\n    const { remove = false, breakpoints = [] } = options;\n    const preludeStr = getPrelude(prelude, subkey);\n    if (!preludeStr) {\n        return { code: currentCode, breakpoints };\n    }\n    const numLines = preludeStr.split(\"\\n\").length;\n    if (remove) {\n        return removePrelude(currentCode, preludeStr, breakpoints);\n    } else {\n        if (currentCode.indexOf(preludeStr) > -1) {\n            return { code: currentCode, breakpoints };\n        }\n        let idx = 0;\n        const match = currentCode.match(STAR_IMPORT) ?? currentCode.match(TEMPLATE_IMPORT);\n        if (match) {\n            idx = (match.index ?? 0) + match[0].length;\n        }\n        const codeBefore = currentCode.substring(0, idx);\n        const codeAfter = currentCode.substring(idx);\n        const newCode = codeBefore + preludeStr + \"\\n\" + codeAfter;\n\n        const numLinesBefore = codeBefore.split(\"\\n\").length;\n\n        const newBreakPoints = breakpoints.map((bp) => {\n            if (bp < numLinesBefore) {\n                return bp;\n            }\n            return bp + numLines;\n        });\n\n        return { code: newCode, breakpoints: newBreakPoints };\n    }\n};\n\n/** reindents the code property of a code item based on the user tabsize preference */\nexport async function applyTabSizing(\n    state: State,\n    item: FormItemYaml | ModuleItemYaml,\n    { targetVersion }: { targetVersion?: RuffTargetVersion } = {}\n) {\n    item.code = await reformat(item.code, getUserTabSize(state), { targetVersion });\n}\n\nconst applyAllPreludes = function (\n    state: State,\n    newItem: FormItemYaml | ModuleItemYaml,\n    subkey: PreludeKey,\n    options: { forceServerImport?: boolean } = {}\n) {\n    const { forceServerImport = false } = options;\n    const depCode = getDependencyCode(state);\n    const services = getAppConfig(state)?.services ?? [];\n    const serviceSpecs = getServiceSpecs(state);\n    const injectPreludes = getUserAutoImport(state);\n    if (!injectPreludes) {\n        return;\n    }\n\n    for (const service of services) {\n        const source = service.source;\n        const spec = serviceSpecs[source];\n        if (spec && spec.prelude) {\n            // special case table service - don't add preludes if we don't have any tables\n            if (source === \"/runtime/services/tables.yml\" && !getHasTables(state)) continue;\n            const { code } = applyPrelude(newItem.code, spec.prelude, subkey);\n            newItem.code = code;\n        }\n    }\n\n    for (const { code_prelude } of Object.values(depCode)) {\n        if (code_prelude) {\n            const { code } = applyPrelude(newItem.code, code_prelude, subkey);\n            newItem.code = code;\n        }\n    }\n\n    // TODO: We should also do this if we have a configured uplink.\n    const codeStructure = getCodeStructure(state);\n    const uplinkVisible = getIsUplinkVisible(state);\n    console.log(\"Uplink\", uplinkVisible);\n    if (uplinkVisible || forceServerImport || (codeStructure?.serverCode?.children?.length ?? 0) > 0) {\n        const { code } = applyPrelude(newItem.code, { client: \"import anvil.server\" }, subkey);\n        newItem.code = code;\n    }\n};\n\nexport const applyPreludeToItem =\n    (\n        codePath: CodePath,\n        prelude: Prelude,\n        subkey: PreludeKey,\n        options: { remove?: boolean; sourceName?: string } = {}\n    ): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const { remove = false, sourceName } = options;\n        const state = getState();\n        const injectPreludes = getUserAutoImport(state);\n        if (!injectPreludes && !remove) {\n            // make sure we still support removing imports\n            return;\n        }\n\n        const currentBreakpoints = (getDebugEnvBreakpoints(state)[codePath]?.breaks ?? []).map((bp) => bp.l);\n\n        const codeItem = await dispatch(openCodeItem(codePath));\n        if (codeItem === null) return;\n        const { item, itemType, conflicts } = codeItem;\n        const { code, breakpoints } = applyPrelude((item as ModuleItemYaml).code, prelude, subkey, {\n            remove,\n            breakpoints: currentBreakpoints,\n        });\n        if (code !== item.code) {\n            if (!isEqual(breakpoints, currentBreakpoints)) {\n                await dispatch(setBreakpoints(codePath, breakpoints));\n            }\n            await dispatch(\n                updateCodeItem(\n                    codePath,\n                    { ...item, code },\n                    conflicts,\n                    `${remove ? \"Remove\" : \"Add\"} default imports for ${sourceName}`,\n                    true,\n                    false\n                )\n            );\n        }\n    };\n\nexport const applyCodePreludeEverywhere =\n    (prelude: Prelude | undefined, options: { sourceName?: string; remove?: boolean } = {}): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const { sourceName, remove } = options;\n        if (!prelude) return;\n\n        const state = getState();\n        const codeStructure = getCodeStructure(state);\n\n        await visitCodeStructureNodesAsync(codeStructure, async ({ type, codePath }) => {\n            switch (type) {\n                case \"form\":\n                    if (typeof prelude !== \"object\" || prelude.form || prelude.client) {\n                        await dispatch(applyPreludeToItem(codePath, prelude, \"form\", { sourceName, remove }));\n                    }\n                    break;\n                case \"module\": {\n                    if (typeof prelude !== \"object\" || prelude.client) {\n                        await dispatch(applyPreludeToItem(codePath, prelude, \"client\", { sourceName, remove }));\n                    }\n                    break;\n                }\n                case \"server_module\": {\n                    if (typeof prelude !== \"object\" || prelude.server) {\n                        await dispatch(applyPreludeToItem(codePath, prelude, \"server\", { sourceName, remove }));\n                    }\n                    break;\n                }\n\n                // Don't do anything for assets.\n            }\n        });\n    };\n\nexport const addFormWithModal = (pkgPrefix?: string | null): AnvilAsyncAction<FormItemYaml | undefined> =>\n    async function (dispatch, getState, updateState) {\n        const result = await dispatch(modal(\"chooseFormType\", {}));\n        if (result) {\n            return await dispatch(addForm(result.form, null, pkgPrefix, true, false, true, result.initialView));\n        }\n    };\n\nfunction getTemplateFormCode(code: string | null | undefined, minimal: boolean) {\n    if (!minimal) {\n        return code ?? defaultStandardFormCode;\n    }\n    // if minimal is true always return the minimal template code\n    return defaultMinimalFormCode;\n}\n\nexport const addForm = (\n    templateForm: Omit<FormItemYaml, \"id\">,\n    className: string | null,\n    pkgPrefix?: string | null,\n    navigateAfterAdd = true,\n    postponeReloadAll = false,\n    fromTemplate = true,\n    initialView?: FullView\n): AnvilAsyncAction<FormItemYaml> =>\n    async function (dispatch, getState, updateState) {\n        const class_name = dispatch(getDefaultItemName(className || templateForm.class_name || \"Form\", fromTemplate));\n        let state = getState();\n        const templateMode = getUserCodeTemplates(state);\n\n        let code = templateForm.code;\n        if (fromTemplate) {\n            code = getTemplateFormCode(code, templateMode === \"minimal\");\n        }\n        const newForm: FormItemYaml = {\n            ...cloneDeep(templateForm),\n            class_name,\n            code,\n            id: generateItemId(),\n        };\n        if (newForm.container) {\n            newForm.components = cloneDeep(templateForm.components || []);\n        }\n        if (pkgPrefix) {\n            newForm.class_name = `${pkgPrefix}.${newForm.class_name}`;\n        }\n\n        newForm.save_as_html = true;\n        canonicalizeFormSpecsInFormYaml(newForm, state);\n        newForm.serialized_html = updateSerializedHtml(newForm, state, {\n            debugContext: { codePath: getItemCodePath(\"form\", newForm) },\n            structural: true,\n        });\n\n        const oldName = fromTemplate ? \"$NAME$\" : templateForm.class_name.split(\".\").pop()!;\n        renameFormCode(newForm, oldName, newForm.class_name, getAppConfig(getState())!);\n        state = getState();\n        applyAllPreludes(state, newForm, \"form\");\n        await applyTabSizing(state, newForm);\n\n        const codePath = getItemCodePath(\"form\", newForm);\n        await dispatch(addCodeItem(codePath, \"form\", newForm));\n\n        dispatch(claimAchievement(\"addedForm\")); // No await\n\n        state = getState();\n        const config = getAppConfig(state)!;\n        if (!config.startup && !config.startup_form) {\n            // We default to the old way (\"startup_form\") in case this is a v1 app\n            // TODO: Replace this with updateApp, or something.\n            updateState(\"Update startup form\", ({ app }) => {\n                const config = app?.config;\n                if (!config) return;\n                config.startup_form = newForm.class_name;\n            });\n            // TODO: Work out how to save the startup form here.\n            dispatch(markAppPathUnsaved([\"SETTINGS\", \"startup_form\"]));\n        }\n        if (!postponeReloadAll) {\n            dispatch(forceReloadAllForms());\n        }\n        if (navigateAfterAdd) {\n            await dispatch(navigate({ type: \"CODE\", codePath, ...(initialView ? { view: initialView } : {}) }));\n        }\n\n        return newForm;\n    };\n\nfunction defaultModuleCode(name: string, pkgPrefix: string | null, isPackage: boolean) {\n    return `# This is a ${\n        isPackage ? \"package\" : \"module\"\n    }.\\n# You can define variables and functions here, and use them from any form. For example, in a top-level form:\\n#\\n#    from ..${\n        pkgPrefix || \"\"\n    } import ${name}\\n#\\n#    ${name}.say_hello()\\n#\\n\\ndef say_hello():\\n  print(\"Hello, world\")\\n`;\n}\n\nfunction defaultServerCode(isPackage: boolean) {\n    return `import anvil.server\\n\\n# This is a server ${\n        isPackage ? \"package\" : \"module\"\n    }. It runs on the Anvil server,\\n# rather than in the user's browser.\\n#\\n# To allow anvil.server.call() to call functions here, we mark\\n# them with @anvil.server.callable.\\n# Here is an example - you can replace it with your own:\\n#\\n# @anvil.server.callable\\n# def say_hello(name):\\n#   print(\"Hello, \" + name + \"!\")\\n#   return 42\\n#\\n\\n`;\n}\n\nexport const addNew =\n    (\n        type: CodeItemType | \"asset_folder\",\n        isPackage = false,\n        pkgPrefix: string | null = null,\n        forceName = \"\",\n        forceCode?: string\n    ): AnvilAsyncAction<StructureItem> =>\n    async (dispatch, getState, updateState) => {\n        // TODO: do we need this?\n        // let addingItemPkgPrefix = pkgPrefix;\n        // let addingIsPackage = isPackage;\n        // api.eventTrack('addItem', scope.appId, {label: type});\n        const state = getState();\n        const app = getApp(state);\n        const minimalTemplate = getUserCodeTemplates(state) === \"minimal\";\n        let codePath = null;\n        let structuredCodeItem;\n        switch (type) {\n            // Note 'Form' case is taken care of in addForm, above\n            case \"module\": {\n                const nameRoot = isPackage ? \"Package\" : \"Module\";\n                const newName = dispatch(getDefaultItemName(nameRoot));\n                let newFullName = newName;\n                if (pkgPrefix) {\n                    newFullName = pkgPrefix + \".\" + newName;\n                }\n\n                const newModule: ModuleItemYaml = {\n                    id: generateItemId(),\n                    is_package: isPackage,\n                    name: newFullName,\n                    code: minimalTemplate ? \"\" : defaultModuleCode(newName, pkgPrefix, isPackage),\n                };\n                applyAllPreludes(state, newModule, \"client\");\n                await applyTabSizing(state, newModule);\n\n                //updateState(`Add ${newModule.name}`, update, ['app', 'content', 'modules'], modules => modules.concat([newModule]))\n                codePath = getItemCodePath(\"module\", newModule);\n                structuredCodeItem = await dispatch(addCodeItem(codePath, \"module\", newModule));\n\n                // Do this here, rather than in addCodeItem, because this is really recording \"clicked an 'Add Module' button\",\n                // not the underlying low-level action of adding a code item, which can be caused by other internal things.\n                dispatch(claimAchievement(\"addedModule\")); // No await\n\n                break;\n            }\n            case \"server_module\": {\n                const nameRoot = isPackage ? \"ServerPackage\" : \"ServerModule\";\n                const newName = dispatch(getDefaultItemName(nameRoot));\n                let newFullName = newName;\n                if (pkgPrefix) {\n                    newFullName = pkgPrefix + \".\" + newName;\n                }\n\n                const newServerModule: ServerItemYaml = {\n                    id: generateItemId(),\n                    is_package: isPackage,\n                    name: newFullName,\n                    code: forceCode ?? (minimalTemplate ? \"import anvil.server\\n\\n\" : defaultServerCode(isPackage)),\n                };\n                applyAllPreludes(state, newServerModule, \"server\", { forceServerImport: true });\n                await applyTabSizing(state, newServerModule, {\n                    targetVersion: getRuffTargetVersion(\n                        state.app?.config.runtime_options,\n                        state.user?.python_environment_catalog,\n                        { isServer: true }\n                    ),\n                });\n\n                if (!app?.codeStructure?.serverCode?.children?.length) {\n                    // First server module, need to prelude import anvil.server\n                    // don't do this for subsequent server modules since it's annoying\n                    await dispatch(applyCodePreludeEverywhere({ client: \"import anvil.server\" }));\n                }\n\n                codePath = getItemCodePath(\"server_module\", newServerModule);\n                structuredCodeItem = await dispatch(addCodeItem(codePath, \"server_module\", newServerModule));\n\n                dispatch(claimAchievement(\"addedServerModule\")); // No await\n\n                break;\n            }\n            case \"script\": {\n                const allScriptNames = new Set(app?.codeStructure?.scripts?.children.map((i) => i.name) ?? []);\n                const nameRoot = \"Script\";\n                let i: number | undefined;\n                while (allScriptNames.has(nameRoot + (i ?? \"\"))) {\n                    i = (i ?? 0) + 1;\n                }\n\n                const newScript: ScriptItemYaml = {\n                    id: generateItemId(),\n                    name: `Script${i ?? \"\"}`,\n                    code: '# This is a Python script.\\n\\nprint(\"Hello, world!\")\\n',\n                };\n                codePath = getItemCodePath(\"script\", newScript);\n                structuredCodeItem = await dispatch(addCodeItem(codePath, \"script\", newScript));\n\n                dispatch(claimAchievement(\"addedScript\")); // No await\n\n                break;\n            }\n            case \"asset_folder\": {\n                // Create \"empty\" asset folders by creating a folder with a \".gitkeep\" file inside.\n                const nameRoot = \"Folder\";\n                const newName = forceName || dispatch(getDefaultItemName(nameRoot));\n                const newFolderName = (pkgPrefix ? pkgPrefix + \"/\" : \"\") + newName + \"/.gitkeep\";\n                const newFolder: AssetItemYaml = {\n                    name: newFolderName,\n                    content: \"\",\n                    is_package: false,\n                    id: generateItemId(),\n                };\n                codePath = getItemCodePath(\"asset\", newFolder);\n                return await dispatch(addCodeItem(codePath, \"asset\", newFolder));\n            }\n            default:\n                throw new Error(\"bad type\");\n        }\n\n        await dispatch(navigate({ type: \"CODE\", codePath }));\n        return structuredCodeItem;\n    };\n\nexport const loadAllForms = (): AnvilAsyncAction<FormItem[]> => async (dispatch, getState, updateState) => {\n    // TODO: Loading progress indicator\n    const formNodes = getForms(getState());\n    const forms: FormItem[] = [];\n    for (const node of formNodes) {\n        const form = await dispatch(openCodeItem(node.codePath));\n        // possibly null if the form was deleted\n        if (form === null) continue;\n        forms.push(form as FormItem);\n    }\n    return forms;\n};\n\nexport const visitCodeStructureNodesAsync = async (\n    codeStructure: AppCodeStructure | undefined,\n    fn: (node: StructureItem) => void | Promise<void>\n) => {\n    if (!codeStructure) return;\n    const walk = async (node: StructureItem | RootStructure) => {\n        if (!isRoot(node)) {\n            // This could be made cleverer - only pick out things we want to conflict with.\n            await fn(node);\n        }\n        for (const c of node.children || []) {\n            await walk(c);\n        }\n    };\n    await walk(codeStructure.clientCode);\n    await walk(codeStructure.serverCode);\n    await walk(codeStructure.assets);\n};\n\nexport const setAppStartupItem = (module: Pick<StructureItem, \"fullName\" | \"type\">): AnvilAsyncAction =>\n    async function (dispatch, getState, updateState) {\n        updateState(`Update app startup to ${module.type} ${module.fullName}`, (state) => {\n            if (!state.app) return;\n            delete state.app.config.startup_form;\n            state.app.config.startup = { type: module.type as StartupItemType, module: module.fullName };\n        });\n        dispatch(\n            markAppPathsUnsaved([\n                [\"SETTINGS\", \"startup_form\"],\n                [\"SETTINGS\", \"startup\"],\n            ])\n        );\n    };\n\nexport const addAssetWithModal = (pkgPrefix: string | null = null): AnvilAsyncAction<StructureItem | undefined> =>\n    async function (dispatch, getState, updateState) {\n        const asset = await dispatch(modal(\"addasset\", {}));\n        if (Array.isArray(asset)) {\n            const uploads = asset.map(({ file, path }) => ({\n                file,\n                path: pkgPrefix ? `${pkgPrefix}/${path}` : path,\n            }));\n            // Recheck after each upload: overwrite prompts can rename earlier files in this batch.\n            for (const [index, { file, path }] of uploads.entries()) {\n                const conflict = findAssetPathConflict([\n                    ...getAppAssets(getState()).map((asset) => asset.fullName),\n                    ...uploads.slice(index).map((upload) => upload.path),\n                ]);\n                if (conflict) {\n                    await dispatch(\n                        alert(\n                            \"Cannot upload assets\",\n                            `\"${conflict}\" would be both a file and a folder. Rename the file or folder and try again. ${index === 0 ? \"No files were uploaded.\" : \"Remaining files were not uploaded.\"}`\n                        )\n                    );\n                    return;\n                }\n                const directory = path.slice(0, Math.max(0, path.lastIndexOf(\"/\")));\n                await dispatch(uploadAsset(file, directory, uploads.length === 1));\n            }\n        } else if (typeof asset === \"string\") {\n            return await dispatch(createAsset(asset, pkgPrefix));\n        }\n    };\n\nconst generateValidAssetName = (baseName: string, appAssets: StructureItem[]) => {\n    let i = 1;\n    let proposedName = baseName;\n    let matchIndex;\n    while ((matchIndex = appAssets.findIndex((a) => a.name === proposedName)) > -1) {\n        const dot = baseName.lastIndexOf(\".\");\n        proposedName = baseName.slice(0, dot) + \"_\" + ++i + \".\" + baseName.slice(dot + 1);\n    }\n    return proposedName;\n};\n\nconst promptForGoodFileName =\n    (baseName: string, pkgPrefix?: string | null, allowOverwrite = true): AnvilAsyncAction<string | undefined> =>\n    async (dispatch, getState, updateState) => {\n        let proposedName = baseName;\n        let children = getCodeStructure(getState())?.assets.children || [];\n        const appAssets = getAppAssets(getState());\n        let existingAsset;\n        if (pkgPrefix) {\n            for (const part of pkgPrefix.split(\"/\")) {\n                children = children.find((a) => a.name === part)?.children ?? [];\n            }\n        }\n\n        while ((existingAsset = children?.find((a) => a.name === proposedName))) {\n            if (\n                allowOverwrite &&\n                (await dispatch(\n                    confirm(\n                        \"Confirm overwrite\",\n                        \"A file named '\" +\n                            proposedName +\n                            \"' already exists. Click 'Yes' to overwrite, or 'No' to upload with a different name.\"\n                    )\n                ))\n            ) {\n                await dispatch(deleteCodeItem(existingAsset));\n                break;\n            } else {\n                const newName = await dispatch(\n                    prompt(\"Choose a new name\", \"Enter new name:\", generateValidAssetName(baseName, appAssets))\n                );\n                if (!newName) return;\n                proposedName = newName;\n            }\n        }\n        return proposedName;\n    };\n\nexport const createAsset =\n    (ext: string, pkgPrefix?: string | null): AnvilAsyncAction<StructureItem> =>\n    async (dispatch, getState, updateState) => {\n        const appAssets = getAppAssets(getState());\n        let name = generateValidAssetName(\"new_file.\" + ext, appAssets);\n        if (name.indexOf(\".\") === -1) {\n            name += `.${ext}`;\n        }\n        if (pkgPrefix) {\n            name = pkgPrefix + \"/\" + name;\n        }\n        const newAsset: AssetItemYaml = {\n            name: name,\n            content: \"\",\n            id: generateItemId(),\n        };\n        const codePath = getItemCodePath(\"asset\", newAsset);\n        const structuredCodeItem = await dispatch(addCodeItem(codePath, \"asset\", newAsset));\n        dispatch(navigate({ type: \"CODE\", codePath }));\n        return structuredCodeItem;\n    };\n\nexport const uploadAsset =\n    (f: File, pkgPrefix?: string | null, redirect = true): AnvilAsyncAction<StructureItem | undefined> =>\n    async (dispatch, getState, updateState) => {\n        const newContent = await fileToBase64Content(f);\n\n        let proposedName = await dispatch(promptForGoodFileName(f.name, pkgPrefix));\n        if (!proposedName) return;\n        if (pkgPrefix) {\n            proposedName = pkgPrefix + \"/\" + proposedName;\n        }\n        const asset: AssetItemYaml = {\n            name: proposedName,\n            content: newContent,\n            id: generateItemId(),\n        };\n        const codePath = getItemCodePath(\"asset\", asset);\n        const structuredCodeItem = await dispatch(addCodeItem(codePath, \"asset\", asset));\n        if (redirect) dispatch(navigate({ type: \"CODE\", codePath }));\n        return structuredCodeItem;\n    };\n\nexport const replaceAsset =\n    (f: File, codePath: CodePath): AnvilAsyncAction<number> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const cacheKey = getCacheKey([\"CODE\", codePath], state);\n        const itemCache = getItemCache(state);\n        const currentItem = _cache[itemCache[cacheKey]].item as AssetItemYaml;\n        const newContent = await fileToBase64Content(f);\n\n        currentItem.content = newContent;\n        return dispatch(markAppPathUnsaved([\"CODE\", codePath]));\n    };\n\nexport const saveNativeLibraries =\n    (nativeLibraryCodeString: string): AnvilAction<number> =>\n    (dispatch, getState, updateState) => {\n        updateState(({ app }) => {\n            if (!app) return;\n            app.config.native_deps ??= {};\n            app.config.native_deps.head_html = nativeLibraryCodeString;\n        });\n        return dispatch(markAppPathUnsaved([\"SETTINGS\", \"native_deps\", \"head_html\"]));\n    };\n\nexport const saveImportMap =\n    (importMapCodeString: string): AnvilAction<number> =>\n    (dispatch, getState, updateState) => {\n        updateState(({ app }) => {\n            if (!app) return;\n            if (!importMapCodeString) {\n                if (app.config.native_deps) {\n                    delete app.config.native_deps.import_map;\n                }\n            } else {\n                app.config.native_deps ??= {};\n                app.config.native_deps.import_map = importMapCodeString;\n            }\n        });\n        return dispatch(markAppPathUnsaved([\"SETTINGS\", \"native_deps\", \"import_map\"]));\n    };\n\nconst isRoot = (node: any): node is RootStructure => !!node?.root;\n\nexport const namesFromCodeStructure = (codeStructure?: AppCodeStructure) => {\n    const allNames: Record<string, StructureItem> = {};\n    if (!codeStructure) return allNames;\n    const walk = (node: RootStructure | StructureItem) => {\n        if (!isRoot(node)) {\n            // This could be made cleverer - only pick out things we want to conflict with.\n            allNames[node.fullName] = node;\n        }\n        for (const c of node.children || []) {\n            walk(c);\n        }\n    };\n    walk(codeStructure.clientCode);\n    walk(codeStructure.serverCode);\n    walk(codeStructure.assets);\n    walk(codeStructure.scripts);\n    return allNames;\n};\n\nconst EMPTY_CODE_STRUCTURE: AppCodeStructure = {\n    clientCode: { name: \"Client Code\", root: true, children: [] },\n    serverCode: { name: \"Server Code\", root: true, children: [] },\n    assets: { name: \"Assets\", root: true, children: [] },\n    scripts: { name: \"Scripts\", root: true, children: [] },\n    serverTests: { name: \"Server Tests\", root: true, children: [] },\n};\n\nconst EMPTY_DEP_CODE: IDEDependencyCode = {};\n\n// N.B. This is not a selector, just plain function.\nexport const generateTitleFromCodeTabItem = (tab: CodeTab, { class_name, name }: CodeItemYaml) => class_name || name;\n\nexport const getItemCache = (state: State) => state.itemCache;\nexport const getCodeStructure = (state: State | GadgetState) => state.app?.codeStructure ?? EMPTY_CODE_STRUCTURE;\nexport const getDependencyCode = (state: State) => state.app?.dependencyCode ?? EMPTY_DEP_CODE;\nexport const getCodeNames = createSelector([getCodeStructure], namesFromCodeStructure);\n\nconst mkStructureWalker = (type: CodeItemType) => {\n    const walk = (node: RootStructure | StructureItem | undefined, structureArray: StructureItem[]) => {\n        if (!node) return;\n        if (!isRoot(node) && node.type === type) {\n            structureArray.push(node);\n        }\n        for (const c of node.children || []) {\n            walk(c, structureArray);\n        }\n    };\n    return walk;\n};\n\nconst walkForms = mkStructureWalker(\"form\");\nconst walkModules = mkStructureWalker(\"module\");\nconst walkServerModules = mkStructureWalker(\"server_module\");\nconst walkAssets = mkStructureWalker(\"asset\");\n\nexport const getForms = createSelector([getCodeStructure], (codeStructure) => {\n    const allForms: StructureItem[] = [];\n    walkForms(codeStructure?.clientCode, allForms);\n    return allForms;\n});\n\nexport const getModules = createSelector([getCodeStructure], (codeStructure) => {\n    const allModules: StructureItem[] = [];\n    walkModules(codeStructure?.clientCode, allModules);\n    return allModules;\n});\n\nexport const getServerModules = createSelector([getCodeStructure], (codeStructure) => {\n    const allServerModules: StructureItem[] = [];\n    walkServerModules(codeStructure?.serverCode, allServerModules);\n    return allServerModules;\n});\n\nexport const getScripts = createSelector([getCodeStructure], (codeStructure) => {\n    return codeStructure.scripts?.children ?? [];\n});\n\nexport const getDependencyForms = createSelector([getDependencyCode], (dependencyCode) => {\n    const allDependencyForms = [];\n    for (const [key, value] of Object.entries(dependencyCode ?? {})) {\n        for (const f of value.forms || []) {\n            const form = { ...f, dependency_id: key };\n            allDependencyForms.push(form);\n        }\n    }\n    return allDependencyForms;\n});\n\nexport const getDependencyStructure = createSelector(\n    [getDependencyCode, (s) => getAppConfig(s)],\n    (dependencyCode, appConfig) => {\n        const deps: Record<string, DependencyStructureContent> = {};\n        const renderItem = (f: any): DependencyStructureItem => {\n            const structPath = (f.class_name || f.name).split(\".\");\n            return {\n                fullName: f.class_name || f.name,\n                name: structPath.pop()!,\n                isPackage: !!f.is_package,\n                customComponent: f.custom_component,\n                isLayout: !!f.slots,\n                toolboxItem: f.toolbox_item,\n                layoutMetadata: f.layout_metadata,\n                helpText: f.help_text,\n            };\n        };\n        for (const [depAppId, dep] of Object.entries(dependencyCode || {})) {\n            if (!dep.error) {\n                const logicalDepId = appConfig ? findLogicalDepIdForDepAppId(depAppId, appConfig) : undefined;\n                deps[depAppId] = {\n                    name: dep.name,\n                    packageName: dep.package_name,\n                    forms: dep.forms.map(renderItem),\n                    modules: dep.modules.map(renderItem),\n                    serverModules: dep.server_modules.map(renderItem),\n                    logicalDepId,\n                    clientInitModule: dep.client_init_module,\n                };\n            }\n        }\n        return deps;\n    }\n);\n\nexport const getAppAssets = createSelector([getCodeStructure], (codeStructure) => {\n    const allAssets: StructureItem[] = [];\n    walkAssets(codeStructure?.assets, allAssets);\n    return allAssets;\n});\n\nexport const getDependencyAssets = createSelector([getDependencyCode], (dependencyCode) => {\n    const allDependencyAssets: DependencyStructureItem[] = [];\n    for (const [depAppId, value] of Object.entries(dependencyCode ?? {})) {\n        for (const asset of value.assets || []) {\n            const structPath = asset.name.split(\"/\");\n            allDependencyAssets.push({\n                ...asset,\n                type: \"asset\",\n                name: structPath.pop()!,\n                fullName: asset.name,\n                dependencyAppId: depAppId,\n            });\n        }\n    }\n    return allDependencyAssets;\n});\n\nexport const setCodeItemHistory =\n    (codePath: EditorPath, newHistory: Partial<EditHistory>): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        // console.log(\"%cDispatch Set CodeItem Hisotry\", \"color: green;\", codePath, newHistory);\n        const state = getState();\n        const cacheKey = getCacheKey([\"CODE\", codePath], state);\n        const currentHistory = state.editHistory[cacheKey] ?? {};\n        updateState(({ editHistory }) => {\n            editHistory[cacheKey] = { ...currentHistory, ...newHistory };\n        });\n    };\n\nexport const getCodeItemHistory = (codePath: EditorPath, state: State) => {\n    // console.log(\"%cGETTING CODE ITEM HISTORY\", \"color: brown\", cacheKey, state.editHistory[cacheKey]);\n    const cacheKey = getCacheKey([\"CODE\", codePath], state);\n    return state.editHistory[cacheKey];\n};\n\nconst getAndMaybeCreateCodeNavState = (state: State, appId: AppId, treeType: TreeType) => {\n    // this should definitely exist - so could be an old app before we keyed by treeType\n    const codeNavState = (state.codeNavState[appId] ??= {\n        client: {},\n        server: {},\n        assets: {},\n        scripts: {},\n        serverTests: {},\n    });\n    codeNavState[treeType] ??= {};\n\n    return codeNavState;\n};\n\nexport const setFileExpanded =\n    (\n        treeType: TreeType,\n        file: Pick<FileTreeItem, \"id\" | \"fullName\" | \"isPackage\" | \"type\">,\n        expanded: boolean\n    ): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        if (!(file.isPackage || file.type === \"folder\")) return;\n        const state = getState();\n        const appId = getAppId(state);\n        if (!appId) return;\n        const codeNavStateForTree = state.codeNavState[appId]?.[treeType];\n        if (codeNavStateForTree?.[file.id || file.fullName]?.expanded === expanded) {\n            return;\n        } else {\n            updateState((state) => {\n                const codeNavState = getAndMaybeCreateCodeNavState(state, appId, treeType);\n                codeNavState[treeType][file.id || file.fullName] = { expanded };\n            });\n        }\n    };\n\nexport const updateCodeNavState =\n    (treeType: TreeType, file: StructureItem, update: Partial<CodeNavFileState>): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        if (!(file.isPackage || file.type === \"folder\")) return;\n        const state = getState();\n        const appId = getAppId(state);\n        if (!appId) return;\n        const codeNavStateForTree = state.codeNavState[appId]?.[treeType];\n        const codeNavFileState = codeNavStateForTree?.[file.id || file.fullName];\n        updateState((state) => {\n            const codeNavState = getAndMaybeCreateCodeNavState(state, appId, treeType);\n            codeNavState[treeType][file.id || file.fullName] = { ...codeNavFileState, ...update };\n        });\n    };\n\nexport const collapseAllFiles =\n    (treeType: TreeType): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState((state) => {\n            const appId = state.app?.id;\n            if (!appId) return;\n            const codeNavState = getAndMaybeCreateCodeNavState(state, appId, treeType);\n            codeNavState[treeType] = {};\n        });\n    };\n\nexport const requestSetFormProperty =\n    (formName: string, propertyName: string, newValue: any): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const formNode = getForms(state).find((form) => form.fullName === formName);\n        const form = formNode && ((await dispatch(openCodeItem(formNode.codePath))) as FormItem | null);\n\n        console.log(\"requestSetFormProperty: looking for\", formName, \", got\", formNode, \"->\", form);\n        // possibly null if the form was deleted\n        if (form) {\n            const topLevelProperties = form.item.container?.properties ?? form.item.layout?.properties;\n            //console.log(\"Comparing \", topLevelProperties[propertyName], \"with\", newValue);\n            if (\n                topLevelProperties &&\n                propertyName in topLevelProperties &&\n                typeof topLevelProperties[propertyName] === typeof newValue\n            ) {\n                topLevelProperties[propertyName] = newValue;\n                syncHtmlFormAfterDesignerMutation(form.item, state, {\n                    debugContext: {\n                        codePath: formNode.codePath,\n                        operation: \"requestSetFormProperty\",\n                        eventContext: { formName, propertyName, newValue },\n                        afterMutationState: form.item,\n                    },\n                });\n                dispatch(notifyUpdatedCodeItem(formNode.codePath));\n            }\n        }\n    };\n\nconst defaultCodeNavState: CodeNavState = {\n    client: {},\n    server: {},\n    assets: {},\n    scripts: {},\n    serverTests: {},\n};\n\nexport const getCodeNavState = createSelector(\n    [(s: State) => s.codeNavState, (s: State) => getAppId(s)],\n    (codeNavStateObject, appId) => (appId && codeNavStateObject[appId]) ?? defaultCodeNavState\n);\n\nexport const getClientCodeStructure = (state: State) => state.app?.codeStructure.clientCode;\nexport const getServerCodeStructure = (state: State) => state.app?.codeStructure.serverCode;\n\nexport const strHashCode = (str: string) => {\n    let hash = 0;\n    if (!str) return hash;\n\n    for (let i = 0; i < str.length; i++) {\n        const char = str.charCodeAt(i);\n        hash = (hash << 5) - hash + char;\n        hash = hash & hash; // Convert to 32bit integer\n    }\n    return hash;\n};\n\ninterface CustomComponentWithDeps extends DependencyStructureItem {\n    depAppId: string;\n    logicalDepId?: string;\n    packageName?: string;\n}\n\nconst getFormsBy = (predicate: (form: StructureItem | DependencyStructureItem) => boolean | undefined) =>\n    createSelector(\n        [getForms, getDependencyStructure],\n        (forms, depStructure): (StructureItem | CustomComponentWithDeps)[] =>\n            (forms.filter(predicate) as (StructureItem | CustomComponentWithDeps)[]).concat(\n                ...Object.entries(depStructure).map(\n                    ([depAppId, { packageName, logicalDepId, forms = [] }]): CustomComponentWithDeps[] =>\n                        forms.filter(predicate).map((f) => ({ depAppId, logicalDepId, packageName, ...f }))\n                )\n            )\n    );\n\nexport const getCustomComponentForms = getFormsBy((f) => f.customComponent);\nexport const getCustomLayoutForms = getFormsBy((f) => f.isLayout);\n\ninterface ToolBoxSectionWithPackage extends ToolboxSection {\n    packageName: string;\n}\n\nexport const getToolboxSections = createSelector(\n    [\n        (state: State) => state.app?.config.toolbox?.sections || state.app?.config.toolbox_sections,\n        (state: State) => state.app?.dependencyCode,\n    ],\n    (sections, depCode): ToolBoxSectionWithPackage[] =>\n        (sections ?? [])\n            .map((s) => ({ packageName: \"\", ...s }) as ToolBoxSectionWithPackage)\n            .concat(\n                ...Object.values(depCode || {}).map((dep) =>\n                    ((dep.toolbox?.sections || dep.toolbox_sections) ?? []).map(\n                        (s) => ({ packageName: dep.package_name, ...s }) as ToolBoxSectionWithPackage\n                    )\n                )\n            )\n);\n\nexport const getHideClassicComponents = createSelector(\n    [(state: State) => state.app?.config.toolbox?.hide_classic_components, (state: State) => state.app?.dependencyCode],\n    (hideInThisApp, depCode): boolean => {\n        return hideInThisApp || Object.values(depCode || {}).some((dep) => dep.toolbox?.hide_classic_components);\n    }\n);\n\nexport const updateEnableHtmlLayout =\n    (asset: StructureItem, useAsLayout: boolean): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ app }) => {\n            const { config } = app!;\n            const existingLayoutIdx =\n                config.layouts?.findIndex(\n                    ({ layout: { properties } }) => properties?.html === `@theme:${asset.fullName}`\n                ) ?? -1;\n            if (!useAsLayout && existingLayoutIdx > -1) {\n                config.layouts?.splice(existingLayoutIdx, 1);\n            } else if (useAsLayout && existingLayoutIdx === -1) {\n                config.layouts ??= [];\n                config.layouts.push({\n                    title: asset.name,\n                    layout: { type: \"HtmlTemplate\", properties: { html: `@theme:${asset.fullName}` } },\n                });\n            }\n        });\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"layouts\"]));\n    };\n\nexport const updateHtmlLayoutMetadata =\n    (asset: StructureItem, metadata: LayoutMetadata): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ app }) => {\n            const { config } = app!;\n            const existingLayout = config.layouts?.find(\n                ({ layout: { properties } }) => properties?.html === `@theme:${asset.fullName}`\n            );\n            if (existingLayout) {\n                Object.assign(existingLayout, metadata);\n            }\n        });\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"layouts\"]));\n    };\n\nexport const getCustomComponentAndLayoutForms = getFormsBy((f) => f.customComponent || f.isLayout);\n","import { pythonLanguage } from \"@codemirror/lang-python\";\nimport { ChangeSet, type ChangeSpec, EditorState } from \"@codemirror/state\";\nimport type { SyntaxNode } from \"@lezer/common\";\nimport type { CodeItemYaml, CodePath } from \"@/types\";\nimport type { PreparedWorkspaceEdit } from \"./workspace-edits\";\n\n/** The logical module name stays put, but its relative-import base moves one\n * package level. A Form's generated template moves alongside its code. */\nexport function prepareModuleConversion(\n    codePath: CodePath,\n    item: CodeItemYaml,\n    options: { isPackage: boolean; code: string }\n): PreparedWorkspaceEdit {\n    const { code, isPackage } = options;\n    const edits: ChangeSpec[] = [];\n    const name = (item.class_name ?? item.name)!.split(\".\").at(-1)!;\n    pythonLanguage.parser.parse(code).iterate({\n        enter(node) {\n            if (node.name !== \"ImportStatement\") return;\n            const from = node.node.firstChild;\n            if (from?.name !== \"from\") return;\n            const firstDot = from.nextSibling;\n            if (!firstDot || ![\".\", \"Ellipsis\"].includes(firstDot.name)) return;\n            let level = 0;\n            let token: SyntaxNode | null = firstDot;\n            while (token && [\".\", \"Ellipsis\"].includes(token.name)) {\n                level += token.name === \"Ellipsis\" ? 3 : 1;\n                token = token.nextSibling;\n            }\n            let module = \"\";\n            while (token && token.name !== \"import\") {\n                if (token.name === \"VariableName\" || token.name === \".\") module += code.slice(token.from, token.to);\n                token = token.nextSibling;\n            }\n            if (!token) return;\n            if (item.class_name && level === 1 && (module === \"_anvil_designer\" || !module)) {\n                const ownName = module ? name + \"Template\" : \"_anvil_designer\";\n                const names: { name: string; from: number; to: number; comma?: SyntaxNode }[] = [];\n                for (let child = token.nextSibling; child; child = child.nextSibling) {\n                    if (child.name !== \"VariableName\" && child.name !== \"*\") continue;\n                    const imported = {\n                        name: code.slice(child.from, child.to),\n                        from: child.from,\n                        to: child.to,\n                        comma: undefined as SyntaxNode | undefined,\n                    };\n                    if (child.nextSibling?.name === \"as\") {\n                        child = child.nextSibling.nextSibling!;\n                        imported.to = child.to;\n                    }\n                    let next = child.nextSibling;\n                    while (next?.name === \"Comment\") next = next.nextSibling;\n                    if (next?.name === \",\") imported.comma = next;\n                    names.push(imported);\n                }\n                const own = (imported: (typeof names)[number]) => imported.name === ownName;\n                if (names.length && names.every(own)) return;\n                const templates = names.filter(own);\n                const wildcard = module && names.find((imported) => imported.name === \"*\");\n                if (wildcard && !isPackage) {\n                    // An empty Form package's Designer exports only its own\n                    // template. Avoid importing extra parent templates on demotion.\n                    edits.push({ from: wildcard.from, to: wildcard.to, insert: name + \"Template\" });\n                    return;\n                }\n                const ownImports = wildcard\n                    ? name + \"Template\"\n                    : templates.map((imported) => code.slice(imported.from, imported.to)).join(\", \");\n                if (ownImports) {\n                    // Split a shared Designer import: only this Form's template\n                    // stays alongside its code. Keep other imports at their original location.\n                    const linePrefix = code.slice(code.lastIndexOf(\"\\n\", node.from - 1) + 1, node.from);\n                    const separator = /^\\s*$/.test(linePrefix) ? \"\\n\" + linePrefix : \"; \";\n                    edits.push({\n                        from: node.from,\n                        insert: `from .${module} import ${ownImports}${separator}`,\n                    });\n                    for (let i = 0; i < names.length; i++) {\n                        if (!own(names[i])) continue;\n                        const start = i;\n                        while (i + 1 < names.length && own(names[i + 1])) i++;\n                        const following = names[i].comma;\n                        if (i + 1 < names.length || following) {\n                            edits.push({ from: names[start].from, to: following!.to });\n                        } else {\n                            edits.push({ from: names[start - 1].comma!.from, to: names[i].to });\n                        }\n                    }\n                }\n            }\n            if (isPackage) edits.push({ from: firstDot.from, insert: \".\" });\n            else if (level > 1) edits.push({ from: firstDot.from, to: firstDot.from + 1 });\n            else edits.push({ from: firstDot.to, insert: name + (module ? \".\" : \"\") });\n        },\n    });\n    const changes = ChangeSet.of(edits, code.length);\n    return {\n        items: new Map([\n            [\n                codePath,\n                {\n                    ...structuredClone(item),\n                    code: changes.apply(EditorState.create({ doc: code }).doc).toString(),\n                    is_package: isPackage,\n                },\n            ],\n        ]),\n        code: new Map([[codePath, { before: code, changes }]]),\n        fields: [],\n        packageChanges: [{ codePath, before: !!item.is_package, after: isPackage }],\n    };\n}\n","import { EVENTS, raiseEvent } from \"@/actions\";\nimport { type ExtraAppFiles, getExtraAppFileTemplates } from \"@/api\";\nimport { navigate } from \"@/router/navigation\";\nimport type { AnvilAction, AnvilAsyncAction, Conflicts, ExtraFiles, State, TreeType } from \"@/types\";\nimport { decodeAssetContent, encodeAssetContent } from \"@/util/asset-content\";\nimport {\n    getAppAssets,\n    getCacheKey,\n    getCodeItemHistory,\n    getForms,\n    getModules,\n    getScripts,\n    getServerModules,\n    rebuildCodeStructureAndSyncCache,\n} from \"./code\";\nimport { getApp, getAppExtraFiles, getAppId, getAppIsEditable, markAppPathUnsaved, markAppPathsUnsaved } from \"./index\";\nimport { flushUnsavedCallbacks, saveApp } from \"./saving\";\n\n//todo: I think all these should actually belong in server-tests.ts instead of here\nconst EXAMPLE_TESTS_CONTENT = (packageName: string) => `\"\"\"Example pytest tests.\n\nPytest discovers tests in files named test_*.py or *_test.py.\nWithin those files, test functions and methods must start with test_.\nTest classes must start with Test.\n\"\"\"\nimport pytest\n\n# from ${packageName}.ServerModule1 import say_hello\n#\n# def test_say_hello():\n#   assert say_hello(\"world\") == 42\n\ndef test_example():\n  assert 1 + 1 == 2\n`;\n\nexport const SERVER_TEST_ROOT = \"tests/server_tests\";\nexport const SERVER_TEST_REQUIREMENTS_PATH = `${SERVER_TEST_ROOT}/requirements.txt`;\nexport const SERVER_TEST_INITIALIZER_PATH = `${SERVER_TEST_ROOT}/__init__.py`;\nconst DEFAULT_SERVER_TEST_REQUIREMENTS = \"# Python dependencies needed for running tests\\npytest\\n\";\n\nexport function hasExtraFileConflictAtPath(state: State, path: string): boolean {\n    return (\n        state.app?.conflicts?.conflicting_items.some(({ item }) => {\n            if (item[0] !== \"extra_files\") return false;\n\n            const conflictPath = item[1];\n            if (typeof conflictPath !== \"string\") return false;\n\n            return conflictPath === path || conflictPath.startsWith(`${path}/`) || path.startsWith(`${conflictPath}/`);\n        }) ?? false\n    );\n}\n\nfunction validateExtraEntryName(requestedName: string): string {\n    const name = requestedName.trim();\n\n    // eslint-disable-next-line no-control-regex\n    const hasControlCharacters = /[\\u0000-\\u001f]/.test(name);\n\n    if (!name || name === \".\" || name === \"..\" || name === \"__proto__\" || /[/\\\\]/.test(name) || hasControlCharacters) {\n        throw new Error(\"Enter a name without slashes or control characters.\");\n    }\n\n    if (name === \".gitkeep\") {\n        throw new Error(\"This name is reserved for empty folders.\");\n    }\n\n    return name;\n}\n\nexport function getExtraFileEntry(files: ExtraFiles | undefined, filePath: string): string | ExtraFiles | undefined {\n    let entry: string | ExtraFiles | undefined = files;\n    for (const part of filePath.split(\"/\")) {\n        if (!entry || typeof entry === \"string\" || !Object.hasOwn(entry, part)) return undefined;\n        entry = entry[part];\n    }\n    return entry;\n}\n\n/** Paths are relative to the app root; file contents are base64, as for theme assets. */\nexport function getExtraFileContent(state: State, filePath: string): string | undefined {\n    const entry = getExtraFileEntry(getAppExtraFiles(state), filePath);\n    return typeof entry === \"string\" ? entry : undefined;\n}\n\nexport const getExtraFileConflicts = (state: State, filePath: string) =>\n    state.app?.conflicts?.conflicting_items.find(\n        ({ item: [type, path] }) => type === \"extra_files\" && path === filePath\n    );\n\n// Omitting conflicts leaves metadata unchanged. A record without text_chunks\n// clears inline markers but keeps the central entry until whole-file confirmation.\nexport const saveExtraFile = (\n    filePath: string,\n    content: string,\n    options: { conflicts?: Conflicts; createIfMissing?: boolean } = {}\n): AnvilAction<number | undefined> => setExtraFileContent(filePath, encodeAssetContent(content), options);\n\n/** Store base64 bytes directly, including binary files chosen during conflict resolution. */\nexport const setExtraFileContent =\n    (\n        filePath: string,\n        encodedContent: string,\n        { conflicts, createIfMissing = false }: { conflicts?: Conflicts; createIfMissing?: boolean } = {}\n    ): AnvilAction<number | undefined> =>\n    (dispatch, getState, updateState) => {\n        if (!getAppIsEditable(getState())) throw new Error(\"This app is not editable.\");\n\n        const previousContent = getExtraFileContent(getState(), filePath);\n        if (!createIfMissing && previousContent === undefined) return;\n\n        const initializerVisibilityChanged =\n            filePath === `${SERVER_TEST_ROOT}/__init__.py` &&\n            (typeof previousContent === \"string\" && previousContent !== \"\") !== (encodedContent !== \"\");\n\n        const parts = filePath.split(\"/\");\n        // Undo can reopen the last resolved conflict after its central merge\n        // metadata has gone. The file's editor history retains that context.\n        const merge =\n            conflicts &&\n            (getState().app?.conflicts?.merge ??\n                getCodeItemHistory(`extra_files/${filePath}`, getState())?.resolvedConflictMerge);\n        const restoringMerge = !!conflicts?.text_chunks?.length && !getState().app?.conflicts;\n        updateState(\"Update extra file\", ({ app }) => {\n            app!.config.extra_files ??= {};\n            let directory = app!.config.extra_files;\n            for (const part of parts.slice(0, -1)) {\n                const entry = Object.hasOwn(directory, part) ? directory[part] : undefined;\n                if (typeof entry === \"string\") throw new Error(`A file blocks the path ${filePath}.`);\n                if (!entry) directory[part] = {};\n                directory = directory[part] as ExtraFiles;\n            }\n            const name = parts[parts.length - 1];\n            if (Object.hasOwn(directory, name) && typeof directory[name] === \"object\") {\n                throw new Error(`${filePath} is a directory.`);\n            }\n            directory[name] = encodedContent;\n            if (\n                conflicts &&\n                app!.editState.merge !== undefined &&\n                merge &&\n                (app!.conflicts || conflicts.text_chunks?.length)\n            ) {\n                app!.conflicts ??= { merge, conflicting_items: [] };\n                const existingConflict = app!.conflicts.conflicting_items.find(\n                    ({ item: [type, conflictPath] }) => type === \"extra_files\" && conflictPath === filePath\n                );\n                // Undo effects retained across rename/move may still carry the old path.\n                if (existingConflict) Object.assign(existingConflict, conflicts, { item: [\"extra_files\", filePath] });\n                else if (conflicts.text_chunks?.length) {\n                    app!.conflicts.conflicting_items.push({\n                        ...conflicts,\n                        item: [\"extra_files\", filePath],\n                        movedToItemCache: false,\n                    });\n                }\n                if (existingConflict && !conflicts.text_chunks) delete existingConflict.text_chunks;\n            }\n        });\n        if (conflicts) {\n            dispatch(markAppPathUnsaved(restoringMerge ? [\"CONFLICTS\"] : [\"CONFLICTS\", [\"extra_files\", filePath]]));\n        }\n        if (initializerVisibilityChanged) {\n            dispatch(rebuildCodeStructureAndSyncCache(new Set()));\n        }\n        return dispatch(markAppPathUnsaved([\"EXTRA_FILES\", ...parts]));\n    };\n\nexport const deleteExtraFile =\n    (filePath: string): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        if (!getAppIsEditable(getState())) throw new Error(\"This app is not editable.\");\n        // The merger can report edit/delete for an entire extra-file directory in a code folder.\n        if (getExtraFileEntry(getAppExtraFiles(getState()), filePath) === undefined) return;\n        const parts = filePath.split(\"/\");\n        updateState(\"Delete extra file\", ({ app }) => {\n            let directory = app!.config.extra_files!;\n            for (const part of parts.slice(0, -1)) directory = directory[part] as ExtraFiles;\n            delete directory[parts[parts.length - 1]];\n        });\n        dispatch(markAppPathUnsaved([\"EXTRA_FILES\", ...parts]));\n    };\n\nexport const deleteExtraFileEntry =\n    (path: string): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const state = getState();\n        if (!getAppIsEditable(state)) {\n            throw new Error(\"This app is not editable.\");\n        }\n\n        const parts = path.split(\"/\");\n        if (parts.some((part) => !part || part === \".\" || part === \"..\")) {\n            throw new Error(\"Invalid file path.\");\n        }\n\n        if (getExtraFileEntry(getAppExtraFiles(state), path) === undefined) {\n            return;\n        }\n\n        // The shared action handles both files and entire directories.\n        dispatch(deleteExtraFile(path));\n\n        if (parts.length < 2) return;\n\n        const parentParts = parts.slice(0, -1);\n        const parentPath = parentParts.join(\"/\");\n        const parent = getExtraFileEntry(getAppExtraFiles(getState()), parentPath);\n\n        if (!parent || typeof parent === \"string\" || Object.keys(parent).length > 0) {\n            return;\n        }\n\n        // Preserve an empty containing directory across save/reload.\n        updateState(\"Preserve empty extra-file directory\", ({ app }) => {\n            const directory = getExtraFileEntry(app!.config.extra_files!, parentPath) as ExtraFiles;\n\n            directory[\".gitkeep\"] = encodeAssetContent(\"\");\n        });\n\n        dispatch(markAppPathUnsaved([\"EXTRA_FILES\", ...parentParts, \".gitkeep\"]));\n    };\n\ntype ExtraFileTreeOptions = {\n    rootPath: string;\n    treeType: TreeType;\n};\nconst relocateExtraFileEntry =\n    (path: string, newPath: string, options: ExtraFileTreeOptions): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n\n        if (!getAppIsEditable(state)) {\n            throw new Error(\"This app is not editable.\");\n        }\n\n        if (path === newPath) {\n            return;\n        }\n\n        const oldParts = path.split(\"/\");\n        const newParts = newPath.split(\"/\");\n\n        if (\n            oldParts.some((part) => !part || part === \".\" || part === \"..\") ||\n            newParts.some((part) => !part || part === \".\" || part === \"..\")\n        ) {\n            throw new Error(\"Invalid file path.\");\n        }\n\n        if (!path.startsWith(`${options.rootPath}/`) || !newPath.startsWith(`${options.rootPath}/`)) {\n            throw new Error(\"Files cannot be moved outside the test directory.\");\n        }\n\n        const oldName = oldParts.at(-1)!;\n        const newName = newParts.at(-1)!;\n        const oldParentPath = oldParts.slice(0, -1).join(\"/\");\n        const newParentPath = newParts.slice(0, -1).join(\"/\");\n\n        const oldParent = getExtraFileEntry(getAppExtraFiles(state), oldParentPath);\n\n        const newParent = getExtraFileEntry(getAppExtraFiles(state), newParentPath);\n\n        if (!oldParent || typeof oldParent === \"string\" || !Object.hasOwn(oldParent, oldName)) {\n            throw new Error(\"The file or folder no longer exists.\");\n        }\n\n        if (!newParent || typeof newParent === \"string\") {\n            throw new Error(\"The destination directory no longer exists.\");\n        }\n\n        if (Object.hasOwn(newParent, newName)) {\n            throw new Error(\"A file or folder with that name already exists.\");\n        }\n\n        const entry = oldParent[oldName];\n        const isDirectory = typeof entry !== \"string\";\n\n        // Remove this restriction once renaming also updates conflict paths.\n        if (hasExtraFileConflictAtPath(state, path) || hasExtraFileConflictAtPath(state, newPath)) {\n            throw new Error(\"Resolve merge conflicts affecting this file or folder before moving or renaming it.\");\n        }\n\n        const isAffected = (filePath: string) => filePath === path || (isDirectory && filePath.startsWith(`${path}/`));\n\n        const renamedPath = (filePath: string) => newPath + filePath.slice(path.length);\n\n        // Include every actual file, including initializers and hidden files.\n        const fileMoves: Array<{ oldPath: string; newPath: string }> = [];\n\n        function collectFiles(value: string | ExtraFiles, filePath: string) {\n            if (typeof value === \"string\") {\n                fileMoves.push({\n                    oldPath: filePath,\n                    newPath: renamedPath(filePath),\n                });\n                return;\n            }\n\n            for (const [name, child] of Object.entries(value)) {\n                collectFiles(child, `${filePath}/${name}`);\n            }\n        }\n\n        collectFiles(entry, path);\n\n        const historyMoves = fileMoves.map((move) => ({\n            oldKey: getCacheKey([\"CODE\", `extra_files/${move.oldPath}`], state),\n            newKey: getCacheKey([\"CODE\", `extra_files/${move.newPath}`], state),\n        }));\n\n        const currentTabId = state.editor.tabStack.at(-1);\n        const currentTab = state.editor.tabs.find(({ id }) => id === currentTabId);\n        const activePath = currentTab?.navTarget.type === \"EXTRA_FILE\" ? currentTab.navTarget.filePath : undefined;\n        const nextActivePath = activePath && isAffected(activePath) ? renamedPath(activePath) : undefined;\n\n        // Listeners synchronously save mounted editors' latest history.\n        // Keep this immediately before moving the files and history entries.\n        dispatch(\n            raiseEvent(\n                EVENTS.EXTRA_FILES_BEFORE_RENAME,\n                historyMoves.map(({ oldKey }) => oldKey)\n            )\n        );\n\n        const movingBetweenDirectories = oldParentPath !== newParentPath;\n\n        const createOldParentGitkeep = movingBetweenDirectories && Object.keys(oldParent).length === 1;\n\n        const removeNewParentGitkeep = movingBetweenDirectories && typeof newParent[\".gitkeep\"] === \"string\";\n\n        updateState(movingBetweenDirectories ? \"Move extra-file entry\" : \"Rename extra-file entry\", (draft) => {\n            const extraFiles = draft.app!.config.extra_files!;\n\n            const sourceDirectory = getExtraFileEntry(extraFiles, oldParentPath) as ExtraFiles;\n\n            const destinationDirectory =\n                oldParentPath === newParentPath\n                    ? sourceDirectory\n                    : (getExtraFileEntry(extraFiles, newParentPath) as ExtraFiles);\n\n            const movingEntry = sourceDirectory[oldName];\n\n            delete sourceDirectory[oldName];\n\n            if (createOldParentGitkeep) {\n                sourceDirectory[\".gitkeep\"] = encodeAssetContent(\"\");\n            }\n\n            if (removeNewParentGitkeep) {\n                delete destinationDirectory[\".gitkeep\"];\n            }\n\n            destinationDirectory[newName] = movingEntry;\n\n            const appId = draft.app!.id;\n            const recentTabs = draft.editor.recentlyOpened[appId] ?? [];\n\n            for (const tab of [...draft.editor.tabs, ...recentTabs]) {\n                if (tab.navTarget.type !== \"EXTRA_FILE\" || !isAffected(tab.navTarget.filePath)) {\n                    continue;\n                }\n\n                const updatedPath = renamedPath(tab.navTarget.filePath);\n                tab.navTarget.filePath = updatedPath;\n\n                const segments = updatedPath.split(\"/\");\n                const filename = segments.at(-1)!;\n                tab.title = filename === \"__init__.py\" ? segments.at(-2)! : filename;\n            }\n\n            for (const { oldKey, newKey } of historyMoves) {\n                const history = draft.editHistory[oldKey];\n                delete draft.editHistory[oldKey];\n                delete draft.editHistory[newKey];\n                if (history) draft.editHistory[newKey] = history;\n            }\n\n            // Folder IDs are extra_files/<directory path>.\n            const treeState = draft.codeNavState[appId]?.[options.treeType];\n            if (treeState) {\n                const oldPrefix = `extra_files/${path}`;\n                const newPrefix = `extra_files/${newPath}`;\n\n                const expansionMoves = Object.entries(treeState).filter(\n                    ([key]) => key === oldPrefix || (isDirectory && key.startsWith(`${oldPrefix}/`))\n                );\n\n                for (const [key, value] of expansionMoves) {\n                    delete treeState[key];\n                    treeState[newPrefix + key.slice(oldPrefix.length)] = value;\n                }\n            }\n        });\n\n        for (const move of fileMoves) {\n            dispatch(markAppPathUnsaved([\"EXTRA_FILES\", ...move.oldPath.split(\"/\")]));\n            dispatch(markAppPathUnsaved([\"EXTRA_FILES\", ...move.newPath.split(\"/\")]));\n        }\n\n        if (createOldParentGitkeep) {\n            dispatch(markAppPathUnsaved([\"EXTRA_FILES\", ...oldParentPath.split(\"/\"), \".gitkeep\"]));\n        }\n\n        if (removeNewParentGitkeep) {\n            dispatch(markAppPathUnsaved([\"EXTRA_FILES\", ...newParentPath.split(\"/\"), \".gitkeep\"]));\n        }\n\n        dispatch(rebuildCodeStructureAndSyncCache(new Set()));\n\n        if (nextActivePath) {\n            await dispatch(navigate({ type: \"EXTRA_FILE\", filePath: nextActivePath }, true));\n        }\n    };\n\nexport const moveExtraFileEntry =\n    (path: string, destinationPath: string, options: ExtraFileTreeOptions): AnvilAsyncAction<void> =>\n    async (dispatch, getState) => {\n        const state = getState();\n\n        if (!getAppIsEditable(state)) {\n            throw new Error(\"This app is not editable.\");\n        }\n\n        if (!path.startsWith(`${options.rootPath}/`)) {\n            throw new Error(\"The root folder cannot be moved.\");\n        }\n\n        if (destinationPath !== options.rootPath && !destinationPath.startsWith(`${options.rootPath}/`)) {\n            throw new Error(\"Files cannot be moved outside the test directory.\");\n        }\n\n        const sourceName = path.split(\"/\").at(-1)!;\n        const sourceParent = path.slice(0, path.lastIndexOf(\"/\"));\n\n        if (sourceName === \"requirements.txt\" && destinationPath === options.rootPath) {\n            throw new Error(\"A requirements.txt file cannot be moved into the test root.\");\n        }\n\n        if (sourceParent === destinationPath) {\n            return;\n        }\n\n        if (destinationPath === path || destinationPath.startsWith(`${path}/`)) {\n            throw new Error(\"A directory cannot be moved into itself.\");\n        }\n\n        const destination = getExtraFileEntry(getAppExtraFiles(state), destinationPath);\n\n        if (destination === undefined || typeof destination === \"string\") {\n            throw new Error(\"The destination directory no longer exists.\");\n        }\n\n        if (Object.hasOwn(destination, sourceName)) {\n            throw new Error(\"A file or directory with that name already exists.\");\n        }\n\n        await dispatch(relocateExtraFileEntry(path, `${destinationPath}/${sourceName}`, options));\n    };\n\nexport const renameExtraFile =\n    (path: string, requestedName: string, options: { rootPath: string; treeType: TreeType }): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n\n        if (!getAppIsEditable(state)) {\n            throw new Error(\"This app is not editable.\");\n        }\n\n        if (\n            !path.startsWith(`${options.rootPath}/`) ||\n            path.split(\"/\").some((part) => !part || part === \".\" || part === \"..\")\n        ) {\n            throw new Error(\"The root folder cannot be renamed.\");\n        }\n\n        const parts = path.split(\"/\");\n        const oldName = parts.at(-1)!;\n        const newName = validateExtraEntryName(requestedName);\n        const parentPath = path.slice(0, path.lastIndexOf(\"/\"));\n\n        // Initializers belong to package rows, which need folder renaming.\n        if (oldName === \"__init__.py\" || newName === \"__init__.py\") {\n            throw new Error(\"Renaming package initializer files is not supported yet.\");\n        }\n        if (parentPath === options.rootPath && (oldName === \"requirements.txt\" || newName === \"requirements.txt\")) {\n            throw new Error(\"Renaming to or from requirements.txt in the test root is not allowed.\");\n        }\n\n        if (newName === oldName) return;\n\n        const parent = getExtraFileEntry(getAppExtraFiles(state), parentPath);\n\n        if (!parent || typeof parent === \"string\" || !Object.hasOwn(parent, oldName)) {\n            throw new Error(\"The file or folder no longer exists.\");\n        }\n\n        if (Object.hasOwn(parent, newName)) {\n            throw new Error(\"A file or folder with that name already exists.\");\n        }\n\n        const newPath = `${parentPath}/${newName}`;\n\n        await dispatch(relocateExtraFileEntry(path, newPath, options));\n    };\n\nexport const createExtraDirectory =\n    (parentPath: string, requestedName: string): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const state = getState();\n        if (!getAppIsEditable(state)) {\n            throw new Error(\"This app is not editable.\");\n        }\n        const name = validateExtraEntryName(requestedName);\n\n        if (name === \"__init__.py\") {\n            throw new Error(\"A directory cannot be named __init__.py.\");\n        }\n\n        const parent = getExtraFileEntry(getAppExtraFiles(state), parentPath);\n        if (!parent || typeof parent === \"string\") {\n            throw new Error(\"The parent directory no longer exists.\");\n        }\n\n        if (Object.hasOwn(parent, name)) {\n            throw new Error(\"A file or directory with that name already exists.\");\n        }\n\n        updateState(\"Create extra-file directory\", ({ app }) => {\n            const directory = getExtraFileEntry(app!.config.extra_files!, parentPath) as ExtraFiles;\n\n            directory[name] = {\n                \".gitkeep\": encodeAssetContent(\"\"),\n            };\n        });\n\n        dispatch(markAppPathUnsaved([\"EXTRA_FILES\", ...parentPath.split(\"/\"), name, \".gitkeep\"]));\n        dispatch(rebuildCodeStructureAndSyncCache(new Set()));\n    };\n\ninterface NewExtraFileOptions {\n    initialContent?: string;\n}\n\nexport const createExtraFile =\n    (\n        parentPath: string,\n        requestedName: string,\n        { initialContent = \"\" }: NewExtraFileOptions = {}\n    ): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        if (!getAppIsEditable(state)) {\n            throw new Error(\"This app is not editable.\");\n        }\n\n        const name = validateExtraEntryName(requestedName);\n\n        if (name === \"__init__.py\") {\n            throw new Error(\"Convert directories into packages instead of creating a __init__.py\");\n        }\n\n        const parent = getExtraFileEntry(getAppExtraFiles(state), parentPath);\n        if (!parent || typeof parent === \"string\") {\n            throw new Error(\"The parent directory no longer exists.\");\n        }\n\n        if (Object.hasOwn(parent, name)) {\n            throw new Error(\"A file or directory with that name already exists.\");\n        }\n\n        const filePath = `${parentPath}/${name}`;\n        const cacheKey = getCacheKey([\"CODE\", `extra_files/${filePath}`], state);\n\n        updateState(\"Create extra file\", (draft) => {\n            const directory = getExtraFileEntry(draft.app!.config.extra_files!, parentPath) as ExtraFiles;\n\n            directory[name] = encodeAssetContent(initialContent);\n\n            // A newly created file must not inherit a deleted file's history.\n            delete draft.editHistory[cacheKey];\n        });\n\n        dispatch(markAppPathUnsaved([\"EXTRA_FILES\", ...filePath.split(\"/\")]));\n        dispatch(rebuildCodeStructureAndSyncCache(new Set()));\n        await dispatch(navigate({ type: \"EXTRA_FILE\", filePath }));\n    };\n/** Copy and save a platform template; preserve existing files unless replacing. False means no template was supplied. */\nexport const copyExtraAppFileFromTemplate =\n    (filePath: string, { replaceExisting = false } = {}): AnvilAsyncAction<boolean> =>\n    async (dispatch, getState) => {\n        const appId = getAppId(getState());\n        const branch = getApp(getState())?.editState.branch;\n        if (!getApp(getState())?.editState?.editable) throw new Error(\"This app is not editable.\");\n        const base = getExtraFileEntry(await getExtraAppFileTemplates(), filePath);\n        if (typeof base !== \"string\") return false;\n        if (getAppId(getState()) !== appId || getApp(getState())?.editState.branch !== branch) {\n            throw new Error(\"The open app or branch has changed. Please try again.\");\n        }\n        flushUnsavedCallbacks();\n        if (!replaceExisting) {\n            // Creation must not replace a file added while the request was in flight.\n            const current = getExtraFileEntry(getApp(getState())?.config.extra_files, filePath);\n            if (typeof current === \"string\") return true;\n        }\n        dispatch(saveExtraFile(filePath, decodeAssetContent(base), { createIfMissing: true }));\n        await dispatch(saveApp(true, `${replaceExisting ? \"Restore\" : \"Create\"} ${filePath} from base`));\n        return true;\n    };\n\n/** Preserve existing files and directories, including app files outside extra_files. */\nexport function mergeMissingExtraFiles(\n    existing: ExtraAppFiles,\n    available: ExtraAppFiles,\n    { existingFilePaths = [] }: { existingFilePaths?: string[] } = {}\n) {\n    const occupiedFiles = new Set(existingFilePaths);\n    const occupiedPaths = new Set(existingFilePaths);\n    for (const path of existingFilePaths) {\n        const parts = path.split(\"/\");\n        for (let i = 1; i < parts.length; i++) occupiedPaths.add(parts.slice(0, i).join(\"/\"));\n    }\n    const addedPaths: string[][] = [];\n    const merge = (current: ExtraAppFiles, incoming: ExtraAppFiles, prefix: string): ExtraAppFiles => {\n        const entries = new Map(Object.entries(current));\n        for (const [name, content] of Object.entries(incoming)) {\n            const path = prefix + name;\n            if (typeof content === \"string\") {\n                if (!entries.has(name) && !occupiedPaths.has(path)) {\n                    entries.set(name, content);\n                    addedPaths.push(path.split(\"/\"));\n                }\n            } else if (typeof entries.get(name) !== \"string\" && !occupiedFiles.has(path)) {\n                const merged = merge((entries.get(name) as ExtraAppFiles | undefined) ?? {}, content, path + \"/\");\n                if (Object.keys(merged).length) entries.set(name, merged);\n            }\n        }\n        return Object.fromEntries(entries);\n    };\n    const files = merge(existing, available, \"\");\n    return { files, added: addedPaths.length, addedPaths };\n}\n\nfunction getExistingFilePaths(state: State): string[] {\n    const app = getApp(state)!;\n    const legacy = app.config.runtime_options.version < 2;\n    const paths = [\n        \"anvil.yaml\",\n        \".anvil_editor.yaml\",\n        \".gitignore\",\n        \"theme/templates.yaml\",\n        \"theme/parameters.yaml\",\n        \"theme/assets/\",\n        \"scripts/\",\n        ...(legacy ? [\"forms/\", \"modules/\", \"server_modules/\"] : [\"client_code/\", \"server_code/\"]),\n    ];\n    if (!legacy) paths.push(\"__init__.py\", \"README.md\");\n    if (app.conflicts) paths.push(\"CONFLICTS.yaml\");\n    const modulePath = (name: string, isPackage = false) =>\n        legacy ? name : name.replaceAll(\".\", \"/\") + (isPackage ? \"/__init__\" : \"\");\n    for (const item of getForms(state)) {\n        const path = `${legacy ? \"forms\" : \"client_code\"}/${modulePath(item.fullName, item.isPackage)}`;\n        paths.push(path + \".py\", path + \".yaml\", path + \".html\");\n    }\n    for (const item of getModules(state)) {\n        paths.push(`${legacy ? \"modules\" : \"client_code\"}/${modulePath(item.fullName, item.isPackage)}.py`);\n    }\n    for (const item of getServerModules(state)) {\n        paths.push(`${legacy ? \"server_modules\" : \"server_code\"}/${modulePath(item.fullName, item.isPackage)}.py`);\n    }\n    for (const item of getScripts(state)) paths.push(`scripts/${item.fullName}.py`);\n    for (const item of getAppAssets(state)) paths.push(`theme/assets/${item.fullName}`);\n    if (app.config.runtime_options.server_spec?.requirements !== undefined) {\n        paths.push(legacy ? \"anvil-server-requirements.txt\" : \"server_code/requirements.txt\");\n    }\n    return paths;\n}\n\n/** Add and save missing files from the platform's configured templates, preserving existing app files. */\nexport const addMissingExtraAppFilesFromTemplate =\n    (): AnvilAsyncAction<number> => async (dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n        const branch = getApp(getState())?.editState.branch;\n        const availableExtraFiles = await getExtraAppFileTemplates();\n        if (getAppId(getState()) !== appId || getApp(getState())?.editState.branch !== branch) {\n            throw new Error(\"The open app or branch has changed. Please try again.\");\n        }\n        flushUnsavedCallbacks();\n        const state = getState();\n        const app = getApp(state);\n        if (!app?.editState?.editable) throw new Error(\"This app is not editable.\");\n        const { files, added, addedPaths } = mergeMissingExtraFiles(app.config.extra_files ?? {}, availableExtraFiles, {\n            existingFilePaths: getExistingFilePaths(state),\n        });\n        if (!added) return 0;\n        updateState(\"Add missing extra app files\", ({ app }) => {\n            app!.config.extra_files = files as ExtraFiles;\n        });\n        dispatch(markAppPathsUnsaved(addedPaths.map((parts) => [\"EXTRA_FILES\", ...parts])));\n        await dispatch(saveApp(true, \"Add missing extra app files from platform server\"));\n        return added;\n    };\n\nexport const createServerTestRequirements = (): AnvilAsyncAction<void> =>\n    createExtraFile(SERVER_TEST_ROOT, \"requirements.txt\", {\n        initialContent: DEFAULT_SERVER_TEST_REQUIREMENTS,\n    });\n\nexport const ensureServerTestRoot = (): AnvilAction => (dispatch, getState, updateState) => {\n    const state = getState();\n\n    if (!getAppIsEditable(state)) {\n        throw new Error(\"This app is not editable.\");\n    }\n\n    const extraFiles = getAppExtraFiles(state);\n    const testsEntry = extraFiles.tests;\n\n    if (typeof testsEntry === \"string\") {\n        throw new Error(\"Cannot create server tests because tests is already a file.\");\n    }\n\n    const serverTestsEntry = testsEntry?.server_tests;\n\n    if (typeof serverTestsEntry === \"string\") {\n        throw new Error(\"Cannot create server tests because tests/server_tests is already a file.\");\n    }\n\n    const initializer = serverTestsEntry?.[\"__init__.py\"];\n    const exampleTestsFile = serverTestsEntry?.[\"test_examples.py\"];\n    const requirements = serverTestsEntry?.[\"requirements.txt\"];\n\n    if (requirements !== undefined && typeof requirements !== \"string\") {\n        throw new Error(\"Cannot create server tests because tests/server_tests/requirements.txt is not a file.\");\n    }\n\n    if (initializer !== undefined && typeof initializer !== \"string\") {\n        throw new Error(\"Cannot create server tests because tests/server_tests/__init__.py is not a file.\");\n    }\n\n    if (exampleTestsFile !== undefined && typeof exampleTestsFile !== \"string\") {\n        throw new Error(\"Cannot create a example tests because tests/server_tests/test_examples.py is not a file.\");\n    }\n\n    const createInitializer = initializer === undefined;\n    const createExampleTestsFile = exampleTestsFile === undefined;\n    const requirementsContent = requirements === undefined ? \"\" : decodeAssetContent(requirements);\n\n    // Recognize pytest itself, including version constraints and extras.\n    const hasPytest = /^\\s*pytest(?=\\s*(?:$|[\\[<>=!~;@#(]))/im.test(requirementsContent);\n    const updateRequirements = requirements === undefined || !hasPytest;\n\n    if (!createInitializer && !createExampleTestsFile && !updateRequirements) return;\n\n    updateState(\"Initialize server tests\", ({ app }) => {\n        app!.config.extra_files ??= {};\n\n        const testsDirectory = (app!.config.extra_files.tests ??= {}) as ExtraFiles;\n        const serverTestsDirectory = (testsDirectory.server_tests ??= {}) as ExtraFiles;\n\n        if (createInitializer) {\n            serverTestsDirectory[\"__init__.py\"] = encodeAssetContent(\"\");\n        }\n        if (createExampleTestsFile) {\n            serverTestsDirectory[\"test_examples.py\"] = encodeAssetContent(EXAMPLE_TESTS_CONTENT(app!.config.package_name || \"main_app_package\"));\n        }\n        if (updateRequirements) {\n            const separator = requirementsContent && !requirementsContent.endsWith(\"\\n\") ? \"\\n\" : \"\";\n\n            serverTestsDirectory[\"requirements.txt\"] = encodeAssetContent(\n                requirementsContent + separator + DEFAULT_SERVER_TEST_REQUIREMENTS\n            );\n        }\n    });\n\n    if (createInitializer) {\n        dispatch(markAppPathUnsaved([\"EXTRA_FILES\", \"tests\", \"server_tests\", \"__init__.py\"]));\n    }\n\n    if (createExampleTestsFile) {\n        dispatch(markAppPathUnsaved([\"EXTRA_FILES\", \"tests\", \"server_tests\", \"test_examples.py\"]));\n    }\n\n    if (updateRequirements) {\n        dispatch(markAppPathUnsaved([\"EXTRA_FILES\", \"tests\", \"server_tests\", \"requirements.txt\"]));\n    }\n\n    dispatch(rebuildCodeStructureAndSyncCache(new Set()));\n};\n\nexport const convertExtraDirectoryToPackage =\n    (directoryPath: string): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const state = getState();\n\n        if (!getAppIsEditable(state)) {\n            throw new Error(\"This app is not editable.\");\n        }\n\n        const parts = directoryPath.split(\"/\");\n\n        if (parts.some((part) => !part || part === \".\" || part === \"..\")) {\n            throw new Error(\"Invalid directory path.\");\n        }\n\n        const entry = getExtraFileEntry(getAppExtraFiles(state), directoryPath);\n\n        if (entry === undefined) {\n            throw new Error(\"The directory no longer exists.\");\n        }\n\n        if (typeof entry === \"string\") {\n            throw new Error(\"Only directories can be converted into packages.\");\n        }\n\n        const initializer = entry[\"__init__.py\"];\n\n        if (typeof initializer === \"string\") {\n            return;\n        }\n\n        if (initializer !== undefined) {\n            throw new Error(\"__init__.py already exists but is not a file.\");\n        }\n\n        const initializerPath = `${directoryPath}/__init__.py`;\n        const initializerCacheKey = getCacheKey([\"CODE\", `extra_files/${initializerPath}`], state);\n\n        const removeGitkeep = typeof entry[\".gitkeep\"] === \"string\";\n\n        updateState(\"Convert extra-file directory to package\", (draft) => {\n            const directory = getExtraFileEntry(draft.app!.config.extra_files!, directoryPath) as ExtraFiles;\n\n            directory[\"__init__.py\"] = encodeAssetContent(\"\");\n\n            if (removeGitkeep) {\n                delete directory[\".gitkeep\"];\n            }\n\n            // A new initializer must not inherit old editor history.\n            delete draft.editHistory[initializerCacheKey];\n        });\n\n        dispatch(markAppPathUnsaved([\"EXTRA_FILES\", ...parts, \"__init__.py\"]));\n\n        if (removeGitkeep) {\n            dispatch(markAppPathUnsaved([\"EXTRA_FILES\", ...parts, \".gitkeep\"]));\n        }\n\n        dispatch(rebuildCodeStructureAndSyncCache(new Set()));\n    };\n","import {\n    LEGACY_CUSTOM_COMPONENT_SPEC,\n    LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX,\n    LEGACY_DEPENDENCY_FORM_PROPERTY_SPEC,\n    PACKAGE_QUALIFIED_FORM_NAME,\n} from \"@runtime/runner/component-spec-constants\";\nimport type { DependencyConfig, IDEDependencyCode } from \"@/types\";\n\ntype DependencyCodeEntry = {\n    package_name?: string;\n    forms?: Array<{ class_name: string; toolbox_item?: { title?: string } }>;\n};\n\nexport interface EditorFormSpecContext {\n    appPackageName?: string;\n    dependencies?: DependencyConfig[];\n    dependencyIds?: Record<string, string>;\n    dependencyCode?: Partial<Record<string, DependencyCodeEntry | undefined>> | IDEDependencyCode;\n    localFormExists?: (appLocalFormName: string) => boolean;\n}\n\ninterface EditorFormSpecInfoBase {\n    originalSpec: string;\n    packageName?: string;\n    logicalDepId?: string;\n    depAppId?: string;\n    depCode?: DependencyCodeEntry;\n    isBuiltin: boolean;\n    isCustomForm: boolean;\n    isDependency: boolean;\n    legacy: boolean;\n}\n\ninterface EditorBuiltInComponentInfo extends EditorFormSpecInfoBase {\n    appLocalFormName?: never;\n    packageQualifiedFormName?: never;\n    qualifiedComponentName: string;\n    isBuiltin: true;\n    isCustomForm: false;\n}\n\ninterface EditorCustomFormSpecInfo extends EditorFormSpecInfoBase {\n    appLocalFormName: string;\n    packageQualifiedFormName: string;\n    qualifiedComponentName: string;\n    isBuiltin: false;\n    isCustomForm: true;\n}\n\nexport type EditorFormSpecInfo = EditorBuiltInComponentInfo | EditorCustomFormSpecInfo;\n\n/**\n * Editor-side reader for persisted strings that may identify form-backed\n * components.\n *\n * A customComponentSpec is a component YAML `type` value when the component is\n * a form-backed custom component. Built-in component YAML types such as\n * `Button` are not customComponentSpecs, but this reader still returns their\n * qualified component name for editor display/autocomplete callers.\n *\n * A formPropertySpec is a form-typed property value such as\n * RepeatingPanel.item_template. appLocalFormName values come from\n * `forms[*].class_name`; packageQualifiedFormName values prefix that name with\n * a Python package name. logicalDepId is the legacy dependency alias in specs;\n * depAppId is the resolved dependency app ID used to read dependency code.\n */\n\nconst dependencyCodeEntries = (context: EditorFormSpecContext) => Object.entries(context.dependencyCode ?? {});\n\nconst depIdentifierMatches = (dep: DependencyConfig, logicalDepId: string) =>\n    dep.dep_id === logicalDepId || dep.app_id === logicalDepId;\n\nconst getDependencyByLogicalDepId = (logicalDepId: string, context: EditorFormSpecContext) =>\n    context.dependencies?.find((dep) => depIdentifierMatches(dep, logicalDepId));\n\nconst getDependencyByPackageName = (packageName: string, context: EditorFormSpecContext) =>\n    context.dependencies?.find((dep) => dep.resolution_hints?.package_name === packageName);\n\nconst getDependencyCodeByPackageName = (packageName: string, context: EditorFormSpecContext) =>\n    dependencyCodeEntries(context).find(([, dep]) => dep?.package_name === packageName)?.[1];\n\nconst getDepAppIdForPackageName = (packageName: string, context: EditorFormSpecContext) => {\n    const depAppIdFromCode = dependencyCodeEntries(context).find(([, dep]) => dep?.package_name === packageName)?.[0];\n    if (depAppIdFromCode) {\n        return depAppIdFromCode;\n    }\n\n    const dep = getDependencyByPackageName(packageName, context);\n    return dep?.app_id || (dep?.dep_id ? context.dependencyIds?.[dep.dep_id] : undefined);\n};\n\nconst getPackageNameForLogicalDepId = (\n    logicalDepId: string,\n    depAppId: string | undefined,\n    context: EditorFormSpecContext\n) =>\n    (depAppId && context.dependencyCode?.[depAppId]?.package_name) ||\n    getDependencyByLogicalDepId(logicalDepId, context)?.resolution_hints?.package_name;\n\nconst packageQualifiedFormNameFor = (packageName: string | undefined, appLocalFormName: string) =>\n    packageName ? `${packageName}.${appLocalFormName}` : appLocalFormName;\n\nconst localAppLocalFormNameExists = (appLocalFormName: string, context: EditorFormSpecContext) =>\n    context.localFormExists?.(appLocalFormName) ?? false;\n\nconst customFormInfo = ({\n    originalSpec,\n    appLocalFormName,\n    packageName,\n    logicalDepId,\n    depAppId,\n    depCode,\n    isDependency,\n    legacy,\n}: {\n    originalSpec: string;\n    appLocalFormName: string;\n    packageName?: string;\n    logicalDepId?: string;\n    depAppId?: string;\n    depCode?: DependencyCodeEntry;\n    isDependency: boolean;\n    legacy: boolean;\n}): EditorCustomFormSpecInfo => {\n    const packageQualifiedFormName = packageQualifiedFormNameFor(packageName, appLocalFormName);\n    return {\n        originalSpec,\n        appLocalFormName,\n        packageQualifiedFormName,\n        qualifiedComponentName: packageQualifiedFormName,\n        packageName,\n        logicalDepId,\n        depAppId,\n        depCode,\n        isBuiltin: false,\n        isCustomForm: true,\n        isDependency,\n        legacy,\n    };\n};\n\nexport const componentYamlTypeInfoForEditor = (\n    componentYamlType: string,\n    context: EditorFormSpecContext = {}\n): EditorFormSpecInfo => {\n    const legacyMatch = componentYamlType.match(LEGACY_CUSTOM_COMPONENT_SPEC);\n    if (legacyMatch) {\n        const [, logicalDepId, appLocalFormName] = legacyMatch;\n        const depAppId = logicalDepId ? context.dependencyIds?.[logicalDepId] : undefined;\n        const packageName = logicalDepId\n            ? getPackageNameForLogicalDepId(logicalDepId, depAppId, context)\n            : context.appPackageName;\n        const depCode = depAppId ? context.dependencyCode?.[depAppId] : undefined;\n\n        return customFormInfo({\n            originalSpec: componentYamlType,\n            appLocalFormName,\n            packageName,\n            logicalDepId,\n            depAppId,\n            depCode,\n            isDependency: !!(logicalDepId && (depAppId || packageName)),\n            legacy: true,\n        });\n    }\n\n    const packageMatch = !componentYamlType.startsWith(\"anvil.\")\n        ? componentYamlType.match(PACKAGE_QUALIFIED_FORM_NAME)\n        : null;\n    if (packageMatch) {\n        const [, packageName, appLocalFormName] = packageMatch;\n        const depAppId =\n            packageName === context.appPackageName ? undefined : getDepAppIdForPackageName(packageName, context);\n        const depCode = depAppId\n            ? context.dependencyCode?.[depAppId]\n            : getDependencyCodeByPackageName(packageName, context);\n\n        return customFormInfo({\n            originalSpec: componentYamlType,\n            appLocalFormName,\n            packageName,\n            depAppId,\n            depCode,\n            isDependency: !!depAppId || !!depCode,\n            legacy: false,\n        });\n    }\n\n    return {\n        originalSpec: componentYamlType,\n        qualifiedComponentName: componentYamlType.includes(\".\") ? componentYamlType : `anvil.${componentYamlType}`,\n        isBuiltin: true,\n        isCustomForm: false,\n        isDependency: false,\n        legacy: false,\n    };\n};\n\nexport const componentYamlTypesReferToSameForm = (\n    leftType: string | undefined,\n    rightType: string | undefined,\n    context: EditorFormSpecContext = {}\n): boolean => {\n    if (!leftType || !rightType) {\n        return false;\n    }\n    if (leftType === rightType) {\n        return true;\n    }\n\n    const left = componentYamlTypeInfoForEditor(leftType, context);\n    const right = componentYamlTypeInfoForEditor(rightType, context);\n    return left.isCustomForm && right.isCustomForm && left.packageQualifiedFormName === right.packageQualifiedFormName;\n};\n\nexport const formPropertySpecInfoForEditor = (\n    formPropertySpec: string,\n    context: EditorFormSpecContext = {}\n): EditorCustomFormSpecInfo | null => {\n    if (!formPropertySpec || formPropertySpec.startsWith(LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX)) {\n        return null;\n    }\n\n    const dependencyFormMatch = formPropertySpec.match(LEGACY_DEPENDENCY_FORM_PROPERTY_SPEC);\n    if (dependencyFormMatch) {\n        const [, logicalDepId, appLocalFormName] = dependencyFormMatch;\n        const depAppId = context.dependencyIds?.[logicalDepId];\n        const packageName = getPackageNameForLogicalDepId(logicalDepId, depAppId, context);\n        const depCode = depAppId ? context.dependencyCode?.[depAppId] : undefined;\n\n        return customFormInfo({\n            originalSpec: formPropertySpec,\n            appLocalFormName,\n            packageName,\n            logicalDepId,\n            depAppId,\n            depCode,\n            isDependency: !!(depAppId || packageName),\n            legacy: true,\n        });\n    }\n\n    if (localAppLocalFormNameExists(formPropertySpec, context)) {\n        return customFormInfo({\n            originalSpec: formPropertySpec,\n            appLocalFormName: formPropertySpec,\n            packageName: context.appPackageName,\n            isDependency: false,\n            legacy: true,\n        });\n    }\n\n    const packageMatch = formPropertySpec.match(PACKAGE_QUALIFIED_FORM_NAME);\n    if (packageMatch) {\n        const [, packageName, appLocalFormName] = packageMatch;\n        const depAppId =\n            packageName === context.appPackageName ? undefined : getDepAppIdForPackageName(packageName, context);\n        const depCode = depAppId\n            ? context.dependencyCode?.[depAppId]\n            : getDependencyCodeByPackageName(packageName, context);\n\n        // Match the runtime parser: once exact appLocalFormName lookup fails,\n        // dotted formPropertySpecs are packageQualifiedFormNames, even when\n        // the package is not loaded in the editor.\n        return customFormInfo({\n            originalSpec: formPropertySpec,\n            appLocalFormName,\n            packageName,\n            depAppId,\n            depCode,\n            isDependency: !!depAppId || !!depCode,\n            legacy: false,\n        });\n    }\n\n    return customFormInfo({\n        originalSpec: formPropertySpec,\n        appLocalFormName: formPropertySpec,\n        packageName: context.appPackageName,\n        isDependency: false,\n        legacy: true,\n    });\n};\n","import {\n    LEGACY_CUSTOM_COMPONENT_SPEC,\n    LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX,\n    PACKAGE_QUALIFIED_FORM_NAME,\n} from \"@runtime/runner/component-spec-constants\";\nimport { makeLegacyCustomComponentSpec } from \"./form-spec-writers\";\n\n/**\n * Rewrite helpers for already-stored IDE YAML, not runtime parsers.\n *\n * customComponentSpec: component/layout `type` values that may identify\n * form-backed components, for example `form:Form1` or `AppPackage.Form1`.\n * formPropertySpec: form-typed property values such as\n * RepeatingPanel.item_template, for example `Form1`, `dep_abc:Form1`, or\n * `AppPackage.Form1`.\n * appLocalFormName: a value from `forms[*].class_name`, such as `Form1` or\n * `Folder.Form1`. packageQualifiedFormName: package name plus appLocalFormName.\n * logicalDepId: legacy dependency alias used in specs, such as `dep_abc`.\n */\nexport const renameLocalFormInCustomComponentSpec = (\n    customComponentSpec: string | undefined,\n    oldToNewFullNames: Record<string, string>,\n    appPackageName?: string\n): string | null => {\n    if (!customComponentSpec) {\n        return null;\n    }\n\n    const oldFormatMatch = customComponentSpec.match(LEGACY_CUSTOM_COMPONENT_SPEC);\n    if (oldFormatMatch) {\n        const [, logicalDepId, appLocalFormName] = oldFormatMatch;\n        if (!logicalDepId && appLocalFormName in oldToNewFullNames) {\n            return makeLegacyCustomComponentSpec(oldToNewFullNames[appLocalFormName]);\n        }\n        return null;\n    }\n\n    const packageMatch = customComponentSpec.match(PACKAGE_QUALIFIED_FORM_NAME);\n    if (packageMatch) {\n        const [, packageName, appLocalFormName] = packageMatch;\n        if (appPackageName && packageName === appPackageName && appLocalFormName in oldToNewFullNames) {\n            return `${packageName}.${oldToNewFullNames[appLocalFormName]}`;\n        }\n    }\n    return null;\n};\n\nexport const renameLocalFormInFormPropertySpec = (\n    formPropertySpec: string | undefined,\n    oldToNewFullNames: Record<string, string>,\n    appPackageName?: string\n): string | null => {\n    if (!formPropertySpec || formPropertySpec.startsWith(LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX)) {\n        return null;\n    }\n    if (formPropertySpec in oldToNewFullNames) {\n        return oldToNewFullNames[formPropertySpec];\n    }\n    const packageMatch = formPropertySpec.match(PACKAGE_QUALIFIED_FORM_NAME);\n    if (packageMatch) {\n        const [, packageName, appLocalFormName] = packageMatch;\n        if (appPackageName && packageName === appPackageName && appLocalFormName in oldToNewFullNames) {\n            return `${packageName}.${oldToNewFullNames[appLocalFormName]}`;\n        }\n    }\n    return null;\n};\n","import { LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX } from \"@runtime/runner/component-spec-constants\";\n\n/**\n * Build the legacy customComponentSpec used when package-qualified specs are\n * unavailable. Do not use this for formPropertySpec values such as\n * RepeatingPanel.item_template.\n */\nexport const makeLegacyCustomComponentSpec = (formName: string, logicalDepId?: string | null): string =>\n    logicalDepId\n        ? `${LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX}${logicalDepId}:${formName}`\n        : `${LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX}${formName}`;\n\nexport interface FormSpecWriterInput {\n    appLocalFormName: string;\n    packageName?: string | null;\n    logicalDepId?: string | null;\n}\n\n/**\n * Pure string writer for YAML component `type` values. Callers mutate YAML by\n * assigning the returned customComponentSpec to a component or layout owner.\n */\nexport const makeCustomComponentSpec = ({ appLocalFormName, packageName, logicalDepId }: FormSpecWriterInput): string => {\n    if (packageName) {\n        return `${packageName}.${appLocalFormName}`;\n    }\n    return makeLegacyCustomComponentSpec(appLocalFormName, logicalDepId);\n};\n\n/**\n * Pure string writer for form-typed component property values. Callers mutate\n * YAML by assigning the returned formPropertySpec to that property.\n */\nexport const makeFormPropertySpec = ({ appLocalFormName, packageName, logicalDepId }: FormSpecWriterInput): string => {\n    if (packageName) {\n        return `${packageName}.${appLocalFormName}`;\n    }\n    return logicalDepId ? `${logicalDepId}:${appLocalFormName}` : appLocalFormName;\n};\n","import { useEffect, useMemo } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { isEmpty, isEqual } from \"lodash-es\";\nimport { createSelector } from \"reselect\";\nimport semver from \"semver\";\nimport { getTyAnalysisEnabled } from \"@/analysis/ide-analysis\";\nimport * as api from \"@/api\";\nimport { maybeShowGitDesyncModal } from \"@/controllers/app/remotes\";\nimport type {\n    AnvilAction,\n    AnvilAsyncAction,\n    AnvilDispatch,\n    AppConfig,\n    AppConflicts,\n    AppEditState,\n    AppId,\n    AppPath,\n    AppRefs,\n    ChangedCodePath,\n    ChangedExtraFilesPath,\n    ChangedSettingsPath,\n    CodePath,\n    CommitHistory,\n    CommitVersion,\n    ConflictItemSpec,\n    ConflictingItem,\n    Conflicts,\n    FormItemYaml,\n    MalleableCommitEntry,\n    ModuleItemYaml,\n    RawCommitRef,\n    State,\n    ThemeConfig,\n    UpdateState,\n} from \"@/types\";\nimport useEffectEvent from \"@/util/useEffectEvent\";\nimport { openOrFocusBottomTab } from \"../bottom-tabs\";\nimport { reloadDependencies } from \"../dependencies\";\nimport { getEnvironments, loadEnvironments } from \"../environments\";\nimport { getIsAllSaved, getUser } from \"../ide\";\nimport { alert, confirm, modal } from \"../modals\";\nimport { revalidateAndReloadOpenTabs } from \"../tabs\";\nimport { recordActivity } from \"../util\";\nimport { WebsocketEvent, WebsocketEventListenerConfig, useWebsocketEventListeners } from \"../websocket\";\nimport * as autocompleter from \"./autocompleter\";\nimport {\n    generateItemId,\n    getCachedCodeItem,\n    getCodeNames,\n    mutateItem,\n    rebuildCodeStructureAndSyncCache,\n    setCodeItemHistory,\n} from \"./code\";\nimport {\n    clearUnsaved,\n    getApp,\n    getAppEditState,\n    getAppId,\n    getAppIsEditable,\n    getInvalidYaml,\n    markAppPathUnsaved,\n    resetAppState,\n    updateAppSchemaSync,\n    updateGlobalLoadingIndicator,\n} from \"./index\";\nimport { saveApp, waitForSavingComplete } from \"./saving\";\n\nconst COMMIT_FREEZE_TIMEOUT = 1000 * 60 * 15;\nlet malleableCommitTimeout: number | undefined = undefined;\n\ntype HistoryStateUpdater = (state: State) => void;\ntype HistoryMergeRef = RawCommitRef & { \"merge-info\"?: { source?: string; target?: string } };\ntype IncrementalEditContext = { branch?: string; merge?: number; visiting?: boolean };\ntype WebsocketIncrementalPayload = {\n    status?: string;\n    changes?: {\n        changes: IncrementalChange[];\n        edit_session?: string;\n    };\n};\ntype ConfigIncrementalChange = {\n    item_type: \"config\";\n    change_type: \"modified\";\n    path: string;\n    content?: Partial<AppConfig>;\n    deleted_keys?: Array<keyof AppConfig>;\n};\ntype ThemeConfigIncrementalChange = {\n    item_type: \"theme_config\";\n    change_type: \"added\" | \"modified\" | \"deleted\";\n    path: keyof ThemeConfig;\n    content?: ThemeConfig[keyof ThemeConfig];\n};\ntype ConflictIncrementalChange = {\n    item_type: \"conflicts\";\n    change_type: \"added\" | \"modified\" | \"deleted\";\n    path: string;\n    content?: AppConflicts;\n};\ntype RequirementsIncrementalChange = {\n    item_type: \"requirements\";\n    change_type: \"added\" | \"modified\" | \"deleted\";\n    path: string;\n    content?: string;\n};\ntype CodeIncrementalChange = {\n    item_type: \"form\" | \"module\" | \"server_module\" | \"script\";\n    change_type: \"added\" | \"modified\" | \"deleted\";\n    path: string;\n    code?: string;\n    yaml?: Partial<FormItemYaml>;\n    id?: string;\n    is_package?: boolean;\n};\ntype AssetIncrementalChange = {\n    item_type: \"asset\";\n    change_type: \"added\" | \"modified\" | \"deleted\";\n    path: string;\n    content?: string;\n    id?: string;\n};\ntype ExtraFilesIncrementalChange = {\n    item_type: \"extra_files\";\n    change_type: \"added\" | \"modified\" | \"deleted\";\n    path: string;\n    content?: string;\n};\ntype IncrementalChange =\n    | ConfigIncrementalChange\n    | ThemeConfigIncrementalChange\n    | ConflictIncrementalChange\n    | RequirementsIncrementalChange\n    | CodeIncrementalChange\n    | AssetIncrementalChange\n    | ExtraFilesIncrementalChange;\ntype IncrementalData = {\n    from_commit?: string;\n    to_commit: string;\n    changes: IncrementalChange[];\n    edit_session?: string;\n    edit_state?: AppEditState;\n    to_commit_info?: CommitVersion;\n};\ntype ExtraFilesTree = { [key: string]: string | ExtraFilesTree };\n\ninterface DependencyBranchWatch {\n    appId: AppId;\n    branch: string;\n}\n\nconst getBranchForDependencyVersionSpec = (versionSpec: unknown) => {\n    if (!versionSpec || typeof versionSpec !== \"object\") {\n        return undefined;\n    }\n    if (\"branch\" in versionSpec && typeof versionSpec.branch === \"string\") {\n        return versionSpec.branch;\n    }\n    if (\"dev\" in versionSpec && versionSpec.dev === true) {\n        return \"master\";\n    }\n    return undefined;\n};\n\nconst getDependencyBranchWatches = createSelector(\n    [(state: State) => state.app?.config?.dependency_order, (state: State) => state.app?.dependencyCode],\n    (dependencyOrder, dependencyCode): DependencyBranchWatch[] => {\n        if (!dependencyOrder || !dependencyCode) {\n            return [];\n        }\n\n        const seen = new Set<string>();\n        const watches: DependencyBranchWatch[] = [];\n        for (const appId of dependencyOrder) {\n            const branch = getBranchForDependencyVersionSpec(dependencyCode[appId]?.[\"version-spec\"]);\n            if (!branch) {\n                continue;\n            }\n            const depAppId = appId as AppId;\n            const key = `${appId}:${branch}`;\n            if (seen.has(key)) {\n                continue;\n            }\n            seen.add(key);\n            watches.push({ appId: depAppId, branch });\n        }\n        return watches;\n    }\n);\n\nconst reloadDependenciesFromRepoUpdate = (): AnvilAsyncAction<void> => async (dispatch, getState) => {\n    const app = getApp(getState());\n    if (!app) {\n        return;\n    }\n\n    // TODO: Make dependency REPO_UPDATE refresh less aggressive by reloading only the changed dependency and dependents.\n    await dispatch(\n        reloadDependencies(app, {\n            ensureNoNewerDependencyRuntime: false,\n            markUnsaved: false,\n            saveBeforeReload: false,\n        })\n    );\n};\n\nconst isWatchedDependencyBranchUpdate = (\n    appId: string,\n    ref: string | undefined,\n    dependencyBranchWatches: DependencyBranchWatch[]\n) => !!ref && dependencyBranchWatches.some((watch) => watch.appId === appId && ref === `refs/heads/${watch.branch}`);\n\ntype CodeConflictItem = {\n    conflicts?: Conflicts;\n    resolvedConflictItem?: ConflictItemSpec;\n    resolvedConflictMerge?: AppConflicts[\"merge\"];\n};\ntype MutableThemeConfig = {\n    parameters?: ThemeConfig[\"parameters\"];\n    templates?: ThemeConfig[\"templates\"];\n};\n\nconst requireApp = (state: State) => {\n    const app = state.app;\n    if (!app) {\n        throw new Error(\"App state is not loaded\");\n    }\n    return app;\n};\n\nconst isCodeIncrementalChange = (\n    change: IncrementalChange\n): change is Extract<IncrementalChange, { item_type: \"form\" | \"module\" | \"server_module\" | \"script\" | \"asset\" }> =>\n    [\"form\", \"module\", \"server_module\", \"script\", \"asset\"].includes(change.item_type);\n\n// This function removes malleable commits that have timed out, and sets a timer to dispatch itself again next time one will time out.\nconst cleanupMalleableCommits = (): AnvilAction => (dispatch, getState, updateState) => {\n    clearTimeout(malleableCommitTimeout);\n    const state = getState();\n    const app = getApp(state);\n    if (!app) {\n        return;\n    }\n    const malleableCommits = getAppMalleableCommits(state);\n    let earliestMalleable = null;\n    for (const [ref, { updated }] of Object.entries(malleableCommits)) {\n        const updatedTime = Date.parse(updated);\n        const dt = Date.now() - updatedTime;\n\n        if (dt > COMMIT_FREEZE_TIMEOUT) {\n            // This commit has frozen. Forget about it.\n            updateState(({ app }) => {\n                if (!app) return;\n                delete app.malleableCommits[ref];\n            });\n        } else {\n            // This commit hasn't frozen yet. Keep track of the earliest one that will time out.\n            if (!earliestMalleable) {\n                earliestMalleable = updatedTime;\n            } else {\n                earliestMalleable = Math.min(earliestMalleable, updatedTime);\n            }\n        }\n    }\n    if (earliestMalleable) {\n        const earliestTimeout = earliestMalleable + COMMIT_FREEZE_TIMEOUT; // Malleable commits freeze after 15 mins.\n        clearTimeout(malleableCommitTimeout);\n        malleableCommitTimeout = setTimeout(() => dispatch(cleanupMalleableCommits()), earliestTimeout - Date.now());\n    }\n};\n\n// Malleable commits change when we load the app, when we receive an event about things other people are doing, and when we save.\n// All updates go through one of these two functions.\n\nexport const setMalleableCommits =\n    (malleableCommits: Record<string, MalleableCommitEntry | null>): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        // Some might be set to null. If so, drop them.\n        const toRemove = [];\n        for (const ref in malleableCommits) {\n            if (malleableCommits[ref] === null) {\n                toRemove.push(ref);\n            }\n        }\n        for (const ref of toRemove) {\n            delete malleableCommits[ref];\n        }\n\n        updateState(({ app }) => {\n            if (!app) return;\n            app.malleableCommits = malleableCommits as Record<string, MalleableCommitEntry>;\n        });\n        dispatch(cleanupMalleableCommits());\n    };\n\n// Setting commitInfo to null removes the malleable commit entirely.\nexport const updateMalleableCommits =\n    (ref: string, commitInfo: MalleableCommitEntry | null): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(\"Update malleable commits\", ({ app }) => {\n            if (!app) return;\n            if (commitInfo) {\n                app.malleableCommits[ref] = commitInfo;\n            } else {\n                delete app.malleableCommits[ref];\n            }\n        });\n        dispatch(cleanupMalleableCommits());\n    };\n\nexport const freezeCommit =\n    (commitId: string): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(`Freeze commit ${commitId}`, ({ app }) => {\n            if (!app) return;\n            const affected = Object.entries(app.malleableCommits).filter(([, entry]) => entry.oid === commitId);\n            for (const [b, _] of affected) {\n                delete app.malleableCommits[b];\n            }\n        });\n    };\n\n// Local utility only\nconst ingestRefUpdate =\n    ({ ref, ...refSpec }: { ref: string } & RawCommitRef) =>\n    (state: State) => {\n        const app = requireApp(state);\n        app.commitHistory.refs[ref] = refSpec;\n    };\n\nexport const withSuppressReloadingOnBranchMove = async (updateState: UpdateState, f: () => Promise<void>) => {\n    try {\n        updateState((state) => {\n            state.suppressReloadingOnBranchMove++;\n        });\n        return await f();\n    } finally {\n        updateState((state) => {\n            state.suppressReloadingOnBranchMove--;\n        });\n    }\n};\n\n// Returns false if the user cancelled, true if safe to proceed.\n// Caller should re-read getState() afterward as saves may update commitSha.\nconst ensureChangesSaved =\n    (appId: string | null | undefined): AnvilAsyncAction<boolean> =>\n    async (dispatch, getState) => {\n        const state = getState();\n        if (getIsAllSaved(state)) {\n            return true;\n        }\n\n        if (!isEmpty(state.unsavedAppPaths)) {\n            dispatch(updateGlobalLoadingIndicator(\"Saving changes...\"));\n            await dispatch(saveApp());\n        }\n\n        if (!isEmpty(getState().savingAppPaths)) {\n            dispatch(updateGlobalLoadingIndicator(\"Waiting for save to complete...\"));\n            const saveCompleted = await dispatch(waitForSavingComplete());\n            dispatch(updateGlobalLoadingIndicator(false));\n\n            if (!saveCompleted) {\n                const proceedAnyway = await dispatch(\n                    confirm(\n                        \"Save taking too long\",\n                        \"A save operation is still in progress. Switching branches now may lose changes. Continue anyway?\"\n                    )\n                );\n                if (!proceedAnyway) return false;\n                dispatch(clearUnsaved());\n            }\n        } else {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n\n        if (!isEmpty(getState().unsavedAppPaths)) {\n            const confirmed = await dispatch(\n                confirm(\n                    \"Discard changes?\",\n                    \"Some changes could not be saved. Switching branches will discard them. Continue?\"\n                )\n            );\n            if (!confirmed) return false;\n            dispatch(clearUnsaved());\n        }\n\n        return true;\n    };\n\n// Incremental update helpers.\n// Each returns a thunk that resolves to true (applied) or false (skipped/failed).\n\nconst tryIncrementalCheckout =\n    ({\n        appId,\n        currentCommitSha,\n        commitId,\n        checkoutBranch,\n        possibleMerge,\n    }: {\n        appId: string | null | undefined;\n        currentCommitSha?: string | null;\n        commitId?: string | null;\n        checkoutBranch?: string | null;\n        possibleMerge?: [string, RawCommitRef] | undefined;\n    }): AnvilAsyncAction<boolean> =>\n    async (dispatch, getState, updateState) => {\n        if (!(appId && currentCommitSha && commitId && currentCommitSha !== commitId)) {\n            return false;\n        }\n\n        const loadingMessage = checkoutBranch\n            ? `Switching to branch '${checkoutBranch}'`\n            : possibleMerge\n              ? \"Switching to unresolved merge\"\n              : `Checking out ${commitId.substring(0, 8)}`;\n\n        dispatch(updateGlobalLoadingIndicator(loadingMessage));\n\n        try {\n            const editContext: IncrementalEditContext = checkoutBranch\n                ? { branch: checkoutBranch }\n                : possibleMerge\n                  ? { merge: parseInt(possibleMerge[0].substring(21), 10) }\n                  : { visiting: true };\n            const incrementalData = (await api.getIncrementalChanges(\n                appId,\n                currentCommitSha,\n                commitId,\n                editContext\n            )) as IncrementalData;\n            const success = await dispatch(applyIncrementalUpdate(incrementalData));\n            if (success) {\n                const newEditState = incrementalData.edit_state;\n                if (!newEditState) {\n                    return false;\n                }\n                await api.setDevelopmentVersion(appId, newEditState);\n                updateState(({ app, editHistory }) => {\n                    if (!app) return;\n                    app.editState = newEditState;\n                    // An explicit checkout ends the old merge's undo context,\n                    // including when unchanged files keep their text history.\n                    for (const history of Object.values(editHistory)) delete history.resolvedConflictMerge;\n                });\n                if (!checkoutBranch && !possibleMerge) {\n                    dispatch(freezeCommit(commitId));\n                }\n                await dispatch(loadCommitIntoHistory(commitId));\n                dispatch(updateGlobalLoadingIndicator(false));\n                dispatch(recordActivity(\"incrementalCheckout\", { from: currentCommitSha, to: commitId }));\n                return true;\n            }\n        } catch (error) {\n            console.warn(\"Incremental checkout failed, falling back to full load:\", error);\n        }\n        dispatch(updateGlobalLoadingIndicator(false));\n        return false;\n    };\n\nconst tryWsIncrementalUpdate =\n    ({\n        incremental,\n        currentCommitSha,\n        expectedFromCommit,\n        newCommitSha,\n        commit,\n    }: {\n        incremental?: WebsocketIncrementalPayload;\n        currentCommitSha?: string | null;\n        expectedFromCommit?: string | null;\n        newCommitSha?: string | null;\n        commit?: CommitVersion | null;\n    }): AnvilAsyncAction<boolean> =>\n    async (dispatch) => {\n        if (incremental?.status === \"ok\" && incremental.changes && currentCommitSha === expectedFromCommit) {\n            console.info(`Using websocket incremental payload (fast path): ${currentCommitSha} -> ${newCommitSha}`);\n            try {\n                const success = await dispatch(\n                    applyIncrementalUpdate({\n                        from_commit: expectedFromCommit ?? undefined,\n                        to_commit: newCommitSha!,\n                        changes: incremental.changes.changes,\n                        edit_session: incremental.changes.edit_session,\n                        to_commit_info: commit ?? undefined,\n                    })\n                );\n                if (success) {\n                    dispatch(\n                        recordActivity(\"incrementalUpdate\", {\n                            from: expectedFromCommit,\n                            to: newCommitSha,\n                            via: \"websocket\",\n                        })\n                    );\n                    return true;\n                }\n            } catch (error) {\n                console.warn(\"Websocket incremental update failed, trying HTTP:\", error);\n            }\n        } else if (incremental?.status && incremental.status !== \"ok\") {\n            console.info(`Websocket incremental not available: ${incremental.status}`);\n        } else if (incremental && currentCommitSha !== expectedFromCommit) {\n            console.info(\n                `Client not at expected commit (${currentCommitSha} vs ${expectedFromCommit}), using HTTP fallback`\n            );\n        }\n        return false;\n    };\n\nconst tryHttpIncrementalUpdate =\n    ({\n        appId,\n        currentCommitSha,\n        newCommitSha,\n    }: {\n        appId: string | null | undefined;\n        currentCommitSha?: string | null;\n        newCommitSha?: string | null;\n    }): AnvilAsyncAction<boolean> =>\n    async (dispatch) => {\n        if (!(appId && currentCommitSha && newCommitSha && currentCommitSha !== newCommitSha)) {\n            return false;\n        }\n        console.info(`Trying HTTP incremental update: ${currentCommitSha} -> ${newCommitSha}`);\n        try {\n            const incrementalData = (await api.getIncrementalChanges(\n                appId,\n                currentCommitSha,\n                newCommitSha\n            )) as IncrementalData;\n            const success = await dispatch(applyIncrementalUpdate(incrementalData));\n            if (success) {\n                console.info(\"HTTP incremental update applied successfully\");\n                dispatch(\n                    recordActivity(\"incrementalUpdate\", {\n                        from: currentCommitSha,\n                        to: newCommitSha,\n                        via: \"http\",\n                    })\n                );\n                return true;\n            }\n        } catch (error) {\n            console.warn(\"HTTP incremental update failed, falling back to full reload:\", error);\n        }\n        return false;\n    };\n\n/**\n * Handle a version update event (branch moved to a new commit).\n *\n * Guard clauses filter out events that don't require action:\n *   1. Missing ref → nothing to do\n *   2. Ref already at target oid → just sync remote-sync metadata\n *   3. Not our branch → update refs/history only, no reload\n *   4. Reload suppressed (our own save, or during merge) → skip\n *\n * When our branch moves and reload isn't suppressed, we try to update\n * incrementally before falling back to a full reload:\n *   WS incremental → HTTP incremental → full reload (focus-gated)\n */\nexport const handleVersionUpdate =\n    (\n        {\n            ref_update,\n            is_malleable,\n            replaced_commit,\n            commit,\n            incremental,\n            invalidYaml,\n        }: {\n            ref_update?: ({ ref: string } & RawCommitRef) | null;\n            is_malleable?: boolean;\n            replaced_commit?: string | null;\n            commit?: CommitVersion | null;\n            incremental?: WebsocketIncrementalPayload;\n            invalidYaml?: boolean;\n        },\n        suppressReload = false\n    ): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        if (!ref_update?.ref) {\n            return;\n        }\n        const { ref, ...refSpec } = ref_update;\n\n        const app = getApp(getState());\n        if (!app) {\n            // The app was probably closed - nothing to update\n            return;\n        }\n        if ((app.commitHistory.refs[ref]?.oid ?? null) === (refSpec.oid ?? null)) {\n            // So the remote and local branch labels show you're actually in sync.\n            if (app.commitHistory.refs[ref]?.[\"remote-sync\"] !== refSpec[\"remote-sync\"]) {\n                updateState(({ app }) => {\n                    if (!app) return;\n                    app.commitHistory.refs[ref][\"remote-sync\"] = refSpec[\"remote-sync\"];\n                });\n            }\n            console.log(\n                `handleVersionUpdate(): ref ${ref} is already at ${app.commitHistory.refs[ref]?.oid} vs ${refSpec.oid}, nothing for handleVersionUpdate() to do`\n            );\n            return;\n        }\n        console.log(\n            `handleVersionUpdate(): ref ${ref} moved from ${app.commitHistory.refs[ref]?.oid} to ${refSpec?.oid}`\n        );\n\n        const movedOurBranch = app.editState.branch && ref === `refs/heads/${app.editState.branch}`;\n\n        updateState((state) => {\n            if (!state.app) {\n                return;\n            }\n            if (commit) {\n                const commits = state.app.commitHistory.versions;\n\n                const replacedCommitIdx = replaced_commit ? commits.findIndex(({ v }) => v === replaced_commit) : -1;\n\n                // Did we just replace a malleable commit?\n                if (commits.find(({ v }) => v === commit.v)) {\n                    console.log(\"Revert to existing commit:\", commit.v);\n                    if (replacedCommitIdx !== -1) {\n                        console.log(\"Splicing out reverted malleable commit:\", commits[replacedCommitIdx].v);\n                        commits.splice(replacedCommitIdx, 1);\n                    }\n                } else if (replacedCommitIdx !== -1) {\n                    commits[replacedCommitIdx] = commit;\n                    console.log(\"Replaced malleable commit\", commit.v);\n                } else {\n                    commits.unshift(commit);\n                    console.log(\"Fresh commit\", commit.v);\n                }\n                state.app.commitHistory.refs[ref] = refSpec;\n            } else {\n                // we delete the branch and then reload it\n                // for this reason, code should not expect the editState.branch to exist in refs.branches\n                delete state.app.commitHistory.refs[ref];\n            }\n        });\n\n        dispatch(\n            updateMalleableCommits(\n                ref,\n                is_malleable\n                    ? {\n                          oid: commit?.v ?? refSpec.oid,\n                          updated: new Date().toISOString(),\n                      }\n                    : null\n            )\n        );\n        if (!movedOurBranch) return;\n        await dispatch(\n            syncLoadedBranchToRef({\n                ref,\n                ref_update: refSpec,\n                commit,\n                incremental,\n                replaced_commit,\n                suppressReload,\n                invalidYaml,\n            })\n        );\n    };\n\nexport const deleteBranch =\n    (branch: string): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        await dispatch(loadEnvironments()); // In case you've just moved away from the branch you're about to delete.\n        const state = getState();\n        const appId = getAppId(state);\n        const envs = getEnvironments(state) || [];\n        const envsOnBranch = envs.filter((e) => e.version?.ref === `refs/heads/${branch}`);\n\n        if (envsOnBranch.length > 0) {\n            // TODO: Nice modal here that explains which environments, and gives more options (keep branch, delete environment, point environment to commit, delete branch anyway)\n            await dispatch(\n                alert(\n                    \"Branch in use\",\n                    `Cannot delete branch ${branch} - it is referenced from one or more environments.`\n                )\n            );\n        } else {\n            await api.deleteBranch(appId, branch);\n            updateState((state) => {\n                if (!state.app) return;\n                delete state.app.commitHistory.refs[`refs/heads/${branch}`];\n            });\n        }\n    };\n\nexport const deleteTag =\n    (tag: string): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = getAppId(state);\n        const envs = getEnvironments(state) || [];\n        const envsOnTag = envs.filter((e) => e.version?.ref === `refs/tags/${tag}`);\n\n        if (envsOnTag.length) {\n            await dispatch(\n                alert(\"Tag in use\", `Cannot delete tag ${tag} - it is referenced from one or more environments.`)\n            );\n        } else if (await dispatch(confirm(\"Delete tag\", `Are you sure you want to delete tag '${tag}'?`))) {\n            await api.deleteTag(appId, tag);\n            updateState((state) => {\n                if (!state.app) return;\n                delete state.app.commitHistory.refs[`refs/tags/${tag}`];\n            });\n        }\n    };\n\nconst commitInLoadedHistory = (commitId: string, state: State) => {\n    const { commitHistory } = requireApp(state);\n    return !!commitHistory.versions.find((commit) => commit.v === commitId);\n};\n\nexport const loadCommitIntoHistory =\n    (commitId: string | null | undefined): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        let state = getState();\n        if (!commitId) return; // can happen in Test Suite app\n        let loadedCommitCount = requireApp(state).commitHistory.versions.length;\n        while (!commitInLoadedHistory(commitId, state)) {\n            state = getState();\n            if (requireApp(state).commitHistory.versions.length < loadedCommitCount) {\n                break;\n            }\n            loadedCommitCount += 500;\n            await dispatch(updateAppCommitHistory(loadedCommitCount));\n        }\n    };\n\nexport const loadVersion = (editState: Partial<AppEditState>, keepMalleable = false): AnvilAsyncAction<void> =>\n    async function (dispatch, getState, updateState) {\n        dispatch(updateGlobalLoadingIndicator(\"Loading app\"));\n        updateState((s) => {\n            s.loadVersionOnFocus = false;\n        });\n        const state = getState();\n        const appId = getAppId(state);\n        if (!appId) {\n            dispatch(updateGlobalLoadingIndicator(false));\n            return;\n        }\n\n        try {\n            const {\n                content,\n                version: commitId,\n                edit_session,\n                edit_state,\n                dependency_graph,\n            } = await api.getApp(appId, editState, keepMalleable);\n            await api.setDevelopmentVersion(appId, edit_state);\n            if (!keepMalleable) {\n                // If we're visiting a malleable commit, it's not malleable any more\n                dispatch(freezeCommit(commitId));\n            }\n            await dispatch(resetAppState(appId, content, edit_state, commitId, { dependencyGraph: dependency_graph }));\n            await dispatch(updateAppSchemaSync());\n            updateState(`Reset edit session`, (state) => {\n                if (!state.app) return;\n                state.app.editSession = edit_session;\n            });\n            dispatch(recordActivity(\"loadAppVersion\", editState));\n            await dispatch(loadCommitIntoHistory(commitId));\n            await dispatch(maybeShowGitDesyncModal());\n        } finally {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n    };\n\n/**\n * Apply incremental changes from the server without full app reload.\n * Used when our branch moves to a new commit (e.g., external push).\n */\nexport const applyIncrementalUpdate =\n    (incrementalData: IncrementalData): AnvilAsyncAction<boolean> =>\n    async (dispatch, getState, updateState) => {\n        const { from_commit, to_commit, changes, edit_session, to_commit_info } = incrementalData;\n        const state = getState();\n        const app = getApp(state);\n\n        if (!app) {\n            console.warn(\"applyIncrementalUpdate: No app state\");\n            return false;\n        }\n        if (from_commit && app.commitSha !== from_commit) {\n            console.warn(\n                `applyIncrementalUpdate: base commit mismatch (app=${app.commitSha}, expected=${from_commit})`\n            );\n            return false;\n        }\n\n        let appSchemaChanged = false;\n        // Update initialCode based on changes.\n        // Changes are processed in server-sent order. The server guarantees one change\n        // per code path — type conversions (form↔module, package↔non-package) are\n        // reported as a single \"modified\" change with the new type, not separate\n        // delete + add. The handlers below defensively remove cross-type items at the\n        // same path (e.g., removing a module when adding a form) to handle conversions.\n        updateState(({ app }) => {\n            if (!app) return;\n\n            const mutableConfig = app.config;\n            const mutableThemeConfig = app.themeConfig;\n            const mutableThemeConfigForIncremental = mutableThemeConfig as MutableThemeConfig;\n            for (const change of changes) {\n                const { change_type, item_type, path } = change;\n\n                switch (item_type) {\n                    case \"config\":\n                        // The server's incremental \"config\" change = parsed anvil.yaml.\n                        // app.config is the {...config} rest from resetAppState, which includes\n                        // both anvil.yaml keys AND server-computed dependency keys\n                        // (dependency_order, dependency_ids, correct_dependency_ids).\n                        // We merge rather than replace to preserve those dependency keys.\n                        // This is safe: dependency changes in anvil.yaml force a full reload\n                        // (the server throws), so incremental config updates only arrive when\n                        // dependencies are unchanged.\n                        const appSchemaBefore = app.config.db_schema;\n                        if (change_type === \"modified\" && change.content) {\n                            Object.assign(app.config, change.content);\n                            // Remove keys that were deleted from anvil.yaml\n                            if (change.deleted_keys) {\n                                for (const key of change.deleted_keys) {\n                                    delete mutableConfig[key];\n                                }\n                            }\n                        }\n                        appSchemaChanged ||= !isEqual(appSchemaBefore, app.config.db_schema);\n                        break;\n\n                    case \"theme_config\": {\n                        // Theme config changes (parameters.yaml, templates.yaml)\n                        // path is \"parameters\" or \"templates\"\n                        if (change_type === \"deleted\") {\n                            if (path === \"parameters\") {\n                                delete mutableThemeConfigForIncremental.parameters;\n                            } else {\n                                delete mutableThemeConfigForIncremental.templates;\n                            }\n                        } else if (change_type === \"added\" || change_type === \"modified\") {\n                            if (path === \"parameters\") {\n                                mutableThemeConfig.parameters = change.content as ThemeConfig[\"parameters\"];\n                            } else {\n                                mutableThemeConfig.templates = change.content as ThemeConfig[\"templates\"];\n                            }\n                        }\n                        break;\n                    }\n\n                    case \"conflicts\":\n                        // CONFLICTS.yaml - merge conflict markers\n                        if (change_type === \"deleted\") {\n                            app.conflicts = undefined;\n                        } else if (change_type === \"added\" || change_type === \"modified\") {\n                            app.conflicts = change.content;\n                        }\n                        break;\n\n                    case \"requirements\":\n                        // requirements.txt - server dependencies\n                        if (change_type === \"deleted\") {\n                            if (app.config.runtime_options?.server_spec) {\n                                delete app.config.runtime_options.server_spec.requirements;\n                                if (isEmpty(app.config.runtime_options.server_spec)) {\n                                    delete app.config.runtime_options.server_spec;\n                                }\n                                if (isEmpty(app.config.runtime_options)) {\n                                    delete (mutableConfig as Partial<AppConfig>).runtime_options;\n                                }\n                            }\n                        } else if (change_type === \"added\" || change_type === \"modified\") {\n                            const runtimeOptions = (mutableConfig.runtime_options ??=\n                                {} as AppConfig[\"runtime_options\"]);\n                            const serverSpec = (runtimeOptions.server_spec ??= {} as NonNullable<\n                                AppConfig[\"runtime_options\"][\"server_spec\"]\n                            >);\n                            serverSpec.requirements = change.content;\n                        }\n                        break;\n\n                    case \"form\": {\n                        if (!app.initialCode.forms) app.initialCode.forms = [];\n                        const forms = app.initialCode.forms;\n                        const existingIdx = forms.findIndex((f) => f.class_name === path);\n\n                        if (change_type === \"deleted\") {\n                            if (existingIdx !== -1) {\n                                forms.splice(existingIdx, 1);\n                            }\n                        } else if (change_type === \"added\" || change_type === \"modified\") {\n                            const existingForm = existingIdx !== -1 ? forms[existingIdx] : undefined;\n                            const form: FormItemYaml = {\n                                ...change.yaml,\n                                class_name: path,\n                                code: change.code || \"\",\n                                id: change.id ?? existingForm?.id ?? generateItemId(),\n                                is_package: change.is_package,\n                            };\n                            // Remove any module with the same path (handles type conversion)\n                            if (app.initialCode.modules) {\n                                const moduleIdx = app.initialCode.modules.findIndex((m) => m.name === path);\n                                if (moduleIdx !== -1) {\n                                    app.initialCode.modules.splice(moduleIdx, 1);\n                                }\n                            }\n                            if (existingIdx !== -1) {\n                                forms[existingIdx] = form;\n                            } else {\n                                forms.push(form);\n                            }\n                        }\n                        break;\n                    }\n\n                    case \"module\": {\n                        if (!app.initialCode.modules) app.initialCode.modules = [];\n                        const modules = app.initialCode.modules;\n                        const existingIdx = modules.findIndex((m) => m.name === path);\n\n                        if (change_type === \"deleted\") {\n                            if (existingIdx !== -1) {\n                                modules.splice(existingIdx, 1);\n                            }\n                        } else if (change_type === \"added\" || change_type === \"modified\") {\n                            const moduleItem = {\n                                name: path,\n                                code: change.code || \"\",\n                                id: change.id ?? modules[existingIdx]?.id ?? generateItemId(),\n                                is_package: change.is_package,\n                            };\n                            // Remove any form with the same path (handles type conversion)\n                            if (app.initialCode.forms) {\n                                const formIdx = app.initialCode.forms.findIndex((f) => f.class_name === path);\n                                if (formIdx !== -1) {\n                                    app.initialCode.forms.splice(formIdx, 1);\n                                }\n                            }\n                            if (existingIdx !== -1) {\n                                modules[existingIdx] = moduleItem;\n                            } else {\n                                modules.push(moduleItem);\n                            }\n                        }\n                        break;\n                    }\n\n                    case \"server_module\": {\n                        if (!app.initialCode.server_modules) app.initialCode.server_modules = [];\n                        const server_modules = app.initialCode.server_modules;\n                        const existingIdx = server_modules.findIndex((m) => m.name === path);\n\n                        if (change_type === \"deleted\") {\n                            if (existingIdx !== -1) {\n                                server_modules.splice(existingIdx, 1);\n                            }\n                        } else if (change_type === \"added\") {\n                            server_modules.push({\n                                name: path,\n                                code: change.code || \"\",\n                                id: change.id ?? generateItemId(),\n                                is_package: change.is_package,\n                            });\n                        } else if (change_type === \"modified\") {\n                            const serverModule = {\n                                name: path,\n                                code: change.code || \"\",\n                                id: change.id ?? server_modules[existingIdx]?.id ?? generateItemId(),\n                                is_package: change.is_package,\n                            };\n                            if (existingIdx !== -1) {\n                                server_modules[existingIdx] = serverModule;\n                            } else {\n                                server_modules.push(serverModule);\n                            }\n                        }\n                        break;\n                    }\n\n                    case \"script\": {\n                        if (!app.initialCode.scripts) app.initialCode.scripts = [];\n                        const scripts = app.initialCode.scripts;\n                        const existingIdx = scripts.findIndex((s) => s.name === path);\n\n                        if (change_type === \"deleted\") {\n                            if (existingIdx !== -1) {\n                                scripts.splice(existingIdx, 1);\n                            }\n                        } else if (change_type === \"added\") {\n                            scripts.push({\n                                name: path,\n                                code: change.code || \"\",\n                                id: change.id ?? generateItemId(),\n                                is_package: change.is_package,\n                            });\n                        } else if (change_type === \"modified\") {\n                            const script = {\n                                name: path,\n                                code: change.code || \"\",\n                                id: change.id ?? scripts[existingIdx]?.id ?? generateItemId(),\n                                is_package: change.is_package,\n                            };\n                            if (existingIdx !== -1) {\n                                scripts[existingIdx] = script;\n                            } else {\n                                scripts.push(script);\n                            }\n                        }\n                        break;\n                    }\n\n                    case \"asset\": {\n                        // Ensure theme and assets structure exists\n                        if (!app.initialCode.theme) {\n                            app.initialCode.theme = { assets: [] };\n                        }\n                        if (!app.initialCode.theme.assets) {\n                            app.initialCode.theme.assets = [];\n                        }\n                        const assets = app.initialCode.theme.assets;\n                        const existingIdx = assets.findIndex((a) => a.name === path);\n\n                        if (change_type === \"deleted\") {\n                            if (existingIdx !== -1) {\n                                assets.splice(existingIdx, 1);\n                            }\n                        } else if (change_type === \"added\" || change_type === \"modified\") {\n                            // Assets have {name, content, id} - content is base64 string\n                            // Use backend-provided id if available, otherwise preserve existing or generate\n                            const assetId =\n                                change.id || (existingIdx !== -1 ? assets[existingIdx].id : generateItemId());\n                            if (existingIdx !== -1) {\n                                assets[existingIdx] = {\n                                    ...assets[existingIdx],\n                                    name: path,\n                                    content: change.content ?? assets[existingIdx].content,\n                                    id: assetId,\n                                };\n                            } else {\n                                assets.push({ name: path, content: change.content ?? \"\", id: assetId });\n                            }\n                        }\n                        break;\n                    }\n\n                    case \"extra_files\": {\n                        // Extra files are stored in a nested structure: extra_files.server_code.file.txt\n                        // path is like \"server_code/myfile.txt\" or \"myfile.txt\"\n                        const parts = path.split(\"/\");\n\n                        // Ensure extra_files exists\n                        mutableConfig.extra_files ??= {};\n\n                        if (change_type === \"deleted\") {\n                            // Navigate to parent and delete the file, tracking parents for pruning\n                            const parents: Array<{ obj: Record<string, unknown>; key: string }> = [\n                                { obj: mutableConfig as unknown as Record<string, unknown>, key: \"extra_files\" },\n                            ];\n                            let current = mutableConfig.extra_files as ExtraFilesTree;\n                            let reachedTarget = true;\n                            for (let i = 0; i < parts.length - 1; i++) {\n                                const next = current[parts[i]];\n                                if (!next || typeof next === \"string\") {\n                                    reachedTarget = false;\n                                    break;\n                                }\n                                parents.push({ obj: current, key: parts[i] });\n                                current = next;\n                            }\n\n                            // Only delete if we navigated to the correct parent\n                            if (reachedTarget) {\n                                delete current[parts[parts.length - 1]];\n\n                                // Prune empty parent objects\n                                for (let i = parents.length - 1; i >= 0; i--) {\n                                    const { obj, key } = parents[i];\n                                    if (obj[key] && Object.keys(obj[key]).length === 0) {\n                                        delete obj[key];\n                                    } else {\n                                        break;\n                                    }\n                                }\n                            }\n                        } else if (change_type === \"added\" || change_type === \"modified\") {\n                            // Navigate/create path and set the content\n                            let current = mutableConfig.extra_files as ExtraFilesTree;\n                            for (let i = 0; i < parts.length - 1; i++) {\n                                const next = current[parts[i]];\n                                if (!next || typeof next === \"string\") {\n                                    current[parts[i]] = {};\n                                }\n                                current = current[parts[i]] as ExtraFilesTree;\n                            }\n                            current[parts[parts.length - 1]] = change.content ?? \"\";\n                        }\n                        break;\n                    }\n                }\n            }\n\n            // Update commit info\n            app.commitSha = to_commit;\n\n            // Update edit session if provided\n            if (edit_session) {\n                app.editSession = edit_session;\n            }\n        });\n\n        // Build set of changed code paths for selective cache handling\n        const changedCodePaths = new Set<CodePath>(\n            changes.filter(isCodeIncrementalChange).flatMap(({ item_type, path }): CodePath[] => {\n                const paths = [`${item_type}s/${path}` as CodePath];\n                // Handle type conversion: form↔module can share paths\n                if (item_type === \"form\") paths.push(`modules/${path}` as CodePath);\n                if (item_type === \"module\") paths.push(`forms/${path}` as CodePath);\n                return paths;\n            })\n        );\n        dispatch(rebuildCodeStructureAndSyncCache(changedCodePaths));\n\n        // Add the new commit to history if we have commit info\n        if (to_commit_info) {\n            updateState(({ app }) => {\n                if (!app?.commitHistory?.versions) return;\n                const versions = app.commitHistory.versions;\n                if (!versions.find(({ v }) => v === to_commit)) {\n                    versions.unshift(to_commit_info);\n                }\n            });\n        }\n\n        if (!getTyAnalysisEnabled(getState())) {\n            for (const change of changes) {\n                const { change_type, item_type, path } = change;\n                // Only process code item types\n                if (item_type === \"form\" || item_type === \"module\" || item_type === \"server_module\") {\n                    if (change_type === \"deleted\") {\n                        autocompleter.deleteItem(item_type, path);\n                    } else {\n                        // Type conversion: delete the other type if it existed (fire-and-forget)\n                        if (item_type === \"form\") {\n                            autocompleter.deleteItem(\"module\", path);\n                        } else if (item_type === \"module\") {\n                            autocompleter.deleteItem(\"form\", path);\n                        }\n                        // For added/modified items, analyze the new content\n                        const item =\n                            item_type === \"form\"\n                                ? ({ class_name: path, code: change.code || \"\", ...change.yaml } as FormItemYaml)\n                                : ({\n                                      name: path,\n                                      code: change.code || \"\",\n                                      id: change.id ?? generateItemId(),\n                                  } as ModuleItemYaml);\n                        dispatch(autocompleter.analyseItem(item as FormItemYaml | ModuleItemYaml, item_type));\n                    }\n                }\n            }\n        }\n\n        // Reload app config if config changed\n        if (changes.some(({ item_type }) => item_type === \"config\")) {\n            dispatch(autocompleter.reloadAppConfig());\n        }\n\n        // Revalidate open tabs - close tabs for deleted items, reload others\n        dispatch(revalidateAndReloadOpenTabs());\n\n        // Sync database schema if it changed\n        if (appSchemaChanged) {\n            await dispatch(updateAppSchemaSync());\n        }\n\n        dispatch(recordActivity(\"applyIncrementalUpdate\", { from_commit, to_commit, change_count: changes.length }));\n\n        // Refresh derived metadata after completing the authoritative update.\n        if (\n            getTyAnalysisEnabled(getState()) &&\n            changes.some(({ item_type }) => [\"form\", \"module\", \"server_module\", \"config\"].includes(item_type))\n        ) {\n            void dispatch(autocompleter.refreshItemMetadata());\n        }\n\n        // console.info(\"%capplyIncrementalUpdate: success\", \"color: hotpink;\", changes);\n\n        return true;\n    };\n\n// For the exclusive use of the history panel UI.\nexport const checkoutVersion =\n    (commitId: string, branch = \"master\", forceVisiting = false): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        let state = getState(),\n            app = state.app;\n        if (!app) {\n            return;\n        }\n        const appId = getAppId(state);\n        let currentBranch = app.editState?.branch;\n        let currentCommitSha = app.commitSha;\n\n        const saved = await dispatch(ensureChangesSaved(appId));\n        if (!saved) return;\n\n        // Re-read state — saves may have completed, changing commitSha\n        state = getState();\n        app = state.app;\n        if (!app) {\n            return;\n        }\n        currentBranch = app.editState?.branch;\n        currentCommitSha = app.commitSha;\n\n        if (\n            !forceVisiting &&\n            currentBranch &&\n            branch === currentBranch &&\n            app.commitHistory.refs[`refs/heads/${currentBranch}`]?.oid === commitId &&\n            currentCommitSha === commitId\n        ) {\n            return;\n        } // no-op\n\n        const possibleRefs = Object.entries(app.commitHistory.refs).filter(([_, { oid }]) => oid === commitId);\n\n        const possibleBranches = possibleRefs\n            .filter(([b, { oid }]) => b.startsWith(\"refs/heads/\") && !b.startsWith(\"refs/heads/users/\"))\n            .map(([b, _]) => b.substring(11));\n\n        const possibleMerge = possibleRefs.find(([r, _]) => r.startsWith(\"refs/resolving-merge/\"));\n\n        const checkoutBranch = !forceVisiting\n            ? possibleBranches.indexOf(branch) !== -1\n                ? branch\n                : possibleBranches[0]\n            : undefined;\n\n        // Check out whatever we clicked on, whether it's a branch or a commit.\n        // If it's another branch, we open it.\n        // If it's a bare commit, we go \"just visiting\"\n        //  Don't try incremental checkout if we have invalid YAML - we might want make the incremental update check for this itself at somepoint\n        if (!getInvalidYaml(state)) {\n            const incrementalSuccess = await dispatch(\n                tryIncrementalCheckout({ appId, currentCommitSha, commitId, checkoutBranch, possibleMerge })\n            );\n            if (incrementalSuccess) {\n                // console.log(\"%ctryIncrementalCheckout: success\", \"color: hotpink;\", incrementalSuccess);\n                return;\n            }\n        }\n\n        // Full-reload fallback\n        if (checkoutBranch) {\n            dispatch(updateGlobalLoadingIndicator(`Switching to branch '${checkoutBranch}'`));\n            await dispatch(loadVersion({ branch: checkoutBranch }));\n            dispatch(updateGlobalLoadingIndicator(false));\n        } else if (possibleMerge) {\n            dispatch(updateGlobalLoadingIndicator(\"Switching to unresolved merge\"));\n            await dispatch(loadVersion({ merge: parseInt(possibleMerge[0].substring(21), 10) }));\n        } else {\n            await dispatch(loadVersion({ commitId }));\n        }\n    };\n\nexport const mergeAppVersion = (\n    mergeThisCommitId: string,\n    fromThisBranch: string | null = null,\n    intoThisBranch_: string | null = null\n): AnvilAsyncAction<void> =>\n    async function (dispatch, getState, updateState) {\n        // This is a bit ikky. There are 2.5 possible things we could be doing:\n        // 1)   Merge the current branch into another\n        // 2)   Merge a random commit into the current branch\n        // 2.5) Merge a random commit into a random branch (we have no UI for this)\n\n        const state = getState();\n        const appId = getAppId(state);\n        const myBranch = `users/${String(getUser(state).email)}`;\n        const currentBranch = getCurrentBranch(state);\n        const intoThisBranch = intoThisBranch_ || currentBranch || \"master\"; // If we haven't specified a branch, merge into the current branch.\n\n        const commitMessage = await dispatch(\n            modal(\"premerge\", { commitId: mergeThisCommitId, targetBranch: intoThisBranch })\n        );\n        if (!commitMessage) {\n            return;\n        }\n\n        await withSuppressReloadingOnBranchMove(updateState, async () => {\n            const response = await api.mergeVersion(\n                appId,\n                intoThisBranch,\n                mergeThisCommitId,\n                commitMessage,\n                fromThisBranch\n            );\n            if (response.merge_failed) {\n                await dispatch(alert(\"Merge failed\", response.merge_failed));\n            } else {\n                const { content, edit_state, edit_session, commit, ref_update, dependency_graph } = response;\n                // Run must use the merged version as soon as the editor switches to it.\n                await api.setDevelopmentVersion(appId, edit_state);\n                await dispatch(\n                    resetAppState(appId!, content, edit_state, commit.v, { dependencyGraph: dependency_graph })\n                );\n                await dispatch(handleVersionUpdate({ ref_update, commit }));\n                await dispatch(updateAppSchemaSync());\n\n                if (edit_state.branch) {\n                    if (currentBranch !== intoThisBranch) {\n                        // Assume that this is case (1), and reset to the target branch.\n                        // Whichever branch we just moved away from is not malleable any more\n                        if (currentBranch) {\n                            dispatch(updateMalleableCommits(`refs/heads/${currentBranch}`, null));\n                        }\n\n                        // Now delete my personal branch, if necessary.\n                        if (currentBranch === myBranch) {\n                            await dispatch(deleteBranch(myBranch));\n                        }\n                    }\n\n                    updateState(`Branch ${intoThisBranch} updated`, ({ app }) => {\n                        if (!app) return;\n                        app.editSession = edit_session;\n                        app.editState.branch = intoThisBranch;\n                    });\n\n                    if (currentBranch) {\n                        dispatch(updateMalleableCommits(`refs/heads/${currentBranch}`, null));\n                    }\n                    dispatch(updateMalleableCommits(`refs/heads/${intoThisBranch}`, null));\n                }\n                if (edit_state.state === \"resolving\") {\n                    updateState(`New edit session for resolving merge`, ({ app }) => {\n                        if (!app) return;\n                        app.editSession = edit_session;\n                    });\n                    await dispatch(\n                        alert(\n                            \"Conflicts\",\n                            \"The changes you made have conflicted with the changes you're merging with.\\n\\nUse the Conflicts tab to resolve them before continuing.\"\n                        )\n                    );\n                    dispatch(openOrFocusBottomTab({ type: \"conflicts\" }));\n                }\n            }\n        });\n    };\n\nconst removeCommitIfOrphaned =\n    (commitId: string): HistoryStateUpdater =>\n    (state) => {\n        const app = state.app;\n        if (!app) return;\n        let orphaned = true;\n        for (const [, { oid }] of Object.entries(app.commitHistory.refs)) {\n            if (oid === commitId) {\n                orphaned = false;\n                break;\n            }\n        }\n        if (app.commitHistory.versions.find((c) => c.p?.indexOf(commitId) > -1)) {\n            orphaned = false;\n        }\n\n        if (orphaned) {\n            app.commitHistory.versions = app.commitHistory.versions.filter((c) => c.v !== commitId);\n        }\n    };\n\nexport const abandonMerge =\n    (mergeId: string | number): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = getAppId(state);\n        const refs = getAppRefs(state);\n        const refName = `refs/resolving-merge/${mergeId}`;\n        const ref = refs.refs[refName] as HistoryMergeRef | undefined;\n        if (!ref) {\n            return;\n        }\n        const appVersion = getAppCommitId(state);\n\n        if (appVersion === ref.oid) {\n            // Leave this commit that is (probably) about to stop existing\n            const branch = ref?.[\"merge-info\"]?.[\"source\"] || ref?.[\"merge-info\"]?.[\"target\"] || \"master\";\n\n            await dispatch(loadVersion({ branch }));\n        }\n        // Abandon the merge\n        await api.abandonMerge(appId, mergeId);\n\n        updateState((state) => {\n            if (!state.app) return;\n            delete state.app.commitHistory.refs[refName];\n        });\n\n        updateState(removeCommitIfOrphaned(ref.oid));\n        dispatch(recordActivity(\"abandonMerge\", { mergeId }));\n    };\n\nexport const completeMerge =\n    (mergeId: string | number): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = getAppId(state);\n        const refs = getAppRefs(state);\n        const refName = `refs/resolving-merge/${mergeId}`;\n        const ref = refs.refs[refName] as HistoryMergeRef | undefined;\n        if (!ref) {\n            return;\n        }\n        const sourceBranch = ref[\"merge-info\"]?.source;\n\n        const { ref_update, branch, tip, error, conflict } = await api.completeMerge(appId, mergeId);\n\n        await withSuppressReloadingOnBranchMove(updateState, async () => {\n            if (error) {\n                await dispatch(alert(\"Merge failed\", error));\n            } else if (conflict) {\n                switch (\n                    await dispatch(\n                        modal(\"mergeCompletionConflict\", {\n                            branch: branch ?? \"\",\n                            canRestart: !!sourceBranch,\n                        })\n                    )\n                ) {\n                    case \"RESTART\":\n                        await dispatch(abandonMerge(mergeId));\n                        if (sourceBranch) {\n                            const { commitId: sourceCommitId } = refs.branches[sourceBranch];\n                            await dispatch(mergeAppVersion(sourceCommitId, sourceBranch, branch));\n                        }\n                        break;\n                    case \"RETRY\":\n                        await dispatch(mergeAppVersion(ref.oid, sourceBranch, branch));\n                        await dispatch(abandonMerge(mergeId));\n                        break;\n                }\n            } else {\n                await dispatch(loadVersion({ branch }));\n\n                updateState((state) => {\n                    if (ref_update) {\n                        ingestRefUpdate(ref_update)(state);\n                    }\n                    if (!state.app) return;\n                    delete state.app.commitHistory.refs[refName];\n                });\n\n                updateState(removeCommitIfOrphaned(ref.oid));\n                dispatch(recordActivity(\"completeMerge\", { mergeId }));\n            }\n        });\n    };\n\ntype HandleRepoUpdateEventParams = {\n    app: string;\n    event: string;\n    ref_update?: ({ ref: string } & RawCommitRef) | null;\n    commit?: CommitVersion | null;\n    is_malleable?: boolean;\n    replaced_commit?: string | null;\n    incremental?: WebsocketIncrementalPayload;\n    invalid_yaml?: boolean;\n};\n\nconst handleRepoUpdateEvent =\n    (\n        {\n            app,\n            event,\n            ref_update,\n            commit,\n            is_malleable,\n            replaced_commit,\n            incremental,\n            invalid_yaml,\n        }: HandleRepoUpdateEventParams,\n        dependencyBranchWatches: DependencyBranchWatch[] = []\n    ): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const stateApp = getState().app;\n        if (stateApp?.$loading) return;\n        if (event === \"REPO_UPDATE\") {\n            if (!ref_update) {\n                console.warn(\"Got REPO_UPDATE for null ref - probably an obsolete branch update.\");\n                return;\n            }\n            const { ref } = ref_update;\n\n            console.log(\"Ref\", ref, \"moves to\", commit, \"with update\", ref_update);\n            if (app !== stateApp?.id) {\n                if (isWatchedDependencyBranchUpdate(app, ref, dependencyBranchWatches)) {\n                    await dispatch(reloadDependenciesFromRepoUpdate());\n                }\n                return;\n            }\n            await dispatch(\n                handleVersionUpdate({\n                    commit,\n                    ref_update,\n                    is_malleable,\n                    replaced_commit,\n                    incremental,\n                    invalidYaml: invalid_yaml,\n                })\n            );\n        } else if (event === \"REPO_INVALIDATE\") {\n            if (app !== stateApp?.id) {\n                if (isWatchedDependencyBranchUpdate(app, ref_update?.ref, dependencyBranchWatches)) {\n                    await dispatch(reloadDependenciesFromRepoUpdate());\n                }\n                return;\n            }\n            await dispatch(handleVersionUpdate({ ref_update, is_malleable, commit, replaced_commit })); // trigger refresh if necessary before resetting versionHistory.refs\n            await dispatch(updateAppCommitHistory());\n        }\n    };\n\nconst syncLoadedBranchToRef =\n    ({\n        ref,\n        ref_update,\n        commit,\n        incremental,\n        replaced_commit,\n        suppressReload = false,\n        invalidYaml,\n    }: {\n        ref: string;\n        ref_update: RawCommitRef;\n        commit?: CommitVersion | null;\n        incremental?: WebsocketIncrementalPayload;\n        replaced_commit?: string | null;\n        suppressReload?: boolean;\n        invalidYaml?: boolean;\n    }): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const app = getApp(getState());\n        if (!app) {\n            return;\n        }\n\n        const movedOurBranch = app.editState.branch && ref === `refs/heads/${app.editState.branch}`;\n        if (!movedOurBranch) {\n            return;\n        }\n\n        const saveSeqSession = ref_update[\"save-seq\"]?.session;\n        const fromAnvilSync = saveSeqSession?.startsWith(\"anvil-sync-\");\n        if (saveSeqSession === app.editSession) {\n            suppressReload = true;\n        }\n\n        const state = getState();\n        if (suppressReload || state.suppressReloadingOnBranchMove) {\n            console.info(\"Our branch moved, but suppressing reloading\");\n            return;\n        }\n\n        const currentApp = getApp(state);\n        if (!currentApp) {\n            return;\n        }\n\n        const appId = getAppId(state);\n        const currentCommitSha = currentApp.commitSha;\n        const newCommitSha = ref_update.oid;\n        const expectedFromCommit = replaced_commit || commit?.p?.[0];\n\n        if (currentCommitSha === newCommitSha) {\n            return;\n        }\n\n        if (invalidYaml) {\n            updateState(({ app }) => {\n                if (!app) return;\n                app.editState = { ...app.editState, state: \"error\", editable: false, invalidYaml: true };\n            });\n        }\n\n        // Don't try incremental updates if we have (or are moving to) invalid YAML - we might want make the incremental update check for this itself at somepoint\n        if (!getInvalidYaml(state) && !invalidYaml) {\n            // Incremental updates are silent (no loading indicator, no flicker),\n            // so we try them even when the window is unfocused.\n            const wsSuccess = await dispatch(\n                tryWsIncrementalUpdate({ incremental, currentCommitSha, expectedFromCommit, newCommitSha, commit })\n            );\n\n            if (wsSuccess) return;\n\n            const httpSuccess = await dispatch(tryHttpIncrementalUpdate({ appId, currentCommitSha, newCommitSha }));\n            if (httpSuccess) return;\n        }\n\n        // Full reload is visually disruptive — only do it when focused.\n        // See: https://anvil.works/forum/t/about-the-continuous-reload-when-working-with-multiple-windows/20659\n        // https://github.com/anvil-works/anvil/issues/5157\n        if (document.hasFocus() || fromAnvilSync) {\n            console.info(\"Our branch moved, reloading\");\n            const editState = currentApp.editState;\n            dispatch(loadVersion(editState, true));\n        } else {\n            console.info(\"Delaying reload till we have focus\");\n            updateState((s) => {\n                s.loadVersionOnFocus = true;\n            });\n        }\n    };\n\nconst reloadCommitHistoryIfAppUnchanged =\n    (appId: string): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        // Make sure changes that happened between loading and connecting don't fall through\n        // the cracks: we fetch the history *after* we've connected\n\n        const state = getState();\n        if (appId !== state.app?.id) {\n            return;\n        }\n\n        await dispatch(updateAppCommitHistory());\n\n        const refreshedState = getState();\n        const app = getApp(refreshedState);\n        const currentBranch = app?.editState?.branch;\n        if (!app || !currentBranch) {\n            return;\n        }\n\n        const ref = `refs/heads/${currentBranch}`;\n        const ref_update = app.commitHistory.refs[ref];\n        if (!ref_update?.oid) {\n            return;\n        }\n\n        const commit = app.commitHistory.versions.find(({ v }) => v === ref_update.oid) ?? null;\n        await dispatch(syncLoadedBranchToRef({ ref, ref_update, commit }));\n    };\n\nexport const useHistoryWebsocketEventListener = (appId: AppId | undefined) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const reloadEditState = useSelector((s: State) => s.loadVersionOnFocus);\n    const editState = useSelector((state: State) => getAppEditState(state));\n    const currentBranch = editState?.branch;\n    const dependencyBranchWatches = useSelector(getDependencyBranchWatches);\n    const websocketListeners = useMemo<WebsocketEventListenerConfig[]>(\n        () => [\n            {\n                appId,\n                onSetup: () => appId && dispatch(reloadCommitHistoryIfAppUnchanged(appId)),\n                subscription: { receive_incremental_updates_for_branch: currentBranch ?? undefined },\n            },\n            ...dependencyBranchWatches.map(({ appId, branch }) => ({\n                appId,\n                subscription: { only_branch: branch },\n            })),\n        ],\n        [appId, currentBranch, dependencyBranchWatches]\n    );\n\n    const onFocus = useEffectEvent(() => {\n        if (!reloadEditState || !editState) return;\n        dispatch(loadVersion(editState, true));\n    });\n\n    useEffect(() => {\n        window.addEventListener(\"focus\", onFocus);\n        return () => {\n            window.removeEventListener(\"focus\", onFocus);\n        };\n    });\n\n    useWebsocketEventListeners(websocketListeners, (e) =>\n        dispatch(\n            handleRepoUpdateEvent(\n                e as WebsocketEvent & Parameters<typeof handleRepoUpdateEvent>[0],\n                dependencyBranchWatches\n            )\n        )\n    );\n};\n\nexport const updateAppCommitHistory =\n    (maxCommits: number | null = null): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = getAppId(state);\n        console.log(\"Updating commit History\");\n        const currentCommitHistory = getAppCommitHistory(state);\n        const commitHistory = await api.getAppCommitHistory(\n            appId,\n            maxCommits || currentCommitHistory?.versions?.length || 50\n        );\n        updateState(({ app }) => {\n            // Check that the app hasn't been closed in the meantime!\n            if (app && app.id === appId) {\n                app.commitHistory = commitHistory;\n            }\n        });\n    };\n\nexport const getAppPathForConflictItem = (\n    conflictItem: ConflictItemSpec,\n    state: State\n): ChangedCodePath | ChangedSettingsPath | ChangedExtraFilesPath | undefined => {\n    // This is an ugly translation from the conflict's spec for an item to the store's spec.\n    // It is extra specially ugly because conflict specs don't know the difference between forms and modules\n    // TODO: They do now! Fix.\n    const [type, itemId] = conflictItem;\n    switch (type) {\n        case \"extra_files\":\n            return typeof itemId === \"string\" ? [\"EXTRA_FILES\", ...itemId.split(\"/\")] : undefined;\n        case \"server_code\":\n            return typeof itemId === \"string\" ? ([\"CODE\", `server_modules/${itemId}`] as ChangedCodePath) : undefined;\n        case \"asset\":\n            return typeof itemId === \"string\" ? ([\"CODE\", `assets/${itemId}`] as ChangedCodePath) : undefined;\n        case \"client_code\": {\n            if (typeof itemId !== \"string\") {\n                return undefined;\n            }\n            const codeStructure = getCodeNames(state);\n            const codePath = codeStructure[itemId]?.codePath;\n            return codePath ? ([\"CODE\", codePath] as ChangedCodePath) : undefined;\n        }\n        case \"config\":\n            return Array.isArray(itemId)\n                ? ([\"SETTINGS\", ...(itemId as [keyof AppConfig, ...string[]])] as ChangedSettingsPath)\n                : undefined;\n\n        // default:\n        //     throw new Error(`Unknown conflict type for item ${itemId}: ${type}`);\n    }\n};\n\nconst mutateItemByMergeItem = (\n    description: string,\n    conflictItem: ConflictItemSpec,\n    f: (item: CodeConflictItem) => void\n): AnvilAsyncAction<void> =>\n    async function (dispatch, getState, updateState) {\n        const state = getState();\n        const path = getAppPathForConflictItem(conflictItem, state);\n        if (!path || path[0] !== \"CODE\") {\n            throw new Error(`Don't know how to find an app path for conflict item ${conflictItem}`);\n        }\n\n        await dispatch(mutateItem(state, path, f));\n    };\n\n/** Ask before clearing the file's central conflict entry after its last inline marker is resolved. */\nexport const confirmItemConflictsResolved =\n    (conflictItem: ConflictItemSpec): AnvilAsyncAction<void> =>\n    async (dispatch, getState) => {\n        const app = getState().app;\n        const confirmed = await dispatch(\n            confirm(\n                \"Conflicts resolved?\",\n                \"You have just removed the last conflict marker in this file.\\nDo you want to mark this whole file as resolved?\",\n                \"Yes, it's resolved\",\n                \"No, I still need to make edits\"\n            )\n        );\n        if (!confirmed) return;\n\n        // Undo and checkout still work while the dialog is open. Its answer must\n        // not clear reopened conflicts or resolve a different pending merge.\n        const state = getState();\n        if (\n            state.app?.id !== app?.id ||\n            state.app?.editState.merge !== app?.editState.merge ||\n            !isEqual(state.app?.conflicts?.merge, app?.conflicts?.merge)\n        )\n            return;\n        const item = state.app?.conflicts?.conflicting_items.find(({ item }) => isEqual(item, conflictItem));\n        if (!item) return;\n        const conflicts = getConflictsForConflictingItem(state, {\n            possiblyOutOfDateConflicts: item,\n            appPath: getAppPathForConflictItem(conflictItem, state),\n        });\n        if ([conflicts?.text_chunks, conflicts?.edits, conflicts?.components].some((items) => items?.length)) return;\n        await dispatch(resolveAllItemConflicts(conflictItem));\n    };\n\nexport const resolveAllItemConflicts =\n    (conflictItem: ConflictItemSpec): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const path = getAppPathForConflictItem(conflictItem, getState());\n        if (path?.[0] === \"EXTRA_FILES\" && !getAppIsEditable(getState())) {\n            throw new Error(\"This app is not editable.\");\n        }\n        let saveIssued = false;\n\n        // If this is a code item, then the master copy of its conflicts lives on the item, so we need to delete it there\n        if (path?.[0] === \"CODE\") {\n            // Retain the merge's base and parents in the item cache so undo can\n            // reopen this file even after the last central conflict is removed.\n            const merge = getState().app?.conflicts?.merge;\n            await dispatch(\n                mutateItemByMergeItem(`Resolve all conflicts for '${conflictItem}'`, conflictItem, (item) => {\n                    delete item.conflicts;\n                    item.resolvedConflictItem = conflictItem;\n                    item.resolvedConflictMerge = merge;\n                })\n            );\n            saveIssued = true;\n        }\n        if (path?.[0] === \"EXTRA_FILES\") {\n            dispatch(\n                setCodeItemHistory(`extra_files/${path.slice(1).join(\"/\")}`, {\n                    resolvedConflictMerge: getState().app?.conflicts?.merge,\n                })\n            );\n        }\n\n        // For all types of item, we need to remove the record from the central index at state.app.conflicts.\n        updateState((state) => {\n            const conflicts = state.app?.conflicts;\n            let ci = conflicts?.conflicting_items;\n            if (ci && conflicts) {\n                conflicts.conflicting_items = ci = ci.filter(\n                    ({ item: [type, id] }) => type !== conflictItem[0] || !isEqual(id, conflictItem[1])\n                );\n                if (ci.length === 0) {\n                    if (state.app) {\n                        delete state.app.conflicts;\n                    }\n                }\n            }\n        });\n        if (!getState().app?.conflicts) {\n            await dispatch(markAppPathUnsaved([\"CONFLICTS\"]));\n        } else if (!saveIssued) {\n            await dispatch(markAppPathUnsaved([\"CONFLICTS\", conflictItem]));\n        }\n    };\n\nexport const resolveAllConflictsForFormComponent = (formName: string, componentName: string) =>\n    mutateItemByMergeItem(\n        `Resolve all conflicts for component ${componentName} on ${formName}`,\n        [\"client_code\", formName],\n        ({ conflicts }) => {\n            if (!conflicts) {\n                return;\n            }\n            conflicts.components = ((conflicts.components || []) as Array<{ component: string }>).filter(\n                ({ component }: { component: string }) => component !== componentName\n            );\n            console.log(\"Conflicts is now\", JSON.stringify(conflicts.components));\n        }\n    );\n\nexport const resolveConfigConflict =\n    (conflictItem: ConflictItemSpec, configPath: unknown[]): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        updateState((state) => {\n            const item = state.app?.conflicts?.conflicting_items?.find?.(({ item }) => isEqual(item, conflictItem));\n            //console.log(\"Resolving\", configPath, \"in\", item, \"in\", JSON.stringify(state.app.conflicts.conflicting_items), \"fot\", [type, id]);\n            if (item?.edits) {\n                item.edits = (item.edits as Array<{ path: unknown[] }>).filter(\n                    ({ path }: { path: unknown[] }) => !isEqual(path, configPath)\n                );\n            }\n        });\n        await dispatch(markAppPathUnsaved([\"CONFLICTS\", conflictItem]));\n    };\n\nexport const deleteCommits =\n    (commitIds: string[], permanent: boolean): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const modal = permanent\n            ? confirm(\n                  \"Delete commit?\",\n                  \"The contents of this commit will be deleted permanently. This cannot be undone.\",\n                  \"Delete\",\n                  \"Cancel\"\n              )\n            : confirm(\n                  \"Remove from history?\",\n                  \"This commit will be removed from your app's Version History. Its changes will not be lost; they will be added to the subsequent commit.\",\n                  \"Remove\",\n                  \"Cancel\"\n              );\n\n        if (await dispatch(modal)) {\n            const state = getState();\n            const appId = getAppId(state);\n            const branch = getCurrentBranch(state);\n            if (!appId || !branch) return;\n            await api.deleteCommits(appId, commitIds, branch);\n        }\n    };\n\nexport const editCommitMessage =\n    (commit: CommitVersion): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const msg = await dispatch(\n            modal(\"precommit\", {\n                title: \"Edit commit message\",\n                text: \"Edit the description of this commit\",\n                initialValue: commit.m,\n                commit,\n            })\n        );\n        if (msg) {\n            const state = getState();\n            const appId = getAppId(state);\n            const branch = getCurrentBranch(state);\n            if (!appId || !branch) return;\n            await api.editCommitMessage(appId, commit.v, branch, msg);\n        }\n    };\n\n// TODO: These should be selectors\nexport const listItemsWithConflicts = (state: State) =>\n    state.app?.conflicts?.conflicting_items.map((c) => ({\n        possiblyOutOfDateConflicts: c,\n        conflictItem: c.item,\n        appPath: getAppPathForConflictItem(c.item, state),\n    }));\nexport const getConflictsForConflictingItem = (\n    state: State,\n    {\n        possiblyOutOfDateConflicts,\n        appPath,\n    }: { possiblyOutOfDateConflicts: ConflictingItem; appPath: AppPath | undefined }\n) => appPath && (appPath[0] === \"CODE\" ? getCachedCodeItem(appPath[1], state)?.conflicts : possiblyOutOfDateConflicts);\n\nconst EMPTY_OBJECT = {};\n\nexport const getAppHasConflicts = (state: State) => !!state.app?.conflicts;\nexport const getAppCommitHistory = (state: State): CommitHistory | undefined => state.app?.commitHistory;\nexport const getAppMalleableCommits = (state: State): Record<string, MalleableCommitEntry> =>\n    state.app?.malleableCommits ?? EMPTY_OBJECT;\nexport const getAppCommitId = (state: State) => state.app?.commitSha;\n\nexport const getAppRefs = createSelector(\n    [(state: State) => getAppCommitHistory(state)?.refs, (state: State) => getUser(state)],\n    (refs = {}, user): AppRefs => {\n        const branches = Object.fromEntries(\n            Object.entries(refs || {})\n                .filter(([ref, spec]) => ref.startsWith(\"refs/heads/\"))\n                .map(([ref, spec]) => [\n                    ref.substring(11),\n                    { commitId: spec.oid, remoteSync: spec[\"remote-sync\"] || {} },\n                ])\n        );\n\n        const remotes = Object.fromEntries(\n            Object.entries(refs || {})\n                .filter(([ref, spec]) => ref.startsWith(\"refs/remotes/\"))\n                .map(([ref, spec]) => {\n                    const match = /refs\\/remotes\\/(.*?)\\/(.*)/.exec(ref);\n                    if (!match) {\n                        return [ref.substring(13), { commitId: spec.oid }];\n                    }\n                    const [, remoteName, branchName] = match;\n                    const localBranch = branches[branchName];\n                    return [\n                        ref.substring(13),\n                        {\n                            commitId: spec.oid,\n                            inSync: localBranch?.remoteSync?.[remoteName]?.[\"synced?\"],\n                            status: localBranch?.remoteSync?.[remoteName]?.status,\n                            message: localBranch?.remoteSync?.[remoteName]?.message,\n                        },\n                    ];\n                })\n        );\n\n        const tagEntries = Object.entries(refs || {})\n            .filter(([ref, spec]) => ref.startsWith(\"refs/tags/\"))\n            .map(([ref, spec]) => [ref.substring(10), { commitId: spec.oid }] as const);\n\n        // Sort tags using semver (newest first), with non-semver tags at the end\n        const sortedTagEntries = tagEntries.sort(([aName], [bName]) => {\n            const aVersion = semver.valid(semver.coerce(aName));\n            const bVersion = semver.valid(semver.coerce(bName));\n\n            // Both are valid semver versions\n            if (aVersion && bVersion) {\n                return semver.rcompare(aVersion, bVersion); // Descending order (newest first)\n            }\n\n            // One is valid semver, one is not - semver versions come first\n            if (aVersion) return -1;\n            if (bVersion) return 1;\n\n            // Neither is valid semver - sort alphabetically\n            return aName.localeCompare(bName);\n        });\n\n        const tags = Object.fromEntries(sortedTagEntries);\n\n        const nonUserBranches = Object.fromEntries(\n            Object.entries(branches)\n                .filter(([branch, oid]) => !branch.startsWith(\"users/\"))\n                .sort(([a], [b]) => a.localeCompare(b))\n        );\n\n        // Non-user branches, plus mine.\n        const nonCollaboratorBranches = Object.fromEntries(\n            Object.entries(branches)\n                .filter(([branch, oid]) => !branch.startsWith(\"users/\") || branch === `users/${user?.email}`)\n                .sort(([a], [b]) => a.localeCompare(b))\n        );\n\n        const resolvingMerges = Object.fromEntries(\n            Object.entries(refs || {})\n                .filter(([ref, spec]) => ref.startsWith(\"refs/resolving-merge/\"))\n                .map(([ref, spec]) => [ref.substring(21), spec])\n        );\n\n        return {\n            refs,\n            tags,\n            branches,\n            remotes,\n            nonUserBranches,\n            nonCollaboratorBranches,\n            resolvingMerges,\n        };\n    }\n);\n\nexport const getCurrentBranch = (state: State) => state.app?.editState?.branch;\n","import * as api from \"@/api\";\nimport { getUser } from \"@/controllers/ide\";\nimport { claimAchievement } from \"@/controllers/user\";\nimport { navigate } from \"@/router/navigation\";\nimport type { AnvilAsyncAction, AppId, State } from \"@/types\";\nimport { queryClient } from \"@/util/queryClient\";\nimport { invalidateIdeAppListQueries } from \"../app-list-query\";\nimport { getApp, getAppId, nullApp, updateGlobalLoadingIndicator } from \"./index\";\n\nexport const loadAppPermissions =\n    (appId: AppId, abort?: AbortController): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const permissionsFromApi = await api.loadAppPermissions(appId, abort);\n        updateState(({ app }) => {\n            if (!app) return;\n            app.permissions = permissionsFromApi;\n        });\n    };\n\nexport const updateShareWithOrganisation =\n    (newValue: boolean): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n        if (!appId) return;\n        await api.setAppOrganisationAccess(appId, newValue);\n        await queryClient.invalidateQueries({ queryKey: [\"app-organisation-access\", appId] });\n        await invalidateIdeAppListQueries();\n        //not checking for newValue since default is false and needs to be toggled true the first time anyways\n        dispatch(claimAchievement(\"addedCollaborators\"));\n    };\n\nexport const addAppCollaborator =\n    (email: string, preset: string): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n        if (!appId) return;\n        try {\n            const r = await api.createPermission(appId, email, { preset });\n            if (r.error) {\n                throw new Error(`Cannot add collaborator: ${r.error}`);\n            }\n            dispatch(claimAchievement(\"addedCollaborators\"));\n        } finally {\n            await dispatch(loadAppPermissions(appId));\n        }\n    };\n\nexport const updateCollaboratorPermissionPreset =\n    (collaborator: any, preset: string): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n        if (!appId) return;\n        await api.updatePermission(appId, { ...collaborator, permission: { preset } });\n        await dispatch(loadAppPermissions(appId));\n    };\n\nexport const removeCollaborator =\n    (collaborator: any): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = getAppId(state);\n        const app = getApp(state);\n        const removingSelf = collaborator.user_email === getUser(state).email;\n        if (!appId || !app) return;\n        const deleted = await api.deletePermission(appId, collaborator);\n        const isOwner = getIsOwner(getState());\n        if (!isOwner && removingSelf && deleted.deleted) {\n            dispatch(updateGlobalLoadingIndicator(true));\n            try {\n                const { accessible } = await api.getAppAccess(appId);\n                await invalidateIdeAppListQueries();\n                if (!accessible) {\n                    dispatch(nullApp());\n                    dispatch(navigate({ type: \"START_PAGE\" }));\n                    return;\n                }\n            } finally {\n                dispatch(updateGlobalLoadingIndicator(false));\n            }\n        }\n        await dispatch(loadAppPermissions(appId));\n    };\n\nexport const getAppPermissions = (state: State) => state.app?.permissions;\nexport const getIsOwner = (state: State) => state.app?.owner?.isOwner;\n","import { useMemo } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { AppId } from \"@/types\";\nimport { getBackgroundTasks } from \"@/api\";\nimport { queryClient } from \"@/util/queryClient\";\nimport { getAppId } from \"./app\";\nimport { getRunMode } from \"./runner\";\n\nexport interface BackgroundTask {\n    id: string;\n    debug: boolean;\n    mine: boolean;\n    completion_status: \"completed\" | \"threw\" | \"killed\" | \"mia\" | string;\n    start_time: number;\n    last_seen_alive: number;\n    task_name: string;\n    session_sha: string;\n    session_id: string;\n}\n\nconst NO_TASKS: BackgroundTask[] = [];\n\nexport const INACTIVE_TASK_TYPES = [\"completed\", \"threw\", \"killed\", \"mia\"];\n\nexport const isMyRunningDebugTask = (task: BackgroundTask) =>\n    task.debug && task.mine && !INACTIVE_TASK_TYPES.includes(task.completion_status);\n\nconst sortTasks = (tasks: BackgroundTask[]) => {\n    tasks.sort((a, b) => {\n        const dateA = new Date(a.start_time),\n            dateB = new Date(b.start_time);\n        if (dateA < dateB) {\n            return 1;\n        }\n        if (dateA > dateB) {\n            return -1;\n        }\n        return 0;\n    });\n};\n\nexport function useBackgroundTasks(myActiveDebugTasksOnly: boolean) {\n    const debugRunMode = useSelector(getRunMode);\n    const appId = useSelector(getAppId);\n\n    const { data, dataUpdatedAt: lastUpdate } = useQuery({\n        queryKey: [\"background-tasks\", appId] as const,\n        queryFn: async ({ queryKey }) => {\n            const [_, appId] = queryKey;\n            let tasks: BackgroundTask[] = await getBackgroundTasks(appId, true);\n            tasks ||= NO_TASKS;\n            sortTasks(tasks);\n            return tasks;\n        },\n        refetchInterval: ({ state }) => {\n            if (state.data?.some(isMyRunningDebugTask)) {\n                return 5000;\n            } else if (debugRunMode) {\n                return 6000;\n            }\n            // no polling\n            return false;\n        },\n        enabled: !!appId,\n        refetchOnMount: true,\n        staleTime: 0,\n    });\n\n    const tasks = useMemo(() => {\n        if (!myActiveDebugTasksOnly) return data;\n        return data?.filter(isMyRunningDebugTask);\n    }, [data, myActiveDebugTasksOnly]);\n\n    return { tasks: tasks ?? NO_TASKS, lastUpdate };\n}\n\nexport function invalidateBackgroundTasks(appId: AppId | undefined) {\n    if (!appId) return;\n    queryClient.invalidateQueries({ queryKey: [\"background-tasks\", appId] });\n}\n\nexport function optimisticallyKillMyRunningDebugTasks(appId: AppId) {\n    queryClient.setQueriesData({ queryKey: [\"background-tasks\", appId] }, (prev?: BackgroundTask[]) => {\n        if (!prev) return prev;\n        const rv: BackgroundTask[] = [];\n        for (const t of prev) {\n            if (isMyRunningDebugTask(t)) {\n                rv.push({ ...t, completion_status: \"killed\" });\n            } else {\n                rv.push(t);\n            }\n        }\n        return rv;\n    });\n}\n","import { isEmpty, set, update } from \"lodash-es\";\nimport { createSelector } from \"reselect\";\nimport { EVENTS, raiseEvent } from \"@/actions\";\nimport { ConversationPid } from \"@/agent/types.ts\";\nimport { getAppCta, validCtas } from \"@/controllers/app/cta\";\nimport { getAppHasConflicts } from \"@/controllers/app/history\";\nimport { getDebugEnvBreakpoints, getDebuggerHyperStacks } from \"@/controllers/debugger\";\nimport { getDesignerHasOutput } from \"@/controllers/designer\";\nimport { getInTutorialMode } from \"@/controllers/ideTutorial\";\nimport { getScriptRuns } from \"@/controllers/scripts\";\nimport { getShowTalkToUsOffer } from \"@/controllers/talkToUsOffer\";\nimport { getHasExitedTutorialTab, getShowRoadmap, updateCtaKey, updateUserEditorPrefs } from \"@/controllers/user\";\nimport { WHERE_TO_START_TUTORIAL_TAB_TITLES, getWhereToStartTutorialTab } from \"@/controllers/whereToStartTutorials\";\nimport {\n    AnvilAction,\n    BottomPanelAgentHeader,\n    BottomPanelDebuggerHeader,\n    BottomPanelReplHeader,\n    BottomPanelTabHeader,\n    BottomPanelTabTarget,\n    BottomPanelTabTargetScriptRun,\n    Repl,\n    State,\n} from \"@/types\";\nimport { getAbGetStartedRoadmap, getAbTutorialsInIde, getAbVideoIntro } from \"@/util/hooks/ab-flags\";\nimport { getRepls } from \"./repl\";\nimport { getTestingEnabled } from \"./services\";\n\nexport const getBottomPanelHeight = (state: State) => {\n    const height = Math.min(state.editor.bottomPanelHeight, document.body.scrollHeight - 110);\n    if (isNaN(height)) {\n        // type guard\n        return 200;\n    } else {\n        return height;\n    }\n};\n\nexport const getStartingBottomPanelHeight = (state: State) => {\n    return Math.max(state.editor.bottomPanelHeight, 200, Math.round(window.innerHeight / 5));\n};\n\nexport const setBottomPanelHeight =\n    (height: number): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        if (height < 80) {\n            dispatch(closeBottomPanel());\n        } else {\n            updateState(set, [\"editor\", \"bottomPanelHeight\"], height);\n        }\n    };\n\nexport const closeBottomPanel = (): AnvilAction => (dispatch, getState, updateState) => {\n    updateState(set, [\"editor\", \"bottomPanelCurrentTab\"], null);\n};\n\nconst isBottomPanelRepl = (tab: BottomPanelTabTarget): tab is BottomPanelReplHeader =>\n    [\"runnerRepl\", \"serverRepl\", \"tableauRepl\"].includes(tab.type);\n\nconst isBottomPanelScriptRun = (tab: BottomPanelTabTarget): tab is BottomPanelTabTargetScriptRun =>\n    tab.type === \"scriptRun\";\n\nconst isBottomPanelDebugger = (tab: BottomPanelTabTarget): tab is BottomPanelDebuggerHeader => tab.type === \"debugger\";\n\nconst isBottomPanelAgent = (tab: BottomPanelTabTarget): tab is BottomPanelAgentHeader => tab.type === \"agent\";\n\nexport const bottomTabsMatch = (tabA: BottomPanelTabTarget, tabB: BottomPanelTabTarget) => {\n    if (tabA.type !== tabB.type) {\n        return false;\n    }\n    if (isBottomPanelRepl(tabA) && isBottomPanelRepl(tabB)) {\n        return tabA.replId === tabB.replId;\n    }\n    if (isBottomPanelScriptRun(tabA) && isBottomPanelScriptRun(tabB)) {\n        return tabA.scriptName === tabB.scriptName;\n    }\n    if (isBottomPanelDebugger(tabA) && isBottomPanelDebugger(tabB)) {\n        return tabA.hyperstackId === tabB.hyperstackId;\n    }\n    if (isBottomPanelAgent(tabA) && isBottomPanelAgent(tabB)) {\n        return tabA.conversationPid === tabB.conversationPid;\n    }\n    return true;\n};\n\ninterface CategorizedRepls {\n    runner: Array<[string, Repl]>;\n    server: Array<[string, Repl]>;\n    tableau: Array<[string, Repl]>;\n}\n\nconst categorizeRepls = (repls: Record<string, Repl>) => {\n    const categories: CategorizedRepls = {\n        runner: [],\n        server: [],\n        tableau: [],\n    };\n\n    Object.entries(repls ?? {}).forEach(([replId, repl]) => {\n        if (repl.isBeingReplaced) return;\n        const { type } = repl;\n        categories[type]?.push([replId, repl]);\n    });\n\n    categories.server.sort(([_, a], [_1, b]) => a.tabIndex - b.tabIndex);\n\n    return categories;\n};\n\nexport const getBottomPanelTabs = createSelector(\n    [\n        getAbTutorialsInIde,\n        (s) => getHasExitedTutorialTab(s),\n        getAbGetStartedRoadmap,\n        (s) => getShowRoadmap(s),\n        getAbVideoIntro,\n        (s) => getWhereToStartTutorialTab(s),\n        (s) => getAppCta(s),\n        (s) => getDesignerHasOutput(s),\n        (s) => getAppHasConflicts(s),\n        (s) => getRepls(s),\n        (s) => getDebuggerHyperStacks(s),\n        (s) => getDebugEnvBreakpoints(s),\n        (s) => getInTutorialMode(s),\n        (s) => getScriptRuns(s),\n        (s) => getBottomPanelConversationPids(s),\n        (s) => getShowTalkToUsOffer(s),\n        getTestingEnabled,\n    ],\n    (\n        tutorialsInIDE,\n        hasExitedTutorialTab,\n        roadmapAbFlag,\n        showRoadmap,\n        introVideoFlag,\n        whereToStartTutorialTab,\n        appCta,\n        designerHasOutput,\n        hasConflicts,\n        repls,\n        debuggerHyperStacks,\n        breakpoints,\n        inTutorialMode,\n        scriptRuns,\n        conversationPids,\n        showTalkToUsOffer,\n        testingEnabled\n    ) => {\n        const tabs: BottomPanelTabHeader[] = [];\n\n        tutorialsInIDE = false;\n\n        if (!inTutorialMode) {\n            if (showTalkToUsOffer) {\n                tabs.push({\n                    type: \"talkToUs\",\n                    title: \"Talk to us\",\n                });\n            }\n\n            if (tutorialsInIDE && !hasExitedTutorialTab) {\n                tabs.push({\n                    type: \"tutorial\",\n                    title: \"New to Anvil?\",\n                });\n            }\n\n            if ((roadmapAbFlag && showRoadmap) || localStorage[\"forceShowAnvilRoadmap\"]) {\n                tabs.push({\n                    type: \"roadmap\",\n                    title: \"Get Started\",\n                });\n            }\n\n            tabs.push({\n                type: \"versionHistory\",\n                title: \"Version History\",\n            });\n\n            tabs.push({\n                type: \"backgroundTasks\",\n                title: \"Background Tasks\",\n            });\n\n            if (testingEnabled) {\n                tabs.push({\n                    type: \"serverTests\",\n                    title: \"Server Tests\",\n                });\n            }\n\n            if (introVideoFlag) {\n                tabs.push({\n                    type: \"introVideo\",\n                    title: \"Video Tour\",\n                });\n            }\n\n            if (whereToStartTutorialTab) {\n                tabs.push({\n                    type: \"onboardingCta\",\n                    title: WHERE_TO_START_TUTORIAL_TAB_TITLES[whereToStartTutorialTab],\n                });\n            }\n\n            if (appCta?.preset) {\n                const cta = validCtas[appCta.preset];\n                if (cta) {\n                    tabs.push({\n                        type: \"appCta\",\n                        title: \"tabTitle\" in cta ? cta.tabTitle : \"How to Build This App\",\n                    });\n                }\n            }\n\n            for (const conversationPid of conversationPids) {\n                tabs.push({\n                    type: \"agent\",\n                    conversationPid,\n                    title: \"Conversation\",\n                });\n            }\n\n            if (hasConflicts) {\n                tabs.push({\n                    type: \"conflicts\",\n                    title: \"Conflicts\",\n                });\n            }\n\n            if (!isEmpty(breakpoints)) {\n                tabs.push({\n                    type: \"breakpoints\",\n                    title: \"Breakpoints\",\n                });\n            }\n\n            if (designerHasOutput) {\n                tabs.push({\n                    type: \"designerOutput\",\n                    title: \"Designer Output\",\n                });\n            }\n\n            if (scriptRuns) {\n                for (const [scriptName, runs] of Object.entries(scriptRuns)) {\n                    tabs.push({\n                        type: \"scriptRun\",\n                        scriptName,\n                        title: `Script Output: ${scriptName}`,\n                    });\n                }\n            }\n        }\n        const { runner: runnerRepls, server: serverRepls, tableau: tableauRepls } = categorizeRepls(repls);\n\n        runnerRepls.forEach(([replId, repl]) => {\n            tabs.push({\n                type: \"runnerRepl\",\n                replId,\n                repl,\n                title: `${repl.readOnly ? \"Stopped\" : \"Running\"} App Console`,\n            });\n        });\n\n        serverRepls.forEach(([replId, repl], idx) => {\n            tabs.push({\n                type: \"serverRepl\",\n                replId,\n                repl,\n                title: `Server Console ${idx + 1}`,\n            });\n        });\n\n        tableauRepls.forEach(([replId, repl], idx) => {\n            tabs.push({\n                type: \"tableauRepl\",\n                replId,\n                repl,\n                title: `Tableau Output ${idx + 1}`,\n            });\n        });\n\n        if (!inTutorialMode) {\n            // Sort by id for a stable order - resuming a debugger re-inserts its entry, which would\n            // otherwise reorder Object.entries and renumber \"Debug (N)\" tabs.\n            const sortedHyperStacks = Object.entries(debuggerHyperStacks).sort(([idA], [idB]) =>\n                idA < idB ? -1 : idA > idB ? 1 : 0\n            );\n            sortedHyperStacks.forEach(([id, dbg], idx) => {\n                tabs.push({\n                    type: \"debugger\",\n                    hyperstackId: id,\n                    title: `Debug${sortedHyperStacks.length > 1 ? ` (${idx + 1})` : \"\"}`,\n                    subText: dbg.client.type,\n                });\n            });\n        }\n\n        if (inTutorialMode) {\n            tabs.push({\n                type: \"ideTutorial\",\n                title: \"Unlock the rest of Anvil\",\n            });\n        }\n\n        return tabs;\n    }\n);\n\nexport const closeBottomTab =\n    (tab: BottomPanelTabTarget): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(`Close bottom panel tab: '${tab.type}'`, ({ editor }) => {\n            editor.bottomPanelTabStack = editor.bottomPanelTabStack.filter((t) => !bottomTabsMatch(t, tab));\n            const currentTab = editor.bottomPanelCurrentTab;\n            if (currentTab && bottomTabsMatch(currentTab, tab)) {\n                // Don't fall back onto a different, unrelated paused debugger's tab.\n                const fallbackStack = isBottomPanelDebugger(tab)\n                    ? editor.bottomPanelTabStack.filter((t) => !isBottomPanelDebugger(t))\n                    : editor.bottomPanelTabStack;\n                editor.bottomPanelCurrentTab = fallbackStack.at(-1) ?? null;\n            }\n        });\n    };\n\nexport const openOrFocusBottomTab =\n    (tab: BottomPanelTabTarget): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(`Focus bottom panel tab: '${tab.type}'`, (state) => {\n            state.editor.bottomPanelTabStack = state.editor.bottomPanelTabStack.filter((t) => !bottomTabsMatch(t, tab));\n            state.editor.bottomPanelTabStack.push(tab);\n            state.editor.bottomPanelCurrentTab = tab;\n            state.editor.bottomPanelHeight = getStartingBottomPanelHeight(state);\n        });\n        dispatch(raiseEvent(EVENTS.OPEN_OR_FOCUS_BOTTOM_TAB));\n    };\n\nexport const openOrFocusPrevBottomTab = (): AnvilAction => (dispatch, getState, updateState) => {\n    const bottomTabStack = getState().editor.bottomPanelTabStack;\n    const tab = bottomTabStack?.at(-1) ?? { type: \"versionHistory\" };\n    dispatch(openOrFocusBottomTab(tab));\n};\n\nexport const closeTutorialTab = (): AnvilAction => (dispatch, getState, updateState) => {\n    dispatch(updateCtaKey(\"bottomPanel\", true));\n    dispatch(closeBottomTab({ type: \"tutorial\" }));\n};\n\n// Permanently dismiss the onboarding CTA tab for this user.\nexport const dismissOnboardingCtaTab = (): AnvilAction => (dispatch) => {\n    dispatch(updateUserEditorPrefs(\"userHasDismissedOnboardingCtaTab\", true));\n    dispatch(closeBottomTab({ type: \"onboardingCta\" }));\n};\n\nexport const getBottomPanelIsOpen = (state: State) => state.editor.bottomPanelCurrentTab != null;\nexport const getBottomPanelCurrentTab = (state: State) => state.editor.bottomPanelCurrentTab;\nexport const getBottomPanelTabStack = (state: State) => state.editor.bottomPanelTabStack;\n\nexport const getBottomPanelConversationPids = (state: State) => state.editor.bottomPanelConversationPids || [];\nexport const openOrFocusBottomPanelConversation =\n    (conversationPid: ConversationPid): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const state = getState();\n        const currentConvs = getBottomPanelConversationPids(state);\n        if (!currentConvs.includes(conversationPid)) {\n            updateState(update, [\"editor\", \"bottomPanelConversationPids\"], (currentConvs: ConversationPid[]) => [\n                ...currentConvs,\n                conversationPid,\n            ]);\n        }\n        dispatch(openOrFocusBottomTab({ type: \"agent\", conversationPid }));\n    };\n\nexport const closeBottomPanelConversation =\n    (conversationPid: ConversationPid): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        dispatch(closeBottomTab({ type: \"agent\", conversationPid }));\n        updateState(update, [\"editor\", \"bottomPanelConversationPids\"], (currentConvs: ConversationPid[]) =>\n            currentConvs.filter((c) => c !== conversationPid)\n        );\n    };\n","// This file contains functions for dealing with Table Mappings and Data Tables.\n// There isn't much here yet, because most functionality remains in the old tableServiceApi for now.\nimport { original } from \"immer\";\nimport { cloneDeep, isEqual, remove } from \"lodash-es\";\nimport { createSelector } from \"reselect\";\nimport modals from \"@/components/modals\";\nimport { getAllDesignerRpcObjects } from \"@/controllers/designer\";\nimport { claimAchievement } from \"@/controllers/user.js\";\nimport type { DBTableNavTarget } from \"@/router/navTypes\";\nimport {\n    AnvilAction,\n    AnvilAsyncAction,\n    AppConfig,\n    AppId,\n    AppState,\n    LiveObjectSingleColumn,\n    State,\n    TableId,\n    TableIndex,\n    UpdateState,\n} from \"@/types\";\nimport type {\n    AccessibleTableMapping,\n    AppSchema,\n    ColumnSpec,\n    Diff,\n    LinkColumn,\n    LiveObjectColumn,\n    SchemaColumnSpec,\n    Table,\n    TableMapping,\n    TableMappingId,\n    TableSchema,\n} from \"@/types/database\";\nimport type { FeatureMap } from \"@/types/user\";\nimport { featureSupported } from \"@/util/features.ts\";\nimport * as api from \"../api/tables\";\nimport * as tableApi from \"../api/tables\";\nimport { updateTable, updateTableAccess } from \"../api/tables\";\nimport * as autocompleter from \"../controllers/app/autocompleter\";\nimport { invalidateTableSchema } from \"../controllers/app/autocompleter\";\nimport { addTaskIfMissing } from \"../controllers/ide_tasks\";\nimport { onIdle } from \"../util\";\nimport {\n    getAppConfig,\n    getAppDBSchema,\n    getAppId,\n    getAppName,\n    getTableMappings,\n    getAllTableMappings,\n    markAppPathUnsaved,\n    markUnsaved,\n    updateAppDBSchema,\n    updateAppSchemaSync,\n    updateGlobalLoadingIndicator,\n} from \"./app\";\nimport { applyCodePreludeEverywhere } from \"./app/code\";\nimport { colSpecToColSchema, getCreateSplitTables, modifyIndex } from \"./db_new\";\nimport { getCategorisedEnvironments } from \"./environments\";\nimport { alert, modal } from \"./modals\";\nimport { getServiceSpecs } from \"./services\";\nimport { closeTabFromNavTarget } from \"./tabs\";\n\nexport * from \"./db_new\";\n\ndeclare const log: { debug: (...args: any[]) => void };\n\ntype DataTableCacheEntry = {\n    id?: number;\n    access?: { table_mapping_id?: TableMappingId; table_mapping_name?: string };\n};\n\ntype DataTablesState = {\n    tables?: Record<string, { tables?: DataTableCacheEntry[] }>;\n};\n\ntype OldIDESchemaUpdateData = {\n    tableMappingId?: string | number | null;\n};\n\ntype OldIDEAddColData = OldIDESchemaUpdateData & {\n    colId: string | number;\n    name: string;\n    admin_ui: { width: number; order?: number };\n    type: SchemaColumnSpec[\"type\"] | \"liveObject\" | \"liveObjectArray\";\n    targetTableId?: number;\n};\n\ntype OldIDEDeleteColsData = OldIDESchemaUpdateData & {\n    colIds: string[];\n};\n\ntype OldIDERenameColData = OldIDESchemaUpdateData & {\n    colId: string | number;\n    newName: string;\n};\n\ntype OldIDEUpdateAccessData = OldIDESchemaUpdateData & {\n    server: Table[\"server\"];\n    client: Table[\"client\"];\n    python_name: string;\n};\n\ntype OldIDESchemaUpdateArgs =\n    | [tableId: number, updateType: \"addCol\", data: OldIDEAddColData]\n    | [tableId: number, updateType: \"deleteCols\", data: OldIDEDeleteColsData]\n    | [tableId: number, updateType: \"renameCol\", data: OldIDERenameColData]\n    | [tableId: number, updateType: \"updateAccess\", data: OldIDEUpdateAccessData];\n\nconst requireAppId = (state: State): AppId => {\n    const appId = getAppId(state);\n    if (!appId) {\n        throw new Error(\"App ID is not loaded\");\n    }\n    return appId;\n};\n\nconst withAppState = (updater: (app: AppState, state: State) => void) => (state: State) => {\n    if (!state.app) return;\n    updater(state.app, state);\n};\n\nconst updateDBAppState = (updateState: UpdateState, updater: (app: AppState, state: State) => void) => {\n    updateState((state) => {\n        if (!state.app) return;\n        updater(state.app, state);\n    });\n};\n\nconst _getDBAppSchema = (state: State): AppSchema => (getAppDBSchema(state) ?? {}) as AppSchema;\n\nconst _getDBConfig = (state: State): AppConfig => (getAppConfig(state) ?? {}) as AppConfig;\n\nconst _getAppNameOrDefault = (state: State): string => getAppName(state) ?? \"\";\n\nconst findMapping = (mappings: TableMapping[], mappingId: TableMappingId) =>\n    mappings.find((m) => m.table_mapping_id === mappingId);\n\nconst getTableSchema = (schema: AppSchema, pythonName: string) => schema[pythonName] as TableSchema | undefined;\n\nconst isLinkedCol = (col: SchemaColumnSpec): col is LinkColumn => \"target\" in col;\n\n// When making schema changes, we often want to update the app schema too. But only if it's currently in sync, apart from index changes.\nexport const diffHasOnlyIndexChanges = (tableMapping: TableMapping | undefined) =>\n    (tableMapping?.diff.filter((a) => a.type !== \"ADD_INDEX\" && a.type !== \"DELETE_INDEX\").length ?? 0) === 0;\n\n/**\n * @param {AbortController} [abort]\n * @returns {import(\"@/types\").AnvilAsyncAction<import(\"@/types/database\").TableMapping[]>}\n */\nexport const reloadAppTableMappings =\n    (abort?: AbortController): AnvilAsyncAction<TableMapping[]> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = requireAppId(state);\n        const appSchema = _getDBAppSchema(state);\n        const hints = getTableIdHints(state);\n        const tableMappings = await tableApi.getTableMappings(appId, appSchema, hints, abort);\n        updateDBAppState(updateState, (app) => {\n            app.tableMappings = tableMappings;\n        });\n        return tableMappings;\n    };\n\nexport const getTableMappingDisplayName = (mapping: Pick<TableMapping, \"name\" | \"ephemeral\"> | undefined | null) =>\n    mapping?.ephemeral ? \"Temporary Database\" : mapping?.name;\n\nexport const getTableNavTarget = (\n    mapping: Pick<TableMapping, \"table_mapping_id\">,\n    table: Pick<Table, \"id\">\n): DBTableNavTarget => ({\n    type: \"DB_TABLE\",\n    tableId: table.id,\n    tableMappingId: mapping.table_mapping_id,\n});\n\nexport const closeTableTab =\n    (mapping: Pick<TableMapping, \"table_mapping_id\">, table: Pick<Table, \"id\">): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        dispatch(closeTabFromNavTarget(getTableNavTarget(mapping, table)));\n    };\n\nconst storeUpdatedTable =\n    (table: Table) =>\n    ({ editor: { dataTables } }: { editor: { dataTables?: DataTablesState } }) => {\n        for (const [_appId, entry] of Object.entries(dataTables?.tables || {})) {\n            const tables = entry.tables ?? [];\n            for (let i = 0; i < tables.length; i++) {\n                if (tables[i].id === table.id) {\n                    tables[i] = table;\n                }\n            }\n        }\n    };\n\nconst toSafeTablePythonName = (name: string, table: Table | null, mappingTables: Table[] | undefined) => {\n    name = name\n        .replace(/[^A-Za-z0-9]/g, \"_\")\n        .replace(/^\\d/, \"_$&\")\n        .toLowerCase();\n    let nameN = 2;\n\n    while (true) {\n        let match = false;\n        for (const t of mappingTables || []) {\n            if (t.python_name === name && t !== table) {\n                match = true;\n                break;\n            }\n        }\n\n        if (!match) return name;\n\n        if (nameN === 2) {\n            name += \"_2\";\n            nameN++;\n        } else {\n            name = name.replace(/_\\d*$/, \"_\" + nameN++);\n        }\n    }\n};\n\nlet inFlightOps = 0;\nlet totalOps = 0;\n\nexport const notifySchemaUpdate = (): AnvilAsyncAction<void> => async (dispatch, getState, updateState) => {\n    // Reload table mappings to make sure we have latest diffs after an update to any schema.\n    //await dispatch(onIdle(reloadAppTableMappings(), \"AFTER-SCHEMA-UPDATE\"));\n};\n\n/**\n * @param {import(\"@/types\").AnvilAction} action\n * @returns {import(\"@/types\").AnvilAction}\n */\nexport const withTableOp =\n    <R = unknown>(action: AnvilAsyncAction<R>): AnvilAsyncAction<R> =>\n    async (dispatch, getState, updateState) => {\n        inFlightOps++;\n        totalOps++;\n        try {\n            return await dispatch(action);\n        } finally {\n            inFlightOps--;\n            if (inFlightOps === 0) {\n                const requireTotalOps = totalOps;\n\n                dispatch(\n                    onIdle(async (dispatch, getState, updateState) => {\n                        if (requireTotalOps !== totalOps) {\n                            return;\n                        }\n                        const state = getState();\n                        const appId = requireAppId(state);\n                        const appSchema = _getDBAppSchema(state);\n                        const hints = getTableIdHints(state);\n                        const rpcs = getAllDesignerRpcObjects();\n                        for (const rpc of rpcs) {\n                            rpc.raiseEvent(\"invalidateRecordSchemas\");\n                        }\n                        const tableMappings = await tableApi.getTableMappings(appId, appSchema, hints); // TODO: Abort on next op.\n                        if (requireTotalOps !== totalOps) {\n                            return;\n                        }\n                        updateDBAppState(updateState, (app) => {\n                            app.tableMappings = tableMappings;\n                        });\n                    }, \"AFTER-SCHEMA-UPDATE\")\n                );\n            }\n        }\n    };\n\nexport const getHasTables = (state: State) => {\n    const tableMappings = getTableMappings(state);\n    return (tableMappings || []).some((m) => m.tables?.length);\n};\n\nexport const linkExistingTableToMapping = (\n    mapping: TableMapping,\n    table: Table\n): AnvilAsyncAction<Table | { error: unknown }> =>\n    withTableOp(async (dispatch, getState, updateState) => {\n        const markSaved = dispatch(markUnsaved(`link-table-to-mapping`));\n        try {\n            const state = getState();\n            const appId = requireAppId(state);\n            const appName = _getAppNameOrDefault(state);\n            const hasTables = getHasTables(state);\n\n            const mappingTables = mapping?.tables;\n            const tableToLink = { ...table, python_name: toSafeTablePythonName(table.name, null, mappingTables) };\n\n            const linkedTable = await api.linkExistingTable(appId, mapping.table_mapping_id, tableToLink);\n\n            const flatLinkedTable = {\n                id: linkedTable.table_id,\n                name: table.name,\n                python_name: linkedTable.python_name,\n                client: linkedTable.client,\n                server: linkedTable.server,\n                columns: {},\n                split: table.split, // TODO: Is this correct?\n                all_indexes: [],\n            };\n            log.debug(\"Linked table:\", flatLinkedTable);\n            updateDBAppState(updateState, (app) => {\n                const { tableMappings } = app;\n                const accessibleTableMappings = app.accessibleTableMappings ?? (app.accessibleTableMappings = []);\n                const tm = findMapping(tableMappings, mapping.table_mapping_id);\n                if (!tm) return;\n                tm.tables.push(flatLinkedTable);\n                tm.schema[flatLinkedTable.python_name] = linkedTable.schema;\n\n                const mappingInAccess = accessibleTableMappings?.find(\n                    (m) => m.table_mapping_id === mapping.table_mapping_id && Object.keys(m.apps || {}).includes(appId)\n                );\n\n                if (mappingInAccess) {\n                    mappingInAccess.tables.push({\n                        id: flatLinkedTable.id,\n                        name: flatLinkedTable.name,\n                        python_name: flatLinkedTable.python_name,\n                    });\n                } else {\n                    const mappingWithTable = {\n                        table_mapping_id: mapping.table_mapping_id || null,\n                        name: mapping.name,\n                        apps: { [appId]: appName }, //todo: this is hacky but I don't know how to figure out how to do it. It should go thru and actually find all the apps that have that mapping I think even if they're empty\n                        tables: [\n                            {\n                                id: flatLinkedTable.id,\n                                name: flatLinkedTable.name,\n                                python_name: flatLinkedTable.python_name,\n                            },\n                        ],\n                    };\n                    accessibleTableMappings.push(mappingWithTable);\n                }\n            });\n\n            await dispatch(notifySchemaUpdate());\n\n            if (!hasTables) {\n                const spec = getServiceSpecs(state)[\"/runtime/services/tables.yml\"];\n                await dispatch(applyCodePreludeEverywhere(spec?.prelude, { sourceName: \"Data Tables service\" }));\n            }\n\n            return flatLinkedTable;\n        } catch (e) {\n            return { error: e };\n        } finally {\n            markSaved();\n        }\n    });\n\nexport const createTable = (mappingId: TableMappingId, name: string): AnvilAsyncAction<Table> =>\n    withTableOp(async (dispatch, getState, updateState) => {\n        const markSaved = dispatch(markUnsaved(`new-table`));\n        try {\n            const state = getState();\n            const appId = requireAppId(state);\n            const appName = _getAppNameOrDefault(state);\n            const hasTables = getHasTables(state);\n            const split = getCreateSplitTables(state);\n            const mappingTables = (getAllTableMappings(state) ?? []).find((m) => m.table_mapping_id === mappingId)?.tables;\n            const newTable = {\n                name,\n                python_name: toSafeTablePythonName(name, null, mappingTables),\n            };\n\n            const isCurrentMapping = mappingId === getDebugEnvironmentTableMappingId(state);\n\n            const createdTable = await api.createTable(appId, mappingId, newTable, split);\n            const flatCreatedTable = {\n                id: createdTable.id,\n                name: createdTable.name,\n                python_name: createdTable.access.python_name,\n                client: createdTable.access.client,\n                server: createdTable.access.server,\n                columns: {},\n                split,\n                all_indexes: [],\n            } satisfies Table;\n            log.debug(\"Created table:\", flatCreatedTable);\n            updateDBAppState(updateState, (app) => {\n                const { tableMappings, config } = app;\n                const accessibleTableMappings = app.accessibleTableMappings;\n                const mapping = findMapping(tableMappings, mappingId);\n                if (!mapping) return;\n                mapping.tables.push(flatCreatedTable);\n                mapping.schema[flatCreatedTable.python_name] = createdTable.schema;\n\n                if (diffHasOnlyIndexChanges(mapping) && isCurrentMapping) {\n                    if (!config.db_schema) {\n                        config.db_schema = {};\n                    }\n                    config.db_schema[flatCreatedTable.python_name] = {\n                        // TODO: Only if current\n                        client: flatCreatedTable.client,\n                        server: flatCreatedTable.server,\n                        columns: [],\n                        title: flatCreatedTable.name,\n                        indexes: [],\n                    };\n                }\n\n                const mappingInAccess = accessibleTableMappings?.find(\n                    (m) => m.table_mapping_id === mappingId && Object.keys(m.apps || {}).includes(appId)\n                );\n                if (mappingInAccess) {\n                    mappingInAccess.tables.push({\n                        id: flatCreatedTable.id,\n                        name: flatCreatedTable.name,\n                        python_name: flatCreatedTable.python_name,\n                    });\n                } else {\n                    //add the entire mapping into accessible table with the table on it.\n                    const mappingWithTable = {\n                        table_mapping_id: mapping.table_mapping_id || null,\n                        name: mapping.name,\n                        apps: { [appId]: appName }, //todo: this is hacky but I don't know how to figure out how to do it. It should go thru and actually find all the apps that have that mapping I think even if they're empty\n                        tables: [\n                            {\n                                id: flatCreatedTable.id,\n                                name: flatCreatedTable.name,\n                                python_name: flatCreatedTable.python_name,\n                            },\n                        ],\n                    };\n                    if (accessibleTableMappings) {\n                        accessibleTableMappings.push(mappingWithTable);\n                    } else {\n                        console.warn(\n                            \"Could not add new table to accessible table mappings because they haven't finished loading yet\"\n                        );\n                    }\n                }\n            });\n            dispatch(markAppPathUnsaved([\"SETTINGS\", \"db_schema\"]));\n\n            await dispatch(notifySchemaUpdate());\n\n            if (!hasTables) {\n                const spec = getServiceSpecs(state)[\"/runtime/services/tables.yml\"];\n                await dispatch(applyCodePreludeEverywhere(spec?.prelude, { sourceName: \"Data Tables service\" }));\n            }\n            if (isCurrentMapping) {\n                dispatch(invalidateTableSchema(mappingId));\n            }\n\n            return flatCreatedTable;\n        } finally {\n            markSaved();\n        }\n    });\n\nexport const accessFromTable = (appId: AppId, mapping: TableMapping | null | undefined, table: Table) => ({\n    table_id: table.id,\n    app_id: appId,\n    server: table.server,\n    client: table.client,\n    table_mapping_id: mapping?.table_mapping_id ?? null,\n    python_name: table.python_name,\n});\n\nexport const renameTable = (mapping: TableMapping, table: Table, name: string): AnvilAction =>\n    withTableOp(async (dispatch, getState, updateState) => {\n        log.debug(\"Renaming table\", mapping, table, name);\n        const saved = dispatch(markUnsaved(`table-${table.id}`));\n        try {\n            const state = getState();\n            const appId = requireAppId(state);\n            const newTable = { ...table, name };\n\n            const isCurrentMapping = mapping.table_mapping_id === getDebugEnvironmentTableMappingId(state);\n\n            const updatedTable = { ...table, ...(await updateTable(appId, mapping.table_mapping_id, newTable)) };\n\n            const sanitise = (name: string) =>\n                (\"\" + name)\n                    .replace(/[^A-Za-z0-9]/g, \"_\")\n                    .replace(/^\\d/, \"_$&\")\n                    .toLowerCase() || \"_\";\n\n            if (new RegExp(\"^\" + sanitise(table.name) + \"(_\\\\d+)?$\").test(table.python_name)) {\n                const newPythonName = toSafeTablePythonName(sanitise(name), table, mapping.tables);\n                const oldAccess = accessFromTable(appId, mapping, table);\n                const newAccess = {\n                    app_id: oldAccess.app_id,\n                    table_id: oldAccess.table_id,\n                    table_mapping_id: oldAccess.table_mapping_id,\n                    python_name: newPythonName,\n                };\n                await updateTableAccess(newAccess);\n                updatedTable.python_name = newPythonName;\n\n                //TODO: rowLinkCache.invalidateTable(ctrl.selectedTable.table.id);\n                //TODO: autoCompleter.invalidateTableSchema();\n            }\n\n            // Save updated table in state to avoid loading from scratch.\n            updateDBAppState(updateState, (app) => {\n                const { tableMappings, accessibleTableMappings, config } = app;\n                const db_schema = (config.db_schema ??= {});\n                tableMappings.forEach((m) => {\n                    const tableToUpdate = m.tables?.find((t) => t.id === updatedTable.id);\n                    if (tableToUpdate) {\n                        tableToUpdate.name = updatedTable.name;\n                        tableToUpdate.python_name = updatedTable.python_name;\n\n                        if (updatedTable.python_name !== table.python_name) {\n                            m.schema[updatedTable.python_name] = { ...m.schema[table.python_name], title: name };\n                            delete m.schema[table.python_name];\n\n                            // Find all cols in tables in this table mapping that link to this table. Update them.\n                            for (const tableSchema of Object.values(m.schema)) {\n                                for (const col of tableSchema.columns) {\n                                    if (isLinkedCol(col) && col.target === table.python_name) {\n                                        col.target = updatedTable.python_name;\n                                    }\n                                }\n                            }\n\n                            // Now do the same in the app db_schema\n                            if (diffHasOnlyIndexChanges(mapping) && isCurrentMapping) {\n                                db_schema[updatedTable.python_name] = {\n                                    ...db_schema[table.python_name],\n                                    title: name,\n                                };\n                                delete db_schema[table.python_name];\n\n                                for (const tableSchema of Object.values(db_schema)) {\n                                    for (const col of tableSchema.columns) {\n                                        if (isLinkedCol(col) && col.target === table.python_name) {\n                                            col.target = updatedTable.python_name;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                });\n\n                if (accessibleTableMappings) {\n                    accessibleTableMappings.forEach(({ tables }) => {\n                        const tableToUpdate = tables?.find((t) => t.id === updatedTable.id);\n                        if (tableToUpdate) {\n                            tableToUpdate.name = updatedTable.name;\n                            tableToUpdate.python_name = updatedTable.python_name;\n                        }\n                    });\n                } else {\n                    console.warn(\n                        \"Could not update accessible table mappings because they haven't finished loading yet\"\n                    );\n                }\n            });\n\n            dispatch(markAppPathUnsaved([\"SETTINGS\", \"db_schema\"])); // TODO: Only if actually changed above.\n            if (isCurrentMapping) {\n                dispatch(invalidateTableSchema(mapping.table_mapping_id));\n            }\n\n            await dispatch(notifySchemaUpdate());\n        } finally {\n            saved();\n        }\n    });\n\nexport const deleteTable = (mapping: TableMapping, table: Table): AnvilAction =>\n    withTableOp(async (dispatch, getState, updateState) => {\n        log.debug(\"Deleting table\", table);\n        const saved = dispatch(markUnsaved(`delete-table-${table.id}`));\n        try {\n            const state = getState();\n            const appId = requireAppId(state);\n\n            const isCurrentMapping = mapping.table_mapping_id === getDebugEnvironmentTableMappingId(state);\n\n            await api.deleteTable(appId, mapping.table_mapping_id, table);\n\n            updateDBAppState(updateState, (app) => {\n                const { tableMappings, accessibleTableMappings, config } = app;\n                const db_schema = (config.db_schema ??= {});\n                const mappingToUpdate = findMapping(tableMappings, mapping.table_mapping_id);\n                if (!mappingToUpdate) return;\n                remove(mappingToUpdate.tables, (t) => t.id === table.id);\n                delete mappingToUpdate.schema[table.python_name];\n\n                if (diffHasOnlyIndexChanges(mappingToUpdate) && isCurrentMapping) {\n                    delete db_schema[table.python_name]; // TODO: Only if current\n                }\n\n                //find that mapping and remove the table from the mapping\n                const mappingInAccess = accessibleTableMappings?.find(\n                    (m) => m.table_mapping_id === mapping.table_mapping_id && Object.keys(m.apps || {}).includes(appId)\n                );\n                if (mappingInAccess) {\n                    remove(mappingInAccess.tables, (t) => t.id === table.id);\n                }\n            });\n\n            dispatch(markAppPathUnsaved([\"SETTINGS\", \"db_schema\"]));\n\n            await dispatch(notifySchemaUpdate());\n\n            if (isCurrentMapping) {\n                dispatch(invalidateTableSchema(mapping.table_mapping_id));\n            }\n\n            dispatch(closeTableTab(mapping, table));\n\n            if (!getHasTables(getState())) {\n                const spec = getServiceSpecs(state)[\"/runtime/services/tables.yml\"];\n                await dispatch(\n                    applyCodePreludeEverywhere(spec?.prelude, {\n                        sourceName: \"Data Tables service\",\n                        remove: true,\n                    })\n                );\n            }\n        } finally {\n            saved();\n        }\n    });\n\nconst liveObjectTypes = [\"liveObject\", \"liveObjectArray\"];\nconst isLiveObject = (colSpec: { type: string }): colSpec is LiveObjectColumn => liveObjectTypes.includes(colSpec.type);\n\n// This will probably go away once we have the full, real table API in the new IDE.\nexport const addTableColumn = (mappingId: TableMappingId, tableId: number, colSpec: ColumnSpec): AnvilAction =>\n    withTableOp(async (dispatch, getState, updateState) => {\n        const saved = dispatch(markUnsaved(`create-col-${colSpec.name}`));\n        try {\n            const state = getState();\n            const isCurrentMapping = mappingId === getDebugEnvironmentTableMappingId(state);\n            const appId = requireAppId(state);\n\n            const addedColumn = await api.saveTableCol(appId, mappingId, tableId, \"\", colSpec);\n\n            const addedColumnSpec: ColumnSpec = isLiveObject(addedColumn)\n                ? {\n                      name: addedColumn.name,\n                      type: addedColumn.type,\n                      admin_ui: addedColumn.admin_ui,\n                      client_hidden: addedColumn.client_hidden ?? false,\n                      table_id: addedColumn.table_id,\n                      backend: addedColumn.backend,\n                  }\n                : {\n                      name: addedColumn.name,\n                      type: addedColumn.type,\n                      admin_ui: addedColumn.admin_ui,\n                      client_hidden: addedColumn.client_hidden ?? false,\n                  };\n            if (\"onDelete\" in addedColumn && addedColumnSpec.type === \"liveObject\") {\n                addedColumnSpec.on_delete = addedColumn.onDelete as LiveObjectSingleColumn[\"on_delete\"];\n            }\n            let didSchemaUpdate = false;\n\n            // Make sure our local cache of the tableMapping includes the new column\n            updateDBAppState(updateState, (app) => {\n                const { tableMappings, config } = app;\n                const tableMapping = findMapping(tableMappings, mappingId);\n                if (!tableMapping) return;\n                const table = tableMapping.tables.find((t) => t.id === tableId);\n                if (!table) return;\n                table.columns ||= {};\n                table.columns[addedColumn.id] = addedColumnSpec;\n                tableMapping.schema[table.python_name] = addedColumn.schema;\n\n                if (diffHasOnlyIndexChanges(tableMapping) && isCurrentMapping) {\n                    const updatedSchema = colSpecToColSchema(addedColumn, tableMapping);\n                    config.db_schema ||= {};\n                    config.db_schema[table.python_name] ||= {\n                        client: table.client,\n                        server: table.server,\n                        columns: [],\n                        title: table.name,\n                        indexes: [],\n                    };\n                    config.db_schema[table.python_name].columns ||= [];\n                    config.db_schema[table.python_name].columns.push(updatedSchema);\n                    didSchemaUpdate = true;\n                }\n            });\n\n            if (didSchemaUpdate) {\n                dispatch(markAppPathUnsaved([\"SETTINGS\", \"db_schema\"]));\n            }\n            if (isCurrentMapping) {\n                dispatch(invalidateTableSchema(mappingId));\n            }\n            await dispatch(notifySchemaUpdate());\n            return addedColumn;\n        } finally {\n            saved();\n        }\n    });\n\nconst sortMappings = (tm: AccessibleTableMapping[] | TableMapping[]) => {\n    tm.sort((a, b) => {\n        if (a.table_mapping_id === null) {\n            return -1;\n        } else if (b.table_mapping_id === null) {\n            return 1;\n        } else {\n            return a.name.toLowerCase().localeCompare(b.name.toLowerCase());\n        }\n    });\n};\n\nexport const linkExistingMapping =\n    (mappingId: TableMappingId): AnvilAsyncAction<TableMapping | { error: unknown }> =>\n    async (dispatch, getState, updateState) => {\n        const markSaved = dispatch(markUnsaved(`link-mapping-to-app`));\n        try {\n            const state = getState();\n            const appId = requireAppId(state);\n            const appName = _getAppNameOrDefault(state);\n            const hasTables = getHasTables(state);\n\n            await api.linkExistingMapping(appId, mappingId);\n            const mapping = await tableApi.getTableMapping(\n                appId,\n                mappingId,\n                _getDBAppSchema(state),\n                getTableIdHints(state)\n            );\n\n            log.debug(\"linked table mapping:\", mapping);\n\n            updateDBAppState(updateState, (app) => {\n                const { tableMappings } = app;\n                const accessibleTableMappings = app.accessibleTableMappings ?? (app.accessibleTableMappings = []);\n                tableMappings.push(mapping);\n                sortMappings(tableMappings);\n\n                const linkedAccessMapping = accessibleTableMappings.find((m) => m.table_mapping_id === mappingId);\n                if (linkedAccessMapping) {\n                    linkedAccessMapping.apps[appId] = appName;\n                }\n                const mappingInAccess = accessibleTableMappings.find(\n                    (m) => m.table_mapping_id === mappingId && Object.keys(m.apps || {}).includes(appId)\n                );\n                if (mappingInAccess) {\n                    mappingInAccess.apps[appId] = appName;\n                }\n            });\n\n            dispatch(claimAchievement(\"addedExistingDatabase\"));\n\n            if (!hasTables && mapping.tables.length > 0) {\n                const spec = getServiceSpecs(state)[\"/runtime/services/tables.yml\"];\n                await dispatch(applyCodePreludeEverywhere(spec?.prelude, { sourceName: \"Data Tables service\" }));\n            }\n\n            return mapping;\n        } catch (e) {\n            return { error: e };\n        } finally {\n            markSaved();\n        }\n    };\n\nexport const createTableMapping =\n    (name: string, deploymentPoolId: string | null = null): AnvilAsyncAction<TableMapping> =>\n    async (dispatch, getState, updateState) => {\n        const saved = dispatch(markUnsaved(`create-mapping-${name}`));\n        try {\n            const state = getState();\n            const appId = requireAppId(state);\n            const appName = _getAppNameOrDefault(state);\n            const appSchema = _getDBAppSchema(state);\n            const split = getCreateSplitTables(state);\n            const newMapping = await api.createTableMapping(appId, name, appSchema, split, deploymentPoolId);\n\n            log.debug(\"Created table mapping:\", newMapping);\n\n            updateDBAppState(updateState, (app) => {\n                const { tableMappings, accessibleTableMappings } = app;\n                tableMappings.push(newMapping);\n                sortMappings(tableMappings);\n\n                if (accessibleTableMappings) {\n                    accessibleTableMappings.push({\n                        table_mapping_id: newMapping.table_mapping_id,\n                        name: newMapping.name,\n                        tables:\n                            newMapping.tables?.map((t: Table) => {\n                                return { id: t.id, name: t.name, python_name: t.python_name };\n                            }) || [],\n                        apps: { [appId]: appName },\n                    });\n                } else {\n                    console.warn(\"Could not update accessibleTableMappings because it was not loaded yet\");\n                }\n            });\n\n            dispatch(claimAchievement(\"addedDatabase\")); // No await\n\n            return newMapping;\n        } finally {\n            saved();\n        }\n    };\n\nexport const renameTableMapping =\n    (mapping: TableMapping, name: string): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        log.debug(\"Renaming table mapping\", mapping, name);\n        const saved = dispatch(markUnsaved(`rename-mapping-${mapping.table_mapping_id}`));\n        try {\n            const appId = requireAppId(getState());\n            await api.renameTableMapping(appId, mapping, name);\n\n            updateState((state) => {\n                if (!state.app) return;\n                const { tableMappings, accessibleTableMappings } = state.app;\n                const { editor } = state;\n                const m = tableMappings.find(({ table_mapping_id }) => mapping.table_mapping_id === table_mapping_id);\n                if (m) {\n                    m.name = name;\n                }\n\n                // For some reason, immer won't let us modify multiple elements of a nested array (!), so do this the boring way.\n                const dts = cloneDeep(editor.dataTables || {});\n                for (const [_appId, { tables }] of Object.entries(dts.tables || {}) as Array<\n                    [string, { tables?: DataTableCacheEntry[] }]\n                >) {\n                    for (const t of tables || []) {\n                        if (t.access?.table_mapping_id === mapping.table_mapping_id) {\n                            t.access.table_mapping_name = name;\n                        }\n                    }\n                }\n                editor.dataTables = dts;\n\n                const mappingInAccess = accessibleTableMappings?.find(\n                    (m) => m.table_mapping_id === mapping.table_mapping_id && Object.keys(m.apps || {}).includes(appId)\n                );\n                if (mappingInAccess) {\n                    mappingInAccess.name = name;\n                }\n            });\n            dispatch(autocompleter.invalidateTableSchema(mapping.table_mapping_id));\n        } finally {\n            saved();\n        }\n    };\n\nexport const setTableMappingRestricted =\n    (mapping: TableMapping, restricted: boolean): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const saved = dispatch(markUnsaved(`restrict-mapping-${mapping.table_mapping_id}`));\n        try {\n            const appId = requireAppId(getState());\n            await tableApi.setTableMappingRestricted(appId, mapping, restricted);\n            updateDBAppState(updateState, (app) => {\n                const updatedMapping = app.tableMappings.find(\n                    ({ table_mapping_id }) => table_mapping_id === mapping.table_mapping_id\n                );\n                if (updatedMapping) {\n                    updatedMapping.restricted = restricted;\n                }\n                const accessibleMapping = app.accessibleTableMappings?.find(\n                    ({ table_mapping_id }) => table_mapping_id === mapping.table_mapping_id\n                );\n                if (accessibleMapping) {\n                    accessibleMapping.restricted = restricted;\n                }\n            });\n        } finally {\n            saved();\n        }\n    };\n\nexport const deleteTableMapping =\n    (mapping: TableMapping): AnvilAsyncAction<{ error: unknown } | { success: true }> =>\n    async (dispatch, getState, updateState) => {\n        log.debug(\"Deleting table mapping:\", mapping);\n        const saved = dispatch(markUnsaved(`delete-mapping-${mapping.table_mapping_id}`));\n        try {\n            const state = getState();\n            const appId = requireAppId(state);\n            const { error } = await api.deleteTableMapping(appId, mapping.table_mapping_id);\n\n            if (error) {\n                return { error: error };\n            } else {\n                updateDBAppState(updateState, (app) => {\n                    const { tableMappings, accessibleTableMappings } = app;\n                    if (accessibleTableMappings) {\n                        remove(accessibleTableMappings, (m) => m.table_mapping_id === mapping.table_mapping_id);\n                    }\n                    remove(tableMappings, (m) => m.table_mapping_id === mapping.table_mapping_id);\n\n                    // TODO: Close open tabs of all tables in this mapping\n                });\n\n                if (!getHasTables(getState())) {\n                    const spec = getServiceSpecs(state)[\"/runtime/services/tables.yml\"];\n                    await dispatch(\n                        applyCodePreludeEverywhere(spec?.prelude, {\n                            sourceName: \"Data Tables service\",\n                            remove: true,\n                        })\n                    );\n                }\n\n                return { success: true };\n            }\n        } finally {\n            saved();\n        }\n    };\n\nexport const removeTableMapping =\n    (mapping: TableMapping): AnvilAsyncAction<{ error: unknown } | { success: true }> =>\n    async (dispatch, getState, updateState) => {\n        log.debug(\"Remove table mapping:\", mapping);\n        const saved = dispatch(markUnsaved(`remove-mapping-${mapping.table_mapping_id}`));\n        try {\n            const state = getState();\n            const appId = requireAppId(state);\n            const { error } = await api.removeTableMappingAccess(appId, mapping.table_mapping_id);\n            if (error) {\n                return { error: error };\n            } else {\n                updateDBAppState(updateState, (app) => {\n                    const { tableMappings, accessibleTableMappings } = app;\n                    if (accessibleTableMappings) {\n                        const mappingToUpdate = accessibleTableMappings.find(\n                            (m) => m.table_mapping_id === mapping.table_mapping_id\n                        );\n                        if (mappingToUpdate) {\n                            delete mappingToUpdate.apps[appId];\n                        }\n                    }\n                    remove(tableMappings, (m) => m.table_mapping_id === mapping.table_mapping_id);\n\n                    // TODO: Close open tabs of all tables in this mapping\n                });\n\n                if (!getHasTables(getState())) {\n                    const spec = getServiceSpecs(state)[\"/runtime/services/tables.yml\"];\n                    await dispatch(\n                        applyCodePreludeEverywhere(spec?.prelude, {\n                            sourceName: \"Data Tables service\",\n                            remove: true,\n                        })\n                    );\n                }\n\n                return { success: true };\n            }\n        } finally {\n            saved();\n        }\n    };\n\nexport const reloadTableMapping =\n    (mappingId: TableMappingId): AnvilAsyncAction<TableMapping> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = requireAppId(state);\n        const mapping = await tableApi.getTableMapping(\n            appId,\n            mappingId,\n            _getDBAppSchema(state),\n            getTableIdHints(state)\n        );\n\n        updateDBAppState(updateState, (app, currentState) => {\n            if (getAppId(currentState) !== appId) return;\n            const toUpdate = findMapping(app.tableMappings, mappingId);\n            if (toUpdate) {\n                Object.assign(toUpdate, mapping);\n            } else {\n                app.tableMappings.push(mapping);\n            }\n        });\n\n        return mapping;\n    };\n\nexport const updateTableMappingSchema =\n    (mapping: TableMapping, requiredChanges: TableMapping[\"diff\"]): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const saved = dispatch(markUnsaved(`update-mapping-schema-${mapping.table_mapping_id}`));\n        const state = getState();\n        const appId = requireAppId(state);\n        const split = getCreateSplitTables(state);\n        try {\n            const updatedMapping = await tableApi.applySchemaDiff(\n                appId,\n                mapping.table_mapping_id,\n                requiredChanges,\n                split\n            );\n\n            updateDBAppState(updateState, (app) => {\n                const target = findMapping(app.tableMappings, mapping.table_mapping_id);\n                if (!target) {\n                    console.warn(\"Tried to update missing table mapping\", mapping.table_mapping_id);\n                    return;\n                }\n                Object.assign(target, updatedMapping);\n            });\n\n            dispatch(claimAchievement(\"resolvedSchemaMismatch\"));\n        } finally {\n            saved();\n        }\n    };\n\nexport const maybeMigrateAppOrDB =\n    (tableMapping: TableMapping): AnvilAsyncAction<boolean> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appSchema = _getDBAppSchema(state);\n        const appId = requireAppId(state);\n        console.log(\"App schema:\", appSchema);\n        console.log(`DB schema '${tableMapping?.name}':`, tableMapping.schema);\n\n        // We have to get the full diff to determine whether there are any changes. Simple equality won't do,\n        // because things like column order need special treatment\n        const latestTableMapping = await tableApi.getTableMapping(\n            appId,\n            tableMapping.table_mapping_id,\n            appSchema,\n            getTableIdHints(state)\n        );\n        const requiredChanges = latestTableMapping.diff;\n\n        if (requiredChanges.length === 0) {\n            // If there are no required changes, but there are some differences (like column order), update app schema to match DB, just to keep things in sync.\n            if (!isEqual(appSchema, tableMapping.schema)) {\n                dispatch(updateAppDBSchema(tableMapping.schema));\n            }\n            return true;\n        } else {\n            const resp = (await dispatch(\n                modal(\"schemaMismatch\", {\n                    requiredChanges,\n                    tableMapping,\n                })\n            )) as string | null;\n\n            switch (resp) {\n                case \"update-yaml\":\n                    // Modify the app YAML to match the DB.\n                    dispatch(updateAppDBSchema(tableMapping.schema));\n                    await dispatch(updateAppSchemaSync());\n                    return true;\n\n                case \"update-db\":\n                    // Auto-migrate the DB to match the app YAML\n                    await dispatch(updateTableMappingSchema(tableMapping, requiredChanges));\n                    await dispatch(updateAppSchemaSync());\n                    return true;\n\n                case \"manual-fix\":\n                    // Switch DB, but don't modify the app YAML\n                    return true;\n\n                default:\n                    // User cancelled mismatch modal. Don't change DB.\n                    return false;\n            }\n        }\n    };\n\nexport const getRequiredSchemaDiffs =\n    (tableMapping: TableMapping): AnvilAsyncAction<Diff[]> =>\n    async (dispatch, getState, updateState) => {\n        // TODO: Probably want to reload this now.\n        return tableMapping.diff;\n        // let state = getState();\n        // let appSchema = getAppDBSchema(state);\n        // let appId = getAppId(state);\n        // let requiredChanges = await tableApi.getSchemaDiff(appId, tableMapping.table_mapping_id, appSchema, getTableIdHints(state));\n        // return requiredChanges;\n    };\n\nexport const getDebugEnvironmentTableMapping = createSelector(\n    [(state: State) => getCategorisedEnvironments(state), (state: State) => getTableMappings(state)],\n    ({ debug }, tableMappings) => (tableMappings || []).find((m) => m.table_mapping_id === debug.table_mapping_id)\n);\n\nexport const getDebugEnvironmentTableMappingId = createSelector(\n    [(state: State) => getCategorisedEnvironments(state)],\n    ({ debug }) => debug?.table_mapping_id ?? null\n);\n\nexport const getDebugEnvironmentTables = createSelector(\n    [(state) => getDebugEnvironmentTableMapping(state)],\n    (mapping) => mapping?.tables || []\n);\n\nexport const getTableIdHints = (state: State) => _getDBConfig(state).table_id_hints;\n\nexport const loadAppAccessibleTableMappings =\n    (appId: AppId, abort?: AbortController): AnvilAsyncAction<AccessibleTableMapping[]> =>\n    async (dispatch, getState, updateState) => {\n        try {\n            const accessibleTableMappings = (await api.getAppAccessibleTableMappings(appId, abort)).filter(\n                (m: AccessibleTableMapping & { ephemeral?: boolean }) => !m.ephemeral\n            );\n            updateDBAppState(updateState, (app) => {\n                app.accessibleTableMappings = accessibleTableMappings;\n            });\n            return accessibleTableMappings;\n        } catch (e: any) {\n            dispatch(alert(\"Error\", `Could not load accessible databases: ${e.error}`));\n            return [];\n        }\n    };\n\nexport const getAppAccessibleTableMappings = (state: State) => state.app?.accessibleTableMappings;\n\nexport const getSharedTableCounts = createSelector([getAppAccessibleTableMappings], (accessibleTableMappings) => {\n    const tableCounts: Record<Table[\"id\"], number> = {};\n    accessibleTableMappings?.forEach(({ tables }) => {\n        tables.forEach(({ id }) => {\n            tableCounts[id] = (tableCounts[id] ?? 0) + 1;\n        });\n    });\n    return tableCounts;\n});\n\nexport const getTablesInUnrestrictedMappings = createSelector([getAppAccessibleTableMappings], (mappings) => {\n    return new Set(mappings?.filter((mapping) => !mapping.restricted).flatMap(({ tables }) => tables.map(({ id }) => id)));\n});\n\nexport const ingestOldIDESchemaUpdate = (...[tableId, updateType, data]: OldIDESchemaUpdateArgs): AnvilAction =>\n    withTableOp(async (dispatch, getState, updateState) => {\n        const state = getState();\n        if (!data) {\n            // Reordering columns produces no data and has no effect on the schema anyway\n            return;\n        }\n        const tableMappingId = data.tableMappingId != null ? parseInt(String(data.tableMappingId), 10) : null;\n        const debugEnv = getDebugEnvironmentTableMapping(state);\n        const isDebugInSync = diffHasOnlyIndexChanges(debugEnv);\n\n        const appMappings = getAllTableMappings(state) ?? [];\n        const currentTables = appMappings.find((m) => m.table_mapping_id === tableMappingId)?.tables;\n        const tableInMapping = currentTables?.find((t) => t.id === tableId);\n        const tablePythonName = tableInMapping?.python_name;\n\n        let touchedDebugDB = false;\n        let colId: string | number | undefined;\n\n        switch (updateType) {\n            case \"addCol\":\n                console.log(\"Add column\", tableId, data);\n                colId = data.colId;\n                const colItem = {\n                    name: data.name,\n                    admin_ui: data.admin_ui,\n                    type: \"string\",\n                } as SchemaColumnSpec;\n                switch (data.type) {\n                    case \"liveObject\":\n                        colItem.type = \"link_single\";\n                        (colItem as LinkColumn).target = currentTables?.find((t) => t.id === data.targetTableId)\n                            ?.python_name as string;\n                        break;\n                    case \"liveObjectArray\":\n                        colItem.type = \"link_multiple\";\n                        (colItem as LinkColumn).target = currentTables?.find((t) => t.id === data.targetTableId)\n                            ?.python_name as string;\n                        break;\n                    default:\n                        colItem.type = data.type as SchemaColumnSpec[\"type\"];\n                        break;\n                }\n\n                updateDBAppState(updateState, (app) => {\n                    const db_schema = (app.config.db_schema ??= {});\n                    app.tableMappings.forEach((mapping) => {\n                        const table = mapping.tables?.find((t) => t.id === tableId);\n                        const mappingTableSchema = tablePythonName\n                            ? getTableSchema(mapping.schema, tablePythonName)\n                            : undefined;\n                        if (table && colId != null && mappingTableSchema) {\n                            if (debugEnv?.table_mapping_id === mapping.table_mapping_id) {\n                                touchedDebugDB = true;\n                            }\n\n                            table.columns[colId] = colItem as ColumnSpec;\n                            mappingTableSchema.columns.push(colItem as SchemaColumnSpec);\n                        }\n                    });\n\n                    const debugTableSchema = tablePythonName ? getTableSchema(db_schema, tablePythonName) : undefined;\n                    if (isDebugInSync && touchedDebugDB && debugTableSchema) {\n                        debugTableSchema.columns.push(colItem);\n                    }\n                });\n                break;\n            case \"deleteCols\":\n                console.log(\"Delete column\", tableId, data);\n                const { colIds } = data;\n                const toRemove: Record<string, number> = {};\n                const makeKey = ({ name, type }: { name: string; type: string }) => `${name}|${type}`;\n                const schemas = (colIds || []).map((colId: string) => tableInMapping?.columns?.[colId]).filter(Boolean);\n                schemas.forEach((schema: ColumnSpec) => {\n                    const key = makeKey(schema);\n                    toRemove[key] = (toRemove[key] ?? 0) + 1;\n                });\n\n                // account for duplicate name/type\n                const filterSchemas = (schemas: SchemaColumnSpec[]) => {\n                    const removeCount: Record<string, number> = {};\n                    const rv: SchemaColumnSpec[] = [];\n                    for (const schema of schemas) {\n                        const key = makeKey(schema);\n                        if (!(key in toRemove)) {\n                            rv.push(schema);\n                            continue;\n                        }\n                        removeCount[key] = (removeCount[key] ?? 0) + 1;\n                        if (removeCount[key] > toRemove[key]) {\n                            rv.push(schema);\n                        }\n                    }\n                    return rv;\n                };\n\n                updateDBAppState(updateState, (app) => {\n                    const db_schema = (app.config.db_schema ??= {});\n                    app.tableMappings.forEach((mapping) => {\n                        const table = mapping.tables?.find((t) => t.id === tableId);\n                        const mappingTableSchema = tablePythonName\n                            ? getTableSchema(mapping.schema, tablePythonName)\n                            : undefined;\n                        if (table && mappingTableSchema) {\n                            //this part only updates the state of the table in the mappings and the schema\n                            if (debugEnv?.table_mapping_id === mapping.table_mapping_id) {\n                                touchedDebugDB = true;\n                            }\n\n                            for (const colId of colIds || []) {\n                                delete table.columns[colId];\n                            }\n\n                            mappingTableSchema.columns = filterSchemas(mappingTableSchema.columns);\n                        }\n                    });\n\n                    const debugTableSchema = tablePythonName ? getTableSchema(db_schema, tablePythonName) : undefined;\n                    if (isDebugInSync && touchedDebugDB && debugTableSchema) {\n                        debugTableSchema.columns = filterSchemas(debugTableSchema.columns);\n                    }\n                });\n                break;\n            case \"renameCol\":\n                console.log(\"Rename column\", tableId, data);\n                colId = data.colId;\n                const newColName = data.newName;\n                let oldName = \"\";\n                let type = \"\";\n                let schemaType = \"\";\n\n                updateDBAppState(updateState, (app) => {\n                    const db_schema = (app.config.db_schema ??= {});\n                    app.tableMappings.forEach((mapping) => {\n                        const table = mapping.tables?.find((t) => t.id === tableId);\n                        const mappingTableSchema = tablePythonName\n                            ? getTableSchema(mapping.schema, tablePythonName)\n                            : undefined;\n                        if (table && colId != null && mappingTableSchema && table.columns[colId]) {\n                            if (debugEnv?.table_mapping_id === mapping.table_mapping_id) {\n                                touchedDebugDB = true;\n                            }\n                            oldName = table.columns[colId].name;\n                            type = table.columns[colId].type;\n                            table.columns[colId].name = newColName;\n                            schemaType = type;\n                            if (type === \"liveObject\") {\n                                schemaType = \"link_single\";\n                            } else if (type === \"liveObjectArray\") {\n                                schemaType = \"link_multiple\";\n                            }\n                            const col = mappingTableSchema.columns.find(\n                                (c) => c.name === oldName && c.type === schemaType\n                            );\n                            if (col) {\n                                col.name = newColName;\n                            }\n                        }\n                    });\n\n                    const debugTableSchema = tablePythonName ? getTableSchema(db_schema, tablePythonName) : undefined;\n                    if (isDebugInSync && touchedDebugDB && debugTableSchema) {\n                        const col = debugTableSchema.columns.find((c) => c.name === oldName && c.type === schemaType);\n                        if (col) {\n                            col.name = newColName;\n                        }\n                    }\n                });\n                break;\n            case \"updateAccess\":\n                console.log(\"Update table access\", tableId, data);\n                const server = data.server;\n                const client = data.client;\n                const newPythonName = data.python_name;\n\n                updateDBAppState(updateState, (app) => {\n                    const db_schema = (app.config.db_schema ??= {});\n                    app.tableMappings.forEach((mapping) => {\n                        const table = mapping.tables?.find((t) => t.id === tableId);\n                        const mappingTableSchema = tablePythonName\n                            ? getTableSchema(mapping.schema, tablePythonName)\n                            : undefined;\n                        if (table && mappingTableSchema) {\n                            if (debugEnv?.table_mapping_id === mapping.table_mapping_id) {\n                                touchedDebugDB = true;\n                            }\n\n                            table.server = server;\n                            table.client = client;\n\n                            mappingTableSchema.server = server;\n                            mappingTableSchema.client = client;\n                            if (tablePythonName !== newPythonName) {\n                                const newPythonNameKey = newPythonName as string;\n                                const tablePythonNameKey = tablePythonName as string;\n                                mapping.schema[newPythonNameKey] = mappingTableSchema;\n                                delete mapping.schema[tablePythonNameKey];\n                            }\n                        }\n                    });\n\n                    const debugTableSchema = tablePythonName ? getTableSchema(db_schema, tablePythonName) : undefined;\n                    if (isDebugInSync && touchedDebugDB && debugTableSchema) {\n                        debugTableSchema.server = server;\n                        debugTableSchema.client = client;\n                        if (tablePythonName !== newPythonName) {\n                            const newPythonNameKey = newPythonName as string;\n                            const tablePythonNameKey = tablePythonName as string;\n                            db_schema[newPythonNameKey] = debugTableSchema;\n                            delete db_schema[tablePythonNameKey];\n\n                            for (const tableSchema of Object.values(db_schema)) {\n                                for (const col of tableSchema.columns) {\n                                    if (isLinkedCol(col) && col.target === tablePythonName) {\n                                        col.target = newPythonName as string;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                });\n                break;\n            default:\n                break;\n        }\n\n        if (isDebugInSync && touchedDebugDB) {\n            dispatch(markAppPathUnsaved([\"SETTINGS\", \"db_schema\"]));\n        }\n\n        await dispatch(notifySchemaUpdate());\n    });\n\nexport const cloneDatabaseToPool =\n    (tableMappingId: TableMappingId, withoutMedia: boolean, deploymentPoolId: string | null): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const saved = dispatch(markUnsaved(`clone-mapping-${tableMappingId}`));\n        try {\n            const state = getState();\n            const appId = requireAppId(state);\n            const split = getCreateSplitTables(state); // TODO: We may allow overriding split true/false with a tri-state argument to cloneDatabaseToPool.\n            const newMapping = await tableApi.cloneDatabase(\n                appId,\n                tableMappingId,\n                withoutMedia,\n                deploymentPoolId,\n                split\n            );\n            await dispatch(reloadAppTableMappings()); //doing this b/c the newMapping you get back from the api call isn't actually in the right structure for the tableMappings in the state\n\n            const appName = _getAppNameOrDefault(getState());\n            updateDBAppState(updateState, (app) => {\n                const { accessibleTableMappings } = app;\n                if (accessibleTableMappings) {\n                    accessibleTableMappings.push({\n                        table_mapping_id: newMapping.table_mapping_id,\n                        name: newMapping.name,\n                        tables:\n                            newMapping.tables?.map((t: Table) => {\n                                return { id: t.id, name: t.name, python_name: t.python_name };\n                            }) || [],\n                        apps: { [appId]: appName },\n                    });\n                } else {\n                    console.warn(\"Could not update accessibleTableMappings because it was not loaded yet\");\n                }\n            });\n        } finally {\n            saved();\n        }\n    };\n\nexport const restoreDatabaseToPool =\n    (\n        tableMappingId: TableMappingId,\n        withoutMedia: boolean,\n        deploymentPoolId: string | null,\n        targetTime: string | null\n    ): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const saved = dispatch(markUnsaved(`restore-mapping-${tableMappingId}`));\n        try {\n            const state = getState();\n            const appId = requireAppId(state);\n            const { newMapping, task } = await tableApi.restoreDatabase(\n                appId,\n                tableMappingId,\n                withoutMedia,\n                deploymentPoolId,\n                targetTime ?? \"\"\n            );\n            dispatch(addTaskIfMissing(task));\n            await dispatch(reloadAppTableMappings()); //doing this b/c the newMapping you get back from the api call isn't actually in the right structure for the tableMappings in the state\n\n            const appName = _getAppNameOrDefault(getState());\n            updateDBAppState(updateState, (app) => {\n                const { accessibleTableMappings } = app;\n                if (accessibleTableMappings) {\n                    accessibleTableMappings.push({\n                        table_mapping_id: newMapping.table_mapping_id,\n                        name: newMapping.name,\n                        tables: [],\n                        apps: { [appId]: appName },\n                    });\n                } else {\n                    console.warn(\"Could not update accessibleTableMappings because it was not loaded yet\");\n                }\n            });\n        } finally {\n            saved();\n        }\n    };\n\nexport const supportsIndexing = (features: FeatureMap | null | undefined, table: Table) =>\n    featureSupported(features, \"db-indexes\") || !!(table?.split && featureSupported(features, \"db-indexes-split\"));\n\nexport const tableIndexIdentifier = (i: TableIndex) => `${i.type}:${i.columns.join(\"|\")}`;\n\ninterface TableIndexChanges {\n    toAdd: TableIndex[];\n    toRemove: TableIndex[];\n}\nexport const openTableIndexesModal =\n    (tableMappingId: TableMappingId | undefined, table: Table): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const tableId = table.id;\n        const updates: TableIndexChanges = await dispatch(modal(\"tableIndexes\", { table }));\n        if (updates) {\n            try {\n                const { toAdd, toRemove } = updates;\n                dispatch(updateGlobalLoadingIndicator(true));\n\n                for (const removedIndex of toRemove) {\n                    await dispatch(modifyIndex(tableMappingId, tableId, removedIndex, \"delete\"));\n                }\n                for (const newIndex of toAdd) {\n                    await dispatch(modifyIndex(tableMappingId, tableId, newIndex, \"create\"));\n                }\n            } catch (e) {\n                dispatch(alert(\"Error\", \"Unable to save changes\"));\n                console.error(e);\n            } finally {\n                dispatch(updateGlobalLoadingIndicator(false));\n            }\n        }\n    };\n","import { mergeWith } from \"lodash-es\";\nimport { updateUiPrefs } from \"@/api\";\nimport { modifyTableIndex, saveTableCol } from \"@/api/tables\";\nimport { invalidateTableSchema } from \"@/controllers/app/autocompleter\";\nimport { getTablesService } from \"@/controllers/services\";\nimport { AnvilAction, State } from \"@/types\";\nimport {\n    ColType,\n    ColumnSpec,\n    LiveObjectColumn,\n    SchemaColumnSpec,\n    Table,\n    TableId,\n    TableIndex,\n    TableMapping,\n    TableMappingId,\n} from \"@/types/database\";\nimport { getAppId, markAppPathUnsaved, markUnsaved } from \"./app\";\nimport { diffHasOnlyIndexChanges, getDebugEnvironmentTableMappingId, withTableOp } from \"./db\";\n\ntype DeepPartial<T> = T extends object\n    ? {\n          [P in keyof T]?: DeepPartial<T[P]>;\n      }\n    : T;\n\nconst customArrayMerge = (objValue: any, srcValue: any) => {\n    if (Array.isArray(objValue)) {\n        return srcValue ?? [];\n    }\n};\n\nexport const colSpecToColSchema = (colSpec: ColumnSpec, tableMapping: TableMapping): SchemaColumnSpec => {\n    let schemaType: SchemaColumnSpec[\"type\"];\n    const type = colSpec.type;\n    if (type === \"liveObject\") {\n        schemaType = \"link_single\";\n    } else if (type === \"liveObjectArray\") {\n        schemaType = \"link_multiple\";\n    } else {\n        schemaType = type;\n    }\n    if (schemaType === \"link_single\" || schemaType === \"link_multiple\") {\n        const table_id = (colSpec as LiveObjectColumn).table_id;\n        const targetTable = tableMapping.tables.find((t) => t.id === table_id);\n        const target = targetTable!.python_name;\n        return {\n            name: colSpec.name,\n            admin_ui: colSpec.admin_ui,\n            type: schemaType,\n            target,\n            client_hidden: colSpec.client_hidden ?? false,\n            ...(schemaType === \"link_single\" && colSpec.type === \"liveObject\" && 'on_delete' in colSpec ? {on_delete: colSpec.on_delete}: {})\n        };\n    } else {\n        return {\n            name: colSpec.name,\n            admin_ui: colSpec.admin_ui,\n            type: schemaType,\n            client_hidden: colSpec.client_hidden ?? false,\n        };\n    }\n};\n\nconst rawIndexesToAppSchemaIndexes = (table: Table, allIndexes: TableIndex[]) => {\n    // Same logic as in yaml-schema-from-table-mapping-description\n    const indexes: TableIndex[] = [];\n    for (const index of allIndexes) {\n        const { type, columns } = index;\n        indexes.push({ type, columns: columns.map((colId) => table.columns[colId].name) });\n    }\n    return indexes;\n};\n\nexport const modifyIndex = (\n    tableMappingId: TableMappingId | undefined,\n    tableId: TableId,\n    index: TableIndex,\n    action: \"create\" | \"delete\"\n): AnvilAction =>\n    withTableOp(async (dispatch, getState, updateState) => {\n        const onSave = dispatch(markUnsaved(\"index-create\"));\n        try {\n            const state = getState();\n            const appId = getAppId(state)!;\n            const updatedIndexes = await modifyTableIndex(appId, tableMappingId, tableId, index, action);\n\n            const isCurrentMapping = tableMappingId === getDebugEnvironmentTableMappingId(state);\n\n            updateState(({ app }) => {\n                if (!app) return;\n                const tableMapping = app.tableMappings.find(\n                    ({ table_mapping_id }) => table_mapping_id === tableMappingId\n                );\n                const table = tableMapping?.tables.find(({ id }) => id === tableId);\n                if (!table) return;\n\n                table.all_indexes = updatedIndexes;\n                const currentlyInSync = tableMapping!.diff.length === 0;\n\n                if (currentlyInSync && isCurrentMapping) {\n                    const tableSchema = app.config.db_schema[table.python_name];\n                    tableSchema.indexes = rawIndexesToAppSchemaIndexes(table, updatedIndexes);\n                }\n            });\n        } finally {\n            onSave();\n        }\n    });\n\nexport const updateCol = (\n    tableMappingId: TableMappingId,\n    tableId: TableId,\n    colId: string,\n    colDef: DeepPartial<ColumnSpec>\n): AnvilAction =>\n    withTableOp(async (dispatch, getState, updateState) => {\n        const onSave = dispatch(markUnsaved(\"col-update-\" + colId));\n        try {\n            const state = getState();\n            const isCurrentMapping = tableMappingId === getDebugEnvironmentTableMappingId(state);\n            const appId = getAppId(state);\n            const app = state.app;\n            if (!app || !appId) return;\n            const tableMappings = app.tableMappings;\n            const tableMapping = tableMappings.find(({ table_mapping_id }) => table_mapping_id === tableMappingId);\n            if (!tableMapping) return;\n            const table = tableMapping.tables.find(({ id }) => id === tableId);\n            const columns = table?.columns;\n            if (!columns) return;\n            const { name: originalName } = columns[colId];\n            const update = mergeWith({}, columns[colId], colDef, customArrayMerge);\n            const updateSpecFromServer = (await saveTableCol(\n                appId,\n                tableMappingId,\n                tableId,\n                colId,\n                update\n            )) as ColumnSpec;\n\n            let didSchemaUpdate = false;\n            updateState(({ app }) => {\n                if (!app) return;\n                const tableMappings = app.tableMappings;\n                const config = app.config;\n\n                const tableMapping = tableMappings.find(({ table_mapping_id }) => table_mapping_id === tableMappingId);\n                if (!tableMapping) return;\n                const table = tableMapping?.tables.find(({ id }) => id === tableId);\n                if (!table) return;\n                const pythonName = table?.python_name;\n                const columns = table?.columns;\n                if (!columns) return;\n                columns[colId] = updateSpecFromServer;\n                const updatedSchema = colSpecToColSchema(updateSpecFromServer, tableMapping);\n                const { type: schemaType } = updatedSchema;\n                const tableSchema = tableMapping.schema[pythonName];\n                const schemaColumns = tableSchema.columns;\n                const schemaIdx = schemaColumns.findIndex((c) => c.name === originalName && c.type === schemaType);\n                if (schemaIdx >= 0) {\n                    schemaColumns[schemaIdx] = updatedSchema;\n                    tableSchema.indexes = rawIndexesToAppSchemaIndexes(table, table.all_indexes);\n                }\n\n                if (diffHasOnlyIndexChanges(tableMapping) && isCurrentMapping) {\n                    const tableSchema = config.db_schema[table.python_name];\n                    const columns = tableSchema.columns;\n                    if (!columns) return;\n                    const columnIndex = columns.findIndex((c) => c.name === originalName && c.type === schemaType);\n                    if (columnIndex >= 0) {\n                        didSchemaUpdate = true;\n                        columns[columnIndex] = updatedSchema;\n                        tableSchema.indexes = rawIndexesToAppSchemaIndexes(table, table.all_indexes);\n                    }\n                }\n            });\n            if (didSchemaUpdate) {\n                dispatch(markAppPathUnsaved([\"SETTINGS\", \"db_schema\"]));\n            }\n            if (isCurrentMapping) {\n                dispatch(invalidateTableSchema(tableMappingId));\n            }\n        } finally {\n            onSave();\n        }\n    });\n\nexport type SortArray = { colId: string; ascending: boolean }[];\n\nconst EMPTY_SORT: SortArray = [];\n\nexport const getSort = (state: State, id: TableId) => state.user?.uiPrefs.tables?.[id]?.sort ?? EMPTY_SORT;\n\nconst sortable = [\"number\", \"string\", \"bool\", \"date\", \"datetime\"];\nexport const canSort = (type: ColType) => sortable.includes(type);\n\nexport const updateSort =\n    (tableMappingId: TableMappingId, tableId: TableId, sortArray: SortArray): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const state = getState();\n        const app = state.app;\n        if (!app) return;\n        const tableMappings = app.tableMappings;\n        const tableMapping = tableMappings.find(({ table_mapping_id }) => table_mapping_id === tableMappingId);\n        const table = tableMapping?.tables.find(({ id }) => id === tableId);\n        const validCols = Object.keys(table?.columns ?? {});\n        const seen: string[] = [];\n        const cleanedSortedArray = sortArray.filter(({ colId }) => {\n            if (seen.includes(colId)) return false;\n            if (!validCols.includes(colId)) return false;\n            const type = table?.columns[colId].type;\n            if (!type || !canSort(type)) return false;\n            seen.push(colId);\n            return true;\n        });\n        updateState((state) => {\n            const tables = (state.user.uiPrefs.tables ??= {});\n            tables[tableId] ??= {};\n            tables[tableId].sort = cleanedSortedArray;\n        });\n        updateUiPrefs([\"tables\", tableId, \"sort\"], cleanedSortedArray);\n    };\n\nexport interface HiddenColumns {\n    [colId: string]: boolean;\n}\n\nconst EMPTY: HiddenColumns = {};\n\nexport const getHiddenColumns = (state: State, id: TableId) => state.user?.uiPrefs.tables?.[id]?.hidden ?? EMPTY;\n\nexport const updateHiddenColumns =\n    (tableMappingId: TableMappingId, tableId: TableId, hidden: HiddenColumns): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const state = getState();\n        const app = state.app;\n        if (!app) return;\n        const tableMappings = app.tableMappings;\n        const tableMapping = tableMappings.find(({ table_mapping_id }) => table_mapping_id === tableMappingId);\n        const table = tableMapping?.tables.find(({ id }) => id === tableId);\n        const validCols = Object.keys(table?.columns ?? {});\n        const seen: string[] = [];\n        const realHiddenColumns: HiddenColumns = {};\n        for (const colId in hidden) {\n            const value = hidden[colId];\n            if (value) continue;\n            if (validCols.includes(colId)) {\n                realHiddenColumns[colId] = false;\n            }\n        }\n        updateState((state) => {\n            const tables = (state.user.uiPrefs.tables ??= {});\n            tables[tableId] ??= {};\n            tables[tableId].hidden = realHiddenColumns;\n        });\n        updateUiPrefs([\"tables\", tableId, \"hidden\"], realHiddenColumns);\n    };\n\nexport const getCreateSplitTables = (state: State) => {\n    const { enable_v2, enable_split } = getTablesService(state)?.client_config || {};\n    return !!(enable_v2 && enable_split);\n};\n","import { useDispatch, useSelector } from \"react-redux\";\nimport {\n    Debugger,\n    DebuggerGetValueRequestPath,\n    DebuggerIdentity,\n    DebuggerRPCAction,\n    DebuggerUpdateMessage,\n    ExpandedFrameState,\n    ModuleBreakpoints,\n    StackFrame,\n} from \"@platform-runner/shared-debugger-types\";\nimport { cloneDeep } from \"lodash-es\";\nimport { createSelector } from \"reselect\";\nimport { EVENTS, raiseEvent } from \"@/actions\";\nimport type { StackFrameContextType } from \"@/components/bottom_panel/DebugInspector\";\nimport { modal } from \"@/controllers/modals\";\nimport { navigate } from \"@/router/navigation\";\nimport { AnvilAction, AnvilDispatch, AppEnvironment, AppId, CodePath, State } from \"@/types\";\nimport defer from \"@/util/defer\";\nimport { getFeatureSupport } from \"@/util/features\";\nimport { postJson } from \"@/util/fetch\";\nimport { replaceEqualDeep } from \"@/util/replace-equal-deep\";\nimport { getAppId } from \"./app\";\nimport { getCodeNames } from \"./app/code\";\nimport { closeBottomTab, openOrFocusBottomTab } from \"./bottom-tabs\";\nimport { getCategorisedEnvironments, getDebugEnvironment, setEnvironmentBreakpoints } from \"./environments\";\nimport { serverReplReturn } from \"./repl\";\nimport { restoreRunner } from \"./runner\";\nimport { WebsocketEvent, useWebsocketEventListener } from \"./websocket\";\n\n// The Anvil interactive debugger\n\n// Yes, this should probably be in api.js, but I wanted to type it properly.\n// TODO: This type doesn't _quite_ work. The request type should constrain the return value.\nconst sendServerDebugRequest = async <T extends DebuggerRPCAction>(\n    appId: AppId,\n    debugLocation: NonNullable<Debugger[\"location\"]>,\n    request: T[\"request\"]\n): Promise<T[\"response\"]> => {\n    const { reference, envId } = debugLocation;\n    return await postJson(`/ide/apps/${encodeURIComponent(appId)}/debugger/${encodeURIComponent(envId)}`, {\n        reference,\n        request,\n    });\n};\n\nexport type DebuggerEventArg = { request: DebuggerRPCAction; callback: () => void };\n\nconst sendRunnerDebugRequest = async <T extends DebuggerRPCAction>(\n    dispatch: AnvilDispatch,\n    request: T[\"request\"]\n): Promise<T[\"response\"]> => {\n    const df = defer();\n    dispatch(raiseEvent(EVENTS.RUNNER_DEBUGGER_REQUEST, { request: request, callback: df.resolve }));\n    return await df.promise;\n};\n\nconst sendRunnerDebugBroadcast = async <T extends DebuggerRPCAction>(\n    dispatch: AnvilDispatch,\n    request: T[\"request\"]\n) => {\n    dispatch(raiseEvent(EVENTS.RUNNER_DEBUGGER_REQUEST, { request: request, callback: () => {} }));\n};\n\nexport const sendDebuggerRequest =\n    (dbg: DebuggerIdentity, request: any): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        if (dbg.location) {\n            const appId = getAppId(getState())!;\n            return await sendServerDebugRequest(appId, dbg.location, request);\n        } else {\n            return await sendRunnerDebugRequest(dispatch, request);\n        }\n    };\n\nconst augmentStack = (stack: StackFrame[], codeNames: any) => {\n    for (const frame of stack) {\n        const moduleName = frame.moduleName\n            ?.substring(frame.moduleName?.indexOf(\".\") + 1)\n            .replace(/.__init__$/, \"\")\n            .replaceAll(\"/\", \".\");\n        const codePath = codeNames[moduleName]?.codePath;\n        frame.moduleName = moduleName;\n        frame.codePath = codePath;\n    }\n};\n\nexport const onDebuggerUpdate =\n    (hyperstack: DebuggerUpdateMessage): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const serverDebuggingAllowed = getFeatureSupport(state, \"full-debugger\");\n        const codeNames = getCodeNames(state);\n\n        const { debuggers, client } = hyperstack;\n        const hyperstackId = debuggers[0].debuggerId;\n\n        // Is this a client debugger for a running app?\n        const clientDebugger = client.type === \"browser\";\n\n        let innermostFrame = null;\n        let pausedDebugger = null;\n        for (const dbg of debuggers) {\n            if (\"stack\" in dbg) {\n                augmentStack(dbg.stack, codeNames);\n                for (const frame of dbg.stack) {\n                    innermostFrame = frame;\n                }\n            } else {\n                // This is just a DebuggerIdentity without a stack.\n            }\n            if (\"state\" in dbg && dbg.state === \"PAUSED\") {\n                pausedDebugger = dbg;\n            }\n        }\n\n        if (pausedDebugger && pausedDebugger.type !== \"browser\" && !serverDebuggingAllowed) {\n            dispatch(sendDebuggerRequest(pausedDebugger, { action: \"CONTINUE\" }));\n            if (!state.debug.alreadyPromptedForFullDebuggerUpgrade) {\n                updateState(({ debug }) => {\n                    debug.alreadyPromptedForFullDebuggerUpgrade = true;\n                });\n                dispatch(\n                    modal(\"upgradePrompt\", {\n                        featureId: \"full-debugger\",\n                        additionalIntroText: \"You just hit a breakpoint in server code!\",\n                    })\n                );\n            }\n        } else {\n            const existingHyperStack = state.debuggerHyperStacks[hyperstackId];\n            const hasExistingHyperStack = !!existingHyperStack;\n            const newHyperStack = replaceEqualDeep(existingHyperStack, hyperstack);\n\n            updateState(({ debug, debuggerHyperStacks }) => {\n                if (clientDebugger) {\n                    debug.debuggerId = hyperstackId;\n                }\n                debuggerHyperStacks[hyperstackId] = newHyperStack;\n            });\n\n            for (const dbg of debuggers) {\n                if (dbg.location) {\n                    dispatch(sendKeepalive(hyperstackId, dbg.debuggerId));\n                }\n                // TODO - we're sending this as this as a debugger update. We should probably create a separate event\n                if (\"execution_state\" in dbg && dbg.execution_state) {\n                    const { exec_id, error } = dbg.execution_state;\n                    if (typeof exec_id === \"number\") {\n                        dispatch(serverReplReturn(exec_id, error));\n                    }\n                }\n            }\n\n            if (clientDebugger) {\n                dispatch(restoreRunner());\n            }\n\n            // Don't steal focus if we're not a new debugger\n            if (!hasExistingHyperStack) {\n                dispatch(openOrFocusBottomTab({ type: \"debugger\", hyperstackId }));\n            }\n\n            // Don't navigate if we're not a new debugger\n            if (!hasExistingHyperStack && innermostFrame?.codePath) {\n                dispatch(\n                    navigate({\n                        type: \"CODE\",\n                        codePath: innermostFrame.codePath as CodePath,\n                        view: { code: [`${innermostFrame.line}`] },\n                    })\n                );\n            }\n        }\n    };\n\nexport const getDebuggerHyperStacks = (state: State) => state.debuggerHyperStacks;\n\nexport const getPausedRunnerDebugger = createSelector([getDebuggerHyperStacks], (debuggerHyperStacks) => {\n    return debuggerHyperStacks?.runner?.debuggers.find((d) => \"state\" in d && d.state === \"PAUSED\");\n});\n\nexport const getIsRunnerPaused = createSelector([getDebuggerHyperStacks], (debuggerHyperStacks) => {\n    return !!debuggerHyperStacks?.runner?.debuggers.find((d) => \"state\" in d && d.state === \"PAUSED\");\n});\n\n// Server console hyperstacks aren't keyed by a fixed id like \"runner\", so find one by replId.\n// Picks the most recent match in case more than one is paused concurrently for this repl.\nexport const getPausedServerReplHyperstackId = (state: State, replId: string): string | undefined => {\n    const debuggerHyperStacks = getDebuggerHyperStacks(state);\n    let mostRecentMatch: string | undefined;\n    for (const [hyperstackId, hyperstack] of Object.entries(debuggerHyperStacks)) {\n        if (\n            hyperstack.client.replId === replId &&\n            hyperstack.debuggers.some((d) => \"state\" in d && d.state === \"PAUSED\")\n        ) {\n            mostRecentMatch = hyperstackId;\n        }\n    }\n    return mostRecentMatch;\n};\n\nexport const debuggerContinue =\n    (hyperstackId: string, step?: \"IN\" | \"OVER\" | \"OUT\"): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const hyperStacks = getDebuggerHyperStacks(getState());\n        const dbg = hyperStacks[hyperstackId];\n        const pausedDebugger = dbg?.debuggers.find((d) => \"state\" in d && d.state === \"PAUSED\");\n\n        // Remove the debugger before continuing, otherwise we could break again before it's gone.\n        if (pausedDebugger) {\n            updateState((state) => {\n                // TODO: Only remove the debugger we're resuming. Whichever that one is.\n                delete state.debuggerHyperStacks[hyperstackId];\n            });\n            dispatch(closeBottomTab({ type: \"debugger\", hyperstackId }));\n\n            if (step) {\n                await dispatch(sendDebuggerRequest(pausedDebugger, { action: \"STEP\", direction: step }));\n            } else {\n                await dispatch(sendDebuggerRequest(pausedDebugger, { action: \"CONTINUE\" }));\n            }\n        }\n    };\n\nexport const debugExec =\n    (code: string, cmdId: number, dbg: DebuggerIdentity, expandedFrame: ExpandedFrameState | undefined): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        if (dbg) {\n            await dispatch(sendDebuggerRequest(dbg, { action: \"EXEC\", code, cmdId, expandedFrame }));\n        }\n    };\n\nconst ingestWebsocketEvent =\n    (e: WebsocketEvent): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        if (e.event === \"DEBUGGER_UPDATE\") {\n            const { app_id, env_id, ...update } = e;\n\n            // console.log(\"Got a debug update!\", update);\n\n            dispatch(onDebuggerUpdate(update as any as DebuggerUpdateMessage));\n        }\n    };\n\nexport const useDebuggerWebsocketEventListener = () => {\n    const appId = useSelector(getAppId);\n    const dispatch = useDispatch<AnvilDispatch>();\n    useWebsocketEventListener(appId, (e) => dispatch(ingestWebsocketEvent(e)));\n};\n\nconst sendKeepalive =\n    (hyperStackId: string, debuggerId: string): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const debuggerHyperStacks = getDebuggerHyperStacks(state);\n        console.log(\"Sending keepalive for\", hyperStackId, debuggerId);\n        const dbg = debuggerHyperStacks[hyperStackId]?.debuggers.find((d) => d.debuggerId === debuggerId);\n        if (!dbg) {\n            console.log(\"Debugger\", debuggerId, \"doesn't exist, giving up\");\n            return;\n        }\n        console.log(\"Sending keepalive for\", dbg);\n        const appId = getAppId(state)!;\n        try {\n            await dispatch(sendDebuggerRequest(dbg, { action: \"KEEPALIVE\" }));\n        } catch (e) {\n            console.error(e);\n            console.log(\"Debugger keepalive failed, destroying debugger\", debuggerId);\n            updateState((state) => {\n                // TODO: Probably don't want to destroy the entire hyperstack. Maybe. What if we've stepped out of a debugger?\n                delete state.debuggerHyperStacks[hyperStackId];\n            });\n            return;\n        }\n        // TODO: Figure out why this isn't working.\n        setTimeout(() => dispatch(sendKeepalive(hyperStackId, debuggerId)), 30000);\n    };\n\nexport const getDebugEnvBreakpoints = createSelector(\n    [(state) => getCategorisedEnvironments(state).debug, (state) => getCodeNames(state) as any],\n    (debugEnv: AppEnvironment | undefined, codeNames) => {\n        return Object.fromEntries(\n            (debugEnv?.debugger?.breakpoints || [])\n                .map((b) => {\n                    const codePath = codeNames[b.module]?.codePath;\n                    if (codePath) {\n                        return [codePath, { breaks: b.breaks, module: b.module }];\n                    }\n                    return false;\n                })\n                .filter(Boolean)\n        ) as { [codePath: string]: ModuleBreakpoints };\n    }\n);\n\nexport const getDebugEnvBreakpointsForRunner = (): AnvilAction => (dispatch, getState, updateState) => {\n    //@ts-ignore\n    return getDebugEnvBreakpoints(getState());\n};\n\nexport const clearBreakpoints = (): AnvilAction => async (dispatch, getState, updateState) => {\n    const debugEnv = getDebugEnvironment(getState());\n    await dispatch(setEnvironmentBreakpoints(debugEnv!, []));\n    sendRunnerDebugBroadcast(dispatch, { action: \"UPDATE_BREAKPOINTS\", breakpoints: [] });\n    dispatch(closeBottomTab({ type: \"breakpoints\" }));\n};\n\nexport const setBreakpoints =\n    (codePath: string, lines: number[]): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const codeNames = getCodeNames(state) as any;\n\n        // TODO: This is horrid. We should really have an index of codePath -> structureNode\n        const moduleName = Object.values<any>(codeNames).find((n) => n.codePath === codePath)?.fullName;\n\n        const debugEnv = getDebugEnvironment(state);\n\n        // Get existing breakpoints for this module to preserve order\n        const existingBreakIndex =\n            debugEnv![\"debugger\"]?.breakpoints?.findIndex(({ module }) => module === moduleName) ?? -1;\n\n        const breakpoints: ModuleBreakpoints[] = cloneDeep(debugEnv![\"debugger\"]?.breakpoints || []);\n\n        if (existingBreakIndex !== -1) {\n            breakpoints[existingBreakIndex] = {\n                module: moduleName,\n                breaks: lines.map((l) => ({ l })),\n            };\n        } else {\n            breakpoints.push({\n                module: moduleName,\n                breaks: lines.map((l) => ({ l })),\n            });\n        }\n\n        // Clear out any modules with no breakpoints\n        const finalBreakpoints = breakpoints.filter(({ breaks }) => breaks.length > 0);\n        finalBreakpoints.sort((a, b) => a.module.localeCompare(b.module));\n\n        await dispatch(setEnvironmentBreakpoints(debugEnv!, finalBreakpoints));\n\n        for (const hyperStack of Object.values(state.debuggerHyperStacks)) {\n            for (const dbg of hyperStack.debuggers) {\n                dispatch(sendDebuggerRequest(dbg, { action: \"UPDATE_BREAKPOINTS\", breakpoints: finalBreakpoints }));\n            }\n        }\n        sendRunnerDebugBroadcast(dispatch, { action: \"UPDATE_BREAKPOINTS\", breakpoints: finalBreakpoints });\n\n        if (!finalBreakpoints.length) {\n            dispatch(closeBottomTab({ type: \"breakpoints\" }));\n        }\n    };\n\nexport const toggleBreakpoint =\n    (codePath: string, line: number): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n\n        const codeNames = getCodeNames(state) as any;\n        const debugEnv = getDebugEnvironment(state);\n        const breakpoints = debugEnv![\"debugger\"]?.breakpoints || [];\n        const moduleName = Object.values<any>(codeNames).find((n) => n.codePath === codePath)?.fullName;\n\n        const moduleBreaks = breakpoints.find(({ module }) => module === moduleName);\n        if (moduleBreaks?.breaks.find((b) => b.l === line)) {\n            // There is already a breakpoint on this line.\n            await dispatch(\n                setBreakpoints(\n                    codePath,\n                    moduleBreaks.breaks.filter((b) => b.l !== line).map((b) => b.l)\n                )\n            );\n        } else if (codePath.startsWith(\"server_modules/\") && !getFeatureSupport(state, \"full-debugger\")) {\n            // There isn't already a breakpoint on this line, but we're not allowed to add breakpoints.\n            dispatch(modal(\"upgradePrompt\", { featureId: \"full-debugger\" }));\n        } else {\n            // There isn't already a breakpoint on this line.\n            await dispatch(setBreakpoints(codePath, [...(moduleBreaks?.breaks.map((b) => b.l) || []), line]));\n        }\n    };\n\nexport const getDebuggerState =\n    (hyperStackId: string, dbg: DebuggerIdentity): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = (await dispatch(sendDebuggerRequest(dbg, { action: \"GET_STATE\" }))) as Debugger;\n        if (state) {\n            augmentStack(state.stack, getCodeNames(getState()));\n            updateState(({ debuggerHyperStacks }) => {\n                const hs = debuggerHyperStacks[hyperStackId];\n                if (hs) {\n                    const idx = hs.debuggers.findIndex((d) => d.debuggerId === dbg.debuggerId);\n                    hs.debuggers[idx] = state;\n                }\n            });\n        }\n    };\n\nconst updateStackFrameObject =\n    (\n        { hyperstackId, dbg, frame }: StackFrameContextType,\n        globals: boolean,\n        path: DebuggerGetValueRequestPath,\n        updater: (obj: any) => void\n    ) =>\n    ({ debuggerHyperStacks }: State) => {\n        if (!dbg || !frame) return;\n        const h = debuggerHyperStacks[hyperstackId];\n        if (h) {\n            const d = h.debuggers.find((d) => d.debuggerId === dbg.debuggerId);\n            if (d && \"stack\" in d) {\n                const f = d.stack.find((f) => f.id === frame.id);\n                if (f) {\n                    f[globals ? \"globals\" : \"locals\"] ??= {} as any;\n                    const ns = globals ? f.globals : f.locals;\n                    if (ns) {\n                        let obj = ns;\n                        for (const [walktype, step] of path) {\n                            if (walktype === \"i\") {\n                                obj = obj.items![step][1];\n                            } else if (walktype === \"a\") {\n                                obj = obj.attrs![step];\n                            }\n                        }\n                        updater(obj);\n                    }\n                }\n            }\n        }\n    };\n\nexport const getValue =\n    (\n        { hyperstackId, dbg, frame }: StackFrameContextType,\n        globals: boolean,\n        path: DebuggerGetValueRequestPath,\n        depth = 1\n    ): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        if (!dbg || !frame) return;\n        const resp: any = await dispatch(\n            sendDebuggerRequest(dbg, { action: \"GET_VALUE\", frame: frame.id, globals, path, depth })\n        );\n        if (resp?.value) {\n            const value = resp.value;\n            updateState(({ debuggerHyperStacks }) => {\n                const h = debuggerHyperStacks[hyperstackId];\n                if (h) {\n                    const d = h.debuggers.find((d) => d.debuggerId === dbg.debuggerId);\n                    if (d && \"stack\" in d) {\n                        const f = d.stack.find((f) => f.id === frame.id);\n                        if (f) {\n                            f[globals ? \"globals\" : \"locals\"] ??= {} as any;\n                            const ns = globals ? f.globals : f.locals;\n                            if (ns) {\n                                let obj = ns;\n                                for (const [walktype, step] of path) {\n                                    if (walktype === \"i\") {\n                                        obj = obj.items![step][1];\n                                    } else if (walktype === \"a\") {\n                                        obj = obj.attrs![step];\n                                    }\n                                }\n                                Object.assign(obj, value);\n                                console.log(\"Setting value\", obj, value);\n                            }\n                        }\n                    }\n                }\n            });\n        } else {\n            console.warn(\"Debugger getValue returned no value:\", hyperstackId, dbg, frame, globals, path);\n        }\n    };\n\nexport const getItems =\n    (\n        { hyperstackId, dbg, frame }: StackFrameContextType,\n        globals: boolean,\n        path: DebuggerGetValueRequestPath,\n        offset: number\n    ): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        if (!dbg || !frame) return;\n\n        const resp: any = await dispatch(\n            sendDebuggerRequest(dbg, { action: \"GET_ITEMS\", frame: frame.id, globals, path, offset })\n        );\n        if (resp?.items) {\n            updateState(\n                updateStackFrameObject({ hyperstackId, dbg, frame }, globals, path, (obj) => {\n                    if (resp.offset === obj.items.length) {\n                        // Just in case several of these happened concurrently.\n                        obj.items.push(...resp.items);\n                    }\n                })\n            );\n        }\n    };\n","import { isEqual, set } from \"lodash-es\";\nimport { DepConfigKeys } from \"@runtime/runner/data\";\nimport { modal } from \"@/controllers/modals\";\nimport {\n    AnvilAction,\n    AnvilAsyncAction,\n    AnvilDispatch,\n    AppConfig,\n    AppPath,\n    AppState,\n    CodePath,\n    DependencyConfig,\n    DependencyGraph,\n    IDEDependencyContent,\n    State,\n} from \"@/types\";\nimport { EMPTY_ARRAY, EMPTY_OBJECT, getRandomString } from \"@/util\";\nimport * as api from \"../api\";\nimport {\n    ensureNoNewerDeps,\n    getApp,\n    getAppId,\n    markAppPathUnsaved,\n    markAppPathsUnsaved,\n    updateEditorSequenceAppPaths,\n} from \"./app\";\nimport { parseDependencyCode } from \"./app/autocompleter\";\nimport { applyCodePreludeEverywhere, loadAllForms, updateSerializedHtml } from \"./app/code\";\nimport { getDependencyPackageRenamesForFormSpecs, renamePackagesInFormSpecs } from \"./app/form-specs\";\nimport type { PackageRename } from \"./app/form-specs\";\nimport { saveApp } from \"./app/saving\";\n\nconst applyPackageRenamesToFormSpecs =\n    (packageRenames: PackageRename[]): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        if (!packageRenames.length) {\n            return;\n        }\n\n        const changedFormCodePaths: CodePath[] = [];\n        const refreshedPreviewCodePaths: CodePath[] = [];\n\n        for (const formItem of await dispatch(loadAllForms())) {\n            // loadAllForms returns loaded code-cache entries. Their `item`\n            // objects are mutable; markAppPathsUnsaved below is the Redux\n            // notification that makes the batched rewrite visible.\n            const form = formItem.item;\n            // Package renames only rewrite package-qualified specs. Legacy\n            // customComponentSpec/formPropertySpec values keep their old shape.\n            const yamlChanged = renamePackagesInFormSpecs(form, packageRenames);\n            const codePath = `forms/${form.class_name}` as CodePath;\n\n            if (form.save_as_html && yamlChanged) {\n                // save_as_html stores canonical YAML, so serialized_html only\n                // changes when package-qualified YAML changed above.\n                form.serialized_html = updateSerializedHtml(form, getState());\n            }\n\n            if (!form.save_as_html && form.edit_as_html) {\n                // edit_as_html keeps YAML in its existing shape, but\n                // serialized_html is a package-qualified preview. Renaming\n                // this app's package or a dependency package can therefore\n                // change the preview even when legacy/app-local YAML stays\n                // byte-for-byte the same. Compare before assigning so an\n                // unrelated package rename does not mark every HTML-edited\n                // form unsaved.\n                const previousSerializedHtml = form.serialized_html;\n                const serializedHtml = updateSerializedHtml(form, getState());\n                if (serializedHtml !== previousSerializedHtml) {\n                    form.serialized_html = serializedHtml;\n                    if (!yamlChanged) {\n                        refreshedPreviewCodePaths.push(codePath);\n                    }\n                }\n            }\n\n            if (yamlChanged) {\n                changedFormCodePaths.push(codePath);\n            }\n        }\n\n        if (changedFormCodePaths.length) {\n            dispatch(markAppPathsUnsaved(changedFormCodePaths.map((codePath) => [\"CODE\", codePath] as AppPath)));\n        }\n        if (refreshedPreviewCodePaths.length) {\n            updateState(\"Refresh edit_as_html serialized previews after package rename\", ({ editor }) => {\n                for (const codePath of refreshedPreviewCodePaths) {\n                    updateEditorSequenceAppPaths(editor, [\"CODE\", codePath]);\n                }\n            });\n        }\n    };\n\nexport const addDependency = (depAppId: string): AnvilAsyncAction =>\n    async function (dispatch, getState, updateState) {\n        const state = getState();\n        const app = getApp(state),\n            appId = getAppId(state);\n        if (depAppId && app) {\n            const depInfo = await api.getDependencyInfo(appId, depAppId);\n\n            const newDep: DependencyConfig = {\n                dep_id: \"dep_\" + getRandomString() + getRandomString(),\n                version: depInfo.default_version?.spec ?? { branch: \"master\" },\n                resolution_hints: {\n                    app_id: depAppId,\n                    name: depInfo.name,\n                    package_name: depInfo.package_name,\n                },\n            };\n\n            if (!appId) return;\n            await api.setDependencyId(appId, newDep.dep_id!, depAppId);\n\n            updateState(\n                `Add dependency ${newDep.dep_id} -> ${depAppId}`,\n                set,\n                [\"app\", \"config\", \"dependencies\"],\n                app.config.dependencies?.concat(newDep) || [newDep]\n            );\n\n            dispatch(markAppPathUnsaved([\"SETTINGS\", \"dependencies\"]));\n            await dispatch(reloadDependencies(app));\n            const depCode = getApp(getState())!.dependencyCode[depAppId];\n            if (depCode?.code_prelude) {\n                await dispatch(applyCodePreludeEverywhere(depCode.code_prelude, { sourceName: depCode.package_name }));\n            }\n            // TODO: Save, probably.\n            // updateState(`Add dependency code for ${dep.name}`, update, ['app', 'content', 'dependency_code'], deps => deps.concat([newDep]))\n            // scope.app.dependency_code = thisApp.content.dependency_code;\n        }\n    };\n\ntype DependencyIdentifier = { app_id: string; dep_id?: undefined } | { app_id?: undefined; dep_id: string };\n\nexport const findDependencyAndIdentifier = (identifier: DependencyIdentifier, dependencyList: DependencyConfig[]) => {\n    const { app_id, dep_id } = identifier;\n    return dependencyList.find((d) => (dep_id ? d.dep_id === dep_id : d.app_id === app_id));\n};\n\nexport const dependencyAndIdentifier = (dependency: DependencyConfig, config: AppConfig) => {\n    const { app_id, dep_id } = dependency as DependencyIdentifier;\n    const identifier = app_id ? { app_id } : { dep_id };\n\n    const depId = dep_id ?? app_id;\n    const activeDepAppId = config.dependency_ids[depId];\n\n    const dep = findDependencyAndIdentifier(\n        identifier as DependencyIdentifier,\n        config.dependencies as DependencyConfig[]\n    );\n\n    return { activeDepAppId, dep };\n};\n\nexport const updateDependencyConfig = (\n    dependency: DependencyConfig,\n    propType: DepConfigKeys,\n    propName: string,\n    value: unknown\n): AnvilAction =>\n    async function (dispatch, getState, updateState) {\n        updateState(`Update ${propName} config value`, ({ app }) => {\n            const { dependencyCode, config } = app!;\n            const { activeDepAppId, dep } = dependencyAndIdentifier(dependency, config);\n            dependencyCode[activeDepAppId].config[propType][propName] = value;\n\n            if (dep?.config) {\n                dep.config[propType] = { ...dep.config[propType], [propName]: { value } };\n            } else {\n                dep!.config = { [propType]: { [propName]: { value } } };\n            }\n        });\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"dependencies\"]));\n    };\n\nexport const removeDependencyConfig = (\n    dependency: DependencyConfig,\n    propType: DepConfigKeys,\n    propName: string\n): AnvilAction =>\n    async function (dispatch, getState, updateState) {\n        updateState(`Remove ${propName} config`, ({ app }) => {\n            const { dependencyCode, config } = app!;\n            const { activeDepAppId, dep } = dependencyAndIdentifier(dependency, config);\n            const defaultValue = dependencyCode[activeDepAppId].config_schema?.[propType][propName].default_value;\n            dependencyCode[activeDepAppId].config[propType][propName] = defaultValue;\n            if (dep?.config?.[propType]) delete dep.config[propType][propName];\n        });\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"dependencies\"]));\n    };\n\nexport const removeStaleConfig = (\n    dependency: DependencyConfig,\n    propType: DepConfigKeys,\n    propName: string\n): AnvilAction =>\n    async function (dispatch, getState, updateState) {\n        updateState(`Remove ${propName} config`, ({ app }) => {\n            const { dependencyCode, config } = app!;\n            const { activeDepAppId, dep } = dependencyAndIdentifier(dependency, config);\n            delete dependencyCode[activeDepAppId]?.config?.[propType]?.[propName];\n\n            if (dep?.config?.[propType]) delete dep.config[propType][propName];\n        });\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"dependencies\"]));\n    };\n\nexport const saveIfDependencyConfigHasChanged = (originalDep: DependencyConfig): AnvilAction =>\n    async function (dispatch, getState, updateState) {\n        const app = getApp(getState());\n        if (!app) return;\n        const { dep } = dependencyAndIdentifier(originalDep, app!.config);\n\n        if (!isEqual(dep?.config, originalDep.config)) dispatch(reloadDependencies(app));\n    };\n\nexport const deleteDependency = (logicalDepId: string): AnvilAction =>\n    async function (dispatch, getState, updateState) {\n        let app = getApp(getState());\n        if (!app) return;\n        const depIds = app.config.dependency_ids;\n        const depAppId = depIds[logicalDepId];\n        const depCode = app.dependencyCode[depAppId];\n\n        updateState(\"Remove dependency\", (state) => {\n            const app = state.app;\n            if (!app) return;\n            const depIds = app.config.dependency_ids;\n            const depAppId = depIds[logicalDepId];\n            delete depIds[logicalDepId];\n            if (!Object.entries(depIds).find(([logicalDepId, appId]) => appId === depAppId)) {\n                delete app.dependencyCode[depAppId];\n            }\n            app.config.dependencies = app.config.dependencies?.filter(\n                (d) => d.dep_id !== logicalDepId && d.app_id !== logicalDepId\n            );\n            // TODO: also remove from dependency order?\n        });\n\n        if (depCode.code_prelude) {\n            dispatch(\n                applyCodePreludeEverywhere(depCode.code_prelude, { sourceName: depCode.package_name, remove: true })\n            );\n        }\n\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"dependencies\"]));\n        app = getApp(getState());\n        if (!app) return;\n        await parseDependencyCode(app.dependencyCode);\n    };\n\nexport const getDependencyOrder = (state: State): string[] => state.app?.config.dependency_order ?? EMPTY_ARRAY;\nexport const getLogicalDependencyIds = (state: State) => state.app?.config.dependency_ids ?? EMPTY_OBJECT;\nexport const getCorrectLogicalDependencyIds = (state: State) =>\n    state.app?.config.correct_dependency_ids ?? EMPTY_OBJECT;\n\ninterface ReloadDependenciesOptions {\n    applyPreludeChanges?: boolean;\n    ensureNoNewerDependencyRuntime?: boolean;\n    markUnsaved?: boolean;\n    saveBeforeReload?: boolean;\n}\n\nexport const reloadDependencies = (\n    app: AppState,\n    {\n        applyPreludeChanges = false,\n        ensureNoNewerDependencyRuntime = true,\n        markUnsaved = true,\n        saveBeforeReload = true,\n    }: ReloadDependenciesOptions = {}\n): AnvilAsyncAction =>\n    async function (dispatch, getState, updateState) {\n        if (saveBeforeReload) {\n            await dispatch(saveApp());\n        }\n\n        const previousDependencyCode = app.dependencyCode;\n        const previousDependencyIds = { ...app.config.dependency_ids };\n        const thisApp = await api.getApp(app.id, app.editState);\n        if (getState().app?.id !== app.id) {\n            return;\n        }\n\n        if (ensureNoNewerDependencyRuntime) {\n            await dispatch(ensureNoNewerDeps(app.config.runtime_options, thisApp.content.dependency_code));\n        }\n\n        updateState(\"Finalise dependency\", (state) => {\n            const app = state.app;\n            if (!app) return;\n            app.dependencyCode = thisApp.content.dependency_code;\n            app.dependencyGraph = thisApp.dependency_graph;\n            app.config.dependency_order = thisApp.content.dependency_order;\n            app.config.dependency_ids = thisApp.content.dependency_ids;\n            app.config.correct_dependency_ids = thisApp.content.correct_dependency_ids;\n        });\n\n        if (markUnsaved) {\n            dispatch(markAppPathUnsaved([\"SETTINGS\", \"dependencies\"]));\n        }\n        if (applyPreludeChanges) {\n            await makeAfterReload(previousDependencyCode, dispatch)(thisApp.content.dependency_code);\n        }\n\n        await parseDependencyCode(thisApp.content.dependency_code);\n\n        const dependencyPackageRenames = getDependencyPackageRenamesForFormSpecs(\n            previousDependencyCode,\n            previousDependencyIds,\n            thisApp.content.dependency_code || {},\n            thisApp.content.dependency_ids || {}\n        );\n\n        if (dependencyPackageRenames.length) {\n            await dispatch(applyPackageRenamesToFormSpecs(dependencyPackageRenames));\n        }\n    };\n\nexport const dependencyVersionChange = (dep: DependencyConfig, value: string): AnvilAsyncAction =>\n    async function (dispatch, getState, updateState) {\n        const spec = JSON.parse(value);\n        const app = getApp(getState());\n        if (!app) return;\n        const dependencies = app.config.dependencies;\n        if (!dependencies) return;\n        const matchingDepIndex = dependencies.findIndex((d) => (d.dep_id ?? d.app_id) === (dep.dep_id ?? dep.app_id));\n        if (matchingDepIndex === -1) return;\n        const matchingDep = dependencies[matchingDepIndex];\n        if (!matchingDep) return;\n        updateState(\"Update dependency version\", (state) => {\n            const matchingDep = state.app?.config.dependencies?.[matchingDepIndex];\n            if (!matchingDep) return;\n            matchingDep.version = spec;\n        });\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"dependencies\"]));\n        await dispatch(reloadDependencies(app, { applyPreludeChanges: true }));\n    };\n\nexport function pythonifyPackageName(name: string) {\n    return name.replace(/[^A-z0-9]/g, \"_\").replace(/^[0-9]/, \"_$&\");\n}\n\nexport const updatePackageName = (newName: string): AnvilAsyncAction =>\n    async function (dispatch, getState, updateState) {\n        if (!newName) {\n            // don't save an empty name\n            return;\n        }\n        newName = pythonifyPackageName(newName);\n        const oldPackageName = getApp(getState())?.config.package_name;\n\n        updateState(`Change package name to: ${newName}`, (state) => {\n            if (!state.app) return;\n            state.app.config.package_name = newName;\n        });\n\n        if (oldPackageName !== newName) {\n            const packageRenames = oldPackageName ? [{ oldPackageName, newPackageName: newName }] : [];\n            await dispatch(applyPackageRenamesToFormSpecs(packageRenames));\n        }\n\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"package_name\"]));\n    };\n\nexport const getAppDependencies = (state: State) => state.app?.config.dependencies || EMPTY_ARRAY;\n\nexport const getDependencyGraph = (state: State): DependencyGraph => state.app?.dependencyGraph ?? EMPTY_OBJECT;\n\nconst makeAfterReload =\n    (previousDependencyCode: AppState[\"dependencyCode\"], dispatch: AnvilDispatch) =>\n    async (dependencyCode: AppState[\"dependencyCode\"]) => {\n        const depAppIds = new Set([...Object.keys(previousDependencyCode), ...Object.keys(dependencyCode)]);\n        for (const depAppId of depAppIds) {\n            const previousDep = previousDependencyCode[depAppId];\n            const newDep = dependencyCode[depAppId];\n            if (isEqual(previousDep?.code_prelude, newDep?.code_prelude)) {\n                continue;\n            }\n            await dispatch(\n                applyCodePreludeEverywhere(previousDep?.code_prelude, {\n                    sourceName: previousDep?.package_name,\n                    remove: true,\n                })\n            );\n            await dispatch(applyCodePreludeEverywhere(newDep?.code_prelude, { sourceName: newDep?.package_name }));\n        }\n    };\n\nexport const remapDependency =\n    (dependency: DependencyConfig, setOfDepAppIds: Set<string>, alreadyBroken: boolean): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const depAppId = await dispatch(\n            modal(\"remapDependency\", {\n                refDep: dependency,\n                setOfDepAppIds,\n                alreadyBroken,\n            })\n        );\n\n        if (depAppId) {\n            const state = getState();\n            const appId = getAppId(state);\n            const app = getApp(state);\n            if (!app) return;\n            const depId = dependency.dep_id ?? dependency.app_id;\n            if (!depId) return;\n            await api.setDependencyId(appId, depId, depAppId);\n            await dispatch(reloadDependencies(app, { applyPreludeChanges: true }));\n        }\n    };\n\nexport const reorderDependencies =\n    (fromDep: DependencyConfig, toDep: DependencyConfig): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        if (fromDep === toDep) return;\n        let deps = getAppDependencies(getState());\n\n        const fromIndex = deps.indexOf(fromDep);\n        const toIndex = deps.indexOf(toDep);\n        console.log(fromIndex, toIndex);\n        if (fromIndex === -1 || toIndex === -1) return;\n        if (toIndex < fromIndex) {\n            // to goes before from\n            deps = [\n                ...deps.slice(0, toIndex),\n                fromDep,\n                toDep,\n                ...deps.slice(toIndex + 1, fromIndex),\n                ...deps.slice(fromIndex + 1),\n            ];\n        } else {\n            deps = [\n                ...deps.slice(0, fromIndex),\n                ...deps.slice(fromIndex + 1, toIndex),\n                toDep,\n                fromDep,\n                ...deps.slice(toIndex + 1),\n            ];\n        }\n\n        // todo - work out the best way to slice and dice here;\n        updateState((state) => {\n            if (!state.app?.config?.dependencies) return;\n            state.app.config.dependencies = deps;\n        });\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"dependencies\"]));\n    };\n\nexport const findLogicalDepIdForDepAppId = (depAppId: string, appConfig: AppConfig) => {\n    const deps = appConfig.dependencies ?? [];\n    const correctDependencyIds = appConfig.correct_dependency_ids ?? appConfig.dependency_ids ?? {};\n    return [...deps.map((d) => d.dep_id ?? d.app_id), ...Object.keys(correctDependencyIds)].find(\n        (ldi) => ldi && correctDependencyIds[ldi] === depAppId\n    );\n};\n\nexport const getDependencyHints = (\n    dependency?: Pick<DependencyConfig, \"dep_id\" | \"app_id\" | \"resolution_hints\"> | null,\n    depCode?: Pick<IDEDependencyContent, \"logical_dep_id\" | \"resolution_hints\"> | null\n) => {\n    const logicalDepId = dependency?.dep_id ?? dependency?.app_id;\n    // Several logical references can share one failed app entry. Its hints may\n    // describe a different reference; in that case use this row's YAML hints.\n    return depCode?.logical_dep_id && logicalDepId && depCode.logical_dep_id !== logicalDepId\n        ? dependency?.resolution_hints\n        : (depCode?.resolution_hints ?? dependency?.resolution_hints);\n};\n\nexport const getDependencyDisplayName = (\n    dependency: Pick<DependencyConfig, \"dep_id\" | \"app_id\" | \"resolution_hints\">,\n    depCode?: Pick<IDEDependencyContent, \"name\" | \"package_name\" | \"resolution_hints\" | \"logical_dep_id\"> | null\n) => {\n    const hints = getDependencyHints(dependency, depCode);\n    return (\n        depCode?.name ||\n        hints?.name ||\n        depCode?.package_name ||\n        hints?.package_name ||\n        dependency.dep_id ||\n        dependency.app_id ||\n        depCode?.logical_dep_id ||\n        null\n    );\n};\n\n// TODO: This is obviously a hack. We'll need some kind of reliable way to detect certain first-party dependencies.\nexport const hasRoutingDependency = (state: State) =>\n    \"3PIDO5P3H4VPEMPL\" in (state.app?.dependencyCode || {}) || !!window.localStorage.hasRoutingDependency;\n","import { useMemo } from \"react\";\nimport { cloneDeep, isEqual, last, set } from \"lodash-es\";\nimport { createSelector } from \"reselect\";\nimport {\n    ConsoleOutputDTO,\n    CustomComponentSpec,\n    DesignerScrollPosition,\n    EditPath,\n    SelectedObjectDTO,\n    ToolboxItem,\n    ToolboxSection,\n} from \"@designer/shared-types\";\nimport { CustomLayoutYaml } from \"@runtime/components/Component\";\nimport { LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX } from \"@runtime/runner/component-spec-constants\";\nimport { FormLayoutYaml, LayoutMetadata } from \"@runtime/runner/data\";\nimport { RpcView } from \"@/components/tabs/code/designer/rpc\";\nimport { provideJsCustomComponentsToAutocompleter } from \"@/controllers/app/autocompleter\";\nimport { makeCustomComponentSpec } from \"@/controllers/app/form-spec-writers\";\nimport { closeBottomTab } from \"@/controllers/bottom-tabs\";\nimport { maybeInsertFormTabAfter, updateOrCreateHiddenTab } from \"@/controllers/tabs\";\nimport { EMPTY_ARRAY } from \"@/util\";\nimport { ExternalStore, useStoreSelector } from \"@/util/external-store\";\nimport { navigate } from \"../router/navigation\";\nimport type { AnvilAction, AnvilAsyncAction, CodePath, CodeTab, State, Tab } from \"../types\";\nimport { getCustomLayoutForms } from \"./app/code\";\nimport { findLogicalDepIdForDepAppId } from \"./dependencies\";\n\nexport type PanelSectionType = \"toolbox\" | \"properties\" | \"componentStructure\";\nexport const PANEL_SECTIONS: PanelSectionType[] = [\"toolbox\", \"properties\", \"componentStructure\"];\ntype PanelSectionMemory = Record<PanelSectionType, boolean>;\ntype PanelSectionState = { expanded: boolean; preExclusiveState?: PanelSectionMemory };\ntype PanelSectionTab = Pick<Tab, \"id\">;\n\nexport interface TabPanelSections {\n    toolbox: PanelSectionState;\n    properties: PanelSectionState;\n    componentStructure: PanelSectionState;\n}\n\nexport interface PanelSections {\n    [tabId: number]: TabPanelSections;\n}\n\nexport interface DesignerState {\n    panelSections: PanelSections;\n    showClassicDesigner: boolean;\n    output: null | any[];\n    panelWidth: string | number;\n    panelDocked: null | boolean;\n    jsCustomComponents?: CustomComponentSpec[];\n    jsLayouts: LayoutSpec[];\n    expandedToolboxSections: Record<string, boolean>;\n    expandedPropertyGroups: Record<string, boolean>;\n    hasErrors: boolean;\n\n    // [key: string]: any; // comment out this line for unsafe types\n    [tabId: number]: { selection?: SelectedObjectDTO[]; editingFormCodePath?: CodePath };\n}\n\ntype BooleanMap = Record<string, boolean>;\ntype BooleanMapUpdater = (value: BooleanMap) => BooleanMap;\n\nexport type Pkg = {\n    defaultItems: ToolboxItem[];\n    roleItems: ToolboxItem[];\n    sections: ToolboxSection[];\n};\n\nexport function useToolboxPackagesOrganizedByType(toolboxPackages: { [p: string]: Pkg }) {\n    return useMemo(() => {\n        const lib: { [type: string]: ToolboxItem & { packageName: string } } = {};\n        const makeItem = (pkgName: string, components: ToolboxItem[]) => {\n            components.forEach((item) => {\n                if (\"slot\" in item) return;\n                lib[item.component.type] = { ...item, packageName: pkgName };\n            });\n        };\n        Object.entries(toolboxPackages).forEach(([packageName, entries]) => {\n            Object.entries(entries).forEach(([entry, itemsOrSections]) => {\n                if (entry === \"sections\") {\n                    (itemsOrSections as ToolboxSection[]).forEach((section) => {\n                        makeItem(packageName, section.items);\n                    });\n                } else {\n                    makeItem(packageName, itemsOrSections as ToolboxItem[]);\n                }\n            });\n        });\n        return lib;\n    }, [toolboxPackages]);\n}\n\n// Don't store the RPC refs in state, because they're rich objects.\nconst DesignerRefStore = new ExternalStore<{ [id: Tab[\"id\"]]: RpcView }>({});\n\nexport const setRpcObject = (tabId: Tab[\"id\"], rpc: RpcView) => {\n    if (!tabId) return;\n    DesignerRefStore.updateState((s) => {\n        s[tabId] = rpc;\n    });\n};\n\nexport const clearRpcObject = (tabId: Tab[\"id\"]) => {\n    DesignerRefStore.updateState((s) => {\n        delete s[tabId];\n    });\n};\n\nexport const getAllDesignerRpcObjects = (): RpcView[] => {\n    return Object.values(DesignerRefStore.getState());\n};\n\nexport const useDesignerRpcByTabId = (tabId?: Tab[\"id\"]) => {\n    return useStoreSelector(DesignerRefStore, (s) => (tabId == null ? undefined : s[tabId]));\n};\n\nconst isTemporary = (editPathFrom?: EditPath, editPathTo?: EditPath) => {\n    if (!editPathFrom) {\n        return !!editPathTo?.length;\n    }\n    if (!editPathTo) {\n        return false;\n    }\n    return editPathFrom.length < editPathTo.length;\n};\n\nconst getNavTarget = (\n    topLevelFormClassName: string,\n    editPath: EditPath,\n    formClassName: string,\n    currentTab: CodeTab\n) => {\n    const navTarget = {\n        type: \"CODE\",\n        codePath: `forms/${formClassName}`,\n        editingPath: editPath,\n        topLevelFormClassName,\n        view: currentTab.navTarget.view,\n        essentialView: { design: true },\n        temp: isTemporary(currentTab.navTarget.editingPath, editPath),\n    } as const;\n    return navTarget;\n};\n\nexport const preNavigateToEditingForm =\n    (topLevelFormClassName: string, editPath: EditPath, formClassName: string, currentTab: CodeTab): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const navTarget = getNavTarget(topLevelFormClassName, editPath, formClassName, currentTab);\n        if (topLevelFormClassName !== formClassName) {\n            dispatch(maybeInsertFormTabAfter(`forms/${formClassName}`, `forms/${topLevelFormClassName}`, navTarget));\n        } else {\n            dispatch(updateOrCreateHiddenTab(navTarget));\n        }\n    };\n\nexport const navigateToEditingForm =\n    (\n        topLevelFormClassName: string,\n        editPath: EditPath,\n        formClassName: string,\n        currentTab: CodeTab,\n        { scrollPosition }: { scrollPosition?: DesignerScrollPosition } = {}\n    ): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const navTarget = getNavTarget(topLevelFormClassName, editPath, formClassName, currentTab);\n        if (topLevelFormClassName !== formClassName) {\n            dispatch(maybeInsertFormTabAfter(`forms/${formClassName}`, `forms/${topLevelFormClassName}`, navTarget));\n        }\n        dispatch(navigate({ ...navTarget, designerScrollPosition: scrollPosition }));\n    };\n\nexport const recordDesignerOutput =\n    (output: ConsoleOutputDTO): AnvilAction =>\n    (dispatch, getState, updateState) =>\n        updateState(\"Designer console output\", ({ editor: { designer } }) => {\n            designer.output ||= [];\n            // TODO: This is very similar to replOutput. Should probably combine them.\n            const previous: ConsoleOutputDTO | undefined = last(designer.output);\n            if (\n                output.fn === \"stdout\" &&\n                previous?.fn === \"stdout\" &&\n                previous.fromServer === output.fromServer &&\n                previous.text &&\n                !previous.text.endsWith(\"\\n\")\n            ) {\n                previous.text += output!.text;\n            } else {\n                designer.output.push(cloneDeep(output));\n            }\n        });\n\nexport const clearDesignerOutput = (): AnvilAction => (dispatch, getState, updateState) => {\n    updateState(\"Clear debug output\", set, [\"editor\", \"designer\", \"output\"], []);\n};\n\nexport const closeDesignerOutput = (): AnvilAction => (dispatch, getState, updateState) => {\n    updateState(\"Clear debug output\", ({ editor }) => {\n        editor.designer.output = null;\n    });\n    dispatch(closeBottomTab({ type: \"designerOutput\" }));\n};\n\nexport interface LayoutSpec {\n    fromDependency: boolean;\n    name: string; // Should be the fairly raw name of the code item. Used if metadata.title is not defined.\n    layout: FormLayoutYaml;\n    metadata: LayoutMetadata;\n    save_as_html?: boolean;\n}\n\n// TODO: This isn't called any more. Get layouts from state.designer.jsCustomComponents\nexport const setJSLayouts =\n    (layouts: LayoutSpec[]): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ editor: { designer } }) => {\n            designer.jsLayouts = layouts;\n        });\n    };\n\nexport const setDesignerPanelDocked =\n    (docked: boolean): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        updateState(({ editor: { designer } }) => {\n            designer.panelDocked = docked;\n        });\n    };\n\nexport const setDesignerPanelWidth =\n    (width: number): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        updateState(({ editor: { designer } }) => {\n            designer.panelWidth = width;\n        });\n    };\n\nexport const setPanelSectionExpanded =\n    (tab: Tab, section: PanelSectionType, expanded: boolean, exclusive = false): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) =>\n        updateState(\n            ({\n                editor: {\n                    designer: { panelSections },\n                },\n            }) => {\n                panelSections[tab.id] ??= {\n                    toolbox: { expanded: true },\n                    properties: { expanded: false },\n                    componentStructure: { expanded: false },\n                };\n                for (const p of PANEL_SECTIONS) {\n                    delete panelSections[tab.id][p].preExclusiveState;\n                    if (expanded && exclusive) {\n                        panelSections[tab.id][p].expanded = false;\n                    }\n                }\n                panelSections[tab.id][section].expanded = expanded;\n                if (PANEL_SECTIONS.every((p) => !panelSections[tab.id][p].expanded)) {\n                    panelSections[tab.id][section === \"toolbox\" ? \"properties\" : \"toolbox\"].expanded = true;\n                }\n            }\n        );\n\nexport const togglePanelSectionExclusive =\n    (tab: PanelSectionTab, section: PanelSectionType): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) =>\n        updateState(\n            ({\n                editor: {\n                    designer: { panelSections },\n                },\n            }) => {\n                panelSections[tab.id] ??= {\n                    toolbox: { expanded: true },\n                    properties: { expanded: false },\n                    componentStructure: { expanded: false },\n                };\n\n                if (!panelSections[tab.id][section].preExclusiveState) {\n                    // It is not already exclusive\n                    panelSections[tab.id][section].preExclusiveState = {\n                        toolbox: false,\n                        properties: false,\n                        componentStructure: false,\n                    };\n                    const preExclusiveState = panelSections[tab.id][section].preExclusiveState!;\n                    for (const p of PANEL_SECTIONS) {\n                        preExclusiveState[p] = panelSections[tab.id][p].expanded;\n                        panelSections[tab.id][p].expanded = p === section;\n                        if (p !== section) {\n                            delete panelSections[tab.id][p].preExclusiveState;\n                        }\n                    }\n                } else {\n                    const preExclusiveState = panelSections[tab.id][section].preExclusiveState;\n                    if (preExclusiveState) {\n                        for (const p of PANEL_SECTIONS) {\n                            panelSections[tab.id][p].expanded = preExclusiveState[p];\n                        }\n                        delete panelSections[tab.id][section].preExclusiveState;\n                    }\n                }\n            }\n        );\n\nexport const updateExpandedToolboxSections =\n    (fn: BooleanMapUpdater): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        updateState(({ editor: { designer } }) => {\n            designer.expandedToolboxSections = fn(designer.expandedToolboxSections);\n        });\n    };\n\nexport const updateExpandedPropertyGroups =\n    (fn: BooleanMapUpdater): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        updateState(({ editor: { designer } }) => {\n            designer.expandedPropertyGroups = fn(designer.expandedPropertyGroups);\n        });\n    };\n\nconst DEFAULT_PANEL_SECTIONS = {\n    toolbox: { expanded: true },\n    properties: { expanded: false },\n    componentStructure: { expanded: false },\n};\n\nexport const getDesignerPanelDocked = (state: State) =>\n    state.editor.designer.panelDocked === null ? window.innerWidth >= 1500 : state.editor.designer.panelDocked;\nexport const getDesignerPanelWidth = (state: State) => state.editor.designer.panelWidth;\nexport const getDesignerPanelSections = (state: State, tab: PanelSectionTab) =>\n    state.editor.designer.panelSections[tab.id] || DEFAULT_PANEL_SECTIONS;\nexport const getExpandedToolboxSections = (state: State) => state.editor.designer.expandedToolboxSections;\nexport const getExpandedPropertyGroups = (state: State) => state.editor.designer.expandedPropertyGroups;\n\nexport const getDesignerOutput = (state: State) => state.editor.designer.output || EMPTY_ARRAY;\nexport const getDesignerHasOutput = (state: State) => state.editor.designer.output !== null;\n\nconst getJsLayouts = (state: State) => state.editor.designer.jsLayouts;\nexport const getJsCustomComponents = (state: State) => state.editor.designer.jsCustomComponents;\nexport const setJSCustomComponents =\n    (customComponents: CustomComponentSpec[]): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const jsComponents = getState().editor.designer.jsCustomComponents;\n        if (isEqual(jsComponents, customComponents)) {\n            // No change, no need to do anything here\n            // we'll get new jsComponents every time a new designer tab is opened\n            return;\n        }\n        updateState(({ editor: { designer } }) => {\n            designer.jsCustomComponents = customComponents;\n        });\n        dispatch(provideJsCustomComponentsToAutocompleter(customComponents));\n    };\n\ninterface LayoutSpecStructureOptions {\n    // Form structure uses `fullName` for the form's class_name, which is an\n    // app-local form name. The app/dependency package name is passed separately.\n    fullName: string;\n    logicalDepId?: string;\n    packageName?: string;\n    appPackageName?: string;\n    layoutMetadata?: LayoutMetadata;\n}\n// This is a temporary hack to turn form structure entries into LayoutSpecs\nconst layoutSpecFromFormStructure = ({\n    fullName,\n    logicalDepId,\n    packageName,\n    appPackageName,\n    layoutMetadata,\n}: LayoutSpecStructureOptions): LayoutSpec => {\n    const appLocalFormName = fullName;\n    const fromDependency = !!packageName || !!logicalDepId;\n    const formPackageName = fromDependency ? packageName : appPackageName;\n    if (!formPackageName) {\n        return {\n            name: fullName,\n            layout: { type: makeCustomComponentSpec({ appLocalFormName, logicalDepId }) },\n            fromDependency,\n            metadata: layoutMetadata ?? {},\n        };\n    }\n    return {\n        // `name` is the display fallback: local layout forms use the app-local\n        // form name, while dependency layout forms include the dependency\n        // package so users can see where the layout comes from.\n        name: fromDependency ? `${formPackageName}.${appLocalFormName}` : appLocalFormName,\n        layout: {\n            type: makeCustomComponentSpec({ appLocalFormName, packageName: formPackageName, logicalDepId }),\n        },\n        fromDependency,\n        metadata: layoutMetadata ?? {},\n    };\n};\n\nconst layoutMapper = ({ title, layout, description, thumbnail }: CustomLayoutYaml) => ({\n    fromDependency: false,\n    name: title,\n    layout,\n    metadata: { title, description, thumbnail },\n});\n\nexport const getLayoutsFromYaml = createSelector(\n    [(s: State) => s.app?.config.layouts, (state: State) => state.app?.dependencyCode, (s) => s.app?.config],\n    (layouts, depCode, appConfig) =>\n        (layouts ?? []).map<LayoutSpec>(layoutMapper).concat(\n            ...Object.entries(depCode || {}).map(([depAppId, dep]) =>\n                (dep.layouts ?? []).map((l) => {\n                    const layoutSpec = layoutMapper(l);\n                    layoutSpec.fromDependency = true;\n                    const logicalDepId = findLogicalDepIdForDepAppId(depAppId, appConfig);\n                    if (logicalDepId && layoutSpec.layout.type?.startsWith(LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX)) {\n                        const appLocalFormName = layoutSpec.layout.type.substring(\n                            LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX.length\n                        );\n                        const type = makeCustomComponentSpec({\n                            appLocalFormName,\n                            packageName: dep.package_name,\n                            logicalDepId,\n                        });\n                        layoutSpec.layout = { ...layoutSpec.layout, type };\n                    }\n                    return layoutSpec;\n                })\n            )\n        )\n);\n\nexport const getAllCustomLayouts = createSelector(\n    [getJsLayouts, (s) => getCustomLayoutForms(s), getLayoutsFromYaml, (s: State) => s.app?.config.package_name],\n    (jsLayouts, customLayoutForms, yamlLayouts, appPackageName) =>\n        // TODO: Work out whether jsLayouts works any more.\n        [...jsLayouts].concat(\n            customLayoutForms.map((layout) => layoutSpecFromFormStructure({ ...layout, appPackageName })),\n            yamlLayouts\n        )\n);\n\nexport const getShowNewDesigner = (s: State) =>\n    s.app?.config.runtime_options?.version === 3 || !s.editor.designer.showClassicDesigner;\n","import { useQuery } from \"@tanstack/react-query\";\n\nexport interface ComponentDoc {\n    props: ComponentPropertyDoc[];\n    docsUrl?: string;\n}\n\nexport interface ComponentPropertyDoc {\n    name: string;\n    type: string;\n    description?: string;\n    exampleValue?: any;\n    defaultValue?: any;\n}\n\ninterface DocsIndex {\n    $builtinTypes?: {\n        anvil?: {\n            attrs?: Record<\n                string,\n                {\n                    docsUrl?: string;\n                    callable?: {\n                        [key: string]: unknown;\n                        returns?: {\n                            docsUrl?: string;\n                            attrs?: Record<string, any>;\n                        };\n                    };\n                    [key: string]: unknown;\n                }\n            >;\n        };\n    };\n}\n\nexport interface DocsData extends DocsIndex {\n    getComponentDoc: (type: string) => ComponentDoc | undefined;\n    getComponentDisplayType: (type: string) => string;\n    getComponentIconType: (type: string) => string;\n}\n\nconst canonicalBuiltinComponentType = (type: string) => {\n    const unqualifiedType = type.startsWith(\"anvil.\") ? type.substring(\"anvil.\".length) : type;\n    return unqualifiedType === \"HtmlPanel\" ? \"HtmlTemplate\" : unqualifiedType;\n};\n\nconst componentIconType = (type: string) => {\n    const canonicalType = canonicalBuiltinComponentType(type);\n    return canonicalType === \"HtmlTemplate\" || canonicalType === \"HtmlComponent\" ? \"HtmlPanel\" : canonicalType;\n};\n\nconst getBuiltinComponentDoc = (docs: DocsIndex, type: string): ComponentDoc | undefined => {\n    const componentDocs = docs.$builtinTypes?.anvil?.attrs?.[canonicalBuiltinComponentType(type)];\n    const instanceDocs = componentDocs?.callable?.returns;\n    const propertyDocs = instanceDocs?.attrs;\n    if (!propertyDocs) return undefined;\n\n    const props = Object.entries(propertyDocs)\n        .filter(\n            (entry): entry is [string, NonNullable<(typeof propertyDocs)[string]>] =>\n                !!entry[1]?.isComponentProperty\n        )\n        .map(([name, property]) => {\n            return {\n                name,\n                type: property.name || \"object\",\n                description: property.docString,\n                exampleValue: property.exampleValue,\n                defaultValue: property.defaultValue,\n            };\n        });\n\n    if (!props.length) return undefined;\n\n    return {\n        props,\n        docsUrl: instanceDocs?.docsUrl ?? componentDocs?.docsUrl,\n    };\n};\n\nconst makeDocsData = (docs: DocsIndex): DocsData => ({\n    ...docs,\n    getComponentDoc: (type) => getBuiltinComponentDoc(docs, type),\n    getComponentDisplayType: canonicalBuiltinComponentType,\n    getComponentIconType: componentIconType,\n});\n\nasync function loadDocs() {\n    const rv = await import(\"docs/index.json\");\n    return makeDocsData(rv.default);\n}\n\nexport function useDocs() {\n    return useQuery({\n        queryKey: [\"docs\"],\n        queryFn: loadDocs,\n        staleTime: Number.POSITIVE_INFINITY,\n    });\n}\n","import { useEffect } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { AnvilAction, AnvilAsyncAction, AnvilDispatch, AppId, RuntimeServerSpec, State } from \"@/types\";\nimport type { DynamicDownlinkImageState } from \"@/types/dynamic-downlinks\";\nimport { EMPTY_OBJECT } from \"@/util\";\nimport { WebsocketEvent, unwatchRuntimeSpec, useGlobalWebsocketEventListener, watchRuntimeSpec } from \"./websocket\";\n\nconst doWatchRuntimeSpec =\n    (appId: AppId, runtimeSpec: RuntimeServerSpec, setSpecHash: (hash: string) => void): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const initialState = await watchRuntimeSpec(appId, runtimeSpec);\n\n        updateState(({ dynamicDownlinkStates }) => {\n            dynamicDownlinkStates[initialState.spec_hash] = initialState;\n        });\n\n        setSpecHash(initialState.spec_hash);\n    };\n\nconst updateDynamicDownlinkImage =\n    (e: WebsocketEvent): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        switch (e.event) {\n            case \"DOWNLINK_IMAGE_UPDATE\":\n                updateState(({ dynamicDownlinkStates }: State) => {\n                    const { event, id, ...imageState } = e;\n                    dynamicDownlinkStates[e.spec_hash] = imageState;\n                });\n                break;\n        }\n    };\n\nexport const useWatchRuntimeSpec = (\n    appId: AppId,\n    runtimeSpec: RuntimeServerSpec,\n    setSpecHash: (hash: string) => void\n) => {\n    const dispatch = useDispatch() as AnvilDispatch;\n    useGlobalWebsocketEventListener((e) => dispatch(updateDynamicDownlinkImage(e)));\n    useEffect(() => {\n        dispatch(doWatchRuntimeSpec(appId, runtimeSpec, setSpecHash));\n        return () => {\n            unwatchRuntimeSpec(appId, runtimeSpec);\n        };\n    }, [appId, JSON.stringify(runtimeSpec)]);\n};\n\nexport const getDynamicDownlinkStates = (state: State): Record<string, DynamicDownlinkImageState> =>\n    state.dynamicDownlinkStates ?? EMPTY_OBJECT;\n","import { ModuleBreakpoints } from \"@platform-runner/shared-debugger-types\";\nimport {\n    cloneDeep,\n    concat,\n    isEmpty,\n    isEqual,\n    isNil,\n    merge,\n    omitBy,\n    pick,\n    remove,\n    some,\n    sortBy,\n    unset,\n} from \"lodash-es\";\nimport { createSelector } from \"reselect\";\nimport * as api from \"@/api\";\nimport { migrationConfirmContent } from \"@/components/modals/environments/EnvironmentsModal\";\nimport { claimAchievement } from \"@/controllers/user\";\nimport {AnvilAction, AnvilAsyncAction, AnvilDispatch, AppEnvironment, AppId, State} from \"@/types\";\nimport { TableMapping } from \"@/types/database\";\nimport { HttpError } from \"@/util/fetch\";\nimport { getAppId, markUnsaved, updateAppSchemaSync } from \"./app\";\nimport { invalidateTableSchema } from \"./app/autocompleter\";\nimport { blockNavigation, getUser, unblockNavigation } from \"./ide\";\nimport { alert, confirm } from \"./modals\";\nimport { recordActivity } from \"./util\";\nimport {useWebsocketEventListener, WebsocketEvent} from \"@/controllers/websocket.ts\";\nimport {useDispatch} from \"react-redux\";\n\nconst isErrorObjectType = (e: unknown): e is { error: unknown } => typeof e === \"object\" && e !== null && \"error\" in e;\n\n/** The platform server refuses to change a legacy app's environments until the app is migrated to environments. */\nconst isLegacyAppError = (e: unknown) =>\n    e instanceof HttpError && typeof e.body === \"object\" && e.body !== null && \"legacyError\" in e.body;\n\nexport const loadEnvironments =\n    (appIdParam: AppId | null = null): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = appIdParam || getAppId(state);\n        const allEnvs = appId ? await api.getEnvironments(appId) : [];\n\n        // TODO: Synthesise an environment with uplink keys if this is an old app without environments.\n\n        updateState(({ app }) => {\n            if (!app) return;\n            app.environments = allEnvs.filter((e) => !e.ephemeral);\n        });\n    };\n\nexport const getSelectedUplinkId = (state: State) => state.editor.selectedUplinkId;\nexport const setSelectedUplinkId =\n    (envId: AppEnvironment[\"env_id\"] | null): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ editor }) => {\n            editor.selectedUplinkId = envId;\n        });\n    };\n\nexport const getSelectedEnvironmentId = (state: State) => state.editor.selectedEnvironmentId;\n\nexport const setSelectedEnvironmentId =\n    (envId?: AppEnvironment[\"env_id\"] | null): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ editor }) => {\n            editor.selectedEnvironmentId = envId;\n        });\n    };\n\nexport const discardUnsavedEnvironments = (): AnvilAction => (dispatch, getState, updateState) => {\n    const toUnblockInvalid: AppEnvironment[\"env_id\"][] = [];\n    const toUnblockUnsaved: AppEnvironment[\"env_id\"][] = [];\n    updateState(({ app }) => {\n        if (!app?.environments) return;\n        for (let i = 0; i < app.environments.length; i++) {\n            const lastGood = app.environments[i].$lastGood;\n            if (lastGood) {\n                app.environments[i] = lastGood;\n                toUnblockInvalid.push(app.environments[i].env_id);\n            }\n            if (app.environments[i].$unsaved) {\n                app.environments[i].$unsaved = false;\n                toUnblockUnsaved.push(app.environments[i].env_id);\n            }\n        }\n    });\n    for (const eId of toUnblockInvalid) {\n        dispatch(unblockNavigation(`invalid-environment-${eId}`));\n    }\n    for (const eId of toUnblockUnsaved) {\n        dispatch(unblockNavigation(`unsaved-environment-${eId}`));\n    }\n};\n\nexport const updateEnvironmentWithoutSaving =\n    (env: AppEnvironment): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ app }) => {\n            if (!app?.environments) return;\n\n            for (let i = 0; i < app.environments.length; i++) {\n                if (app.environments[i].env_id === env.env_id) {\n                    const $lastGood = app.environments[i].$lastGood || app.environments[i];\n                    app.environments[i] = { ...env, $lastGood };\n                    app.environments[i].$unsaved = true;\n                }\n            }\n        });\n        if (!env.$unsaved) {\n            dispatch(blockNavigation(`unsaved-environment-${env.env_id}`));\n        }\n    };\n\nexport const markEnvironmentUnsaved =\n    (env: AppEnvironment): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ app }) => {\n            const environments = app?.environments ?? [];\n            for (const e of environments) {\n                if (e.env_id === env.env_id) {\n                    e.$unsaved = true;\n                }\n            }\n        });\n        if (!env.$unsaved) {\n            dispatch(blockNavigation(`unsaved-environment-${env.env_id}`));\n        }\n    };\n\nexport const confirmLeaveUnsavedEnvironment =\n    (): AnvilAsyncAction<boolean | undefined> => async (dispatch, getState, updateState) => {\n        const environments = getEnvironments(getState());\n        if (some(environments, (e) => e.$unsaved || e.$saveError)) {\n            const leave = await dispatch(\n                confirm(\n                    \"Discard changes?\",\n                    \"If you proceed, your unsaved changes will be lost. Do you want to continue?\"\n                )\n            );\n            if (leave) {\n                dispatch(discardUnsavedEnvironments());\n            }\n            return leave;\n        } else {\n            return true;\n        }\n    };\n\nexport const getEnvironments = (state: State) => state.app?.environments;\nexport const getEnvironmentById = (id: AppEnvironment[\"env_id\"], state: State) =>\n    state.app?.environments?.find((e) => e.env_id === id);\n\nexport const hasLegacyEnvironments = (state: State) => state.app?.environments?.some((env) => env.legacy);\n\nexport const getCategorisedEnvironments = createSelector([(s) => getUser(s), getEnvironments], (me, allEnvs) => {\n    allEnvs ??= [];\n    const userEnvs = allEnvs.filter((e) => e.user_email);\n    const realEnvCount = allEnvs.length - userEnvs.length;\n    const environments = {\n        debug: userEnvs.find((e) => e.mine)!, // My debug environment - guaranteed to exist\n        collaboratorDebug: userEnvs.filter((e) => !e.mine), // Other users' debug environments\n        auto: realEnvCount === 1 && allEnvs.find((e) => e.url === null && !e.user_email), // A magic environment created just for scheduled tasks, uplinks, etc.\n        named: allEnvs.filter((e) => (e.url || realEnvCount > 1) && !e.user_email), // All real environments apart from the magic one (\"Staging\", \"Prod\", \"Client X\" etc).\n        real: allEnvs.filter((e) => !e.user_email), // All real environments\n        restricted: allEnvs.filter((e) => e.restricted),\n        all: allEnvs,\n        sorted: [] as AppEnvironment[],\n    };\n    environments.sorted = concat(\n        sortBy(environments.real || [], [(e) => e.env_id]),\n        environments.debug && (environments.debug.url || !isEmpty(environments.debug.server_keys))\n            ? [environments.debug]\n            : []\n    );\n    return environments;\n});\n\nexport type CategorisedEnvironments = ReturnType<typeof getCategorisedEnvironments>;\n\nexport const getDebugEnvironment = createSelector([(s) => getCategorisedEnvironments(s)], ({ debug }) => debug);\n\nexport const getDefaultPublishedEnvironment = createSelector([(s) => getCategorisedEnvironments(s)], ({ named }) =>\n    named.find((env) => env.tags?.indexOf(\"default_published\") > -1)\n);\n\nexport const getCanPublishApp = createSelector(\n    [(s) => getCategorisedEnvironments(s), (s) => getDefaultPublishedEnvironment(s)],\n    ({ named }, defaultPublishedEnv) => defaultPublishedEnv || named.length === 0\n);\n\nexport const getEnvironmentOrigins = createSelector([(s) => getCategorisedEnvironments(s)], ({ named, debug }) => {\n    const origins = named.map((e) => e.origin).filter((o) => o);\n    if (debug?.origin) {\n        origins.unshift(debug?.origin);\n    }\n    return origins;\n});\n\nexport const getPublishInfo = createSelector([(s) => getCategorisedEnvironments(s)], (environments) => {\n    const privateEnvs = environments?.named.filter((env) => env.url?.access_key);\n    const publicEnvs = environments?.named.filter((env) => env.url?.alias);\n    const customEnvs = environments?.named.filter((env) => env.url?.domain);\n\n    const isPublished = privateEnvs.length > 0 || publicEnvs.length > 0 || customEnvs.length > 0;\n\n    return { privateEnvs, publicEnvs, customEnvs, isPublished };\n});\n\nexport const confirmAndMigrateApp =\n    (): AnvilAsyncAction<AppEnvironment | undefined> => async (dispatch, getState, updateState) => {\n        if (await dispatch(confirm(\"Publish using new Environments?\", migrationConfirmContent))) {\n            const appId = getAppId(getState());\n            const migratedEnv = await api.migrateToEnvironments(appId);\n            await dispatch(loadEnvironments());\n            return migratedEnv; // Return the migrated environment. Now we can retry whatever we were trying to do.\n        }\n    };\n\nexport type SaveEnvironmentError = { error: unknown };\nexport type SaveEnvironmentResult = AppEnvironment | SaveEnvironmentError | undefined;\nexport const isSavedEnvironment = (env: SaveEnvironmentResult): env is AppEnvironment => !!env && !(\"error\" in env);\n\nexport const saveEnvironment =\n    (env: AppEnvironment, envUpdates: Partial<AppEnvironment> = {}): AnvilAsyncAction<SaveEnvironmentResult> =>\n    async (dispatch, getState, updateState) => {\n        const { env_id, app_id } = env;\n        const saved = dispatch(markUnsaved(`env-${env_id}`));\n        try {\n            const { $saveError, $lastGood, $unsaved, $saving, ...toSave } = envUpdates;\n            updateState(({ app }) => {\n                app!.$environmentsSaving = true;\n            });\n            let updatedEnv!: AppEnvironment;\n            let isLegacyApp = false;\n            try {\n                updatedEnv = await api.updateEnvironment({ ...toSave, app_id, env_id });\n            } catch (e) {\n                if (!isLegacyAppError(e)) throw e;\n                isLegacyApp = true;\n            }\n\n            if (isLegacyApp) {\n                updateState(({ app }) => {\n                    app!.$environmentsSaving = false;\n                });\n                const migratedEnv = await dispatch(confirmAndMigrateApp());\n                dispatch(unblockNavigation(`unsaved-environment-${env_id}`));\n                if (migratedEnv) {\n                    saved();\n                    const updatesToReapply = pick(envUpdates, [\n                        \"branch\",\n                        \"table_mapping_id\",\n                        \"run_scheduled_tasks\",\n                        \"server_keys\",\n                        \"tags\",\n                        \"url\",\n                    ]);\n                    const savedEnv = await dispatch(saveEnvironment(migratedEnv, updatesToReapply));\n                    if (isSavedEnvironment(savedEnv)) {\n                        await dispatch(setSelectedEnvironmentId(savedEnv.env_id));\n                    }\n                    return savedEnv;\n                }\n            } else {\n                updateState(({ app }) => {\n                    if (!app?.environments) return;\n                    app.$environmentsSaving = false;\n                    for (let i = 0; i < app.environments.length; i++) {\n                        if (app.environments[i].env_id === env_id) {\n                            app.environments[i] = updatedEnv;\n                        }\n                    }\n                });\n                const e = getEnvironmentById(env_id!, getState());\n                if (!e) return e;\n                if (!e.$unsaved) {\n                    dispatch(unblockNavigation(`unsaved-environment-${env_id}`));\n                }\n                if (e.$saveError) {\n                    dispatch(blockNavigation(`invalid-environment-${env_id}`));\n                } else {\n                    dispatch(unblockNavigation(`invalid-environment-${env_id}`));\n                }\n                return e;\n            }\n        } catch (e) {\n            const isErrorObject = isErrorObjectType(e);\n            const message = e instanceof Error ? e.message : isErrorObject ? String(e.error) : String(e);\n            dispatch(alert(\"Unable to save environment\", message));\n            return { error: isErrorObject ? e.error : e };\n        } finally {\n            saved(); // Not necessarily saved (it could have failed), but definitely not saving any more.\n        }\n    };\n\nexport const setEnvironmentRestricted =\n    (env: AppEnvironment, restricted: boolean): AnvilAsyncAction<SaveEnvironmentResult> =>\n    async (dispatch, getState, updateState) => {\n        const saved = dispatch(markUnsaved(`env-${env.env_id}`));\n        updateState(({ app }) => {\n            if (app) app.$environmentsSaving = true;\n        });\n        try {\n            const updatedEnv = await api.setEnvironmentRestricted(env, restricted);\n            updateState(({ app }) => {\n                if (!app?.environments) return;\n                const index = app.environments.findIndex(({ env_id }) => env_id === env.env_id);\n                if (index !== -1) {\n                    app.environments[index] = updatedEnv;\n                }\n            });\n            return getEnvironmentById(env.env_id, getState());\n        } catch (e) {\n            const message = e instanceof Error ? e.message : String(e);\n            dispatch(alert(\"Unable to update environment\", message));\n            return { error: e };\n        } finally {\n            updateState(({ app }) => {\n                if (app) app.$environmentsSaving = false;\n            });\n            saved();\n        }\n    };\n\nexport const checkForStagingEnvironments = (): AnvilAction => (dispatch, getState, updateState) => {\n    // For the purpose of this function, we consider ourselves to have staging environments if we have\n    // more than one real (non-user) environment, and they point to different versions of the app.\n\n    const state = getState();\n    const { named } = getCategorisedEnvironments(state);\n\n    if (named.length < 2) {\n        return; // We can't possibly have any staging environments.\n    }\n    let lastEnv = null;\n    for (const env of named) {\n        if (lastEnv !== null && !isEqual(env.version, lastEnv.version)) {\n            // We've found at least two environments pointing to different versions of the app.\n            dispatch(claimAchievement(\"usedStagingEnvironments\"));\n            break;\n        }\n        lastEnv = env;\n    }\n};\n\nexport const checkForStagingDatabases = (): AnvilAction => (dispatch, getState, updateState) => {\n    // Similar to checkForStagingEnvironments, above, but looks for environments that point to different databases.\n    // In this case, we include user environments, not just named.\n\n    const state = getState();\n    const { all } = getCategorisedEnvironments(state);\n\n    if (all.length < 1) {\n        return; // We can't possibly have any staging databases.\n    }\n    let lastEnv = null;\n    for (const env of all) {\n        if (lastEnv !== null && env.table_mapping_id !== lastEnv.table_mapping_id) {\n            // We've found at least two environments pointing to different databases.\n            dispatch(claimAchievement(\"usedStagingDatabases\"));\n            break;\n        }\n        lastEnv = env;\n    }\n};\n\nexport const allEnvironmentSavesComplete: AnvilAction = (dispatch, getState, updateState) => {\n    const state = getState();\n    return !state.app?.$environmentsSaving;\n};\n\nconst environmentCreations = new Map<string, Set<Promise<void>>>();\n\nexport const createEnvironment =\n    (env: Partial<AppEnvironment>): AnvilAsyncAction<AppEnvironment | undefined> =>\n    async (dispatch, getState, updateState) => {\n        const appId = env.app_id || getAppId(getState());\n        if (!appId) return;\n        const saved = dispatch(markUnsaved(`create-env`));\n        const creations = environmentCreations.get(appId) || new Set<Promise<void>>();\n        let creationComplete!: () => void;\n        const creation = new Promise<void>((resolve) => { creationComplete = resolve; });\n        creations.add(creation);\n        environmentCreations.set(appId, creations);\n\n        try {\n            let newEnv!: AppEnvironment;\n            let isLegacyApp = false;\n            try {\n                newEnv = await api.createEnvironment(env);\n            } catch (e) {\n                if (!isLegacyAppError(e)) throw e;\n                isLegacyApp = true;\n            }\n\n            if (isLegacyApp) {\n                if (await dispatch(confirmAndMigrateApp())) {\n                    return await dispatch(createEnvironment(env));\n                }\n            } else {\n                updateState(({ app }) => {\n                    if (!app?.environments) return;\n                    app.environments.push(newEnv);\n                });\n                dispatch(recordActivity(\"createEnvironment\"));\n                dispatch(checkForStagingEnvironments());\n                dispatch(checkForStagingDatabases());\n                return newEnv;\n            }\n        } finally {\n            creations.delete(creation);\n            if (!creations.size) environmentCreations.delete(appId);\n            creationComplete();\n            saved();\n        }\n    };\n\nexport const createDefaultEnvironment =\n    (mergeConfig?: Partial<AppEnvironment>): AnvilAsyncAction<AppEnvironment | undefined> =>\n    async (dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n        if (!appId) return;\n\n        const newEnv: Partial<AppEnvironment> = merge(\n            {\n                app_id: appId,\n                version: { ref: \"refs/heads/master\" },\n                name: \"Default Environment\",\n                run_scheduled_tasks: true,\n                server_keys: { uplink: { default: true } },\n            },\n            mergeConfig\n        );\n\n        newEnv.version = omitBy(newEnv.version, isNil) as AppEnvironment[\"version\"];\n\n        const createdEnv = await dispatch(createEnvironment(newEnv));\n        if (createdEnv) {\n            dispatch(setSelectedEnvironmentId(createdEnv.env_id));\n        }\n        return createdEnv;\n    };\n\nexport const publishApp =\n    (version: AppEnvironment[\"version\"], force = false): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        version = { ref: null, \"commit-id\": null, ...version };\n        const state = getState();\n        const publishedEnv = getDefaultPublishedEnvironment(state);\n        if (\n            force ||\n            (await dispatch(\n                confirm(\n                    \"Publish this version of your app?\",\n                    `This version is what visitors to your app will see.${\n                        publishedEnv ? \" It will replace the currently published version.\" : \"\"\n                    }`\n                )\n            ))\n        ) {\n            if (publishedEnv) {\n                await dispatch(saveEnvironment(publishedEnv, { version }));\n            } else {\n                const newEnv = await dispatch(\n                    createDefaultEnvironment({\n                        name: \"Published\",\n                        url: await dispatch(getNewEnvironmentURL(\"public\")),\n                        version: version,\n                        tags: [\"default_published\"],\n                    })\n                );\n            }\n            dispatch(claimAchievement(\"publishedApp\"));\n            dispatch(recordActivity(\"publishApp\", { version }));\n            return true;\n        } else {\n            return false;\n        }\n    };\n\nexport const deleteEnvironment =\n    (env: AppEnvironment): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const saved = dispatch(markUnsaved(`delete-env-${env.env_id}`));\n\n        let isLegacyApp = false;\n        try {\n            await api.deleteEnvironment(env);\n        } catch (e) {\n            if (!isLegacyAppError(e)) {\n                saved();\n                throw e;\n            }\n            isLegacyApp = true;\n        }\n\n        if (isLegacyApp) {\n            const migratedEnv = await dispatch(confirmAndMigrateApp());\n            if (migratedEnv) {\n                saved();\n                await dispatch(deleteEnvironment(migratedEnv));\n                return;\n            }\n        } else {\n            updateState(({ app }) => {\n                if (!app?.environments) return;\n                remove(app.environments, (e) => e.env_id === env.env_id);\n            });\n            dispatch(recordActivity(\"deleteEnvironment\"));\n        }\n\n        saved();\n    };\n\nexport const getNewEnvironmentURL =\n    (type: \"private\" | \"public\" | \"custom\"): AnvilAsyncAction<AppEnvironment[\"url\"]> =>\n    async (dispatch, getState) => {\n        switch (type) {\n            case \"private\":\n                return { access_key: await api.generateNewAppAccessKey() };\n            case \"public\":\n                return { alias: await api.generateNewAppAlias(getAppId(getState())) };\n            case \"custom\":\n                return { domain: \"\" };\n        }\n    };\n\nexport const getCustomDomainStatus =\n    (domain?: string | null): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n\n        const resp = await api.getCustomDomainStatus(appId, domain);\n\n        return resp.status;\n    };\n\nexport const enableEnvironmentUplink =\n    (env: AppEnvironment, type: \"server\" | \"client\" | \"db_read\"): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = getAppId(state);\n\n        let firstEnvWithServerKey = true;\n        for (const e of getEnvironments(state) || []) {\n            if (e.server_keys?.uplink?.server_key) {\n                firstEnvWithServerKey = false;\n                break;\n            }\n        }\n\n        const { server_keys } = env;\n        const s = server_keys ? cloneDeep(server_keys) : {};\n\n        if (s?.uplink) {\n            s.uplink[`${type}_key`] = type + \"_\" + (await api.generateNewUplinkKey(appId));\n        } else {\n            s.uplink = { [`${type}_key`]: type + \"_\" + (await api.generateNewUplinkKey(appId)) };\n        }\n\n        if (type === \"server\" && firstEnvWithServerKey) {\n            // This is the first environment to have a server Uplink key. Let other environments share it by default.\n            s.uplink.default = true;\n        }\n\n        if (env) {\n            await dispatch(saveEnvironment(env, { server_keys: s }));\n        } else {\n            dispatch(createEnvironment({ app_id: appId, branch: \"master\", server_keys: s }));\n        }\n        dispatch(claimAchievement(\"enabledUplink\"));\n    };\n\nexport const disableEnvironmentUplink =\n    (env: AppEnvironment, type: \"server\" | \"client\" | \"db_read\"): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const server_keys = cloneDeep(env.server_keys);\n        if (!server_keys?.uplink) return;\n        server_keys.uplink[`${type}_key`] = null;\n        await dispatch(saveEnvironment(env, { server_keys }));\n    };\n\nexport const resetEnvironmentUplinkKey =\n    (env: AppEnvironment, type: \"server\" | \"client\" | \"db_read\"): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const { server_keys } = env;\n        const s = cloneDeep(server_keys);\n        if (!s?.uplink) return;\n        s.uplink[`${type}_key`] = type + \"_\" + (await api.generateNewUplinkKey(env.app_id));\n        await dispatch(saveEnvironment(env, { server_keys: s }));\n    };\n\nexport const setEnvironmentBreakpoints =\n    (env: AppEnvironment, breakpoints: ModuleBreakpoints[]): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        await dispatch(\n            saveEnvironment(env, {\n                debugger: {\n                    ...env[\"debugger\"],\n                    breakpoints,\n                },\n            })\n        );\n    };\n\nexport const hasUplinkKeys = (env?: AppEnvironment) => {\n    return env?.server_keys?.uplink?.server_key || env?.server_keys?.uplink?.client_key;\n};\n\nexport const hasServerKeys = (env?: AppEnvironment) => {\n    return hasUplinkKeys(env); // TODO: Downlinks?\n};\n\nexport const setCurrentTableMapping =\n    (mapping: TableMapping): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const debugEnvironment = getCategorisedEnvironments(state).debug;\n        await dispatch(saveEnvironment(debugEnvironment, { table_mapping_id: mapping.table_mapping_id }));\n        dispatch(invalidateTableSchema(mapping.table_mapping_id));\n        dispatch(updateAppSchemaSync());\n    };\n\nexport const ingestEnvUpdate = (e: WebsocketEvent): AnvilAsyncAction => async (dispatch, getState, updateState) => {\n    const appId = getAppId(getState());\n    if (!appId) return;\n    const isKnown = () => getEnvironments(getState())?.some((env) => env.env_pid === e.env_pid);\n    if (!isKnown()) {\n        // Our creation broadcast can arrive before the HTTP response adds the environment.\n        await Promise.all(environmentCreations.get(appId) || []);\n        if (getAppId(getState()) !== appId) return;\n        if (!isKnown()) {\n            await dispatch(loadEnvironments(appId));\n            if (getAppId(getState()) !== appId) return;\n        }\n    }\n    updateState(({app}) => {\n        for (const env of app?.environments || []) {\n            if (env.env_pid === e.env_pid) {\n                env.version = e.version;\n                env.table_mapping_id = e.table_mapping_id;\n            }\n        }\n    });\n};\n\nexport const useEnvironmentWebsocketEventListener = (appId: AppId | null | undefined) => {\n    const dispatch: AnvilDispatch = useDispatch();\n    useWebsocketEventListener(appId, (e) => {\n        if (e.event === \"ENV_UPDATE\") {\n            dispatch(ingestEnvUpdate(e));\n        }\n    });\n}\n","import { parseModule, scan } from \"@anvil-works/skulpt-parser/core\";\nimport type { CompatibilityModule, ParseOptions, expr } from \"@anvil-works/skulpt-parser/core\";\n\nexport type AutocompleteModule = CompatibilityModule;\nexport type AutocompleteExpr = expr;\nexport type IdentifierRange = { line: number; startCol: number; endCol: number };\nconst attributeRanges = new WeakMap<object, IdentifierRange>();\n\n/** Source spelling can have a different width from the AST's normalized identifier. */\nexport function attributeNameRange(node: Extract<AutocompleteExpr, { _type: \"Attribute\" }>) {\n    return attributeRanges.get(node);\n}\n\n// Keep the actual parsed source, including autocomplete repairs, for syntax that\n// the AST erases (such as f-string debug markers and quote delimiters).\nconst moduleSources = new WeakMap<object, string>();\n\n/** Parse the native AST and translate source positions to IDE coordinates. */\nexport function parseAutocompleteModule(\n    source: string,\n    options: Pick<ParseOptions, \"asyncAwaitAsIdentifiers\" | \"pythonVersion\" | \"featureVersion\"> = {}\n): AutocompleteModule {\n    const lines = source.split(/\\r\\n?|\\n/);\n    const encodedLines = new Map<number, Uint8Array>();\n    const encoder = new TextEncoder();\n    const decoder = new TextDecoder();\n    function column(line: number, byte: number) {\n        const text = lines[line - 1] ?? \"\";\n        if (!/[^\\x00-\\x7f]/.test(text)) return byte;\n        let encoded = encodedLines.get(line);\n        if (!encoded) encodedLines.set(line, (encoded = encoder.encode(text)));\n        return decoder.decode(encoded.subarray(0, byte)).length;\n    }\n\n    function normalizePositions(node: any): void {\n        if (!node || typeof node !== \"object\") return;\n        if (Array.isArray(node)) {\n            for (const child of node) normalizePositions(child);\n            return;\n        }\n        // Constants contain scalar payloads, including byte arrays, rather than AST children.\n        if (node._type !== \"Constant\") {\n            for (const key in node) normalizePositions(node[key]);\n        }\n        if (node.lineno !== undefined) {\n            node.col_offset = column(node.lineno, node.col_offset);\n            node.end_col_offset = column(node.end_lineno, node.end_col_offset);\n            if (node._type === \"Attribute\") {\n                const line = lines[node.end_lineno - 1];\n                // The range ends at the final NAME token. Its source spelling follows\n                // a dot, whitespace, or the start of a continued line.\n                const spelling = /[^\\s.]+$/u.exec(line.slice(0, node.end_col_offset))![0];\n                attributeRanges.set(node, {\n                    line: node.end_lineno,\n                    startCol: node.end_col_offset - spelling.length,\n                    endCol: node.end_col_offset,\n                });\n            }\n            // Keep the IDE's existing navigation target for decorated definitions.\n            node.lineno = node.decorator_list?.[0]?.lineno ?? node.lineno;\n        }\n    }\n    const ast = parseModule(source, { filename: \"input.py\", ...options });\n    normalizePositions(ast);\n    moduleSources.set(ast, source);\n    return ast;\n}\n\n/** Diagnose rejected client syntax without changing its legacy-name interpretation. */\nexport function unsupportedClientAsync(source: string, errorLine: number) {\n    let ast;\n    try {\n        ast = parseModule(source, { filename: \"input.py\" });\n    } catch (error) {\n        // Malformed modern syntax should retain the original parser diagnostic.\n        if (\n            error instanceof Error &&\n            [\"SyntaxError\", \"IndentationError\", \"TabError\", \"UnicodeNameDatabaseRequired\"].includes(error.name)\n        )\n            return;\n        throw error;\n    }\n    // A legacy-name parse can fail on the token after a continued async/await.\n    // Extend only across explicit continuations, not the async statement's body.\n    const lines = source.split(/\\r\\n?|\\n/);\n    let firstErrorLine = errorLine;\n    while (firstErrorLine > 1 && lines[firstErrorLine - 2]?.endsWith(\"\\\\\")) firstErrorLine--;\n\n    function find(node: any): number | undefined {\n        if (!node || typeof node !== \"object\" || node._type === \"Constant\") return;\n        if (\n            node.lineno >= firstErrorLine &&\n            node.lineno <= errorLine &&\n            [\"AsyncFunctionDef\", \"AsyncFor\", \"AsyncWith\", \"Await\"].includes(node._type)\n        )\n            return node.lineno;\n        // Comprehension clauses have no source range. Report the enclosing expression.\n        if (\n            [\"ListComp\", \"SetComp\", \"DictComp\", \"GeneratorExp\"].includes(node._type) &&\n            node.lineno <= errorLine &&\n            node.end_lineno >= errorLine &&\n            node.generators.some((generator: any) => generator.is_async)\n        )\n            return node.lineno;\n        for (const child of Object.values(node)) {\n            const line = find(child);\n            if (line !== undefined) return line;\n        }\n    }\n    const line = find(ast);\n    return line === undefined\n        ? undefined\n        : { line, message: \"Async/await syntax is not supported in Anvil client code.\" };\n}\n\n/** IDE policy for syntax the current client compiler cannot implement yet. */\nexport function unsupportedClientSyntax(ast: ReturnType<typeof parseAutocompleteModule>) {\n    // The parser accepts newer syntax than the deployed client compiler. Remove each check as support lands.\n    const messages: Record<string, string> = {\n        NamedExpr: \"Assignment expressions (:=) are not supported in Anvil client code.\",\n        Match: \"Match statements are not supported in Anvil client code.\",\n        TryStar: \"Exception groups (except*) are not supported in Anvil client code.\",\n        TypeAlias: \"Type alias statements are not supported in Anvil client code.\",\n        TemplateStr: \"Template strings are not supported in Anvil client code.\",\n    };\n    const warnings: { line: number; message: string }[] = [];\n    let checkedStrings = false;\n    function dottedName(node: any): boolean {\n        return node._type === \"Name\" || (node._type === \"Attribute\" && dottedName(node.value));\n    }\n    function visit(node: any): void {\n        if (!node || typeof node !== \"object\" || node._type === \"Constant\") return;\n        if (node._type === \"JoinedStr\" && !checkedStrings) {\n            checkedStrings = true;\n            const source = moduleSources.get(ast);\n            if (source !== undefined) warnings.push(...unsupportedClientFStrings(source));\n        }\n        for (const decorator of node.decorator_list ?? []) {\n            const target = decorator._type === \"Call\" ? decorator.func : decorator;\n            if (!dottedName(target))\n                warnings.push({\n                    line: decorator.lineno,\n                    message:\n                        \"Decorator expressions other than dotted names or calls are not supported in Anvil client code.\",\n                });\n        }\n        if (messages[node._type]) warnings.push({ line: node.lineno, message: messages[node._type] });\n        if ([\"FunctionDef\", \"ClassDef\"].includes(node._type) && node.type_params.length) {\n            warnings.push({\n                line: node.type_params[0].lineno,\n                message: \"Type parameters are not supported in Anvil client code.\",\n            });\n        }\n        if (node._type === \"arguments\" && node.posonlyargs.length) {\n            warnings.push({\n                line: node.posonlyargs[0].lineno,\n                message: \"Positional-only parameters are not supported in Anvil client code.\",\n            });\n        }\n        for (const child of Object.values(node)) visit(child);\n    }\n    visit(ast);\n    return warnings;\n}\n\n/** Token spelling distinguishes newer f-string syntax from the same older AST nodes. */\nfunction unsupportedClientFStrings(source: string) {\n    const warnings: { line: number; message: string }[] = [];\n    const frames: { quote: string; line: number; brackets: string[]; unsupported: boolean }[] = [];\n    // Scan spelling without imposing an app grammar, including legacy string prefixes.\n    for (const token of scan(source, { extraTokens: true, pythonVersion: 2 })) {\n        if (token.type === \"FSTRING_START\") {\n            for (const frame of frames) {\n                if (token.string.includes(frame.quote)) frame.unsupported = true;\n            }\n            frames.push({\n                quote: token.string.replace(/^[fFrR]+/, \"\"),\n                line: token.start[0],\n                brackets: [],\n                unsupported: false,\n            });\n        } else if (token.type === \"FSTRING_END\") {\n            const frame = frames.pop()!;\n            if (frame.unsupported)\n                warnings.push({\n                    line: frame.line,\n                    message: \"Debug expressions or newer quoting in f-strings are not supported in Anvil client code.\",\n                });\n        } else if (frames.length) {\n            const frame = frames[frames.length - 1];\n            if (token.type === \"STRING\") {\n                for (const enclosing of frames) {\n                    if (token.string.includes(enclosing.quote)) enclosing.unsupported = true;\n                }\n            }\n            if (token.type === \"OP\") {\n                if (token.string === \"=\" && frame.brackets.at(-1) === \"{\") frame.unsupported = true;\n                if ([\"{\", \"(\", \"[\"].includes(token.string)) frame.brackets.push(token.string);\n                else if ([\"}\", \")\", \"]\"].includes(token.string)) frame.brackets.pop();\n            }\n        }\n    }\n    return warnings;\n}\n","import { useEffect, useRef } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { EditorView, ViewUpdate } from \"@codemirror/view\";\nimport { updateUiPrefs } from \"@/api\";\nimport { useExtension } from \"@/code_mirror/utils/hooks\";\nimport { tracker } from \"@/components/IDE\";\nimport { missingFormClasses } from \"@/components/tabs/code/NewFormEditor\";\nimport { analyseItem } from \"@/controllers/app/autocompleter\";\nimport { getAppCommitHistory, updateAppCommitHistory } from \"@/controllers/app/history\";\nimport { openOrFocusBottomTab, setBottomPanelHeight } from \"@/controllers/bottom-tabs\";\nimport { modalIfNotAlreadyOpen } from \"@/controllers/modals\";\nimport { getUserHasAchievement, getUserUiPrefs, getUserUiScale, useAbFlag } from \"@/controllers/user\";\nimport { navigate } from \"@/router/navigation\";\nimport { remToPixelMultiplier } from \"@/theme/ThemeProvider\";\nimport { AnvilAsyncAction, AnvilDispatch, State } from \"@/types\";\nimport { CodeItemType, CodeItemYaml, CodePath } from \"@/types\";\nimport { User } from \"@/types/user\";\nimport { ExternalStore } from \"@/util/external-store\";\nimport { useStoreState } from \"@/util/external-store\";\nimport { useAppsInfiniteQuery, useDebounceFn } from \"@/util/hooks\";\nimport { USER_AB_FLAGS, getAbIdeTutorial } from \"@/util/hooks/ab-flags\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { createApp, getAppEditState, getAppId, resetBranch } from \"./app\";\nimport { getUser } from \"./ide\";\nimport { findTutorialPropertyAssignments } from \"./tutorial-property-assignments\";\n\ninterface IdeTutorialProgressProps {\n    lastCompletedStep: tutorialStepKeys | null;\n    steps: Partial<Record<tutorialStepKeys, boolean>>;\n}\n\nexport const ideTutorialProgress = new ExternalStore<IdeTutorialProgressProps>({\n    lastCompletedStep: null,\n    steps: {},\n});\n// Experiment: Drop the user into tutorial mode and drop them into a tutorial app\n\nconst isRecent = (regDate: User[\"registrationDate\"]) => new Date(regDate) > new Date(\"2025-06-20T18:15Z\");\n\nconst TUTORIAL_APP = {\n    name: \"Tutorial App\",\n    img: \"/ide/img/app_templates/feedback_form.png\",\n    url: \"/ide/app_templates/202506_tutorial\",\n    // Using a clone key for an app that exists on localhost to test cloning\n    // cloneKey: \"UXMLBR7GWIR6ED2R=ZLMN6XVD4TKSGIQ6VQJ7PCRK\",\n    description: \"A blank app.\",\n};\n\nexport const getInTutorialMode = (state: State) =>\n    getAbIdeTutorial(state) && !getUserHasAchievement(state, \"handledFormEvent\");\nexport const getTutorialAppId = (state: State) => getUserUiPrefs(state)?.tutorialAppId;\n\nconst createTutorialApp = (): AnvilAsyncAction => async (dispatch, getState, updateState) => {\n    await dispatch(createApp(TUTORIAL_APP));\n    const appId = getAppId(getState());\n    updateState(({ user: { uiPrefs } }) => {\n        uiPrefs.tutorialAppId = appId;\n    });\n    await updateUiPrefs([\"tutorialAppId\"], appId);\n};\n\nexport const setBottomPanelHeightForTutorial = (): AnvilAsyncAction => async (dispatch, getState, updateState) => {\n    const scale = getUserUiScale(getState());\n    const px = remToPixelMultiplier(32, scale);\n    dispatch(setBottomPanelHeight(px));\n};\n\nexport const resetTutorialProgress = (): AnvilAsyncAction => async (dispatch, getState, updateState) => {\n    dispatch(setBottomPanelHeightForTutorial());\n    ideTutorialProgress.resetState({ lastCompletedStep: null, steps: {} });\n};\n\nexport const resetTutorial = (): AnvilAsyncAction => async (dispatch, getState, updateState) => {\n    await dispatch(updateAppCommitHistory(9999 as any)); // Ew. But whatever.\n    const state = getState();\n    const editState = getAppEditState(state);\n    const commitHistory = getAppCommitHistory(state);\n\n    const tutorialAppId = getTutorialAppId(state);\n\n    if (!commitHistory?.versions.length) return;\n    const firstCommitId = commitHistory.versions[commitHistory.versions.length - 1].v;\n    await dispatch(resetBranch(editState?.branch || \"master\", firstCommitId));\n    dispatch(\n        navigate({ appId: tutorialAppId, codePath: \"forms/Form1\", view: { design: true, code: true }, type: \"CODE\" })\n    );\n    missingFormClasses.resetState({});\n\n    dispatch(resetTutorialProgress());\n};\n\nexport const useMaybeStartIdeTutorial = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const user = useSelector(getUser);\n    // Enrollment closed: pass [] so no new users are bucketed into IDE Tutorial AB test.\n    // Existing `true` users keep the tutorial until they earn the `handledFormEvent` achievement.\n    // If turning this flag back on, change isRecent so that only new users get a flag set\n    // const flag = useAbFlag(\n    //     USER_AB_FLAGS.ideTutorial,\n    //     user && !user.plan?.[\"paid-plan\"] && isRecent(user.registrationDate) ? [false, true] : []\n    // );\n    const flag = useAbFlag(USER_AB_FLAGS.ideTutorial, []);\n    if (flag !== undefined) {\n        tracker?.setMetadata(\"IDE-Tutorial\", `${flag}`);\n    }\n    const inTutorialMode = useSelector(getInTutorialMode);\n    const tutorialAppId = useSelector(getTutorialAppId);\n    const tutorialAppQuery = useAppsInfiniteQuery({\n        initialQuery: tutorialAppId || \"\",\n        includePySpace: true,\n        pageSize: 20,\n        debounceMs: 1,\n        enabled: !!user && !!tutorialAppId && inTutorialMode,\n    });\n\n    useEffect(() => {\n        tutorialAppQuery.setQuery(tutorialAppId || \"\");\n    }, [tutorialAppId, tutorialAppQuery.setQuery]);\n\n    useEffect(() => {\n        if (!!user && inTutorialMode) {\n            if (tutorialAppId && tutorialAppQuery.isLoading) return;\n            const existingTutorialApp = tutorialAppQuery.apps.find((app) => app.id === tutorialAppId);\n            if (!tutorialAppId || !existingTutorialApp) {\n                dispatch(createTutorialApp());\n                dispatch(dispatchIDETutorialModalThenFocusBottomPanelOnQuit());\n            } else {\n                dispatch(navigate({ type: \"APP_ROOT\", appId: tutorialAppId }));\n                dispatch(dispatchIDETutorialModalThenFocusBottomPanelOnQuit());\n            }\n        }\n    }, [!!user, inTutorialMode, tutorialAppId, tutorialAppQuery.isLoading, tutorialAppQuery.apps.length]);\n};\n\nexport const dispatchIDETutorialModalThenFocusBottomPanelOnQuit =\n    (): AnvilAsyncAction => async (dispatch, getState, updateState) => {\n        await dispatch(modalIfNotAlreadyOpen(\"ideTutorialIntro\", {}));\n        dispatch(openOrFocusBottomTab({ type: \"ideTutorial\" }));\n    };\n\nexport type tutorialStepKeys = \"add-component\" | \"add-event-handler\" | \"change-text\";\n\nexport const markTutorialStepIfInTutorial =\n    (step: tutorialStepKeys | null): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const inTutorialMode = getInTutorialMode(getState());\n        if (!inTutorialMode) return;\n        ideTutorialProgress.updateState((s) => {\n            if (!step) return;\n            if (!s.steps[step]) {\n                s.steps[step] = true;\n                s.lastCompletedStep = step;\n            }\n        });\n    };\n\nexport function useDetectTutorialModeCode(\n    view: EditorView,\n    opts: { selected: boolean; codePath: CodePath; codeItem: CodeItemYaml; itemType: CodeItemType }\n) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const inTutorialMode = useSelector(getInTutorialMode);\n    const { steps: tutorialStepsDone } = useStoreState(ideTutorialProgress);\n\n    const enabled =\n        inTutorialMode && opts.selected && opts.codePath === \"forms/Form1\" && !tutorialStepsDone[\"change-text\"];\n\n    const isValidComponentPropertyAtPos = useEvent(async (lineNo: number, col: number, propName: string) => {\n        const code = view.state.doc.toString();\n        const line = view.state.doc.line(lineNo + 1); // CodeMirror lines are 1-based\n        const pos = line.from + col;\n\n        const analysis: any = await dispatch(\n            analyseItem(\n                { ...opts.codeItem, code },\n                opts.itemType,\n                true,\n                lineNo,\n                col,\n                pos,\n                \"\" // seed/identifier; empty is fine right after dot\n            )\n        );\n\n        const completions = analysis?.completions ?? [];\n        return completions.some((c: any) => c?.text === propName);\n    });\n\n    const debounceRunId = useRef(0);\n    const debouncedRun = useDebounceFn(async (code: string) => {\n        const runId = ++debounceRunId.current;\n        try {\n            const hits = findTutorialPropertyAssignments(code);\n            if (!hits.length) return;\n            const valid = await Promise.all(\n                hits.map((hit) => isValidComponentPropertyAtPos(hit.lineNo, hit.col, hit.propName))\n            );\n            if (debounceRunId.current !== runId || tutorialStepsDone[\"change-text\"]) return;\n            if (valid.some(Boolean)) dispatch(markTutorialStepIfInTutorial(\"change-text\"));\n        } catch {\n            // Partially typed code need not parse or provide completions yet.\n        }\n    }, 400);\n\n    const onUpdate = useEvent((update: ViewUpdate) => {\n        if (!update.docChanged) return;\n        debouncedRun(update.state.doc.toString());\n    });\n\n    useExtension(view, () => (enabled ? EditorView.updateListener.of(onUpdate) : []), [enabled]);\n}\n","import { attributeNameRange, parseAutocompleteModule } from \"../workers/autocompleter/parser-ast\";\nimport type { AutocompleteModule } from \"../workers/autocompleter/parser-ast\";\n\nexport type TutorialPropHit = { componentName: string; propName: string; lineNo: number; col: number };\n\n/** Find candidate tutorial property changes; the IDE still validates the property with autocomplete. */\nexport function findTutorialPropertyAssignments(source: string): TutorialPropHit[] {\n    const ast = parseAutocompleteModule(source, { asyncAwaitAsIdentifiers: true });\n    const hits: TutorialPropHit[] = [];\n\n    function walk(node: AutocompleteModule[\"body\"][number], inEventHandler: boolean): void {\n        if (node._type === \"FunctionDef\") {\n            const nextInHandler = inEventHandler || node.args.kwarg?.arg === \"event_args\";\n            for (const statement of node.body) walk(statement, nextInHandler);\n            return;\n        }\n        if (inEventHandler && node._type === \"Assign\") {\n            for (const target of node.targets) {\n                if (target._type !== \"Attribute\") continue;\n                const inner = target.value;\n                if (inner._type !== \"Attribute\" || inner.value._type !== \"Name\" || inner.value.id !== \"self\") continue;\n                const range = attributeNameRange(target)!;\n                hits.push({\n                    componentName: inner.attr,\n                    propName: target.attr,\n                    lineNo: range.line - 1,\n                    col: range.startCol,\n                });\n            }\n        }\n        if (\"body\" in node) for (const child of node.body) walk(child, inEventHandler);\n        if (\"orelse\" in node) for (const child of node.orelse) walk(child, inEventHandler);\n        if (\"finalbody\" in node) for (const child of node.finalbody) walk(child, inEventHandler);\n        if (node._type === \"Try\" || node._type === \"TryStar\")\n            for (const handler of node.handlers) for (const child of handler.body) walk(child, inEventHandler);\n        if (node._type === \"Match\")\n            for (const item of node.cases) for (const child of item.body) walk(child, inEventHandler);\n    }\n    for (const statement of ast.body) walk(statement, false);\n    return hits;\n}\n","import { useDispatch } from \"react-redux\";\nimport { createSelector } from \"reselect\";\nimport { WebsocketEvent, useWebsocketEventListener } from \"@/controllers/websocket\";\nimport { AnvilAction, AnvilAsyncAction, AnvilDispatch, AppId, State } from \"@/types\";\nimport { sleep } from \"@/util\";\nimport defer, { Deferred } from \"@/util/defer\";\n\nconst taskPromises: { [taskId: string]: Deferred<IDETask> } = {};\n\nexport interface IDETask {\n    id: number;\n    type: \"docker-export\" | \"git-sync\"; // | \"...\" | \"...\", etc, as we add new types\n    state: any;\n    start_time: string; // ISO-date\n    completed: string | null; // ISO-date\n    succeeded: boolean | null;\n    failed: boolean | null;\n    error: string | null;\n}\n\nconst augmentTask = (task: IDETask) => ({\n    ...task,\n    succeeded: task.completed ? !task.error : null,\n    failed: task.completed ? !!task.error : null,\n});\n\nexport const addTaskIfMissing =\n    (task: IDETask): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const t = augmentTask(task);\n        updateState(({ ideTasks }) => {\n            if (!(t.id in ideTasks)) {\n                ideTasks[t.id] = t;\n            }\n        });\n    };\n\nconst ideTaskUpdate =\n    (e: WebsocketEvent): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        switch (e.event) {\n            case \"IDE_TASK_UPDATE\": {\n                const task = augmentTask(e.task);\n                updateState(({ ideTasks }) => {\n                    ideTasks[task.id] = task;\n                });\n                taskPromises[task.id]?.resolve(task);\n                taskPromises[task.id] = defer<IDETask>();\n                break;\n            }\n        }\n    };\n\nexport const useIdeTaskWebsocketListener = (appId?: AppId) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    useWebsocketEventListener(appId, (e) => dispatch(ideTaskUpdate(e)));\n};\n\nexport const watchIDETask =\n    (taskId: number, onUpdate: (task: IDETask) => void): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        let task: IDETask | null = null;\n        const start = Date.now();\n\n        // Give the task up to 30 sec to appear, before we declare it invalid.\n        while (Date.now() - start < 30000) {\n            task = getState().ideTasks[taskId];\n            if (task) break;\n            await sleep(500);\n        }\n\n        if (task) {\n            // eslint-disable-next-line no-constant-condition\n            while (true) {\n                console.log(\"Task updated:\", task);\n                onUpdate?.(task);\n                if (task.completed) break;\n                task = await taskPromises[taskId].promise;\n            }\n        } else {\n            console.warn(\"No IDE task to watch: \", taskId);\n        }\n    };\n\nexport const getIDETasks = (state: State) => state.ideTasks as { [taskId: string]: IDETask };\n\nexport const getGitSyncTask = createSelector([getIDETasks], (tasks) =>\n    Object.values(tasks ?? {}).find((t) => t.type === \"git-sync\" && !t.completed)\n);\n","// Helpers for interpreting the watch-key-tagged log-event firehose (script runs and\n// runner-launched background tasks). Leaf module - no heavy imports - so the logic stays\n// unit-testable from controller tests.\n\n/** The script name from a watch-key-tagged SESSION_START event, or null if the event is\n *  not a script run. Watch-key-tagged events also cover runner-launched background tasks\n *  (\"task:<name>\"), which reach any websocket subscribed with log_events: true (e.g. the\n *  pyspace gadget editor) - a task named \"task:send_emails\" must not masquerade as a\n *  script run named \"mails\". */\nexport const scriptNameFromSessionStart = (e: any): string | null =>\n    e?.data?.func?.startsWith(\"task:script:\") ? e.data.func.substring(12) : null;\n\n/** Insert a log-firehose event into an output array ordered by its seq.\n *\n *  The server stamps each session's log events with a monotonic seq at record time, but\n *  broadcasts them asynchronously, so arrival order isn't emission order. Walks back from\n *  the end (arrivals are nearly in order); events without a seq are appended. */\nexport function insertLogEventBySeq(output: any[], event: any) {\n    let i = output.length;\n    if (typeof event.seq === \"number\") {\n        while (i > 0 && typeof output[i - 1].seq === \"number\" && output[i - 1].seq > event.seq) {\n            i--;\n        }\n    }\n    output.splice(i, 0, event);\n}\n","import { ComponentProps } from \"react\";\nimport type { ModalComponent, ModalId, ModalTypes } from \"@/components/modals\";\nimport type { ModalButtonProps } from \"@/components/modals/Modal\";\nimport type { IDEModalTypes } from \"@/components/modals/names/ide-modals\";\nimport type { ManagerModalTypes } from \"@/components/modals/names/manager-modals\";\nimport { recordActivity } from \"@/controllers/util\";\nimport type { PySpaceModalTypes } from \"@/pyspace/gadget_editor/modals/names/pyspace-gadget-editor-modals\";\nimport { SiteModalTypes } from \"@/pyspace/site/modals/names/pyspace-site-modals\";\nimport { ModalAction, ModalAsyncAction, ModalState } from \"@/store/modal-store\";\nimport defer from \"@/util/defer\";\n\nconst callbacks: any[] = [];\nlet nextModalId = 0;\n\ninterface AllModals extends IDEModalTypes, ManagerModalTypes, PySpaceModalTypes, SiteModalTypes {}\ntype ModalType = Extract<keyof AllModals, string>;\n\ninterface ModalPropsCache {\n    type: ModalType;\n    modalId: ModalId;\n    spec: any;\n}\n// don't put the modalSpec in the state - this becomes a readonly object\nexport const modalPropsCache = new Map<number, ModalPropsCache>();\n\nconst LOG_MODALS = [\n    \"upgradePrompt\",\n    \"upgradePromptOnOpenApp\",\n    \"configureOrUpgradePromptOnRuntimeFeatureRequired\",\n    \"upgrade\",\n    \"upgradeSuccessful\",\n    \"gitDesync\",\n];\n\ntype InferSpec<C extends ModalComponent<never, any, any>> = ComponentProps<C>[\"spec\"] extends never\n    ? Record<string, never>\n    : ComponentProps<C>[\"spec\"];\n\ntype ModalReturnType<C extends ModalComponent<never, any, any>> = C[\"returnType\"];\n\ntype ModalMaker<MT extends ModalTypes> = <T extends Extract<keyof MT, string>>(\n    type: T,\n    modalSpec: InferSpec<MT[T]>\n) => ModalAsyncAction<MT[T][\"returnType\"] | undefined>;\n\nexport const modal =\n    <T extends ModalType>(\n        type: T,\n        spec: InferSpec<AllModals[T]>\n    ): ModalAsyncAction<ModalReturnType<AllModals[T]> | undefined> =>\n    (dispatch, _getState, updateState) => {\n        const modalPromise = defer<ModalReturnType<AllModals[T]> | undefined>();\n\n        const modalId = ++nextModalId;\n\n        if (LOG_MODALS.includes(type)) {\n            dispatch(recordActivity(\"modal:\" + type, spec) as ModalAction);\n        }\n\n        callbacks.push({\n            modalId,\n            onResult: modalPromise.resolve,\n            // We are ignoring why it was cancelled for now. We might choose to expose this later.\n            onCancel: (why: any) => modalPromise.resolve(undefined),\n        });\n        updateState(({ modals }) => {\n            modals.push(nextModalId);\n            modalPropsCache.set(nextModalId, { modalId, type, spec });\n        });\n\n        return modalPromise.promise;\n    };\n\n// Idea for modals but probably not worth it\n// might be better to use declarations\nexport const ideModal: ModalMaker<IDEModalTypes> = (type, modalSpec) => modal(type, modalSpec as any);\nexport const pySpaceModal: ModalMaker<PySpaceModalTypes> = (type, modalSpec) => modal(type, modalSpec as any);\nexport const managerModal: ModalMaker<ManagerModalTypes> = (type, modalSpec) => modal(type, modalSpec as any);\n\nexport const modalReturn =\n    (result: any): ModalAction<void> =>\n    (dispatch, getState, updateState) => {\n        callbacks.pop()?.onResult?.(result);\n    };\n\nexport class ModalCancel extends Error {\n    constructor(readonly cancelMethod: string) {\n        super();\n    }\n}\n\nexport const modalCancel =\n    (cancelMethod: string): ModalAction<void> =>\n    (dispatch, getState, updateState) => {\n        callbacks.pop()?.onCancel?.(new ModalCancel(cancelMethod));\n    };\n\nexport const ensureModalCancelled =\n    (modalId: number, cancelMethod: string): ModalAction<void> =>\n    (dispatch) => {\n        const idx = callbacks.findIndex((c) => c.modalId === modalId);\n        if (idx !== -1) {\n            callbacks[idx].onCancel(cancelMethod);\n            callbacks.splice(idx, 1);\n        }\n    };\n\nexport const modalRemove =\n    (id: number): ModalAction<void> =>\n    (dispatch, getState, updateState) => {\n        updateState((state) => {\n            state.modals = state.modals.filter((modalId: number) => modalId !== id);\n            modalPropsCache.delete(id);\n        });\n    };\n\nexport const getModals = (state: ModalState) => state.modals;\nexport const hasModals = (state: ModalState) => state.modals.length > 0;\n\ntype AlertOpts = Omit<ComponentProps<AllModals[\"alert\"]>[\"spec\"], \"title\" | \"text\">;\n\nexport const alert = (title: string, text: React.ReactNode, opts: AlertOpts = {}) =>\n    modal(\"alert\", { title, text, ...opts });\n\nexport const confirm = (\n    title: React.ReactNode,\n    text: React.ReactNode,\n    ok: string | Partial<ModalButtonProps> = \"Yes\",\n    cancel: string | Partial<ModalButtonProps> = \"No\"\n) => modal(\"confirm\", { title, text, ok, cancel });\n\n/** for dangerous actions */\nexport const confirmWithCheckBox = (\n    title: string,\n    text: React.ReactNode,\n    confirmMessage: string,\n    ok = \"Yes\",\n    cancel = \"No\"\n) => modal(\"confirmWithCheckBox\", { title, text, confirmMessage, ok, cancel });\n\nexport const prompt = (title: string, text?: React.ReactNode, initialValue?: string, ok = \"OK\", cancel = \"Cancel\") =>\n    modal(\"prompt\", { title, text, initialValue, ok, cancel });\n\nexport const notImplementedAlert = (feature: string) =>\n    alert(\"Not Implemented\", `${feature} is not implemented yet. Watch this space!`);\n\n// These should be moved into IDE-specific places\n\nexport const deleteAppModal = (appName: string | null = null) => modal(\"deleteapp\", { appName });\n\nexport const updatePayment = (errMsg: string | null = null, subscription: any) =>\n    modal(\"updatePaymentCard\", { errMsg, subscription });\n\nexport const modalIfNotAlreadyOpen =\n    <T extends ModalType>(\n        type: T,\n        spec: InferSpec<AllModals[T]>\n    ): ModalAsyncAction<ModalReturnType<AllModals[T]> | undefined> =>\n    (dispatch, getState, updateState) => {\n        if ([...modalPropsCache.values()].some((p) => p.type === type)) {\n            return Promise.resolve(undefined);\n        }\n        return modal(type, spec)(dispatch, getState, updateState);\n    };","import { markAppPathUnsaved } from \"@/controllers/app\";\nimport { AnvilAsyncAction, State } from \"@/types\";\nimport { encodeAssetContent } from \"@/util/asset-content\";\nimport { getAppExtraFiles } from \"./app\";\n\nexport type LicenceId = \"mit\" | \"lgpl\" | \"gpl\" | \"none\";\nexport type LicenceSelection = { private: true } | { private: false; licence: LicenceId };\n\nexport const licenceDescriptions: { id: LicenceId; name: string; description: string }[] = [\n    {\n        id: \"mit\",\n        name: \"MIT Licence\",\n        description:\n            \"A simple, permissive licence which allows people do almost anything they want with your project, like making and distributing closed source versions.\",\n    },\n    {\n        id: \"lgpl\",\n        name: \"LGPL (v3)\",\n        description:\n            \"Others may use your code in closed-source projects, but if they modify your code and share it with anyone they have to release their changes too.\",\n    },\n    {\n        id: \"gpl\",\n        name: \"GPL (v3)\",\n        description:\n            \"Others may use and modify your code, but must release it (and any apps that use it) under the GPL if they share it with anyone.\",\n    },\n    {\n        id: \"none\",\n        name: \"None\",\n        description: \"Do not add a licence file to this project. You can add one yourself later.\",\n    },\n] as const;\n\nexport const addOssLicence: (licence: LicenceId) => AnvilAsyncAction =\n    (licence) => async (dispatch, getState, updateState) => {\n        if (licence === \"none\") {\n            console.log(\"Skipping 'none' licence\");\n            return;\n        }\n        if (appHasLicenceFile(getState())) {\n            console.log(\"App already has a licence file, aborting. This shouldn't happen!\");\n            return;\n        }\n        const { licenceText } = await import(\"@/data/ossLicenceText\");\n        updateState(({ app }) => {\n            if (!app) return;\n            app.config.extra_files ??= {};\n            app.config.extra_files[\"LICENSE.txt\"] = encodeAssetContent(licenceText[licence]);\n        });\n        await dispatch(markAppPathUnsaved([\"EXTRA_FILES\", \"LICENSE.txt\"]));\n    };\n\nexport const appHasLicenceFile = (state: State) => {\n    const extraFiles = getAppExtraFiles(state);\n    return \"COPYING\" in extraFiles || \"LICENSE\" in extraFiles || \"LICENSE.txt\" in extraFiles;\n};\n","import type { StripeCardElement } from \"@stripe/stripe-js\";\nimport { loadAppPermissions } from \"@/controllers/app/permissions\";\nimport type { AnvilAsyncAction, State } from \"@/types\";\nimport type { SubscriptionCharge } from \"@/types/subscription\";\nimport { getManagerUser } from \"../manager/controller\";\nimport { DarkTheme, LightTheme } from \"../theme/styles\";\nimport { stripePromise } from \"../util\";\nimport * as api from \"../api\";\nimport { updateGlobalLoadingIndicator } from \"./app\";\nimport { getSubscription, getUser, reloadSubscription, reloadSubscriptionInManagerOrIde, reloadUser } from \"./ide\";\nimport { alert, modal } from \"./modals\";\n\ninterface UpgradeDetails {\n    name: string;\n    paymentMethod?: unknown;\n    offerCode?: string;\n    amountOfferCode?: string;\n    [key: string]: unknown;\n}\n\n/** Only worth reloading the user when an offer code was actually redeemed: reloadUser refetches\n * the whole user plus available services, and `currentOffers` is the only part of it a checkout\n * can change. */\nconst reloadUserIfOfferRedeemed =\n    (upgradeDetails: UpgradeDetails): AnvilAsyncAction<void> =>\n    async (dispatch) => {\n        if (!upgradeDetails.offerCode && !upgradeDetails.amountOfferCode) return;\n        try {\n            await dispatch(reloadUser());\n        } catch (e) {\n            console.warn(\"Failed to refresh user after redeeming an offer code:\", e);\n        }\n    };\n\ninterface StartUpgradeOptions {\n    initialPlan?: string;\n    initialFreq?: string;\n}\n\nconst getPaymentEmail = (state: State) => getUser(state)?.email || getManagerUser(state).email;\n\nexport const stripeElementOptions = (isDarkMode: boolean, uiScale: string) => {\n    const theme = isDarkMode ? DarkTheme : LightTheme;\n    let size;\n    switch (uiScale) {\n        case \"tiny\":\n            size = 6 * 1.4;\n            break;\n        case \"small\":\n            size = 8 * 1.4;\n            break;\n        case \"large\":\n            size = 12 * 1.4;\n            break;\n        case \"huge\":\n            size = 14 * 1.4;\n            break;\n        case \"medium\":\n        default:\n            size = 10 * 1.4;\n            break;\n    }\n    return {\n        style: {\n            base: {\n                color: theme.stripeBox.color.toString(),\n                fontFamily:\n                    '\"Poppins\", \"-apple-system\", BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, \"sans-serif\"',\n                fontSize: `${size}px`,\n                fontSmoothing: \"antialiased\",\n                \"::placeholder\": {\n                    color: theme.stripeBox.placeholder.toString(),\n                    fontWeight: 500,\n                },\n            },\n            invalid: {\n                color: theme.palette.danger.toString(),\n                iconColor: theme.palette.danger.toString(),\n            },\n        },\n    };\n};\n\nexport const confirmUpdateCard =\n    (card: StripeCardElement | null): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        try {\n            dispatch(updateGlobalLoadingIndicator(true));\n            const stripe = await stripePromise;\n            const { licenceKey } = getSubscription(getState())!;\n            const { clientSecret } = await api.getChangeCardSetupIntent(licenceKey, !localStorage.stripeTestMode);\n            let { setupIntent, error } = await stripe!.confirmCardSetup(clientSecret, {\n                payment_method: { card: card! },\n            });\n            try {\n                const resp = await api.changePaymentCard(licenceKey, setupIntent!);\n                await dispatch(reloadSubscriptionInManagerOrIde());\n                return { resp, setupIntent };\n            } catch (e) {\n                return { e, error };\n            }\n        } finally {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n    };\n\nexport const authorisePayment =\n    (charge: SubscriptionCharge): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        let response;\n        try {\n            dispatch(updateGlobalLoadingIndicator(true));\n            const stripe = await stripePromise;\n            response = await stripe!.confirmCardPayment(charge.paymentIntentClientSecret!);\n        } finally {\n            await dispatch(reloadSubscription());\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n        if (response.error) {\n            await dispatch(\n                alert(\"Error\", `${response.error.message} For more assistance, please contact billing@anvil.works`)\n            );\n        }\n    };\n\nexport const authoriseSetup =\n    (setupIntent: string): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        let response;\n        try {\n            dispatch(updateGlobalLoadingIndicator(true));\n            const stripe = await stripePromise;\n            response = await stripe!.confirmCardSetup(setupIntent);\n        } finally {\n            await dispatch(reloadSubscription());\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n        if (response.error) {\n            await dispatch(\n                alert(\"Error\", `${response.error.message} For more assistance, please contact billing@anvil.works`)\n            );\n        }\n    };\n\nexport const retryPayment =\n    (charge: SubscriptionCharge): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        let response;\n        try {\n            dispatch(updateGlobalLoadingIndicator(true));\n            const { licenceKey } = getSubscription(getState())!;\n            response = await api.retryPayment(licenceKey, charge.id);\n        } finally {\n            await dispatch(reloadSubscription());\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n        if (response.error) {\n            const message = typeof response.error === \"string\" ? response.error : response.error.message;\n            await dispatch(\n                alert(\"Error\", `${message} For more assistance, please contact billing@anvil.works`)\n            );\n        } else {\n            const state = getState();\n            const subscription = getSubscription(state);\n            const current = subscription!.charges!.find((chargeItem) => chargeItem.id === charge.id);\n            if (current!.paymentStatus === \"requires_action\") {\n                await dispatch(authorisePayment(current!));\n            }\n        }\n    };\n\nexport const startUpgrade =\n    (\n        newOrganisation: boolean,\n        trialUpgrade = false,\n        forceShowAdditionalTableauViewers = false,\n        { initialPlan, initialFreq }: StartUpgradeOptions = {}\n    ): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const isIde = getState().ide;\n        const upgradeAttempt = await dispatch(\n            modal(\"upgrade\", {\n                initialPlanId: initialPlan,\n                initialFreq,\n                newOrganisation,\n                trialUpgrade,\n                managerAction: !isIde,\n                forceShowAdditionalTableauViewers,\n            })\n        );\n        if (upgradeAttempt?.failed) {\n            const errorMessage =\n                upgradeAttempt?.errorMessage ||\n                \"Sorry, we were unable to change your plan. Please contact support@anvil.works for further assistance.\";\n            dispatch(alert(\"Unable to change plan\", errorMessage));\n        } else if (upgradeAttempt?.id) {\n            const subscription = await dispatch(reloadSubscriptionInManagerOrIde());\n            dispatch(modal(\"upgradeSuccessful\", { subscription, trialUpgrade }));\n        }\n        //else if gets passed to here then you just exited out of the modal\n    };\n\nexport const startTrialOrg = (): AnvilAsyncAction => async (dispatch, getState, updateState) => {\n    try {\n        dispatch(updateGlobalLoadingIndicator(true));\n        await api.startTrial();\n        await dispatch(reloadUser());\n        const subscription = await dispatch(reloadSubscription());\n        dispatch(modal(\"upgradeSuccessful\", { subscription }));\n    } finally {\n        dispatch(updateGlobalLoadingIndicator(false));\n    }\n};\n\nexport const upgradeFromFree =\n    (upgradeDetails: UpgradeDetails, card: StripeCardElement | null, inIde: boolean): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        let licenceKeyOfNewOrg: string | undefined;\n        try {\n            dispatch(updateGlobalLoadingIndicator(true));\n            const stripe = await stripePromise;\n            const state = getState();\n            const email = getPaymentEmail(state);\n            const resp = await stripe!.createPaymentMethod({\n                type: \"card\",\n                card: card!,\n                billing_details: {\n                    name: upgradeDetails.name,\n                    email,\n                },\n            });\n            const paymentMethod = resp.paymentMethod;\n            const pmError = resp.error;\n            if (pmError) {\n                //if payment method fails, goes back out to form\n                console.warn(\"Error creating paymentMethod\", pmError);\n                return { error: pmError.message };\n            }\n            upgradeDetails = { ...upgradeDetails, paymentMethod };\n\n            const {\n                status,\n                error,\n                paymentIntentClientSecret,\n                clientSecret,\n                licence_key: newLicenceKey,\n            } = await api.upgradeFromFree(upgradeDetails, inIde);\n            licenceKeyOfNewOrg = newLicenceKey;\n\n            if (error) {\n                return { error };\n            } else {\n                if (status === \"requires_action\") {\n                    const secure = await stripe!.confirmCardPayment(clientSecret!);\n                    if (secure.error) {\n                        return { error: secure.error.message };\n                    }\n                }\n            }\n\n            return { status };\n        } catch (e) {\n            console.warn(\"Error upgrading plan:\", e);\n\n            return { upgradeError: (e as { toString(): string }).toString() };\n        } finally {\n            try {\n                await dispatch(reloadUserIfOfferRedeemed(upgradeDetails));\n                if (inIde) {\n                    await dispatch(reloadSubscriptionInManagerOrIde());\n                } else if (licenceKeyOfNewOrg) {\n                    // Manager org creation can fail before the server returns a licence key,\n                    // and the org chooser has no current organisation to fall back to.\n                    await dispatch(reloadSubscriptionInManagerOrIde(licenceKeyOfNewOrg));\n                }\n            } finally {\n                dispatch(updateGlobalLoadingIndicator(false));\n            }\n        }\n    };\n\nexport const upgradeFromTrial =\n    (upgradeDetails: UpgradeDetails, card: StripeCardElement | null): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        try {\n            console.log(\"upgrading from trial\");\n            dispatch(updateGlobalLoadingIndicator(true));\n            const stripe = await stripePromise;\n            const state = getState();\n            const { licenceKey } = getSubscription(state)!;\n            const email = getPaymentEmail(state);\n\n            const resp = await stripe!.createPaymentMethod({\n                type: \"card\",\n                card: card!,\n                billing_details: {\n                    name: upgradeDetails.name,\n                    email,\n                },\n            });\n            const paymentMethod = resp.paymentMethod;\n            const pmError = resp.error;\n            if (pmError) {\n                //if payment method fails, goes back out to form\n                console.warn(\"Error creating paymentMethod\", pmError);\n                return { error: pmError.message };\n            }\n\n            upgradeDetails = { ...upgradeDetails, paymentMethod };\n            const { status, error, clientSecret } = await api.upgradeFromTrial(licenceKey, upgradeDetails);\n            if (error) {\n                return { error };\n            } else {\n                if (status === \"requires_action\") {\n                    const x = await stripe!.confirmCardSetup(clientSecret!);\n                    if (x.error) {\n                        return { error: x.error.message };\n                    }\n                }\n                return { status };\n            }\n        } catch (e) {\n            console.warn(\"Error upgrading plan:\", e);\n            return { upgradeError: (e as { toString(): string }).toString() };\n        } finally {\n            await dispatch(reloadUserIfOfferRedeemed(upgradeDetails));\n            dispatch(reloadSubscriptionInManagerOrIde());\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n    };\n\nexport const changePlan =\n    (upgradeDetails: UpgradeDetails, card: StripeCardElement | null): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        let response;\n        try {\n            dispatch(updateGlobalLoadingIndicator(true));\n            const { licenceKey } = getSubscription(getState())!;\n            response = await api.changePaidPlan(licenceKey, upgradeDetails);\n            return response;\n        } catch (e) {\n            console.warn(\"Error changing plan:\", e);\n            return { error: e };\n        } finally {\n            await dispatch(reloadUserIfOfferRedeemed(upgradeDetails));\n            dispatch(reloadSubscriptionInManagerOrIde());\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n    };\n\nexport const leaveSubscription = (): AnvilAsyncAction => async (dispatch, getState, updateState) => {\n    let response;\n    try {\n        dispatch(updateGlobalLoadingIndicator(true));\n        response = await api.leaveSubscription();\n        await dispatch(reloadSubscription());\n        const state = getState();\n        if (state.app?.$loaded) {\n            await dispatch(loadAppPermissions(state.app.id));\n        }\n        return response;\n    } catch (e) {\n        console.warn(\"Error leaving subscription:\", e);\n        return { error: e };\n    } finally {\n        dispatch(updateGlobalLoadingIndicator(false));\n    }\n};\n","import { AnvilAction, State } from \"@/types\";\nimport { RecordSchemas } from \"@/types/record-types\";\nimport * as api from \"../api\";\nimport { getAppId } from \"./app\";\n\nexport const loadRecordSchemas: () => AnvilAction = () => async (dispatch, getState, updateState) => {\n    const appId = getAppId(getState());\n    const knownSchemas = [\"anvil.tables\"]; // TODO fetch this from autocomplete\n    const schemas = (await api.loadRecordSchemas(appId, knownSchemas)) as RecordSchemas;\n    updateState(({ app }) => {\n        if (!app) return;\n        app.recordSchemas = schemas;\n    });\n    return schemas;\n};\n\nexport const invalidateRecordSchemas: () => AnvilAction = () => (dispatch, getState, updateState) =>\n    updateState(({ app }) => {\n        if (!app) return;\n        app.recordSchemas = undefined;\n    });\n\nexport const getRecordSchemas = (state: State) => state.app?.recordSchemas;\n","import { useDispatch } from \"react-redux\";\nimport { DebuggerValue, ExpandedFrameState, ExpandedNode } from \"@platform-runner/shared-debugger-types\";\nimport { cloneDeep, find, merge } from \"lodash-es\";\nimport type { StackFrameContextType } from \"@/components/bottom_panel/DebugInspector\";\nimport {\n    AnvilAction,\n    AnvilAsyncAction,\n    AnvilDispatch,\n    AppId,\n    BottomPanelTabTarget,\n    Repl,\n    ReplCodeState,\n    ReplHistoryState,\n    State,\n} from \"@/types\";\nimport { raiseEvent } from \"../actions\";\nimport { getAppId, updateGlobalLoadingIndicator } from \"./app\";\nimport { clearRunnerBgTasks } from \"./runner-bg-tasks\";\nimport { getAppCommitId } from \"./app/history\";\nimport { bottomTabsMatch, closeBottomTab, openOrFocusBottomTab } from \"./bottom-tabs\";\nimport { debugExec, getIsRunnerPaused, sendDebuggerRequest } from \"./debugger\";\nimport { confirm } from \"./modals\";\nimport * as websocket from \"./websocket\";\nimport { replKeepalive, useWebsocketEventListener } from \"./websocket\";\n\nlet lastClientReplId = 0;\n\nlet nextReplIdx = 0; // Used for sorting server repl tabs in BottomPanel\n\nexport const createRepl =\n    (type: Repl[\"type\"], replaceExistingId?: string): AnvilAsyncAction<string> =>\n    async (dispatch, getState, updateState) => {\n        let id: string;\n        // TODO pretty sure there's a less gnarly way of doing this than introducing a dependency between controllers\n        const appId = getAppId(getState());\n        if (!appId) {\n            throw new Error(\"No app open\");\n        }\n        let readOnly = false;\n        // TODO: Whatever is required to actually create the REPL.\n        switch (type) {\n            case \"runner\":\n                // Don't need to do anything - the runner is there for us to communicate with.\n                id = `runner-repl-${++lastClientReplId}`;\n                break;\n            case \"server\":\n                try {\n                    dispatch(updateGlobalLoadingIndicator(\"Launching server console...\"));\n                    id = await websocket.launchServerRepl(appId);\n                } finally {\n                    dispatch(updateGlobalLoadingIndicator(false));\n                }\n                // we use a webworker here because setInterval gets throttled when the browser loses focus\n                // whereas a webworker doesn't seem to be throttled in the same way\n\n                const keepAliveWorker = new Worker(new URL(\"../workers/worker-heartbeat\", import.meta.url), {\n                    type: \"module\",\n                });\n                keepAliveWorker.onmessage = () => {\n                    const repl = getRepl(id)(getState());\n                    if (repl && !repl.terminated) {\n                        replKeepalive(appId, id);\n                    } else {\n                        keepAliveWorker.postMessage({ action: \"stop\" });\n                        keepAliveWorker.terminate();\n                    }\n                };\n                keepAliveWorker.postMessage({ action: \"start\", interval: 20000 });\n                break;\n            case \"tableau\":\n                id = `tableau-repl-${++lastClientReplId}`;\n                readOnly = true;\n                break;\n        }\n\n        const currentCommitId = getAppCommitId(getState());\n\n        let initialReplState: Omit<\n            Repl,\n            \"id\" | \"type\" | \"commitId\" | \"codeMirrorState\" | \"terminated\" | \"readOnly\" | \"executingCmds\"\n        > = {\n            output:\n                type === \"server\"\n                    ? [\n                          {\n                              fn: \"session\",\n                              fromServer: null,\n                              text: `New server session: ${new Date().toLocaleString(\"en-GB\", { hour12: false })}`,\n                          },\n                      ]\n                    : [],\n            historyState: { history: [], session: [], idx: 0, tmp: null },\n            bannerDismissed: type === \"tableau\", // Tableau repls don't need the banner\n            preserveLogs: false,\n            importTimeTracking: { requestCount: 0, totalImportTime: 0, showImportBanner: false },\n            tabIndex: nextReplIdx++,\n        };\n\n        if (replaceExistingId) {\n            initialReplState = getRepl(replaceExistingId)(getState());\n            initialReplState = {\n                ...initialReplState,\n                output: [\n                    ...(initialReplState.output ?? []),\n                    {\n                        fn: \"session\",\n                        text: \"Server Console restarted. All variables have been cleared.\",\n                    },\n                ],\n                historyState: { ...initialReplState.historyState, session: [] },\n            };\n        } else if (type === \"server\") {\n            // TODO - we lose all the history when we close the repl\n            const replState = getState().repl;\n            const prevServerReplHistory = replState.prevServerReplHistory ?? [];\n            const initialHistory = [];\n            for (const { id, historyStart, history } of prevServerReplHistory) {\n                // if we have a history then we were destroyed so use that\n                if (history) {\n                    initialHistory.push(...history);\n                } else {\n                    // history start is history where history we didn't inherit starts from\n                    const historyState = replState.repls[id]?.historyState;\n                    const history = historyState?.history ?? [];\n                    initialHistory.push(...history.slice(historyStart));\n                }\n            }\n            initialReplState.historyState = {\n                history: initialHistory,\n                session: [],\n                idx: initialHistory.length,\n                tmp: null,\n            };\n        }\n\n        updateState(`Create REPL '${id}'`, merge, {\n            repl: {\n                repls: {\n                    [id]: {\n                        ...initialReplState,\n                        id,\n                        type,\n                        readOnly,\n                        codeMirrorState: null,\n                        commitId: currentCommitId,\n                        terminated: false,\n                        executingCmds: {},\n                    },\n                    ...(replaceExistingId\n                        ? // we won't render this in the bottom panel\n                          { [replaceExistingId]: { isBeingReplaced: true } }\n                        : {}),\n                },\n            },\n        });\n        if (type === \"server\") {\n            // we want to preserve insertion order and where the un-inherited history for this repl starts from\n            const prevRepls = getState().repl.prevServerReplHistory ?? [];\n            let currentIndex = -1;\n            if (replaceExistingId) {\n                currentIndex = prevRepls.findIndex(({ id }) => id === replaceExistingId);\n            }\n            if (currentIndex > -1) {\n                updateState(({ repl }) => {\n                    repl.prevServerReplHistory ??= [];\n                    const current = repl.prevServerReplHistory[currentIndex];\n                    current.id = id;\n                });\n            } else {\n                updateState(({ repl }) => {\n                    repl.prevServerReplHistory ??= [];\n                    repl.prevServerReplHistory.push({ id, historyStart: initialReplState.historyState.history.length });\n                });\n            }\n        }\n\n        dispatch(openOrFocusBottomTab({ type: `${type}Repl`, replId: id }));\n        return id;\n    };\n\nfunction isErrorOuput(output: any) {\n    return output.fn === \"pythonError\" || output.fn === \"runtimeError\";\n}\n\nexport const replOutput =\n    (replId: string, output: any): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const isPaused = getIsRunnerPaused(getState());\n        const outputIsError = isErrorOuput(output);\n        const thisRepl = getRepl(replId)(getState());\n\n        updateState(`REPL Output (${replId})`, (state) => {\n            const { repl } = state;\n            const thisRepl = repl.repls[replId];\n            if (!thisRepl) {\n                // The REPL has gone entirely.\n                return;\n            }\n            const previous = thisRepl.output[repl.repls[replId].output.length - 1];\n            const continuePrevious =\n                previous &&\n                previous.fromServer === output.fromServer &&\n                previous.text &&\n                !previous.text.endsWith(\"\\n\") &&\n                output.fn !== \"pythonError\" &&\n                // bgTask markers have no text of their own - without this guard they'd be\n                // silently merged into an unterminated stdout line and vanish\n                output.fn !== \"bgTask\";\n            if (continuePrevious) {\n                previous.text += output.text || \"\"; // don't put undefined in the output;\n            } else {\n                repl.repls[replId].output.push(cloneDeep(output));\n            }\n        });\n\n        if (outputIsError && !isPaused && thisRepl) {\n            dispatch(openOrFocusBottomTab({ type: `${thisRepl.type}Repl`, replId }));\n        }\n    };\n\nlet lastCmdId = 0;\nconst runningCommands: Record<number, string> = {}; // cmdId --> replId\n\n// Must provide one of replId, cmdId\nexport const replReturn =\n    (cmdId: number | null = null, replId: string | null = null): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        replId ??= runningCommands[cmdId as number];\n        if (replId) {\n            updateState(`REPL Return (${replId})`, ({ repl }) => {\n                // This only works as long as we enforce only one running command.\n                const r = repl.repls[replId as string];\n                if (!r) return;\n                if (cmdId === null) {\n                    // server repls don't keep track of their cmd ids\n                    delete r.runningCmdIdx;\n                } else if (cmdId in r.executingCmds) {\n                    const outputIndex = r.executingCmds[cmdId];\n                    delete r.executingCmds[cmdId];\n                    if (outputIndex === r?.runningCmdIdx) {\n                        delete r?.runningCmdIdx;\n                    }\n                }\n            });\n        }\n    };\n\nexport const serverReplReturn =\n    (cmdId: number, error: any): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const replId = runningCommands[cmdId as number];\n        if (replId) {\n            updateState(`REPL Return (${replId})`, ({ repl }) => {\n                // This only works as long as we enforce only one running command.\n                const r = repl.repls[replId as string];\n                if (!r) return;\n                const outputIndex = r.executingCmds[cmdId];\n                delete r.executingCmds[cmdId];\n                if (outputIndex === r?.runningCmdIdx) {\n                    // TODO: Store return value of command, or something. Not actually necessary for now.\n                    delete r.runningCmdIdx;\n                }\n                if (error) {\n                    r.output.push({\n                        fn: \"pythonError\",\n                        errorObj: error,\n                    });\n                }\n            });\n        }\n    };\n\nexport const updateReplHistory =\n    (replId: string, historyState: ReplHistoryState): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ repl }) => {\n            const r = repl.repls[replId];\n            r && (r.historyState = historyState);\n        });\n    };\n\nexport const storeCodeMirrorState =\n    (replId: string, codeMirrorState: ReplCodeState): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ repl }) => {\n            const r = repl.repls[replId];\n            r && (r.codeMirrorState = codeMirrorState);\n        });\n    };\n\nconst maybeWalkChild = (v: DebuggerValue, path: string, expanded: ExpandedNode = {}) => {\n    if (!(v.items || v.attrs)) {\n        return;\n    }\n    expanded.children ??= {};\n    expanded.children[path] = {};\n    walkPaths(v, expanded.children[path]);\n};\n\nconst walkPaths = (value: DebuggerValue, expanded: ExpandedNode = {}) => {\n    if (value.items) {\n        expanded.items = value.items.length;\n        value.items.forEach(([a, v], i) => {\n            maybeWalkChild(v, JSON.stringify([\"i\", i]), expanded);\n        });\n    }\n    if (value.attrs) {\n        for (const [attr, v] of Object.entries(value.attrs)) {\n            maybeWalkChild(v, JSON.stringify([\"a\", attr]), expanded);\n        }\n    }\n    return expanded;\n};\n\nconst getFrameExpandedState = (frame: StackFrameContextType[\"frame\"]) => {\n    if (!frame) return;\n    const rv: ExpandedFrameState = { id: frame.id };\n    if (frame.locals) {\n        rv.locals = walkPaths(frame.locals);\n    }\n    if (frame.globals) {\n        rv.globals = walkPaths(frame.globals);\n    }\n    return rv;\n};\n\nexport const replCommand =\n    (replId: string, code: string, frameContext: StackFrameContextType): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const repl = getRepl(replId)(state);\n        const appId = getAppId(state);\n        if (!appId) return;\n        const { frame, dbg } = frameContext;\n\n        const cmdId = ++lastCmdId;\n\n        updateState(`REPL Command (${replId})`, ({ repl }) => {\n            const r = repl.repls[replId];\n            const onServer = r.type === \"server\" || !!dbg?.location;\n            r.output.push({\n                command: code,\n                onServer,\n                fn: \"replCommand\",\n            });\n            r.runningCmdIdx = r.output.length - 1;\n            r.executingCmds ??= {};\n            r.executingCmds[cmdId] = r.output.length - 1;\n        });\n\n        // Do whatever is required to actually run a command on this type of repl.\n        switch (repl.type) {\n            case \"runner\": {\n                if (dbg?.location) {\n                    runningCommands[cmdId] = replId;\n                    dispatch(debugExec(code, cmdId, dbg, getFrameExpandedState(frame)));\n                } else {\n                    runningCommands[cmdId] = replId;\n                    dispatch(\n                        raiseEvent(\"RUNNER_REPL_COMMAND\", {\n                            cmdId,\n                            code,\n                            extraArgs: { expandedFrame: getFrameExpandedState(frame) },\n                        })\n                    );\n                }\n                break;\n            }\n            case \"server\":\n                try {\n                    await websocket.runReplCommand(appId, replId, (code.trimEnd() || \"None\") + \"\\n\");\n                } catch (e: any) {\n                    console.error(e);\n                    if (e.type === \"anvil.server.NotRunningTask\") {\n                        dispatch(replTerminated(replId));\n                    } else {\n                        throw e;\n                    }\n                }\n                break;\n        }\n    };\n\nexport const replInterrupt =\n    (replId: string, frameContext: StackFrameContextType): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const repl = getRepl(replId)(state);\n        const { dbg } = frameContext;\n\n        // Do whatever is required to actually interrupt a repl of this type.\n        switch (repl.type) {\n            case \"runner\": {\n                if (dbg?.location) {\n                    const c = await dispatch(\n                        confirm(\n                            \"Terminate Server Execution\",\n                            \"Are you sure you want to terminate this server execution?\"\n                        )\n                    );\n                    if (c) {\n                        dispatch(sendDebuggerRequest(dbg, { action: \"INTERRUPT\" }));\n                    }\n                } else {\n                    dispatch(raiseEvent(\"RUNNER_REPL_INTERRUPT\"));\n                }\n                break;\n            }\n            case \"server\":\n                const c = await dispatch(\n                    confirm(\"Terminate Server Repl\", \"Are you sure you want to terminate this server repl?\")\n                );\n                if (c) {\n                    await closeRepl(state, repl);\n                }\n        }\n    };\n\nexport const replTerminated =\n    (id: string): AnvilAction =>\n    (_d, _g, updateState) => {\n        updateState(`Terminate REPL ${id}`, ({ repl }) => {\n            const thisRepl = repl.repls[id];\n            if (thisRepl) {\n                thisRepl.terminated = true;\n                thisRepl.readOnly = true;\n                thisRepl.output.push({\n                    fn: \"session\",\n                    fromServer: null,\n                    text: `Session ended: ${new Date().toLocaleString(\"en-GB\", { hour12: false })}`,\n                });\n            }\n        });\n    };\n\nexport const replLocked =\n    (id: string): AnvilAction =>\n    (_d, _g, updateState) => {\n        updateState(`Lock REPL ${id}`, ({ repl }) => {\n            repl.repls[id].readOnly = true;\n            delete repl.repls[id].runningCmdIdx;\n            repl.repls[id].executingCmds = {};\n        });\n    };\n\n// legacy - not called - we only have one runner repl\nexport const destroyRunnerRepls = (): AnvilAction => (dispatch, getState, updateState) => {\n    const repls = getRepls(getState());\n    for (const repl of Object.values(repls)) {\n        if (repl.type === \"runner\") {\n            dispatch(destroyRepl(repl));\n            break;\n        }\n    }\n};\n\nexport const destroyRepls = (): AnvilAsyncAction => async (dispatch, getState, updateState) => {\n    const state = getState();\n    const repls = getRepls(state);\n    const ids: string[] = [];\n    for (const repl of Object.values(repls)) {\n        await closeRepl(state, repl);\n        ids.push(repl.id);\n    }\n    updateState(({ editor, repl }) => {\n        for (const id of ids) {\n            delete repl.repls[id];\n        }\n        editor.bottomPanelTabStack = editor.bottomPanelTabStack.filter((t) => \"replId\" in t);\n        if (editor.bottomPanelCurrentTab && \"replId\" in editor.bottomPanelCurrentTab) {\n            editor.bottomPanelCurrentTab = editor.bottomPanelTabStack.at(-1) ?? null;\n        }\n    });\n};\n\nconst closeRepl = async (state: State, { id, type }: Repl) => {\n    switch (type) {\n        case \"runner\":\n            // Don't need to do anything - the runner will go away on its own.\n            break;\n        case \"server\":\n            const appId = getAppId(state);\n            if (!appId) return;\n            try {\n                await websocket.terminateRepl(appId, id);\n            } catch (e) {\n                console.error(e);\n                throw e;\n            }\n            break;\n    }\n};\n\nexport const destroyRepl =\n    ({ id, type }: Repl): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        // TODO: Whatever is required to actually destroy the REPL.\n        const state = getState();\n        const replState = state.repl;\n        const repl = getRepl(id)(state);\n\n        if (!repl.terminated) {\n            try {\n                await closeRepl(state, { id, type } as Repl);\n            } catch (e) {\n                //throw new Error(`Error terminating REPL: ${e.message}`);\n            }\n        }\n        let includeHistory = null;\n\n        if (repl.type === \"server\") {\n            const serverReplHistory = replState.prevServerReplHistory?.find((state) => state.id === id);\n            if (serverReplHistory) {\n                includeHistory = repl.historyState.history.slice(serverReplHistory.historyStart);\n            }\n        }\n\n        updateState(`Destroy REPL '${id}'`, ({ editor, repl }) => {\n            delete repl.repls[id];\n            if (includeHistory) {\n                const serverReplHistory = repl.prevServerReplHistory?.find((state) => state.id === id);\n                if (serverReplHistory) {\n                    serverReplHistory.history = includeHistory;\n                }\n            }\n        });\n\n        dispatch(closeBottomTab({ type: `${type}Repl`, replId: id }));\n    };\n\nexport const clearRepl =\n    (replId: string | null, cmdId?: number): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const id = replId ?? runningCommands[cmdId!];\n        updateState(`Clear REPL '${id}'`, (state) => {\n            const { repl, debug } = state;\n            if (id in repl.repls) {\n                repl.repls[id].output = [];\n                repl.repls[id].importTimeTracking = {\n                    requestCount: 0,\n                    totalImportTime: 0,\n                    showImportBanner: false,\n                };\n                if (repl.repls[id].type === \"runner\") {\n                    debug.output = [];\n                    // The inline task widgets just went with the output; forget the tasks\n                    // too (still-running ones will re-appear on their next event).\n                    clearRunnerBgTasks(state);\n                }\n            }\n        });\n    };\n\nexport const restartRepl =\n    (replId: string): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const repl = getRepl(replId)(state);\n        const newId = await dispatch(createRepl(repl.type, replId));\n        const newTab: BottomPanelTabTarget = { type: `${repl.type}Repl`, replId: newId };\n        const oldTab: BottomPanelTabTarget = { type: `${repl.type}Repl`, replId: replId };\n        updateState(({ editor }) => {\n            editor.bottomPanelTabStack = editor.bottomPanelTabStack.map((t) =>\n                bottomTabsMatch(t, oldTab) ? newTab : t\n            );\n        });\n        await dispatch(destroyRepl(repl));\n    };\n\nexport const setPreserveReplLogs =\n    (replId: string, newValue: boolean): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(`${newValue ? \"Preserve\" : \"Don't preserve\"} console logs between runs`, ({ repl }) => {\n            repl.preserveLogs = newValue;\n        });\n    };\n\nexport const incrementImportTimeTracking =\n    (importTime: number): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const state = getState();\n        const id = getRunnerRepl(state)?.id;\n        if (!id) return;\n        const importTimeTracking = getImportTimeTracking(state, id);\n        updateState(`Increment Import Time Taken`, (state) => {\n            state.repl.repls[id].importTimeTracking = {\n                requestCount: (importTimeTracking?.requestCount || 0) + 1,\n                totalImportTime: (importTimeTracking?.totalImportTime || 0) + importTime,\n                showImportBanner: importTimeTracking?.showImportBanner || importTime > 100,\n            };\n        });\n    };\n\nexport const dismissReplBanner =\n    (replId: string): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(`Dismiss REPL banner for ${replId}`, (state) => {\n            state.repl.repls[replId].bannerDismissed = true;\n        });\n    };\n\nexport const getRepl = (id: string) => (state: State) => state.repl.repls[id];\nexport const getRepls = (state: State) => state.repl.repls;\nexport const getRunnerRepl = (state: State) => find(state.repl.repls, (v) => v.type === \"runner\");\nexport const getTableauRepl = (state: State) => find(state.repl.repls, (v) => v.type === \"tableau\");\nexport const getPreserveReplLogs = (state: State) => state.repl.preserveLogs;\nexport const getImportTimeTracking = (state: State, id: string) => state.repl.repls[id].importTimeTracking;\n\n// TODO explain disconnection to the user (the keepalive will get there eventually, but it'll be ugly)\n\nexport const useReplWebsocketEventListener = (appId?: AppId) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    useWebsocketEventListener(appId, (e) => {\n        switch (e.event) {\n            case \"REPL_UPDATE\":\n                dispatch(\n                    replOutput(e.repl, {\n                        fromServer: true,\n                        ...(e.error ? { fn: \"pythonError\", errorObj: e.error } : { fn: \"stdout\", text: e.output }),\n                    })\n                );\n                if (e.ready || e.error) {\n                    dispatch(replReturn(null, e.repl));\n                }\n                if (e.terminated) {\n                    dispatch(replTerminated(e.repl));\n                }\n                break;\n        }\n    });\n};\n","import type { AnvilAction, AnvilAsyncAction, RunnerBgTask, RunnerConnectionState, State } from \"@/types\";\nimport { insertLogEventBySeq } from \"./log-events\";\n\n// Background tasks launched from the current runner debug session. The server tags every\n// task the debug session launches (transitively) with the session's watch key, and forwards\n// tagged log-firehose events down the runner's own websocket; the runner postMessages them\n// to us as {fn: \"bgTaskEvent\"} (see Runner.tsx). Everything here is event-driven - the\n// Background Tasks poller is only passively reflected (see RunnerBgTaskWidget).\n//\n// NB the thunks import their collaborators lazily: almost any controller import in this\n// codebase transitively executes browser-coupled module init, which would make this module\n// unimportable from unit tests (rstest runs in a plain node environment).\n\nconst stripTaskPrefix = (name?: string) => (name || \"\").replace(/^task:/, \"\");\n\n/** Mutates state: mark every task that is live right now as possibly missing output.\n *  Used when the push channel drops and when the runner goes away with tasks still live. */\nexport function markLiveRunnerBgTasksMissingOutput(state: State) {\n    for (const task of Object.values(state.runnerBgTasks)) {\n        if (task.state !== \"TERMINATED\") {\n            task.outputMayBeMissing = true;\n        }\n    }\n}\n\n/** Mutates state: forget tracked tasks (their inline widgets are gone from the output). */\nexport function clearRunnerBgTasks(state: State) {\n    state.runnerBgTasks = {};\n}\n\n/** Merge one forwarded log-firehose event into the tracked-task state.\n *  BG_TASK_LAUNCHED, SESSION_START and LOG_EVENTs can arrive in any order\n *  (SESSION_START is broadcast asynchronously) - merge by session id. */\nexport function applyRunnerBgTaskEvent(state: State, e: any) {\n    const sessionId = e?.session_id;\n    if (!sessionId) return;\n    const task = (state.runnerBgTasks[sessionId] ??= {\n        sessionId,\n        name: \"\",\n        state: \"RUNNING\",\n        output: [],\n    } as RunnerBgTask);\n    switch (e.event) {\n        case \"BG_TASK_LAUNCHED\":\n            task.taskId = e.task_id;\n            task.name = stripTaskPrefix(e.task_name) || task.name;\n            task.startTime ??= e.start_time ?? e.timestamp;\n            break;\n        case \"SESSION_START\":\n            task.session = e;\n            task.name ||= stripTaskPrefix(e.data?.func);\n            task.startTime ??= e.timestamp;\n            break;\n        case \"LOG_EVENT\":\n            insertLogEventBySeq(task.output, e);\n            if (e.type === \"background_task_ended\") {\n                // Terminal events always win (including over KILLING)\n                task.state = \"TERMINATED\";\n                task.finalStatus = e.data?.status;\n            }\n            break;\n    }\n    // On HTTP transport there is no push channel: everything we learn about arrives\n    // truncated, so tasks discovered under it start out marked.\n    if (state.debug?.connectionState === \"none\") {\n        task.outputMayBeMissing = true;\n    }\n}\n\n/** Apply a connection-state signal from the runner. */\nexport function applyRunnerConnectionState(state: State, connState: RunnerConnectionState) {\n    state.debug ??= {} as State[\"debug\"];\n    if (connState === \"session-reset\") {\n        // A one-off event, not a transport state: the session (and its watch key)\n        // rotated, so tasks launched under the old one stop streaming.\n        markLiveRunnerBgTasksMissingOutput(state);\n        return;\n    }\n    state.debug.connectionState = connState;\n    if (connState === \"lost\" || connState === \"none\") {\n        // Mark only the tasks live at this moment; the marker is sticky - a later\n        // reconnect doesn't clear it, the gap already happened.\n        markLiveRunnerBgTasksMissingOutput(state);\n    }\n}\n\nexport const getRunnerBgTasks = (state: State) => state.runnerBgTasks;\nexport const getRunnerBgTask = (sessionId: string) => (state: State) => state.runnerBgTasks[sessionId];\n\n/** Total streamed output lines across tracked tasks - drives the unread badge on the\n *  Running App Console tab (task output never touches debug.output, so the badge would\n *  otherwise only count the launch markers). */\nexport const getRunnerBgTaskOutputCount = (state: State) =>\n    Object.values(state.runnerBgTasks).reduce((n, t) => n + t.output.length, 0);\n\nexport const handleRunnerBgTaskEvent =\n    (e: any): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const sessionId = e?.session_id;\n        if (!sessionId) return;\n        const isNew = !getState().runnerBgTasks[sessionId];\n\n        updateState(\"Runner BG task event\", (state) => applyRunnerBgTaskEvent(state, e));\n\n        if (isNew) {\n            // Embed the task's widget in the output stream at the point it was launched.\n            // (The import resolves in a microtask, so the marker still lands before the\n            // next postMessage event is processed.)\n            void import(\"./runner\").then(({ runnerOutput }) => dispatch(runnerOutput({ fn: \"bgTask\", sessionId })));\n        }\n    };\n\nexport const runnerConnectionStateChanged =\n    (connState: RunnerConnectionState): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(\"Runner connection state\", (state) => applyRunnerConnectionState(state, connState));\n    };\n\nexport const stopRunnerBgTask =\n    (sessionId: string): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        // We would like to import these things normally, but they do things at module-load time that make unit testing outside a browser difficult.\n        // For now, import them lazily.\n        // TODO: Move all module-load-time behaviour into init functions and call them on boot.\n        const [{ getAppId }, api, { invalidateBackgroundTasks }] = await Promise.all([\n            import(\"./app\"),\n            import(\"@/api\"),\n            import(\"./background-tasks-query\"),\n        ]);\n        const state = getState();\n        const appId = getAppId(state);\n        const task = state.runnerBgTasks[sessionId];\n        if (!appId || !task?.taskId || task.state !== \"RUNNING\") return;\n\n        // \"I have successfully requested a kill; awaiting any indication it happened.\"\n        // Resolution comes from the background_task_ended event (or the poller).\n        updateState(\"Kill runner BG task\", ({ runnerBgTasks }) => {\n            const t = runnerBgTasks[sessionId];\n            if (t?.state === \"RUNNING\") t.state = \"KILLING\";\n        });\n        try {\n            await api.killBackgroundTask(appId, task.taskId);\n        } catch (e) {\n            console.warn(\"Failed to kill background task\", task.taskId, e);\n            updateState(({ runnerBgTasks }) => {\n                const t = runnerBgTasks[sessionId];\n                if (t?.state === \"KILLING\") t.state = \"RUNNING\";\n            });\n            return;\n        }\n        invalidateBackgroundTasks(appId);\n    };\n","import { cloneDeep, last, merge, set } from \"lodash-es\";\nimport { AnvilAction, RunnerOutput, State } from \"@/types\";\nimport * as api from \"@/api\";\nimport { getAppId } from \"./app\";\nimport { modal } from \"./modals\";\nimport { getRunnerRepl, replOutput } from \"./repl\";\n\nexport const maximiseRunner = (): AnvilAction => (dispatch, getState, updateState) => {\n    updateState(set, [\"debug\", \"runnerMaximised\"], true);\n    updateState(set, [\"debug\", \"inMaximised\"], true);\n};\n\nexport const restoreRunner = (): AnvilAction => (dispatch, getState, updateState) => {\n    updateState(set, [\"debug\", \"runnerMaximised\"], false);\n    updateState(set, [\"debug\", \"inMaximised\"], false);\n};\n\nexport const restoreRunnerView = (): AnvilAction => (dispatch, getState, updateState) => {\n    updateState(set, [\"debug\", \"inMaximised\"], false);\n};\n\nexport const newDebugSession =\n    (sessionToken: string): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(\"New debug session\", merge, {\n            debug: {\n                sessionToken,\n                output: [],\n                alreadyPromptedForUpgrade: false,\n                alreadyPromptedForFullDebuggerUpgrade: false,\n            },\n        });\n    };\n\n// TODO: Work out whether fromServer is an argument or a property of output\nexport const runnerOutput =\n    (output: RunnerOutput): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const runnerRepl = getRunnerRepl(getState());\n\n        if (runnerRepl) {\n            dispatch(replOutput(runnerRepl.id, output));\n        }\n\n        updateState(\"Debug output\", ({ debug }) => {\n            // TODO: This is very similar to replOutput. Should probably combine them.\n            const previous = last(debug.output);\n            if (\n                previous &&\n                previous.fromServer === output.fromServer &&\n                \"text\" in output &&\n                previous.text &&\n                !previous.text.endsWith(\"\\n\")\n            ) {\n                previous.text += output.text;\n            } else {\n                debug.output.push(cloneDeep(output));\n            }\n        });\n    };\n\nexport const clearOutput = (): AnvilAction => (dispatch, getState, updateState) => {\n    updateState(\"Clear debug output\", set, [\"debug\", \"output\"], []);\n};\n\nexport const endDebugSession = (): AnvilAction => async (dispatch, getState, updateState) => {\n    const state = getState();\n\n    const sessionTokenToKill = getDebugSessionToken(state);\n    const appId = getAppId(state);\n    console.log(\"Killing session with token\", sessionTokenToKill);\n\n    updateState(\"End debug session\", (state) => {\n        state.debug.sessionToken = null;\n        const debuggerId = state.debug.debuggerId;\n        if (debuggerId != null) {\n            delete state.debuggerHyperStacks[debuggerId];\n        }\n    });\n\n    if (sessionTokenToKill) {\n        try {\n            await api.killAppSession(appId, sessionTokenToKill);\n        } catch {\n            console.warn(\"Failed to kill app session:\", sessionTokenToKill);\n            // We don't care if this fails.\n        }\n    } else {\n        log.warn(\"No runtime session token - not killing session.\");\n    }\n};\n\nexport const maybeConfigureOrUpgradeOnImportFailure =\n    (modname: string, runtimeAvailable: boolean, configuredToCustom = false): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const alreadyPromptedForUpgrade = getState().debug.alreadyPromptedForUpgrade;\n        if (!alreadyPromptedForUpgrade) {\n            updateState((state: State) => {\n                state.debug.alreadyPromptedForUpgrade = true;\n            });\n            dispatch(\n                modal(\"configureOrUpgradePromptOnRuntimeFeatureRequired\", {\n                    module: modname,\n                    hasRuntime: runtimeAvailable,\n                    configured: configuredToCustom,\n                })\n            );\n        }\n    };\n\nexport const getDebugSessionToken = (state: State) => state.debug.sessionToken;\nexport const getRunMode = (state: State) => state.debug?.runMode;\n\nexport const getRunnerSavedInMaximised = (state: State) => state.debug.runnerMaximised;\nexport const getRunnerViewMaximised = (state: State) => state.debug?.inMaximised;\n\nexport const getRunnerOutput = (state: State) => state.debug.output;\nexport const getIsRunning = (state: State) => state.debug?.runMode !== null;\nexport const getIsRunningAsInline = (state: State) => state.debug?.runMode === \"INLINE\";\n","import { useMemo } from \"react\";\nimport { update } from \"lodash-es\";\nimport * as api from \"@/api\";\nimport { claimAchievement } from \"@/controllers/user\";\nimport { AnvilAction, AnvilAsyncAction, AppId, AtSpec, Every, ScheduledTask, State, TimeSpec } from \"@/types\";\nimport { markAppPathUnsaved } from \"./app\";\nimport { confirm } from \"./modals\";\n\ninterface NewTask extends Omit<ScheduledTask, \"job_id\"> {\n    job_id?: ScheduledTask[\"job_id\"];\n}\n\nexport const addScheduledTask =\n    (newTask: NewTask): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const app = getState().app;\n        if (!app) return;\n        const scheduledTasks = app.config.scheduled_tasks || [];\n        if (!newTask.job_id || scheduledTasks.filter((t) => t.job_id === newTask.job_id).length === 0) {\n            newTask.job_id = Array.from(\"xxxxxxxx\", (x) =>\n                String.fromCharCode(65 + Math.floor(26 * Math.random()))\n            ).join(\"\");\n        }\n        updateState(\n            `Add Scheduled Task: ${newTask.job_id}`,\n            update,\n            [\"app\", \"config\", \"scheduled_tasks\"],\n            (tasks: ScheduledTask[]) => (tasks ?? []).concat([newTask as ScheduledTask])\n        );\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"scheduled_tasks\"]));\n        dispatch(claimAchievement(\"scheduledBackgroundTask\"));\n    };\n\nexport const updateScheduledTask =\n    (task: ScheduledTask): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(`Update Scheduled Task: ${task.job_id}`, (state) => {\n            const existingTask = state.app?.config.scheduled_tasks?.find((t) => t.job_id === task.job_id);\n            if (!existingTask) return;\n            existingTask.time_spec = task.time_spec;\n            existingTask.task_name = task.task_name;\n        });\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"scheduled_tasks\"]));\n    };\n\nexport const deleteScheduledTask =\n    (task: ScheduledTask): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(`Delete Scheduled Task: ${task.job_id}`, (state) => {\n            if (!state.app) return;\n            state.app.config.scheduled_tasks = state.app.config.scheduled_tasks?.filter(\n                (t) => t.job_id !== task.job_id\n            );\n        });\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"scheduled_tasks\"]));\n    };\n\nexport const deleteScheduledTaskWithModal =\n    (task: ScheduledTask): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        if (\n            await dispatch(\n                confirm(\n                    \"Delete task?\",\n                    \"Are you sure you want to delete this scheduled task?\",\n                    { text: \"Delete\", variant: \"danger\" },\n                    \"Cancel\"\n                )\n            )\n        ) {\n            await dispatch(deleteScheduledTask(task));\n        }\n    };\n\nexport const cleanupBackgroundTasks =\n    (appId: AppId, lastUpdateTime: number): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        if (\n            await dispatch(\n                confirm(\n                    \"Cleanup tasks\",\n                    \"Are you sure you want to clean up finished tasks? Task state will be lost, but logs will remain.\"\n                )\n            )\n        ) {\n            log.warn(\"Cleaning up tasks!\");\n            return await api.cleanupBackgroundTasks(appId, lastUpdateTime);\n        }\n    };\n\nexport const getScheduledTasks = (state: State) => state.app?.config?.scheduled_tasks;\n\nexport const removeScheduledTasks = (): AnvilAction => (dispatch, getState, updateState) => {\n    const state = getState();\n    if (getScheduledTasks(state)?.length) {\n        throw new Error(\"Cannot remove tasks from this app\");\n    }\n    updateState((state) => {\n        if (!state.app) return;\n        delete state.app.config.scheduled_tasks;\n    });\n    // dispatch(markAppPathChanged([\"SETTINGS\", \"scheduled_tasks\"]));\n};\n\nexport type TaskUpdate = Partial<{\n    task_name: string;\n    n: string;\n    every: Every;\n    day: string;\n    hour: string;\n    minute: string;\n}>;\n\ntype TNumberLike = string | number | undefined;\n\nexport const MINUTE = \"minute\";\nexport const HOUR = \"hour\";\nexport const DAY = \"day\";\nexport const WEEK = \"week\";\nexport const MONTH = \"month\";\nexport const DAYS = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nexport const SUFFIXES = [\"th\", \"st\", \"nd\", \"rd\"];\nexport const PERIODS = [MINUTE, HOUR, DAY, WEEK, MONTH];\nexport const namePeriod = (p: string, n: TNumberLike) => p + (parseInt(n as string) <= 1 ? \"\" : \"s\");\nexport const getOrdinalSuffix = (day: TNumberLike) => {\n    day = parseInt(day as string);\n    const relevantDigits = day < 30 ? day % 20 : day % 30;\n    return relevantDigits <= 3 ? SUFFIXES[relevantDigits] : SUFFIXES[0];\n};\n\nfunction makeValidator(min: number, max = Number.MAX_SAFE_INTEGER, val: number | null = null) {\n    return (n?: string | number) => {\n        const asInt = parseInt(n as string);\n        if (isNaN(asInt)) return val ?? min;\n        return Math.min(Math.max(asInt, min), max);\n    };\n}\n\nconst Validate = {\n    N: makeValidator(1),\n    DoM: makeValidator(1, 31),\n    DoW: makeValidator(1, 7),\n    Hour: makeValidator(0, 23, 3),\n    Minute: makeValidator(0, 59),\n    Day(every?: Every, day?: TNumberLike) {\n        switch (every) {\n            case MONTH:\n                return Validate.DoM(day);\n            case WEEK:\n                return Validate.DoW(day);\n            default:\n                return 1;\n        }\n    },\n};\n\nexport const taskReducer = (state: NewTask, update: TaskUpdate) => {\n    const timeSpec = state.time_spec ?? {};\n    const atSpec = timeSpec.at ?? {};\n    const {\n        task_name = state.task_name,\n        n = timeSpec.n,\n        every = timeSpec.every,\n        day = atSpec.day,\n        minute = atSpec.minute,\n        hour = atSpec.hour,\n    } = update;\n\n    const at: AtSpec = {\n        day: Validate.Day(every, day),\n        hour: Validate.Hour(hour),\n        minute: Validate.Minute(minute),\n    };\n    switch (every) {\n        case MINUTE:\n            delete at.minute;\n        // Intentional fall-through: eslint-disable-next-line no-fallthrough\n        case HOUR:\n            delete at.hour;\n        // Intentional fall-through: eslint-disable-next-line no-fallthrough\n        case DAY:\n            delete at.day;\n        // Intentional fall-through: eslint-disable-next-line no-fallthrough\n        case WEEK:\n        case MONTH:\n            break;\n    }\n    return { ...state, task_name, time_spec: { n: Validate.N(n), every, at } };\n};\n\nexport const useFormatTimeSpec = (timeSpec: TimeSpec | undefined) =>\n    useMemo(() => {\n        if (!timeSpec) {\n            return \"\";\n        }\n        let when = \"\";\n        const plural = timeSpec.n && timeSpec.n > 1;\n        const atSpec = timeSpec.at ?? {};\n        switch (timeSpec.every) {\n            case \"minute\":\n                when = plural ? `every ${timeSpec.n} minutes` : \"every minute\";\n                break;\n            case \"hour\":\n                when = plural ? `every ${timeSpec.n} hours` : \"every hour\";\n                if (atSpec.minute != null) {\n                    when += `, at ∗:${((atSpec.minute || 0) + \"\").padStart(2, \"0\")}`;\n                }\n                break;\n            case \"day\":\n                when = plural ? `every ${timeSpec.n} days` : \"every day\";\n                if (atSpec.hour != null) {\n                    when += `, at ${((atSpec.hour || 0) + \"\").padStart(2, \"0\")}:${(\n                        (atSpec.minute || 0) + \"\"\n                    ).padStart(2, \"0\")} UTC`;\n                }\n                break;\n            case \"week\":\n                when = \"every \" + (plural ? `${timeSpec.n} weeks, on ` : \"\") + DAYS[(atSpec.day ?? 1) - 1];\n                if (atSpec.hour != null) {\n                    when += ` at ${((atSpec.hour || 0) + \"\").padStart(2, \"0\")}:${(\n                        (atSpec.minute || 0) + \"\"\n                    ).padStart(2, \"0\")} UTC`;\n                }\n                break;\n            case \"month\":\n                if (plural) {\n                    when = `every ${timeSpec.n} months, on the ${atSpec.day || 1}${getOrdinalSuffix(\n                        atSpec.day || 1\n                    )}`;\n                } else {\n                    when = `on ${atSpec.day || 1}${getOrdinalSuffix(atSpec.day || 1)} of every month, `;\n                }\n                if (atSpec.hour != null) {\n                    when += ` at ${((atSpec.hour || 0) + \"\").padStart(2, \"0\")}:${\n                        ((atSpec.minute || 0) + \"\").padStart(2, \"0\") || \"?\"\n                    } UTC`;\n                }\n                break;\n        }\n        return when;\n    }, [timeSpec]);\n","import { useDispatch } from \"react-redux\";\nimport { getAppId } from \"@/controllers/app\";\nimport { saveApp } from \"@/controllers/app/saving\";\nimport { openOrFocusBottomTab } from \"@/controllers/bottom-tabs\";\nimport { useWebsocketEventListener } from \"@/controllers/websocket\";\nimport * as ws from \"@/controllers/websocket\";\nimport type { AnvilAction, AnvilDispatch, AppId, ScriptRun, State } from \"@/types\";\nimport { sleep } from \"@/util\";\nimport { insertLogEventBySeq, scriptNameFromSessionStart } from \"./log-events\";\n\n// Extremely blunt instrument to prevent launching a script multiple times by clicking the button a lot before the first launch completes.\nconst launching: Record<string, boolean> = {};\n\nconst isPlaceholder = (run: ScriptRun) => run.state === \"LAUNCHING\" && run.sessionId === undefined;\n\nexport const runScript =\n    (scriptName: string): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        await dispatch(saveApp());\n        const appId = getAppId(getState())!;\n        if (launching[scriptName]) {\n            return;\n        }\n        launching[scriptName] = true;\n        // Create the placeholder run synchronously, before awaiting the RPC below - the\n        // server can send update events before that RPC resolves\n        updateState(({ scriptRuns }) => {\n            scriptRuns[scriptName] ??= [];\n            scriptRuns[scriptName].push({ state: \"LAUNCHING\", output: [] });\n        });\n        try {\n            const { session_id, task_id } = await ws.runScript(appId, scriptName);\n            updateState(({ scriptRuns }) => {\n                scriptRuns[scriptName] ??= [];\n                const runs = scriptRuns[scriptName];\n                // The SESSION_START event below may have already claimed the placeholder\n                // (and given it this sessionId), or it may not have arrived yet - either way,\n                // there's exactly one run to update.\n                const run = runs.find((run) => run.sessionId === session_id) ?? runs.find(isPlaceholder);\n                if (run) {\n                    run.sessionId = session_id;\n                    run.taskId = task_id;\n                } else {\n                    runs.push({ sessionId: session_id, taskId: task_id, state: \"LAUNCHING\", output: [] });\n                }\n            });\n        } catch (e) {\n            // Launch failed outright - remove the placeholder, there's nothing to show.\n            updateState(({ scriptRuns }) => {\n                if (scriptRuns[scriptName]) {\n                    scriptRuns[scriptName] = scriptRuns[scriptName].filter((run) => !isPlaceholder(run));\n                }\n            });\n            throw e;\n        } finally {\n            launching[scriptName] = false;\n        }\n\n        dispatch(openOrFocusBottomTab({ type: \"scriptRun\", scriptName }));\n    };\n\nexport const killScript =\n    (scriptName: string): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const appId = getAppId(state)!;\n        const runs = getScriptRuns(state)[scriptName] || [];\n        for (const run of runs) {\n            if (run.taskId) {\n                await ws.killScript(appId, run.taskId);\n            }\n        }\n    };\n\nexport const clearScriptOutput =\n    (scriptName: string): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ scriptRuns }) => {\n            if (scriptRuns[scriptName]) {\n                scriptRuns[scriptName] = scriptRuns[scriptName].filter((run) => run.state !== \"TERMINATED\");\n                for (const run of scriptRuns[scriptName]) {\n                    run.outputCleared = true;\n                    run.output.length = 0;\n                }\n            }\n        });\n    };\n\n// Selector to get script runs from state\nexport const getScriptRuns = (state: State) => state.scriptRuns;\n\nexport const deleteScriptRuns =\n    (scriptName: string): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(\"Delete script run\", ({ scriptRuns }) => {\n            delete scriptRuns[scriptName];\n        });\n    };\n\nconst sessionScriptName: Map<string, string> = new Map();\n\n// Exported for tests\nexport const handleScriptEvent =\n    (e: any): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const sessionId = e.session_id as string;\n        switch (e.event) {\n            case \"SESSION_START\": {\n                const scriptName = scriptNameFromSessionStart(e);\n                if (scriptName === null) {\n                    // Not a script run (see scriptNameFromSessionStart)\n                    break;\n                }\n                sessionScriptName.set(sessionId, scriptName);\n\n                updateState(({ scriptRuns }) => {\n                    scriptRuns[scriptName] ??= [];\n                    const runs = scriptRuns[scriptName];\n                    // Either we heard about this new session here first (before the\n                    // ws.runScript() response above), or it's already claimed the run - or\n                    // there's an unclaimed placeholder (from before it, or from a\n                    // SCRIPT_LAUNCH_STATUS event) still waiting for a sessionId.\n                    const run = runs.find((run) => run.sessionId === sessionId) ?? runs.find(isPlaceholder);\n                    if (run) {\n                        run.sessionId = sessionId;\n                        run.state = \"RUNNING\";\n                        run.session = e;\n                    } else {\n                        runs.push({ sessionId, session: e, state: \"RUNNING\", output: [] });\n                    }\n                });\n                break;\n            }\n            case \"LOG_EVENT\": {\n                updateState(({ scriptRuns }) => {\n                    const scriptName = sessionScriptName.get(sessionId);\n                    const run = scriptName && scriptRuns[scriptName]?.find((run) => run.sessionId === sessionId);\n                    if (run) {\n                        insertLogEventBySeq(run.output, e);\n                        if (e.type === \"background_task_ended\") {\n                            run.state = \"TERMINATED\";\n                        }\n                    }\n                    // else: not one of our script runs (e.g. a runner-launched BG task\n                    // arriving via a log_events: true subscription) - ignore.\n                });\n                break;\n            }\n            // Progress reported while the runtime is still starting/building, before the\n            // script's own session (and therefore its sessionId) exists - eg \"Waiting for\n            // server runtime to start/build...\". Correlate by script name instead; there can\n            // only be one un-started launch per script name (see `launching` above).\n            case \"SCRIPT_LAUNCH_STATUS\": {\n                updateState(({ scriptRuns }) => {\n                    const run = scriptRuns[e.script]?.find(isPlaceholder);\n                    if (run) {\n                        insertLogEventBySeq(run.output, e);\n                    }\n                });\n                break;\n            }\n        }\n    };\n\nexport const useScriptWebsocketEventListener = (appId?: AppId) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    useWebsocketEventListener(appId, (e) => {\n        if (e[\"bg-task-watch-key\"] || e.event === \"SCRIPT_LAUNCH_STATUS\") {\n            switch (e.event) {\n                case \"SESSION_START\":\n                case \"LOG_EVENT\":\n                case \"SCRIPT_LAUNCH_STATUS\":\n                    dispatch(handleScriptEvent(e));\n                    break;\n            }\n        }\n    });\n};\n","import { AppId, EnvironmentPid, SecretValue } from \"@/types\";\n\ntype AppSecretValue = Exclude<SecretValue[AppId], string>;\n\nconst isAppSecretValue = (value: SecretValue[AppId]): value is AppSecretValue =>\n    typeof value === \"object\" && value !== null;\n\nexport const getScopedSecretValue = (\n    secretValue: SecretValue,\n    appId: AppId,\n    environmentPid: EnvironmentPid | \"\",\n    { environmentType }: { environmentType?: string } = {}\n) => {\n    const appValue = secretValue[appId];\n    const environmentValue = environmentPid && isAppSecretValue(appValue) ? appValue.env_id?.[environmentPid] : undefined;\n    const appDefault = isAppSecretValue(appValue) ? appValue[\"\"] : appValue;\n    if (environmentValue) return environmentValue;\n    const scopes = environmentType === \"agent\" ? [\"all\"] : environmentType === \"test\" ? [\"test\", \"all\"] : [\"\", \"all\"];\n    for (const scope of scopes) {\n        const value = scope === \"\" ? appDefault : isAppSecretValue(appValue) ? appValue[scope] : undefined;\n        if (typeof value === \"string\" && value) return value;\n    }\n    if (environmentType !== \"agent\" && environmentType !== \"test\") return secretValue[\"\"];\n};\n\nexport const agentsCanReadSecret = (secretValue: SecretValue, appId: AppId) => {\n    const value = secretValue[appId];\n    return isAppSecretValue(value) && !!value.all;\n};\n\nexport const setScopedSecretValue = (\n    secretValue: SecretValue,\n    appId: AppId,\n    encryptedValue: string,\n    {\n        environmentPid,\n        test = false,\n        allowAgents = false,\n    }: { environmentPid?: EnvironmentPid; test?: boolean; allowAgents?: boolean } = {}\n): SecretValue => {\n    const appValue = secretValue[appId];\n    const appSecretValue = isAppSecretValue(appValue) ? appValue : appValue ? { \"\": appValue } : {};\n    if (test) {\n        return { ...secretValue, [appId]: { ...appSecretValue, test: encryptedValue } };\n    }\n    if (!environmentPid) {\n        const { \"\": _default, all: _all, ...rest } = appSecretValue;\n        if (allowAgents) {\n            return { ...secretValue, [appId]: { ...rest, all: encryptedValue } };\n        }\n        return { ...secretValue, [appId]: { ...rest, \"\": encryptedValue } };\n    }\n    return {\n        ...secretValue,\n        [appId]: {\n            ...appSecretValue,\n            env_id: { ...appSecretValue.env_id, [environmentPid || \"\"]: encryptedValue },\n        },\n    };\n};\n\nexport const hasEnvironmentSecretValue = (\n    secretValue: SecretValue,\n    appId: AppId,\n    environmentPid: EnvironmentPid | \"\"\n) => {\n    if (!environmentPid) return false;\n    const appValue = secretValue[appId];\n    return isAppSecretValue(appValue) && !!appValue.env_id?.[environmentPid];\n};\n\nexport const clearEnvironmentSecretValue = (\n    secretValue: SecretValue,\n    appId: AppId,\n    environmentPid: EnvironmentPid\n): SecretValue => {\n    const appValue = secretValue[appId];\n    if (!isAppSecretValue(appValue) || !appValue.env_id) return secretValue;\n    const environmentValues = { ...appValue.env_id };\n    delete environmentValues[environmentPid];\n    const { env_id, ...appSecretValue } = appValue;\n    return {\n        ...secretValue,\n        [appId]: Object.keys(environmentValues).length\n            ? { ...appSecretValue, env_id: environmentValues }\n            : appSecretValue,\n    };\n};\n\nexport const hasTestSecretValue = (secretValue: SecretValue, appId: AppId) => {\n    const appValue = secretValue[appId];\n    return isAppSecretValue(appValue) && !!appValue.test;\n};\n\nexport const clearTestSecretValue = (secretValue: SecretValue, appId: AppId): SecretValue => {\n    const appValue = secretValue[appId];\n    if (!isAppSecretValue(appValue) || !(\"test\" in appValue)) return secretValue;\n    const { test: _test, ...appSecretValue } = appValue;\n    return { ...secretValue, [appId]: appSecretValue };\n};\n","// The App Log output of server test runs' task sessions. The server tags a run's task with the launching IDE\n// websocket's watch key, so the task's log-firehose events (SESSION_START, BG_TASK_LAUNCHED, LOG_EVENT) stream to the\n// IDE that started the run. pytest's terminal output arrives as the task's print events.\n//\n// Logs are keyed by session ID rather than run ID: a run only learns its session ID once its task has launched, and\n// the task's events can arrive before that. The output is raw LOG_EVENTs, the same shape as a session's App Log, so a\n// run we didn't see stream (eg one from before a reload) could fill its entry from the App Log instead.\nimport { insertLogEventBySeq } from \"./log-events\";\nimport type { TestRun } from \"./server-test-runs\";\n\nexport const SERVER_TESTS_TASK_NAME = \"anvil.private.testing.run_server_tests\";\n\nexport interface ServerTestSessionLog {\n    /** Whether the session is a server test run's task. Undefined until its SESSION_START or BG_TASK_LAUNCHED. */\n    isServerTest?: boolean;\n    /** Raw SESSION_START event, for the log renderer */\n    session?: any;\n    /** Raw LOG_EVENTs, in seq order */\n    output: any[];\n}\n\nexport const isServerTestLogEvent = (e: any) =>\n    !!e?.[\"bg-task-watch-key\"] &&\n    (e.event === \"SESSION_START\" || e.event === \"BG_TASK_LAUNCHED\" || e.event === \"LOG_EVENT\");\n\nconst setTaskName = (log: ServerTestSessionLog, taskName?: string) => {\n    if (typeof taskName !== \"string\") {\n        return;\n    }\n    log.isServerTest = taskName.replace(/^task:/, \"\") === SERVER_TESTS_TASK_NAME;\n    if (!log.isServerTest) {\n        // Another watched task, such as a script run. We only needed its output in case it was ours.\n        log.output = [];\n    }\n};\n\n/** Mutates logs: merges a watch-key-tagged log-firehose event. The events can arrive in any order. */\nexport function applyServerTestLogEvent(logs: Record<string, ServerTestSessionLog>, e: any) {\n    const sessionId = e?.session_id;\n    if (!sessionId) {\n        return;\n    }\n    const log = (logs[sessionId] ??= { output: [] });\n    switch (e.event) {\n        case \"SESSION_START\":\n            log.session = e;\n            setTaskName(log, e.data?.func);\n            break;\n        case \"BG_TASK_LAUNCHED\":\n            setTaskName(log, e.task_name);\n            break;\n        case \"LOG_EVENT\":\n            if (log.isServerTest !== false) {\n                insertLogEventBySeq(log.output, e);\n            }\n            break;\n    }\n}\n\n/** Mutates logs: forgets the logs of complete runs and of sessions that aren't server test runs */\nexport function pruneServerTestLogs(logs: Record<string, ServerTestSessionLog>, runs: TestRun[]) {\n    const completeSessionIds = new Set(\n        runs.filter((run) => run.state.status === \"complete\" && run.session_id).map((run) => run.session_id)\n    );\n    for (const [sessionId, log] of Object.entries(logs)) {\n        if (log.isServerTest === false || completeSessionIds.has(sessionId)) {\n            delete logs[sessionId];\n        }\n    }\n}\n\n/** The most output the run summary shows. Past this it shows the end, where pytest reports failures and its summary. */\nexport const MAX_SERVER_TEST_OUTPUT_LENGTH = 200_000;\n\n/**\n * A run's output as the run summary shows it: the text the task printed, which is pytest's terminal output. pytest\n * prints some lines in fragments, such as a character per test on its progress line, so we join the text rather than\n * showing each event separately. Other events aren't shown: a harness error is in the run's state, and tasks the tests\n * launch have their own logs.\n */\nexport function serverTestOutputText(output: any[], maxLength = MAX_SERVER_TEST_OUTPUT_LENGTH): string {\n    let text = output\n        .filter((event) => event.type === \"print\")\n        .map((event) => event.log_text ?? \"\")\n        .join(\"\");\n    if (text.length > maxLength) {\n        text = \"[Earlier output not shown]\\n\" + text.slice(-maxLength);\n    }\n    return text;\n}\n","// A server test run's state in the IDE, built from HTTP snapshots and live TEST_EVENTs. Each TEST_EVENT is shaped\n// like an update to the run's rows in the DB, so applying a run's events gives the same state as reading the run.\n// overlayTestRuns combines runs to show each test's latest result, including tests a partial run didn't select.\n// See SERVER_TESTS_MESSAGES.md for the events, and SERVER_TESTS_MESSAGE_TRANSPORT.md for the merge rules.\n\nexport interface TestRunError {\n    message: string;\n    type?: string;\n    traceback?: string;\n}\n\nexport interface CollectionError extends TestRunError {\n    file_path: string;\n}\n\nexport interface TestPhaseError extends TestRunError {\n    phase: \"setup\" | \"call\" | \"teardown\";\n}\n\nexport type TestRunStatus = \"launching_server\" | \"collecting_tests\" | \"running_tests\" | \"complete\";\nexport type TestOutcome = \"passed\" | \"failed\" | \"error\" | \"skipped\" | \"xfailed\" | \"xpassed\";\nexport type TestResultStatus = \"pending\" | \"running\" | \"finished\" | \"not_run\" | \"did_not_finish\";\n\nexport interface TestSelection {\n    test_targets?: string[];\n    keyword_expression?: string;\n}\n\n/** The options a run was started with, from RUN_SERVER_TESTS */\nexport interface TestRunOptions {\n    selection?: TestSelection;\n    collect_only?: boolean;\n}\n\n/** The run's row */\nexport interface TestRunState {\n    status?: TestRunStatus;\n    options?: TestRunOptions;\n    launch_message?: string;\n    pytest_version?: string;\n    args?: string[];\n    collection_errors?: CollectionError[];\n    exit_code?: string | null;\n    counts?: Record<TestOutcome, number> | null;\n    duration?: number | null;\n    error?: TestRunError;\n}\n\nexport interface TestResult {\n    status: TestResultStatus;\n    outcome?: TestOutcome;\n    duration?: number;\n    errors?: TestPhaseError[];\n    reason?: string;\n    stdout?: string;\n    stderr?: string;\n    log?: string;\n}\n\nexport interface DiscoveredTest {\n    test_id: string;\n    file_path: string;\n    line: number | null;\n    name: string;\n}\n\nexport type TestEvent =\n    | ({ type: \"test_run_update\" } & TestRunState)\n    | { type: \"discovered_tests\"; tests: DiscoveredTest[] }\n    | { type: \"test_updates\"; tests: { test_id: string; result: TestResult }[] };\n\nexport interface TestEventEnvelope {\n    event: \"TEST_EVENT\";\n    app: string;\n    run_id: string;\n    seqno: number;\n    session_id?: string;\n    timestamp: number;\n    test_event: TestEvent;\n}\n\n/** A run as read over HTTP. It includes every event up to `seqno`. */\nexport interface TestRunSnapshot {\n    run_id: string;\n    session_id?: string;\n    created_at: number;\n    seqno: number;\n    state: TestRunState;\n    /** Null until the run has discovered its tests */\n    discovered_tests: DiscoveredTest[] | null;\n    /** test_id -> result, for the tests the run selected */\n    results: Record<string, TestResult>;\n}\n\nexport interface TestRun {\n    run_id: string;\n    session_id?: string;\n    created_at?: number;\n    /** The seqno of the last event applied */\n    seqno: number;\n    state: TestRunState;\n    /** Null until the run has discovered its tests */\n    discovered_tests: DiscoveredTest[] | null;\n    /** test_id -> result, for the tests the run selected */\n    results: Record<string, TestResult>;\n}\n\n/** The IDE's state for one run: the run itself, plus the live events it can't apply yet */\nexport interface TestRunTracker {\n    run_id: string;\n    run: TestRun;\n    /** Events that arrived after a gap in seqno, in seqno order */\n    heldEvents: TestEventEnvelope[];\n}\n\n/** A run with no events applied: its state at seqno 0 */\nexport const newTestRunTracker = (run_id: string): TestRunTracker => ({\n    run_id,\n    run: { run_id, seqno: 0, state: {}, discovered_tests: null, results: {} },\n    heldEvents: [],\n});\n\nexport const isTestRunComplete = (tracker: TestRunTracker) => tracker.run.state.status === \"complete\";\n\nconst applyEventToRun = (run: TestRun, { seqno, session_id, test_event }: TestEventEnvelope) => {\n    run.seqno = seqno;\n    if (session_id) {\n        run.session_id = session_id;\n    }\n\n    switch (test_event.type) {\n        case \"test_run_update\": {\n            const { type: _type, ...changes } = test_event;\n            Object.assign(run.state, changes);\n            break;\n        }\n        case \"discovered_tests\":\n            run.discovered_tests = test_event.tests;\n            break;\n        case \"test_updates\":\n            for (const { test_id, result } of test_event.tests) {\n                run.results[test_id] = result;\n            }\n            break;\n    }\n};\n\n/** Applies held events for each one in sequence, dropping any that are already applied. */\nconst applyHeldEvents = (tracker: TestRunTracker) => {\n    const run = tracker.run;\n    while (tracker.heldEvents.length > 0 && tracker.heldEvents[0].seqno <= run.seqno + 1) {\n        const event = tracker.heldEvents.shift()!;\n        if (event.seqno === run.seqno + 1) {\n            applyEventToRun(run, event);\n        }\n    }\n};\n\n/**\n * Applies a snapshot of the run if it's newer than the run we have, then applies any held events that follow it.\n * Returns whether we still need a snapshot (if some held events still can't be applied).\n */\nexport const applyTestRunSnapshot = (tracker: TestRunTracker, snapshot: TestRunSnapshot): boolean => {\n    const run = tracker.run;\n    // More than one read can be in flight, so an older snapshot can arrive after a newer one.\n    if (snapshot.run_id === tracker.run_id && snapshot.seqno > run.seqno) {\n        const { state, results, ...fields } = snapshot;\n        Object.assign(run, fields);\n        run.state = { ...state };\n        run.results = { ...results };\n        applyHeldEvents(tracker);\n    }\n    return tracker.heldEvents.length > 0;\n};\n\n/**\n * Applies a live event if it's the next one, drops it if it's already applied, or holds on to it otherwise.\n * Returns whether we need a snapshot (if there's a seqno gap).\n */\nexport const applyTestEvent = (tracker: TestRunTracker, event: TestEventEnvelope): boolean => {\n    if (event.run_id === tracker.run_id && event.seqno > tracker.run.seqno) {\n        // Drop everything up to this event from the held events\n        if (!tracker.heldEvents.some(({ seqno }) => seqno === event.seqno)) {\n            const index = tracker.heldEvents.findIndex(({ seqno }) => seqno > event.seqno);\n            tracker.heldEvents.splice(index === -1 ? tracker.heldEvents.length : index, 0, event);\n        }\n        applyHeldEvents(tracker);\n    }\n    return tracker.heldEvents.length > 0;\n};\n\n/** A test's row across several runs */\nexport interface OverlaidTestResult extends DiscoveredTest {\n    result?: TestResult;\n    /** The run `result` is from */\n    result_run_id?: string;\n}\n\nexport type TestRunOverlay = Record<string, OverlaidTestResult>;\n\n/**\n * Lays a run over the runs before it, following the rules for applying a run's events on top of the previous run's\n * state. Once the run has discovered its tests, they're the tests that exist. Each one has the run's result if it has\n * one, or otherwise the result from the runs before.\n */\nconst layerTestRun = (base: TestRunOverlay, run: TestRun): TestRunOverlay => {\n    // Failed collection invalidates the previous test list and its results.\n    if (run.state.collection_errors?.length) {\n        return {};\n    }\n    if (!run.discovered_tests) {\n        return base;\n    }\n    const overlay: TestRunOverlay = {};\n    for (const test of run.discovered_tests) {\n        const { test_id } = test;\n        const result = run.results[test_id];\n        const baseRow = base[test_id];\n        overlay[test_id] = result\n            ? { ...test, result, result_run_id: run.run_id }\n            : { ...test, ...(baseRow?.result && { result: baseRow.result, result_run_id: baseRow.result_run_id }) };\n    }\n    return overlay;\n};\n\n// run -> its last layer. Runs are updated immutably in the store, so older runs keep their identity while runs are\n// added or the latest run gets events. Their layers are reused, and we only rebuild from the first run that changed.\nconst layerCache = new WeakMap<TestRun, { base: TestRunOverlay; overlay: TestRunOverlay }>();\nconst EMPTY_OVERLAY: TestRunOverlay = {};\n\n/** Each test's latest result across `runs`, oldest first. */\nexport const overlayTestRuns = (runs: TestRun[]): TestRunOverlay =>\n    runs.reduce((base, run) => {\n        const cached = layerCache.get(run);\n        if (cached?.base === base) {\n            return cached.overlay;\n        }\n        const overlay = layerTestRun(base, run);\n        layerCache.set(run, { base, overlay });\n        return overlay;\n    }, EMPTY_OVERLAY);\n","import { useEffect } from \"react\";\nimport { shallowEqual, useDispatch, useSelector } from \"react-redux\";\nimport { createSelector } from \"reselect\";\nimport * as api from \"@/api\";\nimport { getAppExtraFiles, getAppId, getAppIsEditable } from \"@/controllers/app\";\nimport { saveApp } from \"@/controllers/app/saving\";\nimport { applyServerTestLogEvent, isServerTestLogEvent, pruneServerTestLogs } from \"@/controllers/server-test-logs\";\nimport {\n    type TestEventEnvelope,\n    type TestRun,\n    type TestRunOptions,\n    type TestRunOverlay,\n    type TestRunTracker,\n    applyTestEvent,\n    applyTestRunSnapshot,\n    isTestRunComplete,\n    newTestRunTracker,\n    overlayTestRuns,\n} from \"@/controllers/server-test-runs\";\nimport * as ws from \"@/controllers/websocket\";\nimport { useWebsocketEventListener } from \"@/controllers/websocket\";\nimport type {\n    AnvilAction,\n    AnvilAsyncAction,\n    AnvilDispatch,\n    AppId,\n    ServerTestListFilter,\n    ServerTestPanelState,\n    State,\n} from \"@/types\";\nimport { rebuildCodeStructureAndSyncCache } from \"./app/code\";\nimport {\n    SERVER_TEST_REQUIREMENTS_PATH,\n    deleteExtraFileEntry,\n    getExtraFileEntry,\n    hasExtraFileConflictAtPath,\n} from \"./app/extra-files\";\nimport { alert, confirm } from \"./modals\";\nimport { getTestingEnabled } from \"./services\";\nimport { forceCloseTabs, getTabs } from \"./tabs\";\n\nconst createServerTestPanelState = (): ServerTestPanelState => ({\n    selectedTestId: null,\n    keywordExpression: \"\",\n    clearedRunIds: {},\n    listFilter: \"all\",\n});\n\nconst DEFAULT_SERVER_TEST_PANEL_STATE = createServerTestPanelState();\n\nexport const getServerTestPanelState = (state: State): ServerTestPanelState => {\n    const appId = getAppId(state);\n\n    if (!appId) {\n        return DEFAULT_SERVER_TEST_PANEL_STATE;\n    }\n\n    return state.editor.serverTestPanelStateByApp[appId] ?? DEFAULT_SERVER_TEST_PANEL_STATE;\n};\n\nexport const setSelectedServerTestId =\n    (testId: string | null): AnvilAction =>\n    (_dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n\n        if (!appId) {\n            return;\n        }\n\n        updateState(\"Select server test result\", ({ editor }) => {\n            const panelState = (editor.serverTestPanelStateByApp[appId] ??= createServerTestPanelState());\n\n            panelState.selectedTestId = testId;\n        });\n    };\n\nexport const setServerTestKeywordExpression =\n    (expression: string): AnvilAction =>\n    (_dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n\n        if (!appId) {\n            return;\n        }\n\n        updateState(\"Update server-test keyword expression\", ({ editor }) => {\n            const panelState = (editor.serverTestPanelStateByApp[appId] ??= createServerTestPanelState());\n\n            panelState.keywordExpression = expression;\n        });\n    };\n\nexport const getServerTestListFilter = (state: State): ServerTestListFilter =>\n    getServerTestPanelState(state).listFilter ?? \"all\";\n\nexport const setServerTestListFilter =\n    (filter: ServerTestListFilter): AnvilAction =>\n    (_dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n\n        if (!appId) {\n            return;\n        }\n\n        updateState(\"Change server-test list filter\", ({ editor }) => {\n            const panelState = (editor.serverTestPanelStateByApp[appId] ??= createServerTestPanelState());\n\n            panelState.listFilter = filter;\n        });\n    };\n\nexport const getBottomPanelServerTestListWidth = (state: State) => state.editor.bottomPanelServerTestListWidth;\n\nexport const setBottomPanelServerTestListWidth =\n    (width: number): AnvilAction =>\n    (_dispatch, _getState, updateState) => {\n        updateState(\"Resize server-test list\", ({ editor }) => {\n            editor.bottomPanelServerTestListWidth = width;\n        });\n    };\n\nconst getLatestServerTestRunTracker = (state: State) => {\n    const runId = state.serverTestRunIds.at(-1);\n    return runId ? state.serverTestRuns[runId] : undefined;\n};\n\nexport const getLatestServerTestRun = (state: State) => getLatestServerTestRunTracker(state)?.run;\n\nexport const getLatestVisibleServerTestRun = (state: State) => {\n    const latestRun = getLatestServerTestRun(state);\n    const { clearedRunIds } = getServerTestPanelState(state);\n\n    if (latestRun && !clearedRunIds?.[latestRun.run_id]) {\n        return latestRun;\n    }\n\n    return undefined;\n};\n\n/** The App Log output of a run's task, if it streamed to this IDE */\nexport const getServerTestRunLog = (run?: TestRun) => (state: State) =>\n    run?.session_id ? state.serverTestSessionLogs[run.session_id] : undefined;\n\nconst getServerTestRunsInOrder = createSelector(\n    [(state: State) => state.serverTestRuns, (state: State) => state.serverTestRunIds],\n    (runs, runIds) => runIds.map((runId) => runs[runId].run)\n);\n\nexport const getLatestServerTestExecution = createSelector([getServerTestRunsInOrder], (runs) => {\n    for (let index = runs.length - 1; index >= 0; index--) {\n        const run = runs[index];\n\n        if (!run.state.options?.collect_only) {\n            return run;\n        }\n    }\n\n    return undefined;\n});\n\nexport const getLatestServerTestDiscovery = createSelector([getServerTestRunsInOrder], (runs) => {\n    for (let index = runs.length - 1; index >= 0; index--) {\n        const discovered = runs[index].discovered_tests;\n\n        if (discovered !== null) {\n            return discovered;\n        }\n    }\n\n    return undefined;\n});\n\n/** test_id -> the test's latest result across the runs we have, and the run it's from */\nconst getRawServerTestResults = createSelector([getServerTestRunsInOrder], overlayTestRuns);\n\n/** strip results belonging to cleared runs while preserving test discovery */\nexport const getServerTestResults = createSelector(\n    [getRawServerTestResults, getServerTestPanelState],\n    (results, panelState): TestRunOverlay => {\n        const clearedRunIds = panelState.clearedRunIds ?? {};\n        let visibleResults: TestRunOverlay | undefined;\n\n        for (const [testId, test] of Object.entries(results)) {\n            if (!test.result_run_id || !clearedRunIds[test.result_run_id]) {\n                continue;\n            }\n\n            visibleResults ??= { ...results };\n\n            visibleResults[testId] = {\n                test_id: test.test_id,\n                file_path: test.file_path,\n                line: test.line,\n                name: test.name,\n            };\n        }\n\n        return visibleResults ?? results;\n    }\n);\n\nexport const getFailedServerTestIds = createSelector([getServerTestResults], (tests) =>\n    Object.values(tests)\n        .filter(\n            ({ result }) => result?.status === \"finished\" && (result.outcome === \"failed\" || result.outcome === \"error\")\n        )\n        .map(({ test_id }) => test_id)\n);\n\nexport const getServerTestRunRequest = (state: State) => state.serverTestRunRequest;\n\n/** Results for display, including pending feedback for explicitly requested tests. */\nexport const getServerTestDisplayResults = createSelector(\n    [getServerTestResults, getServerTestRunRequest, getLatestServerTestRun, (state: State) => getAppId(state)],\n    (results, request, latestRun, appId): TestRunOverlay => {\n        const requestedTargets =\n            request?.appId === appId && !request?.options.collect_only\n                ? request?.options.selection?.test_targets\n                : undefined;\n\n        const activeTargets =\n            latestRun && latestRun.state.status !== \"complete\" && !latestRun.state.options?.collect_only\n                ? latestRun.state.options?.selection?.test_targets\n                : undefined;\n\n        const requestedIds = new Set(requestedTargets);\n        const activeIds = new Set(activeTargets);\n\n        let displayedResults: TestRunOverlay | undefined;\n\n        for (const [testId, test] of Object.entries(results)) {\n            const requestedByClient = requestedIds.has(testId);\n            const waitingForBackend = activeIds.has(testId) && test.result_run_id !== latestRun?.run_id;\n\n            if (!requestedByClient && !waitingForBackend) {\n                continue;\n            }\n\n            displayedResults ??= { ...results };\n            displayedResults[testId] = {\n                ...test,\n                result: { status: \"pending\" },\n            };\n        }\n\n        return displayedResults ?? results;\n    }\n);\n\nexport const getLatestVisibleServerTestExecution = createSelector(\n    [getLatestServerTestExecution, getServerTestPanelState],\n    (run, panelState) => {\n        // Clearing the latest execution shouldn't reveal an older one.\n        if (!run || panelState.clearedRunIds?.[run.run_id]) {\n            return undefined;\n        }\n\n        return run;\n    }\n);\n\nexport const getFilteredServerTests = createSelector(\n    [\n        getServerTestDisplayResults,\n        getServerTestListFilter,\n        getLatestVisibleServerTestExecution,\n        getServerTestRunRequest,\n        (state: State) => getAppId(state),\n    ],\n    (results, filter, latestExecution, request, appId) => {\n        let tests = Object.values(results);\n\n        if (filter === \"failed\") {\n            tests = tests.filter(\n                ({ result }) =>\n                    result?.status === \"finished\" && (result.outcome === \"failed\" || result.outcome === \"error\")\n            );\n        } else if (filter === \"latest_run\") {\n            const startingExecution = request?.appId === appId && !request?.options.collect_only;\n\n            // Don't show the previous execution while a new one starts.\n            if (startingExecution || !latestExecution) {\n                return [];\n            }\n\n            const selectedIds = new Set(Object.keys(latestExecution.results));\n\n            tests = tests.filter(({ test_id }) => selectedIds.has(test_id));\n        }\n\n        return tests.sort(\n            (a, b) =>\n                a.file_path.localeCompare(b.file_path) || (a.line ?? 0) - (b.line ?? 0) || a.name.localeCompare(b.name)\n        );\n    }\n);\n\n// The runs to watch: every run we have that's incomplete. More than one can be running at once, and an earlier run's\n// results still show for the tests a later run didn't select.\nconst getWatchedServerTestRunIds = createSelector(\n    [(state: State) => state.serverTestRuns, (state: State) => state.serverTestRunIds],\n    (runs, runIds) => runIds.filter((runId) => !isTestRunComplete(runs[runId]))\n);\n\nexport const getAreServerTestsRunning = createSelector([getWatchedServerTestRunIds], (runIds) => runIds.length > 0);\nexport const getAreServerTestsBusy = createSelector(\n    [getAreServerTestsRunning, getServerTestRunRequest, (state: State) => getAppId(state)],\n    (testsAreRunning, requestedRun, appId) => testsAreRunning || (!!appId && requestedRun?.appId === appId)\n);\n\nexport const clearDisplayedServerTestResults = (): AnvilAction => (dispatch, getState, updateState) => {\n    const state = getState();\n    const appId = getAppId(state);\n\n    if (!appId || getAreServerTestsBusy(state)) {\n        return;\n    }\n\n    const visibleResults = getServerTestResults(state);\n    const hasResults = Object.values(visibleResults).some(({ result }) => result !== undefined);\n\n    if (!hasResults) {\n        return;\n    }\n\n    const runIds = [...state.serverTestRunIds];\n\n    updateState(\"Clear displayed server-test results\", ({ editor }) => {\n        const panelState = (editor.serverTestPanelStateByApp[appId] ??= createServerTestPanelState());\n\n        panelState.clearedRunIds ??= {};\n\n        for (const runId of runIds) {\n            panelState.clearedRunIds[runId] = true;\n        }\n\n        panelState.selectedTestId = null;\n    });\n\n    dispatch(setServerTestListFilter(\"all\"));\n};\n\n// Run ID -> number of snapshot reads in flight, so we don't send another read for every event after a gap\nconst snapshotReadsInFlight = new Map<string, number>();\n\nconst fetchServerTestRunSnapshot =\n    (appId: AppId, runId: string): AnvilAction =>\n    async (dispatch) => {\n        snapshotReadsInFlight.set(runId, (snapshotReadsInFlight.get(runId) ?? 0) + 1);\n        let snapshot;\n        try {\n            snapshot = await api.getServerTestRun(appId, runId);\n        } catch (e) {\n            console.warn(\"[server-tests] Failed to read test run\", runId, e);\n            return;\n        } finally {\n            const n = snapshotReadsInFlight.get(runId)! - 1;\n            if (n > 0) {\n                snapshotReadsInFlight.set(runId, n);\n            } else {\n                snapshotReadsInFlight.delete(runId);\n            }\n        }\n\n        dispatch(updateServerTestRun(appId, runId, (tracker) => applyTestRunSnapshot(tracker, snapshot)));\n    };\n\n// Periodically re-fetch the runs we're watching, to capture dropped events and trigger orphan checks\nconst WATCHED_RUN_REFETCH_MS = 60 * 1000;\n\nexport const refetchWatchedServerTestRuns =\n    (appId: AppId): AnvilAction =>\n    (dispatch, getState) => {\n        if (getAppId(getState()) !== appId) {\n            return;\n        }\n        for (const runId of getWatchedServerTestRunIds(getState())) {\n            if (!snapshotReadsInFlight.has(runId)) {\n                void dispatch(fetchServerTestRunSnapshot(appId, runId));\n            }\n        }\n    };\n\n// Applies an event or snapshot to the run, then triggers a snapshot fetch if needed\n// The apply function returns whether a snapshot is needed after applying the event or snapshot\nconst updateServerTestRun =\n    (appId: AppId, runId: string, apply: (tracker: TestRunTracker) => boolean): AnvilAction =>\n    (dispatch, _getState, updateState) => {\n        let needsSnapshot = false;\n        updateState(({ serverTestRuns }) => {\n            const tracker = serverTestRuns[runId];\n            if (tracker) {\n                needsSnapshot = apply(tracker);\n            }\n        });\n        if (needsSnapshot && !snapshotReadsInFlight.has(runId)) {\n            void dispatch(fetchServerTestRunSnapshot(appId, runId));\n        }\n    };\n\n/** Shows the user's latest run for the app. If it's incomplete, we then watch it. */\nconst loadLatestServerTestRun =\n    (appId: AppId): AnvilAction =>\n    async (_dispatch, getState, updateState) => {\n        if (!getTestingEnabled(getState()) || getAppId(getState()) !== appId) {\n            return;\n        }\n        // Any runs we have are for the previous app\n        updateState((state) => {\n            state.serverTestRuns = {};\n            state.serverTestRunIds = [];\n            state.serverTestSessionLogs = {};\n        });\n        let snapshot;\n        try {\n            snapshot = await api.getLatestServerTestRun(appId);\n        } catch (e) {\n            console.warn(\"[server-tests] Failed to read latest test run\", e);\n            return;\n        }\n        if (!snapshot) {\n            return;\n        }\n        updateState((state) => {\n            if (getAppId(state) !== appId) {\n                return;\n            }\n            if (!state.serverTestRuns[snapshot.run_id]) {\n                state.serverTestRuns[snapshot.run_id] = newTestRunTracker(snapshot.run_id);\n                // Any runs we have were started while we were reading, so this one is older\n                state.serverTestRunIds.unshift(snapshot.run_id);\n            }\n            applyTestRunSnapshot(state.serverTestRuns[snapshot.run_id], snapshot);\n        });\n    };\n\n/**\n * Shows why a server tests call failed, unless the IDE has moved to another app. Every error from a websocket call has\n * a message.\n */\nconst alertServerTestsFailure =\n    (appId: AppId, title: string, e: unknown): AnvilAction =>\n    (dispatch, getState) => {\n        if (getAppId(getState()) === appId) {\n            void dispatch(alert(title, (e as { message: string }).message));\n        }\n    };\n\nexport const runServerTests =\n    (options?: TestRunOptions): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const initialState = getState();\n        const appId = getAppId(initialState);\n\n        if (!appId || !getTestingEnabled(initialState) || getAreServerTestsBusy(initialState)) {\n            return;\n        }\n\n        const normalizedOptions = options ?? {};\n\n        updateState(\"Request server-test run\", (state) => {\n            state.serverTestRunRequest = {\n                appId,\n                options: normalizedOptions,\n            };\n        });\n\n        // Capture the stored request so cleanup cannot clear a newer request.\n        const request = getServerTestRunRequest(getState());\n\n        try {\n            await dispatch(saveApp());\n\n            if (getAppId(getState()) !== appId || !getTestingEnabled(getState())) {\n                return;\n            }\n\n            const { run_id } = await ws.runServerTests(appId, normalizedOptions);\n\n            if (getAppId(getState()) !== appId || !getTestingEnabled(getState())) {\n                return;\n            }\n\n            // We watch the new run, then read it once the watch is set up.\n            updateState((state) => {\n                // We only show the latest run's output.\n                pruneServerTestLogs(\n                    state.serverTestSessionLogs,\n                    state.serverTestRunIds.map((runId) => state.serverTestRuns[runId].run)\n                );\n\n                const tracker = newTestRunTracker(run_id);\n                tracker.run.state = {\n                    status: \"launching_server\",\n                    options: normalizedOptions,\n                };\n\n                state.serverTestRuns[run_id] = tracker;\n                state.serverTestRunIds.push(run_id);\n            });\n\n            dispatch(setServerTestListFilter(options?.collect_only ? \"all\" : \"latest_run\"));\n        } catch (error) {\n            console.warn(\"[server-tests] Failed to start test run\", error);\n            dispatch(alertServerTestsFailure(appId, \"Couldn't run the server tests\", error));\n        } finally {\n            if (getServerTestRunRequest(getState()) === request) {\n                updateState(\"Finish server-test run request\", (state) => {\n                    state.serverTestRunRequest = null;\n                });\n            }\n        }\n    };\n\nexport const rerunLastServerTests = (): AnvilAction => (dispatch, getState) => {\n    const state = getState();\n\n    if (!getTestingEnabled(state) || getAreServerTestsBusy(state)) {\n        return;\n    }\n\n    const latestExecution = getLatestServerTestExecution(state);\n\n    if (!latestExecution) {\n        return;\n    }\n\n    dispatch(runServerTests(latestExecution.state.options));\n};\n\nexport const rerunFailedServerTests = (): AnvilAction => (dispatch, getState) => {\n    const state = getState();\n\n    if (!getTestingEnabled(state) || getAreServerTestsRunning(state)) {\n        return;\n    }\n\n    const testTargets = getFailedServerTestIds(state);\n\n    if (testTargets.length === 0) {\n        return;\n    }\n\n    dispatch(\n        runServerTests({\n            selection: {\n                test_targets: testTargets,\n            },\n        })\n    );\n};\n\n/**\n * Cancels every run we're watching. The server completes each run straight away, without waiting for its task to\n * stop. The complete arrives as a TEST_EVENT.\n */\nexport const cancelServerTestRuns = (): AnvilAction => async (dispatch, getState) => {\n    const state = getState();\n    const appId = getAppId(state);\n\n    if (!appId || !getTestingEnabled(state)) {\n        return;\n    }\n\n    await Promise.all(\n        getWatchedServerTestRunIds(state).map(async (runId) => {\n            try {\n                await ws.cancelServerTestRun(appId, runId);\n            } catch (e) {\n                console.warn(\"[server-tests] Failed to cancel test run\", runId, e);\n                dispatch(alertServerTestsFailure(appId, \"Couldn't cancel the server tests\", e));\n            }\n        })\n    );\n};\n\nexport const useServerTestsWebsocketEventListener = (appId?: AppId) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const testingEnabled = useSelector(getTestingEnabled);\n    const test_run_ids = useSelector(getWatchedServerTestRunIds, shallowEqual);\n\n    const enabledAppId = testingEnabled ? appId : undefined;\n    const watchingRuns = test_run_ids.length > 0;\n\n    useEffect(() => {\n        if (enabledAppId) {\n            void dispatch(loadLatestServerTestRun(enabledAppId));\n        }\n    }, [enabledAppId]);\n\n    useEffect(() => {\n        if (!enabledAppId || !watchingRuns) {\n            return;\n        }\n        const interval = setInterval(\n            () => dispatch(refetchWatchedServerTestRuns(enabledAppId)),\n            WATCHED_RUN_REFETCH_MS\n        );\n        return () => clearInterval(interval);\n    }, [enabledAppId, watchingRuns]);\n\n    useWebsocketEventListener(\n        enabledAppId,\n        (e) => {\n            if (enabledAppId && e.event === \"TEST_EVENT\") {\n                const event = e as TestEventEnvelope;\n                dispatch(updateServerTestRun(enabledAppId, event.run_id, (tracker) => applyTestEvent(tracker, event)));\n            } else if (enabledAppId && isServerTestLogEvent(e)) {\n                dispatch((_dispatch, _getState, updateState) => {\n                    updateState(({ serverTestSessionLogs }) => applyServerTestLogEvent(serverTestSessionLogs, e));\n                });\n            }\n        },\n        // Once the server is sending us the runs' events (including after a reconnect), read their state.\n        // This reads every watched run whenever the list changes, not just the new ones. Changing the list\n        // re-registers the listener, which briefly drops our watch on all of them, so we could miss an event on any.\n        enabledAppId && test_run_ids.length > 0\n            ? () => {\n                  for (const runId of test_run_ids) {\n                      void dispatch(fetchServerTestRunSnapshot(enabledAppId, runId));\n                  }\n              }\n            : undefined,\n        { test_run_ids }\n    );\n};\n\nexport const deleteFromTestingSuite =\n    (path: string): AnvilAsyncAction<void> =>\n    async (dispatch, getState) => {\n        const state = getState();\n        const appId = getAppId(state);\n\n        const entry = getExtraFileEntry(getAppExtraFiles(state), path);\n\n        if (\n            !appId ||\n            !getAppIsEditable(state) ||\n            !path.startsWith(\"tests/server_tests/\") ||\n            path === \"tests/server_tests/__init__.py\" ||\n            path === SERVER_TEST_REQUIREMENTS_PATH ||\n            entry === undefined\n        ) {\n            return;\n        }\n        const isDirectory = typeof entry !== \"string\";\n        const confirmed = await dispatch(\n            confirm(\n                isDirectory ? \"Delete folder?\" : \"Delete file?\",\n                isDirectory\n                    ? `Delete ${path} and all files and folders inside it?`\n                    : `Are you sure you want to delete ${path}?`,\n                { text: \"Delete\", variant: \"danger\" },\n                \"Cancel\"\n            )\n        );\n        if (!confirmed) return;\n\n        // The user may have changed apps or permissions during the dialog.\n        const latestState = getState();\n        const latestEntry = getExtraFileEntry(getAppExtraFiles(latestState), path);\n\n        if (\n            getAppId(latestState) !== appId ||\n            !getAppIsEditable(latestState) ||\n            latestEntry === undefined ||\n            typeof latestEntry !== typeof entry\n        ) {\n            return;\n        }\n\n        if (hasExtraFileConflictAtPath(latestState, path)) {\n            await dispatch(\n                alert(\n                    \"Unable to delete file\",\n                    \"Resolve merge conflicts affecting this file or folder before deleting it.\"\n                )\n            );\n            return;\n        }\n\n        const tabIds = getTabs(latestState)\n            .filter(({ navTarget }) => {\n                if (navTarget.type !== \"EXTRA_FILE\") return false;\n\n                return navTarget.filePath === path || (isDirectory && navTarget.filePath.startsWith(`${path}/`));\n            })\n            .map(({ id }) => id);\n\n        dispatch(deleteExtraFileEntry(path));\n        dispatch(rebuildCodeStructureAndSyncCache(new Set()));\n\n        if (tabIds.length > 0) {\n            await dispatch(forceCloseTabs(...tabIds));\n        }\n    };\n","import { load } from \"js-yaml\";\nimport { merge, set, update } from \"lodash-es\";\nimport { createSelector } from \"reselect\";\nimport type { ServiceType } from \"@/router/navTypes\";\nimport type { AnvilAsyncAction, AnvilDispatch, State } from \"@/types\";\nimport type { BasicColumn, Table } from \"@/types/database\";\nimport type {\n    AppService,\n    AvailableService,\n    EmailService,\n    FacebookService,\n    FileService,\n    GoogleService,\n    MicrosoftService,\n    SAMLService,\n    ServiceConfig,\n    ServiceSpec,\n    ServiceSpecProperty,\n    ServiceSpecs,\n    ServicesAppConfig,\n    StripeService,\n    UsersService,\n} from \"@/types/services\";\nimport type { User } from \"@/types/user\";\nimport { getFeatureSupport } from \"@/util/features\";\nimport * as api from \"../api\";\nimport * as tableApi from \"../api/tables\";\nimport { navigate } from \"../router/navigation\";\nimport { EMPTY_ARRAY, removeAndSlimObject, setIn } from \"../util\";\nimport { get } from \"../util/fetch\";\nimport { getApp, getAppConfig, getAppStartupItem, markAppPathUnsaved, updateGlobalLoadingIndicator } from \"./app\";\nimport { applyCodePreludeEverywhere, rebuildCodeStructureAndSyncCache } from \"./app/code\";\nimport { SERVER_TEST_ROOT, deleteExtraFileEntry, ensureServerTestRoot } from \"./app/extra-files\";\nimport { addMissingExtraAppFilesFromTemplate } from \"./app/extra-files\";\nimport { getCurrentBranch } from \"./app/history\";\nimport { closeBottomTab } from \"./bottom-tabs\";\nimport { addTableColumn, createTable, getDebugEnvironmentTableMapping, getDebugEnvironmentTables } from \"./db\";\nimport { createDefaultEnvironment, getCategorisedEnvironments, getEnvironments, saveEnvironment } from \"./environments\";\nimport { alert, modal } from \"./modals\";\nimport { getScheduledTasks, removeScheduledTasks } from \"./scheduledtasks\";\nimport { getPrimarySection, openNav, primaryNav } from \"./sidebar\";\nimport { closeTabFromNavTarget, forceCloseTabs, getTabs, openDefaultTabs } from \"./tabs\";\nimport { recordActivity } from \"./util\";\n\ntype ColumnMutation = {\n    name: string;\n    type: BasicColumn[\"type\"];\n    client_hidden?: boolean;\n    admin_ui?: BasicColumn[\"admin_ui\"];\n};\n\nconst knownServiceTypes: Partial<Record<string, ServiceType>> = {\n    \"/runtime/services/anvil/users.yml\": \"USERS\",\n    \"/runtime/services/anvil/email.yml\": \"EMAIL\",\n    \"/runtime/services/anvil/secrets.yml\": \"SECRETS\",\n    \"/runtime/services/google.yml\": \"GOOGLE\",\n    \"/runtime/services/facebook.yml\": \"FACEBOOK\",\n    \"/runtime/services/anvil/microsoft.yml\": \"MICROSOFT\",\n    \"/runtime/services/anvil/saml.yml\": \"SAML\",\n    \"/runtime/services/stripe.yml\": \"STRIPE\",\n    \"/runtime/services/anvil/tableau.yml\": \"TABLEAU\",\n    \"/runtime/services/anvil/files.yml\": \"FILES\",\n    \"/runtime/services/anvil/tests.yml\": \"TESTS\",\n    \"/runtime/services/hawthorn-deployment.yml\": \"HAWTHORN_DEPLOYMENT\",\n};\n\nconst getKnownServiceType = (source: string | undefined): ServiceType | null =>\n    (source && knownServiceTypes[source]) || null;\n\nconst getServicesConfig = (state: State) =>\n    (getAppConfig(state) as ServicesAppConfig | undefined)?.services ?? (EMPTY_ARRAY as AppService[]);\n\nexport const getAllAvailableServices = (state: State) => state.availableServices;\nexport const getServiceSpecs = (state: State) => state.serviceSpecs ?? {};\n\nexport const loadServiceSpecs =\n    (services: Array<{ source?: string }> | undefined): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const alreadyLoaded = getServiceSpecs(getState());\n        const serviceSpecs: ServiceSpecs = {};\n        const urls = new Set(\n            (services || []).map((s) => s.source).filter((url): url is string => !!url && !(url in alreadyLoaded))\n        );\n        if (urls.size === 0) return;\n        updateState(set, [\"serviceSpecs\", \"$loading\"], true);\n        try {\n            for (const url of urls) {\n                if (!url) continue; // The Uplink service doesn't have a URL, for example.\n                const spec = load(await get<string>(`${url}?buildTime=${BUILD_TIME}`)) as ServiceSpec;\n                serviceSpecs[url] = spec;\n            }\n            serviceSpecs.$loaded = true;\n            updateState(\"Service specs loaded\", merge, { serviceSpecs });\n        } finally {\n            updateState(set, [\"serviceSpecs\", \"$loading\"], false);\n        }\n    };\n\nexport const loadAvailableServices =\n    (user: User | undefined): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const availableServices = await api.getAvailableServices(user);\n        updateState(\"Available Services loaded\", set, [\"availableServices\"], availableServices);\n        await dispatch(loadServiceSpecs(availableServices));\n    };\n\nexport const addServiceWithModal = (): AnvilAsyncAction<void> => async (dispatch, getState, updateState) => {\n    const service = (await dispatch(modal(\"addservice\", {}))) as AvailableService | null;\n    if (service) {\n        dispatch(addAvailableService(service));\n    }\n};\n\nexport const addScheduledTasks =\n    (service: AvailableService): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const branch = getCurrentBranch(state);\n        const environments = getCategorisedEnvironments(state);\n        if (environments.sorted.length === 0) {\n            await dispatch(createDefaultEnvironment());\n        } else if (\n            environments.sorted.length === 1 &&\n            !environments.sorted[0].run_scheduled_tasks &&\n            environments.sorted[0].version?.ref === `refs/heads/${branch}`\n        ) {\n            await dispatch(saveEnvironment(environments.sorted[0], { run_scheduled_tasks: true }));\n        }\n        updateState(`Add ${service.name} service`, update, [\"app\", \"config\", `${service.content_item}`], () => []);\n        await dispatch(markAppPathUnsaved([\"SETTINGS\", \"scheduled_tasks\"])); // TODO: Explain why we're saving scheduled tasks here!\n        dispatch(navigate({ type: \"SCHEDULED_TASKS\" }));\n    };\n\nexport const addUplink = (): AnvilAsyncAction<void> => async (dispatch, getState, updateState) => {\n    updateState(`Add Uplink to app`, set, [\"app\", \"config\", \"uplink_visible\"], true);\n\n    await dispatch(applyCodePreludeEverywhere({ client: \"import anvil.server\" }));\n\n    await dispatch(markAppPathUnsaved([\"SETTINGS\", \"uplink_visible\"]));\n\n    dispatch(modal(\"uplink\", {}));\n};\n\nexport const getIsUplinkVisible = createSelector(\n    [(state: State) => getEnvironments(state), (state: State) => state.app?.config?.uplink_visible],\n    (environments, forceVisible) => {\n        if (forceVisible) {\n            return true;\n        }\n        for (const e of environments || []) {\n            if (e.server_keys?.uplink?.client_key || e.server_keys?.uplink?.server_key) {\n                return true;\n            }\n        }\n    }\n);\n\nexport const addService =\n    (\n        service: AvailableService,\n        selectNewService = true,\n        forceAdd = false,\n        navigateAfterAdd = true\n    ): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        try {\n            dispatch(updateGlobalLoadingIndicator(`Adding ${service.name} service`));\n\n            const state = getState();\n            const app = getApp(state);\n            if (!app) {\n                return;\n            }\n            if ((app.config?.services || []).findIndex((ss) => ss.source === service.source) !== -1) {\n                // don't add this service if it's already there!\n                return;\n            }\n            const serviceSpecs = getServiceSpecs(state);\n            if (!service.source) {\n                throw new Error(`Cannot add service without a source: ${service.name}`);\n            }\n\n            const newService: AppService = {\n                source: service.source,\n                client_config: service.source === \"/runtime/services/tables.yml\" ? { enable_v2: true } : {},\n                server_config: {},\n            };\n            const spec = serviceSpecs[newService.source];\n\n            if (service.source === \"/runtime/services/hawthorn-deployment.yml\") {\n                // Service setup imports the platform's complete configured file set, adding only missing files.\n                await dispatch(addMissingExtraAppFilesFromTemplate());\n            }\n\n            /**\n             * special case table service - don't add preludes when table service is added\n             * instead wait until the first table is added - @see {createTable}\n             * adding table service should only happen on app creation in new ide @see {ensureDataTablesServiceIsAdded}\n             */\n            if (service.source !== \"/runtime/services/tables.yml\") {\n                await dispatch(applyCodePreludeEverywhere(spec?.prelude, { sourceName: `${service.name} service` }));\n            }\n\n            const setConfigToDefaults = (\n                config: ServiceConfig,\n                config_properties: ServiceSpecProperty[] | undefined\n            ) => {\n                for (const cp of config_properties || []) {\n                    if (\"defaultValue\" in cp) {\n                        config[cp.name] = cp.defaultValue;\n                    }\n                }\n            };\n            if (spec) {\n                setConfigToDefaults(\n                    newService.client_config ?? (newService.client_config = {}),\n                    spec.client_config_properties\n                );\n                setConfigToDefaults(\n                    newService.server_config ?? (newService.server_config = {}),\n                    spec.server_config_properties\n                );\n            }\n\n            // If we just added the Users Service, make sure the Users Table exists and wire it up.\n            if (newService.source === \"/runtime/services/anvil/users.yml\") {\n                // TODO: Decide how on earth this will work with multiple table mappings.\n\n                // Find a table called Users. If it exists, point to that. If it doesn't create it and point to it.\n                const debugEnv = getCategorisedEnvironments(state).debug;\n                let usersTable = getConventionalUsersTable(state) as Table | undefined;\n                if (!usersTable) {\n                    usersTable = await dispatch(createTable(debugEnv.table_mapping_id ?? null, \"Users\"));\n                }\n                if (usersTable) {\n                    newService.server_config!.user_table = usersTable.python_name;\n                }\n            } else if (newService.source === \"/runtime/services/anvil/files.yml\") {\n                // Find a table called Files. If it exists, point to that. If it doesn't create it and point to it.\n                const debugEnv = getCategorisedEnvironments(state).debug;\n                let fileTable = getFileTable(state) as Table | undefined;\n                if (!fileTable) {\n                    fileTable = await dispatch(createTable(debugEnv.table_mapping_id ?? null, \"Files\"));\n                }\n                if (fileTable) {\n                    newService.server_config!.file_table = fileTable.python_name;\n                }\n            }\n\n            if (service.source === \"/runtime/services/hawthorn-deployment.yml\") {\n                // Check after the last await so concurrent additions cannot append the service twice.\n                const currentApp = getApp(getState());\n                if (currentApp?.id !== app.id || currentApp?.editState.branch !== app.editState.branch) {\n                    throw new Error(\"The open app or branch has changed. Please try again.\");\n                }\n                if (currentApp.config.services?.some((existing) => existing.source === service.source)) {\n                    return;\n                }\n            }\n\n            updateState(`Add ${service.name} service`, update, [\"app\", \"config\", \"services\"], (ss: AppService[] = []) =>\n                (ss || []).concat([newService])\n            );\n            // Mark unsaved before column setup, which can throw: the service is already in the app config.\n            dispatch(markAppPathUnsaved([\"SETTINGS\", \"services\"]));\n            dispatch(recordActivity(\"addService\", { name: service.name, uri: service.source }));\n\n            if (newService.source === \"/runtime/services/anvil/tests.yml\") {\n                dispatch(ensureServerTestRoot());\n            }\n\n            if (newService.source === \"/runtime/services/anvil/users.yml\") {\n                await dispatch(ensureRequiredUsersServiceColsExist());\n            } else if (newService.source === \"/runtime/services/anvil/files.yml\") {\n                await dispatch(ensureRequiredFileServiceColsExist());\n            }\n\n            const serviceType = getKnownServiceType(service.source);\n            if (navigateAfterAdd && serviceType) {\n                dispatch(navigate({ type: \"SERVICE\", service: serviceType }));\n            }\n        } finally {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n    };\n\nexport const addAvailableService =\n    (service: AvailableService): AnvilAsyncAction<void> =>\n    async (dispatch, getState) => {\n        if (\n            service.requireFeatureOnSubscription &&\n            !getFeatureSupport(getState(), service.requireFeatureOnSubscription)\n        ) {\n            dispatch(modal(\"upgradePrompt\", { featureId: service.requireFeatureOnSubscription }));\n        } else if (service.type === \"UPLINK\") {\n            dispatch(addUplink());\n        } else if (service.name === \"scheduled tasks\") {\n            dispatch(addScheduledTasks(service));\n        } else {\n            const isTestingService = service.source === \"/runtime/services/anvil/tests.yml\";\n            await dispatch(addService(service, true, false, !isTestingService));\n            if (isTestingService) {\n                dispatch(primaryNav(\"tests\"));\n                dispatch(openNav());\n            }\n        }\n    };\n\nexport const removeService =\n    (source: string, sourceName: string): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        try {\n            dispatch(updateGlobalLoadingIndicator(`Removing ${source} service`));\n            const state = getState();\n            const serviceSpecs = getServiceSpecs(state);\n            const spec = serviceSpecs[source];\n            if (source === \"scheduled-tasks\") {\n                const tasks = getScheduledTasks(state);\n                if (tasks && tasks.length) {\n                    dispatch(\n                        alert(\n                            \"Cannot remove scheduled tasks\",\n                            \"Cannot remove the scheduled tasks service while you still have tasks scheduled. Remove the all tasks first.\"\n                        )\n                    );\n                } else {\n                    await dispatch(closeTabFromNavTarget({ type: \"SCHEDULED_TASKS\" }));\n                    await dispatch(removeScheduledTasks());\n                    await dispatch(markAppPathUnsaved([\"SETTINGS\", \"scheduled_tasks\"]));\n                }\n            } else {\n                if (source === \"/runtime/services/anvil/tests.yml\") {\n                    //close all test file tabs\n                    const testingTabIds = getTabs(getState())\n                        .filter(\n                            ({ navTarget }) =>\n                                navTarget.type === \"EXTRA_FILE\" && navTarget.filePath.startsWith(\"tests/\")\n                        )\n                        .map(({ id }) => id);\n\n                    if (testingTabIds.length > 0) {\n                        await dispatch(forceCloseTabs(...testingTabIds));\n                    }\n\n                    //update active sidebar\n                    if (getPrimarySection(getState()) === \"tests\") {\n                        dispatch(primaryNav(\"code\"));\n                    }\n\n                    //decide if we need to open the startup form\n                    const currentState = getState();\n                    const hasVisibleTabs = getTabs(currentState).some((tab) => !tab.hidden);\n\n                    if (!hasVisibleTabs) {\n                        const startupItem = getAppStartupItem(currentState);\n\n                        if (startupItem?.module) {\n                            await dispatch(\n                                navigate({\n                                    type: \"CODE\",\n                                    codePath: `${startupItem.type}s/${startupItem.module}`,\n                                })\n                            );\n                        }\n                    }\n\n                    dispatch(closeBottomTab({ type: \"serverTests\" }));\n                    dispatch(deleteExtraFileEntry(\"tests\"));\n                    dispatch(rebuildCodeStructureAndSyncCache(new Set()));\n                }\n\n                const environments = getCategorisedEnvironments(state);\n                if (source === \"/runtime/services/anvil/tableau.yml\" && environments.debug?.url?.tableau_dashboard) {\n                    const { tableau_dashboard, ...url } = environments.debug.url;\n                    await dispatch(saveEnvironment(environments.debug, { url }));\n                }\n\n                if (source === \"/runtime/services/anvil/secrets.yml\") {\n                    updateState(\"Cleaning Up Secrets for removal\", (state) => {\n                        if (state.app?.config) {\n                            delete state.app.config.secrets;\n                        }\n                    });\n                    dispatch(markAppPathUnsaved([\"SETTINGS\", \"secrets\"]));\n                }\n\n                await dispatch(\n                    applyCodePreludeEverywhere(spec?.prelude, {\n                        sourceName: `${sourceName} service`,\n                        remove: true,\n                    })\n                );\n                updateState(\n                    `Remove ${source} service`,\n                    update,\n                    [\"app\", \"config\", \"services\"],\n                    (ss: AppService[] = []) => ss.filter((s) => s.source !== source)\n                );\n                dispatch(recordActivity(\"removeService\", { name: sourceName, uri: source }));\n\n                await dispatch(closeTabFromNavTarget({ type: \"SERVICE\", service: getKnownServiceType(source)! }));\n                dispatch(markAppPathUnsaved([\"SETTINGS\", \"services\"]));\n            }\n        } finally {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n    };\n\n// TODO: implement refreshAppTables (code below from IDE.js, line 1150)\n// Called from addDataTablesServiceIfNecessary (below)\nconst refreshAppTables = async (app: State[\"app\"], synchronousSchemaSave = false) => {\n    if (!app) return;\n    const appId = app.id;\n    const appList = await tableApi.getAppTables(appId);\n    const thisApp = appList.filter((a) => a.id == appId)[0] || null;\n    // TODO: should thisAppTables be in the store?\n    const thisAppTables = thisApp.tables || [];\n\n    if (JSON.stringify(app.config.db_schema) != JSON.stringify(thisAppTables)) {\n        // Try to prevent some unnecessary saves.\n\n        // TODO: updateState here - db_schema with thisAppTables?\n        // updateState(set, ['app', 'config', 'db_schema'], thisAppTables);\n        // app.config.db_schema = scope.thisAppTables;\n        if (synchronousSchemaSave) {\n            // TODO: emit \"appHistoryCheckpointOnIdle\", [\"db_schema\"], \"Updated DB schema\"\n            // scope.$emit(\"appHistoryCheckpointOnIdle\", [\"db_schema\"], \"Updated DB schema\");\n        } else {\n            // TODO: Mark db_schema as dirty\n            // markPathDirty([\"db_schema\"]);\n        }\n    }\n};\n\n// TODO: implement line below ?\n// scope.$on(\"refreshAppTables\", refreshAppTables.bind(null, true));\n\nexport const ensureDataTablesServiceIsAdded = (\n    app: State[\"app\"],\n    availableServices: AvailableService[],\n    dispatch: AnvilDispatch\n) => {\n    if (!app) return;\n    const tablesService = (app.config.services || []).filter(\n        (service) => service.source === \"/runtime/services/tables.yml\"\n    )[0];\n\n    if (!tablesService) {\n        const tablesServiceToAdd = availableServices.find(\n            (service) => service.source === \"/runtime/services/tables.yml\"\n        );\n        if (tablesServiceToAdd) {\n            dispatch(addService(tablesServiceToAdd, false, false));\n        }\n    }\n};\n\nexport const updateTablesService =\n    (key: string | string[], val: unknown, serverConfig: boolean): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        updateState(\"Configure Data Tables service\", (state: State) => {\n            // Make sure server_config is set before setting auto_create_missing_columns\n            const service = state.app?.config.services?.find((s) => s.source === \"/runtime/services/tables.yml\");\n            if (!service) return;\n            let config: ServiceConfig;\n            if (serverConfig) {\n                config = service.server_config ??= {};\n            } else {\n                config = service.client_config ??= {};\n            }\n            if (typeof key === \"string\") {\n                config[key] = val;\n            } else if (key instanceof Array) {\n                set(config, key, val);\n            }\n        });\n\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"services\"]));\n    };\n\nexport const ensureRequiredUsersServiceColsExist =\n    (): AnvilAsyncAction<void> => async (dispatch, getState, updateState) => {\n        const state = getState();\n        const usersTable = getUsersTable(state);\n        const currentServiceConfig = getUsersService(state);\n        const tableMapping = getDebugEnvironmentTableMapping(state);\n        if (!tableMapping) return;\n\n        // TODO: check which should and shouldn't be client hidden\n        if (usersTable) {\n            const columnList = Object.entries(usersTable.columns || {});\n            const requiredColumns: ColumnMutation[] = [\n                { name: \"email\", type: \"string\", client_hidden: false },\n                { name: \"enabled\", type: \"bool\", client_hidden: true },\n                { name: \"last_login\", type: \"datetime\", client_hidden: true },\n            ];\n\n            if (currentServiceConfig?.client_config?.use_email) {\n                requiredColumns.push({ name: \"password_hash\", type: \"string\", client_hidden: true });\n                requiredColumns.push({ name: \"n_password_failures\", type: \"number\", client_hidden: true }); // TODO: Decide whether we want this one.\n            }\n            if (currentServiceConfig?.client_config?.confirm_email) {\n                requiredColumns.push({ name: \"confirmed_email\", type: \"bool\", client_hidden: true });\n            }\n            if (currentServiceConfig?.client_config?.allow_signup) {\n                requiredColumns.push({ name: \"signed_up\", type: \"datetime\", client_hidden: true });\n            }\n            if (currentServiceConfig?.client_config?.require_mfa) {\n                requiredColumns.push({ name: \"mfa\", type: \"simpleObject\", client_hidden: true });\n            }\n            if (currentServiceConfig?.client_config?.allow_remember_me) {\n                requiredColumns.push({\n                    name: \"remembered_logins\",\n                    type: \"simpleObject\",\n                    client_hidden: true,\n                });\n            }\n\n            let colCount = columnList.length;\n            for (const requiredCol of requiredColumns) {\n                const match = columnList.find(([_id, { name }]) => name === requiredCol.name);\n                if (!match) {\n                    await dispatch(\n                        addTableColumn(tableMapping.table_mapping_id, usersTable.id, {\n                            ...requiredCol,\n                            admin_ui: { order: colCount++, width: 200 },\n                        })\n                    );\n                }\n            }\n        }\n    };\n\nexport const updateUsersService =\n    (path: string[], value: unknown): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        updateState(`Configure ${path} of Users service`, (state: State) => {\n            const service = state.app?.config.services?.find((s) => s.source === \"/runtime/services/anvil/users.yml\");\n            if (!service) return;\n            if (value === undefined) {\n                removeAndSlimObject(service, path);\n            } else {\n                setIn(service, path, value);\n            }\n        });\n\n        // Make sure the Users table has all the required columns for the updated config\n        await dispatch(ensureRequiredUsersServiceColsExist());\n\n        dispatch(markAppPathUnsaved([\"SETTINGS\", \"services\"]));\n    };\n\nexport const ensureUsersServiceTableConfigured = (): AnvilAsyncAction<void> => async (dispatch, getState) => {\n    const state = getState();\n    const debugEnv = getCategorisedEnvironments(state).debug;\n    let usersTable = getConventionalUsersTable(state) as Table | undefined;\n    if (!usersTable) {\n        usersTable = await dispatch(createTable(debugEnv.table_mapping_id ?? null, \"Users\"));\n    }\n    if (usersTable) {\n        await dispatch(updateUsersService([\"server_config\", \"user_table\"], usersTable.python_name));\n    }\n};\n\nexport const updateService =\n    (serviceName: keyof typeof serviceNameToSource | \"users\", path: string[], value: unknown): AnvilAsyncAction<void> =>\n    async (dispatch, getState, updateState) => {\n        if (serviceName !== \"users\") {\n            const source = getServiceSourceFromName(serviceName);\n            updateState(`Configure ${path} of ${serviceName} service`, (state: State) => {\n                const service = state.app?.config.services?.find((s) => s.source === source);\n                if (!service) return;\n                setIn(service, path, value);\n            });\n            dispatch(markAppPathUnsaved([\"SETTINGS\", \"services\"]));\n        } else {\n            console.warn(\"Cannot update Users Services. Use updateUsersService()\");\n        }\n    };\n\nexport const ensureRequiredFileServiceColsExist =\n    (): AnvilAsyncAction<void> => async (dispatch, getState, updateState) => {\n        const state = getState();\n        const fileTable = getFileTable(state);\n        const tableMapping = getDebugEnvironmentTableMapping(state);\n        if (!tableMapping) return;\n\n        if (fileTable) {\n            const columnList = Object.entries(fileTable.columns || {});\n            const requiredColumns: ColumnMutation[] = [\n                { name: \"path\", type: \"string\" },\n                { name: \"file\", type: \"media\" },\n                { name: \"file_version\", type: \"string\" },\n            ];\n\n            let colCount = columnList.length;\n            for (const requiredCol of requiredColumns) {\n                const match = columnList.find(([_id, { name }]) => name === requiredCol.name);\n                if (!match) {\n                    await dispatch(\n                        addTableColumn(tableMapping.table_mapping_id, fileTable.id, {\n                            ...requiredCol,\n                            admin_ui: { order: colCount++, width: 200 },\n                        })\n                    );\n                }\n            }\n        }\n    };\n\nexport const getUsersTable = createSelector(\n    [\n        (state: State) => getUsersService(state)?.server_config?.user_table,\n        (state: State) => getDebugEnvironmentTables(state),\n    ],\n    (usersTableName, appTables) => appTables.find((t) => t.python_name === usersTableName || t.id === usersTableName)\n);\n\nexport const getConventionalUsersTable = createSelector(\n    [(state: State) => getDebugEnvironmentTables(state)],\n    (appTables) => appTables.find((t) => t.python_name === \"users\")\n);\n\n// Factory function to create service selectors\nconst createServiceSelector = <T extends AppService = AppService>(source: string) =>\n    createSelector([(state: State) => getServicesConfig(state)], (services) =>\n        services.find((s) => s.source === source)\n    ) as (state: State) => T | undefined;\n\nexport const getUsersService = createServiceSelector<UsersService>(\"/runtime/services/anvil/users.yml\");\n\nexport const getFileService = createServiceSelector<FileService>(\"/runtime/services/anvil/files.yml\");\n\nexport const getGoogleService = createServiceSelector<GoogleService>(\"/runtime/services/google.yml\");\n\nexport const getEmailService = createServiceSelector<EmailService>(\"/runtime/services/anvil/email.yml\");\n\nexport const getFacebookService = createServiceSelector<FacebookService>(\"/runtime/services/facebook.yml\");\n\nexport const getStripeService = createServiceSelector<StripeService>(\"/runtime/services/stripe.yml\");\n\nexport const getMicrosoftService = createServiceSelector<MicrosoftService>(\"/runtime/services/anvil/microsoft.yml\");\n\nexport const getSecretsService = createServiceSelector(\"/runtime/services/anvil/secrets.yml\");\n\nexport const getSAMLService = createServiceSelector<SAMLService>(\"/runtime/services/anvil/saml.yml\");\n\nexport const getTablesService = createServiceSelector(\"/runtime/services/tables.yml\");\n\nexport const getTestingService = createServiceSelector(\"/runtime/services/anvil/tests.yml\");\n\nexport const getTestingEnabled = createSelector([getTestingService], (testingService) => testingService !== undefined);\n\nexport const getHawthornDeploymentService = createServiceSelector(\"/runtime/services/hawthorn-deployment.yml\");\n\nexport const getFileTable = createSelector(\n    [\n        (state: State) => getFileService(state)?.server_config?.file_table || \"files\",\n        (state: State) => getDebugEnvironmentTables(state),\n    ],\n    (fileTableName, appTables) => appTables.find((t) => t.python_name === fileTableName || t.id === fileTableName)\n);\n\nexport const getService = (state: State, source: string) => getServicesConfig(state).find((s) => s.source === source);\nexport const getUserPaymentPlan = (state: State) => state.subscription?.plan;\nexport const getGoogleServiceSpec = (state: State) => state.serviceSpecs?.[\"/runtime/services/google.yml\"];\nexport const getFacebookServiceSpec = (state: State) => state.serviceSpecs?.[\"/runtime/services/facebook.yml\"];\n\nexport const serviceNameToSource = {\n    google: \"/runtime/services/google.yml\",\n    facebook: \"/runtime/services/facebook.yml\",\n    stripe: \"/runtime/services/stripe.yml\",\n    tables: \"/runtime/services/tables.yml\",\n    users: \"/runtime/services/anvil/users.yml\",\n    files: \"/runtime/services/anvil/files.yml\",\n    email: \"/runtime/services/anvil/email.yml\",\n    secrets: \"/runtime/services/anvil/secrets.yml\",\n    microsoft: \"/runtime/services/anvil/microsoft.yml\",\n    saml: \"/runtime/services/anvil/saml.yml\",\n    kerberos: \"/runtime/services/kerberos.yml\",\n    pki: \"/runtime/services/pki.yml\",\n    tableau: \"/runtime/services/anvil/tableau.yml\",\n};\n\nexport const getServiceSourceFromName = (name: keyof typeof serviceNameToSource) => serviceNameToSource[name];\n","import { set } from \"lodash-es\";\nimport { createSelector } from \"reselect\";\nimport { getRunMode } from \"@/controllers/runner\";\nimport type { AnvilAction, State } from \"@/types\";\n\nexport const primaryNav =\n    (section: string): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(set, [\"sidebar\", \"primarySection\"], section);\n    };\n\nexport const secondaryNavResize =\n    (width: number): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(set, [\"sidebar\", \"secondaryNavWidth\"], width);\n    };\n\nexport const toggleAdvancedCodeView =\n    (newValue: boolean): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(set, [\"sidebar\", \"advancedCodeView\"], newValue);\n    };\n\nexport const setCodeNavSectionExpanded =\n    (section: \"assets\" | \"dependencies\", expanded: boolean): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const key = section === \"assets\" ? \"showAssetsInCodeNav\" : \"showDependenciesInCodeNav\";\n        updateState(set, [\"sidebar\", key], expanded);\n    };\n\nconst toggleShowSecondaryNav =\n    (force: boolean | null = null): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const runMode = getRunMode(state);\n        updateState(({ sidebar }) => {\n            if (runMode === \"INLINE\") {\n                sidebar.inlineShowSecondaryNav = force != null ? force : !sidebar.inlineShowSecondaryNav;\n            } else {\n                sidebar.showSecondaryNav = force != null ? force : !sidebar.showSecondaryNav;\n            }\n        });\n    };\n\nexport const hideIfOverlay = (): AnvilAction => async (dispatch, getState) => {\n    const state = getState();\n    if (getNavMode(state) === \"overlay\") {\n        dispatch(closeNav());\n    }\n};\n\n/*\n * General behavior regardless of runMode\n *                               OPEN DOCK       CLOSED DOCK |   OPEN OVERLAY    |  CLOSED OVERLAY\n * SubNav already Selected   |   close Nav   |    open Nav   |     close Nav     |     open Nav\n * SubNav not Selected       |  do nothing   |    open Nav   |    do nothing     |     open Nav\n * Not SubNav                |  do nothing   |   do nothing  |     close Nav     |    do nothing\n *\n */\n\nexport const evaluateSecondaryNavState =\n    (subNav?: string | null): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const primarySection = getPrimarySection(state);\n\n        const mode = getNavMode(state);\n        const open = getSecondaryNavOpen(state);\n\n        if (open) {\n            if (subNav) {\n                if (subNav === primarySection) {\n                    dispatch(closeNav());\n                }\n            } else {\n                if (mode === \"overlay\") {\n                    dispatch(closeNav());\n                }\n            }\n        } else {\n            if (subNav) {\n                dispatch(openNav());\n            }\n        }\n    };\n\n/*\n    Switching from docked to overlay when not running inline affects both default and when-running state.\n    Switching from overlay to docked when running inline affects both default and when-running state.\n */\n\nexport const setNavModeToOverlay = (): AnvilAction => async (dispatch, getState, updateState) => {\n    const state = getState();\n    const runningInline = getRunMode(state) === \"INLINE\";\n\n    updateState((state) => {\n        const { sidebar } = state;\n        if (runningInline) {\n            sidebar.inlineNavMode = \"overlay\";\n        } else {\n            sidebar.navMode = \"overlay\";\n            sidebar.inlineNavMode = \"overlay\";\n            sidebar.inlineShowSecondaryNav = false;\n        }\n    });\n};\n\nexport const setNavModeToDocked = (): AnvilAction => async (dispatch, getState, updateState) => {\n    const state = getState();\n    const runningInline = getRunMode(state) === \"INLINE\";\n\n    updateState(({ sidebar }) => {\n        if (runningInline) {\n            sidebar.inlineNavMode = \"docked\";\n            sidebar.navMode = \"docked\";\n            sidebar.showSecondaryNav = true;\n        } else {\n            sidebar.navMode = \"docked\";\n        }\n    });\n};\n\nexport const showHideSecondaryNav = (): AnvilAction => async (dispatch) => {\n    dispatch(toggleShowSecondaryNav());\n};\n\nexport const openNav = (): AnvilAction => async (dispatch) => {\n    dispatch(toggleShowSecondaryNav(true));\n};\n\nexport const closeNav = (): AnvilAction => async (dispatch) => {\n    dispatch(toggleShowSecondaryNav(false));\n};\n\nexport const getPrimarySection = (state: State) => state.sidebar.primarySection;\nexport const getSecondaryNavWidth = (state: State) => state.sidebar.secondaryNavWidth;\nexport const getIsSidebarVisible = (state: State) => state.sidebar.isSidebarVisible;\n// export const getAdvancedCodeView = state => state.sidebar.advancedCodeView;\nexport const getAdvancedCodeView = (_state: State) => true; // advanced codeview toggle was removed\nexport const getShowAssetsInCodeNav = (state: State) => state.sidebar.showAssetsInCodeNav;\nexport const getShowDependenciesInCodeNav = (state: State) => state.sidebar.showDependenciesInCodeNav;\n\nexport const getNavMode = createSelector(\n    [\n        (state: State) => state.sidebar.navMode,\n        (state: State) => state.sidebar.inlineNavMode,\n        (s: State) => getRunMode(s),\n    ],\n    (navMode, inlineNavMode, runMode) => (runMode === \"INLINE\" ? inlineNavMode : navMode)\n);\n\nexport const getSecondaryNavOpen = createSelector(\n    [\n        (state: State) => state.sidebar.showSecondaryNav,\n        (state: State) => state.sidebar.inlineShowSecondaryNav,\n        (s: State) => getRunMode(s),\n    ],\n    (show, inlineShow, runMode) => (runMode === \"INLINE\" ? inlineShow : show)\n);\n","import { type InfiniteData, type QueryClient, keepPreviousData, useInfiniteQuery } from \"@tanstack/react-query\";\nimport { type TableRowsPage, getTableRows } from \"@/api/tables\";\nimport type { AnvilRow } from \"@/components/tabs/database/types\";\nimport type { SortArray } from \"@/controllers/db_new\";\n\nexport const FETCH_SIZE = 30;\n\nexport const cleanTableSortParam = (columnSorting: SortArray) => {\n    let sort = \"\";\n    for (const { colId: id, ascending: asc } of columnSorting) {\n        if (sort) sort += \",\";\n        sort += (asc ? \"+\" : \"-\") + id;\n    }\n    return sort || null;\n};\n\nexport const getTableDataQueryKey = ({\n    appId,\n    tableId,\n    tableMappingId,\n}: {\n    appId: string;\n    tableId: number;\n    tableMappingId: number | null;\n}) => [\"table-data\", { appId, tableId, tableMappingId }] as const;\n\ntype TableDataQueryArgs = {\n    appId: string;\n    tableId: number;\n    tableMappingId: number | null;\n};\n\nexport const useTableRowsInfiniteQuery = ({\n    appId,\n    tableId,\n    tableMappingId,\n    columnSorting,\n    enabled = true,\n}: {\n    appId: string;\n    tableId: number;\n    tableMappingId: number | null;\n    columnSorting: SortArray;\n    enabled?: boolean;\n}) => {\n    const columnSortingKey = JSON.stringify(columnSorting);\n\n    return useInfiniteQuery({\n        queryKey: [...getTableDataQueryKey({ appId, tableId, tableMappingId }), \"page-data\", columnSortingKey] as const,\n        queryFn: ({ pageParam }) =>\n            getTableRows<AnvilRow>(appId, tableMappingId, tableId, {\n                more: pageParam,\n                pageSize: FETCH_SIZE,\n                sort: cleanTableSortParam(columnSorting),\n            }),\n        getNextPageParam: (lastPage) => lastPage.more,\n        initialPageParam: 0,\n        placeholderData: keepPreviousData,\n        refetchOnWindowFocus: true,\n        refetchOnMount: \"always\",\n        staleTime: 0,\n        enabled,\n    });\n};\n\nexport const invalidateTableDataQuery = async (queryClient: QueryClient, args: TableDataQueryArgs) => {\n    await queryClient.invalidateQueries({ queryKey: getTableDataQueryKey(args) });\n};\n\nexport const refetchFirstTableDataPage = async (queryClient: QueryClient, args: TableDataQueryArgs) => {\n    const queryKey = getTableDataQueryKey(args);\n    queryClient.setQueriesData<InfiniteData<TableRowsPage<AnvilRow>, string | null>>({ queryKey }, (oldData) => {\n        if (!oldData?.pages.length) return oldData;\n\n        return {\n            ...oldData,\n            pages: oldData.pages.slice(0, 1),\n            pageParams: oldData.pageParams.slice(0, 1),\n        };\n    });\n\n    await queryClient.invalidateQueries({ queryKey });\n};\n","import { useDispatch } from \"react-redux\";\nimport { createSelector } from \"reselect\";\nimport type { AnvilAsyncAction, AnvilDispatch, AppId, Repl, State } from \"@/types\";\nimport type { AppEnvironment } from \"@/types/app-environment\";\nimport { getAppConfig } from \"./app\";\nimport { getCategorisedEnvironments, getNewEnvironmentURL, saveEnvironment } from \"./environments\";\nimport { modal } from \"./modals\";\nimport { createRepl, getPreserveReplLogs, getRepl, getTableauRepl, replOutput } from \"./repl\";\nimport { useWebsocketEventListener } from \"./websocket\";\n\ninterface TableauTraceFrame {\n    filename: string;\n    lineno: number;\n}\n\ninterface TableauErrorData {\n    message: string;\n    trace: [string, number][];\n    type: string;\n}\n\ninterface TableauEvent {\n    app_id?: AppId;\n    data?: TableauErrorData;\n    env_id?: AppEnvironment[\"env_id\"];\n    event: \"SESSION_START_EVENT\" | \"SESSION_LOG_EVENT\" | string;\n    log_text?: string;\n    session_data?: unknown;\n    session_id: string;\n    type?: \"print\" | \"client_print\" | \"client_err\" | \"err\";\n}\n\ntype TableauRepl = Repl & {\n    lastSessionId?: string;\n};\n\nconst getDebugEnvironment = (state: State) => getCategorisedEnvironments(state).debug;\n\nexport const testInTableau = (): AnvilAsyncAction<void> => async (dispatch, getState) => {\n    // TODO: At this point, might want to do something clever like open the last-used dashboard by default.\n    const state = getState();\n    const debugEnv = getDebugEnvironment(state);\n\n    if (!debugEnv.url) {\n        dispatch(saveEnvironment(debugEnv, { url: await dispatch(getNewEnvironmentURL(\"private\")) }));\n    }\n    dispatch(modal(\"tableauDebug\", {}));\n};\n\nexport const publishToTableau = (): AnvilAsyncAction<void> => async (dispatch) => {\n    // Do whatever we need to do to publish the app.\n    dispatch(modal(\"tableauPublish\", {}));\n};\n\nexport const getTableauService = createSelector([(state: State) => getAppConfig(state)?.services], (services) =>\n    services?.find((service) => service.source === \"/runtime/services/anvil/tableau.yml\")\n);\n\nconst maybeOpenOrResetTableauRepl =\n    (sessionId: string): AnvilAsyncAction<Repl | undefined> =>\n    async (dispatch, getState, updateState) => {\n        console.log(\"SESSION ID\", sessionId);\n        let state = getState();\n        const replId = getTableauRepl(state)?.id || (await dispatch(createRepl(\"tableau\")));\n        state = getState();\n        const repl = getRepl(replId)(state) as TableauRepl | undefined;\n        const preserveReplLogs = getPreserveReplLogs(state);\n\n        if (repl && repl.lastSessionId !== sessionId && !preserveReplLogs) {\n            updateState(({ repl }) => {\n                const thisRepl = repl.repls[replId] as TableauRepl;\n                thisRepl.output = [];\n                thisRepl.lastSessionId = sessionId;\n            });\n        }\n\n        return repl;\n    };\n\nexport const tableauSessionStart =\n    ({ session_id }: TableauEvent): AnvilAsyncAction<void> =>\n    async (dispatch) => {\n        const repl = await dispatch(maybeOpenOrResetTableauRepl(session_id));\n\n        await dispatch(\n            replOutput(repl!.id, {\n                fn: \"session\",\n                text: \"Tableau dashboard loaded\\n\\n\",\n            })\n        );\n    };\n\nexport const tableauDebugOutput =\n    ({ app_id, env_id, session_id, type, log_text, data }: TableauEvent): AnvilAsyncAction<void> =>\n    async (dispatch) => {\n        const repl = await dispatch(maybeOpenOrResetTableauRepl(session_id));\n\n        let output:\n            | {\n                  fn: \"stdout\";\n                  fromServer: boolean;\n                  text: string | undefined;\n              }\n            | {\n                  fn: \"pythonError\";\n                  message: string;\n                  traceback: (TableauTraceFrame & { fromServer: boolean })[];\n                  type: string;\n              }\n            | undefined;\n        switch (type) {\n            case \"print\":\n            case \"client_print\":\n                output = {\n                    fn: \"stdout\",\n                    text: log_text,\n                    fromServer: type === \"print\",\n                };\n                break;\n            case \"client_err\":\n            case \"err\":\n                output = {\n                    fn: \"pythonError\",\n                    traceback: data!.trace.map(([filename, lineno]) => ({\n                        filename,\n                        lineno,\n                        fromServer: type === \"err\",\n                    })),\n                    type: data!.type,\n                    message: data!.message,\n                };\n                break;\n        }\n        if (output) {\n            await dispatch(replOutput(repl!.id, output));\n        }\n\n        console.log(\"Tableau output\", app_id, env_id, session_id, type, log_text, data);\n    };\n\nconst handleTableauEvent =\n    (e: TableauEvent): AnvilAsyncAction<void> =>\n    async (dispatch, getState) => {\n        switch (e.event) {\n            case \"SESSION_START_EVENT\": {\n                // Currently, these only come from tableau debug sessions.\n                const debugEnv = getDebugEnvironment(getState());\n                if (debugEnv && debugEnv.env_id === e.env_id) {\n                    // Only show output for my debug environment.\n                    await dispatch(tableauSessionStart(e));\n                }\n                break;\n            }\n            case \"SESSION_LOG_EVENT\": {\n                // Currently, these only come from tableau debug sessions.\n                const debugEnv = getDebugEnvironment(getState());\n                if (debugEnv && debugEnv.env_id === e.env_id) {\n                    // Only show output for my debug environment.\n                    await dispatch(tableauDebugOutput(e));\n                }\n                break;\n            }\n        }\n    };\n\nexport const useTableauWebsocketListener = (appId: AppId | null | undefined) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    useWebsocketEventListener(appId, (e) => dispatch(handleTableauEvent(e as TableauEvent)));\n};\n","import { useCallback, useEffect, useInsertionEffect, useRef } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { clamp } from \"lodash-es\";\nimport { createSelector } from \"reselect\";\nimport { EVENTS, raiseEvent } from \"@/actions\";\nimport { getNumViews } from \"@/components/tabs/code/useViewModes\";\nimport { dispatchIDETutorialModalThenFocusBottomPanelOnQuit, getInTutorialMode } from \"@/controllers/ideTutorial\";\nimport { modal } from \"@/controllers/modals\";\nimport { getNavMode, getSecondaryNavWidth } from \"@/controllers/sidebar\";\nimport {\n    CodeNavTarget,\n    ConversationNavTarget,\n    DBTableNavTarget,\n    NavTarget,\n    ServiceNavTarget,\n    ServiceType,\n    SessionNavTarget,\n    ThemeNavTarget,\n} from \"@/router/navTypes\";\nimport { remToPixelMultiplier } from \"@/theme/ThemeProvider\";\nimport type { FullView } from \"@/types\";\nimport {\n    AnvilAction,\n    AnvilDispatch,\n    CodeItemYaml,\n    CodePath,\n    CodeTab,\n    CodeTabPrefs,\n    ServiceTab,\n    State,\n    Tab,\n} from \"@/types\";\nimport { CodeItemType } from \"@/types/code\";\nimport { USER_AB_FLAGS } from \"@/util/hooks/ab-flags\";\nimport { replaceEqualDeep } from \"@/util/replace-equal-deep\";\nimport { getIconFromFile } from \"../components/reusable/IconHooks\";\nimport { navigate } from \"../router/navigation\";\nimport { cacheView, getAppId, getAppStartupItem, getCachedView, getInvalidYaml } from \"./app\";\nimport {\n    HIDDEN_CODE_PATH,\n    generateTitleFromCodeTabItem,\n    getCodeNames,\n    getCodeStructure,\n    itemTypeFromCodePath,\n} from \"./app/code\";\nimport { getSplitCodeEditorRatio, getSplitRunnerWidth, getUser } from \"./ide\";\nimport { getScheduledTasks } from \"./scheduledtasks\";\nimport {\n    getEmailService,\n    getFacebookService,\n    getFileService,\n    getGoogleService,\n    getHawthornDeploymentService,\n    getMicrosoftService,\n    getSAMLService,\n    getSecretsService,\n    getStripeService,\n    getUsersService,\n} from \"./services\";\nimport { getTableauService } from \"./tableau\";\nimport { getAbFlag, getUserUiScale } from \"./user\";\nimport { recordActivity } from \"./util\";\n\nexport const navTargetsMatch = (navTargetA: NavTarget, navTargetB: NavTarget) => {\n    if (navTargetA.type !== navTargetB.type) return false;\n    switch (navTargetB.type) {\n        case \"START_PAGE\":\n        case \"APP_ROOT\":\n        case \"APP_SCHEMA\":\n        case \"HELP\":\n        case \"BACKGROUND_TASKS\":\n        case \"CPU_USAGE\":\n        case \"MEMORY_USAGE\":\n        case \"SESSIONS\":\n        case \"APP_DEPENDENCIES\":\n        case \"PYTHON_DEPENDENCIES\":\n        case \"JAVASCRIPT_DEPENDENCIES\":\n        case \"SCHEDULED_TASKS\":\n        case \"SETTINGS\":\n        case \"IMPORT_MAP\":\n        case \"_COMPONENTS\":\n            // These are all singletons - you can't ever have more than one tab with this type, so it matches.\n            return true;\n        case \"CODE\":\n            return navTargetB.codePath === (navTargetA as CodeNavTarget).codePath;\n        case \"DB_TABLE\":\n            const tnt = navTargetA as DBTableNavTarget;\n            return navTargetB.tableId === tnt.tableId && navTargetB.tableMappingId === tnt.tableMappingId;\n        case \"SESSION\":\n            return navTargetB.sessionId === (navTargetA as SessionNavTarget).sessionId;\n        case \"CONVERSATION\":\n            return navTargetB.conversationPid === (navTargetA as ConversationNavTarget).conversationPid;\n        case \"THEME\":\n            return navTargetB.section === (navTargetA as ThemeNavTarget).section;\n        case \"SERVICE\":\n            return navTargetB.service === (navTargetA as ServiceNavTarget).service;\n        case \"EXTRA_FILE\":\n            return navTargetA.type === \"EXTRA_FILE\" && navTargetA.filePath === navTargetB.filePath;\n        case \"PYTHON_SOURCE\":\n            return navTargetA.type === \"PYTHON_SOURCE\" && navTargetA.uri === navTargetB.uri;\n    }\n    return false;\n};\n\nexport const tabMatchesNavTarget = (tab: Tab, navTarget: NavTarget) => {\n    const tabNavTarget = tab.navTarget;\n    return navTargetsMatch(tabNavTarget, navTarget);\n};\n\nexport const getTabMatchingNavTarget = (state: State, navTarget: NavTarget) => {\n    const tabs = getTabs(state);\n    return tabs.find((t) => tabMatchesNavTarget(t, navTarget));\n};\n\nlet nextTabId = 1;\n\n// updateOnly is a flag we use so as to ignore pushing tabs that shouldn't be here\n// e.g. when we're updating a hidden tab\n// or when renaming a code item that may or may not be in the recently opened tabs\n// note ids of recently opened tabs are not guaranteed to be unique since they persist across sessions\n// whenever we work with recently opened tabs we need to use tabMatchesNavTarget for filtering and finding\nexport const recentlyOpenedUpdater = (recentlyOpenedTabs: Tab[] | undefined, tab: Tab, updateOnly = false) => {\n    if (!recentlyOpenedTabs) return;\n\n    const recentlyOpenedIndex = recentlyOpenedTabs.findIndex((t) => tabMatchesNavTarget(t, tab.navTarget));\n    if (recentlyOpenedIndex === -1 && updateOnly) return;\n\n    if (!updateOnly) {\n        if (recentlyOpenedIndex > -1) {\n            recentlyOpenedTabs.splice(recentlyOpenedIndex, 1);\n        }\n        recentlyOpenedTabs.push(tab);\n    } else {\n        recentlyOpenedTabs[recentlyOpenedIndex] = tab;\n    }\n    while (recentlyOpenedTabs.length > 20) {\n        recentlyOpenedTabs.shift();\n    }\n};\n\nfunction createNewTabAndPushUpdater(editor: State[\"editor\"], tab: Tab, index?: number) {\n    switch (tab.navTarget.type) {\n        case \"CODE\":\n            Object.assign(tab, {\n                itemType: itemTypeFromCodePath(tab.navTarget.codePath),\n                codeTabPrefs: { ...editor.codeTabPrefs },\n            });\n            break;\n        case \"BACKGROUND_TASKS\":\n            tab.section = \"background-tasks\";\n            break;\n        case \"CPU_USAGE\":\n            tab.section = \"app-usage\";\n            break;\n        case \"MEMORY_USAGE\":\n            tab.section = \"app-usage\";\n            break;\n    }\n    tab.temp = tab.navTarget.temp;\n\n    if (typeof index === \"number\" && index < editor.tabs.length) {\n        editor.tabs.splice(index, 0, tab);\n    } else {\n        editor.tabs.push(tab);\n    }\n    if (!tab.hidden) {\n        editor.tabStack.push(tab.id);\n    }\n}\n\nfunction closeTemporaryTabsUpdater(editor: State[\"editor\"]) {\n    // close temporary tabs that are not hidden\n    const activeTabId = editor.tabStack.at(-1);\n    const tempTabIds = editor.tabs\n        .filter(({ id, temp, hidden }) => id !== activeTabId && temp && !hidden)\n        .map(({ id }) => id);\n    editor.tabs = editor.tabs.filter(({ id, temp }) => !tempTabIds.includes(id));\n    editor.tabStack = editor.tabStack.filter((id) => !tempTabIds.includes(id));\n}\n\nconst HIDDEN_TAB_TIMEOUT = 5000;\n\nfunction dropOldHiddenTabsUpdater(editor: State[\"editor\"]) {\n    const threshold = Date.now() - HIDDEN_TAB_TIMEOUT;\n    editor.tabs = editor.tabs.filter(({ hidden, created }) => !hidden || (created ?? 0) > threshold);\n}\n\nfunction closeOldestTabUpdater(editor: State[\"editor\"]) {\n    const oldestId = editor.tabStack.shift()!;\n    editor.tabs = editor.tabs.filter(({ id }) => id !== oldestId);\n}\n\nfunction navTargetUpdater(tab: Tab, navTarget: NavTarget) {\n    tab.navTarget = replaceEqualDeep(tab.navTarget, navTarget);\n}\n\nfunction getExistingTab(target: NavTarget, editor: State[\"editor\"]) {\n    let existingTab = editor.tabs.find((t) => tabMatchesNavTarget(t, target));\n    if (!existingTab && target.type === \"CODE\") {\n        existingTab = editor.tabs.find((t) => t.navTarget.type === \"CODE\" && t.navTarget.codePath === HIDDEN_CODE_PATH);\n    }\n    return existingTab;\n}\n\nexport const openOrFocusTab =\n    (target: NavTarget, preserveExistingNavTarget = false): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n        updateState(`Open or focus tab: ${target.type}`, ({ editor }) => {\n            // Work out whether target matches an already-open tab. If so, just open that tab, otherwise create a new tab\n            const existingTab = getExistingTab(target, editor);\n            if (appId) {\n                editor.recentlyOpened[appId] ??= [];\n            }\n\n            if (existingTab) {\n                if (!preserveExistingNavTarget) {\n                    navTargetUpdater(existingTab, target);\n                }\n                // we might not be a temporary tab anymore\n                if (existingTab.temp) {\n                    existingTab.temp = target.temp;\n                }\n                delete existingTab.hidden;\n                const existingTabId = existingTab.id;\n                editor.tabStack = editor.tabStack.filter((id) => id !== existingTabId);\n                editor.tabStack.push(existingTab.id);\n                if (appId) {\n                    recentlyOpenedUpdater(editor.recentlyOpened[appId], existingTab);\n                }\n            } else {\n                const tab = { id: nextTabId++, navTarget: target, inView: true } as Tab;\n                createNewTabAndPushUpdater(editor, tab);\n                if (appId) {\n                    recentlyOpenedUpdater(editor.recentlyOpened[appId], tab);\n                }\n\n                while (editor.tabStack.length > 10) {\n                    closeOldestTabUpdater(editor);\n                }\n            }\n            closeTemporaryTabsUpdater(editor);\n            dropOldHiddenTabsUpdater(editor);\n        });\n        dispatch(createHiddenFormEditor());\n        dispatch(recordActivity(\"openOrFocusTab\", { navTarget: target }));\n        dispatch(raiseEvent(EVENTS.OPEN_OR_FOCUS_TAB));\n    };\n\nexport const updateTabsInView =\n    (tabId: Tab[\"id\"], isInView: boolean): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ editor }) => {\n            const tab = editor.tabs.find((tab) => tab.id === tabId);\n            if (tab) {\n                tab.inView = isInView;\n            }\n        });\n    };\n\n// like a normal tab - but we don't get added to the tabstack\nexport const updateOrCreateHiddenTab =\n    (target: NavTarget, index?: number): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        let created = Date.now();\n        if (target.type === \"CODE\") {\n            target = updateCodeTabView(getState(), target, dispatch);\n            if (target.codePath === HIDDEN_CODE_PATH) {\n                created = Number.POSITIVE_INFINITY;\n            }\n        }\n        updateState(({ editor }) => {\n            const existingTab = getExistingTab(target, editor);\n            if (existingTab) {\n                // don't change the nav target for a non-hidden form\n                if (!existingTab.hidden) return;\n                navTargetUpdater(existingTab, target);\n                existingTab.created = created;\n                if (typeof index === \"number\" && index < editor.tabs.length) {\n                    const existingTabId = existingTab.id;\n                    const currentIndex = editor.tabs.findIndex(({ id }) => existingTabId === id);\n                    if (currentIndex !== index) {\n                        editor.tabs.splice(currentIndex, 1);\n                        editor.tabs.splice(index, 0, existingTab);\n                    }\n                }\n            } else {\n                dropOldHiddenTabsUpdater(editor);\n                const numHidden = editor.tabs.reduce((sum, tab) => sum + Number(!!tab.hidden), 0);\n                if (numHidden < 5) {\n                    const tab = { id: nextTabId++, navTarget: target, hidden: true, created, inView: true } as Tab;\n                    createNewTabAndPushUpdater(editor, tab, index);\n                }\n            }\n        });\n        if (!hasHiddenFormEditor(getState())) {\n            dispatch(createHiddenFormEditor());\n        }\n    };\n\nconst hasHiddenFormEditor = (state: State) =>\n    !!getExistingTab({ type: \"CODE\", codePath: HIDDEN_CODE_PATH }, state.editor);\n\nexport const createHiddenFormEditor = (): AnvilAction => async (dispatch, getState, updateState) => {\n    if (!localStorage.disableHiddenFormEditor) {\n        dispatch(updateOrCreateHiddenTab({ type: \"CODE\", codePath: HIDDEN_CODE_PATH, temp: true }));\n    }\n};\n\nexport const navigateToTabMatchingTarget =\n    (target: NavTarget): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const tabs = getTabs(getState());\n        const tab = tabs.find((t) => tabMatchesNavTarget(t, target));\n        dispatch(navigate(tab?.navTarget || target));\n    };\n\nconst go =\n    (direction: number): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const state = getState();\n        const tabs = getTabs(state).filter((t) => !t.hidden);\n        const currentTabId = getCurrentTabId(state);\n        const currentTabIdx = tabs.findIndex((t) => t.id === currentTabId);\n        const newTabIdx = clamp(currentTabIdx + direction, 0, tabs.length - 1);\n        if (currentTabIdx !== newTabIdx) {\n            dispatch(navigate(tabs[newTabIdx].navTarget));\n        }\n    };\n\nexport const openTabToLeft = () => go(-1);\n\nexport const openTabToRight = () => go(1);\n\nexport const forceCloseTabs =\n    (...tabIds: number[]): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const currentTabId = getCurrentTabId(state);\n        const closingCurrentTab = currentTabId && tabIds.includes(currentTabId);\n        if (closingCurrentTab) {\n            const appId = getAppId(state);\n            const tabStack = state.editor.tabStack;\n            let prevId: number | null = null;\n            for (let i = tabStack.length - 1; i >= 0; i--) {\n                const id = tabStack[i];\n                if (!tabIds.includes(id)) {\n                    prevId = id;\n                    break;\n                }\n            }\n            if (appId) {\n                if (prevId === null) {\n                    await dispatch(navigate({ type: \"APP_ROOT\", appId }));\n                } else {\n                    const allTabs = getTabs(state);\n                    const tab = allTabs.find(({ id }) => id === prevId)!;\n                    await dispatch(navigate(tab.navTarget));\n                }\n            }\n        }\n        updateState(`Close tabs: ${tabIds}`, ({ editor }) => {\n            editor.tabs = editor.tabs.filter(({ id }) => !tabIds.includes(id));\n            editor.tabStack = editor.tabStack.filter((id) => !tabIds.includes(id));\n        });\n    };\n\nexport const closeTab =\n    (tabId: number): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const currentTabId = getCurrentTabId(state);\n        const inTutorialMode = getInTutorialMode(state);\n        if (inTutorialMode) {\n            const tabs = getTabs(state);\n            const closingTab = tabs.find((t) => t.id === tabId)!;\n            if (closingTab?.navTarget?.type === \"CODE\") {\n                dispatch(dispatchIDETutorialModalThenFocusBottomPanelOnQuit());\n                return;\n            }\n        }\n        if (currentTabId === tabId) {\n            // We're closing the current tab. Try to navigate to previous tab in the stack.\n            const appId = getAppId(state);\n            const prevId = getPreviousTabId(state);\n            const tabs = getTabs(state);\n            const prevTab = tabs.find((t) => t.id === prevId);\n            const newTarget = prevTab?.navTarget || { type: \"APP_ROOT\" };\n            if (appId && !(await dispatch(navigate(newTarget)))) {\n                // If we didn't succeed in navigating away (because of unsaved changes, probably), abort closing the tab.\n                return;\n            }\n        }\n\n        updateState(`Close tab: ${tabId}`, ({ editor }) => {\n            editor.tabs = editor.tabs.filter((t) => t.id !== tabId);\n            editor.tabStack = editor.tabStack.filter((id) => id !== tabId);\n        });\n        dispatch(createHiddenFormEditor());\n    };\n\nexport const closeTabFromNavTarget =\n    (navTarget: NavTarget): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const openTab = getTabs(getState()).find((t) => tabMatchesNavTarget(t, navTarget));\n        if (openTab === undefined) return;\n        dispatch(closeTab(openTab.id));\n        dispatch(createHiddenFormEditor());\n    };\n\nexport const closeAllTabs = (): AnvilAction => async (dispatch, getState, updateState) => {\n    const state = getState();\n    const appId = getAppId(state);\n    const inTutorialMode = getInTutorialMode(state);\n    if (inTutorialMode) {\n        dispatch(dispatchIDETutorialModalThenFocusBottomPanelOnQuit());\n        return;\n    }\n\n    if (appId && !(await dispatch(navigate({ type: \"APP_ROOT\" })))) {\n        // If we didn't succeed in navigating away (because of unsaved changes, probably), abort closing the tab.\n        return;\n    }\n    updateState(\"Close All Tabs\", ({ editor }) => {\n        editor.tabs = [];\n        editor.tabStack = [];\n    });\n    dispatch(createHiddenFormEditor());\n};\n\nexport const closeOtherTabs =\n    (tabId: number): AnvilAction =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const currentTabId = getCurrentTabId(state);\n        const inTutorialMode = getInTutorialMode(state);\n        if (inTutorialMode) {\n            dispatch(dispatchIDETutorialModalThenFocusBottomPanelOnQuit());\n            return;\n        }\n\n        if (currentTabId !== tabId) {\n            const appId = getAppId(state);\n            const tabs = getTabs(state);\n            const targetTab = tabs.find((t) => t.id === tabId);\n            if (appId && targetTab && !(await dispatch(navigate(targetTab.navTarget)))) {\n                // If we didn't succeed in navigating away (because of unsaved changes, probably), abort closing the tab.\n                return;\n            }\n        }\n\n        updateState(`Close other tabs: ${tabId}`, ({ editor }) => {\n            editor.tabs = editor.tabs.filter((t) => t.id === tabId);\n            editor.tabStack = editor.tabStack.filter((id) => id === tabId);\n        });\n    };\n\nconst getTabService = (service: ServiceType, state: State) => {\n    switch (service) {\n        case \"GOOGLE\":\n            return getGoogleService(state);\n        case \"FACEBOOK\":\n            return getFacebookService(state);\n        case \"MICROSOFT\":\n            return getMicrosoftService(state);\n        case \"USERS\":\n            return getUsersService(state);\n        case \"EMAIL\":\n            return getEmailService(state);\n        case \"STRIPE\":\n            return getStripeService(state);\n        case \"SECRETS\":\n            return getSecretsService(state);\n        case \"SAML\":\n            return getSAMLService(state);\n        case \"FILES\":\n            return getFileService(state);\n        case \"TABLEAU\":\n            return getTableauService(state);\n        case \"HAWTHORN_DEPLOYMENT\":\n            return getHawthornDeploymentService(state);\n    }\n};\n\nexport const shouldReloadForAppVersionChange = (tab: Tab) => {\n    // Keep this exhaustive: adding a new tab type should force an explicit\n    // decision about whether app-version changes should remount it.\n    switch (tab.navTarget.type) {\n        case \"CODE\":\n        case \"EXTRA_FILE\":\n        case \"PYTHON_SOURCE\":\n        case \"SERVICE\":\n        case \"SCHEDULED_TASKS\":\n        case \"DB_TABLE\":\n        case \"APP_SCHEMA\":\n        case \"SETTINGS\":\n        case \"THEME\":\n        case \"APP_DEPENDENCIES\":\n        case \"PYTHON_DEPENDENCIES\":\n        case \"JAVASCRIPT_DEPENDENCIES\":\n        case \"IMPORT_MAP\":\n            return true;\n        case \"APP_ROOT\":\n        case \"HELP\":\n        case \"BACKGROUND_TASKS\":\n        case \"CPU_USAGE\":\n        case \"MEMORY_USAGE\":\n        case \"SESSIONS\":\n        case \"SESSION\":\n        case \"CONVERSATION\":\n        case \"_COMPONENTS\":\n            return false;\n        default:\n            console.error(\"Unknown tab type when deciding app-version reload policy\", tab);\n            return true;\n    }\n};\n\nexport const revalidateAndReloadOpenTabs = (): AnvilAction => async (dispatch, getState, updateState) => {\n    const state = getState();\n    const allNames = getCodeNames(state);\n    const allCodeItems = Object.values(allNames);\n\n    const closeTabs = [] as number[];\n\n    for (const tab of getTabs(state)) {\n        const { navTarget } = tab;\n        if (navTarget.type === \"CODE\") {\n            if (!allCodeItems.find((i) => i.codePath === navTarget.codePath)) {\n                // The code item no-longer exists. Close the tab.\n                closeTabs.push(tab.id);\n            }\n        } else if (navTarget.type === \"SERVICE\") {\n            if (!getTabService((tab as ServiceTab).navTarget.service, state)) {\n                closeTabs.push(tab.id);\n            }\n        } else if (navTarget.type === \"SCHEDULED_TASKS\") {\n            if (!getScheduledTasks(state)) {\n                closeTabs.push(tab.id);\n            }\n        }\n    }\n    dispatch(forceCloseTabs(...closeTabs));\n    updateState(({ editor: { tabs } }) => {\n        for (const tab of tabs) {\n            if (shouldReloadForAppVersionChange(tab)) {\n                tab.forceReload = (tab.forceReload || 0) + 1;\n            }\n        }\n    });\n};\n\nexport const closeOldestTab = (): AnvilAction => (dispatch, getState, updateState) => {\n    updateState(({ editor }) => {\n        closeOldestTabUpdater(editor);\n    });\n};\n\nexport const updateTab =\n    <T extends Tab>(tab: T, updates: Partial<T>): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n        updateState((state) => {\n            const existingTab = getTabById(state, tab.id);\n            if (!existingTab) return;\n            const updatedTab = Object.assign(existingTab, updates);\n            if (appId && state.editor.recentlyOpened[appId]) {\n                // we could be updating the hidden tab - we want to ignore this update\n                recentlyOpenedUpdater(state.editor.recentlyOpened[appId], updatedTab, true);\n            }\n        });\n    };\n\nexport const persistTemporaryTab =\n    (tab: Tab): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        dispatch(updateTab(tab, { temp: false }));\n    };\n\nconst weakCache = new WeakMap();\n\nexport const useWrapWithPersistTab = (tab: Tab) => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const tabRef = useRef(tab);\n    useInsertionEffect(() => {\n        tabRef.current = tab;\n    }, [tab]);\n    // eslint-disable-next-line @typescript-eslint/ban-types\n    const wrapper = <T extends Function>(fn: T) => {\n        let wrapped = weakCache.get(fn);\n        if (wrapped) return wrapped as T;\n        wrapped = (...args: any[]) => {\n            dispatch(persistTemporaryTab(tabRef.current));\n            return fn(...args);\n        };\n        weakCache.set(fn, wrapped);\n        return wrapped as unknown as T;\n    };\n    return useCallback(wrapper, []);\n};\n\nconst calcAvailableTabSpace = (state: State) => {\n    let availableSpace = window.innerWidth - remToPixelMultiplier(7.1, getUserUiScale(state)); // window and primary nav\n    if (getNavMode(state) === \"docked\") {\n        availableSpace -= getSecondaryNavWidth(state);\n    }\n    if (state.debug.runMode === \"INLINE\") {\n        availableSpace -= parseInt(getSplitRunnerWidth(state));\n    }\n    return availableSpace;\n};\n\nexport function updateCodeTabView(state: State, target: CodeNavTarget, dispatch: AnvilDispatch) {\n    const availableSpace = calcAvailableTabSpace(state);\n    if (!target.view) {\n        let cachedView = getCachedView(state, target.codePath);\n\n        if (cachedView && Object.keys(cachedView).length > 1) {\n            const splitCodeEditorWidth = availableSpace * getSplitCodeEditorRatio(state);\n\n            //200px is arbitrary amount I picked\n            if (splitCodeEditorWidth < 200) {\n                cachedView = { design: true };\n            } else if (availableSpace - splitCodeEditorWidth < 200) {\n                cachedView = { ...cachedView, design: false };\n            }\n        }\n        if (getInTutorialMode(state) && itemTypeFromCodePath(target.codePath) === \"form\") {\n            cachedView = { design: true };\n        }\n        target = {\n            ...target,\n            view: cachedView,\n        };\n    }\n    // Extract which view type should be focused from essentialView before deleting it\n    if (target.essentialView) {\n        // Check which view type has a position array (not just boolean true)\n        // Determine which view type is essential\n        const essentialType = target.essentialView.html\n            ? \"html\"\n            : target.essentialView.htmlProperty\n              ? \"htmlProperty\"\n              : target.essentialView.code\n                ? \"code\"\n                : target.essentialView.design\n                  ? \"design\"\n                  : undefined;\n\n        const currentFocus = target.view?.focus;\n        if (essentialType) {\n            target.view = { ...target.view, ...target.essentialView, focus: essentialType };\n            const essentialViewValue = target.essentialView[essentialType];\n            if (Array.isArray(essentialViewValue) && essentialViewValue.length > 0) {\n                dispatch(cacheView(target.codePath, target.view));\n            }\n        }\n        if (currentFocus && currentFocus === essentialType) {\n            // we need to refocus the tab\n            target.refocusView = Math.random();\n        }\n    }\n    if (target.view?.focus && !target.view[target.view.focus]) {\n        target = { ...target, view: { ...target.view } };\n        if (!target.view) {\n            //pass\n        } else if (target.view.code) {\n            target.view.focus = \"code\";\n        } else if (target.view.html) {\n            target.view.focus = \"html\";\n        } else if (target.view.htmlProperty) {\n            target.view.focus = \"htmlProperty\";\n        } else {\n            target.view.focus = undefined;\n        }\n    }\n    if (target.view && getNumViews(target.view, \"design\") === 1) {\n        // we don't care about the focus if there's only one editor other than design\n        target = { ...target, view: { ...target.view, focus: undefined } };\n    }\n    delete target.essentialView;\n    return target;\n}\n\nexport const updateCodeTabTitle =\n    (tab: CodeTab, item: CodeItemYaml): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const newTitle = generateTitleFromCodeTabItem(tab, item);\n        if (tab.title !== newTitle) {\n            dispatch(updateTabTitle(tab, newTitle));\n        }\n    };\n\nexport const updateCodeTabIcon =\n    (tab: CodeTab, itemType: CodeItemType, item: CodeItemYaml): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const newIcon = getIconFromFile(itemType, item);\n        if (tab.icon !== newIcon) {\n            dispatch(updateTab(tab, { icon: newIcon, itemType }));\n        }\n    };\n\n/** TODO it would be nice if this wasn't in a useEffect */\nexport function useUpdateTabTitle(tab: Tab, title: string) {\n    const dispatch = useDispatch<AnvilDispatch>();\n    useEffect(() => {\n        if (tab.title === title) return;\n        dispatch(updateTabTitle(tab, title));\n    }, [tab, title, dispatch]);\n}\n\nexport const updateTabTitle = (tab: Tab, title?: string) => updateTab(tab, { title });\nexport const updateTabLoading = (tab: Tab, $loading: boolean) => updateTab(tab, { $loading });\n\nexport const updateCodeTabPrefs =\n    (tab: CodeTab, updates: Partial<CodeTabPrefs>): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const codeTabPrefs = { ...tab.codeTabPrefs, ...updates };\n        dispatch(updateTab(tab, { codeTabPrefs }));\n        updateState(`updating code tab prefs: ${JSON.stringify(updates)}`, ({ editor }) => {\n            editor.codeTabPrefs = { ...editor.codeTabPrefs, ...codeTabPrefs };\n        });\n    };\n\nexport const getTabs = (state: State) => state.editor.tabs;\nexport const getTabStack = (state: State) => state.editor.tabStack;\n\nconst defaultOpened: Tab[] = [];\nexport const getRecentlyOpened = createSelector(\n    [(s: State) => s.editor.recentlyOpened, (s: State) => getAppId(s)],\n    (recentlyOpened, appId) => (appId && recentlyOpened?.[appId]) ?? defaultOpened\n);\n\n/** @returns {string} */\nexport const getCurrentTabId = (state: State) => state.editor.tabStack[state.editor.tabStack.length - 1];\nexport const getPreviousTabId = (state: State) => state.editor.tabStack[state.editor.tabStack.length - 2];\nexport const getTabById = (state: State, id: number) => state.editor.tabs?.find((t) => t.id === id);\nexport const getTabByCodePath = (state: State, codePath: string) =>\n    state.editor.tabs?.find(({ navTarget }) => navTarget.type === \"CODE\" && navTarget.codePath === codePath);\n\nexport const moveTab =\n    (fromTab: Tab, maybeToTab: Tab | null | undefined): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const state = getState();\n        let tabs = getTabs(state);\n        maybeToTab ??= tabs.at(-1);\n        if (maybeToTab == null) {\n            return;\n        }\n        const toTab = maybeToTab;\n        if (fromTab.id === toTab.id) return;\n        const fromIndex = tabs.findIndex(({ id }) => id === fromTab.id);\n        const toIndex = tabs.findIndex(({ id }) => id === toTab.id);\n\n        if (fromIndex === -1 || toIndex === -1) return;\n\n        if (toIndex < fromIndex) {\n            // to goes before from\n            tabs = [\n                ...tabs.slice(0, toIndex),\n                fromTab,\n                toTab,\n                ...tabs.slice(toIndex + 1, fromIndex),\n                ...tabs.slice(fromIndex + 1),\n            ];\n        } else {\n            tabs = [\n                ...tabs.slice(0, fromIndex),\n                ...tabs.slice(fromIndex + 1, toIndex),\n                toTab,\n                fromTab,\n                ...tabs.slice(toIndex + 1),\n            ];\n        }\n        updateState(({ editor }) => {\n            editor.tabs = tabs;\n        });\n    };\n\nexport const moveTabWithCodePath =\n    (fromCodePath: CodePath, maybeToTab: Tab | null | undefined): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const moveToEnd = maybeToTab === null;\n        const tabs = getTabs(getState());\n        maybeToTab ??= tabs.at(-1);\n        const fromTab = tabs.find(({ navTarget }) => navTarget.type === \"CODE\" && navTarget.codePath === fromCodePath);\n        if (maybeToTab == null) {\n            // no tabs are open\n        } else if (fromTab) {\n            dispatch(moveTab(fromTab, maybeToTab));\n        } else if (!moveToEnd) {\n            const toTab = maybeToTab;\n            const toIndex = tabs.findIndex(({ id }) => id === toTab.id);\n            dispatch(updateOrCreateHiddenTab({ type: \"CODE\", codePath: fromCodePath }, toIndex));\n        }\n        dispatch(navigate(fromTab?.navTarget || { type: \"CODE\", codePath: fromCodePath }));\n    };\n\nexport const maybeInsertFormTabAfter =\n    (openCodePath: CodePath, adjacentToCodePath: CodePath, navTarget: CodeNavTarget): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const tabs = getTabs(getState());\n        const existingTab = tabs.find(\n            ({ navTarget }) => navTarget.type === \"CODE\" && navTarget.codePath === openCodePath\n        );\n        const adjacentToTabIndex = tabs.findIndex(\n            ({ navTarget }) => navTarget.type === \"CODE\" && navTarget.codePath === adjacentToCodePath\n        );\n        if (adjacentToTabIndex > -1) {\n            dispatch(updateOrCreateHiddenTab(navTarget, adjacentToTabIndex + 1));\n        } else if (existingTab) {\n            dispatch(updateOrCreateHiddenTab(navTarget));\n        }\n    };\n\nexport const openDefaultTabs = (): AnvilAction => async (dispatch, getState, updateState) => {\n    const state = getState();\n    const user = getUser(state);\n    const appId = getAppId(state)!;\n    const invalidYaml = getInvalidYaml(state);\n    const startupItem = getAppStartupItem(state);\n    const hasTabsAlready = !!getTabs(state).length;\n\n    const showHelpTab =\n        user?.uiPrefs?.showHelpTabOnStartup === undefined\n            ? getAbFlag(dispatch, user, USER_AB_FLAGS.helpTabOnStartup)\n            : user.uiPrefs.showHelpTabOnStartup;\n    const showStartupItem = !!startupItem?.module;\n\n    const tabs: Tab[] = [];\n\n    const openCodePath = (codePath: CodePath) =>\n        tabs.push({\n            type: \"CODE\",\n            navTarget: { appId, type: \"CODE\", codePath, editingPath: [] },\n            codeTabPrefs: { ...state.editor.codeTabPrefs },\n            id: nextTabId++,\n        } as CodeTab);\n\n    if (!hasTabsAlready) {\n        if (startupItem && showStartupItem) {\n            openCodePath(`${startupItem.type}s/${startupItem.module}`);\n        } else {\n            const { serverCode, scripts } = getCodeStructure(state);\n            if (serverCode.children.length) {\n                openCodePath(serverCode.children[0].codePath);\n            } else if (scripts.children.length) {\n                openCodePath(scripts.children[0].codePath);\n            }\n        }\n        if (showHelpTab && !invalidYaml) {\n            tabs.push({ navTarget: { type: \"HELP\" }, title: \"Help\", id: nextTabId++ });\n        }\n    }\n\n    updateState(({ editor }) => {\n        for (const tab of tabs) {\n            if (!editor.tabs.find((t) => tabMatchesNavTarget(t, tab.navTarget))) {\n                editor.tabs.unshift(tab);\n                editor.tabStack.unshift(tab.id);\n                if (appId) {\n                    editor.recentlyOpened[appId] ??= [];\n                    recentlyOpenedUpdater(editor.recentlyOpened[appId], tab);\n                }\n            }\n        }\n    });\n\n    if (!hasTabsAlready && tabs[0]) {\n        dispatch(navigate(tabs[0].navTarget, true));\n    }\n};\n\nexport const removeRecentlyOpened =\n    (...tabs: Tab[]): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const appId = getAppId(getState());\n        if (!appId) return;\n        updateState(({ editor }) => {\n            editor.recentlyOpened[appId] =\n                editor.recentlyOpened[appId]?.filter(\n                    (t) => !tabs.some((tab) => tabMatchesNavTarget(t, tab.navTarget))\n                ) ?? [];\n        });\n    };\n","/**\n * Dated, temporary intervention (2026-08, revised 2026-11): brand new users whose `talk-to-us-v2`\n * survey answers mark them as a prospect (`User.talkToUsProspect`, worked out on the server by\n * anvil.works.prospects/talk-to-us-v2-prospect?) are offered an Amazon gift card if they book a\n * feedback call within an hour of signing up.\n *\n * The IDE side of this offer lives here and in `components/TalkToUsOffer`, so it can be removed\n * again cleanly. Click-through is recorded in UI prefs.\n */\nimport { useEffect, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { openOrFocusBottomTab } from \"@/controllers/bottom-tabs\";\nimport { getInTutorialMode } from \"@/controllers/ideTutorial\";\nimport { updateUserEditorPrefs, useAbFlag } from \"@/controllers/user\";\nimport { recordActivity } from \"@/controllers/util\";\nimport { AnvilAction, AnvilAsyncAction, AnvilDispatch, State } from \"@/types\";\nimport { USER_AB_FLAGS } from \"@/types/user\";\nimport { formatCountdown } from \"@/util/time\";\n\n/**\n * Switch for the whole offer. It was off 2026-10 to 2026-11; it's back on, now gated on the\n * talk-to-us-v2 survey rather than an explicit \"open to a call?\" question. The matching drip email\n * (drip-011-interview-request) uses the same criteria, via q/talk-to-us-v2-prospect. `forceOffer`\n * still works for testing while this is off.\n */\nconst TALK_TO_US_OFFER_ENABLED = true;\n\nexport const TALK_TO_US_SCHEDULING_URL = \"https://calendly.com/meredydd/feedback-call-with-anvil-s-ceo\";\n\n/** Banner copy test. See components/TalkToUsOffer for what each arm shows. */\nexport type TalkToUsBannerArm = \"original\" | \"personal\" | \"personal-no-countdown\";\nconst TALK_TO_US_BANNER_ARMS: TalkToUsBannerArm[] = [\"original\", \"personal\", \"personal-no-countdown\"];\n\nconst getBannerArm = (state: State) =>\n    state.user?.ab?.[USER_AB_FLAGS.talkToUsBannerTest] as TalkToUsBannerArm | undefined;\n\n/**\n * The offer is open for the first hour after the user signs up - or a week, for the arm with no\n * countdown on screen. Users get their arm while the banner is showing, so within that first hour.\n */\nconst getOfferWindowMs = (state: State) =>\n    getBannerArm(state) === \"personal-no-countdown\" ? 7 * 24 * 60 * 60 * 1000 : 60 * 60 * 1000;\n\n/** Set when the user clicks through to the scheduling page. Not a confirmed booking. */\nconst TALK_TO_US_OPENED_LINK_PREF = \"2026-11-talk-to-us-opened-scheduling-link\";\n\n/**\n * Escape hatch for testing: overrides the survey verdict, paid plan and the offer window, since our\n * test accounts fail all three. It deliberately does *not* override the click-through pref, so that the\n * \"offer disappears once you've opened the link\" behaviour stays testable - clear that pref to\n * bring the offer back.\n */\nconst forceOffer = () => !!localStorage[\"forceTalkToUsOffer\"];\n\n/** Fixed once per page load, so a forced countdown ticks down instead of standing still. */\nlet forcedDeadline: number | null = null;\n\nconst getDeadline = (state: State) => {\n    const registrationDate = state.user?.registrationDate;\n    const registeredAt = registrationDate ? +new Date(registrationDate) : NaN;\n    const deadline = isNaN(registeredAt) ? null : registeredAt + getOfferWindowMs(state);\n\n    // When forcing, a real account is almost always older than the window, so give it a fresh one.\n    if (forceOffer() && (deadline == null || deadline <= Date.now())) {\n        forcedDeadline ??= Date.now() + getOfferWindowMs(state);\n        return forcedDeadline;\n    }\n    return deadline;\n};\n\n/**\n * Everything except the AB arm itself: this is the population we're allowed to randomise, so we\n * don't bucket users who could never have seen the offer anyway.\n */\nconst getTalkToUsOfferCandidate = (state: State) => {\n    const user = state.user;\n    if (!user?.$loaded) return false;\n    //if (user.uiPrefs?.[TALK_TO_US_OPENED_LINK_PREF]) return false;\n    if (forceOffer()) return true;\n    if (!TALK_TO_US_OFFER_ENABLED) return false;\n    // Includes ruling out educational email addresses\n    if (!user.talkToUsProspect) return false;\n    if (user.plan?.[\"paid-plan\"]) return false;\n    const deadline = getDeadline(state);\n    return deadline != null && deadline > Date.now();\n};\n\n/** Should the offer be on screen right now? Also drives the bottom-panel tab list. */\nexport const getShowTalkToUsOffer = (state: State) =>\n    getTalkToUsOfferCandidate(state) &&\n    !state.editor?.talkToUsOfferExpired;\n\nconst markExpired = (): AnvilAction => (dispatch, getState, updateState) => {\n    if (getState().editor?.talkToUsOfferExpired) return;\n    updateState(\"Talk-to-us offer expired\", ({ editor }) => {\n        editor.talkToUsOfferExpired = true;\n    });\n};\n\nconst autoOpenBottomTab = (): AnvilAction => (dispatch, getState, updateState) => {\n    // Tracked in the store, not a ref: BottomPanel is remounted every time the bottom panel opens\n    // or closes, so a per-component guard would re-fire and make the panel impossible to close.\n    if (getState().editor?.talkToUsOfferAutoOpened) return;\n    if (!getState().app?.$loaded) return;\n    updateState(\"Talk-to-us offer auto-opened\", ({ editor }) => {\n        editor.talkToUsOfferAutoOpened = true;\n    });\n    dispatch(openOrFocusBottomTab({ type: \"talkToUs\" }));\n};\n\n/**\n * The whole client-side lifecycle of the offer in one place: assigns the AB arm, runs the live\n * countdown, retires the offer when it runs out, and opens the bottom-panel tab the first time the\n * user becomes eligible.\n *\n * Cheap and idempotent, so it's safe to call from anywhere the offer might appear. Callers that\n * only need the side effects (eg BottomPanel, which has to assign the arm even when the tab isn't\n * showing yet) can ignore the return value.\n */\nexport const useTalkToUsOffer = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const candidate = useSelector(getTalkToUsOfferCandidate);\n    // Passing `[]` when they aren't a candidate means only users who could see it get an arm\n    const arm: TalkToUsBannerArm | undefined = useAbFlag(\n        USER_AB_FLAGS.talkToUsBannerTest,\n        candidate ? TALK_TO_US_BANNER_ARMS : []\n    );\n    const inTutorialMode = useSelector(getInTutorialMode);\n    const deadline = useSelector(getDeadline);\n    const show = useSelector(getShowTalkToUsOffer);\n    // There is no bottom panel until an app is open, so the start page must not claim the current\n    // tab: the forced tutorial only auto-opens if no tab is selected when BottomPanel first mounts.\n    const appLoaded = useSelector((state: State) => !!state.app?.$loaded);\n\n    // Only tick while the offer is actually live. This hook is called from BottomPanel, which every\n    // user has, so an unconditional 1s timer would re-render the panel forever for everybody.\n    const [now, setNow] = useState(Date.now);\n    useEffect(() => {\n        if (!show) return;\n        setNow(Date.now());\n        const timer = setInterval(() => setNow(Date.now()), 1000);\n        return () => clearInterval(timer);\n    }, [show]);\n\n    const msRemaining = deadline == null ? 0 : deadline - now;\n    const expired = msRemaining <= 0;\n\n    useEffect(() => {\n        if (!show) return;\n        if (expired) {\n            dispatch(markExpired());\n        } else if (!inTutorialMode && appLoaded) {\n            dispatch(autoOpenBottomTab());\n        }\n    }, [show, expired, inTutorialMode, appLoaded]);\n\n    return { show: show && !expired, arm, countdown: formatCountdown(msRemaining) };\n};\n\nexport type TalkToUsOfferPlacement = \"startPage\" | \"bottomPanel\";\n\n/**\n * Calendly records UTM parameters against each booking, so tag the link with where the offer was\n * shown and which banner arm the user saw. Keep `utm_campaign` in step with the drip email\n * (drip-011-interview-request) so both channels group together in Calendly.\n *\n * We also prefill the booking form with the user's name and email: one less step for them, and it\n * lets us match bookings to accounts.\n */\nconst getTalkToUsSchedulingUrl = (state: State, placement: TalkToUsOfferPlacement, bannerVariant?: string | null) => {\n    const url = new URL(TALK_TO_US_SCHEDULING_URL);\n    const { name, email } = state.user ?? {};\n    if (name) url.searchParams.set(\"name\", name);\n    if (email) url.searchParams.set(\"email\", email);\n    url.searchParams.set(\"utm_medium\", \"ide\");\n    url.searchParams.set(\"utm_source\", placement === \"startPage\" ? \"ide:start-page\" : \"ide:bottom-panel\");\n    url.searchParams.set(\"utm_campaign\", \"talk-to-us-offer\");\n    if (bannerVariant) url.searchParams.set(\"utm_content\", bannerVariant);\n    return url.toString();\n};\n\n/** Opens the scheduling page, and retires the offer - they've done what we asked. */\nexport const openTalkToUsScheduling =\n    (placement: TalkToUsOfferPlacement, bannerVariant?: string | null): AnvilAsyncAction =>\n    async (dispatch, getState) => {\n        window.open(getTalkToUsSchedulingUrl(getState(), placement, bannerVariant), \"_blank\", \"noopener\");\n        dispatch(recordActivity(\"talkToUsOfferSchedulingLinkOpened\"));\n        await dispatch(updateUserEditorPrefs(TALK_TO_US_OPENED_LINK_PREF, true));\n    };\n","import { type AgentTypeId } from \"@/agent/types\";\nimport type { State } from \"@/types\";\n\n// Also defined in the Agent Host (rpc_types.ts).\n// We don't import it from there because that would require building the entire agent host.\nexport const AGENT_TYPE_IDS = [\"codex\", \"claude\", \"zai\", \"codex-anvil\"] as const;\n\nexport const AGENT_TYPE_NAMES: Record<AgentTypeId, string> = {\n    codex: \"ChatGPT/Codex\",\n    claude: \"Claude\",\n    zai: \"Z.ai\",\n    \"codex-anvil\": \"Codex (included)\",\n};\n\nexport const getAgentTypeName = (agentType: AgentTypeId | undefined) =>\n    agentType === undefined ? \"Agent\" : AGENT_TYPE_NAMES[agentType];\n\nexport const getEnabledAgentTypes = (state: State) =>\n    state.user?.ideConfig.enabledAgentTypes ?? [...AGENT_TYPE_IDS];\n\nexport const getDefaultAgent = (state: State): AgentTypeId => {\n    const enabled = getEnabledAgentTypes(state);\n    // The Anvil-managed (included) Codex is the default wherever it is available:\n    // zero setup, and it's what the plan includes. Bring-your-own Codex otherwise.\n    const builtInDefault: AgentTypeId = enabled.includes(\"codex-anvil\") ? \"codex-anvil\" : \"codex\";\n    const preferred = state.user?.uiPrefs?.defaultAgent ?? builtInDefault;\n    if (enabled.includes(preferred)) {\n        return preferred;\n    }\n    if (enabled[0]) {\n        return enabled[0];\n    }\n    throw Error(\"No agent types are enabled\");\n};\n","import { useDispatch, useSelector } from \"react-redux\";\nimport { AchievementId } from \"@platform-runner/instrumentation\";\nimport confetti from \"canvas-confetti\";\nimport { set } from \"lodash-es\";\nimport { createSelector } from \"reselect\";\nimport * as api from \"@/api\";\nimport { setAbArm } from \"@/api\";\nimport { tracker } from \"@/components/IDE\";\nimport { getInTutorialMode } from \"@/controllers/ideTutorial\";\nimport { recordActivity } from \"@/controllers/util\";\nimport { navigate } from \"@/router/navigation\";\nimport { AnvilAction, AnvilAsyncAction, AnvilDispatch, State } from \"@/types\";\nimport { CtaKey, ServerRuntime, User } from \"@/types/user\";\nimport type { UserABFlagName } from \"@/types/user\";\nimport { getFeatureSupport, getPlanName } from \"@/util/features\";\nimport { get } from \"@/util/fetch\";\nimport { getAppId, markUnsaved, updateGlobalLoadingIndicator } from \"./app\";\nimport {\n    getSubscription,\n    getUser,\n    reloadSubscription,\n    reloadSubscriptionInManagerOrIde,\n    reloadUser,\n    stopApp,\n} from \"./ide\";\nimport { alert, modal, prompt } from \"./modals\";\n\nexport const updateUserEditorPrefs =\n    (editorOption: keyof User[\"uiPrefs\"], newOption: any): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const markSaved = dispatch(markUnsaved(`user-${editorOption}`));\n        try {\n            const updatedPrefs = await api.updateUiPrefs([editorOption], newOption);\n            updateState(`Configure User ${editorOption}`, set, [\"user\", \"uiPrefs\"], updatedPrefs);\n        } finally {\n            markSaved();\n        }\n    };\n\nexport const updateSshKeys =\n    (newKeys: string): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const markSaved = dispatch(markUnsaved(\"ssh-keys\"));\n        try {\n            await api.setSSHKeys(newKeys);\n            const apiKeys = await api.getSSHKeys();\n            updateState(\"Update SSH keys\", set, [\"ssh\"], apiKeys);\n        } finally {\n            markSaved();\n        }\n    };\n\nexport const updateSubscriptionToMailingList =\n    (optIn: unknown, list: string): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        const markSaved = dispatch(markUnsaved(`mailing-list`));\n        try {\n            api.subscribeToMailingList(optIn, list);\n            updateState(({ user }) => {\n                user.mailingListSubscriptions ??= {};\n                user.mailingListSubscriptions[list] = optIn;\n            });\n        } finally {\n            markSaved();\n        }\n    };\n\nexport const updateUser =\n    (updates: Partial<User>): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ user }) => {\n            Object.assign(user, updates);\n        });\n    };\n\nexport const updateUser2faEnabled =\n    (enabled: boolean): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ user }) => {\n            user[\"2fa\"].enabled = enabled;\n        });\n    };\n\nexport const updatePasswordExpires =\n    (date: number): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ user }) => {\n            user.passwordExpires = date;\n        });\n    };\n\nexport const reloadUserServerRuntimes =\n    (): AnvilAsyncAction<ServerRuntime[]> => async (dispatch, getState, updateState) => {\n        const serverRuntimes = await api.getUserServerRuntimes();\n        updateState(({ user }) => {\n            user.server_runtimes = serverRuntimes;\n        });\n        return serverRuntimes; // So we can use the updated runtimes immediately without waiting for a render\n    };\n\nexport const updateInvoiceEmail =\n    (email?: string): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        if (email === undefined) return;\n        const subscription = getSubscription(getState());\n        if (!subscription) return;\n        const { licenceKey } = subscription;\n        await api.setInvoiceEmail(licenceKey, email);\n        updateState((state) => {\n            state.subscription!.invoiceEmail = email;\n        });\n    };\n\nexport const startTrial =\n    (feature: string): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        await api.startRuntimeTrial(feature);\n        await dispatch(reloadUser());\n    };\n\nexport const cancelSubscription =\n    (feedback = \"\"): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        let response;\n        try {\n            dispatch(updateGlobalLoadingIndicator(true));\n            const subscription = getSubscription(getState());\n            if (!subscription) return;\n            const { licenceKey } = subscription;\n            response = await api.cancelSubscriptionRequest(licenceKey, feedback);\n            await dispatch(reloadSubscriptionInManagerOrIde());\n            response = {};\n        } catch (e) {\n            response = { error: e };\n        } finally {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n\n        return response;\n    };\n\nexport const uncancelSubscription = (): AnvilAsyncAction => async (dispatch, getState, updateState) => {\n    try {\n        dispatch(updateGlobalLoadingIndicator(true));\n        const subscription = getSubscription(getState());\n        if (!subscription) throw Error(\"No subscription.\");\n        const { licenceKey } = subscription;\n        await api.uncancelSubscriptionRequest(licenceKey);\n        await dispatch(reloadSubscriptionInManagerOrIde());\n        dispatch(\n            alert(\"Un-cancel Subscription Request Confirmed\", \"Your subscription has been successfully un-cancelled.\")\n        );\n    } catch (e: any) {\n        dispatch(\n            alert(\n                \"Unable to Un-Cancel Subscription\",\n                e?.error || \"Unable to un-cancel your subscription, please contact support@anvil.works\"\n            )\n        );\n    } finally {\n        dispatch(updateGlobalLoadingIndicator(false));\n    }\n};\n\nexport const joinOrgWithLicenseKey =\n    (licenseKey: string): AnvilAsyncAction<{ resp: any } | { error: unknown }> =>\n    async (dispatch, getState, updateState) => {\n        let response;\n        try {\n            dispatch(updateGlobalLoadingIndicator(true));\n            response = await api.enterLicenceKey(licenseKey);\n            await dispatch(reloadSubscription());\n        } catch (e) {\n            response = { error: e };\n        } finally {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n        return response;\n    };\n\nexport const acceptOrgInvite =\n    (token: string): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        let name: string | null | undefined = getUserName(getState());\n        if (!name)\n            name = await dispatch(\n                prompt(\"Accept Invitation\", \"Please enter your name to join this subscription\", \"\", \"Submit\")\n            );\n        try {\n            const { resp } = await api.acceptOrgInvite(token, name);\n            dispatch(alert(\"Invitation Accepted\", `You're now a part of a ${getPlanName(resp.plan)} plan.`));\n        } catch (e: any) {\n            dispatch(alert(\"Error accepting invite\", e.toString()));\n        }\n        await dispatch(navigate({ type: \"START_PAGE\" }, true));\n        dispatch(reloadSubscription());\n    };\n\nexport const setUserAlwaysShowNewDesigner =\n    (value: boolean): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState((s) => {\n            s.editor.designer.showClassicDesigner = !value;\n        });\n        dispatch(recordActivity(\"previewV3Designer\", { enabled: value }));\n    };\n\n// This is a nasty little hack to bridge the duration of the setAbArm() call\nconst abCache: Record<string, any> = {};\n\nexport const getAbFlag = (\n    dispatch: AnvilDispatch | null /* Can be null if not setting values */,\n    user: User,\n    flagName: UserABFlagName,\n    values: any = [false, true]\n) => {\n    if (!user?.ab || (user?.plan?.[\"paid-plan\"] === \"enterprise\" && values?.length > 0)) {\n        return values[0];\n    } else if (user.ab && flagName in user.ab) {\n        return user.ab[flagName];\n    } else if (flagName in abCache) {\n        return abCache[flagName];\n    } else if (values.length === 0) {\n        // empty array signals \"do not set\"\n        return undefined;\n    } else {\n        const value = values[Math.floor(Math.random() * values.length)];\n        abCache[flagName] = value;\n        dispatch!(async (dispatch, getState, updateState) => {\n            await setAbArm(flagName, value);\n            updateState(({ user: { ab } }) => {\n                ab[flagName] = value;\n            });\n            delete abCache[flagName];\n        });\n        return value;\n    }\n};\n\nexport const updateUserAb =\n    (flagName: UserABFlagName, value: any): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        updateState(({ user: { ab } }) => {\n            ab[flagName] = value;\n        });\n        setAbArm(flagName, value);\n    };\n\nexport const getUserAb = (state: State, flagName: UserABFlagName) => state.user?.ab?.[flagName];\n\nexport const getUserHasAchievement = (state: State, achievementName: AchievementId) =>\n    !!state.user?.achievements?.[achievementName]?.completed;\n\n/**\n * Returns a random value from the values array, setting the AB flag in the backend.\n * If the flag is already set, it will return the existing value.\n * If the user has not loaded yet, you will get the first value in the array\n * If you pass an empty array, you will get the existing value if it exists, otherwise undefined and the flag will NOT be set.\n */\nexport const useAbFlag = (flagName: UserABFlagName, values: any[] = [false, true]) => {\n    const dispatch = useDispatch();\n    const user = useSelector(getUser);\n    return getAbFlag(dispatch, user, flagName, values);\n};\n\nexport const setRoadmapStep =\n    (newStepId: string): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        api.setRoadmapStep(newStepId);\n\n        updateState(({ user: { roadmap } }) => {\n            roadmap.currentStep = newStepId;\n        });\n    };\n\nexport const markRoadmapStep =\n    (stepId: string, complete = true): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        if (complete) {\n            api.markRoadmapStepComplete(stepId);\n            updateState(({ user: { roadmap } }) => {\n                roadmap.completed ??= {};\n                roadmap.completed[stepId] = new Date().toISOString();\n            });\n        } else {\n            api.markRoadmapStepIncomplete(stepId);\n            updateState(({ user: { roadmap } }) => {\n                const completed = roadmap.completed;\n                if (completed) {\n                    delete completed[stepId];\n                }\n            });\n        }\n    };\n\nexport const claimAchievement =\n    (achievementId: AchievementId): AnvilAsyncAction =>\n    async (dispatch, getState, updateState) => {\n        console.log(\"Claim achievement: \", achievementId);\n        const state = getState();\n        const user = getUser(state);\n        const appId = getAppId(state);\n        if (!user.achievements?.[achievementId]?.completed) {\n            if (achievementId === \"handledFormEvent\") {\n                // This one is special right now, and gets confetti.\n                const inTutorialMode = getInTutorialMode(getState());\n\n                if (inTutorialMode) {\n                    dispatch(modal(\"claimedAchievement\", {})); // No await\n                    setTimeout(() => confetti({ zIndex: 200, particleCount: 100, spread: 90 }), 300);\n                    dispatch(stopApp()); // No await\n                }\n            }\n\n            const achievements = await api.claimAchievement(achievementId, appId);\n            tracker?.setMetadata(\"Achievement\", achievementId);\n            updateState(({ user }) => {\n                user.achievements = achievements;\n            });\n        }\n    };\n\nexport const chooseAbFlag =\n    (flagName: UserABFlagName, values: any = [false, true]): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const user = getUser(getState());\n        getAbFlag(dispatch, user, flagName, values);\n    };\n\nexport const updateCtaKey =\n    (ctaKey: CtaKey, value: boolean): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const user = getState().user;\n        if (!user) return;\n        dispatch(updateUserEditorPrefs(\"collapsedCTA\", { ...user.uiPrefs.collapsedCTA, [ctaKey]: value }));\n    };\n\nexport const getCtaKey = (state: State, ctaKey: CtaKey) => state.user?.uiPrefs?.collapsedCTA?.[ctaKey];\n\nexport const getPasswordExpires = (state: State) => state.user?.passwordExpires || 0;\n/**\n * This should not be used to check for darkmode\n * if you want to check darkmode use `useIsDark()`\n */\nexport const getUserTheme = (state: State) => state.user?.uiPrefs?.theme;\n/** Scales are set at 0.6, 0.75, 1, 1.25, 1.4 */\nexport const getUserUiScale = (state: State): \"tiny\" | \"small\" | \"medium\" | \"large\" | \"huge\" =>\n    state.user?.uiPrefs?.scale ?? localStorage.ideScale ?? \"medium\";\nexport const getUserEslintPref = (state: State) => state.user?.uiPrefs?.eslint ?? true;\nexport const getUserKeyBindings = (state: State) => state.user?.uiPrefs?.keyBindings ?? \"default\";\nexport const getUserAutoImport = (state: State) => Number(state.user?.uiPrefs?.autoImport ?? 1);\nexport const getUserTabSize = (state: State) => Number(state.user?.uiPrefs?.tabSize || 2);\nexport const getUserPythonInlayHints = (state: State) => state.user?.uiPrefs?.pythonInlayHints ?? false;\nexport const getUserMinimapPref = (state: State) => state.user?.uiPrefs?.minimap ?? true;\nexport const getUserCodeTemplates = (state: State) => state.user?.uiPrefs?.codeTemplates ?? \"standard\";\nexport const getUserRegistrationAgeDays = createSelector([(s) => getUser(s)], (user) =>\n    user?.registrationDate\n        ? Math.floor((+new Date() - +new Date(user?.registrationDate)) / (24 * 3600 * 1000))\n        : undefined\n);\n\nexport const getEligibleOffers = (state: State) => state.user?.currentOffers?.eligible;\nexport const getActiveOffers = (state: State) => state.user?.currentOffers?.active;\n\nexport const getSshKeys = (state: State) => state.ssh?.keys;\nexport const getUserUiPrefs = (state: State) => state.user?.uiPrefs;\nexport const getInvoices = (state: State) => state.invoices;\nexport const getUserRoadmap = (state: State) => state.user?.roadmap;\nexport const getShowRoadmap = (state: State) => state.user?.roadmap?.enabled;\nexport const getUserName = (state: State) => state.user?.name;\n\nexport const getCustomPackagesAvailable = (state: State) => getFeatureSupport(state, \"custom-packages\");\n\nexport const getHasExitedTutorialTab = (state: State) => getCtaKey(state, \"bottomPanel\");\nexport const getUserWasShownWelcomeModal = (state: State) => getCtaKey(state, \"welcome\");\n\nexport const getUserWasShownIntroVideo = (state: State) => state.user?.uiPrefs?.userWasShownIntroVideo;\n\nexport const getUserHasClosedFeedbackPromoBanner = (state: State) =>\n    state.user?.uiPrefs?.userHasClosedFeedbackPromoBanner;\n","import type { AnvilAction, AnvilAsyncAction, State } from \"@/types\";\nimport * as api from \"@/api\";\nimport { getAppId, getLoadingIndicator, updateGlobalLoadingIndicator } from \"./app\";\n\nconst aborters: { [key: string]: AbortController[] } = {};\n\nexport const registerAborter = (key: string, abortPrevious = true) => {\n    if (abortPrevious) abort(key);\n    const aborter = new AbortController();\n    const clearAborter = () => {\n        delete aborters[key];\n    };\n    (aborters[key] ??= []).push(aborter);\n    return [aborter, clearAborter] as const;\n};\n\nexport const abort = (key: string) => {\n    for (const a of aborters[key] || []) {\n        a.abort();\n    }\n    delete aborters[key];\n};\n\nexport const defaultStandardFormCode =\n    \"from anvil import *\\n\\nclass $NAME$($NAME$Template):\\n\\n  def __init__(self, **properties):\\n    # Set Form properties and Data Bindings.\\n    super().__init__(**properties)\\n\\n    # Any code you write here will run before the form opens.\";\n\nexport const defaultMinimalFormCode =\n    \"\\n\\nclass $NAME$($NAME$Template):\\n\\n  def __init__(self, **properties):\\n    super().__init__(**properties)\\n\\n\";\n\nexport const blankFormTemplate = {\n    class_name: \"Form\",\n    container: { type: \"ColumnPanel\" },\n    components: [],\n    code: defaultStandardFormCode,\n    is_package: true,\n} as const;\n\nexport const dataRowPanel = {\n    class_name: \"Form\",\n    container: { type: \"DataRowPanel\" },\n    components: [],\n    code: defaultStandardFormCode,\n    is_package: true,\n} as const;\n\n// TODO - decide how to present this to the user\nexport const htmlComponent = {\n    class_name: \"Form\",\n    container: {\n        type: \"HtmlComponent\",\n        properties: {\n            html: '<center style=\"font-style:italic; color:#888; margin: 3em;\">\\n  (Edit this HTML in the HTML pane)\\n</center>\\n<anvil-dropzone name=\"default\"></anvil-dropzone>',\n        },\n    },\n    components: [],\n    code: defaultStandardFormCode,\n    is_package: true,\n} as const;\n\nexport const recordActivity =\n    (type: string, data?: any): AnvilAction =>\n    (dispatch, getState) => {\n        const state = getState();\n        const appId = getAppId(state);\n        const isPySpace = getIsPySpace(state);\n\n        // N.B. No await. No need to wait for this to return. Fire and forget.\n        void api.recordActivity(appId, type, data, isPySpace);\n    };\n\n// polyfill for when window.crypto.randomUUID is not supported\nfunction _generateUUID() {\n    let d = Date.now();\n    const uuid = \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n        const r = ((d + Math.random() * 16) % 16) | 0;\n        d = Math.floor(d / 16);\n        return (c === \"x\" ? r : (r & 0x3) | 0x8).toString(16);\n    });\n    return uuid;\n}\n\nexport const generateUUID = window.crypto.randomUUID ? () => window.crypto.randomUUID() : _generateUUID;\n\nexport const getEditorType = (state: State) => state.editorType;\nexport const getIsPySpace = (state: State) => getEditorType(state) === \"pyspace\";\nexport const getIsIde = (state: State) => getEditorType(state) === \"ide\";\n\nexport const withoutLoadingIndicator =\n    <T>(body: () => Promise<T>): AnvilAsyncAction<T> =>\n    async (dispatch, getState, updateState) => {\n        const state = getState();\n        const currentLoadingIndicator = getLoadingIndicator(state);\n        if (currentLoadingIndicator) {\n            dispatch(updateGlobalLoadingIndicator(false));\n        }\n        try {\n            return await body();\n        } finally {\n            dispatch(updateGlobalLoadingIndicator(currentLoadingIndicator));\n        }\n    };\n","import type { State } from \"@/types\";\nimport { WHERE_TO_START_QUESTION_ID, WHERE_TO_START_SURVEY_ID, WhereToStartOptionId } from \"@/util/userSurveys\";\n\n/**\n * Tutorials we advertise (start page CTA + default-open bottom panel tab) based on the user's\n * answer to the where-to-start survey. The survey also saves the answer in this uiPref, which\n * takes precedence over the answer in the user's survey responses.\n */\nexport const WHERE_TO_START_ANSWER_PREF = \"2026-09-where-to-start-answer\";\n\n/** Users who signed up before this answered an older version of the survey, so don't get the tutorials. */\nconst WHERE_TO_START_TUTORIALS_SIGNUP_CUTOFF = new Date(\"2026-09-27T21:51:00Z\");\n\nconst getUserSignedUpAfterCutoff = (state: State) => {\n    const registrationDate = state.user?.registrationDate;\n    return !!registrationDate && new Date(registrationDate) > WHERE_TO_START_TUTORIALS_SIGNUP_CUTOFF;\n};\n\nexport type WhereToStartTutorial = \"guisAreDifferent\" | \"scriptsTutorial\";\n\nconst TUTORIAL_FOR_ANSWER: Partial<Record<WhereToStartOptionId, WhereToStartTutorial>> = {\n    \"learn-build-web-uis\": \"guisAreDifferent\",\n    \"python-script-or-notebook\": \"scriptsTutorial\",\n};\n\nexport const WHERE_TO_START_TUTORIAL_TAB_TITLES: Record<WhereToStartTutorial, string> = {\n    guisAreDifferent: \"Intro to GUI programming\",\n    scriptsTutorial: \"UIs for scripts\", // TODO: Placeholder copy\n};\n\nconst getSurveyAnswer = (state: State) => {\n    const answers = state.user?.surveyResponses?.[WHERE_TO_START_SURVEY_ID]?.answers;\n    return (answers?.[WHERE_TO_START_QUESTION_ID] as { answer?: string } | undefined)?.answer;\n};\n\n/**\n * `localStorage[\"2026-09-where-to-start-answer\"]` overrides the user's answer (and the signup cutoff),\n * for testing.\n */\nexport const getWhereToStartTutorial = (state: State): WhereToStartTutorial | null => {\n    const override = window.localStorage[WHERE_TO_START_ANSWER_PREF];\n    if (!override && !getUserSignedUpAfterCutoff(state)) return null;\n    const answer = override || state.user?.uiPrefs?.[WHERE_TO_START_ANSWER_PREF] || getSurveyAnswer(state);\n    return TUTORIAL_FOR_ANSWER[answer as WhereToStartOptionId] ?? null;\n};\n\n/** The tutorial's bottom panel tab, unless the user has closed it. */\nexport const getWhereToStartTutorialTab = (state: State): WhereToStartTutorial | null =>\n    state.user?.uiPrefs?.userHasDismissedOnboardingCtaTab ? null : getWhereToStartTutorial(state);\n","import {AppNavTarget} from \"@/router/navTypes.ts\";\n\nexport interface AppTemplate {\n    name: string;\n    description?: string;\n    img?: string;\n    cloneKey?: string;\n    id?: string;\n    url?: string;\n    tableau?: boolean;\n    initialNavTarget?: AppNavTarget;\n}\n\nexport const exampleApps: AppTemplate[] = [\n    {\n        name: \"Dashboard\",\n        description: \"A simple dashboard with some Plotly data visualisations\",\n        img: \"/ide/img/app_templates/dashboard-a-thumbnail.png\",\n        cloneKey: \"2D2MDIH3H5JCWNS6=AXESLFLUDCQVHKFRH3SMNMUY\",\n        id: \"dashboard-a\",\n    },\n    {\n        name: \"Database-backed App\",\n        description: \"An app that displays entries from a database\",\n        img: \"/ide/img/app_templates/database-backed-app-thumbnail.png\",\n        cloneKey: \"FOYKAEQ2AOYWXN63=HIXAKD6HRZ3ED5CBUF732IK7\",\n        id: \"task-manager\",\n    },\n    {\n        name: \"Dashboard 2\",\n        description: \"Another dashboard with some Plotly data visualisations\",\n        img: \"/ide/img/app_templates/dashboard-b-thumbnail.png\",\n        cloneKey: \"DGDRIG5VDFHQ3ZB6=5DFFNYFCG7RBDXA5QYCDOMDO\",\n        id: \"dashboard-b\",\n    },\n\n    // {\n    //     name: \"Task Manager\",\n    //     description: \"A task management tool with editable tables\",\n    //     img: \"/ide/img/app_templates/task-manager-thumb.png\",\n    //     cloneKey: \"FDI7MLH6ZBWWRJ6R=MPXTVBDGKJEYYCZ363Q5NKDM\",\n    //     id: \"task-manager\",\n    // },\n    // {\n    //     name: \"Static Website\",\n    //     description: \"A simple website with landing, contact-us and about-us pages\",\n    //     img: \"/ide/img/app_templates/simple-website-new-ide-thumb.png\",\n    //     cloneKey: \"XK7PRCIVVPDPD725=KSE3XXUIPIWK7GBVR5KSUKBU\",\n    //     id: \"static-website\",\n    // },\n    // {\n    //     name: \"Online Shop\",\n    //     description: \"An e-commerce shop integrating Stripe transactions\",\n    //     img: \"/ide/img/app_templates/shop-new-ide-thumb.png\",\n    //     cloneKey: \"SYHHBAIJKDSXOWE2=MFCNC7A4KANXBHP7EK7G357W\",\n    //     id: \"online-shop\",\n    // },\n    // {\n    //     name: \"Invoice Generator\",\n    //     description: \"An online shop that allows you to generate PDF invoices\",\n    //     img: \"/ide/img/app_templates/plantly-new-ide-thumb.png\",\n    //     cloneKey: \"AYDQD7WKV6M74HCK=J6PTV5JR4XX4AYBZAD37ROKK\"\n    // },\n    {\n        name: \"Survey Form\",\n        description: \"A basic webform with a generated report\",\n        img: \"/ide/img/app_templates/webform-new-ide-thumb.png\",\n        cloneKey: \"C7BRD3RXM4RKL6AQ=GENUE6E2VRQV5KYUKFYYCZFH%7cOHWC42ZUNUZNJNLA=MHE3T7NKUNT5R3P32LN5V4B2\",\n        id: \"survey-form\",\n    },\n    {\n        name: \"SaaS Template\",\n        description: \"A solid starting point for your SaaS product.\",\n        img: \"/ide/img/app_templates/saas-template-thumb.png\",\n        cloneKey: \"SUTICB6NGVZM7J5S=CB3DXR7V65FYL6UQOF2VQF5L\",\n        id: \"saas-template\",\n    },\n    {\n        name: \"Expense Approval System\",\n        description: \"An internal tool for submitting and approving expenses\",\n        img: \"/ide/img/app_templates/expense-approval-thumb.png\",\n        cloneKey: \"ODKPA5XG5ZBEYSLZ%3dT6QRGCPIIRYAZ5FKKXALBEQI\",\n        id: \"expense-approval\",\n    },\n    // {\n    //     name: \"Booking Manager\",\n    //     description: \"An app for managing and booking appointments\",\n    //     img: \"/ide/img/app_templates/booking-new-ide-thumb.png\",\n    //     cloneKey: \"OIO5ASGNADOALQ4U%3dF6O6Q7TWRS7ES6HJSWBVTLMW\",\n    //     id: \"booking-manager\",\n    // },\n    // {\n    //     name: \"Support Tickets\",\n    //     description: \"A customer support management tool\",\n    //     img: \"/ide/img/app_templates/ticketing-new-ide-thumb.png\",\n    //     cloneKey: \"EHISYUAFWUDH6O7N=JNJGD5KF5Q4QJQPHU2TWAQFM\"\n    // },\n    // {\n    //     name: \"News Aggregator\",\n    //     description: \"A simple CRUD app for displaying news articles\",\n    //     img: \"/ide/img/app_templates/news-aggregator-thumb.png\",\n    //     cloneKey: \"CMKH4FP2BWACSTCQ%3d556VNNKQ5JM7WCFUVFH5EXEF\",\n    //     id: \"news-aggregator\",\n    // },\n\n    {\n        name: \"Tableau Chat Extension\",\n        description: \"A Tableau extension to add comments to sales data\",\n        img: \"/img/anvil-x/tableau-chat-extension.png\",\n        cloneKey: \"VC4C34V4TID2L65N=N6FGLLP6QXFWX4PHJW3UGUDF\",\n        id: \"tableau-chat\",\n        tableau: true,\n    },\n    {\n        name: \"Value Override Extension\",\n        description: \"Change values of data points directly from your Tableau dashboard\",\n        img: \"/img/home/gallery/override-tableau-gallery.png\",\n        cloneKey: \"NR64GCNUQ4HWTUG5=QVKZBRW7XYQPFBYHKF4Q3FNU\",\n        id: \"tableau-value-override\",\n        tableau: true,\n    },\n\n    // {\n    //     name: \"Feedback Form\",\n    //     img: \"/ide/img/app_templates/feedback_form.png\",\n    //     // Using a clone key for an app that exists to test cloning\n    //     cloneKey: \"XHRKE3AKQ5J4IQL7=PWPI2FY75QYAAZZ5EQC3OFI7\",\n    //     // cloneKey: \"5QJDEMJLQY4CO443=B5LSZ23F46BQHHIQYGXNBP6T\",\n    //     description: \"Collect form entries, store them in a database, and send them by email.\",\n    // },\n    // {\n    //     name: \"Data Dashboard\",\n    //     img: \"/ide/img/app_templates/dashboard.png\",\n    //     cloneKey: \"MNIPHFOW6RHYNBAZ=4TCY3OGYYLXWZWFTWLJO6IVU\",\n    //     description: \"Fetch and plot data from databases, APIs, and more.\",\n    // },\n    // // This one is still referred to by the drip campaign;\n    // // TODO: I don't think this is still the case\n    // // TODO find another way of keeping that email link live.\n    // {\n    //     name: \"To-Do List\",\n    //     url: \"ide/app_templates/todo_list\",\n    //     img: \"ide/img/app_templates/todo_list.png\",\n    //     description: \"Uses data tables to store To-Do reminders.\",\n    //     hidden:true\n    // },\n];\n","import { byPrefixAndName } from \"@awesome.me/kit-5370d71ccb/icons\";\n\nexport const faAnvilLogoSolidAlt = byPrefixAndName.fak[\"logo-solid-alt\"];\nexport const faAnvilLogoSolid = byPrefixAndName.fak[\"logo-solid\"];\nexport const faAnvilLogoOutline = byPrefixAndName.fak[\"logo-outline\"];\nexport const faAnvilLogoDuotone = byPrefixAndName.fak[\"logo-duotone\"];\n","import React, { useEffect, useMemo } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faLock, faRocket, faTrashAlt } from \"@fortawesome/pro-regular-svg-icons\";\nimport { faMinus, faPlus, faSort } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { Button } from \"@/components/reusable/Button\";\nimport { LoadingSpinner } from \"@/components/reusable/LoadingSpinner\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport UpgradeBadge from \"@/components/reusable/UpgradeBadge\";\nimport { updateGlobalLoadingIndicator } from \"@/controllers/app\";\nimport { getSubscription } from \"@/controllers/ide\";\nimport { alert, confirm, modal, prompt } from \"@/controllers/modals\";\nimport { startUpgrade } from \"@/controllers/payment\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useFeatureSupported } from \"@/util/features\";\nimport { useDeveloperQuery } from \"@/util/hooks/use-developer-query.ts\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { getPendingInvitations, inviteDeveloper, revokeDeveloperInvite } from \"@manager/api.ts\";\nimport { getCurrentOrganisationLicenceKey } from \"../controller\";\nimport { UserRow, useStyles } from \"./Manager\";\n\nconst emailsMatch = (left?: string, right?: string) =>\n    Boolean(left && right && left.toLowerCase() === right.toLowerCase());\n\ninterface PendingInvitation {\n    email: string;\n    timestamp: string;\n}\n\nconst Developer = ({ user = null }: { user: any }) => {\n    const { classes } = useStyles();\n    const dispatch = useDispatch<AnvilDispatch>();\n\n    const { developers, handleRemoveDeveloper, handleAssignMyUser, isAssigningMyUser } = useDeveloperQuery();\n    const subscription = useSelector(getSubscription);\n    const licenceKey = useSelector(getCurrentOrganisationLicenceKey);\n    const queryClient = useQueryClient();\n\n    const { data: pendingInvitations, isLoading: isLoadingInvitations } = useQuery({\n        queryKey: [\"pending-invitations\", licenceKey],\n        queryFn: () => getPendingInvitations(licenceKey),\n        enabled: !!licenceKey,\n        staleTime: 0,\n    });\n\n    // Mutation for revoking invitations with optimistic updates\n    const revokeInvitationMutation = useMutation({\n        mutationFn: async (email: string) => {\n            return revokeDeveloperInvite(licenceKey, email);\n        },\n        onMutate: async (email: string) => {\n            await queryClient.cancelQueries({ queryKey: [\"pending-invitations\", licenceKey] });\n\n            const previousInvitations = queryClient.getQueryData<PendingInvitation[]>([\n                \"pending-invitations\",\n                licenceKey,\n            ]);\n\n            // Optimistically update UI\n            queryClient.setQueryData([\"pending-invitations\", licenceKey], (old: PendingInvitation[]) =>\n                old?.filter((invite) => invite.email !== email)\n            );\n\n            return { previousInvitations, email };\n        },\n        onError: (_err, _email, context) => {\n            // Rollback if revoke failed\n            if (context?.previousInvitations) {\n                queryClient.setQueryData([\"pending-invitations\", licenceKey], context.previousInvitations);\n            }\n            dispatch(\n                alert(\n                    \"Unable to revoke invite\",\n                    `Could not revoke invitation for ${context?.email}. Please try again or contact support@anvil.works`\n                )\n            );\n        },\n        onSettled: () => {\n            queryClient.invalidateQueries({ queryKey: [\"pending-invitations\", licenceKey] });\n        },\n    });\n\n    const handleRevokeInvitation = async (email: string) => {\n        const revoke = await dispatch(\n            confirm(\n                \"Revoke Invitation\",\n                `You are about to revoke the invitation to ${email} to join this organisation. The previously sent invitation will become invalid.`,\n                \"Revoke\",\n                \"Cancel\"\n            )\n        );\n        if (revoke) {\n            revokeInvitationMutation.mutate(email);\n        }\n    };\n\n    // Mutation for inviting developers\n    const inviteDeveloperMutation = useMutation({\n        mutationFn: async (email: string) => {\n            dispatch(updateGlobalLoadingIndicator(true));\n            return inviteDeveloper(licenceKey, email);\n        },\n        onSuccess: (data, email) => {\n            dispatch(updateGlobalLoadingIndicator(false));\n            dispatch(alert(\"Invite Sent\", `An email containing an invite link has been sent to ${email}.`));\n            queryClient.invalidateQueries({ queryKey: [\"pending-invitations\", licenceKey] });\n        },\n        onError: () => {\n            dispatch(updateGlobalLoadingIndicator(false));\n            dispatch(alert(\"Unable to send invite\", \"Something's gone wrong!\"));\n        },\n    });\n\n    const handleInviteDeveloper = async () => {\n        const email = await dispatch(\n            prompt(\n                \"Invite user\",\n                \"Enter the email of the user you'd like to invite to join your organisation. An email invite will be sent to them.\",\n                \"\",\n                \"Invite\"\n            )\n        );\n        if (email) {\n            if (email.match(/.+@.+\\..+/)) {\n                inviteDeveloperMutation.mutate(email);\n            } else {\n                dispatch(alert(\"Error\", `${email} is an invalid email`));\n            }\n        }\n    };\n\n    const loading = subscription === undefined || user === undefined; // is this right?\n    const supportsCollaboration = useFeatureSupported(\"collaboration\");\n    const isNonManagerDev = subscription?.isManager === false; // Will be undefined for a free user\n\n    const totalSeats = subscription?.totalDevCount ?? 1;\n    const usedSeats = developers?.length ?? 1;\n    const pendingInvites = pendingInvitations?.length ?? 0;\n\n    const canInvite = totalSeats > usedSeats + pendingInvites;\n\n    const hasIdeUser = !!user?.hasIdeUser;\n    const managerAlreadyAssigned =\n        developers?.some((developer: any) => emailsMatch(developer.email, user?.email)) ?? false;\n    const canAssignMyUser = hasIdeUser && !managerAlreadyAssigned && canInvite;\n\n    const onAddSeats = useEvent(async () => {\n        if (supportsCollaboration) {\n            return handleInviteDeveloper();\n        } else {\n            return await dispatch(modal(\"upgradePrompt\", { featureId: \"collaboration\" }));\n        }\n    });\n\n    const addSeatsButton = useMemo(() => {\n        if (subscription?.plan) {\n            if (supportsCollaboration && subscription?.planUpdateCapability?.canChangeSeatCount) {\n                return (\n                    <Button\n                        disabled={subscription?.cancelled}\n                        icon={faSort}\n                        variant={\"primary\"}\n                        onClick={() =>\n                            dispatch(\n                                startUpgrade(false, false, false, {\n                                    initialPlan: subscription?.plan,\n                                    initialFreq: subscription?.recurringInterval,\n                                })\n                            )\n                        }\n                        title={\n                            subscription?.cancelled ? \"Cancellation in progress. Please email contact@anvil.works\" : \"\"\n                        }\n                        titlePosition={\"left\"}>\n                        Add or Remove Seats\n                    </Button>\n                );\n            } else if (subscription?.trial) {\n                return (\n                    <Button icon={faRocket} variant={\"primary\"} onClick={() => dispatch(startUpgrade(false, true))}>\n                        Upgrade to add Seats\n                    </Button>\n                );\n            }\n        }\n    }, [subscription, supportsCollaboration]);\n\n    if (loading) {\n        return <LoadingSpinner />;\n    }\n\n    return (\n        <>\n            <Heading level={1}>Developers</Heading>\n            {isNonManagerDev ? (\n                <Text level={2}>Only account managers can view and update developers of an account.</Text>\n            ) : (\n                <>\n                    <Text level={2}>The following Anvil users are developers on this account:</Text>\n                    <div className=\"flex flex-col\">\n                        {!developers ? (\n                            <UserRow // We don't have developers, therefore we're on a free plan\n                                key={0}\n                                name={user?.name}\n                                email={user?.email}\n                                isAdmin={true}\n                                icon={faLock}\n                                variant={\"highlight3\"}\n                                remove={null}\n                            />\n                        ) : usedSeats > 0 ? (\n                            developers?.map((developer: any, idx: number) => (\n                                <UserRow\n                                    key={idx}\n                                    name={developer.name}\n                                    email={developer.email}\n                                    isAdmin={emailsMatch(subscription.email, developer.email)}\n                                    icon={!emailsMatch(developer.email, user?.email) ? faTrashAlt : faLock}\n                                    variant={!emailsMatch(developer.email, user?.email) ? \"danger\" : \"highlight3\"}\n                                    remove={\n                                        !emailsMatch(developer.email, user?.email)\n                                            ? () => handleRemoveDeveloper(developer.email)\n                                            : null\n                                    }\n                                    tooltipText={\n                                        !emailsMatch(developer.email, user?.email)\n                                            ? \"Remove Developer from this plan\"\n                                            : \"To remove your own developer access go to the Account Manager\"\n                                    }\n                                />\n                            ))\n                        ) : (\n                            <Text level={2}>No Developers</Text>\n                        )}\n                        {isAssigningMyUser ? (\n                            <div className={classes.userRow}>\n                                <LoadingSpinner inline sizeRem={1.6} />\n                                <span className={\"ml-2\"}>Assigning your user...</span>\n                            </div>\n                        ) : (\n                            canAssignMyUser && (\n                                <div className={cx(\"cursor-pointer\", classes.userRow)} onClick={handleAssignMyUser}>\n                                    <FontAwesomeIcon className={\"mr-2\"} fixedWidth icon={faPlus} />\n                                    Assign your user to this account\n                                </div>\n                            )\n                        )}\n                        {(canInvite || !supportsCollaboration) && (\n                            <div className={cx(\"cursor-pointer\", classes.userRow)} onClick={onAddSeats}>\n                                <FontAwesomeIcon className={\"mr-2\"} fixedWidth icon={faPlus} />\n                                Invite a user to join this account\n                                <UpgradeBadge feature={\"collaboration\"} />\n                            </div>\n                        )}\n                    </div>\n                    {subscription?.plan && (\n                        <>\n                            <div className=\"flex w-11/12 flex-col\">\n                                {pendingInvitations && pendingInvitations.length > 0 && (\n                                    <>\n                                        <Heading level={3}>Pending Invitations ({pendingInvites})</Heading>\n                                        {pendingInvitations?.map((invite: any, idx: number) => (\n                                            <UserRow\n                                                key={idx}\n                                                email={invite.email}\n                                                remove={handleRevokeInvitation}\n                                                tooltipText={\"Revoke Invitation\"}\n                                                icon={faMinus}\n                                            />\n                                        ))}\n                                    </>\n                                )}\n                            </div>\n\n                            <Heading level={1}>Developer Seats</Heading>\n                            {/*todo: make pretty and clear. reorder. take some out. organise better*/}\n                            <div className={\"mb-12 grid max-w-2xl grid-cols-4\"}>\n                                <div className={\"col-span-3\"}>Occupied Seats</div>\n                                <div>{usedSeats}</div>\n                                {supportsCollaboration ? (\n                                    <>\n                                        <div className={\"col-span-3\"}>Pending Invites</div>\n                                        <div>{pendingInvites}</div>\n                                        <div className={\"col-span-3\"}>Number of developer seats</div>\n                                        <div>{totalSeats}</div>\n                                    </>\n                                ) : (\n                                    <>\n                                        <div className={\"col-span-3\"}>Number of developer seats</div>\n                                        <div>{totalSeats}</div>\n                                    </>\n                                )}\n                            </div>\n                        </>\n                    )}\n                    {addSeatsButton}\n                </>\n            )}\n        </>\n    );\n};\n\nexport default Developer;\n","import React from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { faLock, faTrashAlt } from \"@fortawesome/pro-light-svg-icons\";\nimport { faPlus } from \"@fortawesome/pro-solid-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport Link from \"@/components/reusable/Link\";\nimport { Heading, Text } from \"@/components/reusable/Text\";\nimport UpgradeBadge from \"@/components/reusable/UpgradeBadge\";\nimport { getIsIDE, getSubscription } from \"@/controllers/ide\";\nimport { modal } from \"@/controllers/modals\";\nimport { cx } from \"@/theme/styles\";\nimport { AnvilDispatch } from \"@/types\";\nimport { useFeatureSupported } from \"@/util/features\";\nimport useEvent from \"@/util/useEventCallback\";\nimport { addManager, getManagerUser, removeManager } from \"../controller\";\nimport { UserRow, useStyles } from \"./Manager\";\n\nconst Managers = () => {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const user = useSelector(getManagerUser);\n    const subscription = useSelector(getSubscription);\n\n    const { classes } = useStyles();\n    const inIde = useSelector(getIsIDE);\n    const supported = useFeatureSupported(\"account-management\");\n\n    const isNonManagerDev = subscription?.isManager === false;\n\n    const onAddManager = useEvent(async () => {\n        // Allow switching it off if your subscription doesn't support it.\n        if (supported) {\n            return await dispatch(addManager());\n        } else {\n            return await dispatch(modal(\"upgradePrompt\", { featureId: \"account-management\" }));\n        }\n    });\n\n    return (\n        <>\n            <Heading level={1}>Managers</Heading>\n            <Text level={2}>\n                The following people can log into{\" \"}\n                {inIde ? (\n                    <Link\n                        target={\"_blank\"}\n                        to={\n                            isNonManagerDev\n                                ? \"/docs/overview/account-management#account-management-for-business-plans-and-above\"\n                                : \"/manage\"\n                        }\n                        style={{ textDecorationLine: \"underline\" }}>\n                        Anvil's Account Manager\n                    </Link>\n                ) : (\n                    <>Anvil's Account Manager</>\n                )}{\" \"}\n                to manage this account:\n            </Text>\n\n            {subscription?.managers?.map((email: any, idx: number) => {\n                const isAdmin = subscription.email === email;\n                const isCurrentUser = user.email === email;\n                const unRemovable = isAdmin || isCurrentUser;\n                return (\n                    <UserRow\n                        key={idx}\n                        email={email}\n                        isAdmin={isAdmin}\n                        icon={isNonManagerDev ? null : unRemovable ? faLock : faTrashAlt}\n                        variant={unRemovable ? \"highlight3\" : \"danger\"}\n                        remove={isNonManagerDev || unRemovable ? null : removeManager}\n                        tooltipText={\n                            isNonManagerDev\n                                ? \"\"\n                                : isAdmin\n                                  ? \"Contact support@anvil.works to change the subscription administrator.\"\n                                  : isCurrentUser\n                                    ? \"You cannot remove your own manager access.\"\n                                    : \"Remove Manager from this plan\"\n                        }\n                    />\n                );\n            })}\n\n            {subscription?.isManager && (\n                <div className={cx(\"cursor-pointer\", classes.userRow)} onClick={onAddManager}>\n                    <FontAwesomeIcon className={\"mr-2\"} fixedWidth icon={faPlus} />\n                    Add a manager to this account\n                    <UpgradeBadge feature={\"account-management\"} />\n                </div>\n            )}\n        </>\n    );\n};\n\nexport default Managers;\n","import React from \"react\";\nimport { cx } from \"@/theme/styles\";\n\nconst tabs = [\n    { title: \"Subscription\", value: \"subscription\" },\n    { title: \"Quotas\", value: \"quotas\" },\n    { title: \"Billing\", value: \"billing\" },\n    { title: \"Apps\", value: \"apps\" },\n    { title: \"Developers\", value: \"developers\" },\n    { title: \"Managers\", value: \"managers\" },\n    { title: \"Anvil X\", value: \"tableau\" },\n] as const;\n\nexport type TabType = (typeof tabs)[number][\"value\"];\n\ninterface NavBarProps {\n    currentTab: TabType;\n    setCurrentTab: React.Dispatch<React.SetStateAction<TabType>>;\n    enableAccounting?: boolean;\n}\n\nconst NavItem = ({ tab, currentTab, setCurrentTab }: NavBarProps & { tab: (typeof tabs)[number] }) => (\n    <div\n        className={cx(\n            \"border-r border-b border-light-bg4 bg-light-bg5 px-6 py-2 hover:text-grey-2 dark:border-dark-sectionborder dark:bg-dark-bg2 hover:dark:text-grey-0\",\n            {\n                \"border-b-white bg-white text-grey-2 hover:cursor-auto dark:border-b-dark-sectionborder dark:bg-dark-bg6 dark:text-grey-0\":\n                    currentTab === tab.value,\n                \"hover:cursor-pointer\": currentTab !== tab.value,\n            }\n        )}\n        onClick={() => setCurrentTab(tab.value)}>\n        {tab.title}\n    </div>\n);\n\nconst tabsWithoutQuotas = tabs.filter((t) => t.value !== \"quotas\");\n\nconst NavBar = ({ enableAccounting, ...props }: NavBarProps) => {\n    const visibleTabs = enableAccounting ? tabs : tabsWithoutQuotas;\n\n    return (\n        <div className=\"flex bg-light-bg1 font-medium text-light-bg6 dark:bg-dark-bg1\">\n            <div className=\"w-4 border-r border-b border-light-bg4 dark:border-dark-sectionborder\" />\n            {visibleTabs.map((tab) => (\n                <NavItem key={tab.value} tab={tab} {...props} />\n            ))}\n            <div className=\"shrink-0 grow border-b border-light-bg4 dark:border-dark-sectionborder\" />\n        </div>\n    );\n};\n\nexport default NavBar;\n","import React from \"react\";\nimport { useSelector } from \"react-redux\";\nimport Subscription from \"@/components/modals/account/Subscription\";\nimport { getSubscription } from \"@/controllers/ide\";\n\nconst OrgSummary = () => {\n    const subscription = useSelector(getSubscription);\n    return subscription && <Subscription subscription={subscription} isManagerPortal />;\n};\n\nexport default OrgSummary;\n","import React, { useMemo, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport Billing from \"@/components/modals/account/Billing\";\nimport { OrgApps } from \"@/components/modals/account/OrgApps\";\nimport { Quotas } from \"../../components/modals/account/Quotas\";\nimport { getManagerUser, getOrgQuota } from \"../controller\";\nimport Developers from \"./Developers\";\nimport { useStyles } from \"./Manager\";\nimport Managers from \"./Managers\";\nimport NavBar, { TabType } from \"./NavBar\";\nimport OrgSummary from \"./OrgSummary\";\nimport TableauUsers from \"./TableauUsers\";\nimport { cx } from \"@/theme/styles.ts\";\n\n\nexport const Organisation = () => {\n    const { classes } = useStyles();\n\n    const [currentTab, setCurrentTab] = useState<TabType>(\"subscription\");\n    const quotasAndLimits = useSelector(getOrgQuota);\n    const user = useSelector(getManagerUser);\n\n    const currentTabContent = () => {\n        switch (currentTab) {\n            case \"tableau\":\n                return <TableauUsers />;\n            case \"quotas\":\n                return <Quotas quotasAndLimits={quotasAndLimits} />;\n            case \"developers\":\n                return <Developers user={user} />;\n            case \"managers\":\n                return <Managers />;\n            case \"billing\":\n                return <Billing />;\n            case \"apps\":\n                return <OrgApps />;\n            default:\n                return <OrgSummary />;\n        }\n    };\n\n\n    return (\n        <>\n            <NavBar currentTab={currentTab} setCurrentTab={setCurrentTab} enableAccounting={user?.ideConfig?.enableAccounting} />\n            <div className={cx(classes.content, \"@container\")}>{currentTabContent()}</div>\n        </>\n    );\n};\n","import React, { useMemo } from \"react\";\nimport { connect } from \"react-redux\";\nimport { faPencil, faTrashAlt } from \"@fortawesome/pro-solid-svg-icons\";\nimport { getSubscription } from \"@/controllers/ide\";\nimport { Button } from \"../../components/reusable/Button\";\nimport { Heading, Text } from \"../../components/reusable/Text\";\nimport type { AnvilConnectedProps } from \"../../types\";\nimport { getTableauInfo, onUpdateTableauLicences, removeTableauUser } from \"../controller\";\nimport { UserRow } from \"./Manager\";\n\nconst TableauUsers = ({ licence, users, subscription, dispatch }: AnvilConnectedProps<typeof connector>) => {\n    const [usedLicences, totalLicences] = useMemo(() => {\n        return [users?.length || 0, (licence?.n_users || 0) + 10];\n    }, [licence, users]);\n\n    const unusedLicences: number = useMemo(() => totalLicences - usedLicences || 0, [totalLicences, usedLicences]);\n\n    if (!subscription?.isManager) {\n        // TODO: Really, we should show number of licences used/available, but we don't yet have that data easily available if you're not a manager.\n        return null;\n    }\n\n    return (\n        <>\n            <div>\n                <Heading level={2}>\n                    You have {unusedLicences} of {totalLicences} Tableau Viewers available\n                </Heading>\n                <div className={\"mt-12 flex items-center justify-center\"}>\n                    {users?.length > 0 ? (\n                        <div className=\"flex w-11/12 flex-col\">\n                            {users?.map(({ email }: any, idx: number) => (\n                                <UserRow\n                                    key={idx}\n                                    email={email}\n                                    icon={faTrashAlt}\n                                    remove={removeTableauUser}\n                                    tooltipText={\"Remove User from this licence\"}\n                                />\n                            ))}\n                        </div>\n                    ) : (\n                        <Text level={3}>No users</Text>\n                    )}\n                </div>\n            </div>\n            {subscription?.planUpdateCapability?.canAddTableauSeats && (\n                <div className={\"mt-4 flex flex-wrap\"}>\n                    <Button variant={\"primary\"} icon={faPencil} onClick={() => dispatch(onUpdateTableauLicences())}>\n                        Update Anvil X Licence\n                    </Button>\n                </div>\n            )}\n        </>\n    );\n};\n\nconst connector = connect((state: any) => ({\n    ...getTableauInfo(state),\n    subscription: getSubscription(state),\n}));\n\nexport default connector(TableauUsers);\n","/** Let the mobile layout fill the screen; its controls account for safe-area insets. */\nexport function enableMobileViewport() {\n    const existing = [...document.querySelectorAll<HTMLMetaElement>('meta[name=\"viewport\"]')];\n    const viewport = existing[0] ?? document.createElement(\"meta\");\n    const previousContent = viewport.getAttribute(\"content\");\n    existing.slice(1).forEach((duplicate) => duplicate.remove());\n    viewport.name = \"viewport\";\n    viewport.content = \"width=device-width, initial-scale=1, viewport-fit=cover\";\n    document.head.append(viewport);\n\n    return () => {\n        if (!existing.length) viewport.remove();\n        else if (previousContent === null) viewport.removeAttribute(\"content\");\n        else viewport.content = previousContent;\n    };\n}\n","import React, { useEffect, useState } from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport { faBell } from \"@fortawesome/pro-light-svg-icons/faBell\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { LinkInternal } from \"@/components/reusable/LinkInternal\";\nimport { modal } from \"@/controllers/modals\";\nimport { Notification } from \"@/pyspace/common/types\";\nimport * as pySpaceApi from \"@/pyspace/pyspace-api\";\nimport { SiteDispatch } from \"@/pyspace/site/store/pyspace-site-store\";\nimport { cx } from \"@/theme/styles\";\n\nexport const NotificationsButton = ({\n    newNotifications,\n    className,\n}: {\n    className?: string;\n    newNotifications: Notification[];\n}) => {\n    const [seenNotifications, setSeenNotifications] = useState(false);\n    const pendingNotifications = !!newNotifications.length && !seenNotifications;\n    const openedNotifications = () => {\n        if (!seenNotifications) {\n            setSeenNotifications(true);\n            if (newNotifications.length) {\n                pySpaceApi.markNotificationsRead(newNotifications[0].time);\n            }\n        }\n    };\n    const dispatch = useDispatch<SiteDispatch>();\n\n    // The below is a massive hack which will be replaced with proper routing\n    useEffect(() => {\n        if (window.location.hash === \"#notifications\") {\n            void dispatch(modal(\"notifications\", { newNotifications: newNotifications }));\n        }\n    }, []);\n\n    return (\n        <LinkInternal\n            className={cx(\n                \"relative mt-[-4px] flex items-center justify-center px-3.5 text-center text-[1.6rem]\",\n                \"hover:border-primary-700 hover:text-primary-700\",\n                \"active:border-primary active:text-primary\",\n                className\n            )}\n            onClick={() => {\n                openedNotifications();\n                dispatch(modal(\"notifications\", { newNotifications: newNotifications }));\n            }}>\n            <FontAwesomeIcon className={\"h-[24px]\"} fixedWidth icon={faBell} />\n            {pendingNotifications && (\n                <div className={\"absolute top-0 right-[8px] aspect-square w-3.5 rounded-full bg-tertiary\"} />\n            )}\n        </LinkInternal>\n    );\n};\n","import React, { useCallback, useRef, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { ModalComponent } from \"@/components/modals\";\nimport Modal from \"@/components/modals/Modal\";\nimport { ModalRef } from \"@/components/modals/Modal\";\nimport { getAppName } from \"@/controllers/app\";\nimport { modalReturn } from \"@/controllers/modals\";\nimport PySpaceTextInput from \"@/pyspace/common/components/TextInput\";\n\nconst DeleteGadgetModal: ModalComponent = ({ modalId, spec: { appName } }) => {\n    const app = useSelector(getAppName);\n    const name = appName || app;\n    const modalRef = useRef<ModalRef>(null);\n\n    const [input, setInput] = useState(\"\");\n    const enabled = name === input;\n\n    const inputRef = useCallback((node: HTMLInputElement | null) => {\n        node?.focus();\n    }, []);\n\n    return (\n        <Modal\n            size={\"small\"}\n            autoFocus={false}\n            title={`Delete ${name}?`}\n            modalId={modalId}\n            ref={modalRef}\n            buttons={[\n                {\n                    text: \"Delete\",\n                    clickActionCreator: () => modalReturn(true),\n                    round: true,\n                    variant: \"danger\",\n                    enabled,\n                },\n                { text: \"Cancel\", clickActionCreator: () => modalReturn(false), round: true, variant: \"highlight3\" },\n            ]}>\n            <div className={\"flex flex-col gap-[1.6rem] text-[1.4rem] select-none\"}>\n                <div>\n                    This action cannot be undone. This will permanently delete the{\" \"}\n                    <span className={\"font-mono font-semibold text-primary select-text\"}>{name}</span> app.\n                </div>\n                <div>\n                    Please type <span className={\"font-mono font-semibold text-primary select-text\"}>{name}</span> to\n                    confirm.\n                </div>\n                <PySpaceTextInput ref={inputRef} value={input} onChange={setInput} />\n                <div className={\"flex justify-start gap-[1.6rem] md:justify-end\"}>\n                    {/*<Button*/}\n                    {/*    disabled={!enabled}*/}\n                    {/*    elevated*/}\n                    {/*    round*/}\n                    {/*    variant={\"danger\"}*/}\n                    {/*    onClick={() => modalRef.current.returnValue(true)}>*/}\n                    {/*    Delete*/}\n                    {/*</Button>*/}\n                    {/*<Button elevated round variant={\"light\"} onClick={() => modalRef.current.returnValue(false)}>*/}\n                    {/*    Cancel*/}\n                    {/*</Button>*/}\n                </div>\n            </div>\n        </Modal>\n    );\n};\n\nexport default DeleteGadgetModal;\n","export const forceImageToSizeAndType = async (image: Blob, type: string, maxSize: number): Promise<Blob> => {\n    if (image.size <= maxSize && image.type === type) {\n        return image;\n    }\n\n    const blobUrl = URL.createObjectURL(image);\n    try {\n        const imgElt = await new Promise<HTMLImageElement>((resolve, reject) => {\n            const img = new Image();\n            img.onload = () => resolve(img);\n            img.onerror = reject;\n            img.src = blobUrl;\n        });\n        const canvas = document.createElement(\"canvas\");\n        const ctx = canvas.getContext(\"2d\")!;\n        const { naturalWidth: w, naturalHeight: h } = imgElt;\n\n        let scale = image.type === type ? 0.75 : 1;\n\n        // eslint-disable-next-line no-constant-condition\n        while (true) {\n            const newW = scale * w;\n            const newH = scale * h;\n\n            canvas.width = newW;\n            canvas.height = newH;\n\n            ctx.drawImage(imgElt, 0, 0, newW, newH);\n\n            const blob = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, type, 0.92));\n            if (!blob) {\n                throw new Error(\"Blob creation failed\");\n            }\n            if (blob.size <= maxSize) {\n                return blob;\n            } else {\n                scale *= 0.75;\n            }\n        }\n    } finally {\n        URL.revokeObjectURL(blobUrl);\n    }\n};\n","import { useMemo } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { getCategorisedEnvironments } from \"@/controllers/environments\";\n\nexport const useMasterEnvironmentOrigin = () => {\n    const environments = useSelector(getCategorisedEnvironments);\n    return useMemo(\n        () => environments.real.find((e) => e.version.ref === \"refs/heads/master\" && e.origin)?.origin,\n        [environments]\n    );\n};\n","import { DesignerScrollPosition, EditPath } from \"@designer/shared-types\";\nimport { ConversationPid } from \"@/agent/types\";\nimport { AppId, CodePath, CodeTabPrefs, FullView, View } from \"@/types\";\nimport { TableMappingId } from \"@/types/database\";\n\nexport interface BaseNavTarget {\n    temp?: boolean;\n    type?: string;\n}\n\ninterface RootNavTarget extends BaseNavTarget {\n    type: \"START_PAGE\"; // No app open.\n}\n\nexport type AuthHash = \"OAUTH\" | \"SSH\" | \"GH\" | \"AI\";\n\nexport type AccountNavTarget =\n    | (BaseNavTarget & {\n          type: \"ACCOUNT\";\n          section?:\n              | \"SUBSCRIPTION\"\n              | \"USERS\"\n              | \"LOOK-FEEL\"\n              | \"COMMUNICATIONS\"\n              | \"BILLING\"\n              | \"QUOTAS\"\n              | \"SCHEDULED-TASKS\";\n          backTo?: NavTarget;\n          hash?: undefined;\n      })\n    | (BaseNavTarget & {\n          type: \"ACCOUNT\";\n          section: \"AUTHENTICATION\";\n          backTo?: NavTarget;\n          hash?: AuthHash;\n      });\n\ninterface AcceptInviteTarget extends BaseNavTarget {\n    type: \"ACCEPT_INVITE\";\n    token: string;\n}\n\ninterface AppNavTargetBase extends BaseNavTarget {\n    appId?: AppId; // If not supplied, use the current app ID.\n}\n\ninterface AppRootNavTarget extends AppNavTargetBase {\n    type: \"APP_ROOT\";\n}\n\nexport interface CodeNavTarget extends AppNavTargetBase {\n    type: \"CODE\";\n    codePath: CodePath;\n    view?: FullView;\n    essentialView?: View; // Will be combined with 'view' from cache, but CodeTab can decide to fall back to this if screen too small.\n    focusView?: keyof View; // Which view type should receive focus when multiple views are active (deprecated, use view.focus)\n    refocusView?: number; // When the view.focus doesn't change, but we want to force the focus to the appropriate editor\n    topLevelFormClassName?: string; // required in conjunction with an edit path\n    editingPath?: EditPath;\n    designerScrollPosition?: DesignerScrollPosition; // Consumed when opening a nested designer in its parent context.\n    codeTabPrefs?: CodeTabPrefs;\n    preserveFocus?: boolean; // Current navigation only; not stored in tabs or cached views.\n}\n\nexport interface PythonSourceNavTarget extends AppNavTargetBase {\n    type: \"PYTHON_SOURCE\";\n    uri: string;\n    label: string;\n    view?: FullView;\n    refocusView?: number;\n}\n\nexport interface DBTableNavTarget extends AppNavTargetBase {\n    type: \"DB_TABLE\";\n    tableId: number;\n    tableMappingId: TableMappingId;\n}\n\nexport interface AppSchemaNavTarget extends AppNavTargetBase {\n    type: \"APP_SCHEMA\";\n    tableMappingId?: TableMappingId | \"debug\"; // undefined means app schema, null means default mapping\n}\n\nexport interface SettingsNavTarget extends AppNavTargetBase {\n    type: \"SETTINGS\";\n    section: \"ROOT\" | \"PERMISSIONS\" | \"DATATABLES\" | \"EMBEDDING\";\n}\n\ninterface HelpNavTarget extends AppNavTargetBase {\n    type: \"HELP\";\n}\n\nexport interface BackgroundTasksNavTarget extends AppNavTargetBase {\n    type: \"BACKGROUND_TASKS\";\n}\n\ninterface UsageNavTarget extends AppNavTargetBase {\n    type: \"CPU_USAGE\";\n}\n\ninterface MemoryUseNavTarget extends AppNavTargetBase {\n    type: \"MEMORY_USAGE\";\n}\n\nexport interface SessionsNavTarget extends AppNavTargetBase {\n    type: \"SESSIONS\";\n    expandSessionSha?: string;\n}\n\nexport interface SessionNavTarget extends AppNavTargetBase {\n    type: \"SESSION\";\n    sessionId: string;\n    displayMode: \"LOGS\" | \"TRACES\" | \"PROFILE\";\n}\n\nexport interface AppDependenciesNavTarget extends AppNavTargetBase {\n    type: \"APP_DEPENDENCIES\";\n}\n\nexport interface PythonDependenciesNavTarget extends AppNavTargetBase {\n    type: \"PYTHON_DEPENDENCIES\";\n}\n\nexport interface JavaScriptDependenciesNavTarget extends AppNavTargetBase {\n    type: \"JAVASCRIPT_DEPENDENCIES\";\n}\n\n// Browser history and recent tabs can contain targets saved before the standalone dependency routes.\nexport const dependencyTargetFromLegacyNavTarget = ({\n    type,\n    section,\n    appId,\n    temp,\n}: { type: string; section?: string; appId?: AppId; temp?: boolean }):\n    | AppDependenciesNavTarget\n    | PythonDependenciesNavTarget\n    | JavaScriptDependenciesNavTarget\n    | undefined => {\n    if (type === \"NATIVE_LIBRARIES\") {\n        return { type: \"JAVASCRIPT_DEPENDENCIES\", appId, temp };\n    }\n    if (type === \"SETTINGS\") {\n        switch (section) {\n            case \"DEPENDENCIES\":\n                return { type: \"APP_DEPENDENCIES\", appId, temp };\n            case \"RUNTIME\":\n                return { type: \"PYTHON_DEPENDENCIES\", appId, temp };\n        }\n    }\n};\n\nexport interface ScheduledTasksNavTarget extends AppNavTargetBase {\n    type: \"SCHEDULED_TASKS\";\n}\n\nexport interface ThemeNavTarget extends AppNavTargetBase {\n    type: \"THEME\";\n    section: \"ROLES\" | \"COLOUR_SCHEME\";\n}\n\nexport type ServiceType =\n    | \"USERS\"\n    | \"FILES\"\n    | \"SECRETS\"\n    | \"GOOGLE\"\n    | \"EMAIL\"\n    | \"FACEBOOK\"\n    | \"STRIPE\"\n    | \"MICROSOFT\"\n    | \"SAML\"\n    | \"TABLEAU\"\n    | \"TESTS\"\n    | \"HAWTHORN_DEPLOYMENT\";\n\nexport interface ServiceNavTarget extends AppNavTargetBase {\n    type: \"SERVICE\";\n    service: ServiceType;\n}\n\nexport interface ConversationNavTarget extends AppNavTargetBase {\n    type: \"CONVERSATION\";\n    conversationPid: ConversationPid;\n}\n\nexport interface ImportMapTarget extends AppNavTargetBase {\n    type: \"IMPORT_MAP\";\n}\n\nexport interface _ComponentsTarget extends AppNavTargetBase {\n    type: \"_COMPONENTS\";\n}\n\nexport interface ExtraFileNavTarget extends AppNavTargetBase {\n    type: \"EXTRA_FILE\";\n    /** App-relative path, including the extension. */\n    filePath: string;\n    view?: FullView;\n    refocusView?: number;\n    preserveFocus?: boolean; // Current navigation only; not stored in tabs or cached views.\n}\n\ntype GlobalNavTarget = RootNavTarget | AccountNavTarget | AcceptInviteTarget; // + any new targets outside the app.\n\nexport type BasicNavTarget =\n    | AppRootNavTarget\n    | SettingsNavTarget\n    | ScheduledTasksNavTarget\n    | AppDependenciesNavTarget\n    | PythonDependenciesNavTarget\n    | JavaScriptDependenciesNavTarget\n    | ImportMapTarget\n    | ThemeNavTarget\n    | SessionsNavTarget\n    | BackgroundTasksNavTarget\n    | UsageNavTarget\n    | MemoryUseNavTarget\n    | HelpNavTarget\n    | _ComponentsTarget;\n\nexport type AppNavTarget =\n    | BasicNavTarget\n    | CodeNavTarget\n    | ExtraFileNavTarget\n    | PythonSourceNavTarget\n    | DBTableNavTarget\n    | AppSchemaNavTarget\n    | SessionNavTarget\n    | ServiceNavTarget\n    | ConversationNavTarget;\n\nexport type NavTarget = GlobalNavTarget | AppNavTarget;\n\nexport type FullNavTarget = GlobalNavTarget | (AppNavTarget & { appId: AppId });\n","import { useSelector } from \"react-redux\";\nimport { FullNavTarget } from \"@/router/navTypes\";\nimport { getCurrentNavTarget } from \"@/router/navigation\";\nimport { State } from \"@/types\";\n\nexport function useNavTargetSelector<T>(selector: (target: FullNavTarget | undefined) => T) {\n    return useSelector((state: State) => selector(getCurrentNavTarget(state)));\n}\n\nexport function useCurrentNavTarget() {\n    return useSelector(getCurrentNavTarget);\n}\n\nexport function usePreserveNavigationFocus() {\n    return useNavTargetSelector(\n        (target) => (target?.type === \"CODE\" || target?.type === \"EXTRA_FILE\") && !!target.preserveFocus\n    );\n}\n","import { produce } from \"immer\";\nimport { cloneDeep, get, merge, set, update } from \"lodash-es\";\nimport { Middleware, Reducer, applyMiddleware, legacy_createStore as createStore } from \"redux\";\nimport { createLogger } from \"redux-logger\";\nimport { thunk } from \"redux-thunk\";\nimport { base64EncStr } from \"@runtime/lib/b64\";\nimport { AnvilAction, AnvilDispatch, BaseAction, State } from \"@/types\";\nimport {\n    LOAD_PREVIOUS_STATE,\n    OFF_EVENT,\n    ON_EVENT,\n    ON_IDLE,\n    ON_IDLE_CANCEL,\n    RAISE_EVENT,\n    UPDATE_STATE,\n} from \"../actions\";\nimport { alert } from \"../controllers/modals\";\n\ntype AnvilMiddleware = Middleware<AnvilAction, unknown, AnvilDispatch>;\ntype AnvilReducer = Reducer<unknown, BaseAction>;\n\nconst loggerMiddleware = createLogger({\n    actionTransformer: (action) => {\n        if (\"async\" in action) {\n            return update(\n                cloneDeep(action),\n                [\"type\"],\n                (type) =>\n                    `${type} (${\n                        action.success\n                            ? \"Loaded\"\n                            : action.error\n                              ? \"Failed\"\n                              : action.abort\n                                ? \"Abort previous\"\n                                : \"Loading\"\n                    })`\n            );\n        }\n        if (action.type === \"UPDATE_STATE\" && action.description) {\n            return update(cloneDeep(action), [\"type\"], (type) => action.description);\n        }\n        return action;\n    },\n    predicate: (getState, action, logEntry) => {\n        return false;\n        // if (action.type === \"UPDATE_STATE\") {\n        //     return !!action.description;\n        // }\n        // return true;\n    },\n    collapsed: true,\n}) as AnvilMiddleware;\n\nconst dispatchOnIdleMiddleware: AnvilMiddleware = (store) => (next) => {\n    const queuedActions = new Map();\n    return (action: any) => {\n        const dispatch = store.dispatch;\n\n        switch (action.type) {\n            case ON_IDLE: {\n                queuedActions.get(action.key)?.();\n\n                const timeout = setTimeout(() => {\n                    queuedActions.delete(action.key);\n                    dispatch(action.action);\n                }, action.timeout);\n\n                queuedActions.set(action.key, () => {\n                    queuedActions.delete(action.key);\n                    clearTimeout(timeout);\n                });\n\n                break;\n            }\n\n            case ON_IDLE_CANCEL: {\n                queuedActions.get(action.key)?.();\n                break;\n            }\n\n            default:\n                return next(action);\n        }\n    };\n};\n\nconst eventSystemMiddleware: AnvilMiddleware = (store) => (next) => {\n    const callbacks: Record<string, ((...args: any[]) => void)[]> = {};\n    return (action: any) => {\n        switch (action.type) {\n            case ON_EVENT:\n                callbacks[action.event] ??= [];\n                if (!callbacks[action.event].includes(action.callback)) {\n                    callbacks[action.event].push(action.callback);\n                }\n                return;\n\n            case OFF_EVENT:\n                callbacks[action.event] ??= [];\n                callbacks[action.event] = callbacks[action.event].filter((c) => c !== action.callback);\n                return;\n\n            case RAISE_EVENT:\n                return Promise.allSettled((callbacks[action.event] ?? []).map((cb) => cb(...action.args)));\n\n            default:\n                return next(action);\n        }\n    };\n};\n\nconst persistLocalStateMiddleware: AnvilMiddleware = (store) => (next) => {\n    let db: null | IDBDatabase = null;\n    if (indexedDB) {\n        const request = indexedDB.open(\"anvil\", 2);\n        request.onupgradeneeded = (e) => {\n            db = (e.target as IDBOpenDBRequest)?.result ?? null;\n            if (db === null) return;\n            if (!db.objectStoreNames.contains(\"state\")) {\n                db.createObjectStore(\"state\");\n            }\n        };\n        request.onsuccess = (e) => {\n            db = (e.target as IDBOpenDBRequest).result;\n        };\n    }\n\n    let persistTimeout: number | undefined = undefined;\n\n    const persist = () => {\n        if (!db) return;\n        const state = store.getState();\n\n        const persistPaths: string[][] = [];\n\n        const walk = (path: string[]) => {\n            const s = path.length > 0 ? get(state, path) : state;\n\n            if (s != null && typeof s === \"object\") {\n                const persist = s.$persist;\n                if (persist instanceof Array) {\n                    for (const p of persist) {\n                        persistPaths.push([...path, p]);\n                    }\n                } else if (persist) {\n                    persistPaths.push(path);\n                }\n                for (const k of s.$persistWalk ?? []) {\n                    walk([...path, k]);\n                }\n            }\n        };\n\n        walk([]);\n\n        console.time(\"Persist state to Indexed DB\");\n        const persistState = {};\n        for (const p of persistPaths) {\n            const persistObject = get(state, p); //cloneDeep(get(state, p));\n            // if (persistObject && typeof(persistObject) === \"object\") {\n            //     delete persistObject.$persist;\n            // }\n            set(persistState, p, persistObject);\n        }\n\n        try {\n            const tx = db.transaction(\"state\", \"readwrite\");\n            const store = tx.objectStore(\"state\");\n            store.put(persistState, 0);\n        } catch {\n            // ignore error\n        }\n        console.timeEnd(\"Persist state to Indexed DB\");\n    };\n\n    return (action) => {\n        clearTimeout(persistTimeout);\n        persistTimeout = setTimeout(persist, 1000);\n        return next(action);\n    };\n};\n\nexport const exportStore = (): AnvilAction => (dispatch, getState, updateState) => {\n    if (indexedDB) {\n        indexedDB.open(\"anvil\", 2).onsuccess = (e) => {\n            const db = (e.target as IDBOpenDBRequest)?.result ?? null;\n            if (db.objectStoreNames.contains(\"state\")) {\n                const store = db.transaction(\"state\", \"readonly\").objectStore(\"state\");\n                store.get(0).onsuccess = (e) => {\n                    const previousState = (e.target as any).result;\n                    const a = document.createElement(\"a\");\n                    document.body.appendChild(a);\n                    a.href = \"data:\" + \"text/json\" + \";base64,\" + base64EncStr(JSON.stringify(previousState));\n                    a.download = `anvilStoreExport-${getState().user.email}.json`;\n                    a.click();\n                    setTimeout(() => {\n                        document.body.removeChild(a);\n                    }, 0);\n                };\n            }\n        };\n    }\n};\n\n// <ErrorBoundary /> won't handle async errors so display a message\n// we only display errors for ones that we've seen through our internal dispatching\nwindow.addEventListener(\"unhandledrejection\", (ev) => {\n    const e = ev.reason;\n    // This error wasn't from a dispatch - ignore it\n    const dispatch = seenErrors.get(e);\n    if (!dispatch) return;\n    console.error(e);\n    // We don't care about aborts.\n    if (e.message !== \"Aborted\") {\n        let errorDetail = \"\";\n        try {\n            errorDetail = JSON.stringify(e);\n        } catch {\n            // Fallback to a safe string representation\n            errorDetail = `${e}`;\n        }\n        dispatch(alert(e.title || \"Error\", e.message || errorDetail));\n    }\n});\n\n// Keep track of errors that were thrown during dispatch\n// This way we don't display random errors to the user.\n// Track which AnvilDispatch instance they were from\nconst seenErrors = new WeakMap();\n\nconst stateUpdaterMiddleware: AnvilMiddleware = (_store) => (next) => (action) => {\n    if (typeof action === \"function\") {\n        const newAction = (dispatch: AnvilDispatch, getState: () => State) => {\n            const updateState = (...args: any[]) => {\n                let timing = false;\n                if (typeof args[0] !== \"string\") {\n                    args.unshift(null);\n                } else {\n                    timing = true;\n                    console.time(args[0]);\n                }\n                const [description, producer, ...restArgs] = args;\n                dispatch({ type: UPDATE_STATE, description, producer, args: restArgs });\n                if (timing) {\n                    console.timeEnd(args[0]);\n                }\n            };\n\n            const resp = action(dispatch, getState, updateState);\n\n            if (resp instanceof Promise) {\n                return resp.catch(async (e) => {\n                    if (e !== null && typeof e === \"object\") {\n                        seenErrors.set(e, dispatch);\n                    }\n                    throw e;\n                });\n            } else {\n                return resp;\n            }\n        };\n        return next(newAction);\n    } else {\n        return next(action);\n    }\n};\n\nexport const baseProducer: AnvilReducer = (state, action) => {\n    switch (action.type) {\n        case LOAD_PREVIOUS_STATE:\n            try {\n                return merge(state, action.state);\n            } catch {\n                return state;\n            }\n\n        case UPDATE_STATE:\n            // TODO enforce that fn is not async. Overwriting the state with a Promise would get...messy.\n            return produce(action.producer)(state, ...action.args);\n\n        default:\n            return state;\n    }\n};\n\nexport const initStore = <T = AnvilDispatch>(rootReducer: AnvilReducer) =>\n    createStore(\n        rootReducer,\n        applyMiddleware<T>(\n            stateUpdaterMiddleware,\n            thunk,\n            dispatchOnIdleMiddleware,\n            eventSystemMiddleware,\n            loggerMiddleware,\n            persistLocalStateMiddleware\n        )\n    );\n\n","import {\n    faFile,\n    faFileCode,\n    faFileCsv,\n    faFileLines,\n    faFolder,\n    faFolderGear,\n    faFolderOpen,\n    faVial,\n} from \"@fortawesome/pro-regular-svg-icons\";\nimport type { ExtraFileStructureItem } from \"@/types\";\n\nexport function getTestFileIcon(\n    file: Pick<ExtraFileStructureItem, \"type\" | \"isPackage\" | \"fullName\">,\n    expanded: boolean\n) {\n    // Directories containing __init__.py are editable Python packages.\n    if (file.isPackage) {\n        return faFolderGear;\n    }\n\n    // Plain directories have no __init__.py or associated editor.\n    if (file.type === \"folder\") {\n        return expanded ? faFolderOpen : faFolder;\n    }\n\n    // Use the real filename: the display label may omit \".py\".\n    const filename = file.fullName.split(\"/\").at(-1) ?? \"\";\n    const extension = filename.split(\".\").at(-1)?.toLowerCase();\n\n    if (extension === \"py\") {\n        const looksLikeTest = filename.startsWith(\"test_\") || filename.endsWith(\"_test.py\");\n\n        return looksLikeTest ? faVial : faFileCode;\n    }\n\n    switch (extension) {\n        case \"csv\":\n        case \"tsv\":\n            return faFileCsv;\n\n        case \"txt\":\n        case \"text\":\n        case \"md\":\n        case \"markdown\":\n        case \"rst\":\n        case \"log\":\n            return faFileLines;\n\n        case \"ini\":\n        case \"json\":\n        case \"yaml\":\n        case \"yml\":\n        case \"xml\":\n        case \"html\":\n        case \"css\":\n        case \"js\":\n        case \"jsx\":\n        case \"ts\":\n        case \"tsx\":\n            return faFileCode;\n\n        default:\n            return faFile;\n    }\n}\n","import type { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport {\n    faCircle,\n    faCircleCheck,\n    faCircleExclamation,\n    faCircleMinus,\n    faCircleNotch,\n    faCircleQuestion,\n    faCircleStop,\n    faCircleXmark,\n    faTriangleExclamation,\n} from \"@fortawesome/pro-light-svg-icons\";\nimport type { TestResult, TestRun } from \"@/controllers/server-test-runs\";\n\nexport interface TestStatusDisplay {\n    icon: IconDefinition;\n    label: string;\n    className: string;\n    spin?: boolean;\n}\n\nexport function getTestStatusDisplay(result?: TestResult): TestStatusDisplay {\n    const status = !result ? \"not_run\" : result.status === \"finished\" ? (result.outcome ?? \"finished\") : result.status;\n\n    switch (status) {\n        case \"passed\":\n            return {\n                icon: faCircleCheck,\n                label: \"Passed\",\n                className: \"text-highlight\",\n            };\n\n        case \"failed\":\n            return {\n                icon: faCircleXmark,\n                label: \"Failed\",\n                className: \"text-danger\",\n            };\n\n        case \"error\":\n            return {\n                icon: faCircleExclamation,\n                label: \"Error\",\n                className: \"text-danger\",\n            };\n\n        case \"skipped\":\n            return {\n                icon: faCircleMinus,\n                label: \"Skipped\",\n                className: \"text-light-fg3 dark:text-dark-fg3\",\n            };\n\n        case \"xfailed\":\n            return {\n                icon: faCircleXmark,\n                label: \"Expected failure\",\n                className: \"text-secondary-700 dark:text-secondary-300\",\n            };\n\n        case \"xpassed\":\n            return {\n                icon: faTriangleExclamation,\n                label: \"Unexpected pass\",\n                className: \"text-tertiary-700 dark:text-tertiary-300\",\n            };\n\n        case \"running\":\n            return {\n                icon: faCircleNotch,\n                label: \"Running\",\n                className: \"text-primary\",\n                spin: true,\n            };\n\n        case \"pending\":\n            return {\n                icon: faCircle,\n                label: \"Pending\",\n                className: \"text-secondary\",\n            };\n\n        case \"finished\":\n            return {\n                icon: faCircleQuestion,\n                label: \"Finished without an outcome\",\n                className: \"text-tertiary-700 dark:text-tertiary-300\",\n            };\n\n        case \"did_not_finish\":\n            return {\n                icon: faCircle,\n                label: \"Didn't finish\",\n                className: \"text-amber-800 dark:text-amber-600\",\n            };\n\n        case \"not_run\":\n            return {\n                icon: faCircle,\n                label: \"Not run\",\n                className: \"text-light-fg3 dark:text-dark-fg3\",\n            };\n    }\n}\n\nexport function getTestRunStatusDisplay(run?: TestRun): TestStatusDisplay {\n    const muted = \"text-light-fg3 dark:text-dark-fg3\";\n\n    if (!run) {\n        return {\n            icon: faCircle,\n            label: \"Not run\",\n            className: muted,\n        };\n    }\n\n    const { state } = run;\n\n    if (state.status !== \"complete\") {\n        let label = \"Starting\";\n\n        switch (state.status) {\n            case \"launching_server\":\n                label = \"Starting server\";\n                break;\n            case \"collecting_tests\":\n                label = \"Discovering tests\";\n                break;\n            case \"running_tests\":\n                label = \"Running tests\";\n                break;\n        }\n\n        return {\n            icon: faCircleNotch,\n            label,\n            className: \"text-primary\",\n            spin: true,\n        };\n    }\n\n    // The backend currently identifies cancellation by this message.\n    // Replace with a structured cancellation field when available.\n    if (state.error?.message === \"The test run was cancelled before it finished\") {\n        return {\n            icon: faCircleStop,\n            label: \"Cancelled\",\n            className: muted,\n        };\n    }\n\n    if (state.collection_errors?.length) {\n        return {\n            icon: faCircleExclamation,\n            label: \"Collection failed\",\n            className: \"text-danger\",\n        };\n    }\n\n    if (state.exit_code === \"NO_TESTS_COLLECTED\") {\n        return {\n            icon: faCircle,\n            label: \"No tests selected\",\n            className: muted,\n        };\n    }\n\n    if (state.error || state.exit_code === \"INTERNAL_ERROR\" || state.exit_code === \"USAGE_ERROR\") {\n        return {\n            icon: faTriangleExclamation,\n            label: \"Run error\",\n            className: \"text-danger\",\n        };\n    }\n\n    if (state.exit_code === \"INTERRUPTED\") {\n        return {\n            icon: faCircleExclamation,\n            label: \"Interrupted\",\n            className: \"text-secondary\",\n        };\n    }\n\n    if (state.exit_code === \"TESTS_FAILED\" || (state.counts?.failed ?? 0) > 0 || (state.counts?.error ?? 0) > 0) {\n        return {\n            icon: faCircleXmark,\n            label: \"Tests failed\",\n            className: \"text-danger\",\n        };\n    }\n\n    if (state.exit_code === \"OK\") {\n        if (state.options?.collect_only) {\n            return {\n                icon: faCircleCheck,\n                label: \"Discovery complete\",\n                className: \"text-quaternary\",\n            };\n        }\n\n        if ((state.counts?.passed ?? 0) > 0) {\n            return {\n                icon: faCircleCheck,\n                label: \"Passed\",\n                className: \"text-highlight\",\n            };\n        }\n\n        return {\n            icon: faCircle,\n            label: \"Completed\",\n            className: muted,\n        };\n    }\n\n    return {\n        icon: faCircleQuestion,\n        label: \"Finished without an outcome\",\n        className: \"text-secondary\",\n    };\n}\n","import { placeholder } from \"@codemirror/view\";\nimport Color from \"color\";\nimport { merge } from \"lodash-es\";\n\ntype ThemeColor = ReturnType<typeof Color>;\n\nconst lightPalette = {\n    bg0: Color(\"#fcfcfc\"),\n    bg1: Color(\"#F4F4F4\"),\n    bg2: Color(\"#F7FDFF\"),\n    bg3: Color(\"#DDE8EC\"),\n    bg4: Color(\"#D6E9EF\"),\n    bg5: Color(\"#B0C6CE\"),\n    bg6: Color(\"#6C858E\"),\n    bg7: Color(\"#485a60\"),\n    //added for version history, this is the color in Light:\n    bg8: Color(\"#EDEDED\"),\n\n    fg1: Color(\"#515151\"),\n    // these are the same as fg1 but it keeps typescript happy for merging dark/light Palette\n    fg2: Color(\"#515151\"),\n    fg3: Color(\"#515151\"),\n\n    white: Color(\"#ffffff\"),\n    grey0: Color(\"#dddddd\"),\n    grey1: Color(\"#999999\"),\n    grey2: Color(\"#444444\"),\n\n    primary: Color(\"#1BB0EE\"),\n    secondary: Color(\"#FFA640\"),\n    tertiary: Color(\"#FF6541\"),\n    quaternary: Color(\"#20bfa9\"),\n\n    danger: Color(\"#dd3c3c\"),\n\n    highlight: Color(\"#00BB4C\"),\n\n    primaryBg: Color(\"#e8f7fd\"),\n\n    lightRed: Color(\"#f8e0e0\"),\n    greyRed: Color(\"#e8d0d0\"),\n};\n\nconst darkPalette = {\n    ...lightPalette,\n    bg0: Color(\"#1f1f1f\"),\n    bg1: Color(\"#141414\"),\n    bg2: Color(\"#1f1f1f\"),\n    bg3: Color(\"#484D58\"),\n    bg4: Color(\"#666666\"),\n    bg6: Color(\"#31343C\"),\n    bg7: Color(\"#838A9A\"),\n    bg8: Color(\"#636978\"),\n\n    fg1: Color(\"#DDDDDD\"), //should have changed fg1 at the start - now its the same as fg3\n    fg2: Color(\"#000000\"),\n    fg3: Color(\"#DDDDDD\"),\n\n    lightRed: Color(\"#895260\"),\n    greyRed: Color(\"#8C5F6A\"),\n\n    // white: Color(\"#000000\"),\n    // grey0: Color(\"#000000\"),\n    // grey1: Color(\"#000000\"),\n    // grey2: Color(\"#000000\"),\n\n    // highlight: Color(\"#000000\"),\n\n    // primaryBg: Color(\"#000000\"),\n};\n\nconst Base = {\n    codeFont: \"Source Code Pro, monospace\",\n    appearTime: \"0.1s\",\n\n    sectionBorderColor: lightPalette.bg4,\n\n    primaryNav: {\n        iconSize: \"2.3rem\",\n        background: lightPalette.white,\n        defaultIconColor: lightPalette.bg5,\n        iconHoverBg: lightPalette.bg4,\n        iconHoverColor: lightPalette.bg5,\n        iconActiveBg: lightPalette.bg6,\n        iconActiveColor: lightPalette.bg2,\n        selectedIconColor: lightPalette.white,\n        selectedIconBg: lightPalette.grey2,\n        addButtonColor: lightPalette.white,\n        addButtonBg: lightPalette.primary,\n    },\n\n    secondaryNav: {\n        sectionHeader: {\n            color: lightPalette.grey2,\n            background: lightPalette.bg2,\n            fontSize: \"1.4rem\",\n            fontWeight: 600,\n            hoverColor: lightPalette.grey2,\n            hoverBg: lightPalette.bg4.alpha(0.5),\n            dotsColor: lightPalette.bg6,\n        },\n        linkHeight: \"3.2rem\",\n        fontSize: \"1.2rem\",\n        fontWeight: 500,\n        background: lightPalette.bg2,\n        color: lightPalette.bg6,\n        iconSize: \"1.8rem\",\n        iconColor: lightPalette.grey2,\n        icon1: { color: lightPalette.white, background: lightPalette.primary },\n        icon2: { color: lightPalette.white, background: lightPalette.secondary },\n        icon3: { color: lightPalette.white, background: lightPalette.tertiary },\n        icon4: { color: lightPalette.white, background: lightPalette.quaternary },\n        hoverBg: lightPalette.bg4.alpha(0.5),\n        hoverColor: lightPalette.grey2,\n        activeBg: lightPalette.bg4,\n        enabledChevron: lightPalette.grey2, // Or bg5 if we want more subtle\n        disabledChevron: lightPalette.bg4,\n        expandedChevron: lightPalette.grey2, // Or bg5 if we want more subtle\n        hoverChevron: lightPalette.grey1,\n        dotsHoverBg: lightPalette.bg4,\n        dotsActiveBg: lightPalette.bg4,\n        folderLines: lightPalette.bg4,\n        selectedBg: lightPalette.grey2,\n        selectedColor: lightPalette.white,\n        selectedBgDotsHoverBg: lightPalette.bg6, // TODO: This is horrid.\n        selectedBgDotsHoverColor: lightPalette.grey2,\n        selectedBgDotsActiveBg: lightPalette.bg6, // TODO: This is horrid.\n        selectedBgDotsActiveColor: lightPalette.grey2,\n        alert: {\n            borderRadius: \"0.4rem\",\n            borderColor: lightPalette.bg6,\n            borderWidth: 2,\n            background: lightPalette.white,\n            iconBarWidth: \"4rem\",\n            iconFontSize: \"2.2rem\",\n            iconColor: lightPalette.white,\n            fontSize: \"1.2rem\",\n            titleWeight: 600,\n            bodyWeight: 500,\n        },\n    },\n\n    notice: {\n        background: Color(\"#ffd\"),\n        borderBottom: Color(\"#000\").alpha(0.2).toString(),\n        color: Color(\"#000\"),\n        linkColor: lightPalette.primary,\n    },\n\n    header: {\n        background: lightPalette.white,\n        savedIconColor: lightPalette.highlight,\n        warningIconColor: lightPalette.danger,\n        fontSize: \"1.3rem\",\n        lightLink: {\n            color: lightPalette.grey1,\n            hoverColor: lightPalette.grey2,\n            fontWeight: 400,\n        },\n        heavyLink: {\n            color: lightPalette.grey2,\n            hoverColor: lightPalette.grey1,\n            fontWeight: 600,\n        },\n        userAccountBg: lightPalette.grey2,\n        userAccountColor: lightPalette.white,\n    },\n\n    button: {\n        borderRadius: \"0.4rem\",\n        background: lightPalette.bg4,\n        hoverBg: lightPalette.bg5,\n        activeBg: lightPalette.bg6,\n        color: lightPalette.bg7,\n        disabledColor: lightPalette.bg4,\n        iconColor: lightPalette.bg6,\n        fontSize: \"1.4rem\",\n        fontWeight: 600,\n        height: \"3.8rem\",\n        padding: \"1.2rem\",\n        border: lightPalette.bg4,\n\n        tiny: {\n            fontSize: \"1rem\",\n            height: \"1.8rem\",\n            padding: \"0.3rem\",\n            fontWeight: 600,\n            color: lightPalette.bg7,\n        },\n\n        small: {\n            fontSize: \"1.2rem\",\n            height: \"2.8rem\",\n            padding: \"0.6rem\",\n            fontWeight: 600,\n            color: lightPalette.bg7,\n        },\n\n        large: {\n            fontSize: \"1.9rem\",\n            height: \"4rem\",\n            padding: \"2rem\",\n            fontWeight: 600,\n            color: lightPalette.bg7,\n        },\n\n        disabled: { border: undefined as string | undefined, background: undefined as string | undefined },\n\n        hidden: {\n            color: undefined as string | undefined,\n            background: undefined as string | undefined,\n            boxShadow: undefined as string | undefined,\n            hoverTransform: undefined as string | undefined,\n            hoverBg: undefined as string | undefined,\n            activeBg: undefined as string | undefined,\n        },\n\n        primary: {\n            background: lightPalette.primary,\n            color: lightPalette.white,\n            iconColor: lightPalette.white,\n        },\n        secondary: {\n            background: lightPalette.secondary,\n            color: lightPalette.white,\n            iconColor: lightPalette.white,\n        },\n        tertiary: {\n            background: lightPalette.tertiary,\n            color: lightPalette.white,\n            iconColor: lightPalette.white,\n        },\n        danger: {\n            background: lightPalette.danger,\n            color: lightPalette.white,\n            iconColor: lightPalette.white,\n        },\n        highlight1: {\n            background: lightPalette.highlight,\n            color: lightPalette.white,\n            iconColor: lightPalette.white,\n        },\n        highlight2: {\n            background: lightPalette.grey2,\n            color: lightPalette.white,\n            iconColor: lightPalette.white,\n        },\n        highlight3: {\n            background: lightPalette.bg4,\n            color: lightPalette.bg7,\n            iconColor: lightPalette.bg6,\n        },\n    },\n\n    buttonGroup: {\n        divider: lightPalette.bg5,\n    },\n\n    tabBar: {\n        background: lightPalette.bg2,\n        tabPadding: \"1rem\",\n        fontSize: \"1.2rem\",\n        iconSize: \"1.8rem\",\n        height: \"3.9rem\",\n        closeIconHoverColor: lightPalette.grey2,\n        activeTab: {\n            background: lightPalette.white,\n            closeButton: lightPalette.grey1,\n            closeButtonHover: lightPalette.grey2,\n            borderTop: lightPalette.white,\n            color: lightPalette.grey2,\n        },\n        inactiveTab: {\n            background: lightPalette.bg5,\n            closeButton: lightPalette.grey2,\n            hoverBg: lightPalette.grey1,\n            color: lightPalette.bg6,\n            iconColor: lightPalette.bg6,\n        },\n        bottom: {\n            closedBarTab: {\n                background: lightPalette.white,\n                hoverBg: lightPalette.bg4,\n                activeBg: lightPalette.bg5,\n                color: lightPalette.grey2,\n            },\n            openBarInactiveTab: {\n                background: lightPalette.bg5,\n                closeButton: lightPalette.grey2,\n                hoverBg: lightPalette.bg4,\n                hoverColor: lightPalette.bg6,\n                iconHoverColor: lightPalette.bg6,\n                activeBg: lightPalette.bg3,\n                color: lightPalette.bg6,\n            },\n            openBarActiveTab: {\n                background: lightPalette.white,\n                closeButton: lightPalette.grey1,\n                borderTop: lightPalette.white,\n                color: lightPalette.grey2,\n            },\n        },\n    },\n\n    tabToolbar: {\n        background: lightPalette.white,\n    },\n\n    formInput: {\n        height: \"5rem\",\n        padding: \"1.5rem\",\n        border: lightPalette.bg5,\n        color: lightPalette.grey2,\n        background: lightPalette.white,\n        placeholderColor: lightPalette.bg5,\n        smallPlaceholderColor: lightPalette.bg6,\n        smallHeight: \"2.2rem\",\n        smallBackground: lightPalette.bg4,\n        smallBorder: lightPalette.bg4,\n        smallFontSize: \"1.2rem\",\n        smallPadding: \"0.5rem\",\n        focusOutline: undefined as string | undefined,\n        focusOffset: undefined as string | undefined,\n    },\n\n    inputLabel: undefined as\n        | {\n              fontSize?: string;\n              lineHeight?: string;\n              fontWeight?: number;\n              color?: string;\n              marginBottom?: string | number;\n              subtitle?: {\n                  fontSize?: string;\n                  lineHeight?: string;\n                  fontWeight?: number;\n                  color?: ThemeColor;\n                  marginBottom?: string | number;\n              };\n          }\n        | undefined,\n\n    dropDown: undefined as\n        | {\n              height?: string;\n              padding?: string;\n              fontSize?: string;\n              color?: ThemeColor;\n              fontWeight?: number;\n              chevron?: {\n                  right?: string | number;\n                  fontWeight?: number;\n                  fontSize?: string;\n                  color?: ThemeColor;\n              };\n              small?: {\n                  padding?: string;\n                  height?: string;\n                  chevron?: {\n                      right?: string | number;\n                      fontSize?: string;\n                  };\n              };\n          }\n        | undefined,\n\n    form: {\n        checkbox: {\n            color: lightPalette.fg1,\n        },\n    },\n\n    spacing: {\n        h1: {\n            margin: \"1rem 0\",\n        },\n        h2: {\n            margin: \"20px 0 10px 0\",\n        },\n        h3: {\n            margin: \"20px 0 10px 0\",\n        },\n        p1: {\n            margin: \"0.5rem 0\",\n        },\n        p2: {\n            margin: \"0.5rem 0\",\n        },\n        p3: {\n            margin: \"0.5rem 0\",\n        },\n    },\n\n    text: {\n        h1: {\n            fontSize: \"1.8rem\",\n            fontWeight: 600,\n            color: lightPalette.grey2,\n        },\n        h2: {\n            fontSize: \"1.6rem\",\n            fontWeight: 600,\n            color: lightPalette.grey2,\n        },\n        h3: {\n            fontSize: \"1.2rem\",\n            fontWeight: 600,\n            color: lightPalette.grey2,\n        },\n        p1: {\n            fontSize: \"1.4rem\",\n            fontWeight: 400,\n            color: lightPalette.grey2,\n        },\n        p2: {\n            fontSize: \"1.4rem\",\n            fontWeight: 400,\n            color: lightPalette.grey1,\n        },\n        p3: {\n            fontSize: \"1.2rem\",\n            fontWeight: 400,\n            color: lightPalette.grey1,\n        },\n        dark: lightPalette.grey2,\n        light: lightPalette.grey1,\n        extraLight: lightPalette.grey0,\n    },\n\n    table: {\n        header: {\n            fontSize: \"1.2rem\",\n            fontWeight: 600,\n        },\n        fontSize: \"1.2rem\",\n        fontWeight: 500,\n        verticalPadding: \"1.5rem\",\n        borderColor: lightPalette.bg5,\n        thickBorder: \"4px\",\n        thinBorder: \"2px\",\n    },\n\n    settings: {\n        rightBarBackground: lightPalette.bg2,\n        separator: lightPalette.bg4,\n        background: lightPalette.white,\n    },\n\n    dropDownMenu: {\n        borderColor: lightPalette.bg4,\n        color: lightPalette.grey2,\n        background: lightPalette.white,\n        hoverBg: lightPalette.bg4,\n        activeBg: lightPalette.bg5,\n        fontSize: \"1.2rem\",\n        fontWeight: 500,\n        itemHeight: \"3rem\",\n        borderWidth: undefined,\n        borderRadius: undefined,\n        shadow: undefined,\n        separatorMargin: undefined,\n        separatorWidth: undefined,\n        padding: undefined,\n        itemPadding: undefined,\n        firstItemPaddingTop: undefined,\n        lastItemPaddingBottom: undefined,\n        iconFontSize: undefined,\n    },\n\n    modal: {\n        border: undefined as string | undefined,\n        borderRadius: undefined as string | number | undefined,\n        boxShadow: undefined as string | undefined,\n        header: {\n            background: lightPalette.bg2,\n            hoverBg: lightPalette.bg3,\n            height: \"6rem\",\n            fontSize: \"2.2rem\",\n            fontWeight: 600,\n            iconColor: lightPalette.bg6,\n            margin: undefined as string | undefined,\n            closeHover: undefined as ThemeColor | undefined,\n        },\n        footer: undefined as { padding?: string } | undefined,\n        background: lightPalette.white,\n        color: lightPalette.grey2,\n        padding: \"2rem\",\n        icon: lightPalette.fg1,\n        code: {\n            color: lightPalette.fg1,\n            background: lightPalette.bg8,\n            borderColor: lightPalette.bg8,\n        },\n        notification: {\n            headingColor: \"#121212\",\n            backgroundColor: \"#ffd\",\n            borderColor: Color(\"#000\").alpha(0.2).toString(),\n        },\n        planCard: {\n            color: lightPalette.fg1,\n            background: lightPalette.bg1.fade(0.6), //would like to be f7 actually\n            borderTop: lightPalette.primary,\n            border: lightPalette.bg2,\n            featuresBorder: lightPalette.bg4,\n            featureBackground: lightPalette.bg2,\n            currentPlan: {\n                background: lightPalette.bg2,\n                featureBackground: lightPalette.white,\n            },\n        },\n        addMappingOrTable: {\n            noResults: {\n                color: lightPalette.grey1,\n                background: lightPalette.bg5.lighten(0.3),\n            },\n        },\n    },\n\n    accordion: {\n        header: {\n            background: lightPalette.bg2,\n            expandedBg: lightPalette.bg4,\n            hoverBg: lightPalette.bg2.darken(0.03),\n            expandedHoverBg: lightPalette.bg4.darken(0.04),\n            chevronColor: lightPalette.grey1,\n            title: {\n                fontSize: \"1.4rem\",\n                fontWeight: 600,\n                color: lightPalette.grey2,\n            },\n            subtitle: {\n                fontSize: \"1rem\",\n                fontWeight: 500,\n                color: lightPalette.bg6,\n            },\n            actionLink: {\n                fontSize: \"1.2rem\",\n                fontWeight: 500,\n                color: lightPalette.bg7,\n                hoverColor: lightPalette.grey2.darken(0.5),\n            },\n            iconColor: lightPalette.grey2.alpha(0.15),\n            iconColorPresent: lightPalette.grey2,\n        },\n        children: {\n            color: lightPalette.bg7,\n            background: lightPalette.white,\n            hoverBackground: lightPalette.bg2.fade(0.3),\n            selectedBg: lightPalette.bg2.darken(0.03),\n        },\n    },\n\n    startPage: {\n        headerIconColor: lightPalette.primary,\n        background: lightPalette.white,\n        appCardBackground: lightPalette.bg2,\n        appCardSubtitleColor: lightPalette.bg6,\n        carouselNavLink: {\n            background: lightPalette.grey2,\n            enabledBg: lightPalette.grey2,\n            disabledBg: lightPalette.grey1,\n            enabledColor: lightPalette.white,\n            activeColor: lightPalette.bg7,\n        },\n    },\n\n    ///// OLD\n    hl1: Color(\"#1BB0EE\"),\n    hl3: Color(\"#19dd74\"),\n    hl4: Color(\"#c7254e\"),\n\n    primary: Color(\"#1bb0ee\"),\n    secondary: Color(\"#ffa640\"),\n    tertiary: Color(\"#ff6541\"),\n    danger: Color(\"#f2dede\"),\n\n    tabBanner: {\n        background: \"#ffd\",\n        textAlign: \"center\",\n        borderBottom: \"1px solid \" + Color(\"#000\").alpha(0.2).toString(),\n    },\n\n    // sidebarSectionHeader: {\n    //     textTransform: 'uppercase',\n    //     fontWeight: 'bold',\n    //     marginTop: 0,\n    //     marginBottom: 10,\n    // },\n\n    versionHistory: {\n        branch: {\n            color: lightPalette.fg1,\n            background: lightPalette.bg8,\n            border: lightPalette.bg0,\n        },\n        currentBranch: {\n            border: lightPalette.fg1,\n        },\n    },\n    roles: {\n        color: lightPalette.fg1,\n        highlight: {\n            background: lightPalette.white,\n            border: lightPalette.bg8,\n            color: lightPalette.fg1,\n        },\n        editRole: {\n            color: lightPalette.fg1,\n            titleBackground: lightPalette.bg8,\n            background: lightPalette.white,\n            border: lightPalette.bg8,\n            codeColor: lightPalette.fg1,\n            component: {\n                background: lightPalette.bg0,\n                border: lightPalette.bg8,\n            },\n        },\n    },\n\n    colourScheme: {\n        dropdown: {\n            background: lightPalette.bg3,\n            border: lightPalette.bg2,\n            itemHover: lightPalette.bg2,\n            itemBorder: lightPalette.bg2,\n        },\n        color: lightPalette.fg1,\n    },\n\n    noServiceSplashPage: {\n        color: lightPalette.grey1,\n        background: lightPalette.bg5.lighten(0.3),\n        border: lightPalette.bg4,\n    },\n\n    userService: {\n        color: lightPalette.fg1,\n        sampleCode: {\n            background: lightPalette.bg2,\n            color: lightPalette.fg1,\n            borderColor: lightPalette.bg2,\n        },\n    },\n\n    emailService: {\n        color: lightPalette.fg1,\n        alert: {\n            backgroundColor: \"#ffd\",\n            borderColor: Color(\"#000\").alpha(0.2).toString(),\n        },\n        separator: lightPalette.bg4,\n    },\n\n    googleService: {\n        background: lightPalette.bg2,\n        fileRowBg: lightPalette.bg2,\n        pythonNameBg: lightPalette.bg4.fade(0.6),\n        color: lightPalette.fg1,\n        modal: {\n            rowHoverBg: lightPalette.bg2,\n            rowSelectBg: lightPalette.bg3.fade(0.5),\n            emptyNotice: lightPalette.bg5.lighten(0.3),\n            emptyTextColor: lightPalette.grey1,\n        },\n    },\n\n    scheduledTasks: {\n        color: lightPalette.fg1,\n        border: lightPalette.grey0,\n        item: {\n            hoverBackground: lightPalette.bg4,\n            activeBackground: lightPalette.bg5,\n        },\n    },\n\n    backgroundTasks: {\n        color: lightPalette.fg1.lighten(0.4),\n        border: lightPalette.bg8,\n        code: {\n            color: lightPalette.fg1,\n            border: lightPalette.bg8,\n            background: lightPalette.bg8,\n        },\n    },\n\n    facebookService: {\n        background: lightPalette.bg2,\n        border: lightPalette.bg4,\n        panelBackground: lightPalette.white,\n    },\n\n    dataFileService: {\n        background: lightPalette.bg2,\n        border: lightPalette.bg4,\n        panelBackground: lightPalette.white,\n        nodeColor: lightPalette.fg1,\n        nodeBgHover: lightPalette.bg3.fade(0.7),\n        nodeSelectedBg: lightPalette.bg3,\n        actionIcon: lightPalette.fg1,\n    },\n    secretServices: {\n        secretTagBg: lightPalette.grey0,\n        itemHover: lightPalette.bg3.fade(0.5),\n        rowBgColor: lightPalette.bg2,\n        color: lightPalette.fg1,\n    },\n\n    stripeService: {\n        background: lightPalette.bg2,\n        border: lightPalette.bg4,\n        panelBackground: lightPalette.white,\n        alert: {\n            backgroundColor: \"#ffd\",\n            borderColor: Color(\"#000\").alpha(0.2).toString(),\n        },\n        error: {\n            backgroundColor: lightPalette.danger.alpha(0.2).toString(),\n            color: lightPalette.fg1,\n        },\n    },\n\n    appSessions: {\n        color: lightPalette.fg1,\n        fontSize: \"1.4rem\",\n        gridRow: {\n            hover: Color(\"#eee\"),\n        },\n        oddRow: {\n            background: lightPalette.bg1,\n        },\n        errorRow: {\n            background: lightPalette.lightRed,\n            hover: lightPalette.greyRed,\n        },\n        sessionPill: {\n            background: lightPalette.bg2,\n        },\n        errorEvent: {\n            color: Color(\"#c7254e\"),\n        },\n        expandedRow: {\n            background: lightPalette.grey2,\n            color: lightPalette.white,\n        },\n    },\n\n    appListFilter: {\n        color: lightPalette.bg7,\n        border: lightPalette.bg5,\n        background: lightPalette.bg4,\n        hover: {\n            background: lightPalette.bg3,\n        },\n        active: {\n            background: lightPalette.primary,\n            color: lightPalette.white,\n        },\n    },\n\n    loading: {\n        background: lightPalette.bg4,\n    },\n\n    disableDeleteApp: {\n        color: lightPalette.bg6.lighten(0.6).toString(),\n    },\n\n    historyPanel: {\n        commit: {\n            hoverBg: Color(\"#EEEEEE\"),\n        },\n        headCommit: {\n            background: lightPalette.primary,\n        },\n        selectedCommit: {\n            background: lightPalette.bg1,\n            hoverBg: lightPalette.bg1.darken(0.05),\n        },\n    },\n\n    liveOutput: {\n        serverBorder: lightPalette.secondary,\n        clientBorder: lightPalette.primary,\n        codeColor: Color(\"#c7254e\"),\n        codeHighlightBg: Color(\"#f9f2f4\"),\n        alert: {\n            color: Color(\"#c7254e\"),\n            bgColor: Color(\"#f2dede\"),\n            border: Color(\"#ebccd1\"),\n            warningBg: Color(\"#fcf8e3\"),\n            warningBorder: Color(\"#faebcc\"),\n        },\n        link: {\n            color: Color(\"#337ab7\"),\n        },\n        sessionOutputBg: lightPalette.primary.fade(0.9),\n    },\n\n    stripeBox: {\n        color: lightPalette.grey2,\n        placeholder: lightPalette.bg5,\n    },\n    deleteLink: {\n        color: lightPalette.danger,\n        hoverColor: lightPalette.danger.darken(0.3),\n    },\n    codeSnippets: {\n        color: lightPalette.grey2,\n        background: lightPalette.bg2,\n        border: lightPalette.bg4,\n        shield: Color(\"#000000\"),\n        tab: {\n            color: lightPalette.bg7,\n            background: lightPalette.bg4,\n            hoverBackground: lightPalette.bg5,\n            activeBackground: lightPalette.bg6,\n        },\n        docLinkIcon: {\n            background: lightPalette.bg4,\n            fill: lightPalette.bg6,\n        },\n        components: {\n            background: lightPalette.white,\n            backgroundExpanded: lightPalette.bg2,\n            labelColor: Color(\"#000000\"),\n            iconBg: lightPalette.primary.fade(0.9),\n        },\n        noComponents: {\n            color: lightPalette.grey1,\n            background: lightPalette.bg5.lighten(0.3),\n        },\n        property: {\n            color: lightPalette.bg7,\n            background: lightPalette.white,\n            unselectedBackground: lightPalette.bg2.fade(0.3),\n            docLinkIcon: lightPalette.grey0,\n            helpText: lightPalette.grey1,\n            descriptionText: Color(\"#000000\"),\n            exampleBackground: Color(\"#EEEEEE\"),\n            unselected: {\n                hoverBackground: lightPalette.bg2,\n                activeBackground: lightPalette.bg2.darken(0.03),\n            },\n        },\n    },\n\n    tooltip: {\n        background: \"rgba(17, 17, 17, .9)\",\n        color: lightPalette.white,\n        left: 'url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E\") no-repeat',\n        top: 'url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E\") no-repeat',\n        bottom: 'url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E\") no-repeat',\n        right: 'url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E\") no-repeat',\n    },\n\n    schema: {\n        tableBackgrounds: lightPalette.bg2.fade(0.2),\n        color: \"undefined\",\n        highlightDiff: lightPalette.primary.fade(0.65).desaturate(0.3),\n        highlightRow: lightPalette.primary.fade(0.92),\n    },\n\n    toggles: {\n        background: lightPalette.bg4,\n        color: lightPalette.bg7,\n        borderColor: lightPalette.bg5.darken(0.1),\n        selected: {\n            background: lightPalette.primary,\n            color: lightPalette.white,\n        },\n        hover: {\n            background: lightPalette.bg5,\n        },\n    },\n\n    managerPortal: {\n        rootBgColor: lightPalette.bg2,\n        separator: \"1px solid \" + lightPalette.bg4.toString(),\n        color: lightPalette.grey2,\n        bodyBackground: lightPalette.white,\n\n        navBar: {\n            background: lightPalette.bg2,\n            color: lightPalette.bg6,\n            tabBg: lightPalette.bg5,\n            hoverColor: lightPalette.grey2,\n            selected: {\n                background: lightPalette.white,\n                borderBottom: \"1px solid \" + lightPalette.white.toString(),\n                color: lightPalette.grey2,\n            },\n        },\n\n        listRow: {\n            highlightBg: lightPalette.bg2,\n            hover: lightPalette.bg3.fade(0.5),\n        },\n    },\n    chart: {\n        axis: {\n            legend: { text: { fill: lightPalette.fg1.toString() } },\n            ticks: { text: { fill: lightPalette.fg1.toString() } },\n        },\n        crosshair: { line: { stroke: lightPalette.fg1.toString(), strokeWidth: 2 } },\n    },\n\n    agentConversations: {\n        promptComposer: {\n            placeholderColor: lightPalette.bg7.alpha(0.5).toString(),\n        },\n    },\n};\n\nconst Dark = {\n    isDark: true,\n    palette: darkPalette,\n\n    sectionBorderColor: darkPalette.bg4,\n\n    primaryNav: {\n        iconSize: \"2.3rem\",\n        background: darkPalette.bg1,\n        defaultIconColor: darkPalette.bg4,\n        iconHoverBg: darkPalette.bg7,\n        iconHoverColor: darkPalette.bg1,\n        iconActiveBg: darkPalette.bg8,\n        iconActiveColor: darkPalette.bg1,\n        selectedIconColor: darkPalette.bg1,\n        selectedIconBg: darkPalette.white,\n        addButtonColor: darkPalette.white,\n        addButtonBg: darkPalette.primary,\n    },\n\n    secondaryNav: {\n        sectionHeader: {\n            color: darkPalette.fg3,\n            background: darkPalette.bg2,\n            fontWeight: 500,\n            //figure out what the next 2 do:\n            hoverColor: darkPalette.fg3,\n            hoverBg: lightPalette.bg4.alpha(0.5),\n            dotsColor: darkPalette.grey1,\n        },\n\n        background: darkPalette.bg2,\n        color: darkPalette.grey1,\n        iconColor: darkPalette.grey0,\n        icon1: { color: lightPalette.white, background: lightPalette.primary },\n        icon2: { color: lightPalette.white, background: lightPalette.secondary },\n        icon3: { color: lightPalette.white, background: lightPalette.tertiary },\n        icon4: { color: lightPalette.white, background: lightPalette.quaternary },\n        hoverBg: darkPalette.bg3.alpha(0.4),\n        //TODO:\n        hoverColor: darkPalette.fg3,\n        activeBg: darkPalette.bg3,\n        enabledChevron: darkPalette.grey0,\n        disabledChevron: darkPalette.grey2,\n        expandedChevron: darkPalette.grey0,\n        // hoverChevron: lightPalette.white,\n        dotsHoverBg: darkPalette.grey2,\n        dotsActiveBg: darkPalette.grey2,\n        folderLines: darkPalette.grey2,\n\n        selectedBg: darkPalette.bg3,\n        selectedColor: darkPalette.white,\n        selectedBgDotsHoverBg: darkPalette.bg6,\n        selectedBgDotsHoverColor: darkPalette.grey1,\n        selectedBgDotsActiveBg: darkPalette.bg6,\n        selectedBgDotsActiveColor: darkPalette.grey1,\n        alert: {\n            borderColor: darkPalette.bg8,\n            background: darkPalette.bg3.fade(0.3),\n            iconBarWidth: \"4rem\",\n            iconColor: darkPalette.white,\n        },\n    },\n\n    header: {\n        background: darkPalette.bg1,\n        // savedIconColor: lightPalette.highlight,\n        lightLink: {\n            color: darkPalette.grey1,\n            hoverColor: darkPalette.white,\n            fontWeight: 400,\n        },\n        heavyLink: {\n            color: darkPalette.grey0,\n            hoverColor: darkPalette.white,\n            fontWeight: 600,\n        },\n        userAccountBg: darkPalette.white,\n        userAccountColor: darkPalette.bg1,\n    },\n\n    button: {\n        borderRadius: 4,\n        background: darkPalette.bg3,\n        hoverBg: darkPalette.bg8,\n        activeBg: darkPalette.bg7,\n        color: darkPalette.fg3,\n        disabledColor: darkPalette.grey1,\n        iconColor: lightPalette.bg3,\n        //this doesn't actually control anything - border color is controlled by button.background\n        //not any more. Since pyspace, changed so that border is actually controlled by this again\n        border: darkPalette.bg3,\n\n        small: {\n            color: darkPalette.fg3,\n        },\n\n        tiny: {\n            color: darkPalette.fg3,\n        },\n\n        // highlight1: {\n        //     background: lightPalette.highlight,\n        //     color: lightPalette.white,\n        //     iconColor: lightPalette.white,\n        // },\n        //figure out where the next two are used:\n        highlight2: {\n            background: darkPalette.white,\n            color: darkPalette.bg1,\n            iconColor: darkPalette.bg1,\n        },\n        //this is the publish button - should it be different?\n        highlight3: {\n            background: darkPalette.bg3,\n            color: darkPalette.fg3,\n            iconColor: darkPalette.fg3,\n        },\n    },\n\n    buttonGroup: {\n        divider: darkPalette.bg8,\n    },\n\n    tabBar: {\n        background: darkPalette.bg2,\n        closeIconHoverColor: darkPalette.bg7,\n        activeTab: {\n            background: darkPalette.bg1,\n            //what does closeButton do? - apparently nothing. this should be fixed\n            closeButtonHover: darkPalette.fg3,\n            closeButton: darkPalette.bg8,\n            //what is bordertop? -nothing\n            // borderTop: lightPalette.white,\n            color: darkPalette.fg3,\n        },\n        inactiveTab: {\n            background: darkPalette.bg2,\n            closeButton: darkPalette.white,\n            //what does hoverBg do? -also nothing\n            // hoverBg: lightPalette.grey1,\n            color: darkPalette.grey1,\n            iconColor: darkPalette.bg7,\n        },\n        bottom: {\n            closedBarTab: {\n                background: darkPalette.bg1,\n                hoverBg: darkPalette.bg8,\n                activeBg: darkPalette.bg3,\n                color: darkPalette.fg3,\n            },\n            openBarInactiveTab: {\n                background: darkPalette.bg2,\n                //closeButton isn't used\n                closeButton: lightPalette.grey2,\n                hoverBg: darkPalette.bg8,\n                hoverColor: darkPalette.bg2,\n                iconHoverColor: darkPalette.bg2,\n                activeBg: darkPalette.bg3,\n                color: darkPalette.grey1,\n            },\n            openBarActiveTab: {\n                background: darkPalette.bg1,\n                //closeButton isn't used\n                closeButton: lightPalette.grey1,\n                borderTop: lightPalette.white,\n                color: darkPalette.fg3,\n            },\n        },\n    },\n    tabToolbar: {\n        background: darkPalette.bg1,\n    },\n    formInput: {\n        border: darkPalette.bg3,\n        color: darkPalette.fg3,\n        background: darkPalette.bg1,\n        placeholderColor: darkPalette.bg3,\n        smallPlaceholderColor: darkPalette.bg7,\n        //figure out what these do - dropdown for changing branches\n        smallBackground: darkPalette.bg8,\n        smallBorder: darkPalette.bg3,\n    },\n\n    form: {\n        checkbox: {\n            color: darkPalette.fg1,\n        },\n    },\n\n    text: {\n        h1: {\n            color: darkPalette.fg3,\n        },\n        h2: {\n            color: darkPalette.fg3,\n        },\n        h3: {\n            color: darkPalette.fg3,\n        },\n        p1: {\n            color: darkPalette.fg3,\n        },\n        p2: {\n            color: lightPalette.grey1,\n        },\n        p3: {\n            color: lightPalette.grey1,\n        },\n        //figure out when these are used\n        //used for app template title on start page:\n        dark: darkPalette.white,\n\n        light: lightPalette.grey1,\n        extraLight: lightPalette.grey0,\n    },\n\n    // table: {\n    //     header: {\n    //         fontSize: 12,\n    //         fontWeight: 600,\n    //     },\n    //     fontSize: 12,\n    //     fontWeight: 500,\n    //     verticalPadding: 15,\n    //     borderColor: lightPalette.bg5,\n    //     thickBorder: 4,\n    //     thinBorder: 2,\n    // },\n\n    settings: {\n        rightBarBackground: darkPalette.bg2,\n        separator: darkPalette.bg4,\n        background: darkPalette.bg1,\n    },\n\n    dropDownMenu: {\n        borderColor: darkPalette.bg3,\n        color: darkPalette.fg3,\n        background: darkPalette.bg1,\n        hoverBg: darkPalette.bg6,\n        //is activebg used?\n        activeBg: darkPalette.bg8,\n    },\n    modal: {\n        header: {\n            background: darkPalette.bg2,\n            hoverBg: darkPalette.bg3,\n            iconColor: darkPalette.fg3,\n        },\n        background: darkPalette.bg1,\n        color: darkPalette.fg3,\n        icon: darkPalette.fg3,\n        code: {\n            color: darkPalette.fg3,\n            background: darkPalette.bg3,\n            borderColor: darkPalette.bg4,\n        },\n        notification: {\n            headingColor: \"#121212\",\n            backgroundColor: \"#ffd\",\n            borderColor: Color(\"#000\").alpha(0.2).toString(),\n        },\n\n        planCard: {\n            color: darkPalette.fg1,\n            background: darkPalette.bg3,\n            borderTop: darkPalette.primary,\n            border: darkPalette.bg2,\n            featuresBorder: darkPalette.bg8,\n            featureBackground: darkPalette.bg6,\n            currentPlan: {\n                background: darkPalette.bg6,\n                featureBackground: darkPalette.bg2,\n            },\n        },\n        addMappingOrTable: {\n            noResults: {\n                color: darkPalette.grey1,\n                background: darkPalette.bg2.lighten(0.5),\n            },\n        },\n    },\n\n    accordion: {\n        header: {\n            background: darkPalette.bg2,\n            expandedBg: darkPalette.bg8,\n            hoverBg: darkPalette.bg3,\n            //figure out if this is used:\n            expandedHoverBg: lightPalette.bg4.darken(0.04),\n            chevronColor: darkPalette.grey1,\n            title: {\n                color: darkPalette.fg3,\n            },\n            subtitle: {\n                color: darkPalette.fg3,\n            },\n            actionLink: {\n                color: darkPalette.fg3,\n                hoverColor: darkPalette.fg1,\n            },\n            iconColor: darkPalette.grey2,\n            iconColorPresent: darkPalette.fg3,\n        },\n        children: {\n            color: darkPalette.bg3.lighten(0.95),\n            background: darkPalette.fg2,\n            hoverBackground: darkPalette.primary.fade(0.95),\n            selectedBg: darkPalette.primary.fade(0.85),\n        },\n    },\n\n    startPage: {\n        headerIconColor: lightPalette.primary,\n        background: darkPalette.bg1,\n        appCardBackground: darkPalette.bg3,\n        appCardSubtitleColor: darkPalette.fg3,\n        carouselNavLink: {\n            //what is background for?\n            background: darkPalette.bg8,\n            enabledBg: darkPalette.bg8,\n            disabledBg: darkPalette.bg3,\n            enabledColor: darkPalette.white,\n            //misleadingly, this is hover color\n            activeColor: darkPalette.bg7,\n        },\n    },\n\n    tabBanner: {\n        background: \"white\",\n        textAlign: \"center\",\n        borderBottom: \"1px solid \" + Color(\"#000\").alpha(0.2).toString(),\n    },\n\n    versionHistory: {\n        branch: {\n            color: darkPalette.fg3,\n            background: darkPalette.bg8,\n            border: darkPalette.bg3,\n        },\n        currentBranch: {\n            border: lightPalette.fg1,\n        },\n    },\n\n    roles: {\n        color: darkPalette.white,\n        highlight: {\n            background: darkPalette.white,\n            border: darkPalette.bg3,\n            color: darkPalette.bg1,\n        },\n        editRole: {\n            color: darkPalette.fg3,\n            titleBackground: darkPalette.bg8,\n            background: darkPalette.bg2,\n            border: darkPalette.bg8,\n            codeColor: darkPalette.fg3,\n            component: {\n                background: darkPalette.bg3,\n                border: darkPalette.bg3,\n            },\n        },\n    },\n\n    colourScheme: {\n        dropdown: {\n            background: darkPalette.bg1,\n            border: darkPalette.bg7,\n            itemHover: darkPalette.bg7,\n            itemBorder: darkPalette.bg1,\n        },\n        color: darkPalette.fg3,\n    },\n\n    noServiceSplashPage: {\n        color: darkPalette.grey1,\n        background: darkPalette.bg2.lighten(0.5),\n        border: darkPalette.bg4,\n    },\n\n    userService: {\n        color: darkPalette.fg3,\n        sampleCode: {\n            background: darkPalette.bg3,\n            color: darkPalette.fg3,\n            borderColor: darkPalette.bg4,\n        },\n    },\n\n    emailService: {\n        color: darkPalette.fg1,\n        alert: {\n            backgroundColor: \"#ffd\",\n            borderColor: Color(\"#000\").alpha(0.2).toString(),\n        },\n        separator: darkPalette.bg4,\n    },\n\n    googleService: {\n        background: darkPalette.bg2,\n        fileRowBg: darkPalette.bg8,\n        pythonNameBg: darkPalette.bg3.fade(0.3),\n        color: darkPalette.fg1,\n        modal: {\n            rowHoverBg: darkPalette.bg8,\n            rowSelectBg: darkPalette.bg6,\n            emptyNotice: darkPalette.bg2.lighten(0.5),\n            emptyTextColor: darkPalette.grey1,\n        },\n    },\n\n    scheduledTasks: {\n        color: darkPalette.fg3,\n        border: darkPalette.bg4,\n        item: {\n            hoverBackground: darkPalette.bg3,\n            activeBackground: darkPalette.bg8,\n        },\n    },\n\n    backgroundTasks: {\n        color: darkPalette.fg3,\n        border: darkPalette.bg4,\n        code: {\n            color: darkPalette.fg3,\n            border: darkPalette.bg4,\n            background: darkPalette.bg3,\n        },\n    },\n\n    facebookService: {\n        background: darkPalette.bg2,\n        border: darkPalette.bg4,\n        panelBackground: darkPalette.bg1,\n    },\n\n    dataFileService: {\n        background: darkPalette.bg2,\n        border: darkPalette.bg4,\n        panelBackground: darkPalette.bg1,\n        nodeColor: darkPalette.fg1.fade(0.2),\n        nodeBgHover: darkPalette.bg3.fade(0.7),\n        nodeSelectedBg: darkPalette.bg3,\n        actionIcon: darkPalette.fg1.fade(0.2),\n    },\n\n    secretServices: {\n        secretTagBg: darkPalette.grey0,\n        itemHover: darkPalette.bg8,\n        rowBgColor: darkPalette.bg6,\n        color: darkPalette.fg2,\n    },\n\n    stripeService: {\n        background: darkPalette.bg2,\n        border: darkPalette.bg4,\n        panelBackground: darkPalette.bg1,\n        alert: {\n            backgroundColor: \"#ffd\",\n            borderColor: Color(\"#000\").alpha(0.2).toString(),\n        },\n        error: {\n            backgroundColor: darkPalette.danger.desaturate(0.3).toString(),\n            color: darkPalette.fg1,\n        },\n    },\n\n    appSessions: {\n        color: darkPalette.fg3,\n        gridRow: {\n            hover: darkPalette.grey2,\n        },\n        oddRow: {\n            background: darkPalette.bg2,\n        },\n        errorRow: {\n            background: Color(\"#895260\"),\n            hover: darkPalette.greyRed,\n        },\n        sessionPill: {\n            background: darkPalette.bg3,\n        },\n        errorEvent: {\n            color: Color(\"#CF5877\"),\n        },\n        expandedRow: {\n            background: darkPalette.bg8.lighten(0.6),\n            color: darkPalette.bg2,\n        },\n    },\n\n    loading: {\n        background: darkPalette.bg8,\n    },\n\n    appListFilter: {\n        color: darkPalette.fg1,\n        border: darkPalette.bg7,\n        background: darkPalette.bg3,\n        hover: {\n            background: darkPalette.bg4,\n        },\n        active: {\n            background: lightPalette.primary,\n            color: lightPalette.white,\n        },\n    },\n    toggles: {\n        background: darkPalette.bg3,\n        color: darkPalette.fg3,\n        borderColor: darkPalette.bg4,\n        selected: {\n            background: darkPalette.primary,\n            color: darkPalette.white,\n        },\n        hover: {\n            background: darkPalette.bg4,\n        },\n    },\n\n    disableDeleteApp: {\n        color: darkPalette.bg3.darken(0.1),\n    },\n\n    historyPanel: {\n        commit: {\n            hoverBg: darkPalette.grey2.darken(0.4),\n        },\n        headCommit: {\n            background: darkPalette.primary,\n        },\n        selectedCommit: {\n            background: darkPalette.bg1.darken(1),\n            hoverBg: darkPalette.bg1,\n        },\n    },\n\n    liveOutput: {},\n\n    stripeBox: {\n        color: darkPalette.fg3,\n        placeholder: darkPalette.bg3,\n    },\n    deleteLink: {\n        color: darkPalette.danger,\n        hoverColor: darkPalette.danger.darken(0.3),\n    },\n    codeSnippets: {\n        color: darkPalette.fg1,\n        background: darkPalette.bg0,\n        border: darkPalette.bg4,\n        shield: Color(\"#555555\"),\n        tab: {\n            color: darkPalette.fg1,\n            background: darkPalette.bg3,\n            hoverBackground: darkPalette.bg3,\n            activeBackground: darkPalette.bg6,\n        },\n        docLinkIcon: {\n            background: darkPalette.fg3,\n            fill: darkPalette.fg3,\n        },\n        components: {\n            background: darkPalette.fg2,\n            backgroundExpanded: darkPalette.bg0,\n            labelColor: darkPalette.fg1,\n            iconBg: darkPalette.bg7.fade(0.6),\n        },\n        noComponents: {\n            color: darkPalette.grey1,\n            background: darkPalette.bg2.lighten(0.5),\n        },\n        property: {\n            color: darkPalette.bg3.lighten(0.95),\n            background: darkPalette.fg2,\n            unselectedBackground: darkPalette.bg1,\n            docLinkIcon: darkPalette.grey0,\n            helpText: darkPalette.fg1,\n            descriptionText: darkPalette.fg1,\n            exampleBackground: darkPalette.bg6,\n            unselected: {\n                hoverBackground: darkPalette.primary.fade(0.8),\n                activeBackground: darkPalette.primary.fade(0.75),\n            },\n        },\n    },\n    tooltip: {\n        background: \"rgba(226, 226, 226, .9)\",\n        color: darkPalette.bg2,\n        left: 'url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%28226,%20226,%20226,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E\") no-repeat',\n        top: 'url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%28226,%20226,%20226,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E\") no-repeat',\n        bottom: 'url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%28226,%20226,%20226,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E\") no-repeat',\n        right: 'url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%28226,%20226,%20226,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E\") no-repeat',\n    },\n\n    schema: {\n        tableBackgrounds: darkPalette.bg2.lighten(0.4),\n        color: darkPalette.fg3,\n        highlightDiff: darkPalette.lightRed,\n        highlightRow: darkPalette.greyRed.fade(0.5),\n    },\n\n    managerPortal: {\n        rootBgColor: darkPalette.fg2,\n        separator: \"1px solid \" + darkPalette.bg4.toString(),\n        color: darkPalette.fg1,\n        bodyBackground: darkPalette.bg0,\n\n        navBar: {\n            background: darkPalette.bg0,\n            color: lightPalette.grey1,\n            tabBg: darkPalette.bg6,\n            hoverColor: darkPalette.fg1,\n            selected: {\n                background: darkPalette.bg0,\n                borderBottom: \"1px solid \" + darkPalette.bg4.toString(),\n                color: darkPalette.fg1,\n            },\n        },\n\n        listRow: {\n            highlightBg: darkPalette.bg6,\n            hover: darkPalette.bg8,\n        },\n    },\n    chart: {\n        axis: {\n            legend: { text: { fill: darkPalette.fg1.toString() } },\n            ticks: { text: { fill: darkPalette.fg1.toString() } },\n        },\n        crosshair: { line: { stroke: \"#FFFFFF\", strokeWidth: 2 } },\n    },\n\n    agentConversations: {\n        promptComposer: {\n            placeholderColor: darkPalette.white.alpha(0.5).toString(),\n        },\n    },\n};\n\nconst Light = {\n    palette: lightPalette,\n    isDark: false,\n    bg0: Color(\"#fcfcfc\"),\n    bg1: Color(\"#F4F4F4\"),\n    bg2: Color(\"#EDEDED\"),\n    bg3: Color(\"#ffffff\"),\n    fg1: Color(\"#515151\"),\n};\n\nexport const LightTheme = merge({}, Base, Light, { isPySpace: false });\nexport const DarkTheme = merge({}, Base, Dark, { isPySpace: false });\n\n// Todo: put PySpace theme things maybe in a better place\nconst PySpaceLight = {\n    isPySpace: true,\n    isDark: false,\n    modal: {\n        borderRadius: \"4px\",\n        border: `2px solid ${lightPalette.grey2}`,\n        boxShadow: `2px 2px 0px ${lightPalette.grey2}`,\n        header: {\n            background: \"transparent\", //\n            hoverBg: \"transparent\", //\n            height: \"unset\", //\n            fontSize: \"2.4rem\", //\n            fontWeight: 600, //\n            iconColor: lightPalette.bg6, //\n            margin: \"unset\",\n            closeHover: lightPalette.grey2,\n        },\n        footer: {\n            padding: \"2px\",\n        },\n        background: lightPalette.bg2, //\n        color: lightPalette.grey2, //\n    },\n    formInput: {\n        height: \"unset\",\n        padding: \"0.2rem 0.8rem\",\n        border: lightPalette.grey2,\n        color: lightPalette.grey2,\n        background: lightPalette.white,\n        placeholderColor: lightPalette.grey1,\n        smallBackground: lightPalette.bg0,\n        smallBorder: lightPalette.grey2,\n        smallPadding: \"0.8rem\",\n        focusOutline: \"2px solid transparent\",\n        focusOffset: \"2px\",\n    },\n    inputLabel: {\n        fontSize: \"1.4rem\",\n        lightHeight: \"normal\",\n        fontWeight: 600,\n        color: lightPalette.grey2,\n        marginBottom: \".4rem\",\n        subtitle: {\n            fontSize: \"1.4rem\",\n            lightHeight: \"normal\",\n            fontWeight: 400,\n            color: lightPalette.grey2,\n            marginBottom: \".2rem\",\n        },\n    },\n    dropDownMenu: {\n        fontWeight: 400,\n        fontSize: \"1.6rem\",\n        iconFontSize: \"1.3rem\",\n        background: lightPalette.bg2,\n        borderRadius: 4,\n        borderWidth: 2,\n        borderColor: lightPalette.grey2,\n        shadow: \"4px 4px 0px 0px #444444\",\n        padding: 0,\n        itemPadding: \"7.5px 15px\",\n        firstItemPaddingTop: 12,\n        lastItemPaddingBottom: 10,\n        separatorMargin: \"2px 0px\",\n        separatorWidth: 2,\n    },\n    resizePanel: {\n        handleColor: lightPalette.grey2,\n    },\n    button: {\n        background: lightPalette.bg6,\n        hoverBg: \"\",\n        activeBg: \"\",\n        color: lightPalette.bg0,\n        disabledColor: lightPalette.bg1,\n        iconColor: lightPalette.bg0,\n        fontSize: \"2rem\",\n        fontWeight: 400,\n        height: \"5rem\",\n        padding: \"1rem 1.4rem\",\n        border: lightPalette.grey2,\n        disabled: {\n            background: Color(\"#BBB\"),\n            border: lightPalette.grey1,\n        },\n        tiny: {\n            height: \"1.8rem\",\n            padding: \"0.3rem\",\n            fontWeight: 400,\n            color: lightPalette.bg0,\n        },\n        small: {\n            height: \"2.8rem\",\n            padding: \"0.6rem\",\n            fontWeight: 400,\n            color: lightPalette.bg0,\n        },\n        hidden: {\n            color: lightPalette.grey2,\n            background: lightPalette.bg5,\n            boxShadow: \"none\",\n            hoverTransform: \"translate(0)\",\n            hoverBg: lightPalette.bg3,\n            activeBg: lightPalette.bg5,\n        },\n        large: {\n            fontSize: \"2.2rem\",\n            height: \"5rem\",\n            padding: \"1rem\",\n            fontWeight: 600,\n            color: lightPalette.bg0,\n        },\n        primary: {\n            color: lightPalette.bg0,\n            iconColor: lightPalette.bg0,\n        },\n        secondary: {\n            color: lightPalette.bg0,\n            iconColor: lightPalette.bg0,\n        },\n        tertiary: {\n            color: lightPalette.bg0,\n            iconColor: lightPalette.bg0,\n        },\n        danger: {\n            color: lightPalette.bg0,\n            iconColor: lightPalette.bg0,\n        },\n        highlight1: {\n            color: lightPalette.bg0,\n            iconColor: lightPalette.bg0,\n        },\n        highlight2: {\n            color: lightPalette.bg0,\n            iconColor: lightPalette.bg0,\n        },\n        highlight3: {\n            background: lightPalette.bg3,\n            color: lightPalette.grey2,\n            iconColor: lightPalette.grey2,\n        },\n    },\n\n    buttonGroup: {\n        display: \"flex\",\n        divider: lightPalette.grey2,\n        firstBorderRadius: \"2.8rem 0 0 2.8rem !important\",\n        firstBorder: `2px solid ${lightPalette.grey2.toString()}`,\n        lastBorderRadius: \"0 2.8rem 2.8rem 0 !important\",\n        marginLeft: \"-2px\",\n    },\n\n    dropDown: {\n        height: \"5rem\",\n        padding: \"0.2rem 1.4rem\",\n        fontSize: \"1.2rem\",\n        color: lightPalette.grey2,\n        fontWeight: 400,\n\n        chevron: {\n            right: \"1.4rem\",\n            fontWeight: 900,\n            fontSize: \"1.6rem\",\n            color: lightPalette.grey2,\n        },\n        small: {\n            padding: \"0.2rem 0.8rem\",\n\n            height: \"3.4rem\",\n            chevron: {\n                right: \".8rem\",\n                fontSize: \"1.4rem\",\n            },\n        },\n    },\n};\nconst PySpaceDark = { isPySpace: true, isDark: true };\n\nexport const PySpaceLightTheme = merge({}, Base, Light, PySpaceLight);\nexport const PySpaceDarkTheme = merge({}, Base, Dark, PySpaceLight, PySpaceDark);\n\ntype PySpaceTheme = typeof PySpaceDarkTheme | typeof PySpaceLightTheme;\n\nexport type IDETheme = typeof LightTheme | typeof DarkTheme | PySpaceTheme;\n","export const ignoreSsrWarning =\n    \"/* emotion-disable-server-rendering-unsafe-selector-warning-please-do-not-use-this-the-warning-exists-for-a-reason */\";\n","import type * as clientTypes from \"@runtime/runner/data\";\nimport { CodeNavTarget } from \"@/router/navTypes\";\nimport type { AppConflicts } from \"./app\";\n\nexport type CacheKey = number;\nexport type Cache = Record<CacheKey, CodeItem>;\n\nexport type AssetPath = `assets/${string}`;\nexport type FormPath = `forms/${string}`;\nexport type ModulePath = `modules/${string}`;\nexport type ServerPath = `server_modules/${string}`;\nexport type ScriptPath = `scripts/${string}`;\nexport type CodePath = AssetPath | FormPath | ModulePath | ServerPath | ScriptPath;\nexport type ExtraFilePath = `extra_files/${string}`;\nexport type EditorPath = CodePath | ExtraFilePath;\nexport type CodeItemType = \"form\" | \"module\" | \"server_module\" | \"script\" | \"asset\";\nexport type CodeStructureType = CodeItemType | \"folder\" | \"extra_file\";\nexport type ConflictType = \"client_code\" | \"server_code\" | \"script\" | \"asset\";\n\nexport const isCodePath = (path: EditorPath): path is CodePath => !path.startsWith(\"extra_files/\");\n\ntype AltState = \"A\" | \"B\" | \"E\"; // \"O\"\n\ntype Alt = {\n    s: AltState; // state\n    l: number; // line - zero based\n    n: number; // num lines\n};\n\ninterface TextChunk {\n    alternatives: [Alt, Alt];\n    start: number;\n}\n\nexport type ConflictItemIdentifier = string | string[];\nexport type ConflictItemSpec = [string, ConflictItemIdentifier];\n\nexport interface Conflicts {\n    item?: ConflictItemSpec;\n    text_chunks?: TextChunk[];\n    components?: unknown[];\n    edits?: unknown[];\n    binary?: boolean;\n    edit_delete?: { deleted_by: \"A\" | \"B\" };\n    // some other things\n}\n\nexport interface RootStructure<T extends FileTreeItem = StructureItem> {\n    name: string;\n    root: true;\n    children: T[];\n}\n\nexport interface FileTreeItem {\n    codePath?: EditorPath;\n    customComponent?: boolean;\n    toolboxItem?: clientTypes.FormYaml[\"toolbox_item\"];\n    layoutMetadata?: clientTypes.FormYaml[\"layout_metadata\"];\n    helpText?: clientTypes.FormYaml[\"help_text\"];\n    isLayout?: boolean;\n    fullName: string;\n    id?: string;\n    isPackage?: boolean;\n    name: string;\n    type: CodeStructureType;\n    // url: string;\n    // redirectLinkUrl?: string;\n    // redirectLinkUrlV3?: string;\n    inPlaceEdit?: CodeNavTarget;\n    inPlaceEditV3?: CodeNavTarget;\n    children?: FileTreeItem[];\n    defaultExpanded?: boolean; //Used until the user explicitly expands or collapses this node.\n}\n\nexport interface StructureItem extends FileTreeItem {\n    type: Exclude<CodeStructureType, \"extra_file\">;\n    codePath: CodePath;\n    children?: StructureItem[];\n}\n\nexport interface ExtraFileStructureItem extends FileTreeItem {\n    type: \"extra_file\" | \"folder\";\n    codePath?: ExtraFilePath;\n    children?: ExtraFileStructureItem[];\n}\n\nexport type HistoryState = {\n    hash: number;\n    selection: { main: number; ranges: [{ anchor: number; head: number }] }; // since we don't have multiselect ranges is of length 1.\n    // Keep CodeMirror's live history: its JSON representation omits state effects.\n    history: unknown;\n    renameBoundaries?: ReadonlySet<number>;\n    folding?: number[];\n};\n\nexport type FormDesignItem = Omit<FormItemYaml, \"code\">;\n\nexport type EditHistory = {\n    code?: HistoryState;\n    design?: {\n        done: FormDesignItem[];\n        undone: FormDesignItem[];\n        renameBoundaries?: { done: Record<number, number>; undone: Record<number, number> };\n    };\n    html?: HistoryState;\n    htmlProperty?: HistoryState;\n    // Extra files have no item cache. Retain the merge context so undo can\n    // reopen a resolved file while its pending merge is still being edited.\n    resolvedConflictMerge?: AppConflicts[\"merge\"];\n};\n\nexport interface CodeItemBase {\n    conflicts?: Conflicts;\n    resolvedConflictItem?: ConflictItemSpec;\n    resolvedConflictMerge?: AppConflicts[\"merge\"];\n    // editHistory?: EditHistory;\n    deleted?: boolean;\n    renamed?: boolean;\n    redirect?: string;\n}\n\nexport interface FormItem extends CodeItemBase {\n    itemType: \"form\";\n    item: FormItemYaml;\n}\n\nexport interface AssetItem extends CodeItemBase {\n    itemType: \"asset\";\n    item: AssetItemYaml;\n}\n\nexport interface ModuleItem extends CodeItemBase {\n    itemType: \"module\";\n    item: ModuleItemYaml;\n}\n\nexport interface ServerItem extends CodeItemBase {\n    itemType: \"server_module\";\n    item: ServerItemYaml;\n}\n\nexport interface ScriptItem extends CodeItemBase {\n    itemType: \"script\";\n    item: ScriptItemYaml;\n}\n\nexport type CodeItem = FormItem | ModuleItem | ServerItem | ScriptItem | AssetItem;\n\n/** Basically just the runtime equivalent but with an id */\nexport interface CodeItemYamlBase {\n    code?: string;\n    id?: string;\n    is_package?: boolean;\n    name?: string;\n    class_name?: string; // allows us to do .class_name || .name\n}\n\nexport interface FormItemYaml extends CodeItemYamlBase, clientTypes.FormYaml {\n    id: string;\n    code: string;\n    class_name: string;\n    edit_as_html?: boolean; // In-memory-only flag for editing forms as HTML without conversion\n}\n\nexport interface ModuleItemYaml extends CodeItemYamlBase, clientTypes.ModuleYaml {\n    id: string;\n    name: string;\n    code: string;\n}\n\nexport interface ServerItemYaml extends CodeItemYamlBase, clientTypes.ModuleYaml {\n    id: string;\n    name: string;\n    code: string;\n}\n\nexport interface ScriptItemYaml extends CodeItemYamlBase, clientTypes.ModuleYaml {\n    id: string;\n    name: string;\n    code: string;\n}\n\nexport interface AssetItemYaml extends CodeItemYamlBase {\n    id: string;\n    name: string;\n    content: string;\n}\n\nexport type CodeItemYaml<T = any> = T extends \"form\"\n    ? FormItemYaml\n    : T extends \"asset\"\n      ? AssetItemYaml\n      : T extends \"module\"\n        ? ModuleItemYaml\n        : T extends \"script\"\n          ? ScriptItemYaml\n          : T extends \"server_module\"\n            ? ServerItemYaml\n            : FormItemYaml | AssetItemYaml | ModuleItemYaml | ServerItemYaml | ScriptItemYaml;\n\nexport interface CodeState {\n    itemCache: Record<string, number>;\n    editHistory: Record<string, EditHistory>;\n}\n","import { ConnectedProps } from \"react-redux\";\nimport { ThunkAction, ThunkDispatch } from \"redux-thunk\";\nimport { BaseAction } from \"@/actions\";\nimport { AgentChatsLocation, ConversationPid } from \"@/agent/types.ts\";\nimport { DesignerState } from \"@/controllers/designer\";\nimport type { ServerTestSessionLog } from \"@/controllers/server-test-logs\";\nimport type { TestRunOptions, TestRunTracker } from \"@/controllers/server-test-runs\";\nimport { GadgetState } from \"@/pyspace/gadget_editor/store/gadget-store\";\nimport { FullNavTarget } from \"@/router/navTypes\";\nimport { StoreID } from \"@/router/navigation\";\nimport { ModalState } from \"@/store/modal-store\";\nimport { DebuggerHyperStack } from \"@/types/debugger\";\nimport { AppId, AppState } from \"./app\";\nimport { AppEnvironment } from \"./app-environment\";\nimport { GithubConnection } from \"./app-remotes\";\nimport { CodePath, CodeState, EditorPath } from \"./code\";\nimport type { DynamicDownlinkImageState } from \"./dynamic-downlinks\";\nimport { EditorSearchState } from \"./editor-search\";\nimport { Repl } from \"./repl\";\nimport { AppPath } from \"./saving\";\nimport { AvailableService, ServiceSpecs } from \"./services\";\nimport { Subscription } from \"./subscription\";\nimport { TabState } from \"./tabs\";\nimport { FeatureMap, User } from \"./user\";\n\nexport * from \"./app\";\nexport * from \"./app-environment\";\nexport * from \"./app-history\";\nexport * from \"./app-item\";\nexport * from \"./app-remotes\";\nexport * from \"./app-scheduled-tasks\";\nexport * from \"./app-theme-config\";\nexport * from \"./code\";\nexport * from \"./editor-search\";\nexport * from \"./repl\";\nexport * from \"./saving\";\nexport * from \"./services\";\nexport * from \"./subscription\";\nexport * from \"./tabs\";\nexport * from \"./database\";\nexport * from \"./dynamic-downlinks\";\nexport * from \"./sessions\";\nexport * from \"./record-types\";\nexport * from \"./user\";\n\nexport type ServerTestListFilter = \"all\" | \"latest_run\" | \"failed\";\n\nexport interface ServerTestPanelState {\n    selectedTestId: string | null;\n    keywordExpression: string;\n    clearedRunIds: Record<string, true>;\n    listFilter: ServerTestListFilter;\n}\n\nexport type ViewMode = \"design\" | \"code\" | \"html\" | \"htmlProperty\";\nexport const VIEW_MODES: readonly ViewMode[] = [\"design\", \"code\", \"html\", \"htmlProperty\"];\n\nexport type ViewValue = boolean | readonly [string] | readonly [string, string] | readonly [number, number];\n\nexport interface View {\n    design?: ViewValue;\n    code?: ViewValue;\n    html?: ViewValue;\n    htmlProperty?: ViewValue;\n}\n\nexport interface FullView extends View {\n    focus?: ViewMode;\n}\n\nexport interface RunnerOutput {\n    fromServer?: boolean;\n    text?: string;\n    fn?: \"clear\" | \"pythonError\" | \"bgTask\";\n    /** Only for fn === \"bgTask\": keys into state.runnerBgTasks */\n    sessionId?: string;\n}\n\nexport type RunMode = \"INLINE\" | \"NEWTAB\" | null;\n\nexport type RunnerConnectionState = \"connected\" | \"lost\" | \"none\" | \"session-reset\";\n\nexport interface DebugState {\n    runMode: RunMode;\n    sessionToken?: string | null;\n    sessionId: null | string;\n    runnerMaximised: boolean;\n    inMaximised?: boolean;\n    output: RunnerOutput[];\n    alreadyPromptedForUpgrade: boolean;\n    alreadyPromptedForFullDebuggerUpgrade: boolean;\n    runCommitId: string;\n    prevMode?: RunMode;\n    refresh?: null | number;\n    debuggerId: string | null;\n    /** Transport state of the runner's connection to the app server (\"session-reset\" is\n     *  transient and never stored - see runner-bg-tasks controller) */\n    connectionState?: Exclude<RunnerConnectionState, \"session-reset\">;\n}\n\n// TODO\n\ninterface BottomPanelTabTargetBase {}\n\nexport interface BottomPanelTabTargetRepl {\n    type: \"serverRepl\" | \"tableauRepl\" | \"runnerRepl\";\n    replId: string;\n}\n\nexport interface BottomPanelTabTargetScriptRun {\n    type: \"scriptRun\";\n    scriptName: string;\n}\n\nexport interface BottomPanelTabTargetAgent {\n    type: \"agent\";\n    conversationPid: ConversationPid;\n}\n\nexport interface BottomPanelTabTargetOther {\n    type:\n        | \"conflicts\"\n        | \"designerOutput\"\n        | \"versionHistory\"\n        | \"backgroundTasks\"\n        | \"appCta\"\n        | \"tutorial\"\n        | \"roadmap\"\n        | \"breakpoints\"\n        | \"introVideo\"\n        | \"talkToUs\"\n        | \"onboardingCta\"\n        | \"ideTutorial\"\n        | \"serverTests\";\n}\n\nexport interface BottomPanelTabTargetDebugger {\n    type: \"debugger\";\n    hyperstackId: string;\n}\n\nexport type BottomPanelTabTarget =\n    | BottomPanelTabTargetDebugger\n    | BottomPanelTabTargetRepl\n    | BottomPanelTabTargetScriptRun\n    | BottomPanelTabTargetAgent\n    | BottomPanelTabTargetOther;\n\ninterface BottomPanelTabBaseHeader extends BottomPanelTabTargetBase {\n    title: string;\n}\n\nexport interface BottomPanelReplHeader extends BottomPanelTabBaseHeader, BottomPanelTabTargetRepl {\n    repl: Repl;\n}\n\nexport interface BottomPanelScriptRunHeader extends BottomPanelTabBaseHeader, BottomPanelTabTargetScriptRun {}\n\nexport interface BottomPanelAgentHeader extends BottomPanelTabBaseHeader, BottomPanelTabTargetAgent {}\n\nexport interface BottomPanelDebuggerHeader extends BottomPanelTabBaseHeader, BottomPanelTabTargetDebugger {\n    subText: string;\n}\n\ninterface BottomPanelTabHeaderOther extends BottomPanelTabTargetOther, BottomPanelTabBaseHeader {}\n\nexport type BottomPanelTabHeader =\n    | BottomPanelTabHeaderOther\n    | BottomPanelReplHeader\n    | BottomPanelScriptRunHeader\n    | BottomPanelAgentHeader\n    | BottomPanelDebuggerHeader;\n\nexport interface ServerTestPanelState {\n    selectedTestId: string | null;\n    keywordExpression: string;\n    clearedRunIds: Record<string, true>;\n}\n\ninterface EditorState extends TabState {\n    dataTables: null | {\n        tables?: Record<\n            string,\n            {\n                tables?: Array<{\n                    id?: number;\n                    access?: { table_mapping_id?: number | null; table_mapping_name?: string };\n                }>;\n            }\n        >;\n    };\n    versionControl: {\n        ignoreDesyncs: Record<string, boolean>;\n    };\n    designer: DesignerState;\n    isDiffVisible?: boolean;\n    isFirstRun: boolean | null;\n    disableInlineRunnerSplitView: boolean;\n    bottomPanelHeight: number;\n    bottomPanelCurrentTab: BottomPanelTabTarget | null;\n    bottomPanelTabStack: BottomPanelTabTarget[];\n    bottomPanelCommitListDiffWidth: number;\n    bottomPanelServerTestListWidth: number;\n    bottomPanelConversationPids: ConversationPid[];\n    /** Transient (not persisted): set when the talk-to-us offer countdown runs out, so the\n     * memoised bottom-tab list re-evaluates and drops the tab at exactly the right moment. */\n    talkToUsOfferExpired: boolean;\n    /** Transient (not persisted): whether we've already auto-opened the talk-to-us tab. Must live\n     * here rather than in a ref, because BottomPanel remounts whenever the panel is opened or\n     * closed - a per-instance guard would re-fire and make the panel impossible to close. */\n    talkToUsOfferAutoOpened: boolean;\n    codeSnippetPanelWidth: number;\n    splitCodeEditorRatio: number;\n    splitRunnerWidth: string;\n    expandedTableMappings: Record<AppId, Record<string, boolean>>;\n    sequenceNumbers: Record<string, number>;\n    search: EditorSearchState;\n    selectedUplinkId?: AppEnvironment[\"env_id\"] | null;\n    selectedEnvironmentId?: AppEnvironment[\"env_id\"] | null;\n    zenMode: boolean;\n    agentChatsLocation: AgentChatsLocation;\n    isSidebarConversationActive: boolean;\n    lastTouchedConversationId: ConversationPid | null;\n    isCreatingConversation: boolean;\n    serverTestPanelStateByApp: Record<AppId, ServerTestPanelState>;\n\n    // [key: string]: any; // comment out when typing\n}\n\nexport interface CodeNavFileState {\n    expanded?: boolean;\n    standalone?: boolean;\n}\nexport type CodeNavTreeTypeState = Record<string, CodeNavFileState>;\nexport type TreeType = \"client\" | \"server\" | \"scripts\" | \"assets\" | \"serverTests\";\n\nexport type CodeNavState = Record<TreeType, CodeNavTreeTypeState>;\n\nexport interface NewFeatureReleased {\n    featureId: string;\n    title: string;\n    msgContent: string;\n    learnMore: { text: string; url?: string }[];\n}\n\nexport interface ScriptRun {\n    // Absent for the brief window between clicking Run and the RUN_SCRIPT RPC resolving -\n    // see the placeholder run created synchronously in the `runScript` thunk.\n    sessionId?: string;\n    taskId?: string;\n    session?: any;\n    state: \"LAUNCHING\" | \"RUNNING\" | \"TERMINATED\";\n    output: any[];\n    outputCleared?: boolean;\n}\n\n/** A background task launched from the current runner debug session, tracked live from\n *  watch-key-tagged log-firehose events forwarded by the runner. */\nexport interface RunnerBgTask {\n    sessionId: string;\n    /** From BG_TASK_LAUNCHED (may arrive before or after SESSION_START) */\n    taskId?: string;\n    /** Task name, \"task:\" prefix stripped */\n    name: string;\n    /** Raw SESSION_START event, for the log renderer */\n    session?: any;\n    /** KILLING = kill requested, awaiting any evidence it happened */\n    state: \"RUNNING\" | \"KILLING\" | \"TERMINATED\";\n    /** From background_task_ended data.status (eg \"completed\", \"threw ...\", \"killed\") */\n    finalStatus?: string;\n    /** Raw LOG_EVENTs */\n    output: any[];\n    startTime?: number;\n    /** Sticky: some streamed output was (or may have been) missed */\n    outputMayBeMissing?: boolean;\n}\n\nexport interface BaseState extends CodeState, ModalState {\n    ide: boolean;\n    ideMode: \"full\" | \"simple\";\n    storeId: StoreID;\n    user?: User;\n    organisation: ({ features?: FeatureMap } & Partial<{ licence_key: string; name: string; email: string }>) | null; // only valid in the manager app\n    editorType: \"ide\" | \"pyspace\";\n    editor: EditorState;\n    debug: DebugState;\n    app: AppState | null;\n    ssh: null | { keys?: string; $loading?: boolean; $loaded?: boolean };\n    docs: null | {\n        $loading?: boolean;\n        $loaded?: boolean;\n        [key: string]: unknown;\n    };\n    viewCache: Record<AppId, Record<EditorPath, FullView>>;\n    recentCodeItemCodePaths: CodePath[];\n    codeNavState: Record<AppId, CodeNavState>;\n    suppressReloadingOnBranchMove: number;\n    savingAppPaths: Record<number, AppPath[]>;\n    unsavedAppPaths: Record<string, true>; // JSON stringified app paths\n    unsaved: Record<string, string | null>;\n    repl: {\n        repls: Record<string, Repl>;\n        preserveLogs?: boolean;\n        prevServerReplHistory?: {\n            id: string;\n            historyStart: number;\n            history?: string[];\n        }[];\n    };\n    scriptRuns: Record<string, ScriptRun[]>;\n    /** run_id -> run, for the server test runs we know about in the current app */\n    serverTestRuns: Record<string, TestRunTracker>;\n    /** for tracking client-side \"run-requested\" state */\n    serverTestRunRequest: {\n        appId: AppId;\n        options: TestRunOptions;\n    } | null;\n    /** The runs in serverTestRuns, oldest first */\n    serverTestRunIds: string[];\n    /** session_id -> the App Log output of a server test run's task, as streamed to this IDE */\n    serverTestSessionLogs: Record<string, ServerTestSessionLog>;\n    runnerBgTasks: Record<string, RunnerBgTask>;\n    showGlobalLoadingIndicator?: React.ReactNode;\n    recentApps: AppId[];\n    currentNavTarget?: FullNavTarget;\n    navBlocks: Record<string, { onNavigateAnyway: null | (() => void) }>;\n    subscriptionPromise?: Promise<Subscription>;\n    subscription?: Subscription;\n    githubConnection: GithubConnection | null;\n    dynamicDownlinkStates: Record<string, DynamicDownlinkImageState>;\n    availableServices?: AvailableService[];\n    serviceSpecs?: ServiceSpecs;\n    invoices?: Record<string, string> | null;\n    hideBetaBanner: boolean;\n    loadVersionOnFocus?: boolean;\n}\n\nexport interface State extends BaseState {\n    user: User;\n    debuggerHyperStacks: { [id: string]: DebuggerHyperStack };\n    [key: string]: any; // comment out when typing\n}\n\nexport type WebsocketConnectionPhase = \"idle\" | \"connecting\" | \"connected\" | \"reconnecting\" | \"disconnected\";\n\nexport interface WebsocketConnectionState {\n    phase: WebsocketConnectionPhase;\n    retryAttempt: number;\n    retryScheduledInMs?: number;\n    nextRetryAt?: number;\n    restoredUntil?: number;\n    pausedByVisibility: boolean;\n    lastError?: string;\n}\n\nexport interface UpdateState<S = State, A = any> {\n    (description: string, updater: (state: State, ...args: A[]) => void, ...args: A[]): void;\n    (updater: (state: S, ...args: A[]) => void, ...args: A[]): void;\n    (description: string, ...args: A[]): void;\n}\n\nexport type { BaseAction } from \"@/actions\";\n\n/** If you need the return value you have to type it, it can't be inferred. unknown rather then any for stricter usage */\nexport type AnvilAction<R = unknown> = ThunkAction<R, State, UpdateState, BaseAction>;\nexport type AnvilAsyncAction<R = unknown> = AnvilAction<Promise<R>>;\n\nexport type AnvilDispatch = ThunkDispatch<State, UpdateState, BaseAction>;\n\nexport type AnvilConnectedProps<T> = ConnectedProps<T> & {\n    dispatch: AnvilDispatch;\n};\n\nexport type GadgetAction<R = unknown> = ThunkAction<R, GadgetState, UpdateState<GadgetState>, BaseAction>;\nexport type GadgetAsyncAction<R = unknown> = GadgetAction<Promise<R>>;\nexport type GadgetDispatch = ThunkDispatch<GadgetState, UpdateState<GadgetState>, BaseAction>;\n\nexport type GadgetConnectedProps<T> = ConnectedProps<T> & {\n    dispatch: GadgetDispatch;\n};\n","import { AgentTypeId } from \"@agent-host/rpc_types\";\nimport { AchievementId } from \"@platform-runner/instrumentation\";\nimport { AccountLimits } from \"@/components/modals/account/Quotas\";\nimport { SortArray } from \"@/controllers/db_new\";\nimport { AppTemplate } from \"@/data/appTemplates\";\nimport { UserProfile } from \"@/pyspace/common/types\";\nimport { AppId } from \"./app\";\nimport { TableId } from \"./database\";\n\nexport const USER_AB_FLAGS = {\n    tyAnalysis: \"ty-analysis\",\n    createEventHandlerWidget: \"2026-08-create-event-handler-widget\",\n    dockerExport: \"dockerExport\",\n    editHistory: \"editHistory\",\n    helpTabOnStartup: \"2023-05-show-help-tab\",\n    ideTutorial: \"2025-06-ide-tutorial\",\n    newThemes: \"newThemes\",\n    mobileIde: \"mobile-ide\",\n    onboardingSurvey: \"onboardingSurvey\",\n    whereToStartSurvey: \"2026-09-where-to-start-survey\",\n    previewRoadmap: \"previewRoadmap\",\n    recordSchemas: \"recordSchemas\",\n    showFacultyTheme: \"showFacultyTheme\",\n    showNewDesignerToNewUsers: \"2023-10-show-new-designer-to-new-users\",\n    showPimoroniTheme: \"showPimoroniTheme\",\n    signedUpViaPySpace: \"signedUpViaPySpace\",\n    themeSnarfer: \"themeSnarfer\",\n    tutorialsInIde: \"2024-12-11-tutorials-in-ide\",\n    videoIntro: \"2025-03-video-intro\",\n    getStartedRoadmap: \"2025-03-get-started-roadmap\",\n    aiFirstExperiment: \"2026-08-ai-first-experiment\",\n    guisAreDifferent: \"2026-08-guis-are-different\",\n    serverTests: \"serverTests\",\n    talkToUsBannerTest: \"2026-11-talk-to-us-banner\",\n} as const;\n\nexport type UserABFlagValue = boolean | string | null;\nexport type UserABFlags = Partial<Record<(typeof USER_AB_FLAGS)[keyof typeof USER_AB_FLAGS], UserABFlagValue>>;\nexport type UserABFlagName = keyof UserABFlags;\n\nexport type PaidPlan = \"personal\" | \"individual\" | \"business\" | \"production\" | \"dedicated\" | \"enterprise\";\nexport type UserPlan = \"free\" | PaidPlan;\n\nexport interface PythonImageLifecycle {\n    deprecated?: boolean;\n    end_of_life?: string;\n}\n\nexport interface PythonEnvironment extends PythonImageLifecycle {\n    base: string;\n    python_version?: string;\n    title: string;\n    migration_requirements?: string[];\n    available: boolean;\n    default: boolean;\n}\n\nexport type PythonEnvironmentCatalog = PythonEnvironment[];\n\nexport interface DeploymentPool {\n    dp_id: string;\n    info: { title: string } | null;\n}\n\nexport interface Feature {\n    active: true;\n    helpLink?: string;\n    name: string;\n    plan: UserPlan;\n    upgradePlan?: UserPlan; //If this feature should prompt to upgrade to a different plan than the feature plan, usually because the original plan is deprecated\n    trial: boolean;\n    canRunWithout?: boolean;\n}\n\nexport type FeatureMap = Record<string, Feature>;\n\nexport interface ServerRuntime {\n    available: boolean;\n    deprecated?: boolean;\n    description: string;\n    id: string;\n    name: string;\n    requested?: boolean;\n}\n\n/** Row in the Python version dropdown (legacy runtimes and/or dynamic downlink option). */\nexport type PythonVersionOption = Pick<ServerRuntime, \"id\" | \"name\" | \"description\"> & {\n    _dynamic?: boolean;\n};\n\ninterface UserServiceEmail {\n    html: string;\n    subject?: string;\n    subject_suffix?: string;\n}\n\ninterface DockerRegistry {\n    username: string;\n    password: string;\n    url: string;\n}\n\nexport type CtaKey = keyof NonNullable<User[\"uiPrefs\"][\"collapsedCTA\"]>;\n\ninterface UserUiPrefs {\n    scale: \"tiny\" | \"small\" | \"medium\" | \"large\" | \"huge\";\n    theme: \"light\" | \"dark\" | \"system\";\n    eslint: boolean;\n    keyBindings: \"vim\" | \"emacs\" | \"default\";\n    autoImport: 0 | 1;\n    tabSize: 2 | 4;\n    formatOnSave: boolean;\n    minimap: boolean;\n    pythonInlayHints: boolean;\n    defaultContainerRegistry: DockerRegistry;\n    defaultAppExportRepoPaths: Record<AppId, string>;\n    showHelpTabOnStartup: boolean;\n    appListSortPriority: \"name\" | \"last_updated\" | \"date\";\n    appListDisplayAscending: boolean;\n    appListPinFav: boolean;\n    appListOwnershipFilter: \"Shared\" | \"Mine\";\n    customExampleApps: AppTemplate[];\n    userServiceEmailEditor: \"RICH\" | \"HTML\";\n    tables: Record<TableId, { sort?: SortArray; hidden?: Record<string, boolean> }>;\n    appRunPaths?: Record<AppId, string>;\n    codeTemplates?: \"standard\" | \"minimal\";\n    collapsedCTA?: {\n        db?: boolean;\n        publish?: boolean;\n        email?: boolean;\n        users?: boolean;\n        bottomPanel?: boolean;\n        welcome?: boolean;\n    };\n    userWasShownIntroVideo: boolean;\n    userHasDismissedOnboardingCtaTab: boolean;\n    /**\n     * The user's where-to-start survey answer (see controllers/whereToStartTutorials). Takes\n     * precedence over the answer in `User.surveyResponses`.\n     */\n    \"2026-09-where-to-start-answer\"?: string;\n    /**\n     * Dated, temporary: the \"gift card for a feedback call\" offer (see controllers/talkToUsOffer).\n     * Records that they clicked through to Calendly - a click-through, not a confirmed booking.\n     */\n    \"2026-11-talk-to-us-opened-scheduling-link\"?: boolean;\n    tutorialAppId?: AppId;\n    userHasClosedFeedbackPromoBanner: boolean;\n    defaultAgent?: AgentTypeId;\n}\n\nexport interface SurveyResponse {\n    /** ISO timestamp */\n    time: string;\n    /** Keyed by question id. Single-select questions' answers look like `{ answer: \"...\" }`. */\n    answers: Record<string, unknown>;\n}\n\nexport interface DiscountOffer {\n    tier: string;\n    name: string;\n    code?: string;\n    /** Exactly one of discountPercent / discountAmount is ever set on a given offer. */\n    discountPercent?: number;\n    /** Minor currency units (pence/cents), matching Stripe's `amount_off`. */\n    discountAmount?: number;\n    /** 3-letter currency code, set whenever discountAmount is. */\n    discountCurrency?: string;\n    description: string;\n    \"coupon-campaign-dates\": {\n        end: string;\n        start: string;\n    };\n}\n\ninterface Achievement {\n    completed: string; // ISO date\n}\n\nexport interface User {\n    \"2fa\": { available: boolean; enabled: boolean };\n    $loaded: boolean;\n    $loading: boolean;\n    $promise: Promise<User>;\n    ab: UserABFlags;\n    achievements: Record<AchievementId, Achievement> | null;\n    activeBanner: string | null;\n    attribOffer: null;\n    closedNotices: Record<string, string | number>;\n    /** Ids of the surveys in `surveyResponses`. */\n    completedSurveys: string[];\n    currency: string | null;\n    /** Every survey the user has answered, keyed by survey id. */\n    surveyResponses: Record<string, SurveyResponse>;\n    /**\n     * Whether their talk-to-us-v2 survey answers (and email address) make them someone we'd like to\n     * talk to - see anvil.works.prospects/talk-to-us-v2-prospect? on the server. Gates the\n     * talk-to-us offer.\n     */\n    talkToUsProspect?: boolean;\n    currentOffers: {\n        active: any;\n        eligible: Record<string, DiscountOffer>;\n    };\n    python_environment_catalog?: PythonEnvironmentCatalog;\n    dynamicDownlinkBuildLimits: AccountLimits;\n    deploymentPools: null | DeploymentPool[];\n    name: string;\n    email: \"stu@anvil.works\";\n    features: FeatureMap;\n    has_dedicated_downlink_runner: boolean;\n    has_password: boolean;\n    ideConfig: {\n        onSite: boolean;\n        dynamicDownlinks: { id: string; name: string; description: string; _dynamic: true }[];\n        services: Record<string, boolean>;\n        externalSshPort: number;\n        dbUplinkHost?: string;\n        appUrls?: string[];\n        googleProjectNumber?: string;\n        googlePickerApiKey?: string;\n        customPackageInstallation: boolean;\n        githubUrl: string;\n        enableAccounting: boolean;\n        enableDbRestore?: boolean;\n        enableAgents?: boolean;\n        enabledAgentTypes?: AgentTypeId[];\n    };\n    id: string;\n    internal_tracing: boolean;\n    ipLocation: { country: { code: string; name: string }; currency: string; vat: number };\n    licence_warning: null;\n    mailingListSubscriptions: null | Record<string, unknown>;\n    old_ide_default?: boolean;\n    plan: { \"paid-plan\": PaidPlan | null; trial: boolean | null };\n    registrationDate: string;\n    roadmap: { enabled?: boolean; currentStep?: string; completed?: Record<string, string> };\n    runtimeTrialStart: number;\n    server_runtimes: ServerRuntime[];\n    tableau: boolean;\n    trial: {\n        plan: UserPlan;\n        startTimeMs: number;\n        startTime: string;\n        expires: string;\n        expired: boolean;\n    };\n    trialOrg: null;\n    uiPrefs: Partial<UserUiPrefs>;\n    username: string;\n    usersServiceEmails: {\n        token_login: UserServiceEmail;\n        mfa_reset: UserServiceEmail;\n        confirm_address: UserServiceEmail;\n        reset_password: UserServiceEmail;\n    };\n    passwordExpires?: number;\n    impersonator?: string;\n    readOnlyMode?: boolean;\n    profile: UserProfile;\n}\n","import { ExternalState, useExternalState } from \"./external-state\";\n\nexport const tabPanelRef = new ExternalState<React.MutableRefObject<HTMLDivElement | null>>({ current: null });\n\nexport function useTabPanelRef() {\n    const [ref] = useExternalState(tabPanelRef);\n    return ref;\n}\n","import { base64DecToArr, base64EncArr } from \"@runtime/lib/b64\";\n\n/** Decode asset content from base64 to string - use when you have a base64 string and want to decode it to a string\n * e.g. when working with an asset in code mirror\n */\nexport const decodeAssetContent = (content: string): string => {\n    return new TextDecoder(\"utf-8\").decode(base64DecToArr(content));\n};\n\n/** Encode asset content to base64 from string - use when you have a string and want to encode it to base64 */\nexport const encodeAssetContent = (content: string): string => {\n    const bytes = new TextEncoder().encode(content);\n    return base64EncArr(bytes);\n};\n","export interface AssetUpload {\n    file: File;\n    path: string;\n}\n\nexport function selectedAssetFiles(files: FileList | File[]): AssetUpload[] {\n    return Array.from(files, (file) => ({ file, path: file.webkitRelativePath || file.name }));\n}\n\nexport async function droppedAssetFiles(dataTransfer: DataTransfer): Promise<AssetUpload[]> {\n    // Capture entries and files before yielding: the browser protects the drag data after the drop event.\n    const items = Array.from(dataTransfer.items).filter((item) => item.kind === \"file\");\n    const roots = items.map((item) => ({ entry: item.webkitGetAsEntry?.(), file: item.getAsFile() }));\n    const fallback = selectedAssetFiles(dataTransfer.files);\n    const files: AssetUpload[] = [];\n    async function walk(entry: FileSystemEntry) {\n        if (entry.isFile) {\n            const file = await new Promise<File>((resolve, reject) =>\n                (entry as FileSystemFileEntry).file(resolve, reject)\n            );\n            files.push({ file, path: entry.fullPath.replace(/^\\//, \"\") });\n        } else if (entry.isDirectory) {\n            const reader = (entry as FileSystemDirectoryEntry).createReader();\n            // Directory readers return batches, not necessarily all children at once.\n            while (true) {\n                const children = await new Promise<FileSystemEntry[]>((resolve, reject) =>\n                    reader.readEntries(resolve, reject)\n                );\n                if (!children.length) break;\n                for (const child of children) await walk(child);\n            }\n        }\n    }\n    for (const { entry, file } of roots) {\n        if (entry) await walk(entry);\n        else if (file) files.push({ file, path: file.name });\n    }\n    return roots.length ? files : fallback;\n}\n\n// Asset paths may share directories, but a file cannot also be a directory.\nexport function findAssetPathConflict(paths: string[]): string | undefined {\n    const files = new Set(paths);\n    for (const path of files) {\n        let slash = path.indexOf(\"/\");\n        while (slash !== -1) {\n            const directory = path.slice(0, slash);\n            if (files.has(directory)) return directory;\n            slash = path.indexOf(\"/\", slash + 1);\n        }\n    }\n}\n","// keep this file separate for autocompleter web-worker to easily code split\n\nexport type Deferred<T> = {\n    promise: Promise<T>;\n    resolve: (value: T | PromiseLike<T>) => void;\n    reject: (reason?: any) => void;\n};\n\n// taken from rsvp.defer https://github.com/tildeio/rsvp.js/blob/master/lib/rsvp/defer.js\nfunction defer<T = any>() {\n    const deferred = { resolve: () => {}, reject: () => {} } as Partial<Deferred<T>>;\n\n    deferred.promise = new Promise<T>((resolve, reject) => {\n        deferred.resolve = resolve;\n        deferred.reject = reject;\n    });\n\n    return deferred as Deferred<T>;\n}\n\nexport default defer;\n","import type { DiscountOffer } from \"@/types/user\";\n\nexport const CURRENCY_SYMBOLS: Record<string, string> = { USD: \"$\", EUR: \"€\", GBP: \"£\" };\n\nexport interface ActiveTierOffers {\n    percentOffer?: DiscountOffer;\n    amountOffer?: DiscountOffer;\n}\n\n/** Minimal shape shared by `DiscountOffer` and `SubscriptionDiscount` (types/subscription.ts). */\nexport interface DiscountAmountFields {\n    discountPercent?: number;\n    discountAmount?: number;\n    discountCurrency?: string;\n    duration?: \"forever\" | \"once\" | \"repeating\";\n    end?: number | null;\n}\n\n/** discountAmount is in minor currency units (pence/cents). */\nexport const getDiscountedPrice = (basePrice: number, offer: DiscountAmountFields | null | undefined): number => {\n    if (!offer) return basePrice;\n    if (offer.discountAmount != null) {\n        return Math.max(0, basePrice - offer.discountAmount / 100);\n    }\n    if (offer.discountPercent != null) {\n        return basePrice * (1 - offer.discountPercent / 100);\n    }\n    return basePrice;\n};\n\n/** Stripe only sends `end` for a discount with a known expiry - a repeating discount still mid-run\n * has no `end` until its final period, so we fall back to duration-only wording in that case. */\nconst formatDiscountDuration = (offer: DiscountAmountFields): string => {\n    if (offer.end) {\n        const date = new Date(offer.end).toLocaleDateString(undefined, {\n            year: \"numeric\",\n            month: \"long\",\n            day: \"numeric\",\n        });\n        return `until ${date}`;\n    }\n    if (offer.duration === \"forever\") {\n        return \"for the life of this plan\";\n    }\n    if (offer.duration === \"once\") {\n        return \"on your next invoice\";\n    }\n    return \"\";\n};\n\nexport const formatDiscountLabel = (offer: DiscountAmountFields | null | undefined): string => {\n    if (!offer) return \"\";\n    let label;\n    if (offer.discountAmount != null) {\n        const symbol = (offer.discountCurrency && CURRENCY_SYMBOLS[offer.discountCurrency]) || \"\";\n        label = `${symbol}${(offer.discountAmount / 100).toFixed(0)} off`;\n    } else if (offer.discountPercent != null) {\n        label = `${offer.discountPercent}% off`;\n    } else {\n        return \"\";\n    }\n    const duration = formatDiscountDuration(offer);\n    return duration ? `${label}, ${duration}` : label;\n};\n\nconst keepBigger = (a: DiscountOffer | undefined, b: DiscountOffer | undefined): DiscountOffer | undefined => {\n    if (!a) return b;\n    if (!b) return a;\n    return (b.discountPercent ?? b.discountAmount ?? 0) > (a.discountPercent ?? a.discountAmount ?? 0) ? b : a;\n};\n\n/** Tier-scoping is independent of discount type, so a tier-scoped and an any-tier offer of the\n * same type can both be active for a plan at once - keep whichever is worth more. */\nexport const mergeTierOffers = (\n    tierScoped: ActiveTierOffers | null | undefined,\n    anyTier: ActiveTierOffers | null | undefined\n): ActiveTierOffers => ({\n    percentOffer: keepBigger(tierScoped?.percentOffer, anyTier?.percentOffer),\n    amountOffer: keepBigger(tierScoped?.amountOffer, anyTier?.amountOffer),\n});\n\n","import { useCallback, useEffect, useInsertionEffect, useMemo, useRef, useState } from \"react\";\nimport { useRemToPixels } from \"@/theme/ThemeProvider\";\nimport { useTheme } from \"@/theme/styles\";\nimport { ExternalStore, createExternalStoreHooks } from \"./external-store\";\nimport { useStateWithCustomUpdate } from \"./hooks\";\nimport useEffectEvent from \"./useEffectEvent\";\nimport useEvent from \"./useEventCallback\";\nimport { useLongPress } from \"./useLongPress\";\n\ntype DragType = string | symbol;\ntype Accept = DragType | DragType[];\n\nexport type MouseTouchEvent = TouchEvent | MouseEvent | React.TouchEvent | React.MouseEvent;\nexport type MouseEventOrTouch = Touch | MouseEvent | React.Touch | React.MouseEvent;\n\nexport const isTouchEvent = (e: any): e is TouchEvent | React.TouchEvent => !!e?.touches;\n\nexport const getMouseEventOrTouch = (e: MouseTouchEvent) => (isTouchEvent(e) ? e.touches[0] : e);\n\nexport const isMultiTouch = (e: MouseTouchEvent) => isTouchEvent(e) && e.touches && e.touches.length > 1;\n\nexport const ANY = Symbol(\"any\");\n\ninterface DropItem {\n    canDrop: (type: DragType, dragItem: any) => boolean;\n    onOverChange: (monitor: MonitorProps) => void;\n    onDrop?: (dragItem: any) => void;\n    onHover?: (dragItem: any, event: Touch | MouseEvent | React.Touch | React.MouseEvent) => void;\n    dropEffect?: string;\n}\n\nlet CURRENT_DROP_REF: null | React.MutableRefObject<DropItem | null> = null;\n\nconst useDragImage = (dragItem: any) => {\n    const dragImage = useMemo(() => {\n        const d = document.createElement(\"div\");\n        d.className = \"absolute top-0 left-0 z-999 rounded-md bg-primary px-3 py-0.5 text-white\";\n        return d;\n    }, []);\n\n    useEffect(() => {\n        dragImage.textContent = dragItem.name;\n    }, [dragItem.name]);\n\n    return dragImage;\n};\n\nconst useDragRef = (onDragStart: (e: MouseTouchEvent) => void) => {\n    const dragRef = useRef<null | HTMLElement>(null);\n    const { onTouchEnd, onTouchMove, onTouchStart } = useLongPress(onDragStart, { threshold: 250 });\n\n    const onCleanup = useEvent(() => {\n        const currentDragRef = dragRef.current;\n        if (!currentDragRef) return;\n        currentDragRef.removeEventListener(\"mousedown\", onDragStart);\n        currentDragRef.removeEventListener(\"touchstart\", onTouchStart);\n        currentDragRef.removeEventListener(\"touchend\", onTouchEnd);\n        currentDragRef.removeEventListener(\"touchmove\", onTouchMove);\n        currentDragRef.ondragstart = null;\n        delete currentDragRef.dataset.anvilDraggable;\n    });\n\n    const dragRefCallback: React.RefCallback<HTMLElement> = useEvent((ref) => {\n        // use a callback as a ref since the domNode might change during the lifecycle of this hook\n        // see issue #3019\n        // clean up\n        onCleanup();\n        dragRef.current = ref;\n        if (ref) {\n            ref.ondragstart = () => false;\n            ref.dataset.anvilDraggable = \"\";\n            ref.addEventListener(\"mousedown\", onDragStart);\n            ref.addEventListener(\"touchstart\", onTouchStart);\n            ref.addEventListener(\"touchend\", onTouchEnd);\n            ref.addEventListener(\"touchmove\", onTouchMove);\n        }\n    });\n\n    useEffect(() => onCleanup, []);\n\n    return [dragRef, dragRefCallback] as const;\n};\n\ninterface DragOptions {\n    item: any;\n    onDrag?: (dragItem: any) => void;\n    type: DragType;\n}\n\nfunction getInheritedBackgroundColor(el: HTMLElement) {\n    let currentEl: HTMLElement | null = el;\n    while (currentEl) {\n        const computedStyle = window.getComputedStyle(currentEl);\n        const bgColor = computedStyle.backgroundColor;\n\n        if (bgColor !== \"transparent\" && bgColor !== \"rgba(0, 0, 0, 0)\") {\n            return bgColor;\n        }\n\n        currentEl = currentEl.parentElement;\n    }\n\n    return \"\";\n}\n\nconst useDragImageFactory = (dragItem: any) => {\n    const previewRef = useRef<HTMLElement>(null!);\n    const previewRefCallback = useCallback((node: HTMLElement) => {\n        previewRef.current = node;\n    }, []);\n    const theme = useTheme();\n\n    const dragImage = useDragImage(dragItem);\n    const defaultRef = useRef(dragImage);\n    const dragImageRef = useRef(dragImage);\n    const generatePreview = useCallback(() => {\n        let dragImage;\n        if (previewRef.current) {\n            const preview = previewRef.current;\n            dragImage = document.createElement(\"div\");\n            dragImage.className = \"absolute top-0 left-0 z-999 rounded-md px-3 py-0.5 dark:text-white\";\n            dragImage.style.width = preview.clientWidth + 4 + \"px\";\n            dragImage.style.height = preview.clientHeight + 4 + \"px\";\n            dragImage.style.backgroundColor =\n                getInheritedBackgroundColor(preview) || theme.secondaryNav.background.toString();\n            dragImage.style.border = `1px solid ${theme.sectionBorderColor.toString()}`;\n            const image = preview.cloneNode(true) as HTMLElement;\n            image.style.pointerEvents = \"none\";\n            image.style.border = \"none\";\n            dragImage.append(image);\n        } else {\n            dragImage = defaultRef.current;\n        }\n        dragImageRef.current = dragImage;\n    }, []);\n\n    return [previewRefCallback, dragImageRef, generatePreview] as const;\n};\n\nconst INIT_GLOBAL_DRAGGING = {\n    isDragging: false,\n    dragPosition: { clientX: 0, clientY: 0 },\n};\n\nconst dragStore = new ExternalStore(INIT_GLOBAL_DRAGGING);\n\nconst { useStore: useDragStore } = createExternalStoreHooks(dragStore);\n\nexport const useDrag = ({ item: dragItem, onDrag, type }: DragOptions) => {\n    const isDraggingRef = useRef(false);\n    // we keep a ref to isDragging so that our mouseDown callback doesn't depend on it\n    // but we still want to trigger a render when isDragging changes\n    const [isDragging, setIsDragging] = useStateWithCustomUpdate(false, (val: boolean) => {\n        isDraggingRef.current = val;\n        dragStore.setState({ isDragging: val });\n        return val;\n    });\n\n    const [previewRef, dragImageRef, generatePreview] = useDragImageFactory(dragItem);\n\n    const onDragStart = useEvent((event: MouseTouchEvent) => {\n        if (isMultiTouch(event)) return;\n        generatePreview();\n        const d = dragImageRef.current;\n        const { clientX: initX, clientY: initY } = getMouseEventOrTouch(event);\n        const currentDragRef = dragRef.current;\n        const offsetWidth = currentDragRef?.offsetWidth;\n        const offsetHeight = currentDragRef?.offsetHeight;\n        const initOffsetX = offsetWidth != null ? offsetWidth / 2 : null;\n        const initOffsetY = offsetHeight != null ? offsetHeight / 2 : null;\n        CURRENT_DROP_REF = null;\n\n        const cancelDrag = () => {\n            setIsDragging(false);\n            d.remove();\n            document.removeEventListener(\"mousemove\", onDragMove);\n            document.removeEventListener(\"touchmove\", onDragMove);\n            document.removeEventListener(\"touchend\", cancelDrag);\n            document.removeEventListener(\"touchend\", onDragEnd);\n            document.removeEventListener(\"touchcancel\", cancelDrag);\n            document.removeEventListener(\"touchcancel\", onDragEndCancel);\n            CURRENT_DROP_REF = null;\n            d.onmouseup = null;\n            d.ontouchend = null;\n            d.ontouchcancel = null;\n            currentDragRef?.removeEventListener(\"mouseup\", cancelDrag);\n            currentDragRef?.removeEventListener(\"touchend\", cancelDrag);\n            currentDragRef?.removeEventListener(\"touchcancel\", cancelDrag);\n            currentDragRef?.removeEventListener(\"mouseleave\", startDrag);\n            currentDragRef?.removeEventListener(\"contextmenu\", cancelDrag);\n            currentDragRef?.removeEventListener(\"keydown\", keyDown);\n        };\n\n        const keyDown = (e: KeyboardEvent) => {\n            if (e.key === \"Escape\") {\n                onDragEndCancel(e);\n            }\n        };\n\n        const startDrag = () => {\n            setIsDragging(true);\n            document.body.appendChild(d);\n            onDrag?.(dragItem);\n            d.onmouseup = onDragEnd;\n            d.ontouchend = onDragEnd;\n            d.ontouchcancel = onDragEndCancel;\n            document.addEventListener(\"touchend\", onDragEnd);\n            document.addEventListener(\"touchcancel\", onDragEndCancel);\n            currentDragRef?.removeEventListener(\"mouseup\", cancelDrag);\n            currentDragRef?.removeEventListener(\"touchend\", cancelDrag);\n            currentDragRef?.removeEventListener(\"touchcancel\", cancelDrag);\n            currentDragRef?.removeEventListener(\"mouseleave\", startDrag);\n            currentDragRef?.removeEventListener(\"contextmenu\", cancelDrag);\n            document.removeEventListener(\"touchend\", cancelDrag);\n            document.removeEventListener(\"touchcancel\", cancelDrag);\n        };\n\n        const onDragEndCancel = (e: any) => {\n            onDragEnd(e, { cancelled: true });\n        };\n\n        const onDragEnd = (e: any, { cancelled = false } = {}) => {\n            const current = CURRENT_DROP_REF?.current;\n            cancelDrag();\n            if (!current) {\n                return;\n            }\n            const canDrop = current.canDrop(type, dragItem);\n            if (canDrop && !cancelled) {\n                current.onDrop?.(dragItem);\n            }\n            current.onOverChange({ isOver: false, canDrop, dragItem, dragImage: dragImageRef.current! });\n        };\n\n        // currentDragRef will not be null\n        // because we're only here if we were triggered by an event listener for the ref\n        currentDragRef?.addEventListener(\"mouseup\", cancelDrag);\n        currentDragRef?.addEventListener(\"touchend\", cancelDrag);\n        currentDragRef?.addEventListener(\"touchcancel\", cancelDrag);\n        currentDragRef?.addEventListener(\"mouseleave\", startDrag);\n        currentDragRef?.addEventListener(\"contextmenu\", cancelDrag);\n        currentDragRef?.addEventListener(\"keydown\", keyDown);\n\n        const moveTo = (clientX: number, clientY: number) => {\n            const offsetX = initOffsetX !== null ? Math.min(initOffsetX, d.offsetWidth / 2) : d.offsetWidth / 2;\n            const offsetY = initOffsetY !== null ? Math.min(initOffsetY, d.offsetHeight / 2) : d.offsetHeight / 2;\n            d.style.left = clientX - offsetX + \"px\";\n            d.style.top = clientY - offsetY + \"px\";\n        };\n\n        function onDragMove(event: MouseTouchEvent) {\n            const touchOrMouseEvent = getMouseEventOrTouch(event);\n            const { clientX, clientY } = touchOrMouseEvent;\n            moveTo(clientX, clientY);\n            dragStore.setState({ dragPosition: { clientX, clientY } });\n            if (!isDraggingRef.current) {\n                // use a distance to determine if we're dragging!\n                // we can also start dragging if we leave the component\n                if (Math.hypot(clientX - initX, clientY - initY) > 30) {\n                    startDrag();\n                }\n                return;\n            }\n\n            d.hidden = true;\n            const elemBelow = document.elementFromPoint(clientX, clientY);\n            d.hidden = false;\n\n            if (!elemBelow) {\n                CURRENT_DROP_REF = null;\n                return;\n            }\n\n            const prevDropRef = CURRENT_DROP_REF;\n\n            const dropElem = elemBelow.closest(\"[data-anvil-droppable]\");\n            CURRENT_DROP_REF = (dropElem && DROP_REFS.get(dropElem)) || null;\n\n            // currentDropRef and dropItem both point to react Refs or null\n            if (CURRENT_DROP_REF === prevDropRef) {\n                if (!CURRENT_DROP_REF) {\n                    dragImageRef.current.style.cursor = \"not-allowed\";\n                }\n                // if they point to the same ref then exit\n                prevDropRef?.current?.onHover?.(dragItem, getMouseEventOrTouch(event));\n                return;\n            } else {\n                const canDrop = !!prevDropRef?.current?.canDrop(type, dragItem);\n                prevDropRef?.current?.onOverChange({\n                    isOver: false,\n                    dragItem,\n                    dragImage: dragImageRef.current!,\n                    canDrop,\n                });\n            }\n\n            const current = CURRENT_DROP_REF?.current;\n            if (!current) {\n                dragImageRef.current.style.cursor = \"not-allowed\";\n                return;\n            }\n\n            const canDrop = current.canDrop(type, dragItem);\n            current.onOverChange({ isOver: true, canDrop, dragItem, dragImage: dragImageRef.current });\n            if (current.canDrop(type, dragItem)) {\n                dragImageRef.current.style.cursor = current.dropEffect || \"auto\";\n            } else {\n                dragImageRef.current.style.cursor = \"not-allowed\";\n            }\n        }\n\n        document.addEventListener(\"mousemove\", onDragMove);\n        document.addEventListener(\"touchmove\", onDragMove);\n        document.addEventListener(\"touchend\", cancelDrag);\n        document.addEventListener(\"touchcancel\", cancelDrag);\n    });\n\n    const [dragRef, dragRefCallback] = useDragRef(onDragStart);\n\n    return [{ isDragging } as const, dragRefCallback, previewRef] as const;\n};\n\nconst DROP_REFS = new Map<HTMLElement | Element, React.MutableRefObject<DropItem | null>>();\n\ntype MonitorProps = { isOver: boolean; dragItem: any; dragImage: HTMLDivElement; canDrop: boolean };\n\ninterface DropOptions {\n    accept: Accept;\n    onOverChange?: (monitor: MonitorProps) => void;\n    onDrop?: (dragItem: any) => void;\n    canDrop?: (dragItem: any) => boolean;\n    dropEffect?: string;\n    onHover?: (dragItem: any, event: MouseEventOrTouch) => void;\n}\n\nexport const useDrop = ({\n    canDrop: canDropCb,\n    onOverChange: onOverCb,\n    onDrop,\n    accept,\n    dropEffect,\n    onHover,\n}: DropOptions) => {\n    const [isOver, setIsOver] = useState(false);\n    const [canDrop, setCanDrop] = useState(false);\n    const dropRef = useRef<HTMLElement | null>(null);\n    const dropItem = useRef<DropItem | null>(null);\n\n    const onOverChange = useEvent((monitor: MonitorProps) => {\n        setIsOver(monitor.isOver);\n        onOverCb?.(monitor);\n    });\n\n    const checkCanDrop = useEvent((type: symbol | string, item: any) => {\n        let rv;\n        if (accept !== ANY && type !== accept && !(accept as any[])?.includes(type)) {\n            rv = false;\n        } else if (!canDropCb) {\n            rv = true;\n        } else {\n            rv = !!canDropCb(item);\n        }\n        setCanDrop(rv);\n        return rv;\n    });\n\n    useInsertionEffect(() => {\n        dropItem.current = { canDrop: checkCanDrop, onOverChange, onDrop, dropEffect, onHover };\n    });\n\n    const dropRefCallback: React.RefCallback<HTMLElement> = useCallback((ref) => {\n        // use a callback as a ref since the domNode might change during the lifecylce of this hook\n        // clean up\n        const currentDropRef = dropRef.current;\n        if (currentDropRef) {\n            delete currentDropRef.dataset.anvilDroppable;\n            DROP_REFS.delete(currentDropRef);\n        }\n        dropRef.current = ref;\n        if (ref) {\n            ref.dataset.anvilDroppable = \"\";\n            dropItem && DROP_REFS.set(ref, dropItem);\n        }\n    }, []);\n\n    return [{ isOver, canDrop } as const, dropRefCallback] as const;\n};\n\nexport function useScrollWhenDragging(containerRef: React.MutableRefObject<HTMLElement | null>) {\n    const animationFrameRef = useRef<undefined | number>(undefined);\n\n    const threshold = useRemToPixels(5);\n    const baseScrollSpeed = useRemToPixels(3);\n\n    const {\n        isDragging,\n        dragPosition: { clientY: dragY },\n    } = useDragStore();\n\n    const checkForAutoScroll = useEffectEvent(() => {\n        const container = containerRef.current;\n        if (!isDragging || !container) return;\n\n        const { scrollTop, clientHeight, scrollHeight } = container;\n        const relativeY = dragY - container.getBoundingClientRect().top;\n\n        let scrollAmount = 0;\n\n        if (relativeY < 0 || relativeY > clientHeight) {\n            // pass\n        } else if (relativeY < threshold) {\n            const speedFactor = (threshold - relativeY) / threshold;\n            scrollAmount = -baseScrollSpeed * speedFactor;\n            container.scrollTop = Math.max(scrollTop - baseScrollSpeed, 0);\n        } else if (clientHeight - relativeY < threshold) {\n            const speedFactor = (threshold - (clientHeight - relativeY)) / threshold;\n            scrollAmount = baseScrollSpeed * speedFactor;\n        }\n        if (scrollAmount) {\n            container.scrollTop = Math.max(Math.min(scrollTop + scrollAmount, scrollHeight - clientHeight), 0);\n        }\n\n        animationFrameRef.current = requestAnimationFrame(checkForAutoScroll);\n    });\n\n    useEffect(() => {\n        if (!isDragging) return;\n        animationFrameRef.current = requestAnimationFrame(checkForAutoScroll);\n        return () => {\n            cancelAnimationFrame(animationFrameRef.current as number);\n        };\n    }, [isDragging]);\n}\n","import { useSelector } from \"react-redux\";\nimport { startCase } from \"lodash-es\";\nimport { getFeatures } from \"@/controllers/ide\";\nimport type { State } from \"@/types\";\nimport type { FeatureMap } from \"@/types/user\";\n\nexport const featureSupported = (features: FeatureMap | null | undefined, featureId: string) => {\n    return features?.[featureId]?.active;\n};\n\nexport const getFeatureSupport = (state: State, featureId: string) => featureSupported(getFeatures(state), featureId);\n\n// Component version of `getFeatureSupport`, for use outside of `connect`/thunks.\nexport const useFeatureSupported = (featureId: string) =>\n    useSelector((state: State) => getFeatureSupport(state, featureId));\n\nexport const getPlanName = (planId: string | null | undefined) =>\n    planId === \"individual\" ? \"Professional\" : planId === \"dedicated\" ? \"Business\" : startCase(planId ?? \"\");\n","import { pickBy } from \"lodash-es\";\n\nconst JSON_HEADER = { \"Content-Type\": \"application/json\" };\nconst PARAM_HEADER = { \"Content-Type\": \"application/x-www-form-urlencoded\" };\n\n/** removes null/undefined from the object (keeps 0, false, and empty string) */\nfunction queryParams(params: { [param: string]: any }) {\n    return new URLSearchParams(pickBy(params, (v) => v != null)).toString();\n}\n\n/** adds query params to a url - the url should not have any query params already set */\nexport function urlQueryParams(url: string, params: { [param: string]: any }) {\n    const searchParams = queryParams(params);\n    if (searchParams) {\n        return url + \"?\" + searchParams;\n    }\n    return url;\n}\n\n/** Sends a GET request to the specified URL */\nexport async function get<T = unknown>(url: string, init: RequestInit = {}): Promise<T> {\n    const response = await fetch(url, { method: \"GET\", ...init });\n    return handleResponse<T>(response);\n}\n\nexport class HttpError {\n    status: number;\n    /** The response's `error` value, if it is a JSON object with one; otherwise the response text. */\n    error: any;\n    message: string;\n    /** The parsed response, or undefined if it was not valid JSON. */\n    body: unknown;\n    constructor(response: Response, text: string, body: unknown) {\n        this.status = response.status;\n        this.body = body;\n        this.error = typeof body === \"object\" && body !== null && \"error\" in body ? body.error : text;\n        const error = this.error;\n        this.message = typeof error === \"string\" ? error : error?.error || error?.message || JSON.stringify(error);\n    }\n}\n\n/** Sends a POST request with JSON payload to the specified URL */\nexport async function postJson<T = unknown>(url: string, body?: any, init: RequestInit = {}): Promise<T> {\n    body &&= JSON.stringify(body);\n    const response = await fetch(url, { method: \"POST\", headers: JSON_HEADER, body, ...init });\n    return handleResponse(response);\n}\n\nexport const post = postJson;\n\n/** Sends a POST request with URL-encoded form parameters to the specified URL. */\nexport async function postParams<T = unknown>(url: string, params?: any, init: RequestInit = {}): Promise<T> {\n    const body = new URLSearchParams(params);\n    const response = await fetch(url, { method: \"POST\", headers: PARAM_HEADER, body, ...init });\n    return handleResponse(response);\n}\n\n/** Sends a PUT request with JSON payload to the specified URL. */\nexport async function put<T = unknown>(url: string, body: any, init: RequestInit = {}): Promise<T> {\n    body &&= JSON.stringify(body);\n    const response = await fetch(url, { method: \"PUT\", headers: JSON_HEADER, body, ...init });\n    return handleResponse(response);\n}\n\n/** Sends a DELETE request to the specified URL. */\nexport async function del<T = unknown>(url: string, init: RequestInit = {}): Promise<T> {\n    const response = await fetch(url, { method: \"DELETE\", ...init });\n    return handleResponse(response);\n}\n\nexport async function handleResponse<T = unknown>(response: Response): Promise<T> {\n    const isJson = response.headers.get(\"content-type\") === \"application/json\";\n    if (response.status >= 400) {\n        // Parse whatever the content type: Ring sends \"application/json; charset=utf-8\".\n        const text = await response.text();\n        let body: unknown;\n        try {\n            body = JSON.parse(text);\n        } catch {\n            body = undefined;\n        }\n        throw new HttpError(response, text, body);\n    }\n    if (isJson) {\n        return response.json();\n    } else {\n        const text = await response.text();\n        try {\n            return JSON.parse(text);\n        } catch {\n            return text as T;\n        }\n    }\n}\n","import type { State } from \"@/types\";\nimport { USER_AB_FLAGS } from \"@/types/user\";\nimport type { UserABFlagName } from \"@/types/user\";\n\nexport { USER_AB_FLAGS };\nexport type { UserABFlagName, UserABFlags, UserABFlagValue } from \"@/types/user\";\n\nexport const getUserAbFlag = (state: State, flagName: UserABFlagName) => state.user?.ab?.[flagName];\nconst getBooleanUserAbFlag = (state: State, flagName: UserABFlagName) => getUserAbFlag(state, flagName) === true;\n\nexport const getAbTyAnalysis = (state: State) =>\n    __DEV__ ? localStorage.getItem(\"anvil-ty\") !== \"false\" : getBooleanUserAbFlag(state, USER_AB_FLAGS.tyAnalysis);\n\nexport const getAbIdeTutorial = (state: State) => getBooleanUserAbFlag(state, USER_AB_FLAGS.ideTutorial);\n\nexport const getAbTutorialsInIde = (state: State) => getBooleanUserAbFlag(state, USER_AB_FLAGS.tutorialsInIde);\n\nexport const getAbVideoIntro = (state: State) => getBooleanUserAbFlag(state, USER_AB_FLAGS.videoIntro);\n\nexport const getAbGetStartedRoadmap = (state: State) => getBooleanUserAbFlag(state, USER_AB_FLAGS.getStartedRoadmap);\n\nexport const getAbServerTests = (state: State) => getBooleanUserAbFlag(state, USER_AB_FLAGS.serverTests);\n\nexport const getAbMobileIde = (state: State) => getBooleanUserAbFlag(state, USER_AB_FLAGS.mobileIde);\n","import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { faJs } from \"@fortawesome/free-brands-svg-icons\";\nimport {\n    IconDefinition,\n    faFileAlt,\n    faFileAudio,\n    faFileCode,\n    faFilePdf,\n    faFileVideo,\n    faHashtag,\n} from \"@fortawesome/pro-light-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport type Mime from \"mime\";\nimport { base64DecToStr, base64EncArr } from \"@runtime/lib/b64\";\nimport { getAppOrigins } from \"@/controllers/app\";\nimport { getAppAssets, getDependencyAssets } from \"@/controllers/app/code\";\nimport { darkIcons, icons } from \"@/data/componentIcons\";\nimport { cx, useIsDark } from \"@/theme/styles\";\nimport { DependencyStructureItem, StructureItem } from \"@/types\";\nimport useEvent from \"../useEventCallback\";\n\nexport { decodeAssetContent, encodeAssetContent } from \"../asset-content\";\n\nconst IMAGE_PATHS = /\\.(png|gif|jpg|jpeg|svg)$/i;\n\nexport type Asset = StructureItem | DependencyStructureItem;\n\nfunction getImageType(assetName: string) {\n    const match = assetName.match(IMAGE_PATHS);\n    switch (match?.[1].toLowerCase()) {\n        case \"png\":\n            return \"image/png\";\n        case \"gif\":\n            return \"image/gif\";\n        case \"svg\":\n            return \"image/svg+xml\";\n        default:\n            return \"image/jpeg\";\n    }\n}\n\nexport const fileToBase64Content = async (file: File): Promise<string> => {\n    const bytes = new Uint8Array(await file.arrayBuffer());\n    return base64EncArr(bytes);\n};\n\nexport const getDataUriForAsset = (asset: any) => {\n    const assetName = asset?.item?.name;\n    const content = asset?.item?.content;\n    return \"data:\" + getImageType(assetName) + \";base64,\" + content;\n};\n\nexport const cssify = (url: string) =>\n    'url(\"' + url.replace(\"^asset:\", \"\").replace('\"', \"%22\").replace(\"\\\\\", \"\\\\\\\\\") + '\")';\nexport const cssifyAsset = (asset: any) => cssify(getDataUriForAsset(asset));\n\ntype ParsedAccept = ReturnType<typeof parseAccept>;\n\nfunction parseAccept(accept?: string) {\n    let any = false;\n    const types = [];\n    const mimeTypes = [];\n    const extensions = [];\n\n    if (!accept) {\n        any = true;\n    }\n\n    const preParsed =\n        accept\n            ?.toLowerCase()\n            .split(\",\")\n            .map((x) => x.trim()) ?? [];\n    for (const p of preParsed) {\n        if (p === \"*/*\") {\n            any = true;\n        } else if (p.endsWith(\"/*\")) {\n            types.push(p.slice(0, -1));\n        } else if (p.startsWith(\".\")) {\n            extensions.push(p);\n        } else {\n            mimeTypes.push(p);\n        }\n    }\n    return { any, types, mimeTypes, extensions } as const;\n}\n\nfunction pushValidAssets(assets: Asset[], parsedAccept: ParsedAccept, valid: Asset[]) {\n    const { any, types, mimeTypes, extensions } = parsedAccept;\n\n    for (const asset of assets) {\n        if (asset.name === \".gitkeep\") continue;\n        if (any) {\n            valid.push(asset);\n            continue;\n        }\n        if (extensions.some((ext) => asset.fullName.endsWith(ext))) {\n            valid.push(asset);\n            continue;\n        }\n        const assetMime = mime?.getType(asset.fullName);\n        if (!assetMime) continue;\n        if (mimeTypes.includes(assetMime)) {\n            valid.push(asset);\n        } else if (types.some((type) => assetMime.startsWith(type))) {\n            valid.push(asset);\n        }\n    }\n}\n\nlet loadingMime: Promise<any> | boolean = false;\nlet mime: null | typeof Mime = null;\n\nfunction useLazyMimeTypesModule() {\n    const [loaded, setLoaded] = useState(loadingMime === true);\n    useLayoutEffect(() => {\n        if (loadingMime === false) {\n            loadingMime = Promise.resolve(import(\"mime\")).then((mod) => {\n                mime = mod.default;\n                loadingMime = true;\n                setLoaded(true);\n            });\n        } else if (loadingMime === true) {\n            setLoaded(true);\n        } else {\n            loadingMime.then(() => {\n                setLoaded(true);\n            });\n        }\n    }, []);\n    return loaded;\n}\n\nfunction useValidAssetList(assets: Asset[], parsedAccept: ParsedAccept) {\n    const loadedMime = useLazyMimeTypesModule();\n\n    return useMemo(() => {\n        if (!loadedMime) return [];\n        const valid: Asset[] = [];\n        pushValidAssets(assets, parsedAccept, valid);\n        valid.sort((a, b) => a.fullName.localeCompare(b.fullName));\n        return valid;\n    }, [loadedMime, assets, parsedAccept]);\n}\n\nconst EMPTY_ASSETS: Asset[] = [];\nconst getEmptyAssets = () => EMPTY_ASSETS;\n\nexport function useAssets(accept?: string, deps?: boolean) {\n    const parsedAccept = useMemo(() => parseAccept(accept), [accept]);\n    const assets = useSelector(getAppAssets);\n    const dependencyAssets = useSelector(deps ? getDependencyAssets : getEmptyAssets);\n\n    const appAssets = useValidAssetList(assets, parsedAccept);\n    const depAssets = useValidAssetList(dependencyAssets, parsedAccept);\n\n    const allAssets = useMemo(() => {\n        return [...appAssets, ...depAssets].sort((a, b) => a.fullName.localeCompare(b.fullName));\n    }, [appAssets, depAssets]);\n\n    return { appAssets, depAssets, allAssets };\n}\n\nexport const useImageAssets = () => {\n    const { allAssets } = useAssets(\"image/*\");\n    return allAssets;\n};\n\n// includes optional query params\nconst IMAGE_REGEX = /\\.(png|gif|jpg|jpeg|svg)(?:\\?.*)?$/;\nconst pathRegex = /^.*\\.(\\w+)$/i;\n\nconst getIcon = (path: string) => {\n    const [, ext] = path.match(pathRegex) ?? [];\n    switch (ext) {\n        case \"html\":\n            return faFileCode;\n        case \"css\":\n            return faHashtag;\n        case \"js\":\n            return faJs as IconDefinition;\n        case \"pdf\":\n            return faFilePdf;\n        case \"mp4\":\n        case \"mov\":\n        case \"avi\":\n            return faFileVideo;\n        case \"mp3\":\n        case \"wav\":\n        case \"ogg\":\n            return faFileAudio;\n        default:\n            return faFileAlt;\n    }\n};\n\nexport const useDebugThemePrefix = () => {\n    const appOrigins = useSelector(getAppOrigins);\n    return appOrigins!.debugOrigin + \"/_/theme/\";\n};\n\nexport const useMaybeRemoveAssetPrefix = (src: string) => {\n    const themePrefix = useDebugThemePrefix();\n    if (src.startsWith(\"asset:\")) {\n        return themePrefix + src.slice(6);\n    }\n    return src;\n};\n\ninterface ImageWithRetryProps {\n    src: string;\n    dark?: boolean;\n    visible?: boolean;\n    className?: string;\n}\n\nconst getPlaceholderImg = (isDark: boolean) => (isDark ? darkIcons.UNKNOWN_MIN : icons.UNKNOWN_MIN);\n\n/** If we've just loaded the asset it might fail to fetch so retry */\nexport const ImageWithRetry = ({ src, className, dark, visible = true }: ImageWithRetryProps) => {\n    const isDarkTheme = useIsDark();\n    const isDark = dark ?? isDarkTheme;\n    const [loaded, setLoaded] = useState<boolean | null>(null);\n    const fallbackIcon = getPlaceholderImg(isDark);\n    const imgRef = useRef<HTMLImageElement>(null!);\n    const [attempt, setAttempt] = useState(0);\n    if (!visible && loaded === false) {\n        setLoaded(null);\n    }\n    const [prevSrc, setPrevSrc] = useState(src);\n    if (prevSrc !== src) {\n        setPrevSrc(src);\n        setLoaded(null);\n        setAttempt(0);\n    }\n\n    useEffect(() => {\n        if (!visible) {\n            return;\n        }\n        const img = imgRef.current;\n        if (!img) return;\n        if (img.complete) {\n            setLoaded(true);\n        } else {\n            setTimeout(() => setLoaded((v) => !!v), 250);\n        }\n    }, [src, visible]);\n\n    const onError = useEvent(() => {\n        if (attempt > 3) {\n            setLoaded(true);\n        }\n        setTimeout(\n            () => {\n                const img = imgRef.current;\n                if (!img) return;\n                img.src = src;\n            },\n            Math.min(attempt > 1 ? 2 ** attempt * 500 : 500, 12 * 1000)\n        );\n        setAttempt((s) => ++s);\n    });\n\n    const onLoad = useEvent(() => {\n        setLoaded(true);\n    });\n\n    return (\n        <div\n            className={cx(\n                \"pointer-events-none relative h-full w-full bg-cover bg-no-repeat before:absolute before:inset-0 before:animate-pulse before:rounded-lg\",\n                className,\n                isDark ? \"before:bg-dark-sidebar\" : \"before:bg-sidebar\",\n                { \"before:animate-none before:content-none\": loaded }\n            )}\n            style={{ backgroundImage: loaded === false ? `url(${fallbackIcon})` : undefined }}>\n            <img\n                alt=\"\"\n                ref={imgRef}\n                loading=\"lazy\" // might be annoying\n                onLoad={onLoad}\n                onError={onError}\n                className={cx(loaded ? \"opacity-100\" : \"opacity-0\", \"h-full w-full transition-opacity\")}\n                src={src}\n            />\n        </div>\n    );\n};\n\nexport const getThumbnail = (fullPath?: string | null) => {\n    if (fullPath == null) return null;\n    if (IMAGE_REGEX.test(fullPath)) {\n        return <ImageWithRetry src={fullPath} />;\n    }\n    return <FontAwesomeIcon className=\"m-auto\" icon={getIcon(fullPath)} />;\n};\n\nexport const useThumbnails = (assets: Asset[]) => {\n    const themePrefix = useDebugThemePrefix();\n    return useMemo(() => {\n        return assets.map(({ fullName }) => getThumbnail(themePrefix + fullName));\n    }, [assets, themePrefix]);\n};\n","import { useRef, useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport { getEditorSequenceNumbers } from \"@/controllers/app\";\nimport { useRefreshValue } from \"./index\";\n\n/**\n *\n * [[\"CODE\", \"forms/Form1\"], [\"SETTINGS\", \"dependencies\"]]\n *\n * this will start at 0.\n * It will NOT change if paths have changed,\n * It will ONLY change if the editorSequenceNumbers have changed since we last changed the paths.\n */\nexport const useEditSequenceNumbersChanged = (paths: string[][]) => {\n    // we only want the sequenceNumber to change if our sequenceNumbers no longer match the global sequenceNumbers\n    const currentEditSequenceNumbers = useSelector(getEditorSequenceNumbers);\n    const prevEditSequenceNumbers = useRef(currentEditSequenceNumbers);\n\n    const [sequenceNumber, incSequenceNumber] = useRefreshValue();\n    const myPaths = useRef<string[][] | null>(null);\n    const mySequenceNumbersRef = useRef<Record<string, number> | null>(null);\n\n    const getSequenceNumbers = () => {\n        const sequenceNumbers: Record<string, number> = {};\n        for (let i = 0; i < paths.length; i++) {\n            const p = JSON.stringify(paths[i]); //.join(\"\"); // must match the MarkPathsChanged\n            sequenceNumbers[p] = currentEditSequenceNumbers[p];\n        }\n        return sequenceNumbers;\n    };\n\n    // NB: updating a ref might be dangerous inside a render\n    if (myPaths.current !== paths) {\n        // Paths that I depend on have changed, so update my subset of sequence numbers\n        // don't update the sequenceNumber state\n        myPaths.current = paths;\n        mySequenceNumbersRef.current = getSequenceNumbers();\n    } else if (currentEditSequenceNumbers !== prevEditSequenceNumbers.current) {\n        // Editor sequence numbers have changed, check if we need to update our subset.\n        prevEditSequenceNumbers.current = currentEditSequenceNumbers;\n        const mySequenceNumbers = mySequenceNumbersRef.current;\n        let rerender = false;\n        for (const path in mySequenceNumbers) {\n            const current = currentEditSequenceNumbers[path];\n            if (mySequenceNumbers[path] !== current) {\n                rerender = true;\n                mySequenceNumbers[path] = current;\n            }\n        }\n        if (rerender) {\n            incSequenceNumber();\n        }\n    }\n\n    return sequenceNumber;\n};\n\nexport const useEditSequenceNumber = (path: string) => {\n    const currentEditSequenceNumbers = useSelector(getEditorSequenceNumbers);\n    return currentEditSequenceNumbers[path];\n};\n\nfunction mutateObject(obj1: any, obj2: any) {\n    // Remove properties from obj1 that are not in obj2\n    for (const key in obj1) {\n        if (!Object.hasOwn(obj2, key)) {\n            delete obj1[key];\n        }\n    }\n\n    // Add or update properties in obj1 to match obj2\n    for (const key in obj2) {\n        obj1[key] = obj2[key];\n    }\n\n    return obj1;\n}\n\n/** Bespoke hook used in useDependOnCodeDeps */\nexport const useEditSequenceNumbers = (paths: string[][]) => {\n    const currentEditSequenceNumbers = useSelector(getEditorSequenceNumbers);\n    const myPaths = useRef<string[][] | null>(paths);\n\n    // we only want the sequenceNumber to change if our sequenceNumbers no longer match the global sequenceNumbers\n    const sequenceNumber = useEditSequenceNumbersChanged(paths);\n    const [prevSeq, setPrevSeq] = useState(sequenceNumber);\n\n    const getSequenceNumbers = () => {\n        const sequenceNumbers: Record<string, number> = {};\n        for (let i = 0; i < paths.length; i++) {\n            const path = paths[i];\n            const p = JSON.stringify(path); //.join(\"\"); // must match the MarkPathsChanged\n            sequenceNumbers[path.at(-1)!] = currentEditSequenceNumbers[p];\n        }\n        return sequenceNumbers;\n    };\n\n    const [mySequenceNumbers, setMySequenceNumbers] = useState<Record<string, number>>(getSequenceNumbers);\n\n    if (prevSeq !== sequenceNumber) {\n        setPrevSeq(sequenceNumber);\n        setMySequenceNumbers(getSequenceNumbers());\n    } else if (paths !== myPaths.current) {\n        // paths have changed, silently mutate the object and don't force a re-render\n        // a bit un-react - but we don't care about this change!\n        myPaths.current = paths;\n        mutateObject(mySequenceNumbers, getSequenceNumbers());\n    }\n\n    return mySequenceNumbers;\n};\n","import { useEffect } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport { getAppId } from \"@/controllers/app\";\nimport { saveApp } from \"@/controllers/app/saving\";\nimport { restartApp, runApp, stopApp, toggleZenMod } from \"@/controllers/ide\";\nimport { getInTutorialMode } from \"@/controllers/ideTutorial\";\nimport { modal } from \"@/controllers/modals\";\nimport { getRunMode } from \"@/controllers/runner\";\nimport { openSearchNav } from \"@/controllers/search\";\nimport { showHideSecondaryNav } from \"@/controllers/sidebar\";\nimport { openTabToLeft, openTabToRight } from \"@/controllers/tabs\";\nimport { AnvilDispatch } from \"@/types\";\nimport { blockEvent, cancelOnIdle, checkMeta, getSelectedText } from \"..\";\nimport useEvent from \"../useEventCallback\";\n\nconst isInput = (e: any) => e.target?.tagName === \"INPUT\" || e.target?.tagName === \"TEXTAREA\";\n\nexport function useGlobalKeyBindings() {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const appId = useSelector(getAppId);\n    const debugRunMode = useSelector(getRunMode);\n    const inTutorialMode = useSelector(getInTutorialMode);\n\n    const keydown = useEvent((e: KeyboardEvent) => {\n        // log.warn(e.keyCode);\n        switch (e.code) {\n            case \"KeyS\":\n                if (checkMeta(e)) {\n                    dispatch(cancelOnIdle(\"SAVE\"));\n                    dispatch(saveApp());\n                    blockEvent(e);\n                }\n                break;\n            case \"Enter\":\n                // don't open app if it's already open or if we are in an input\n                // this tries to deal with race conditions with react events vs native events\n                // textarea might still be problematic but codemirror runs in a textarea\n                if ((e.ctrlKey || e.metaKey) && !isInput(e) && !e.defaultPrevented) {\n                    if (debugRunMode) {\n                        dispatch(restartApp());\n                    } else {\n                        dispatch(runApp());\n                    }\n                    blockEvent(e);\n                }\n                break;\n            case \"Escape\":\n                if (checkMeta(e) && !e.defaultPrevented) {\n                    if (debugRunMode) {\n                        dispatch(stopApp());\n                        blockEvent(e);\n                    }\n                }\n                break;\n            case \"KeyB\":\n                if (checkMeta(e) && !e.defaultPrevented) {\n                    blockEvent(e);\n                    dispatch(showHideSecondaryNav());\n                }\n                break;\n            case \"KeyF\":\n                if (checkMeta(e)) {\n                    blockEvent(e);\n                    if (e.shiftKey) {\n                        log.warn(\"whole app search\");\n                        dispatch(openSearchNav(getSelectedText()));\n                    } else {\n                        log.warn(\"Find\");\n                    }\n                }\n                break;\n            case \"KeyG\":\n                if (checkMeta(e)) {\n                    blockEvent(e);\n                    if (e.shiftKey) {\n                        log.warn(\"Find previous\");\n                    } else {\n                        log.warn(\"Find next\");\n                    }\n                }\n                break;\n            case \"KeyH\":\n                if (checkMeta(e)) {\n                    blockEvent(e);\n                    if (e.shiftKey) {\n                        log.warn(\"Replace all\");\n                    } else {\n                        log.warn(\"Replace\");\n                    }\n                }\n                break;\n            case \"KeyJ\":\n                // Definitely not - this is a useful Chrome shortcut!\n                // if ((e.ctrlKey || e.metaKey)) {\n                //     e.stopPropagation();\n                //     e.preventDefault();\n                //     dispatch(toggleBottomPanel());\n                // }\n                break;\n\n            case \"KeyZ\":\n                if (e.altKey && e.shiftKey) {\n                    dispatch(toggleZenMod());\n                    blockEvent(e);\n                }\n                break;\n            case \"KeyP\":\n                if (checkMeta(e) && !inTutorialMode) {\n                    dispatch(modal(\"quickSwitcher\", {}));\n                    blockEvent(e);\n                }\n                break;\n\n            // Need to be careful with the PgUp/PgDown shortcuts\n            // PgUp - move around in text\n            // Shift+PgUp - select whole pages of text\n            // Ctrl+PgUp - move to previous browser tab\n            // Alt+PgUp - move to previous Anvil Editor tab.\n            case \"PageUp\":\n                if (e.altKey) {\n                    dispatch(openTabToLeft());\n                    blockEvent(e);\n                }\n                break;\n            case \"PageDown\":\n                if (e.altKey) {\n                    dispatch(openTabToRight());\n                    blockEvent(e);\n                }\n                break;\n            default:\n                break;\n        }\n    });\n\n    // Ew. We'd like to add this using React, but when there's nothing focused the events go to the <body>. So we have to catch them there.\n    useEffect(() => {\n        if (!appId) return;\n        document.body.addEventListener(\"keydown\", keydown);\n        return () => {\n            document.body.removeEventListener(\"keydown\", keydown);\n        };\n    }, [appId, keydown]);\n}\n\nexport const useCopyAllKeyBinding = (ref: React.RefObject<HTMLElement | null>): React.KeyboardEventHandler =>\n    useEvent((e) => {\n        if (e.code === \"KeyA\" && checkMeta(e)) {\n            e.preventDefault();\n            const selection = window.getSelection();\n            const range = document.createRange();\n            if (!ref.current) return;\n            range.selectNodeContents(ref.current);\n            selection?.removeAllRanges();\n            selection?.addRange(range);\n        }\n    });\n","import { useMemo, useState } from \"react\";\nimport { InfiniteData, UseInfiniteQueryResult, useInfiniteQuery } from \"@tanstack/react-query\";\nimport * as api from \"@/api\";\nimport { IDE_APP_LIST_QUERY_KEY } from \"@/controllers/app-list-query\";\nimport { AppId, AppItem } from \"@/types\";\nimport { useDebounceFn } from \"./use-debounce-fn\";\n\ninterface UseAppsInfiniteQueryOptions {\n    initialQuery?: string;\n    owner?: \"All\" | \"Shared\" | \"Mine\";\n    includePySpace?: boolean;\n    sort?: \"name\" | \"date\";\n    order?: \"asc\" | \"desc\";\n    pinFav?: boolean;\n    pageSize?: number;\n    page_size?: number;\n    enabled?: boolean;\n    debounceMs?: number;\n    validDependencyOf?: string;\n}\n\ninterface AppsPageResponse {\n    apps: AppItem[];\n    next_cursor?: string;\n}\n\ntype AppsInfiniteQueryResult = UseInfiniteQueryResult<InfiniteData<AppsPageResponse>, Error>;\n\ninterface UseAppsInfiniteQueryResult {\n    apps: AppItem[];\n    debouncedQuery: string;\n    data: AppsInfiniteQueryResult[\"data\"];\n    error: AppsInfiniteQueryResult[\"error\"];\n    status: AppsInfiniteQueryResult[\"status\"];\n    isLoading: AppsInfiniteQueryResult[\"isLoading\"];\n    isError: AppsInfiniteQueryResult[\"isError\"];\n    isFetched: AppsInfiniteQueryResult[\"isFetched\"];\n    isFetching: AppsInfiniteQueryResult[\"isFetching\"];\n    isPlaceholderData: AppsInfiniteQueryResult[\"isPlaceholderData\"];\n    isFetchingNextPage: AppsInfiniteQueryResult[\"isFetchingNextPage\"];\n    hasNextPage: AppsInfiniteQueryResult[\"hasNextPage\"];\n    fetchNextPage: AppsInfiniteQueryResult[\"fetchNextPage\"];\n    refetch: AppsInfiniteQueryResult[\"refetch\"];\n    setQuery: (value: string) => void;\n}\n\nexport const useAppsInfiniteQuery = ({\n    initialQuery = \"\",\n    owner = \"All\",\n    includePySpace = false,\n    sort = \"date\",\n    order = \"desc\",\n    pinFav = false,\n    pageSize = 20,\n    page_size,\n    enabled = true,\n    debounceMs = 200,\n    validDependencyOf = undefined,\n}: UseAppsInfiniteQueryOptions = {}): UseAppsInfiniteQueryResult => {\n    const effectivePageSize = page_size ?? pageSize;\n    const [debouncedQuery, setDebouncedQuery] = useState(initialQuery.trim().toLowerCase());\n    const setQuery = useDebounceFn((value: string) => setDebouncedQuery(value.trim().toLowerCase()), debounceMs);\n\n    const queryResult = useInfiniteQuery<AppsPageResponse>({\n        queryKey: [\n            ...IDE_APP_LIST_QUERY_KEY,\n            { debouncedQuery, owner, includePySpace, sort, order, pinFav, pageSize: effectivePageSize, validDependencyOf },\n        ],\n        queryFn: ({ pageParam, signal }) =>\n            api.getAppsPage({\n                limit: effectivePageSize,\n                cursor: (pageParam as string | undefined) ?? undefined,\n                q: debouncedQuery || undefined,\n                owner,\n                includePySpace,\n                sort,\n                order,\n                pinFav,\n                signal,\n                validDependencyOf,\n            }),\n        initialPageParam: undefined as string | undefined,\n        getNextPageParam: (lastPage) => lastPage?.next_cursor || undefined,\n        placeholderData: (previousData) => previousData,\n        enabled,\n    });\n\n    const apps = useMemo(() => queryResult.data?.pages.flatMap((page) => page.apps || []) ?? [], [queryResult.data]);\n\n    return {\n        apps,\n        debouncedQuery,\n        data: queryResult.data,\n        error: queryResult.error,\n        status: queryResult.status,\n        isLoading: queryResult.isLoading,\n        isError: queryResult.isError,\n        isFetched: queryResult.isFetched,\n        isFetching: queryResult.isFetching,\n        isPlaceholderData: queryResult.isPlaceholderData,\n        isFetchingNextPage: queryResult.isFetchingNextPage,\n        hasNextPage: queryResult.hasNextPage,\n        fetchNextPage: queryResult.fetchNextPage,\n        refetch: queryResult.refetch,\n        setQuery,\n    };\n};\n","import { useEffect } from \"react\";\nimport { DebounceSettings, debounce } from \"lodash-es\";\nimport { useConstant } from \".\";\nimport useEvent from \"../useEventCallback\";\n\ntype noop = (...args: any[]) => any;\n\n/**\n * Returns a stable debounced version of `fn` that delays invoking it until\n * `wait` milliseconds have elapsed since the last call. The pending call is\n * automatically cancelled when the component unmounts.\n *\n * @param fn - The function to debounce. Always uses the latest version via a stable ref.\n * @param wait - Milliseconds to wait after the last invocation before calling `fn`.\n * @param options - Optional lodash `DebounceSettings` (e.g. `leading`, `trailing`, `maxWait`).\n * @returns A debounced function with the same signature as `fn`, plus `.cancel()` and `.flush()`.\n *\n * @example\n * const debouncedSave = useDebounceFn(saveToServer, 500);\n * <input onChange={(e) => debouncedSave(e.target.value)} />\n */\nexport function useDebounceFn<T extends noop>(fn: T, wait: number, options?: DebounceSettings) {\n    const fnRef = useEvent(fn);\n\n    const debounced = useConstant(() =>\n        debounce(\n            (...args: Parameters<T>): ReturnType<T> => {\n                return fnRef(...args);\n            },\n            wait,\n            options\n        )\n    );\n\n    useEffect(() => {\n        return () => debounced.cancel();\n    }, []);\n\n    return debounced;\n}\n","import { useEffect, useRef, useState } from \"react\";\n\n/**\n * Delays transitions to `false` by `delayMs`, but applies `true` immediately.\n *\n * @param value Current source flag.\n * @param delayMs Milliseconds to wait before committing `false`. `null`/`<=0` means no delay.\n * @param initialFlag Initial returned value on first render. Defaults to `value`.\n */\nexport function useDelayWhenFalseFlag(value: boolean, delayMs: number | null, initialFlag = value) {\n    const [delayedValue, setDelayedValue] = useState(initialFlag);\n    const timeoutRef = useRef<number | null>(null);\n\n    useEffect(() => {\n        if (timeoutRef.current !== null) {\n            clearTimeout(timeoutRef.current);\n            timeoutRef.current = null;\n        }\n\n        if (value) {\n            setDelayedValue(true);\n        } else if (delayMs == null || delayMs <= 0) {\n            setDelayedValue(false);\n        } else {\n            timeoutRef.current = setTimeout(() => {\n                timeoutRef.current = null;\n                setDelayedValue(false);\n            }, delayMs);\n        }\n\n        return () => {\n            if (timeoutRef.current !== null) {\n                clearTimeout(timeoutRef.current);\n                timeoutRef.current = null;\n            }\n        };\n    }, [value, delayMs]);\n\n    return delayedValue;\n}\n\n/**\n * Inverse of `useDelayWhenFalseFlag`: delays transitions to `true` by `delayMs`,\n * while transitions to `false` are immediate.\n *\n * @param value Current source flag.\n * @param delayMs Milliseconds to wait before committing `true`. `null`/`<=0` means no delay.\n * @param initialFlag Initial returned value on first render. Pass `false` to delay initial\n * spinner/overlay display when `value` is already `true`.\n */\nexport function useDelayWhenTrueFlag(value: boolean, delayMs: number | null, initialFlag = value) {\n    return !useDelayWhenFalseFlag(!value, delayMs, !initialFlag);\n}\n","import { useDispatch, useSelector } from \"react-redux\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { getPermissionsOfAppsSharedByUser } from \"@/api\";\nimport { alert, confirm, modal } from \"@/controllers/modals\";\nimport { AnvilDispatch } from \"@/types\";\nimport { getDevelopers } from \"@manager/api\";\nimport * as api from \"@manager/api\";\nimport { getCurrentOrganisationLicenceKey, getManagerOrganisations, loadOrganisations } from \"@manager/controller\";\n\ninterface OrgDevelopers {\n    email: string;\n    name: string;\n}\n\nexport function useDeveloperQuery() {\n    const dispatch = useDispatch<AnvilDispatch>();\n    const licenceKey = useSelector(getCurrentOrganisationLicenceKey);\n    const organisations = useSelector(getManagerOrganisations);\n    const queryClient = useQueryClient();\n\n    const { data: developers } = useQuery({\n        queryKey: [\"org-developers\", licenceKey],\n        queryFn: () => getDevelopers(licenceKey),\n        enabled: !!licenceKey,\n        staleTime: 0,\n    });\n\n    const removeDevMutation = useMutation({\n        mutationFn: async (email: string) => await api.removeDeveloper(licenceKey, email),\n        onMutate: async (email: string) => {\n            await queryClient.cancelQueries({ queryKey: [\"org-developers\", licenceKey] });\n\n            const previousDevs = queryClient.getQueryData<OrgDevelopers[]>([\"org-developers\", licenceKey]);\n            queryClient.setQueryData([\"org-developers\", licenceKey], (old: OrgDevelopers[]) =>\n                old?.filter((dev) => dev.email !== email)\n            );\n\n            return { previousDevs, email };\n        },\n        onError: (e, email, context) => {\n            if (context?.previousDevs) {\n                queryClient.setQueryData([\"org-developers\", licenceKey], context.previousDevs);\n            }\n            dispatch(\n                alert(\n                    \"Unable to remove developer\",\n                    `Could not remove ${context?.email}. Please try again or contact support@anvil.works`\n                )\n            );\n        },\n        onSettled: () => queryClient.invalidateQueries({ queryKey: [\"org-developers\", licenceKey] }),\n    });\n\n    const handleRemoveDeveloper = async (email: string) => {\n        const permissionsOfAppsOfUser = await getPermissionsOfAppsSharedByUser(licenceKey, email);\n        if (await dispatch(modal(\"removeUserFromSubscription\", { email, permissionsOfAppsOfUser }))) {\n            removeDevMutation.mutate(email);\n        }\n    };\n\n    const assignMyUserMutation = useMutation({\n        mutationFn: async () => await api.assignMyUserToOrg(licenceKey),\n        onSuccess: () => {\n            // Refresh the org list in the background so is_developer badges / ownership\n            // flags elsewhere in the manager portal catch up; doesn't block the UI.\n            dispatch(loadOrganisations());\n        },\n        onError: (e: any) => {\n            dispatch(\n                alert(\n                    \"Unable to assign your user\",\n                    e?.message ||\n                        \"Could not assign your user to this subscription. Please try again or contact support@anvil.works\"\n                )\n            );\n        },\n        onSettled: () => queryClient.invalidateQueries({ queryKey: [\"org-developers\", licenceKey] }),\n    });\n\n    const handleAssignMyUser = async () => {\n        const ownsOtherActiveOrg = organisations?.some(\n            (org: any) => org.licence_key !== licenceKey && org.status === \"active\" && org.is_developer && org.is_owner\n        );\n        const warningText = ownsOtherActiveOrg\n            ? \"Your user is currently assigned to another account  you manage with an active subscription. Assigning your user here will cancel that subscription (it will remain active until the end of its current billing period) and move you off that account and onto this one, using up one of its developer seats.\"\n            : \"This will move your Anvil user onto this account, using up one of its developer seats. You'll be removed from your current account if you are already assigned to one.\";\n        if (await dispatch(confirm(\"Assign your user to this subscription\", warningText, \"Assign my user\", \"Cancel\"))) {\n            assignMyUserMutation.mutate();\n        }\n    };\n\n    return { developers, handleRemoveDeveloper, handleAssignMyUser, isAssigningMyUser: assignMyUserMutation.isPending };\n}\n","import { useLayoutEffect } from \"react\";\nimport { useConstant } from \".\";\nimport useEvent from \"../useEventCallback\";\n\nexport function useIntersectionObserver(\n    ref: React.RefObject<Element | null>,\n    callback: IntersectionObserverCallback,\n    options?: IntersectionObserverInit\n): void {\n    const wrappedCallback = useEvent(callback);\n    const observer = useConstant(() => new IntersectionObserver(wrappedCallback, options));\n\n    useLayoutEffect(() => {\n        const currentRef = ref.current;\n        if (!currentRef) return;\n        observer.observe(currentRef);\n        return () => {\n            observer.unobserve(currentRef);\n        };\n    }, [ref.current]);\n}\n\nexport function useIsInView(\n    ref: React.RefObject<Element | null>,\n    callback: (intersecting: boolean) => void,\n    options?: IntersectionObserverInit\n): void {\n    const wrappedCallback = useEvent(callback);\n    useIntersectionObserver(\n        ref,\n        (entries) => {\n            const [entry] = entries;\n            wrappedCallback(entry.isIntersecting);\n        },\n        options\n    );\n}\n","import { useEffect } from \"react\";\nimport { ThrottleSettings, throttle } from \"lodash-es\";\nimport { useConstant } from \".\";\nimport useEvent from \"../useEventCallback\";\n\ntype noop = (...args: any[]) => any;\n\n/**\n * Returns a stable throttled version of `fn` that invokes it at most once per\n * `wait` milliseconds. The pending call is automatically cancelled when the\n * component unmounts.\n *\n * @param fn - The function to throttle. Always uses the latest version via a stable ref.\n * @param wait - Minimum milliseconds between invocations.\n * @param options - Optional lodash `ThrottleSettings` (e.g. `leading`, `trailing`).\n * @returns A throttled function with the same signature as `fn`, plus `.cancel()` and `.flush()`.\n *\n * @example\n * const throttledScroll = useThrottleFn(handleScroll, 100);\n * <div onScroll={throttledScroll} />\n */\nexport function useThrottleFn<T extends noop>(fn: T, wait: number, options?: ThrottleSettings) {\n    const fnRef = useEvent(fn);\n\n    const throttled = useConstant(() =>\n        throttle(\n            (...args: Parameters<T>): ReturnType<T> => {\n                return fnRef(...args);\n            },\n            wait,\n            options\n        )\n    );\n\n    useEffect(() => {\n        return () => throttled.cancel();\n    }, []);\n\n    return throttled;\n}\n","import { useCallback, useEffect, useRef } from \"react\";\nimport useEvent from \"../useEventCallback\";\n\ntype noop = (...args: any[]) => any;\n\n/**\n * Runs `fn` once after `delay` milliseconds, re-scheduling whenever `delay`\n * changes. Passing `null` or a negative number suspends the timer without\n * firing. The timeout is cleared automatically on unmount.\n *\n * @param fn - The callback to invoke after the delay. Always uses the latest version via a stable ref.\n * @param delay - Delay in milliseconds. Pass `null` or a negative number to disable.\n * @returns A `clear` function that cancels the pending timeout imperatively.\n *\n * @example\n * // Show a tooltip after 500 ms, cancel it on mouse-leave\n * const cancel = useTimeout(() => setVisible(true), 500);\n * <div onMouseLeave={cancel} />\n */\nexport function useTimeout<T extends noop>(fn: T, delay?: number | null) {\n    const timerCallback = useEvent(fn);\n    const timerRef = useRef<number | null>(null);\n\n    const clear = useCallback(() => {\n        if (timerRef.current) {\n            clearTimeout(timerRef.current);\n        }\n    }, []);\n\n    useEffect(() => {\n        if (delay == null || delay < 0) {\n            return;\n        }\n        timerRef.current = setTimeout(timerCallback, delay);\n        return clear;\n    }, [delay]);\n\n    return clear;\n}\n","import type { IconDefinition, IconName } from \"@fortawesome/fontawesome-svg-core\";\n\nexport const icons = [\n    { c: \"fa-500px\", l: \"500px\" },\n    { c: \"fa-adjust\", l: \"Adjust\" },\n    { c: \"fa-adn\", l: \"Adn\" },\n    { c: \"fa-align-center\", l: \"Align center\" },\n    { c: \"fa-align-justify\", l: \"Align justify\" },\n    { c: \"fa-align-left\", l: \"Align left\" },\n    { c: \"fa-align-right\", l: \"Align right\" },\n    { c: \"fa-amazon\", l: \"Amazon\" },\n    { c: \"fa-ambulance\", l: \"Ambulance\" },\n    { c: \"fa-anchor\", l: \"Anchor\" },\n    { c: \"fa-android\", l: \"Android\" },\n    { c: \"fa-angellist\", l: \"Angellist\" },\n    { c: \"fa-angle-double-down\", l: \"Angle double down\" },\n    { c: \"fa-angle-double-left\", l: \"Angle double left\" },\n    { c: \"fa-angle-double-right\", l: \"Angle double right\" },\n    { c: \"fa-angle-double-up\", l: \"Angle double up\" },\n    { c: \"fa-angle-down\", l: \"Angle down\" },\n    { c: \"fa-angle-left\", l: \"Angle left\" },\n    { c: \"fa-angle-right\", l: \"Angle right\" },\n    { c: \"fa-angle-up\", l: \"Angle up\" },\n    { c: \"fa-apple\", l: \"Apple\" },\n    { c: \"fa-archive\", l: \"Archive\" },\n    { c: \"fa-area-chart\", l: \"Area chart\" },\n    { c: \"fa-arrow-circle-down\", l: \"Arrow circle down\" },\n    { c: \"fa-arrow-circle-left\", l: \"Arrow circle left\" },\n    { c: \"fa-arrow-circle-o-down\", l: \"Arrow circle o down\" },\n    { c: \"fa-arrow-circle-o-left\", l: \"Arrow circle o left\" },\n    { c: \"fa-arrow-circle-o-right\", l: \"Arrow circle o right\" },\n    { c: \"fa-arrow-circle-o-up\", l: \"Arrow circle o up\" },\n    { c: \"fa-arrow-circle-right\", l: \"Arrow circle right\" },\n    { c: \"fa-arrow-circle-up\", l: \"Arrow circle up\" },\n    { c: \"fa-arrow-down\", l: \"Arrow down\" },\n    { c: \"fa-arrow-left\", l: \"Arrow left\" },\n    { c: \"fa-arrow-right\", l: \"Arrow right\" },\n    { c: \"fa-arrow-up\", l: \"Arrow up\" },\n    { c: \"fa-arrows\", l: \"Arrows\" },\n    { c: \"fa-arrows-alt\", l: \"Arrows alt\" },\n    { c: \"fa-arrows-h\", l: \"Arrows h\" },\n    { c: \"fa-arrows-v\", l: \"Arrows v\" },\n    { c: \"fa-asterisk\", l: \"Asterisk\" },\n    { c: \"fa-at\", l: \"At\" },\n    { c: \"fa-backward\", l: \"Backward\" },\n    { c: \"fa-balance-scale\", l: \"Balance scale\" },\n    { c: \"fa-ban\", l: \"Ban\" },\n    { c: \"fa-bar-chart\", l: \"Bar chart\" },\n    { c: \"fa-barcode\", l: \"Barcode\" },\n    { c: \"fa-bars\", l: \"Bars\" },\n    { c: \"fa-battery-empty\", l: \"Battery empty\" },\n    { c: \"fa-battery-full\", l: \"Battery full\" },\n    { c: \"fa-battery-half\", l: \"Battery half\" },\n    { c: \"fa-battery-quarter\", l: \"Battery quarter\" },\n    { c: \"fa-battery-three-quarters\", l: \"Battery three quarters\" },\n    { c: \"fa-bed\", l: \"Bed\" },\n    { c: \"fa-beer\", l: \"Beer\" },\n    { c: \"fa-behance\", l: \"Behance\" },\n    { c: \"fa-behance-square\", l: \"Behance square\" },\n    { c: \"fa-bell\", l: \"Bell\" },\n    { c: \"fa-bell-o\", l: \"Bell o\" },\n    { c: \"fa-bell-slash\", l: \"Bell slash\" },\n    { c: \"fa-bell-slash-o\", l: \"Bell slash o\" },\n    { c: \"fa-bicycle\", l: \"Bicycle\" },\n    { c: \"fa-binoculars\", l: \"Binoculars\" },\n    { c: \"fa-birthday-cake\", l: \"Birthday cake\" },\n    { c: \"fa-bitbucket\", l: \"Bitbucket\" },\n    { c: \"fa-bitbucket-square\", l: \"Bitbucket square\" },\n    { c: \"fa-black-tie\", l: \"Black tie\" },\n    { c: \"fa-bold\", l: \"Bold\" },\n    { c: \"fa-bolt\", l: \"Bolt\" },\n    { c: \"fa-bomb\", l: \"Bomb\" },\n    { c: \"fa-book\", l: \"Book\" },\n    { c: \"fa-bookmark\", l: \"Bookmark\" },\n    { c: \"fa-bookmark-o\", l: \"Bookmark o\" },\n    { c: \"fa-briefcase\", l: \"Briefcase\" },\n    { c: \"fa-btc\", l: \"Btc\" },\n    { c: \"fa-bug\", l: \"Bug\" },\n    { c: \"fa-building\", l: \"Building\" },\n    { c: \"fa-building-o\", l: \"Building o\" },\n    { c: \"fa-bullhorn\", l: \"Bullhorn\" },\n    { c: \"fa-bullseye\", l: \"Bullseye\" },\n    { c: \"fa-bus\", l: \"Bus\" },\n    { c: \"fa-buysellads\", l: \"Buysellads\" },\n    { c: \"fa-calculator\", l: \"Calculator\" },\n    { c: \"fa-calendar\", l: \"Calendar\" },\n    { c: \"fa-calendar-check-o\", l: \"Calendar check o\" },\n    { c: \"fa-calendar-minus-o\", l: \"Calendar minus o\" },\n    { c: \"fa-calendar-o\", l: \"Calendar o\" },\n    { c: \"fa-calendar-plus-o\", l: \"Calendar plus o\" },\n    { c: \"fa-calendar-times-o\", l: \"Calendar times o\" },\n    { c: \"fa-camera\", l: \"Camera\" },\n    { c: \"fa-camera-retro\", l: \"Camera retro\" },\n    { c: \"fa-car\", l: \"Car\" },\n    { c: \"fa-caret-down\", l: \"Caret down\" },\n    { c: \"fa-caret-left\", l: \"Caret left\" },\n    { c: \"fa-caret-right\", l: \"Caret right\" },\n    { c: \"fa-caret-square-o-down\", l: \"Caret square o down\" },\n    { c: \"fa-caret-square-o-left\", l: \"Caret square o left\" },\n    { c: \"fa-caret-square-o-right\", l: \"Caret square o right\" },\n    { c: \"fa-caret-square-o-up\", l: \"Caret square o up\" },\n    { c: \"fa-caret-up\", l: \"Caret up\" },\n    { c: \"fa-cart-arrow-down\", l: \"Cart arrow down\" },\n    { c: \"fa-cart-plus\", l: \"Cart plus\" },\n    { c: \"fa-cc\", l: \"Cc\" },\n    { c: \"fa-cc-amex\", l: \"Cc amex\" },\n    { c: \"fa-cc-diners-club\", l: \"Cc diners club\" },\n    { c: \"fa-cc-discover\", l: \"Cc discover\" },\n    { c: \"fa-cc-jcb\", l: \"Cc jcb\" },\n    { c: \"fa-cc-mastercard\", l: \"Cc mastercard\" },\n    { c: \"fa-cc-paypal\", l: \"Cc paypal\" },\n    { c: \"fa-cc-stripe\", l: \"Cc stripe\" },\n    { c: \"fa-cc-visa\", l: \"Cc visa\" },\n    { c: \"fa-certificate\", l: \"Certificate\" },\n    { c: \"fa-chain-broken\", l: \"Chain broken\" },\n    { c: \"fa-check\", l: \"Check\" },\n    { c: \"fa-check-circle\", l: \"Check circle\" },\n    { c: \"fa-check-circle-o\", l: \"Check circle o\" },\n    { c: \"fa-check-square\", l: \"Check square\" },\n    { c: \"fa-check-square-o\", l: \"Check square o\" },\n    { c: \"fa-chevron-circle-down\", l: \"Chevron circle down\" },\n    { c: \"fa-chevron-circle-left\", l: \"Chevron circle left\" },\n    { c: \"fa-chevron-circle-right\", l: \"Chevron circle right\" },\n    { c: \"fa-chevron-circle-up\", l: \"Chevron circle up\" },\n    { c: \"fa-chevron-down\", l: \"Chevron down\" },\n    { c: \"fa-chevron-left\", l: \"Chevron left\" },\n    { c: \"fa-chevron-right\", l: \"Chevron right\" },\n    { c: \"fa-chevron-up\", l: \"Chevron up\" },\n    { c: \"fa-child\", l: \"Child\" },\n    { c: \"fa-chrome\", l: \"Chrome\" },\n    { c: \"fa-circle\", l: \"Circle\" },\n    { c: \"fa-circle-o\", l: \"Circle o\" },\n    { c: \"fa-circle-o-notch\", l: \"Circle o notch\" },\n    { c: \"fa-circle-thin\", l: \"Circle thin\" },\n    { c: \"fa-clipboard\", l: \"Clipboard\" },\n    { c: \"fa-clock-o\", l: \"Clock o\" },\n    { c: \"fa-clone\", l: \"Clone\" },\n    { c: \"fa-cloud\", l: \"Cloud\" },\n    { c: \"fa-cloud-download\", l: \"Cloud download\" },\n    { c: \"fa-cloud-upload\", l: \"Cloud upload\" },\n    { c: \"fa-code\", l: \"Code\" },\n    { c: \"fa-code-fork\", l: \"Code fork\" },\n    { c: \"fa-codepen\", l: \"Codepen\" },\n    { c: \"fa-coffee\", l: \"Coffee\" },\n    { c: \"fa-cog\", l: \"Cog\" },\n    { c: \"fa-cogs\", l: \"Cogs\" },\n    { c: \"fa-columns\", l: \"Columns\" },\n    { c: \"fa-comment\", l: \"Comment\" },\n    { c: \"fa-comment-o\", l: \"Comment o\" },\n    { c: \"fa-commenting\", l: \"Commenting\" },\n    { c: \"fa-commenting-o\", l: \"Commenting o\" },\n    { c: \"fa-comments\", l: \"Comments\" },\n    { c: \"fa-comments-o\", l: \"Comments o\" },\n    { c: \"fa-compass\", l: \"Compass\" },\n    { c: \"fa-compress\", l: \"Compress\" },\n    { c: \"fa-connectdevelop\", l: \"Connectdevelop\" },\n    { c: \"fa-contao\", l: \"Contao\" },\n    { c: \"fa-copyright\", l: \"Copyright\" },\n    { c: \"fa-creative-commons\", l: \"Creative commons\" },\n    { c: \"fa-credit-card\", l: \"Credit card\" },\n    { c: \"fa-crop\", l: \"Crop\" },\n    { c: \"fa-crosshairs\", l: \"Crosshairs\" },\n    { c: \"fa-css3\", l: \"Css3\" },\n    { c: \"fa-cube\", l: \"Cube\" },\n    { c: \"fa-cubes\", l: \"Cubes\" },\n    { c: \"fa-cutlery\", l: \"Cutlery\" },\n    { c: \"fa-dashcube\", l: \"Dashcube\" },\n    { c: \"fa-database\", l: \"Database\" },\n    { c: \"fa-delicious\", l: \"Delicious\" },\n    { c: \"fa-desktop\", l: \"Desktop\" },\n    { c: \"fa-deviantart\", l: \"Deviantart\" },\n    { c: \"fa-diamond\", l: \"Diamond\" },\n    { c: \"fa-digg\", l: \"Digg\" },\n    { c: \"fa-dot-circle-o\", l: \"Dot circle o\" },\n    { c: \"fa-download\", l: \"Download\" },\n    { c: \"fa-dribbble\", l: \"Dribbble\" },\n    { c: \"fa-dropbox\", l: \"Dropbox\" },\n    { c: \"fa-drupal\", l: \"Drupal\" },\n    { c: \"fa-eject\", l: \"Eject\" },\n    { c: \"fa-ellipsis-h\", l: \"Ellipsis h\" },\n    { c: \"fa-ellipsis-v\", l: \"Ellipsis v\" },\n    { c: \"fa-empire\", l: \"Empire\" },\n    { c: \"fa-envelope\", l: \"Envelope\" },\n    { c: \"fa-envelope-o\", l: \"Envelope o\" },\n    { c: \"fa-envelope-square\", l: \"Envelope square\" },\n    { c: \"fa-eraser\", l: \"Eraser\" },\n    { c: \"fa-eur\", l: \"Eur\" },\n    { c: \"fa-exchange\", l: \"Exchange\" },\n    { c: \"fa-exclamation\", l: \"Exclamation\" },\n    { c: \"fa-exclamation-circle\", l: \"Exclamation circle\" },\n    { c: \"fa-exclamation-triangle\", l: \"Exclamation triangle\" },\n    { c: \"fa-expand\", l: \"Expand\" },\n    { c: \"fa-expeditedssl\", l: \"Expeditedssl\" },\n    { c: \"fa-external-link\", l: \"External link\" },\n    { c: \"fa-external-link-square\", l: \"External link square\" },\n    { c: \"fa-eye\", l: \"Eye\" },\n    { c: \"fa-eye-slash\", l: \"Eye slash\" },\n    { c: \"fa-eyedropper\", l: \"Eyedropper\" },\n    { c: \"fa-facebook\", l: \"Facebook\" },\n    { c: \"fa-facebook-official\", l: \"Facebook official\" },\n    { c: \"fa-facebook-square\", l: \"Facebook square\" },\n    { c: \"fa-fast-backward\", l: \"Fast backward\" },\n    { c: \"fa-fast-forward\", l: \"Fast forward\" },\n    { c: \"fa-fax\", l: \"Fax\" },\n    { c: \"fa-female\", l: \"Female\" },\n    { c: \"fa-fighter-jet\", l: \"Fighter jet\" },\n    { c: \"fa-file\", l: \"File\" },\n    { c: \"fa-file-archive-o\", l: \"File archive o\" },\n    { c: \"fa-file-audio-o\", l: \"File audio o\" },\n    { c: \"fa-file-code-o\", l: \"File code o\" },\n    { c: \"fa-file-excel-o\", l: \"File excel o\" },\n    { c: \"fa-file-image-o\", l: \"File image o\" },\n    { c: \"fa-file-o\", l: \"File o\" },\n    { c: \"fa-file-pdf-o\", l: \"File pdf o\" },\n    { c: \"fa-file-powerpoint-o\", l: \"File powerpoint o\" },\n    { c: \"fa-file-text\", l: \"File text\" },\n    { c: \"fa-file-text-o\", l: \"File text o\" },\n    { c: \"fa-file-video-o\", l: \"File video o\" },\n    { c: \"fa-file-word-o\", l: \"File word o\" },\n    { c: \"fa-files-o\", l: \"Files o\" },\n    { c: \"fa-film\", l: \"Film\" },\n    { c: \"fa-filter\", l: \"Filter\" },\n    { c: \"fa-fire\", l: \"Fire\" },\n    { c: \"fa-fire-extinguisher\", l: \"Fire extinguisher\" },\n    { c: \"fa-firefox\", l: \"Firefox\" },\n    { c: \"fa-flag\", l: \"Flag\" },\n    { c: \"fa-flag-checkered\", l: \"Flag checkered\" },\n    { c: \"fa-flag-o\", l: \"Flag o\" },\n    { c: \"fa-flask\", l: \"Flask\" },\n    { c: \"fa-flickr\", l: \"Flickr\" },\n    { c: \"fa-floppy-o\", l: \"Floppy o\" },\n    { c: \"fa-folder\", l: \"Folder\" },\n    { c: \"fa-folder-o\", l: \"Folder o\" },\n    { c: \"fa-folder-open\", l: \"Folder open\" },\n    { c: \"fa-folder-open-o\", l: \"Folder open o\" },\n    { c: \"fa-font\", l: \"Font\" },\n    { c: \"fa-fonticons\", l: \"Fonticons\" },\n    { c: \"fa-forumbee\", l: \"Forumbee\" },\n    { c: \"fa-forward\", l: \"Forward\" },\n    { c: \"fa-foursquare\", l: \"Foursquare\" },\n    { c: \"fa-frown-o\", l: \"Frown o\" },\n    { c: \"fa-futbol-o\", l: \"Futbol o\" },\n    { c: \"fa-gamepad\", l: \"Gamepad\" },\n    { c: \"fa-gavel\", l: \"Gavel\" },\n    { c: \"fa-gbp\", l: \"Gbp\" },\n    { c: \"fa-genderless\", l: \"Genderless\" },\n    { c: \"fa-get-pocket\", l: \"Get pocket\" },\n    { c: \"fa-gg\", l: \"Gg\" },\n    { c: \"fa-gg-circle\", l: \"Gg circle\" },\n    { c: \"fa-gift\", l: \"Gift\" },\n    { c: \"fa-git\", l: \"Git\" },\n    { c: \"fa-git-square\", l: \"Git square\" },\n    { c: \"fa-github\", l: \"Github\" },\n    { c: \"fa-github-alt\", l: \"Github alt\" },\n    { c: \"fa-github-square\", l: \"Github square\" },\n    { c: \"fa-glass\", l: \"Glass\" },\n    { c: \"fa-globe\", l: \"Globe\" },\n    { c: \"fa-google\", l: \"Google\" },\n    { c: \"fa-google-plus\", l: \"Google plus\" },\n    { c: \"fa-google-plus-square\", l: \"Google plus square\" },\n    { c: \"fa-google-wallet\", l: \"Google wallet\" },\n    { c: \"fa-graduation-cap\", l: \"Graduation cap\" },\n    { c: \"fa-gratipay\", l: \"Gratipay\" },\n    { c: \"fa-h-square\", l: \"H square\" },\n    { c: \"fa-hacker-news\", l: \"Hacker news\" },\n    { c: \"fa-hand-lizard-o\", l: \"Hand lizard o\" },\n    { c: \"fa-hand-o-down\", l: \"Hand o down\" },\n    { c: \"fa-hand-o-left\", l: \"Hand o left\" },\n    { c: \"fa-hand-o-right\", l: \"Hand o right\" },\n    { c: \"fa-hand-o-up\", l: \"Hand o up\" },\n    { c: \"fa-hand-paper-o\", l: \"Hand paper o\" },\n    { c: \"fa-hand-peace-o\", l: \"Hand peace o\" },\n    { c: \"fa-hand-pointer-o\", l: \"Hand pointer o\" },\n    { c: \"fa-hand-rock-o\", l: \"Hand rock o\" },\n    { c: \"fa-hand-scissors-o\", l: \"Hand scissors o\" },\n    { c: \"fa-hand-spock-o\", l: \"Hand spock o\" },\n    { c: \"fa-hdd-o\", l: \"Hdd o\" },\n    { c: \"fa-header\", l: \"Header\" },\n    { c: \"fa-headphones\", l: \"Headphones\" },\n    { c: \"fa-heart\", l: \"Heart\" },\n    { c: \"fa-heart-o\", l: \"Heart o\" },\n    { c: \"fa-heartbeat\", l: \"Heartbeat\" },\n    { c: \"fa-history\", l: \"History\" },\n    { c: \"fa-home\", l: \"Home\" },\n    { c: \"fa-hospital-o\", l: \"Hospital o\" },\n    { c: \"fa-hourglass\", l: \"Hourglass\" },\n    { c: \"fa-hourglass-end\", l: \"Hourglass end\" },\n    { c: \"fa-hourglass-half\", l: \"Hourglass half\" },\n    { c: \"fa-hourglass-o\", l: \"Hourglass o\" },\n    { c: \"fa-hourglass-start\", l: \"Hourglass start\" },\n    { c: \"fa-houzz\", l: \"Houzz\" },\n    { c: \"fa-html5\", l: \"Html5\" },\n    { c: \"fa-i-cursor\", l: \"I cursor\" },\n    { c: \"fa-ils\", l: \"Ils\" },\n    { c: \"fa-inbox\", l: \"Inbox\" },\n    { c: \"fa-indent\", l: \"Indent\" },\n    { c: \"fa-industry\", l: \"Industry\" },\n    { c: \"fa-info\", l: \"Info\" },\n    { c: \"fa-info-circle\", l: \"Info circle\" },\n    { c: \"fa-inr\", l: \"Inr\" },\n    { c: \"fa-instagram\", l: \"Instagram\" },\n    { c: \"fa-internet-explorer\", l: \"Internet explorer\" },\n    { c: \"fa-ioxhost\", l: \"Ioxhost\" },\n    { c: \"fa-italic\", l: \"Italic\" },\n    { c: \"fa-joomla\", l: \"Joomla\" },\n    { c: \"fa-jpy\", l: \"Jpy\" },\n    { c: \"fa-jsfiddle\", l: \"Jsfiddle\" },\n    { c: \"fa-key\", l: \"Key\" },\n    { c: \"fa-keyboard-o\", l: \"Keyboard o\" },\n    { c: \"fa-krw\", l: \"Krw\" },\n    { c: \"fa-language\", l: \"Language\" },\n    { c: \"fa-laptop\", l: \"Laptop\" },\n    { c: \"fa-lastfm\", l: \"Lastfm\" },\n    { c: \"fa-lastfm-square\", l: \"Lastfm square\" },\n    { c: \"fa-leaf\", l: \"Leaf\" },\n    { c: \"fa-leanpub\", l: \"Leanpub\" },\n    { c: \"fa-lemon-o\", l: \"Lemon o\" },\n    { c: \"fa-level-down\", l: \"Level down\" },\n    { c: \"fa-level-up\", l: \"Level up\" },\n    { c: \"fa-life-ring\", l: \"Life ring\" },\n    { c: \"fa-lightbulb-o\", l: \"Lightbulb o\" },\n    { c: \"fa-line-chart\", l: \"Line chart\" },\n    { c: \"fa-link\", l: \"Link\" },\n    { c: \"fa-linkedin\", l: \"Linkedin\" },\n    { c: \"fa-linkedin-square\", l: \"Linkedin square\" },\n    { c: \"fa-linux\", l: \"Linux\" },\n    { c: \"fa-list\", l: \"List\" },\n    { c: \"fa-list-alt\", l: \"List alt\" },\n    { c: \"fa-list-ol\", l: \"List ol\" },\n    { c: \"fa-list-ul\", l: \"List ul\" },\n    { c: \"fa-location-arrow\", l: \"Location arrow\" },\n    { c: \"fa-lock\", l: \"Lock\" },\n    { c: \"fa-long-arrow-down\", l: \"Long arrow down\" },\n    { c: \"fa-long-arrow-left\", l: \"Long arrow left\" },\n    { c: \"fa-long-arrow-right\", l: \"Long arrow right\" },\n    { c: \"fa-long-arrow-up\", l: \"Long arrow up\" },\n    { c: \"fa-magic\", l: \"Magic\" },\n    { c: \"fa-magnet\", l: \"Magnet\" },\n    { c: \"fa-male\", l: \"Male\" },\n    { c: \"fa-map\", l: \"Map\" },\n    { c: \"fa-map-marker\", l: \"Map marker\" },\n    { c: \"fa-map-o\", l: \"Map o\" },\n    { c: \"fa-map-pin\", l: \"Map pin\" },\n    { c: \"fa-map-signs\", l: \"Map signs\" },\n    { c: \"fa-mars\", l: \"Mars\" },\n    { c: \"fa-mars-double\", l: \"Mars double\" },\n    { c: \"fa-mars-stroke\", l: \"Mars stroke\" },\n    { c: \"fa-mars-stroke-h\", l: \"Mars stroke h\" },\n    { c: \"fa-mars-stroke-v\", l: \"Mars stroke v\" },\n    { c: \"fa-maxcdn\", l: \"Maxcdn\" },\n    { c: \"fa-meanpath\", l: \"Meanpath\" },\n    { c: \"fa-medium\", l: \"Medium\" },\n    { c: \"fa-medkit\", l: \"Medkit\" },\n    { c: \"fa-meh-o\", l: \"Meh o\" },\n    { c: \"fa-mercury\", l: \"Mercury\" },\n    { c: \"fa-microphone\", l: \"Microphone\" },\n    { c: \"fa-microphone-slash\", l: \"Microphone slash\" },\n    { c: \"fa-minus\", l: \"Minus\" },\n    { c: \"fa-minus-circle\", l: \"Minus circle\" },\n    { c: \"fa-minus-square\", l: \"Minus square\" },\n    { c: \"fa-minus-square-o\", l: \"Minus square o\" },\n    { c: \"fa-mobile\", l: \"Mobile\" },\n    { c: \"fa-money\", l: \"Money\" },\n    { c: \"fa-moon-o\", l: \"Moon o\" },\n    { c: \"fa-motorcycle\", l: \"Motorcycle\" },\n    { c: \"fa-mouse-pointer\", l: \"Mouse pointer\" },\n    { c: \"fa-music\", l: \"Music\" },\n    { c: \"fa-neuter\", l: \"Neuter\" },\n    { c: \"fa-newspaper-o\", l: \"Newspaper o\" },\n    { c: \"fa-object-group\", l: \"Object group\" },\n    { c: \"fa-object-ungroup\", l: \"Object ungroup\" },\n    { c: \"fa-odnoklassniki\", l: \"Odnoklassniki\" },\n    { c: \"fa-odnoklassniki-square\", l: \"Odnoklassniki square\" },\n    { c: \"fa-opencart\", l: \"Opencart\" },\n    { c: \"fa-openid\", l: \"Openid\" },\n    { c: \"fa-opera\", l: \"Opera\" },\n    { c: \"fa-optin-monster\", l: \"Optin monster\" },\n    { c: \"fa-outdent\", l: \"Outdent\" },\n    { c: \"fa-pagelines\", l: \"Pagelines\" },\n    { c: \"fa-paint-brush\", l: \"Paint brush\" },\n    { c: \"fa-paper-plane\", l: \"Paper plane\" },\n    { c: \"fa-paper-plane-o\", l: \"Paper plane o\" },\n    { c: \"fa-paperclip\", l: \"Paperclip\" },\n    { c: \"fa-paragraph\", l: \"Paragraph\" },\n    { c: \"fa-pause\", l: \"Pause\" },\n    { c: \"fa-paw\", l: \"Paw\" },\n    { c: \"fa-paypal\", l: \"Paypal\" },\n    { c: \"fa-pencil\", l: \"Pencil\" },\n    { c: \"fa-pencil-square\", l: \"Pencil square\" },\n    { c: \"fa-pencil-square-o\", l: \"Pencil square o\" },\n    { c: \"fa-phone\", l: \"Phone\" },\n    { c: \"fa-phone-square\", l: \"Phone square\" },\n    { c: \"fa-picture-o\", l: \"Picture o\" },\n    { c: \"fa-pie-chart\", l: \"Pie chart\" },\n    { c: \"fa-pied-piper\", l: \"Pied piper\" },\n    { c: \"fa-pied-piper-alt\", l: \"Pied piper alt\" },\n    { c: \"fa-pinterest\", l: \"Pinterest\" },\n    { c: \"fa-pinterest-p\", l: \"Pinterest p\" },\n    { c: \"fa-pinterest-square\", l: \"Pinterest square\" },\n    { c: \"fa-plane\", l: \"Plane\" },\n    { c: \"fa-play\", l: \"Play\" },\n    { c: \"fa-play-circle\", l: \"Play circle\" },\n    { c: \"fa-play-circle-o\", l: \"Play circle o\" },\n    { c: \"fa-plug\", l: \"Plug\" },\n    { c: \"fa-plus\", l: \"Plus\" },\n    { c: \"fa-plus-circle\", l: \"Plus circle\" },\n    { c: \"fa-plus-square\", l: \"Plus square\" },\n    { c: \"fa-plus-square-o\", l: \"Plus square o\" },\n    { c: \"fa-power-off\", l: \"Power off\" },\n    { c: \"fa-print\", l: \"Print\" },\n    { c: \"fa-puzzle-piece\", l: \"Puzzle piece\" },\n    { c: \"fa-qq\", l: \"Qq\" },\n    { c: \"fa-qrcode\", l: \"Qrcode\" },\n    { c: \"fa-question\", l: \"Question\" },\n    { c: \"fa-question-circle\", l: \"Question circle\" },\n    { c: \"fa-quote-left\", l: \"Quote left\" },\n    { c: \"fa-quote-right\", l: \"Quote right\" },\n    { c: \"fa-random\", l: \"Random\" },\n    { c: \"fa-rebel\", l: \"Rebel\" },\n    { c: \"fa-recycle\", l: \"Recycle\" },\n    { c: \"fa-reddit\", l: \"Reddit\" },\n    { c: \"fa-reddit-square\", l: \"Reddit square\" },\n    { c: \"fa-refresh\", l: \"Refresh\" },\n    { c: \"fa-registered\", l: \"Registered\" },\n    { c: \"fa-renren\", l: \"Renren\" },\n    { c: \"fa-repeat\", l: \"Repeat\" },\n    { c: \"fa-reply\", l: \"Reply\" },\n    { c: \"fa-reply-all\", l: \"Reply all\" },\n    { c: \"fa-retweet\", l: \"Retweet\" },\n    { c: \"fa-road\", l: \"Road\" },\n    { c: \"fa-rocket\", l: \"Rocket\" },\n    { c: \"fa-rss\", l: \"Rss\" },\n    { c: \"fa-rss-square\", l: \"Rss square\" },\n    { c: \"fa-rub\", l: \"Rub\" },\n    { c: \"fa-safari\", l: \"Safari\" },\n    { c: \"fa-scissors\", l: \"Scissors\" },\n    { c: \"fa-search\", l: \"Search\" },\n    { c: \"fa-search-minus\", l: \"Search minus\" },\n    { c: \"fa-search-plus\", l: \"Search plus\" },\n    { c: \"fa-sellsy\", l: \"Sellsy\" },\n    { c: \"fa-server\", l: \"Server\" },\n    { c: \"fa-share\", l: \"Share\" },\n    { c: \"fa-share-alt\", l: \"Share alt\" },\n    { c: \"fa-share-alt-square\", l: \"Share alt square\" },\n    { c: \"fa-share-square\", l: \"Share square\" },\n    { c: \"fa-share-square-o\", l: \"Share square o\" },\n    { c: \"fa-shield\", l: \"Shield\" },\n    { c: \"fa-ship\", l: \"Ship\" },\n    { c: \"fa-shirtsinbulk\", l: \"Shirtsinbulk\" },\n    { c: \"fa-shopping-cart\", l: \"Shopping cart\" },\n    { c: \"fa-sign-in\", l: \"Sign in\" },\n    { c: \"fa-sign-out\", l: \"Sign out\" },\n    { c: \"fa-signal\", l: \"Signal\" },\n    { c: \"fa-simplybuilt\", l: \"Simplybuilt\" },\n    { c: \"fa-sitemap\", l: \"Sitemap\" },\n    { c: \"fa-skyatlas\", l: \"Skyatlas\" },\n    { c: \"fa-skype\", l: \"Skype\" },\n    { c: \"fa-slack\", l: \"Slack\" },\n    { c: \"fa-sliders\", l: \"Sliders\" },\n    { c: \"fa-slideshare\", l: \"Slideshare\" },\n    { c: \"fa-smile-o\", l: \"Smile o\" },\n    { c: \"fa-sort\", l: \"Sort\" },\n    { c: \"fa-sort-alpha-asc\", l: \"Sort alpha asc\" },\n    { c: \"fa-sort-alpha-desc\", l: \"Sort alpha desc\" },\n    { c: \"fa-sort-amount-asc\", l: \"Sort amount asc\" },\n    { c: \"fa-sort-amount-desc\", l: \"Sort amount desc\" },\n    { c: \"fa-sort-asc\", l: \"Sort asc\" },\n    { c: \"fa-sort-desc\", l: \"Sort desc\" },\n    { c: \"fa-sort-numeric-asc\", l: \"Sort numeric asc\" },\n    { c: \"fa-sort-numeric-desc\", l: \"Sort numeric desc\" },\n    { c: \"fa-soundcloud\", l: \"Soundcloud\" },\n    { c: \"fa-space-shuttle\", l: \"Space shuttle\" },\n    { c: \"fa-spinner\", l: \"Spinner\" },\n    { c: \"fa-spoon\", l: \"Spoon\" },\n    { c: \"fa-spotify\", l: \"Spotify\" },\n    { c: \"fa-square\", l: \"Square\" },\n    { c: \"fa-square-o\", l: \"Square o\" },\n    { c: \"fa-stack-exchange\", l: \"Stack exchange\" },\n    { c: \"fa-stack-overflow\", l: \"Stack overflow\" },\n    { c: \"fa-star\", l: \"Star\" },\n    { c: \"fa-star-half\", l: \"Star half\" },\n    { c: \"fa-star-half-o\", l: \"Star half o\" },\n    { c: \"fa-star-o\", l: \"Star o\" },\n    { c: \"fa-steam\", l: \"Steam\" },\n    { c: \"fa-steam-square\", l: \"Steam square\" },\n    { c: \"fa-step-backward\", l: \"Step backward\" },\n    { c: \"fa-step-forward\", l: \"Step forward\" },\n    { c: \"fa-stethoscope\", l: \"Stethoscope\" },\n    { c: \"fa-sticky-note\", l: \"Sticky note\" },\n    { c: \"fa-sticky-note-o\", l: \"Sticky note o\" },\n    { c: \"fa-stop\", l: \"Stop\" },\n    { c: \"fa-street-view\", l: \"Street view\" },\n    { c: \"fa-strikethrough\", l: \"Strikethrough\" },\n    { c: \"fa-stumbleupon\", l: \"Stumbleupon\" },\n    { c: \"fa-stumbleupon-circle\", l: \"Stumbleupon circle\" },\n    { c: \"fa-subscript\", l: \"Subscript\" },\n    { c: \"fa-subway\", l: \"Subway\" },\n    { c: \"fa-suitcase\", l: \"Suitcase\" },\n    { c: \"fa-sun-o\", l: \"Sun o\" },\n    { c: \"fa-superscript\", l: \"Superscript\" },\n    { c: \"fa-table\", l: \"Table\" },\n    { c: \"fa-tablet\", l: \"Tablet\" },\n    { c: \"fa-tachometer\", l: \"Tachometer\" },\n    { c: \"fa-tag\", l: \"Tag\" },\n    { c: \"fa-tags\", l: \"Tags\" },\n    { c: \"fa-tasks\", l: \"Tasks\" },\n    { c: \"fa-taxi\", l: \"Taxi\" },\n    { c: \"fa-television\", l: \"Television\" },\n    { c: \"fa-tencent-weibo\", l: \"Tencent weibo\" },\n    { c: \"fa-terminal\", l: \"Terminal\" },\n    { c: \"fa-text-height\", l: \"Text height\" },\n    { c: \"fa-text-width\", l: \"Text width\" },\n    { c: \"fa-th\", l: \"Th\" },\n    { c: \"fa-th-large\", l: \"Th large\" },\n    { c: \"fa-th-list\", l: \"Th list\" },\n    { c: \"fa-thumb-tack\", l: \"Thumb tack\" },\n    { c: \"fa-thumbs-down\", l: \"Thumbs down\" },\n    { c: \"fa-thumbs-o-down\", l: \"Thumbs o down\" },\n    { c: \"fa-thumbs-o-up\", l: \"Thumbs o up\" },\n    { c: \"fa-thumbs-up\", l: \"Thumbs up\" },\n    { c: \"fa-ticket\", l: \"Ticket\" },\n    { c: \"fa-times\", l: \"Times\" },\n    { c: \"fa-times-circle\", l: \"Times circle\" },\n    { c: \"fa-times-circle-o\", l: \"Times circle o\" },\n    { c: \"fa-tint\", l: \"Tint\" },\n    { c: \"fa-toggle-off\", l: \"Toggle off\" },\n    { c: \"fa-toggle-on\", l: \"Toggle on\" },\n    { c: \"fa-trademark\", l: \"Trademark\" },\n    { c: \"fa-train\", l: \"Train\" },\n    { c: \"fa-transgender\", l: \"Transgender\" },\n    { c: \"fa-transgender-alt\", l: \"Transgender alt\" },\n    { c: \"fa-trash\", l: \"Trash\" },\n    { c: \"fa-trash-o\", l: \"Trash o\" },\n    { c: \"fa-tree\", l: \"Tree\" },\n    { c: \"fa-trello\", l: \"Trello\" },\n    { c: \"fa-tripadvisor\", l: \"Tripadvisor\" },\n    { c: \"fa-trophy\", l: \"Trophy\" },\n    { c: \"fa-truck\", l: \"Truck\" },\n    { c: \"fa-try\", l: \"Try\" },\n    { c: \"fa-tty\", l: \"Tty\" },\n    { c: \"fa-tumblr\", l: \"Tumblr\" },\n    { c: \"fa-tumblr-square\", l: \"Tumblr square\" },\n    { c: \"fa-twitch\", l: \"Twitch\" },\n    { c: \"fa-twitter\", l: \"Twitter\" },\n    { c: \"fa-twitter-square\", l: \"Twitter square\" },\n    { c: \"fa-umbrella\", l: \"Umbrella\" },\n    { c: \"fa-underline\", l: \"Underline\" },\n    { c: \"fa-undo\", l: \"Undo\" },\n    { c: \"fa-university\", l: \"University\" },\n    { c: \"fa-unlock\", l: \"Unlock\" },\n    { c: \"fa-unlock-alt\", l: \"Unlock alt\" },\n    { c: \"fa-upload\", l: \"Upload\" },\n    { c: \"fa-usd\", l: \"Usd\" },\n    { c: \"fa-user\", l: \"User\" },\n    { c: \"fa-user-md\", l: \"User md\" },\n    { c: \"fa-user-plus\", l: \"User plus\" },\n    { c: \"fa-user-secret\", l: \"User secret\" },\n    { c: \"fa-user-times\", l: \"User times\" },\n    { c: \"fa-users\", l: \"Users\" },\n    { c: \"fa-venus\", l: \"Venus\" },\n    { c: \"fa-venus-double\", l: \"Venus double\" },\n    { c: \"fa-venus-mars\", l: \"Venus mars\" },\n    { c: \"fa-viacoin\", l: \"Viacoin\" },\n    { c: \"fa-video-camera\", l: \"Video camera\" },\n    { c: \"fa-vimeo\", l: \"Vimeo\" },\n    { c: \"fa-vimeo-square\", l: \"Vimeo square\" },\n    { c: \"fa-vine\", l: \"Vine\" },\n    { c: \"fa-vk\", l: \"Vk\" },\n    { c: \"fa-volume-down\", l: \"Volume down\" },\n    { c: \"fa-volume-off\", l: \"Volume off\" },\n    { c: \"fa-volume-up\", l: \"Volume up\" },\n    { c: \"fa-weibo\", l: \"Weibo\" },\n    { c: \"fa-weixin\", l: \"Weixin\" },\n    { c: \"fa-whatsapp\", l: \"Whatsapp\" },\n    { c: \"fa-wheelchair\", l: \"Wheelchair\" },\n    { c: \"fa-wifi\", l: \"Wifi\" },\n    { c: \"fa-wikipedia-w\", l: \"Wikipedia w\" },\n    { c: \"fa-windows\", l: \"Windows\" },\n    { c: \"fa-wordpress\", l: \"Wordpress\" },\n    { c: \"fa-wrench\", l: \"Wrench\" },\n    { c: \"fa-xing\", l: \"Xing\" },\n    { c: \"fa-xing-square\", l: \"Xing square\" },\n    { c: \"fa-y-combinator\", l: \"Y combinator\" },\n    { c: \"fa-yahoo\", l: \"Yahoo\" },\n    { c: \"fa-yelp\", l: \"Yelp\" },\n    { c: \"fa-youtube\", l: \"Youtube\" },\n    { c: \"fa-youtube-play\", l: \"Youtube play\" },\n    { c: \"fa-youtube-square\", l: \"Youtube square\" },\n];\n\nexport const faAnvilX: IconDefinition = {\n    prefix: \"fab\",\n    iconName: \"anvilx\" as IconName,\n    icon: [\n        107.22,\n        97.685,\n        [],\n        \"e001\",\n        \"M25.947,88.524c6.868-6.105,13.609-14.881,20.223-26.328,3.021,9.279,6.591,16.91,10.711,22.894l7.355-12.21c-3.798-6.956-7.022-15.733-9.671-26.328,6.614-12.21,12.846-21.241,18.697-27.091,6.105-5.851,12.464-8.776,19.078-8.776,4.07,0,6.614,1.526,7.631,4.579,1.018,3.052,.255,6.741-2.289,11.065,0,.763,.254,1.399,.763,1.908,.763,.254,1.526,.127,2.29-.382,1.526-2.798,2.925-5.851,4.197-9.158,1.526-3.561,2.289-6.487,2.289-8.776,0-2.798-1.017-5.087-3.052-6.868-1.781-2.035-4.452-3.053-8.013-3.053-7.123,0-14.627,3.816-22.513,11.447-7.631,7.377-14.499,16.789-20.604,28.236-.763-5.088-1.272-9.921-1.526-14.5-.254-4.833-.636-9.03-1.145-12.592-.254-3.816-.89-6.868-1.908-9.158-.763-2.289-2.035-3.434-3.816-3.434-2.035,0-4.324,.89-6.868,2.671-2.289,1.526-4.579,3.561-6.868,6.105-2.035,2.289-3.943,4.833-5.724,7.631-1.526,2.544-2.544,4.96-3.053,7.25-.254,.763,0,1.272,.763,1.526,1.018,.254,1.781,.127,2.289-.382,1.272-3.307,2.925-6.36,4.96-9.158,2.035-3.053,3.943-4.579,5.724-4.579,1.272,0,2.035,1.145,2.289,3.434,.509,2.289,.89,5.469,1.145,9.539,.509,3.816,1.018,8.522,1.526,14.118,.509,5.596,1.653,11.574,3.434,17.934-5.851,10.429-11.32,17.933-16.407,22.512-4.833,4.325-9.412,6.487-13.736,6.487-2.798,0-4.833-1.399-6.105-4.197-1.272-3.053-.89-6.869,1.145-11.447,0-1.018-.382-1.781-1.145-2.29-.509-.509-1.017-.509-1.526,0-2.289,4.325-3.943,8.395-4.96,12.21-1.018,3.816-1.526,7.25-1.526,10.303,0,5.342,2.035,8.013,6.105,8.013,6.614,0,13.228-3.053,19.841-9.158Zm74.411-15.642c-.763-.509-1.526-.509-2.29,0-.861,1.292-1.751,2.525-2.671,3.7l1.995,4.415c1.427-1.942,2.67-3.884,3.729-5.826,.254-1.017,0-1.78-.763-2.289Zm-10.686,9.921c-1.215,1.216-2.479,2.167-3.79,2.855l1.327,5.514c.312-.242,.625-.487,.937-.737,1.652-1.322,3.25-2.75,4.794-4.287l-2.036-4.516c-.406,.4-.816,.79-1.232,1.171Zm-16.026,14.882c2.036,0,4.325-.636,6.869-1.908,.388-.233,.776-.472,1.164-.717l-1.902-8.088c-1.492-.116-2.985-.584-4.477-1.403l-5.946,11.216c1.455,.6,2.886,.9,4.292,.9Zm-16.764-12.592c.736,1.07,1.491,2.088,2.263,3.052,1.65,2.063,3.273,3.791,4.87,5.185l6.399-11.697c-1.467-1.56-2.934-3.459-4.401-5.698-.61-.983-1.207-2.009-1.79-3.078l-7.341,12.236Z\",\n    ],\n};\n\nexport const faAnvilXCircle: IconDefinition = {\n    prefix: \"fab\",\n    iconName: \"anvilx-circle\" as IconName,\n    icon: [\n        200,\n        200,\n        [],\n        \"e001\",\n        \"M100,0C44.75,0,0,44.75,0,100s44.75,100,100,100,100-44.75,100-100S155.25,0,100,0Zm26.479,146.968c-2.544,1.272-4.833,1.908-6.869,1.908-1.406,0-2.837-.3-4.292-.9l5.946-11.216c1.492,.819,2.985,1.287,4.477,1.403l1.902,8.088c-.388,.245-.776,.484-1.164,.717Zm7.631-5.342c-.312,.25-.625,.495-.937,.737l-1.327-5.514c1.311-.688,2.575-1.639,3.79-2.855,.416-.381,.826-.771,1.232-1.171l2.036,4.516c-1.544,1.537-3.142,2.965-4.794,4.287Zm12.975-15.264c-1.059,1.942-2.302,3.884-3.729,5.826l-1.995-4.415c.92-1.175,1.81-2.408,2.671-3.7,.764-.509,1.527-.509,2.29,0s1.017,1.272,.763,2.289Zm3.811-56.474c-1.272,3.307-2.671,6.359-4.197,9.158-.764,.509-1.527,.636-2.29,.382-.509-.509-.763-1.145-.763-1.908,2.544-4.324,3.307-8.013,2.289-11.065-1.017-3.052-3.561-4.579-7.631-4.579-6.614,0-12.973,2.925-19.078,8.776-5.851,5.851-12.083,14.881-18.697,27.091,2.649,10.595,5.873,19.372,9.671,26.328h0c.579,1.061,1.171,2.079,1.777,3.055,1.467,2.239,2.934,4.138,4.401,5.698l-6.399,11.697c-1.597-1.394-3.22-3.122-4.87-5.185-.772-.964-1.527-1.982-2.263-3.052l.688-1.147-.689,1.144c-4.12-5.984-7.69-13.615-10.711-22.894-6.614,11.447-13.355,20.223-20.223,26.328-6.614,6.105-13.228,9.158-19.841,9.158-4.07,0-6.105-2.671-6.105-8.013,0-3.053,.509-6.487,1.526-10.303,1.018-3.815,2.671-7.885,4.96-12.21,.509-.509,1.018-.509,1.526,0,.763,.509,1.145,1.272,1.145,2.29-2.035,4.578-2.417,8.394-1.145,11.447,1.272,2.798,3.307,4.197,6.105,4.197,4.324,0,8.903-2.162,13.736-6.487,5.088-4.579,10.557-12.083,16.407-22.512-1.781-6.36-2.925-12.338-3.434-17.934-.509-5.596-1.017-10.302-1.526-14.118-.254-4.07-.636-7.25-1.145-9.539-.254-2.289-1.018-3.434-2.289-3.434-1.781,0-3.688,1.526-5.724,4.579-2.035,2.798-3.688,5.851-4.96,9.158-.509,.509-1.272,.636-2.289,.382-.763-.254-1.018-.763-.763-1.526,.509-2.289,1.526-4.706,3.053-7.25,1.781-2.798,3.688-5.342,5.724-7.631,2.289-2.544,4.579-4.579,6.868-6.105,2.544-1.781,4.833-2.671,6.868-2.671,1.781,0,3.052,1.145,3.816,3.434,1.018,2.289,1.654,5.342,1.908,9.158,.509,3.561,.89,7.759,1.145,12.592,.254,4.579,.763,9.412,1.526,14.5,6.105-11.447,12.973-20.859,20.604-28.236,7.886-7.631,15.39-11.447,22.513-11.447,3.561,0,6.232,1.018,8.013,3.052,2.035,1.781,3.052,4.07,3.052,6.868,0,2.289-.763,5.215-2.289,8.776Z\",\n    ],\n};\n","// export const DEFAULT_ICON_SET = [\"material-icons\", \"font-awesome-4.7.0\"];\nexport const DEFAULT_ICON_SETS = [\"font-awesome-4.7.0\"];\n\nexport interface IconsetModule {\n    iconsetName: string;\n    inject?: HTMLElement[];\n    shadowInject?: HTMLElement[];\n    renderer: (icon: string) => HTMLElement;\n    values: string[];\n}\n\nexport function lazyLoadIconSet(iconset: string): Promise<IconsetModule> {\n    // console.log(\"%cFetching iconset\", \"color:green\", iconset);\n    switch (iconset) {\n        case \"font-awesome-4.7.0\":\n            return import(\"./fontawesome4\");\n        case \"material-icons\":\n            return import(\"./materialicons\");\n        default:\n            return Promise.resolve({\n                iconsetName: iconset,\n                renderer: (icon: string) => document.createElement(\"span\"),\n                values: [],\n            });\n    }\n}\n","const IMAGE_MIME_TYPES: Record<string, string> = {\n    png: \"image/png\",\n    gif: \"image/gif\",\n    jpg: \"image/jpeg\",\n    jpeg: \"image/jpeg\",\n    webp: \"image/webp\",\n    avif: \"image/avif\",\n    bmp: \"image/bmp\",\n    ico: \"image/x-icon\",\n    svg: \"image/svg+xml\",\n};\n\nexport const getImageMimeType = (filePath: string): string | undefined => {\n    const extension = filePath.match(/\\.([^.\\/]+)$/)?.[1].toLowerCase();\n    return extension && Object.hasOwn(IMAGE_MIME_TYPES, extension) ? IMAGE_MIME_TYPES[extension] : undefined;\n};\n","import { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\nimport { faFacebook } from \"@fortawesome/free-brands-svg-icons/faFacebook\";\nimport { faGoogle } from \"@fortawesome/free-brands-svg-icons/faGoogle\";\nimport { faJenkins } from \"@fortawesome/free-brands-svg-icons/faJenkins\";\nimport { faMicrosoft } from \"@fortawesome/free-brands-svg-icons/faMicrosoft\";\nimport { faStripe } from \"@fortawesome/free-brands-svg-icons/faStripe\";\nimport { faFlask } from \"@fortawesome/pro-light-svg-icons\";\nimport { faDatabase } from \"@fortawesome/pro-light-svg-icons/faDatabase\";\nimport { faFolders } from \"@fortawesome/pro-light-svg-icons/faFolders\";\nimport { faKey } from \"@fortawesome/pro-light-svg-icons/faKey\";\nimport { faLock } from \"@fortawesome/pro-light-svg-icons/faLock\";\nimport { faMailBulk } from \"@fortawesome/pro-light-svg-icons/faMailBulk\";\nimport { faUserFriends } from \"@fortawesome/pro-light-svg-icons/faUserFriends\";\nimport { faUserSecret } from \"@fortawesome/pro-light-svg-icons/faUserSecret\";\nimport { loadStripe } from \"@stripe/stripe-js\";\nimport { isEmpty } from \"lodash-es\";\nimport { PropertyValue } from \"@runtime/components/Component\";\nimport { AnvilAction, FullView, View } from \"@/types\";\nimport { ON_IDLE, ON_IDLE_CANCEL } from \"../actions\";\nimport { faAnvilXCircle } from \"./icons\";\n\n// it's better to always return the same empty array from a selector to prevent re-rerenders\nexport const EMPTY_ARRAY = Object.freeze([]) as [];\nexport const EMPTY_OBJECT = Object.freeze({}) as Record<string, never>;\n\nexport const sleep = (ms: number) => new Promise((resolve) => setTimeout(() => resolve(undefined), ms));\n\nexport const onIdle = (action: AnvilAction, key: string, timeout = 2000) => {\n    return { type: ON_IDLE, key, timeout, action } as const;\n};\n\nexport const cancelOnIdle = (key: string) => {\n    return { type: ON_IDLE_CANCEL, key } as const;\n};\n\nexport const delayAction =\n    (action: AnvilAction, timeout = 0): AnvilAction =>\n    (dispatch) => {\n        return setTimeout(() => dispatch(action), timeout);\n    };\n\nlet iconMap: ReturnType<typeof getIconMap>;\n\nfunction getIconMap() {\n    // for code splitting\n    return {\n        \"/runtime/services/tables.yml\": faDatabase,\n        \"/runtime/services/anvil/users.yml\": faUserFriends,\n        \"/runtime/services/anvil/email.yml\": faMailBulk,\n        \"/runtime/services/anvil/secrets.yml\": faLock,\n        \"/runtime/services/google.yml\": faGoogle,\n        \"/runtime/services/facebook.yml\": faFacebook,\n        \"/runtime/services/anvil/microsoft.yml\": faMicrosoft,\n        \"/runtime/services/anvil/saml.yml\": faLock,\n        \"/runtime/services/stripe.yml\": faStripe,\n        \"/runtime/services/kerberos.yml\": faUserSecret,\n        \"/runtime/services/pki.yml\": faKey,\n        \"/runtime/services/anvil/tableau.yml\": faAnvilXCircle,\n        \"/runtime/services/anvil/files.yml\": faFolders,\n        \"/runtime/services/anvil/tests.yml\": faFlask,\n        \"/runtime/services/hawthorn-deployment.yml\": faJenkins,\n    };\n}\n\ntype ServiceIconInput = {\n    source?: string;\n    icon?: IconDefinition;\n};\n\nexport const getServiceIcon = ({ source, icon }: ServiceIconInput) => {\n    iconMap ??= getIconMap();\n    return icon || iconMap[source as keyof typeof iconMap];\n};\n\nconst urlMap = {\n    \"/runtime/services/anvil/users.yml\": \"USERS\",\n    \"/runtime/services/anvil/email.yml\": \"EMAIL\",\n    \"/runtime/services/anvil/secrets.yml\": \"SECRETS\",\n    \"/runtime/services/google.yml\": \"GOOGLE\",\n    \"/runtime/services/facebook.yml\": \"FACEBOOK\",\n    \"/runtime/services/anvil/microsoft.yml\": \"MICROSOFT\",\n    \"/runtime/services/anvil/saml.yml\": \"SAML\",\n    \"/runtime/services/stripe.yml\": \"STRIPE\",\n    \"/runtime/services/kerberos.yml\": \"\",\n    \"/runtime/services/pki.yml\": \"\",\n    \"/runtime/services/anvil/tableau.yml\": \"TABLEAU\",\n    \"/runtime/services/anvil/files.yml\": \"FILES\",\n    \"/runtime/services/anvil/tests.yml\": \"TESTS\",\n    \"/runtime/services/hawthorn-deployment.yml\": \"HAWTHORN_DEPLOYMENT\",\n} as const;\n\nexport const getServiceType = (url: keyof typeof urlMap) => urlMap[url];\n\nexport const convertToHash = (view: FullView | View | undefined, essentialView: View | undefined) => {\n    if (!view && !essentialView) return \"\";\n    const newHash = [];\n    for (const [key, value] of Object.entries(view ?? essentialView ?? {})) {\n        if (value) {\n            if (key === \"focus\") {\n                // Handle focus as a special case - it's a string, not an array\n                newHash.push(`focus:${value}`);\n            } else {\n                const prefix = key in (essentialView || {}) ? \"+\" : \"\";\n                !value.length ? newHash.push(`${prefix}${key}`) : newHash.push(`${prefix}${key}:${value.join(\":\")}`);\n            }\n        }\n    }\n    if (newHash.length > 0) {\n        return \"#\" + newHash.join(\";\");\n    } else {\n        return \"\";\n    }\n};\n\nexport const waitFor =\n    (action: AnvilAction, timeoutMs = 1000, pollIntervalMs = 20): AnvilAction =>\n    (dispatch, getState, updateState) => {\n        const startTime = Date.now();\n        return new Promise((resolve, reject) => {\n            const test = async () => {\n                const done = await dispatch(action);\n                if (done) {\n                    resolve(done);\n                } else {\n                    if (Date.now() - startTime < timeoutMs) {\n                        setTimeout(test, pollIntervalMs);\n                    } else {\n                        reject(\"TIMEOUT\");\n                    }\n                }\n            };\n            test();\n        });\n    };\n\nexport const setIn = (object: any, path: string[], value: any) => {\n    for (let i = 0; i < path.length - 1; i++) {\n        const k = path[i];\n        if (!object[k]) {\n            object[k] = {};\n        }\n        object = object[k];\n    }\n    object[path[path.length - 1]] = value;\n};\n\nexport const removeAndSlimObject = (object: any, path: string[]) => {\n    const pointers = [object];\n    for (let i = 0; i < path.length - 1; i++) {\n        const k = path[i];\n        if (!object[k]) {\n            return;\n        }\n        object = object[k];\n        pointers.push(object);\n    }\n    delete object[path[path.length - 1]];\n\n    for (let i = pointers.length - 1; i >= 1; i--) {\n        const k = path[i - 1];\n        const pointer = pointers[i];\n        if (!isEmpty(pointer)) {\n            return;\n        }\n        delete pointers[i - 1][k];\n    }\n};\n\nexport const valOrDefault = (v: any, defaultVal = \"default\") => (v === null ? defaultVal : v);\n\ntype SessionTyp = \"unknown\" | \"browser\" | \"http\" | \"background_task\" | \"email\" | \"uplink\" | \"repl\";\n\nexport const sessionTypeTitle = (type: SessionTyp) => {\n    switch (type) {\n        case \"unknown\": // TODO: Remove this ~30 days after next release, when browser sessions are correctly identified.\n        case \"browser\":\n            return \"Browser\";\n        case \"http\":\n            return \"HTTP\";\n        case \"background_task\":\n            return \"Background Task\";\n        case \"email\":\n            return \"Email\";\n        case \"uplink\":\n            return \"Uplink\";\n        case \"repl\":\n            return \"Console\";\n    }\n};\n\nexport const stripePromise = loadStripe(\n    localStorage.stripeTestMode ? \"pk_test_K6g3Ip5VTV6zvp0ZAQ7xAPjf\" : \"pk_live_FhjfmB3MWoVkiyYBvSEw8Pj0\"\n);\n\nexport const isMac = /Mac/.test(navigator.platform);\nexport const checkMeta = (e: KeyboardEvent | React.KeyboardEvent | MouseEvent | React.MouseEvent) =>\n    isMac ? e.metaKey : e.ctrlKey;\n\nexport const getRandomString = () => Math.random().toString(36).substring(6);\n\nexport const isFirefox = navigator.userAgent.toLowerCase().includes(\"firefox\");\n\nconst isInputOrTextArea = (el: Element): el is HTMLInputElement | HTMLTextAreaElement =>\n    el.tagName === \"INPUT\" || el.tagName === \"TEXTAREA\";\n\n// because firefox doesn't support window.getSelection in input/textarea\nexport function getSelectedText() {\n    const selection = window.getSelection()?.toString() ?? \"\";\n    if (selection || !isFirefox) return selection;\n    const el = document.activeElement;\n    if (!el || !isInputOrTextArea(el)) return selection;\n    const selectionStart = el.selectionStart ?? undefined;\n    const selectionEnd = el.selectionEnd ?? undefined;\n    return el.value.slice(selectionStart, selectionEnd);\n}\n\nexport const noop = () => {};\n\nexport const THEME_PREFIX = \"@theme:\";\nexport const isThemeAsset = (template?: string | PropertyValue<\"html\">) => template?.startsWith(THEME_PREFIX);\nexport const getTemplateName = (template: string) => template.slice(THEME_PREFIX.length);\n\nexport function wait(ms = 500) {\n    return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function blockEvent(e: React.SyntheticEvent | Event) {\n    e.preventDefault();\n    e.stopPropagation();\n}\n\nexport function preventDefault(e: React.SyntheticEvent | Event) {\n    e.preventDefault();\n}\n\nexport function stopPropagation(e: React.SyntheticEvent | Event) {\n    e.stopPropagation();\n}\n\nexport const isAnvilProd = document.location.host.endsWith(\"anvil.works\") || window.localStorage.pretendWereOnProd;\n","import React, { Suspense, lazy } from \"react\";\nimport { DelayedLoadingSpinner } from \"@/components/reusable/Loading\";\n\ninterface Options {\n    fallback?: React.ReactNode;\n}\n\nexport const lazyComponent = <T,>(\n    importFn: () => Promise<any>,\n    name: string | null = \"default\",\n    { fallback = <DelayedLoadingSpinner /> }: Options = {}\n) => {\n    const LazyComponent = lazy(async () => {\n        const module = await importFn();\n        return { default: module[name ?? \"default\"] };\n    });\n    const LazyFc = (props: any) => (\n        <Suspense fallback={fallback}>\n            <LazyComponent {...props} />\n        </Suspense>\n    );\n    if (name) {\n        LazyFc.displayName = name;\n    }\n    return LazyFc;\n};\n","import type Plot from \"plotly.js-basic-dist-min\";\nimport { lazyComponent } from \".\";\n\nconst LazyPlot = lazyComponent<typeof Plot>(async () => {\n    const Plotly = (await import(\"plotly.js-basic-dist-min\")).default;\n    const createPlotlyComponent = (await import(\"react-plotly.js/factory\")).default;\n    const Plot = createPlotlyComponent(Plotly);\n    return { default: Plot };\n});\n\nexport default LazyPlot;\n","import type { RuntimeOptions } from \"@/types/app\";\nimport type { PythonEnvironmentCatalog } from \"@/types/user\";\n\nexport type ServerPythonMinorVersion = 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14;\n\nconst versions: Record<string, ServerPythonMinorVersion> = {\n    \"3.7\": 7,\n    \"3.8\": 8,\n    \"3.9\": 9,\n    \"3.10\": 10,\n    \"3.11\": 11,\n    \"3.12\": 12,\n    \"3.13\": 13,\n    \"3.14\": 14,\n};\n\n/** Share the selected server version between Python analysis, linting and formatting. */\nexport function getServerPythonMinorVersion(\n    runtimeOptions: Pick<RuntimeOptions, \"server_spec\" | \"server_version\"> | undefined,\n    catalog: PythonEnvironmentCatalog | undefined\n): ServerPythonMinorVersion {\n    const base = runtimeOptions?.server_spec?.base;\n    const pythonVersion = catalog?.find((image) => image.base === base)?.python_version;\n    if (pythonVersion && versions[pythonVersion]) return versions[pythonVersion];\n    // Keep name-based fallback until supported servers/sessions guarantee catalog metadata.\n    const runtime = base ?? runtimeOptions?.server_version;\n    const match = runtime?.match(/^python(3(?:1[0-4]|[7-9]))(?:-|$)/);\n    return match ? (Number(match[1].slice(1)) as ServerPythonMinorVersion) : 7;\n}\n","import { QueryClient } from \"@tanstack/react-query\";\n\nexport const DEFAULT_QUERY_STALE_TIME = 1000 * 60 * 10;\n\nexport const queryClient = new QueryClient({\n    defaultOptions: {\n        queries: {\n            retry: 3,\n            retryDelay: (attempt) => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 120 * 1000),\n            refetchOnWindowFocus: false,\n            staleTime: DEFAULT_QUERY_STALE_TIME,\n        },\n    },\n});\n","// Adapted form tanstack query\n\nexport function isPlainArray(value: unknown) {\n    return Array.isArray(value) && value.length === Object.keys(value).length;\n}\n\nconst ObjectProto = Object.prototype;\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function isPlainObject(o: any): o is Object {\n    if (typeof o !== \"object\" || o === null) return false;\n    const proto = Object.getPrototypeOf(o);\n    return proto === null || proto === ObjectProto;\n}\n\n/**\n * Recursively compares two values and returns a new value if they differ.\n * For arrays and plain objects, it performs a deep comparison of their elements.\n * @param a The first value to compare\n * @param b The second value to compare\n * @returns A new value if `a` and `b` are different, otherwise returns `a`\n */\nexport function replaceEqualDeep(a: any, b: any): any {\n    if (a === b) {\n        return a;\n    }\n\n    const array = isPlainArray(a) && isPlainArray(b);\n\n    if (array || (isPlainObject(a) && isPlainObject(b))) {\n        const aItems = array ? a : Object.keys(a);\n        const aSize = aItems.length;\n        const bItems = array ? b : Object.keys(b);\n        const bSize = bItems.length;\n        const copy: any = array ? [] : {};\n\n        let equalItems = 0;\n\n        for (let i = 0; i < bSize; i++) {\n            const key = array ? i : bItems[i];\n            if (!array && a[key] === undefined && b[key] === undefined && aItems.includes(key)) {\n                copy[key] = undefined;\n                equalItems++;\n            } else {\n                copy[key] = replaceEqualDeep(a[key], b[key]);\n                if (copy[key] === a[key] && a[key] !== undefined) {\n                    equalItems++;\n                }\n            }\n        }\n        // console.log(\"%cCHECKING\", \"color: green\", aSize === bSize && equalItems === aSize, copy);\n\n        return aSize === bSize && equalItems === aSize ? a : copy;\n    }\n\n    return b;\n}\n","import { type KeyboardEvent, useRef, useState } from \"react\";\nimport { debounce } from \"lodash-es\";\nimport { ExternalStore, useStoreSelector } from \"@/util/external-store\";\nimport useEvent from \"@/util/useEventCallback\";\n\nclass SearchHistoryStore extends ExternalStore<{ terms: string[] }> {\n    // Search inputs share a history, so they must also share the pending record.\n    // A newer query, submission or recall supersedes it, including across tabs.\n    recordAfterPause = debounce((term: string) => this.record(term), 500);\n\n    cancelPendingRecord() {\n        this.recordAfterPause.cancel();\n    }\n\n    record(term: string) {\n        this.cancelPendingRecord();\n        const { terms } = this.getState();\n        if (!term || terms.at(-1) === term) return;\n        this.setState({ terms: [...terms, term].slice(-100) });\n    }\n\n    clear() {\n        this.cancelPendingRecord();\n        this.setState({ terms: [] });\n    }\n}\n\n// Each search has its own history, lasting until the app closes.\nexport const searchHistoryStore = new SearchHistoryStore({ terms: [] });\nexport const editorSearchHistoryStore = new SearchHistoryStore({ terms: [] });\nexport const outputSearchHistoryStore = new SearchHistoryStore({ terms: [] });\nexport const sessionSearchHistoryStore = new SearchHistoryStore({ terms: [] });\n\ntype HistoryNavigation = { terms: string[]; index: number; draft: string };\n\nexport function useSearchHistory(store: SearchHistoryStore) {\n    const hasHistory = useStoreSelector(store, ({ terms }) => terms.length > 0);\n    const [isFocused, setIsFocused] = useState(false);\n    const navigation = useRef<HistoryNavigation | null>(null);\n    const resetNavigation = useEvent(() => {\n        navigation.current = null;\n    });\n    const onFocus = useEvent(() => {\n        resetNavigation();\n        setIsFocused(true);\n    });\n    const onBlur = useEvent(() => setIsFocused(false));\n\n    const navigateHistory = useEvent((direction: \"previous\" | \"next\", input: string) => {\n        const { terms } = store.getState();\n        if (!terms.length) {\n            navigation.current = null;\n            return;\n        }\n        if (!navigation.current) {\n            if (direction === \"next\") return;\n            // Skip the latest entry if it is already in the input. Keep the\n            // original draft so Down can restore it after browsing history.\n            const previousTerms = terms.at(-1) === input ? terms.slice(0, -1) : terms;\n            if (!previousTerms.length) return;\n            navigation.current = { terms: previousTerms, index: previousTerms.length, draft: input };\n        }\n        const cursor = navigation.current;\n        cursor.index = Math.max(0, Math.min(cursor.terms.length, cursor.index + (direction === \"previous\" ? -1 : 1)));\n        if (cursor.index === cursor.terms.length) {\n            navigation.current = null;\n            return cursor.draft;\n        }\n        return cursor.terms[cursor.index];\n    });\n\n    return { hasHistory, showHistoryHint: hasHistory && isFocused, navigateHistory, resetNavigation, onFocus, onBlur };\n}\n\nexport function useSearchHistoryKeyDown(\n    history: ReturnType<typeof useSearchHistory>,\n    input: string,\n    onRecall: (term: string) => void\n) {\n    return useEvent((e: KeyboardEvent<HTMLInputElement>) => {\n        if (e.nativeEvent.isComposing || e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) return;\n        if (e.key !== \"ArrowUp\" && e.key !== \"ArrowDown\") return;\n        const term = history.navigateHistory(e.key === \"ArrowUp\" ? \"previous\" : \"next\", input);\n        if (term === undefined) return;\n        e.preventDefault();\n        e.stopPropagation();\n        onRecall(term);\n    });\n}\n","import { useEffect, useState } from \"react\";\nimport { startCase } from \"lodash-es\";\nimport moment from \"moment\";\n\nexport const timeAgoString = (t: number, capitalize = false) => {\n    const s = moment.duration(t - Date.now()).humanize(true);\n    if (capitalize) {\n        return startCase(s);\n    } else {\n        return s;\n    }\n};\n\nexport const durationString = (durationMs: number | string) => {\n    return moment.duration(durationMs).humanize();\n};\n\nconst plural = (n: number, unit: string) => `${n} ${unit}${n === 1 ? \"\" : \"s\"}`;\n\n/**\n * A countdown as \"59 minutes 23 seconds\". Part-seconds round up, so the countdown only reads zero\n * once the time has genuinely run out; negative durations clamp to zero.\n */\nexport const formatCountdown = (msRemaining: number) => {\n    const totalSeconds = Math.max(0, Math.ceil(msRemaining / 1000));\n    return `${plural(Math.floor(totalSeconds / 60), \"minute\")} ${plural(totalSeconds % 60, \"second\")}`;\n};\n\nconst agoString = (n: number, unit: string) => {\n    n = Math.round(n);\n    return `${n} ${unit}${n === 1 ? \"\" : \"s\"} ago`;\n};\n\nconst agoStringShort = (n: number, unit: string) => {\n    n = Math.round(n);\n    return `${n}${unit}`;\n};\n\nexport const timeAgo = (now: Date, then: Date) => {\n    const diff = (+now - +then) / 60000;\n    return diff < 1\n        ? \"a few moments ago\"\n        : diff < 60\n          ? agoString(diff, \"minute\")\n          : diff < 24 * 60\n            ? agoString(diff / 60, \"hour\")\n            : diff < 30 * 24 * 60\n              ? agoString(diff / (24 * 60), \"day\")\n              : diff < 2 * 365 * 24 * 60\n                ? agoString(diff / (30 * 24 * 60), \"month\")\n                : agoString(365 * 24 * 60, \"year\");\n};\n\nexport const timeAgoShort = (now: Date, then: Date) => {\n    const diff = (+now - +then) / 60000;\n    return diff < 1\n        ? \"now\"\n        : diff < 60\n          ? agoStringShort(diff, \"m\")\n          : diff < 24 * 60\n            ? agoStringShort(diff / 60, \"h\")\n            : diff < 30 * 24 * 60\n              ? agoStringShort(diff / (24 * 60), \"d\")\n              : diff < 2 * 365 * 24 * 60\n                ? agoStringShort(diff / (30 * 24 * 60), \"mo\")\n                : agoStringShort(365 * 24 * 60, \"y\");\n};\n\nexport const useNowWithRefresh = (refreshInterval = 60000) => {\n    const [now, setNow] = useState(new Date());\n\n    useEffect(() => {\n        const t = setInterval(() => setNow(new Date()), refreshInterval);\n        return () => clearInterval(t);\n    }, []);\n\n    return now;\n};\n\nconst dateOptions = { year: \"numeric\", month: \"long\", day: \"numeric\" } as const;\n\nexport const dateAndDaysAway = (expires?: number | string) => {\n    const date = expires ? new Date(expires) : new Date();\n    const ex = date.toLocaleString(\"en-GB\", dateOptions);\n    const oneDay = 24 * 60 * 60 * 1000;\n    const remains = Math.round((+date - Date.now()) / oneDay);\n    return [ex, remains];\n};\n","import { useInsertionEffect, useRef } from \"react\";\nimport { noop } from \"./index\";\n\n/**\n * @description\n * Experimental hook\n * https://react.dev/learn/separating-events-from-effects#declaring-an-effect-event\n *\n * This is a polyfill based on:\n * https://stackoverflow.com/questions/76335194/is-this-an-accurate-polyfill-of-reacts-useeffectevent\n * https://github.com/scottrippey/react-use-event-hook/blob/main/src/useEvent.ts\n *\n * typing: A specific function type would not trigger implicit any.\n * See https://github.com/DefinitelyTyped/DefinitelyTyped/issues/52873#issuecomment-845806435 for a comparison between `Function` and more specific types.\n */\n//eslint-disable-next-line @typescript-eslint/ban-types\nfunction useEffectEvent<T extends Function>(fn: T) {\n    const ref = useRef<T>(((...args: any[]) => {\n        // @ts-ignore\n        if (process.env.NODE_ENV !== \"production\") {\n            console.error(\"Calling a useEventEffect during the render phase, consider a useCallback instead\");\n        }\n        return fn(...args);\n    }) as unknown as T);\n\n    useInsertionEffect(() => {\n        ref.current = fn;\n    });\n\n    // Create a stable callback that always calls the latest callback:\n    // using useRef instead of useCallback avoids creating an empty array on every render\n    const stableRef = useRef<T | undefined>(undefined);\n    if (!stableRef.current) {\n        stableRef.current = function (this: any) {\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-return, prefer-rest-params, @typescript-eslint/no-unsafe-argument\n            return ref.current.apply(this, arguments as any);\n        } as unknown as T;\n    }\n\n    return stableRef.current as T;\n}\n\nexport default useEffectEvent;\n","import { useInsertionEffect, useRef } from \"react\";\nimport { noop } from \"./index\";\n\n/**\n * @description\n * This hook is for event handlers\n * It should never be used for callbacks used inside render methods\n *\n * this was part of an rfc that was parked: https://github.com/reactjs/rfcs/pull/220\n * https://github.com/reactjs/rfcs/pull/220#issuecomment-1259938816\n *\n * This is a polyfill based on: https://stackoverflow.com/questions/76335194/is-this-an-accurate-polyfill-of-reacts-useeffectevent\n * https://github.com/scottrippey/react-use-event-hook/blob/main/src/useEvent.ts\n *\n * Re typing: A specific function type would not trigger implicit any.\n * See https://github.com/DefinitelyTyped/DefinitelyTyped/issues/52873#issuecomment-845806435 for a comparison between `Function` and more specific types.\n */\n// eslint-disable-next-line @typescript-eslint/ban-types\nfunction useEvent<T extends Function>(fn: T) {\n    const ref = useRef<T>(((...args: any[]) => {\n        // @ts-ignore\n        if (process.env.NODE_ENV !== \"production\") {\n            console.error(\"Calling a useEvent during the render phase, consider a useCallback instead\");\n        }\n        return fn(...args);\n    }) as unknown as T);\n\n    useInsertionEffect(() => {\n        ref.current = fn;\n    });\n\n    // Create a stable callback that always calls the latest callback:\n    // using useRef instead of useCallback avoids creating an empty array on every render\n    const stableRef = useRef<T>(undefined);\n    if (!stableRef.current) {\n        stableRef.current = function (this: any) {\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-return, prefer-rest-params, @typescript-eslint/no-unsafe-argument\n            return ref.current.apply(this, arguments as any);\n        } as unknown as T;\n    }\n\n    return stableRef.current;\n}\n\nexport default useEvent;\n","import React from \"react\";\nimport { noop } from \".\";\nimport { isTouchEvent } from \"./dnd\";\nimport { useConstant } from \"./hooks\";\nimport useEvent from \"./useEventCallback\";\n\ninterface LongPressOptions {\n    threshold?: number;\n    onStart?: (e: React.TouchEvent | TouchEvent) => void;\n    onFinish?: (e: React.TouchEvent | TouchEvent) => void;\n    onCancel?: (e: React.TouchEvent | TouchEvent) => void;\n}\n\nexport function getLongPressCallbacks(\n    callback: (e: React.TouchEvent | TouchEvent) => void,\n    options: LongPressOptions = {}\n) {\n    const { threshold = 400, onStart, onFinish, onCancel } = options;\n    let isLongPressActive = false;\n    let isPressed = false;\n    let timerId: number | undefined = undefined;\n\n    const onTouchStart = (event: React.TouchEvent | TouchEvent) => {\n        if (!isTouchEvent(event)) return;\n\n        onStart?.(event);\n\n        isPressed = true;\n        timerId = setTimeout(() => {\n            callback(event);\n            isLongPressActive = true;\n        }, threshold);\n    };\n\n    const onTouchMove = (event: React.TouchEvent | TouchEvent) => {\n        clearTimeout(timerId);\n    };\n\n    const onTouchEnd = (event: React.TouchEvent | TouchEvent) => {\n        if (!isTouchEvent(event)) return;\n\n        if (isLongPressActive) {\n            onFinish?.(event);\n        } else if (isPressed) {\n            onCancel?.(event);\n        }\n\n        isLongPressActive = false;\n        isPressed = false;\n\n        clearTimeout(timerId);\n    };\n    return {\n        onTouchStart,\n        onTouchEnd,\n        onTouchMove,\n    };\n}\n\nexport function useLongPress(callback: (e: React.TouchEvent | TouchEvent) => void, options: LongPressOptions = {}) {\n    const { threshold = 400, onStart, onFinish, onCancel } = options;\n    const wrappedStart = useEvent(onStart ?? noop);\n    const wrappedFinish = useEvent(onFinish ?? noop);\n    const wrappedCancel = useEvent(onCancel ?? noop);\n    const wrappedCallback = useEvent(callback);\n\n    return useConstant(() =>\n        getLongPressCallbacks(wrappedCallback, {\n            onCancel: wrappedCancel,\n            onFinish: wrappedFinish,\n            onStart: wrappedStart,\n            threshold,\n        })\n    );\n}\n","/**\n * Surveys that will be forced upon new users.\n * Surveys are an object whose keys are the various versions of the \"same\" survey. These keys must be globally unique.\n * These version names are the VALUE of the abFlag in the user object eg: {\"\n * welcomeSurvey\": \"welcome-survey-v1\"}\n *\n * Structure of a survey is an ordered array of Question objects.\n * See the Question interface below for the structure of Question and type requirements.\n * Regarding the responses, if an \"Other\" option is made available, do not include it in the responses,\n * instead set otherOption to true.\n *\n * */\n\nexport interface QuestionProps {\n    id: string;\n    type: \"singleSelect\" | \"multiSelect\";\n    question: string;\n    responses: string[];\n    reorderOptions?: boolean;\n    otherOption: boolean;\n}\n\nexport const WHERE_TO_START_SURVEY_ID = \"where-to-start\";\nexport const WHERE_TO_START_QUESTION_ID = \"where-to-start\";\nexport const WHERE_TO_START_OPTIONS = [\n    {\n        id: \"learn-build-web-uis\",\n        label: \"I want to learn to build web UIs with Anvil\",\n    },\n    {\n        id: \"python-script-or-notebook\",\n        label: \"I already have a Python script or notebook and want to put a UI on it\",\n    },\n    {\n        id: \"prompt-ai-agent\",\n        label: \"I know what I want to build, let me prompt the AI agent\",\n    },\n    {\n        id: \"following-tutorial-or-class\",\n        label: \"I'm following a tutorial or class\",\n    },\n    {\n        id: \"already-know-anvil\",\n        label: \"I already know how to use Anvil\",\n    },\n] as const;\nexport type WhereToStartOptionId = (typeof WHERE_TO_START_OPTIONS)[number][\"id\"];\n\nexport const ACTIVE_SURVEYS = [\"talk-to-us-v2\"] as const;\n\nconst LEGACY_SURVEYS = [\"jtbd-v1\", \"welcome-survey-v2\", \"talk-to-us-survey\"] as const;\n\nconst ALL_ONBOARDING_SURVEYS = new Set<string>([...LEGACY_SURVEYS, ...ACTIVE_SURVEYS]);\n\nexport const hasCompletedOnboardingSurvey = (completedSurveys: string[] | undefined) =>\n    completedSurveys?.some((survey) => ALL_ONBOARDING_SURVEYS.has(survey)) ?? false;\n\nexport const hasChosenWhereToStart = (completedSurveys: string[] | undefined) =>\n    completedSurveys?.includes(WHERE_TO_START_SURVEY_ID) ?? false;\n\nexport const welcomeSurveys: { [name: string]: QuestionProps[] } = {\n    \"welcome-survey-v1\": [\n        {\n            id: \"1\",\n            type: \"singleSelect\",\n            question: \"What is the main thing you’ll use Anvil for?\",\n            responses: [\"Work\", \"Education\", \"Personal\"],\n            otherOption: false,\n        },\n        {\n            id: \"2\",\n            type: \"singleSelect\",\n            question: \"Which of these best describes you?\",\n            responses: [\n                \"Frontend Developer\",\n                \"Backend Developer\",\n                \"Full Stack Developer\",\n                \"Data scientist or ML specialist\",\n                \"Data or business analyst\",\n                \"Entrepreneur\",\n                \"Student or Educator\",\n            ],\n            otherOption: true,\n        },\n        {\n            id: \"3\",\n            type: \"multiSelect\",\n            question: \"Why you are using Anvil?\",\n            responses: [\n                \"Faster web app development\",\n                \"Simplified Python code deployment\",\n                \"No need for HTML, CSS, JavaScript, or web stack\",\n                \"Minimum viable product development\",\n                \"Notebook-based Python code deployment\",\n                \"IoT app development or machine connectivity\",\n                \"Internal tool development\",\n                \"Deployment of machine learning models\",\n                \"Data or business analytics\",\n                \"Educational course or personal development\",\n            ],\n            otherOption: true,\n        },\n    ],\n    \"welcome-survey-v2\": [\n        {\n            id: \"job-role\",\n            type: \"singleSelect\",\n            question: \"What's your job role?\",\n            responses: [\n                \"Software Developer\",\n                \"Data science/engineering\",\n                \"Student\",\n                \"Educator\",\n                \"Other IT\",\n                \"I don't work in IT\",\n            ],\n            otherOption: false,\n            reorderOptions: false,\n        },\n        {\n            id: \"use-case\",\n            type: \"singleSelect\",\n            question: \"What will you use Anvil for?\",\n            responses: [\n                \"Classroom learning\",\n                \"Personal learning/hobby\",\n                \"Side project\",\n                \"Startup\",\n                \"Tools for colleagues\",\n            ],\n            otherOption: true,\n        },\n        {\n            id: \"programming-experience\",\n            type: \"singleSelect\",\n            question: \"How much coding experience do you have?\",\n            responses: [\"Experienced\", \"Intermediate\", \"Learning now\", \"Never written code before\"],\n            reorderOptions: false,\n            otherOption: false,\n        },\n        {\n            id: \"python-experience\",\n            type: \"singleSelect\",\n            question: \"How much Python experience do you have?\",\n            responses: [\"Experienced\", \"Intermediate\", \"Learning now\", \"Never written code before\"],\n            reorderOptions: false,\n            otherOption: false,\n        },\n    ],\n    \"jtbd-v1\": [\n        {\n            id: \"jtbd\",\n            type: \"singleSelect\",\n            question: \"What are you using Anvil to do?\",\n            responses: [\n                \"Build an app for a client\",\n                \"Automate a process at my company\",\n                \"Build or prototype a new product\",\n                \"Just for fun\",\n                \"Education (learning or teaching)\",\n            ],\n            otherOption: true,\n            reorderOptions: true,\n        },\n        {\n            id: \"programming-experience\",\n            type: \"singleSelect\",\n            question: \"How much coding experience do you have?\",\n            responses: [\"Experienced\", \"Intermediate\", \"Learning now\", \"Never written code before\"],\n            reorderOptions: false,\n            otherOption: false,\n        },\n    ],\n    \"talk-to-us-survey\": [\n        {\n            id: \"use-case\",\n            type: \"singleSelect\",\n            question: \"What will you use Anvil for?\",\n            responses: [\n                \"Classroom learning or teaching\",\n                \"Personal learning/hobby\",\n                \"Startup\",\n                \"Tools to use at work\",\n                \"Customer-facing product\",\n                \"Work for a client\",\n            ],\n            otherOption: true,\n        },\n        {\n            id: \"programming-experience\",\n            type: \"singleSelect\",\n            question: \"How much coding experience do you have?\",\n            responses: [\"Experienced\", \"Intermediate\", \"Learning now\", \"Never written code before\"],\n            reorderOptions: false,\n            otherOption: false,\n        },\n        {\n            id: \"ai-subscription\",\n            type: \"singleSelect\",\n            question: \"Do you have an existing AI subscription?\",\n            responses: [\"Yes - I have a ChatGPT/Codex subscription\", \"Yes - I have a Claude subscription\", \"Yes - I have a subscription to another AI provider\", \"No\"],\n            reorderOptions: false,\n            otherOption: false,\n        },\n        // Until 2026-10 this survey also asked for consent to a feedback call, so older responses\n        // have an answer to this question:\n        // {\n        //     id: \"talk-to-us\",\n        //     type: \"singleSelect\",\n        //     question: \"Would you be open to a quick call to share feedback on your Anvil experience?\",\n        //     responses: [\"Yes (You'll receive an Amazon gift card as a thank you.)\", \"No\"],\n        //     reorderOptions: false,\n        //     otherOption: false,\n        // },\n    ],\n    // Gates the feedback-call offer from 2026-11. The server decides who qualifies from these\n    // answers (anvil.works.prospects/talk-to-us-v2-prospect?, sent as `User.talkToUsProspect`), and\n    // so does the dashboard (is_prospect in platform/database/schema-dashboard.sql). Both match on\n    // the question ids and answer text, so change them too if you change those.\n    \"talk-to-us-v2\": [\n        {\n            id: \"use-case\",\n            type: \"singleSelect\",\n            question: \"What will you use Anvil for?\",\n            responses: [\n                \"Classroom teaching\",\n                \"Personal projects\",\n                \"Startup\",\n                \"Apps for my job\",\n                \"Work for paying clients\",\n            ],\n            otherOption: true,\n        },\n        {\n            id: \"programming-experience\",\n            type: \"singleSelect\",\n            question: \"How much coding experience do you have?\",\n            responses: [\"Experienced\", \"Intermediate\", \"Learning now\", \"Never written code before\"],\n            reorderOptions: false,\n            otherOption: false,\n        },\n        {\n            id: \"particular-project\",\n            type: \"singleSelect\",\n            question: \"Do you have a particular project in mind?\",\n            responses: [\"Yes\", \"No\"],\n            reorderOptions: false,\n            otherOption: false,\n        },\n    ],\n};\n","import { base64DecToArr } from \"@runtime/lib/b64\";\n\nexport const SEARCH_RESULT_LIMIT = 2048;\n\nexport interface SearchPattern {\n    source: string;\n    flags: string;\n}\n\nexport interface TextSearchMatch {\n    lineNo: number;\n    index: number;\n    colOffset: number;\n    matchLine: string;\n}\n\nconst escapeHtml = (text: string) =>\n    text.replace(/[&<>]/g, (char) => ({ \"&\": \"&amp;\", \"<\": \"&lt;\", \">\": \"&gt;\" })[char]!);\n\n/** Search one document, retaining only bounded snippets, never the decoded document. */\nexport function searchFile(\n    content: string,\n    pattern: SearchPattern,\n    { encoded, limit }: { encoded: boolean; limit: number }\n): { matches: TextSearchMatch[]; truncated: boolean; skipped: boolean } {\n    if (encoded) {\n        try {\n            content = new TextDecoder(\"utf-8\", { fatal: true }).decode(base64DecToArr(content));\n        } catch {\n            return { matches: [], truncated: false, skipped: true };\n        }\n        if (content.includes(\"\\0\")) return { matches: [], truncated: false, skipped: true };\n    }\n\n    const matches: TextSearchMatch[] = [];\n    const regex = new RegExp(pattern.source, pattern.flags);\n    let lineNo = 1;\n    let lineStart = 0;\n    let lineEnd = content.indexOf(\"\\n\");\n    for (const match of content.matchAll(regex)) {\n        if (!match[0].length) continue;\n        if (matches.length === limit) return { matches, truncated: true, skipped: false };\n        while (lineEnd !== -1 && lineEnd < match.index) {\n            lineNo++;\n            lineStart = lineEnd + 1;\n            lineEnd = content.indexOf(\"\\n\", lineStart);\n        }\n        const start = Math.max(lineStart, match.index - 30);\n        const end = Math.min(lineEnd === -1 ? content.length : lineEnd, match.index + 50);\n        const matchEnd = Math.min(end, match.index + match[0].length);\n        const matchLine =\n            (start > lineStart ? \"…\" : \"\") +\n            escapeHtml(content.slice(start, match.index)) +\n            \"<b>\" +\n            escapeHtml(content.slice(match.index, matchEnd)) +\n            \"</b>\" +\n            escapeHtml(content.slice(matchEnd, end));\n        matches.push({ lineNo, index: match.index, colOffset: match.index - lineStart, matchLine });\n    }\n    return { matches, truncated: false, skipped: false };\n}\n","\"use strict\";\n\n/*\\\n|*|\n|*|  Base64 / binary data / UTF-8 strings utilities\n|*|\n|*|  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding\n|*|  Lightly hacked by Meredydd\n\\*/\n\n/* Array of bytes to base64 string decoding */\n\nfunction b64ToUint6 (nChr) {\n\n  return nChr > 64 && nChr < 91 ?\n      nChr - 65\n    : nChr > 96 && nChr < 123 ?\n      nChr - 71\n    : nChr > 47 && nChr < 58 ?\n      nChr + 4\n    : nChr === 43 ?\n      62\n    : nChr === 47 ?\n      63\n    :\n      0;\n\n}\n\n/**\n * @param {string} sBase64\n * @param {number=} nBlocksSize\n */\nfunction base64DecToArr (sBase64, nBlocksSize) {\n\n  var\n    sB64Enc = sBase64.replace(/[^A-Za-z0-9+/]/g, \"\"), nInLen = sB64Enc.length,\n    nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen);\n\n  for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {\n    nMod4 = nInIdx & 3;\n    nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 6 * (3 - nMod4);\n    if (nMod4 === 3 || nInLen - nInIdx === 1) {\n      for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {\n        taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;\n      }\n      nUint24 = 0;\n\n    }\n  }\n\n  return taBytes;\n}\n\nfunction base64DecToStr (sBase64) {\n\n  var arr = base64DecToArr(sBase64), r = \"\";\n\n  for (var i=0; i<arr.length; i++) {\n    r += String.fromCharCode(arr[i]);\n  }\n\n  return r;\n}\n\n/* Base64 string to array encoding */\n\nfunction uint6ToB64 (nUint6) {\n\n  return nUint6 < 26 ?\n      nUint6 + 65\n    : nUint6 < 52 ?\n      nUint6 + 71\n    : nUint6 < 62 ?\n      nUint6 - 4\n    : nUint6 === 62 ?\n      43\n    : nUint6 === 63 ?\n      47\n    :\n      33; // '!' - an error\n\n}\n\nfunction base64EncArr (aBytes) {\n\n  var nMod3 = 2, sB64Enc = \"\";\n\n  for (var nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {\n    nMod3 = nIdx % 3;\n    //if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += \"\\r\\n\"; }\n    nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24);\n    if (nMod3 === 2 || aBytes.length - nIdx === 1) {\n      sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63));\n      nUint24 = 0;\n    }\n  }\n\n  return sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + (nMod3 === 2 ? '' : nMod3 === 1 ? '=' : '==');\n\n}\n\nfunction base64EncStr (aBytes) {\n\n  var nMod3 = 2, sB64Enc = \"\";\n\n  for (var nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {\n    nMod3 = nIdx % 3;\n    //if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += \"\\r\\n\"; }\n    nUint24 |= aBytes.charCodeAt(nIdx) << (16 >>> nMod3 & 24);\n    if (nMod3 === 2 || aBytes.length - nIdx === 1) {\n      sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63));\n      nUint24 = 0;\n    }\n  }\n\n  return sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + (nMod3 === 2 ? '' : nMod3 === 1 ? '=' : '==');\n\n}\n\n/* UTF-8 array to DOMString and vice versa */\n\nfunction UTF8ArrToStr (aBytes) {\n\n  var sView = \"\";\n\n  for (var nPart, nLen = aBytes.length, nIdx = 0; nIdx < nLen; nIdx++) {\n    nPart = aBytes[nIdx];\n    sView += String.fromCharCode(\n      nPart > 251 && nPart < 254 && nIdx + 5 < nLen ? /* six bytes */\n        /* (nPart - 252 << 30) may be not so safe in ECMAScript! So...: */\n        (nPart - 252) * 1073741824 + (aBytes[++nIdx] - 128 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128\n      : nPart > 247 && nPart < 252 && nIdx + 4 < nLen ? /* five bytes */\n        (nPart - 248 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128\n      : nPart > 239 && nPart < 248 && nIdx + 3 < nLen ? /* four bytes */\n        (nPart - 240 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128\n      : nPart > 223 && nPart < 240 && nIdx + 2 < nLen ? /* three bytes */\n        (nPart - 224 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128\n      : nPart > 191 && nPart < 224 && nIdx + 1 < nLen ? /* two bytes */\n        (nPart - 192 << 6) + aBytes[++nIdx] - 128\n      : /* nPart < 127 ? */ /* one byte */\n        nPart\n    );\n  }\n\n  return sView;\n\n}\n\nfunction strToUTF8Arr (sDOMStr) {\n\n  var aBytes, nChr, nStrLen = sDOMStr.length, nArrLen = 0;\n\n  /* mapping... */\n\n  for (var nMapIdx = 0; nMapIdx < nStrLen; nMapIdx++) {\n    nChr = sDOMStr.charCodeAt(nMapIdx);\n    nArrLen += nChr < 0x80 ? 1 : nChr < 0x800 ? 2 : nChr < 0x10000 ? 3 : nChr < 0x200000 ? 4 : nChr < 0x4000000 ? 5 : 6;\n  }\n\n  aBytes = new Uint8Array(nArrLen);\n\n  /* transcription... */\n\n  for (var nIdx = 0, nChrIdx = 0; nIdx < nArrLen; nChrIdx++) {\n    nChr = sDOMStr.charCodeAt(nChrIdx);\n    if (nChr < 128) {\n      /* one byte */\n      aBytes[nIdx++] = nChr;\n    } else if (nChr < 0x800) {\n      /* two bytes */\n      aBytes[nIdx++] = 192 + (nChr >>> 6);\n      aBytes[nIdx++] = 128 + (nChr & 63);\n    } else if (nChr < 0x10000) {\n      /* three bytes */\n      aBytes[nIdx++] = 224 + (nChr >>> 12);\n      aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);\n      aBytes[nIdx++] = 128 + (nChr & 63);\n    } else if (nChr < 0x200000) {\n      /* four bytes */\n      aBytes[nIdx++] = 240 + (nChr >>> 18);\n      aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);\n      aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);\n      aBytes[nIdx++] = 128 + (nChr & 63);\n    } else if (nChr < 0x4000000) {\n      /* five bytes */\n      aBytes[nIdx++] = 248 + (nChr >>> 24);\n      aBytes[nIdx++] = 128 + (nChr >>> 18 & 63);\n      aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);\n      aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);\n      aBytes[nIdx++] = 128 + (nChr & 63);\n    } else /* if (nChr <= 0x7fffffff) */ {\n      /* six bytes */\n      aBytes[nIdx++] = 252 + (nChr >>> 30);\n      aBytes[nIdx++] = 128 + (nChr >>> 24 & 63);\n      aBytes[nIdx++] = 128 + (nChr >>> 18 & 63);\n      aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);\n      aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);\n      aBytes[nIdx++] = 128 + (nChr & 63);\n    }\n  }\n\n  return aBytes;\n\n}\n\nif (typeof module !== \"undefined\") {\n    module.exports = { base64EncStr, base64DecToStr, base64DecToArr, base64EncArr };\n}\n","export const LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX = \"form:\";\nexport const LEGACY_CUSTOM_COMPONENT_SPEC = new RegExp(`^${LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX}(?:([^:]+):)?(.+)$`);\nexport const LEGACY_DEPENDENCY_FORM_PROPERTY_SPEC = /^([^:]+):(.+)$/;\nexport const PACKAGE_QUALIFIED_FORM_NAME = /^([^.]+)\\.(.+)$/;\n","interface OrderedSlotDef {\n    index?: number;\n    slot_order?: number;\n}\n\ntype NamedSlotDef<T extends OrderedSlotDef> = readonly [name: string, slot: T];\n\nexport const compareNamedSlotDefs = <T extends OrderedSlotDef>(\n    [nameA, slotA]: NamedSlotDef<T>,\n    [nameB, slotB]: NamedSlotDef<T>\n) => {\n    const indexDiff = (slotA.index ?? 0) - (slotB.index ?? 0);\n    if (indexDiff !== 0) {\n        return indexDiff;\n    }\n\n    const slotOrderA = slotA.slot_order;\n    const slotOrderB = slotB.slot_order;\n    if (typeof slotOrderA === \"number\") {\n        if (typeof slotOrderB !== \"number\") {\n            return -1;\n        }\n        const slotOrderDiff = slotOrderA - slotOrderB;\n        if (slotOrderDiff !== 0) {\n            return slotOrderDiff;\n        }\n    } else if (typeof slotOrderB === \"number\") {\n        return 1;\n    }\n    return nameA < nameB ? -1 : nameA > nameB ? 1 : 0;\n};\n"],"names":["AgentComposerCard","children","className","highlighted","props","agentChatsLocation","useSelector","getAgentsChatsLocation","cx","isObject","value","codexErrorInfo","error","undefined","ANVIL_CREDIT_CARDS","CardActions","actions","dispatch","useDispatch","Button","navigate","ErrorTurn","turn","info","conversation","useConversationContext","agentType","doLogout","useConversationCallbacks","agentAuth","useAgentAuth","hasRestarted","setHasRestarted","useState","outOfCredit","quotas","useQuery","getQuota","kind","classifyModelError","credit","recoveryAction","getAgentErrorRecoveryAction","data","isCodexErrorThatNeedsLogout","authType","isConnected","canRecover","isLatest","billingLink","getProviderBillingLink","message","isAnvilCreditKind","showRestart","showLogout","FontAwesomeIcon","faExclamationTriangle","restartAgent","ConversationTurn","PromptTurn","faDatabase","schemaEntries","schema","Object","isSupportedFormProperty","property","isUserNote","key","customAnswerQuestionId","questionsForSchema","entries","byKey","Map","associatedFields","questionId","parentKey","optionsForProperty","option","anyOf","Array","enumValues","hasValue","valueIsValid","required","Number","questionIsComplete","question","values","answer","otherAnswer","hasNoteAnswer","formIsComplete","questions","displayValue","options","item","String","choiceClass","selected","propertyText","OptionText","label","description","index","QuestionInput","setValue","disabled","checked","atLimit","CheckBox","event","RadioButton","TextBox","TextArea","NoteInput","onChange","onSubmit","placeholder","FormElicitationComposer","section","onRespondToElicitation","setValues","step","setStep","submitting","setSubmitting","questionHeading","showMessage","submit","useEvent","responseValues","finalStep","commitQuestion","nextValues","updateValue","commit","updateFormQuestionValue","current","next","skipQuestion","onPreviousQuestion","onNextQuestion","onQuestionValueChange","onAssociatedValueChange","onAssociatedSubmit","faCircleQuestion","faChevronLeft","faChevronRight","FormElicitationHistory","expanded","setExpanded","onToggleExpanded","response","LinkInternal","faChevronDown","Expander","answerLines","lines","answerLinesForQuestion","associatedAnswer","line","LoginPrompts","conversationInfo","enabledAgentTypes","getEnabledAgentTypes","onClickOpenCodexLogin","wakeConversation","modal","onClickOpenClaudeLogin","onClickOpenZaiLogin","onClickOpenCustomLogin","faArrowRight","selectedOptionName","currentValue","ConfigurationOptionLabel","tooltip","tooltipRef","useTooltip","ComposerConfiguration","config","pending","onChangeConfig","modelConfig","effortConfig","modelOptions","selectableEffortConfig","effortOptions","modelValue","effortValue","modelName","effortName","checkIcon","faCheck","DropdownMenu","showMenu","anchor","e","AgentChooser","onChangeAgentType","DropDown","agentTypeId","AGENT_TYPE_NAMES","DEFAULT_RECOGNITION_LANGUAGE","replaceDictationTranscript","view","transcript","range","docLength","from","Math","to","insert","transcriptWithSpacing","text","before","after","prefix","suffix","dictationWave","keyframes","useDictationStyles","makeStyles","theme","_props","classes","DictationIndicator","_","PromptDictation","dictation","faMicrophone","kindPaths","contextMarkdownLink","href","encodeURI","char","contextCompletionDisplay","fullName","packageName","separator","splitAt","parent","Boolean","contextCompletionForLocal","path","contextCompletionForDependency","agentCommandInfoElement","command","document","title","slashCommandDisplayText","availableCommandSubmittedTokenName","type","sourceLabelDisplayText","availableCommandSourceLabel","body","hint","contextLinkMatcher","RegExp","agentMarkdownDestinationPattern","ContextLinkWidget","WidgetType","navTarget","appId","onNavigate","other","JSON","link","getUrlForNavTarget","DisabledContextLinkWidget","span","SlashTokenWidget","onShowCommand","button","makeDecorations","app","commandsByName","ranges","seenRanges","Set","addRange","decoration","visibleRange","match","decodeAgentMarkdownHref","navTargetFromAgentMarkdownHref","Decoration","isDependencyCodePath","findSlashCommandTokenMatches","rangeFrom","a","b","builder","RangeSetBuilder","PromptComposerDecorations","update","renderPromptCompletionIcon","completion","completionTypes","iconDefinition","faCube","faRobot","faPage","iconElement","icon","renderPromptCompletionParent","parentPath","renderPromptCompletionMetadata","sourceLabel","metadata","sourceElement","IMAGE_SIZE_LIMIT_LABEL","MAX_IMAGE_BYTES","readFileAsDataUrl","file","Promise","resolve","reject","reader","FileReader","Error","dataTransferHasFiles","dataTransfer","dataTransferHasImageFile","items","imageToContentBlock","image","dataUrlPayload","dataUrl","ContextUsageIndicator","usage","usedPercent","percentUsed","circumference","dashOffset","formatTokenCount","ComposerImageTray","images","onRemoveImage","faTimes","SubmitStopButton","turnActive","onSubmitClick","onStopClick","faStop","faArrowUp","ComposerToolbar","configuration","controls","PromptComposer","onStop","availableCommands","isVisible","sessionConfig","onOpenSearch","header","sessionStatus","useMemo","displayedConversationConfig","user","getUser","isDisabled","getAppId","conversationPid","composerImages","useComposerImages","fileInputRef","useRef","dragDepthRef","setImages","useStateWithCustomUpdate","getPromptComposerDraft","setPromptComposerDraftImages","draggingImages","setDraggingImages","addImageFiles","files","nextImages","crypto","alert","removeImage","id","clearImages","restoreImages","onImageInputChange","onAttachImageClick","onDragEnter","onDragOver","onDragLeave","onDrop","inputComponent","clearSavedDraft","usePromptComposerDraftView","onChangeInteractionMode","supportsPlan","interactionMode","planModeActive","togglePlanMode","onPromptSubmit","prompt","usePromptDictation","recognitionRef","intentionallyStoppingRef","insertionRangeRef","draftRangeRef","isDictating","setIsDictating","setError","SpeechRecognitionCtor","window","supported","stop","recognition","toggle","getRecognitionLanguage","language","navigator","finalTranscript","interimTranscript","i","result","insertedRange","useEffect","toolbarComponent","submitCommand","submissionError","clearSubmissionError","usePromptSubmit","onPromptCleared","submittingRef","setSubmissionError","acceptCompletion","onOpenUsage","usageCompletion","editorView","localSlashCompletions","providerCommands","omitProviderPlanCommand","useBaseTheme","useFocusCodeOnSelection","useTheme","composerTheme","EditorView","useExtension","startCompletion","Prec","checkMeta","keymap","insertNewlineAndIndent","enabled","slashCommandsByName","usePromptAutocompletion","contextCompletions","slashCompletions","dollarCompletions","usePromptComposerCompletions","useContextCompletions","forms","getForms","modules","getModules","serverModules","getServerModules","assets","getAppAssets","dependencyStructure","getDependencyStructure","dependencyAssets","getDependencyAssets","completions","dependency","preferLocalSlashCompletions","slashCompletionsForCommands","dollarCompletionsForCommands","slashCommandName","promptCommand","autocompletion","completionSource","getApp","navigateContextLink","showCommandDetails","promptComposerDecorations","plugin","ViewPlugin","isTurnActive","CodeMirrorElement","faPlus","faListRadio","faImage","faXmark","StartPagePromptComposer","setPrompt","submittingPrompt","setSubmittingPrompt","submitPrompt","createAppWithPrompt","ContentTextAreaInput","DEFAULT_CONTEXT_LINES","splitTextLines","isStructuredDiffContent","content","diff","countChangedLines","changes","change","hunkHeader","oldLineNumbers","newLineNumbers","oldStart","newStart","oldLineCount","newLineCount","normalizeDiff","oldText","diffTextLines","newText","oldLines","newLines","idx","dp","Uint32Array","j","oldIdx","newIdx","buildUnifiedDiffRowsFromChanges","contextLines","changedIndexes","hunks","changedIndex","start","end","previousHunk","rows","hunk","hunkChanges","DiffGutterMarker","GutterMarker","marker","rowTypeClass","row","DiffCodeMirror","doc","useEditorView","EditorState","scrollBar","StateField","state","buildDiffDecorations","decorations","field","gutter","isDark","diffTheme","CountBadge","addedLines","deletedLines","DiffPathLabel","labelForAgentFilePathReference","openFileSlotClass","AgentFileDiff","suppliedDiff","load","queryKey","status","collapsed","setCollapsed","hasOpened","setHasOpened","Infinity","navTargetFromAgentPathReference","Link","titleForAgentPathReference","faFileCode","AgentToolCallDiff","diffs","AgentTurnDiff","showAll","setShowAll","promptPid","expiredByTime","Date","unavailable","getTurnDiff","expired","fileCount","visibleFiles","hiddenFileCount","faFilePen","getTurnFileDiff","faChevronUp","IDE_ASSETS_PATH_RE","THEME_ASSETS_PATH_RE","ENV_THEME_ASSETS_PATH_RE","decodePathSegments","part","decodeURIComponent","themeAssetSrc","themePrefix","assetRelativePath","encodeURIComponent","resolveAgentImageSrc","mimeType","uri","assetPath","themeAssetRelativePath","ref","normalized","AgentImageContent","alt","src","useDebugThemePrefix","textFromNode","node","isValidElement","IdeTargetLink","iconForCodePath","codePath","folder","nameParts","name","itemType","itemTypeByFolder","getIconFromFile","icons","serviceIcons","Children","isCodeLink","showArrow","ExternalLink","opensNewTab","DisabledCodeReference","DisabledFileReference","MarkdownLink","labelForAgentMarkdownLink","pathLabel","labelForAgentNavTarget","replaceSingleCodeChildText","childArray","child","cloneElement","segments","splitAgentPathReferenceText","isAgentFilePathLink","labelForDisabledFileLink","displayPath","displayPathFromAgentPathReference","AgentPathReference","AgentPathReferenceText","segment","markdownAlertMarkerPattern","markdownAlertStyles","faCircleInfo","faLightbulb","faCircleExclamation","faTriangleExclamation","stripMarkdownAlertMarker","strippedNode","stripped","nodeArray","element","markdownConversationComponents","childNodes","markerChildIndex","markerChild","alertType","markdownAlertTypeFromText","alertStyle","alertChildren","copyText","CopyButton","AgentMarkdown","components","remarkPlugins","agentPathLinks","agentPathReferenceLinks","Markdown","remarkGfm","AgentContent","finalResponse","markdownClassName","nodes","textBuffer","flushText","ProposedPlanContent","plan","entry","ProposedPlanCard","isWriting","scroller","canScrollDown","setCanScrollDown","updateFade","el","useResizeObserver","LoadingSpinner","PermissionRequestCard","onRespondToPermission","resolvedExpanded","setResolvedExpanded","isPending","selectedOptionId","selectedOption","optionId","cancelled","hasContent","choose","heading","uniqueNonEmptyPaths","paths","seen","uniquePaths","trimmedPath","ToolPathReference","ToolCall","toolCall","callMessage","toolKindIcon","faFile","action","restParts","rest","faFileMagnifyingGlass","faFileLines","extractToolCallDiffs","diffsByPath","editToolCallFiles","locations","locationPaths","location","contentPaths","f","contentNodes","renderedImage","block","rawOutput","skillLinkPrefix","SkillDetails","SkillCommandButton","skillName","showSkillDetails","Prompt","timestamp","skillCommandLinks","useCallback","tree","addSkillCommandLinks","visit","lastIndex","useShowSkillDetails","markdownComponents","hasPromptText","contentBlock","cb","formatRelativeCalendarTime","AgentContentSection","contentType","c","ToolCallsSection","promptTurn","call","elicitationToolCallIds","candidate","toolCallId","permissionToolCallIds","visibleToolCalls","ResponseSection","AgentFinalMessage","ResponseTimeline","isWorkingOnThisTurn","timeline","buildResponseTimeline","sections","awaitingPermission","settledIndexes","latestMessageIndex","workingSections","flushWorking","isWritingPlan","hasWorkingSections","duration","startTime","diffMs","endTime","getAgentTypeName","sectionIndex","SchemaMigrationBanner","tableMapping","isNewConversation","canApplyDirectly","canApplySchemaDiffDirectly","summary","summariseSchemaDiff","agentName","applying","setApplying","reportFailure","applyChanges","updateTableMappingSchema","updateAppSchemaSync","faListCheck","activateButtonOnKeyDown","TemporaryDatabaseDialog","tableMappingId","closeOnTableClick","onClose","mappings","getAllTableMappings","mapping","tables","sortBy","selectedTableId","useNavTargetSelector","target","dialogRef","dialog","previousFocus","HTMLElement","isError","reloadTableMapping","table","SecondaryNavLink","getTableNavTarget","faTable","localCodePathMatcher","dependencyCodePathMatcher","dependencyFilesystemPathMatcher","viewModes","serviceTargets","decodeURI","parseAgentMarkdownViewHash","hash","viewType","viewRest","focus","viewValue","mode","dotPathFromFilesystemPath","codeView","designView","htmlView","sourcePathLineSuffixMatcher","normalizeAgentPathReference","urlSchemeMatcher","agentCheckoutPathMatcher","appRelativePathFromAgentPathReference","normalizedPath","agentCheckoutPath","appIndex","displayUnlinkedAppRelativePath","pythonCodeNameFromStoragePath","packageMatch","fileMatch","stripToAppStoragePath","decodedFilePath","appRelativePath","bestMatchIndex","root","startMatch","innerMatch","splitSourcePathLineSuffix","lineMatch","codeViewForLine","testFileReferenceMatcher","decodedPath","testFileTarget","testFileNavTargetFromAgentPathReference","filePath","appStoragePathReference","appStoragePath","clientPath","htmlTemplateMatch","htmlBodyLineForSourceLine","sourceLine","form","offset","htmlTemplateBodyLineOffset","bodyLine","yamlTemplateMatch","codeName","formExists","serverPath","decodedHref","pathTarget","localCodePathMatch","codePathType","codePathName","schemaRoute","routeSegment","dataTableName","defaultMapping","table_mapping_id","python_name","codeNameParts","filesystemRootMatcher","anvilYamlMatcher","sourceFileExtensionMatcher","pathReferenceMatcher","unlinkedAppPathMatcher","trailingPunctuationMatcher","quoteCharacters","splitPathReference","linkText","trailingText","trailingMatch","appendTextSegments","quote","isQuoted","prefixEnd","split","linkifyTextValue","inlineCode","navTargetFromInlineCodeReference","linkifyAgentPathReferences","SCROLLABLE_OVERFLOW_RE","USER_SCROLLABLE_OVERFLOW_RE","TEXT_NODE_FILTER","NodeFilter","highlightFromRangeRect","rangeRect","turnRect","clipElement","boundaryElement","matchIndex","turnIndex","occurrenceIndex","scopeKind","sourceText","visibleLeft","visibleTop","visibleRight","visibleBottom","style","getComputedStyle","overflow","rect","isNestedScrollableElement","canScrollX","canScrollY","isHorizontalScrollableElement","isVerticalScrollableElement","revealRangeVertically","virtualScrollerElement","scrollVirtualizerByDelta","scrollElement","nearestVerticalScrollableAncestor","scrollRect","revealPadding","revealTop","occludedScrollTop","top","panel","panelRect","overlapsScrollElement","revealBottom","revealCenter","rangeCenter","scrollDelta","forEachTurnSearchOccurrence","turnElement","searchTerm","onOccurrence","normalizedSearchTerm","searchScope","currentNode","walker","Node","normalizedText","startPos","parentElement","shouldContinue","ConversationTurnSearchHighlights","currentMatchIndex","matches","totalMatchCount","turnRef","highlights","setHighlights","trimmedSearchTerm","updateHighlights","collectTurnHighlights","visibleHighlights","visibleMatchIndexes","indexes","occurrence","matchIndexes","highlight","useLayoutEffect","animationFrame","settleReveal","attempt","requestAnimationFrame","didScroll","revealActiveMatch","activeMatch","nearestHorizontalScrollableAncestor","cancelAnimationFrame","scheduleHighlightUpdate","resizeObserver","ResizeObserver","scrollableElements","scrollableElement","isCurrent","ConversationSearch","search","isOpen","inputRef","closeSearch","resetSearch","onSearchTermChange","onPreviousClick","onNextClick","onEnter","ContentTextInput","faAngleUp","faAngleDown","agentMessageText","approximateRenderedText","INITIAL_CONVERSATION_SEARCH","clampMatchIndex","matchCount","conversationSearchReducer","useConversationSearchFeature","isTab","isTurnMounted","scrollToTurnIndex","useConversationSearch","useReducer","searchConversation","searchableTurns","searchableTextForTurn","finalAgentMessageText","finalSection","currentMatch","transcriptSearchState","controllerState","open","onKeyDown","onDocumentKeyDown","SLASH_COMMAND_NAME_START_PATTERN","SLASH_COMMAND_NAME_BODY_PATTERN","SLASH_COMMAND_NAME_PATTERN","SLASH_COMMAND_COMPLETION_PATTERN","DOLLAR_COMMAND_COMPLETION_PATTERN","slashCommandTokenMatcher","leadingText","dollarToken","dollarCommandName","commandName","tokenStart","slashCommandApplyText","isAvailableCommandSkill","commandMetaCommandKind","anvilMeta","commandKind","commandMetaSourceLabel","sourceLabelRank","completionSectionRank","compareCompletions","commandCompletion","includeSection","applyText","isSkill","submittedTokenName","boost","sourceLabelBoost","commandInfo","providerCompletions","localCompletions","localLabels","trigger","triggerPattern","matcher","validFor","context","token","triggerIndex","tokenFrom","matched","apply","_completion","closeCompletion","ConversationContext","createContext","createContextHook","createConversationModel","cancelOpenPromptSections","evt","findFormElicitationSection","elicitationId","findPermissionSection","permissionId","applyConversationSectionEvent","currentPromptTurn","updateProposedPlan","existingPlan","existingPlanTurn","removeProposedPlan","planId","cancellation","planIndex","planSection","structuredClone","normalizeConversationConfig","interactionModes","applyConversationConfigUpdate","mergeConversationConfigUpdate","EMPTY_CONVERSATION_MODEL","freeze","activeAgentErrorAlerts","normalizeAgentSessionError","applyConversationEvent","conv","console","fullyReceived","mergeUsageUpdate","latestSection","m","tc","errorTurn","addSessionBoundaryTurn","latestPromptTurn","buildInitialConversationModel","session_status","pending_prompt","getConversationQueryKey","seedNewConversation","queryClient","updateConversationQuery","updater","produce","ingestAgentSessionUpdate","getConversationListQueryKey","cacheSessionCapabilities","showAgentSessionErrorAlert","alertKey","openConversation","ingestConversationInfoUpdate","useConversation","useQueryClient","isStale","fetchStatus","failureCount","refetch","conversationModel","queryOptions","events","getConversation","updateConversationListQuery","cs","dropProviderUsage","query","DEFAULT_QUERY_STALE_TIME","onWsEvent","refreshAgentAuth","parseAgentUrlElicitation","codeMatch","cursors","useWebsocketEventListener","getQueryOptions","conversations","historyNotice","useConversationScrolling","showScrollToTop","setShowScrollToTop","showScrollToBottom","setShowScrollToBottom","scrollingToBottom","setScrollingToBottom","scrollingToTop","setScrollingToTop","didInitialScrollToEnd","estimatedTurnHeight","useRemToPixels","turnPaddingStart","turnGap","showActiveTurn","virtualRows","virtualRowsRef","getVirtualRowKey","itemCount","rowVirtualizer","useVirtualizer","virtualItems","totalSize","updateScrollAffordances","isAtTop","isAtBottom","distanceFromBottom","onScroll","scrollToTop","scrollToBottomWithOptions","behavior","trackAnimation","updatedEl","scrollToBottom","ws","onSubmitMessage","request","draftInteractionModeId","interaction_mode","source","prompt_id","requestId","msg","t","category","configAfterThisChoice","updateConversationInfo","updateUserEditorPrefs","apiKey","loginType","doDisconnectAgent","getAgentAuth","promptComposerDrafts","draftStorageKey","persistDraftText","sessionStorage","copyDraft","draft","setPromptComposerDraft","hasDraftContent","clearPromptComposerDraft","createPromptComposerState","stateObject","basicExtensions","completionTab","basicKeyMap","historyField","useUpdateListener","editorState","SAFE_CHANGE_TYPES","describeCount","count","singular","plural","getSchemaChangeActions","pastTense","counts","safeChangeTypes","operations","otherOperationCount","joinActions","storageKey","session","_selected","localStorage","cached","readSessionCapabilities","offered","base","incoming","mergeProviderUsage","windows","tokens","used","size","percentLeft","sortedUsageWindows","formatResetTime","resetsAtEpochSeconds","resetDate","now","time","date","refreshPythonDiagnostics","StateEffect","deduplicateHoverActions","diagnostics","diagnostic","pythonDiagnosticSource","syntaxDiagnostics","controller","AbortController","discard","forEachDiagnostic","quickFixes","diagnosticKey","code","fixesByDiagnostic","fixKey","fix","editor","applyPythonQuickFix","edits","edit","lspRangeToOffsets","ChangeSet","isolateHistory","Transaction","fixes","sharedActions","jumpCandidateAt","coords","hit","syntaxTree","quoted","pointerClass","pointerTheme","setNavigationNotice","navigationNotice","transaction","effect","showTooltip","pythonEditorTools","clearTimeout","closeHoverTooltips","dom","setTimeout","followsCaret","pythonJumpPointer","hasJumpTarget","previous","x","y","isModifier","delay","found","hoverTooltip","pos","side","hover","selection","onAction","run","pythonDocumentationElement","ProjectAnalysis","project","documents","snapshot","diffAnalysisFiles","performance","position","autoImport","signal","params","DOMException","finish","abort","job","targets","results","readSource","sources","readable","URL","definitions","isAtLocation","references","getTyAnalysisEnabled","getAbTyAnalysis","editors","getAnalysisEditors","registration","contexts","designers","sourceEditors","registerReadOnlySource","disposeUnusedAnalysis","getReadOnlySourceEditor","pendingProjectQueries","projectCache","owners","disposeAnalysis","projectKind","analysis","analysisProjectKind","registerAnalysisDesigner","designer","registerAnalysisEditor","registerAnalysisContext","currentOwner","getAnalysisInputs","getDebugEnvironmentTables","getDebugEnvironmentTableMapping","getUserTabSize","getAnalysisItems","structures","group","structure","getCachedCodeItem","collectProject","inputs","input","buildAnalysisProject","getServerPythonMinorVersion","collectDocuments","getAnalysisFiles","withPythonAnalysis","completionActivity","requestedProjectKind","_dispatch","getState","contextIsRegistered","originalDoc","owner","module","library","latest","currentDocuments","pythonSourceUri","getPythonBackgroundTasks","task","refreshPythonAppMetadata","publish","_input","_position","uris","findPythonTargets","sourceForLocation","readPythonSource","requestPython","requestedRevision","revisionMatches","requestPythonHover","definition","typeDefinition","rename","hoveredPosition","destinations","types","sameDestinations","requestPythonItemMetadata","requestPythonContext","getContext","requestPythonRename","requestPythonResourceRename","requestPythonComponentRename","setHints","hints","HintWidget","pythonInlayHints","visible","widgets","character","affectedReleases","addConfig","package_name","db_schema","dependencies","services","runtime_options","startup_form","startup","addItem","dependencyId","directory","codeFile","serialized_html","template","templatePath","packages","decodeAssetContent","tests","addTests","dependencyRoots","dependencyRoot","addMaterial3PropertyTypes","commitId","decoratorInput","declarations","newline","decoratorLine","importLine","wrapsProperty","callback","logicalId","properties","layoutProperties","methods","container","args","optional","pythonSourceLabel","url","relative","boundary","renameBoundaries","ids","renameHistoryEffects","invertedEffects","registered","WeakMap","WeakSet","dispatchWithRenameHistory","transactions","history","renameHistoryCommand","direction","undo","redo","confirmation","accepted","matchingRenameBoundary","registerRenameHistory","renameBoundary","setSignature","callArguments","head","signatureField","pythonSignatures","help","signatureElement","signature","parameter","active","_state","focusing","instance","pythonSourceNavTarget","isCodePath","sourcePath","textChanges","resolveField","object","applyFormFields","fields","findComponentByNameInTree","prepareWorkspaceEdit","original","binding","component","containers","expression","renamed","ownerNames","slot","handlerRenames","names","handlers","bindings","handler","replacement","layout","walk","resource","newCodePath","unsubscribeOwner","records","nextId","committing","ownApp","releaseUnloadedApp","mapRecords","record","patch","abandonRedo","captureCodeHistory","folding","foldState","strHashCode","registerAppRenameEditor","unregister","confirmRenameHistory","prepareRenameHistory","CodeMirror","currentPath","registerRenameDesigner","abandonRenameRedo","prepareCommit","getAppIsEditable","resources","publishResources","prepareCodeResourceRenames","packageItems","syncHtmlFormAfterDesignerMutation","activeDesigners","liveDesignPaths","moveDesignHistory","designHistories","design","getCodeItemHistory","HistoryState","openPaths","codeHistories","saved","loaded","loadWithEditorHistory","nativeHistory","native","ExternalUpdate","activeResource","_getState","updateState","originalPath","appPath","updateEditorSequenceAppPaths","saveAppOnIdle","refreshes","refreshItemMetadata","commitWorkspaceRename","patches","structural","scope","details","confirm","loadWorkspaceRenameSources","flushUnsavedCallbacks","openCodeItem","applyPythonRename","nextPatches","views","_from","_to","listConversations","get","createConversation","app_id","agent_type","env_id","post","deleteConversation","del","updates","put","resetAllAgents","turnDiffUrl","getAppAccessibleTableMappings","linkExistingMapping","mappingId","linkExistingTable","valOrDefault","createTable","updateTable","deleteTable","applySchemaDiff","forceSetSchema","saveTableCol","tableId","colId","colSpec","deleteTableCol","modifyTableIndex","updateTableAccess","access","getTableMappings","app_schema","getTableMapping","createTableMapping","deploymentPoolId","renameTableMapping","setTableMappingRestricted","restricted","deleteTableMapping","removeTableMappingAccess","getTableRows","urlQueryParams","omit","addTableRow","getTableRow","rowId","getLiveObject","uploadMedia","blob","rowToCreate","onProgressUpdate","aborter","rootUrl","resp","fetch","server","uploadId","chunkCount","last","chunkResp","deleteMedia","deleteTableRow","updateTableRow","deleteAllRows","getTableDownloadUrl","getMediaDownloadUrl","cloneDatabase","withoutMedia","restoreDatabase","targetTime","pythonGlobalCompletions","beforeSpace","globalCompletion","CompletionContext","getCompletions","usePythonCompletionEngine","doAnalysis","analysisEnabled","tyCompletionEnabled","diagnosticLinter","useDiagnostics","completionOverride","requestCompletions","importCompletionOverride","prepareCompletion","clearParamaterHelper","pythonAutocompletion","_event","paramaterTooltipField","analysisFailuresField","useTyCompletions","completionSources","pythonCompletionSources","method","useServerTestAutoComplete","diagnosticRequest","useTyDiagnosticRequest","useAutoComplete","codeItem","requestDiagnostics","metadataEffects","updateItemMetadata","autocomplete","col","seed","analyseItem","useContextCompletion","getScope","useId","useIsolatedFormCodeAutoComplete","formUri","analyseIsolatedFormCode","useReplAutoComplete","isServer","invalidate","rv","analyseReplCode","pythonCompletionAllowed","filter","getCompletionProps","importMatch","wordMatch","stringMatch","tokenStringMatch","globals","setAnalysisFailures","messages","httpEndpoints","emailEndpoints","routes","eventHandlers","setParamaterHelper","getCompletionOptions","defaultCompletionIndex","isDouble","priority","popup","CompletionInfoElement","typeName","typeEnding","typeMatcher","iconMap","defaultOption","globalOptions","scopeNames","foldRangeRecursively","invalid","effects","foldable","foldEffect","findFold","getFoldableRegion","startingIndent","lineBlock","getIndentation","doFold","onRangeFound","selectedLines","l","foldAtLevel","level","levels","levelRange","foldKeymap","unfoldAll","hasRegions","unfoldEffect","regions","announceFold","fold","lineFrom","lineTo","unfoldCode","clipboardMimeType","leadingWhitespace","firstNonBlankLine","n","smartPaste","linewise","firstLine","countColumn","preserve","readCopyMetadata","empty","pasteFrom","indentationState","indented","indentPastedBlock","inserted","sourceIndent","afterCode","pasted","suggestedIndent","column","targetIndent","originalIndent","delta","sourceColumn","indent","indentString","endLine","endPrefix","Text","rawPaste","format","MapConflictsFrom","defaultTabBinding","indentMoreOverride","closeBracketsKeymap","historyKeymap","defaultKeymap","deleteLine","toggleComment","editorKeyMap","lintKeymap","highlightSpecialChars","drawSelection","indentOnInput","syntaxHighlighting","defaultHighlightStyle","bracketMatching","closeBrackets","dropCursor","rectangularSelection","highlightSelectionMatches","editorExtensions","keyBindingsExtension","lineNumbers","highlightActiveLineGutter","foldGutter","faCaretDown","faCaretRight","altKey","shiftKey","highlightActiveLine","python","pythonLanguage","LanguageSupport","useToolBarBtnStyles","ignoreSsrWarning","useImageViewStyles","ToolBarBtn","onClick","EDIT_REGEX","IMAGE_REGEX","getEditableFileType","fileName","getImageType","ReplaceBtn","useReplaceAsset","faUpload","ESLintButton","fileType","eslint","getUserEslintPref","onToggleESLint","faShieldCheck","faShieldTimes","AssetFormatButton","canFormat","useViewSelector","formatCodeCommand","FormatCodeButton","ToolBar","isEditable","canPreview","preview","setPreview","formatButton","renameAsset","newName","renameCodeItem","deleteAsset","deleteCodeItem","copyClickHandler","copyTooltip","copyRef","useCopyAssetPath","onTogglePreview","v","TabToolbar","faCode","faEye","faPencilAlt","faTrashAlt","faCopy","ImageView","imageType","editableFile","isMarkdown","markdownContent","setEditorView","isSvg","MarkdownAssetPreview","AssetCodeEditor","lazyComponent","ModuleEditor","AssetEditor","ExtraFileEditor","DataBindingEditor","HtmlFormTemplateEditor","HtmlPropertyEditor","ImportMapEditor","LazyAssetEditor","NativeLibrariesEditor","StylePropertyEditor","HtmlBodyEditor","autoFocus","scrollIntoView","height","domWrapperRef","domWrapper","CodeMirrorWithSearch","getRandomString","SearchPanel","NavigableCodeMirrorWithSearch","preserveFocus","usePreserveNavigationFocus","useFocusCodeOnNavigation","ReplEditor","getRuffTargetVersion","runtimeOptions","catalog","resolveRuffConfig","parse","defaultConfig","L","D","KEY0","KEY1","LIT0","LIT1","VAR0","COMMENT","TEXT","baseStyles","colorMap","styleDef","tagStyleDef","tagName","color","styles","tagStyle","getTag","tagNames","tag","tags","callableTag","makeStylesLight","makeStylesDark","baseStylesLight","baseStylesDark","cssStyleDef","cssTagsLight","cssTagsDark","HtmlStyleDef","htmlTagsLight","htmlTagsDark","jsStyleDef","jsTagsLight","jsTagsDark","markdownStyleDef","markdownTagsLight","markdownTagsDark","yamlStyleDef","yamlTagsLight","yamlTagsDark","mkHighlightStyle","tagStyles","HighlightStyle","lightHighlightStyle","darkHighlightStyle","highlightStyles","javascriptLanguage","cssLanguage","ThemeExtension","overrides","useSyntaxHighlighting","fileExtension","syntaxHighlightStyle","highlightStyle","useGutters","GutterExtension","useEditorTheme","activeLineColor","MethodFound","ClassDefinitionEnd","ClassBodyScanner","methodName","tabSize","quiet","scanPython","string","countLeadingWhiteSpace","chr","useConflictMarkers","conflicts","updateCodeItem","useIsDark","mergeIdentity","mergeId","getAppEditState","merge","manager","newConflicts","text_chunks","UpdatingCodeItemEffect","seqNum","SeqNumberEffect","conflictListener","isExternalUpdate","conflictManager","conflictManagerState","tr","ResolveConflictEffect","RestoreConflictsEffect","useSubscribeToDispatchEvent","EVENTS","navCodePath","nextConflict","textChunks","anchorLineNumber","textChunk","conflictTheme","ConflictManager","makeMarkers","markers","altRanges","from0","from1","s0","s1","infoBannerDecoration","makeLines","lineDecos","lineStarts","froms0","froms1","backgroundColorLine","shade","conflictMinimap","isEqual","InitializeConflictsEffect","portals","widget","InfoBanner","createPortal","createElement","ConflictActions","toolbar","banner","edited","conflictMinimapGutters","Facet","colors","chunks","folds","foldedRanges","first","minimapRow","hidden","gutters","chunk","mapAltsToRanges","alts","alt_froms","TextChunkRange","newFrom","newTo","deletedLine","lineStart","lineEnd","touched","text_chunk","newRanges","Annotation","restores","preceding","conflictEffect","resolveConflict","choice","rejected","nextLine","cssDropzoneWarningLintSource","warnings","cssDropzoneWarningLinter","linter","extensionCreator","deps","compartmentRef","Compartment","compartment","extension","effectValueFromUpdate","ifNotFound","ef","initState","viewRef","useImperativeHandle","historyState","_history","withoutHistory","useUpdateIndent","indentUnit","codemirrorReindenter","indentRange","useReindent","useAsyncExtension","useConstant","useEffectAsync","subscribe","useSyncExternalStore","useDependOnEditorSequenceNumber","getDoc","sequenceNum","useEditSequenceNumber","onSequenceNumChanged","localSequenceNum","updating","SequenceNumberState","currentItemDoc","useDependOnEditorSequenceNumberCode","usePanelPortal","outerContainer","portalDiv","useUpdateCodeItem","saveCode","saveRest","useUpdateCodeItemWithUpdater","conflicts_","SaveCodeItemEffect","useUpdateCodeItemLazy","codeItemUpdater","timeoutRef","unsavedRef","unsavedCb","onSaveCode","saveEffect","markUnsaved","afterSave","notifyUnsavedCallback","useEffectWhen","useSaveEditorHistory","hashItem","savedBoundaries","setCodeItemHistory","useSaveExtraFileEditorHistory","cacheKey","getCacheKey","saveHistory","getExtraFileContent","onBeforeRename","affectedCacheKeys","onEvent","offEvent","refocusView","useFocusCodeOnViewChange","viewFocus","editorType","useLayoutEffectWhen","useUpdateNavigationOnPointerSelection","updateView","startAnchor","anchorPos","NavigationAnnotation","viewVal","cacheView","insertHistoryStateBeforeNextNavigation","useUpdateSelectionOnHashChange","jumpToCode","jumpLoc","newAnchorPos","lastProcessHash","hashObject","jumpToHash","useEffectEvent","isEmpty","lineStr","colStr","isFirstRenderRef","useUpdateGlobalHistory","globalHistoryChange","onFocus","useSetGlobalHistory","undoDepth","redoDepth","create","useMiniMap","includeMiniMap","getUserMinimapPref","isEditorWideEnoughForMiniMap","setIsEditorWideEnoughForMiniMap","remToPixels","wideEnough","editorWidth","EDITOR_MIN_WIDTH_REM","flushSync","shouldUseMiniMap","showMinimap","useFormatOnSave","formatOnSave","getUserUiPrefs","useExtraFileDocument","editable","getExtraFileConflicts","onUpdate","saveExtraFile","_description","updatedConflicts","justResolvedLastConflict","sequenceNumber","confirmItemConflictsResolved","indentationGuides","IndentationGuides","getTheme","useIndentationGuides","createGradient","markerCssProperty","thickness","indentWidth","startOffset","columns","gradient","makeIndentationDecorators","cursorPos","activeLines","spaceOnlyLines","cursorIndex","visibleFrom","visibleTo","length","number","whiteSpace","getWhiteSpaceAndColumn","backgrounds","makeBackgroundCSS","hideFirstIndent","startAt","markersBeforeActive","clientBg","serverBg","baseIndentationGuides","useFocusMethod","MethodFocusPlugin","methodFocusTheme","methodFocusField","FocusMethodEffect","unfocusedLineDeco","targetDefDeco","FocusRange","targetPos","focusFieldValue","focusFrom","focusTo","prevRange","unfocusedLines","targetDec","filename","literal","depth","scan","splitLines","Reindenter","readString","expandTabs","stats","have2want","thisstmt","thislevel","nextstmt","have","getlspace","want","jline","jlevel","remove","reindent","TestAnchor","RangeValue","testIds","MapMode","replaceTestAnchors","testAnchorsField","RangeSet","anchors","nextAnchors","ServerTestMarker","display","getLineTestDisplay","displays","test","getTestStatusDisplay","running","outcome","unsuccessful","showPlay","actionLabel","statusDetails","statusIcon","faPlay","playIcon","useServerTestGutter","testingEnabled","getTestingEnabled","getServerTestDisplayResults","testsAreBusy","getAreServerTestsBusy","onRunTests","setSelectedServerTestId","openOrFocusBottomTab","runServerTests","discoveredTests","getLatestServerTestDiscovery","scheduleAnchorRefresh","pendingFrame","pendingRefresh","discoveredPath","rebuildAnchors","positions","findServerTestPositions","testIdsByPosition","testId","testsAtLine","MouseEvent","candidates","ensureSyntaxTree","parts","qualifiedName","nodeIdPrefix","relativeId","parameterStart","getServerTestSourceLine","changeBySelectedLine","atLine","changeSet","EditorSelection","indentMore","indentLess","unIndent","r","AccountPageContent","currentNavTarget","useCurrentNavTarget","Heading","AccountModalContent","contentRef","showContent","useDelayWhenFalseFlag","zenMode","getZenMode","TagChip","onRemove","VALID_TAG_RE","TagInput","suggestions","ddClasses","useDdStyles","inputValue","setInputValue","showDropdown","setShowDropdown","hoverIndex","setHoverIndex","validationError","setValidationError","dropdownAbove","setDropdownAbove","dropdownMeasured","setDropdownMeasured","containerRef","dropdownRef","mergedRef","useMergeRefs","isAtLimit","filteredSuggestions","tagsLower","available","s","fuzzySearch","checkDropdownPosition","containerRect","dropdownHeight","spaceBelow","spaceAbove","frame","addTag","trimmed","removeTag","tagToRemove","numItems","prev","preventDefault","suggestion","FILTER_OWNER_OPTIONS","Left","Middle","Right","AppListSearch","setSearch","noop","faSearch","AppListHeadings","userUiPrefs","pinFav","anchorRef","onTogglePinFav","setSortPriorityAndDirection","faSortAlphaDown","faSortAlphaUpAlt","faSortAlt","faArrowDown","faStarSolid","faStarRegular","AppListItem","allTags","onTagSelect","scrollContainerRef","tagPopoverOpen","setTagPopoverOpen","tagInputRef","canEditApp","disabledTagsTooltip","disabledTagsTooltipRef","disabledDeleteTooltip","disabledDeleteTooltipRef","onStarClick","blockEvent","setAppIsFavourite","onTagsChange","newTags","previousTags","setAppTags","updateIdeAppListQueries","listedApp","onTagButtonClick","Popover","PopoverTrigger","faTag","PopoverContent","deleteAppWithConfirm","searchState","ExternalState","AppResizePanel","ResizePanel","apps","includePySpace","setIncludePySpace","ownerFilter","useAppListData","useExternalState","sort","order","useAppsInfiniteQuery","mapped","moment","setSearchAndQuery","tagSet","bodyHeight","hiddenEmptyStateGate","useHiddenEmptyStateGate","isFetched","isFetching","hasRevealedPanelRef","isResolvedEmpty","gate","isFetchingNextPageWithVisibleResults","showSlowPaginationSpinner","useDelayWhenTrueFlag","isRefreshingVisibleResults","showSlowPlaceholderOverlay","faFileAlt","ButtonGroup","mainMenuItems","faBook","faComments","faBooks","faGraduationCap","additionalMenuItems","MenuItem","StartPageActionMenu","containerWidth","StartPageActionButton","openMenu","setOpenMenu","faQuestion","startPageContentContainer","setContainerWidth","StartPageContent","AppList","AgentPanel","Conversation","TableauCtaContent","sampleDashboardUrl","ANVIL_X_LOGO","AnvilCtaContent","img","BuildThis","appCta","getAppCta","cta","validCtas","closeTab","removeCta","isTableauCta","StepperContext","React","useStepperContext","Stepper","steps","buttonClasses","requestedStepIndex","onStepIndexChange","stepCount","stepIndex","setStepIndex","canNext","goToIndex","ind","maxIndex","useMemoiseObject","canPrev","StepperBody","StepperPrevButton","StepperForwardButton","StepIndicator","jumpTo","faCircle","StepCard","titleContent","mainContent","gif","tutorialSteps","IDETutorialPanel","missingClasses","useStoreState","missingFormClasses","anyMissingClasses","setBottomPanelHeightForTutorial","setRequestedStepIndex","lastCompletedStep","completedSteps","ideTutorialProgress","lastCompletedIndex","resetTutorial","useStyles","TILE_REM_SIZE","faRoad","setRoadmapStep","faArrowUpRightFromSquare","faLaptop","faServer","faCloudArrowUp","faBookOpen","roadmap","getUserRoadmap","contentContainerRef","width","setWidth","currentStep","stepNumber","hasNext","hasPrev","updateStep","newStep","changeStep","goBack","Roadmap","toggleCompleted","alreadyMarked","markRoadmapStep","StepContent","mapContainerRef","gridColCount","setGridColCount","gridRowCount","setGridRowCount","setGridCounts","gridComputedStyle","RoadmapTile","stepInd","completed","isCurrentStep","singleColumn","firstCol","lastCol","firstRow","lastRow","middle","inRange","RoadmapCard","statusIndicator","faCircleCheck","faCircleXmark","tileStyle","BLANK_SESSION","OutputScroller","scriptRuns","autoScroll","outputScroller","dropNextNewline","scriptRun","compressEvent","LogEvent","scriptName","runs","getScriptRuns","setAutoScroll","isRunning","launching","setLaunching","doRun","runScript","doKill","killScript","clearOutput","clearScriptOutput","autoScrollToolTip","autoScrollAnchorRef","runToolTip","runAnchorRef","stopToolTip","stopAnchorRef","clearToolTip","clearAnchorRef","faLevelDownAlt","BreakpointModule","moduleBreaks","breaks","moduleName","handleBreakpointClick","setBreakpoints","BreakpointsToolbar","onClearAllBreakpoints","clearBreakpoints","faTrashCan","Breakpoints","breakpoints","getDebugEnvBreakpoints","APP_PATH_RE","ConnectedConflictingItem","connector","connect","whichItem","getConflictsForConflictingItem","conflictItemSpec","setOpen","itemId","extraFileContent","canEditExtraFile","wholeFileConflict","getImageMimeType","codeType","linkTarget","breadcrumb","p","BottomPanelContentButton","resolveAllItemConflicts","deleteExtraFile","renderConfigConflicts","editConflicts","irregularPastTense","op","a_value","b_value","resolveConfigConflict","StructuralValueDiff","renderComponentConflicts","hasValueChange","resolveAllConflictsForFormComponent","a_change","b_change","opA","opB","showDirectValueDiff","DiffComponentEdit","conflictingItems","listItemsWithConflicts","ci","designerOutput","getDesignerOutput","liveOutputSearchStore","BottomPanelToolbarButton","clearDesignerOutput","faTrash","faMagnifyingGlass","LiveOutput","ResultHeading","TestRunStatusBadge","getTestRunStatusDisplay","TestStatusIcon","TEST_OUTCOMES","TestRunOutput","runLog","serverTestOutputText","sessionId","RunDetailsRow","resultClasses","TestError","TestRunSummary","getServerTestRunLog","outputLength","getAppRuntimeOptions","testRequirementsBase64","testRequirements","testRuntimeSpec","scrollerRef","followOutputRef","sawRunningRef","RuntimeBuildStatus","TestOutputSection","SelectedTestDetails","tt","ttRef","faArrowLeft","RunTestsButtons","latestRun","testsAreRunning","onShowRunSummary","hasTestResults","failedTestCount","latestExecution","getLatestServerTestExecution","cancelServerTestRuns","rerunLastServerTests","faRotateForward","rerunFailedServerTests","faRotateExclamation","clearDisplayedServerTestResults","faAlignSlash","TestRowButtons","encodedContent","DiscoveredTestRow","isSelected","DiscoveredTests","selectedTest","getFilteredServerTests","getServerTestListFilter","executionActive","useServerTestExecutionState","getServerTestRunRequest","getLatestVisibleServerTestExecution","startingExecution","ServerTestsBottomPanel","getAreServerTestsRunning","resultsPanelWidth","getBottomPanelServerTestListWidth","getLatestServerTestRun","latestVisibleRun","getLatestVisibleServerTestRun","getFailedServerTestIds","listFilter","resultMap","getServerTestResults","selectedTestId","keywordExpression","getServerTestPanelState","showRunSummary","trimmedKeywordExpression","onRunWithKeywordExpression","setServerTestListFilter","setServerTestKeywordExpression","setBottomPanelServerTestListWidth","Header","tab","allowClose","currentHeight","getBottomPanelHeight","onVisibilityChange","useBottomPanelContext","currentTab","getBottomPanelCurrentTab","bottomTabsMatch","elementRef","useIsInView","isInView","onAuxClick","closeBottomPanel","RunnerReplHeader","runnerOutput","getRunnerOutput","bgTaskOutputCount","getRunnerBgTaskOutputCount","runnerRepl","getRunnerRepl","seenRunnerOutputLines","setSeenRunnerOutputLines","totalOutputLines","outputNotification","faTerminal","destroyRepl","VersionHistoryHeader","editState","refs","getAppRefs","hasMultipleBranches","currentTag","refIcon","faCodeBranch","DesignerOutputHeader","seenDesignerOutputLines","setSeenDesignerOutputLines","designerNotification","faObjectGroup","closeDesignerOutput","ScriptRunHeader","isTerminated","scriptRunTab","deleteScriptRuns","OnboardingCtaHeader","tutorial","getWhereToStartTutorial","dismissOnboardingCtaTab","BottomPanelHeader","closeTutorialTab","enableRoadmap","faTasksAlt","faVideo","faGift","faHammer","faTools","faAnvilX","faBug","faShieldHalved","faSparkle","closeBottomPanelConversation","faFlask","getTabKey","BottomPanelContext","getBottomPanelIsOpen","debuggerHyperStacks","getDebuggerHyperStacks","repls","getRepls","whereToStartTutorial","showRoadmap","getShowRoadmap","bottomPanelTabs","getBottomPanelTabs","visibleTabs","setVisibleTabs","currentTabComponent","DesignerOutput","History","Conflicts","BackgroundTasks","TutorialPanel","RoadmapPanel","IntroVideoPanel","WhereToStartTutorialPanel","TalkToUsOffer","REPL","dbg","DebugInspector","ScriptOutputTab","roadmapAbFlag","useRoadmapAbFlag","userRegisteredForDays","getUserRegistrationAgeDays","useAbFlag","USER_AB_FLAGS","inTutorialMode","getInTutorialMode","useTalkToUsOffer","launchServerRepl","createRepl","bottomTabsWithVisibility","ddItems","needsBreak","bottomPanelContext","closeBottomTab","faWindowRestore","selectItem","hideMenu","faTerminalHeavy","openOrFocusPrevBottomTab","faChevronRightHeavy","ErrorBoundary","INTENT_STATUS","NewUserFeedbackFormTutorialPromoBanner","eligibleOffers","getEligibleOffers","closedPromoBanner","getUserHasClosedFeedbackPromoBanner","TRIAL_EXPIRED_NOTICE","SubscriptionBanner","subscription","getSubscription","trialExpiryDate","trialDaysRemaining","dateAndDaysAway","onClearExpiredTrialNotification","closeNotice","faRocket","startUpgrade","InterventionBanner","ImpersonatorBanner","LicenseWarning","getSplitRunnerWidth","getRunMode","getRunnerViewMaximised","getIsSidebarVisible","bottomPanelHeight","splitRunnerWidth","debugRunMode","runnerMaximised","isSidebarVisible","bottomPanelOpen","showSidebar","runnerResizePanel","setSplitRunnerWidth","RunnerIframe","bottomResizePanel","BottomPanel","setBottomPanelHeight","showAccountPage","showStartPage","hasLicenceWarning","appPanelsRef","keepWidthReasonable","splitWidthInt","parseInt","entirePanelWidth","AccountPage","Sidebar","TabPanel","StartPage","SurveyQuestion","reorderOptions","possibleResponses","otherOption","surveyResponses","recordResponses","reorderedResponses","reordered","otherInput","setOtherInput","showOther","setShowOther","val","updateSingleSelect","dets","updateMultiSelect","updatedAnswers","allResponses","SingleSelectDropDown","selectedResponses","MultiSelectDropDown","survey","setSurveyResponses","handleSurveySubmit","parsedResponses","submitSurvey","surveyData","welcomeSurveys","disableSubmit","q","MEREDYDD_PHOTO","variant","show","arm","countdown","card","openTalkToUsScheduling","agentsEnabled","useAgentsEnabled","WHERE_TO_START_OPTIONS","chooseOption","WHERE_TO_START_SURVEY_ID","WHERE_TO_START_QUESTION_ID","WHERE_TO_START_ANSWER_PREF","typeToTitle","Literal","StackFrameContext","ExpandableDebuggerValue","global","jsonPath","initialExpand","showHeader","frameContext","useContext","_setExpanded","expandable","getValue","doLoadMoreItems","getItems","headerContent","classNameToIcon","faQuotes","faBinary","faToggleOn","faToggleOff","faEmptySet","faListOl","faList","faFunction","faCubes","k","EMPTY_PATH","StackFrameScope","ReplSizeState","hyperstackId","hyperstack","getAppPackageName","debuggers","d","selectedStackFrameIds","setSelectedStackFrameIds","selectedDebuggerId","selectedStackFrameId","selectedDebugger","selectedStackFrame","expandDebugger","getDebuggerState","selectStackFrame","isRunner","repl","panelSize","setPanelSize","useIsRunning","debuggerContinue","restartApp","faRedoAlt","stopApp","faArrowDownToLine","faArrowRightToBracket","faArrowLeftFromBracket","currentBranch","currentCommitId","onSelectBranch","onSelectTag","onCreateBranch","onCreateTag","includePersonalBranch","inputClasses","useInputStyles","componentRef","textBoxRef","ddRef","listRef","dropdownVisible","setDropdownVisible","activeTab","setActiveTab","setSearchTerm","focusLocation","setFocusLocation","ringIndex","setRingIndex","userBranch","checkPosition","buttonRect","useIntersectionObserver","handleClickOutside","branches","branchList","filteredBranches","filteredTags","isViewingTag","isViewingCommit","onClickChevron","willOpen","handleSelectBranch","branch","handleSelectTag","handleCreateNew","currentItems","virtualizer","selectedIndex","virtualItem","isHovered","NoodleCommit","activeCommitRef","headCommitId","onSelectCommit","onDoubleClickCommit","labels","selectedCommit","readOnly","visWidth","longPressProps","useLongPress","commitRef","NoodlePane","givenCommits","malleableCommitIds","reserveFirstLane","initialSelectedCommit","onDoubleClickBranch","generateCommitContextMenuItems","onLoadMore","givenClasses","headCommit","getAppCommitId","malleableCommits","getAppMalleableCommits","commitHistory","getAppCommitHistory","environments","getCategorisedEnvironments","internalClasses","commits","visLayout","layoutVis","reserveFirstColumn","circleElements","noodleElements","REM_PX","parseFloat","LINE_HEIGHT_PX","LINE_HEIGHT","COL_WIDTH_PX","COL_WIDTH","BLOB_SIZE_PX","BLOB_SIZE","colx","colcol","colcolFade","columnAllocations","findColumnAllocations","noodle","cols","allocation","mergeCol","minDist","dist","drawNoodles","noodles","finishCol","fromCol","fromY","lineCol","fromX","lineX","toX","lineY","K","malleable","setSelectedCommit","_onSelectCommit","lastLoadCount","loadingMore","setLoadingMore","commitProps","oid","BranchLabel","remoteSync","env","onDoubleClick","inSync","isCurrentTag","environment","faRedo","branchLabelConnector","userEmail","isUser","username","userDomain","__","myDomain","faUser","remotes","remoteName","sync","faCloudCheck","faCloudExclamation","faLink","getCommitsReachableFromBranches","fromCommits","allCommits","except","findableCommitIds","pid","GitSyncButton","menuItems","gitSyncTask","getGitSyncTask","prevGitSyncTaskRef","showModal","setShowModal","allBranchesInSync","gitSyncButtonIcon","faArrowsSpin","faCodeCompare","onCheckWhichBranchesAreInSync","remote","prevGitSyncTask","onHandleSyncClick","pullAllRemotes","historyConnector","getDefaultPublishedEnvironment","getCommitListDiffWidth","getIsDiffVisible","getAppHasConflicts","getCanPublishApp","getGitRemotes","getGithubRemote","publishedEnv","publishedCommit","githubRemote","commitListDiffWidth","isDiffVisible","hasConflicts","canPublish","legacy","publishLegacy","publishAppVersion","unpublishLegacy","removePublishedAppVersion","version","confirmed","publishApp","unpublish","deleteEnvironment","recordActivity","commitInfo","doCommit","saveApp","loadAndScroll","loadCommitIntoHistory","checkoutVersion","loadVersion","diffPanel","setBottomPanelCommitListDiffWidth","CommitDetails","hasRemotes","remotesMenuItems","faGithub","_selectItem","_hideMenu","commitsReachableFromOtherBranches","commitsReachableFromThisBranchOnly","reachableFromOtherBranches","reachableFromThisBranchOnly","RefSelector","createNewBranch","createNewTag","mergeAppVersion","abandonMerge","completeMerge","connectToNewGithubRepo","toggleDiffVisible","faColumns","forceVisiting","updateAppCommitHistory","resetBranch","merges","allBranches","otherBranches","deleteBranch","editCommitMessage","permanent","deleteCommits","tagsOnCommit","deleteTag","WHERE_TO_START_TUTORIAL_CTAS","whereToStartTutorialLink","surface","utmSlug","imageURL","panelHeading","ownerOptions","userHasLoaded","getUserHasLoaded","setOwner","isPlaceholderData","hasNextPage","fetchNextPage","setQuery","loadMoreRef","sentinel","observer","IntersectionObserver","sampleChats","ChatPicker","selectedChat","onSelectChat","chatQuery","setChatQuery","chatPicker","chatSelector","chat","sampleIcon","tabIcon","tabTitle","MobileHeader","realTabs","activeRealTab","activeTitle","sampleTabs","activeSample","menuButton","onOpenNavigation","onOpenSample","onCloseSample","onSelectSample","onFocusRealTab","allSaved","getIsAllSaved","activeIcon","isActive","close","faComment","runApp","codeIcons","listCodeItems","NavigationDrawer","drawer","currentRealTab","showingRealTab","onOpenCode","codeStructure","getCodeStructure","setSection","searchVisible","setSearchVisible","codeNavItems","sampleNavItem","navItems","searchResults","SampleContent","MobileIDE","allRealTabs","getTabs","currentTabId","getCurrentTabId","tabPanelRef","useTabPanelRef","setSampleTabs","setActiveSample","setSelectedChat","orderedRealTabs","WrappedTabContent","AppPicker","modalId","buttons","Modal","modalReturn","applyButtonOverrides","ok","cancel","ButtonConfirm","ButtonCancel","confirmMessage","setEnabled","ModalHeightContext","Buttons","dispatchAndMaybeClose","processing","setProcessing","clickActionCreator","defaultButton","shrinkable","round","elevated","WrappedSpinner","modalProps","allowDismiss","leftButtons","closeIcon","beforeClose","onMouseDown","isPySpace","useIsPySpace","mobile","useIsMobileIde","setHidden","actualButtons","ensureModalCancelled","delayAction","modalRemove","prevFocusRef","useTimeout","cancelMethod","modalCancel","onModalKeyDown","dButton","btn","onModalMouseDown","useInsertionEffect","modalRef","innerRef","registerModalHeight","unregisterModalHeight","stopPropagation","ErrorSuspenseBoundary","faTimesBold","afterInput","initialValue","COMMON_TARGET_TYPES","isValidTab","isValidSI","isCommonNavTarget","getItemTitle","FIXED_TARGETS","SCHEDULED_TASK_TARGET","useIconStyles","useOpenQuickSwitcherInZenModeIfNoTabs","tabStack","getTabStack","useUpdateEffect","Item","onConfirm","onRemoveRecent","getNavTarget","isConversation","getFileIconClass","useFileIconClassGetter","iconClass","extraFileIcon","getExtraFileIcon","hasNavTarget","tabIconClass","onRemoveClick","faClose","NEXT","PREV","RecentFilesDivider","filteredItems","recentlyOpenEndsAt","useItemState","codeNames","getCodeNames","extraFiles","getAppExtraFiles","tableMappings","currentServices","scheduledTasks","getScheduledTasks","CommonNavTargets","navTargets","service","getServiceType","capitalize","addExtraFiles","recent","getRecentlyOpened","numTabs","validRecent","getExtraFileEntry","dependencyTargetFromLegacyNavTarget","validCodeItems","si","tabMatchesNavTarget","numFiltered","applyFilter","inputRefCallback","selectedItem","removeRecentlyOpened","scrollToIndex","useUpdateLayoutEffect","dividerItem","modalButtons","btnProps","OAuthTokenRow","revokeTokenMutation","useMutation","api","previousTokens","old","_err","_id","revokeDeviceToken","revoke","createdAt","parseISO","isLoading","useScrollToHash","keys","getSshKeys","sshKeys","setSshKeys","useStateWithReset","saveTimeout","setSaveTimeout","saveIndicator","setSaved","useSaveIndicator","h","updateSshKeys","HelpLink","ConnectionRow","disconnectAgent","disconnectAgentMutation","disconnectButton","faSignOut","conn","getGithubConnection","onHandleDisconnectClick","promptAndMaybeDisconnectGitHubAccount","SSHKeys","OAuthTokens","AIConnections","faLinkSlash","ensureGithubConnection","timeoutId","Authentication","passwordExpires","getPasswordExpires","ChangePassword","ConfigureMFA","ConfirmPassword","KeysAndTokens","currPassword","setCurrPassword","newPassword","setNewPassword","confirmPassword","setConfirmPassword","errorMsg","setErrorMsg","onChangePassword","res","updatePassword","InputLabel","ModalButton","passwordError","setPasswordError","password","setPassword","onConfirmPassword","updatePasswordExpires","isEnabled","qrCode","setQrCode","authCode","setAuthCode","authCodeError","setAuthCodeError","enable2fa","qr","update2fa","disable2fa","updateUser2faEnabled","cancel2fa","confirmAuthCode","confirm2fa","PrefPromptAndSelect","optIn","callbackFn","savePrefIndicator","setPrefSaved","updateSelection","mailing","subscriptions","updateSubscriptionToMailingList","pref","LookAndFeelDropDown","configOption","selectedLookAndFeel","setSelectedLookAndFeel","tooltipAnchorRef","updateUserPrefs","newOption","faQuestionCircle","ContentDropdownMenuItem","userMinimap","getUserPythonInlayHints","pythonAnalysis","userTheme","getUserTheme","userKeyBindings","getUserKeyBindings","userTabSize","userFormatOnSave","uiScale","getUserUiScale","getUserAutoImport","userCodeTemplates","getUserCodeTemplates","exportStore","onClickViewApps","Developer","Managers","SORT_OPTIONS","TaskRow","task_name","time_spec","suspended_at","formatted","useFormatTimeSpec","AppRow","formattedDate","suspendedCount","setApps","setSort","getAllScheduledTasks","sorted","o","newAccountPage","isSubscriptionLoading","getSubscriptionLoading","supportsScheduledTasks","useFeatureSupported","isEnterprise","accountItems","faFileInvoiceDollar","faUsers","faKey","faPalette","faMoneyCheck","faChartArea","faClock","_setSelectedItem","setSelectedItem","bucketQuotas","setBucketQuotas","quotasAndLimits","Subscription","billingItem","ManageDevelopers","Quotas","LookAndFeel","Billing","Communications","AccountScheduledTasks","accItem","billingTabStyles","getFeatureSupport","getInvoices","supportsInvoiceEmail","invoices","modalClasses","disabledButton","setDisabledButton","realCharges","charge","currency","CURRENCY_SYMBOLS","showMoreHistory","setShowAllHistory","firstElems","elems","onAuthorizeButtonClick","authorisePayment","onRetryButtonClick","retryPayment","paymentButton","historyElement","dateTime","visibleHistory","openUpdatePaymentFlow","errMsg","cardUpdate","updatePayment","updateInvoiceAddress","initVal","invoiceEmailAddress","updateInvoiceEmail","authorisingFirstPayment","setAuthorisingFirstPayment","authoriseFirstPayment","authoriseSetup","tabBody","nextInvoiceDate","daysRemaining","requiresPaymentAction","formatDiscountLabel","UpgradeBadge","DirectToManagerPortal","useUpdateAppOwnership","initialOwner","developers","useDeveloperQuery","appOwner","setAppOwner","updateOwnershipSaveIndicator","setOwnershipSaved","licenceKey","getCurrentOrganisationLicenceKey","chooseAppOwner","updateAppOwner","UpdateOwnerRow","email","num_shared","alternatingRowStyle","orgAppsModal","spec","OrgApps","loadOrgApps","capColors","sharedHeaderStyle","orgLicenceKey","refresh","incrementRefreshValue","useRefreshValue","twoMonthsAgo","oneWeekAgo","oneDayAgo","setStartTime","inIde","getIsIDE","onRefresh","getUsage","getOrgUsage","onStartChange","sharedUsageChart","limit","onLegendEntryClick","plotWidth","figure","usageData","deletedAppCounter","UsageGraph","downlinkUsageChart","downlinks","DBQuotaUseBarChart","traces","traceMetadata","LazyPlot","remToPixelMultiplier","LazyReactTabulator","DBQuotaUseTable","sortedData","cell","mappingNames","allowedToView","inIDE","getQuotasUseBreakdown","getOrgDBQuotaUsageData","bytes","aiCredits","emailQuota","customPackageLimits","AiCreditBar","ComputeUsage","DatabaseUsageBreakdown","quota","max","fraction","SortRow","ascending","localColumnSorting","moveSort","updateColumnSorting","removeColumnSorting","setColumnSorting","onAscendingChange","drop","useDrop","dragIndex","hoverBoundingRect","hoverMiddleY","hoverClientY","clientY","isDragging","drag","previewRef","useDrag","mergedRefs","opacity","faGripLines","SortModalContent","currentTable","columnSorting","namedSortArray","useSortArrayWithColSpec","sortArray","getSort","canSort","remainingCols","alreadySorted","onAddSort","setLocalColumnSorting","prevColumnSorting","dragItem","hoverItem","newColumnSorting","environmentStyles","migrationConfirmContent","useSelectVersion","initialCommitId","saveEnvironment","claimAchievement","checkForStagingEnvironments","allowRestrictedEnvironmentUpdates","selectedEnvironmentId","getSelectedEnvironmentId","supportsMultipleEnvironments","loadEnvironments","sortedEnvironments","isEnvironmentReadOnly","onCreateEnvironment","newEnv","getNewEnvironmentURL","createdEnv","createEnvironment","setSelectedEnvironmentId","onDeleteEnvironment","isBlank","hasServerKeys","onAddDebug","onRemoveDebug","hasUplinkKeys","waitFor","allEnvironmentSavesComplete","confirmLeaveUnsavedEnvironment","onSelectEnvironment","expandedKeys","freeOrgNoTrial","useOrgType","faCloudUpload","PublishCTA","Accordion","isExpanded","EnvironmentHeader","EnvironmentBody","RemoveSelfFromSubscription","sharedApps","appsAndNumberOfCollaborators","getPlanName","ChangeAppOwnershipRow","RemoveUserFromSubscription","permissionsOfAppsOfUser","str","setConfirmed","submitted","setSubmitted","expiryDate","feedback","setFeedback","terminatePlan","cancelSubscription","uncancelSubscription","updateCardModalStyles","isDarkMode","showCardElement","setShowCardElement","buttonText","setButtonText","errorMessage","setErrorMessage","elements","useElements","handleButton","confirmUpdateCard","CardElement","stripeElementOptions","allCountries","rawCountries","countries","country","countryItems","countryValues","paymentFormStyles","isEUMember","countryCode","PersonalOrBusinessDetails","accountType","paymentRegion","useVRN","setUseVRN","vrn","setVRN","crn","setCRN","companyName","setCompanyName","taxId","PaymentForm","userName","countryFromIP","pricing","getPaymentAmount","serverUpgrade","supportUpgrade","displaySupportUpgrade","setFormComplete","setFormEntries","newOrganisation","trialUpgrade","currentActiveDevs","forceShowAdditionalTableauViewers","formErrors","planSelectMarker","setInitialEntries","subscriptionFreq","switchToBusinessPlan","seats","setSeats","setAccountType","billingFrequency","setBillingFrequency","capability","activeOffers","getActiveOffers","collectAllInfo","setName","address","setAddress","selectedCountry","setSelectedCountry","countryPhoneCode","setCountryPhoneCode","phoneNumber","setPhoneNumber","additionalTableauViewers","setAdditionalTableauViewers","showAdditionalTableauViewers","setShowAdditionalTableauViewers","minSeats","cardComplete","setCardComplete","hasServerUpgrade","hasAwsOnlyUpgrade","planWithSidebarExtras","tierOffers","currencyMismatchedAmountOffer","merged","mergeTierOffers","countryMatchesIP","needsVAT","price","validString","consolidatedCollectedInfo","force","baseRequirements","locationInfoEntered","business","consumer","enable","updateCardLinkClicked","dropdownChanged","planSideBar","paymentTotalDisplay","standardMonthlyDisplay","percentDiscountedAmount","amountDiscountedAmount","remainingCredit","basePrice","afterPercent","getDiscountedPrice","afterAmount","discountAppliedTT","discountAppliedTTAnchorRef","exclVatUnitPrice","unit","productId","vatRate","vatIsInclusive","planBasePriceDisplay","ComboBox","IncrementingNumericTextInput","faRepeat","faTags","PERSONAL_PLANS","LEGACY_PLANS","initialPlanId","initialFreq","managerAction","getManagerUser","fixedPlan","requeryDevelopers","locationOrPlanCurrency","subscribeText","paymentProcessing","setPaymentProcessing","formComplete","formEntries","getPricing","seatPlans","selectedPlan","setSelectedPlan","browsingPlans","setBrowsingPlans","setPlanSelectMarker","initialEntries","formChanged","selectPlan","plans","nDevs","serverExtraResourcesUpgradeCost","serverExtraResourcesAWSCost","supportCost","paymentCurrency","userLocation","tierPricing","tableauPricePerUser","symbol","planPrice","planBasePrice","planPriceIncludesVAT","seatsPriceExecVAT","tableauPrice","vat","supportCostExcVAT","priceIncVAT","plansWithOffer","backButton","discountTT","discountTTAnchorRef","priceData","vatSubtext","displayPrice","planCard","eligibleOfferForTier","newWindow","offer","LegacyBanner","hobbyTooManySeats","hobbyBusinessUse","upgradeObj","makeUpgradeObj","obj","upgradeFromTrial","upgradeFromFree","changePlan","businessPlan","lowerTier","UpgradeSuccessful","planInfo","pi","getAccountModals","Upgrade","UpdatePaymentCard","UpgradePrompt","TerminateSubscription","UnTerminateSubscription","ideModalTypes","setApiKey","list","searchInput","setSelected","filtered","rowHeight","onChoose","onSearchChange","accept","multiple","buttonProps","selectedFiles","setSelectedFiles","handleClick","onInputChange","assetTypes","isFileEvent","closing","dragActive","setDragActive","reading","setReading","droppedAssetFiles","onFilesSelected","selectedAssetFiles","ContentButton","FileUploadButton","MappingHeader","appIds","appList","faUserFriends","MappingTables","sharedTables","mappingIdentifier","selectedTable","setSelectedTable","tableRow","uniqueTableId","AddExistingTable","addExistingTableConnector","getSharedTableCounts","accessibleTableMappings","addNewTable","addNewTableLabel","selectedMapping","setSelectedMapping","searching","setSearching","addNewTableInstead","addExistingTable","linkedTable","linkExistingTableToMapping","defaultDBs","setDefaultDBs","setTableMappings","idsInMap","restrictedTableIds","mappingsWithSharedOrNotIndicator","defaults","nonDefaults","sortedMappingsWithKey","selectDB","setSearchResults","applySearchToMappings","mappingsWithMatchNames","tablesWithMatchNames","searchMappingAndAppNames","runSearch","useOverride","debouncedSearch","useDebounceFn","delayedShowSearching","doSearch","uniqueKey","AddableMappings","AddExistingTableMapping","addExistingTableMappingConnector","createNewDatabase","addNewMappingInstead","itm","addExistingMapping","linkedMapping","matchedMappings","matchedTables","mappingName","alreadyAdded","headline","selectVersionButton","tagButtons","selectBranchButton","branchButtons","branchesOnCommit","selectionButtons","BetaWelcomeModal","faFlagCheckered","ChooseFormButton","useMaybeRemoveAssetPrefix","ImageWithRetry","runtimeVersion","getAppRuntimeVersion","dependencyCode","getDependencyCode","customLayouts","getAllCustomLayouts","layoutForFormClassName","currentLayout","currentLayoutType","initialTemplates","chooseFormButtons","templates","btns","btnPropsFromLayout","LAYOUT","defaultStandardFormCode","componentYamlTypesReferToSameForm","makeLegacyCustomComponentSpec","cl","btnPropsFromTemplate","logicalDepId","qualifyFormTemplateFromDependency","qualifyDep","customComponentSpec","LEGACY_CUSTOM_COMPONENT_SPEC","existingLogicalDepId","appLocalFormName","qualifyComponents","slotName","BLANK_PANEL","blankFormTemplate","CUSTOM_HTML","htmlComponent","tutorials","timeEst","faArrowTrendUp","faTrophy","Parameters","doUpdate","parameters","addOrUpdateParameter","param","updatedParam","cleanPythonName","newParams","newParam","deleteParameter","ParameterRow","onDelete","useResetState","setDescription","onBlur","EventBody","isDefault","PropSection","DescriptionInput","AdvancedExpander","ID_KEY","Symbol","IS_NEW","PropEventHeader","subtitle","updateName","onSwap","updateDragState","nameEditBox","nameBuffer","setNameBuffer","editingName","setEditingName","useNameBuffer","finishEditingName","toggleEditingName","renameTooltip","renameTooltipRef","deleteTooltip","deleteTooltipRef","dropRef","fromIndex","isOver","canDrop","dragRef","DESIGNER_HINTS","DesignSection","startCase","PropertyDesigner","important","setGroup","priorityAsString","setPriorityAsString","updateGroup","updatePriority","asNumber","designerHints","Sections","designer_hint","sectionProps","NULL_VALUE","PLACE_HOLDER","EMPTY_OPTIONS","EnumDropDown","onSave","default_value","include_none_option","none_option_label","onDropDownChange","newValue","EnumOptions","enumOptions","setEnumOptions","onSave_","updated","prevIdex","delaySave","doSave","useActionOnTimeout","NoneOption","showNoneOption","noneLabel","setNoneLabel","onDeleteNoneOption","onAddNoneOption","onBlurNoneLabel","IconProperty","defaultValue","setDefaultValue","iconsets","IconComboBox","DEFAULT_ICON_SETS","PropertyEditor","saveValue","newVal","onChangeDefaultUriValue","useChangeUriPropertyWithModal","formName","useCustomComponentContext","ColourInput","AvailableFormsDropdown","MarginProperty","PaddingProperty","SpacingProperty","PropertyEditorSections","setAccept","PropertyWriteback","allow_binding_writeback","binding_writeback_events","WriteBackEvents","WritebackPills","eventName","CUSTOM_EVENT","eventNames","addWritebackEvent","customEvent","union","bindingEvents","difference","PropertyBody","onTypeChange","getDefaultFromType","propTypes","prop","ExpandableDesignerPropSection","designerSectionExpanded","setIsOpen","helplink","advancedExpanderAtom","openState","setOpenState","ComponentAccordion","onToggle","renderBody","useSwapPropEvent","updateCustomComponent","fromIdx","toIdx","dragState","usePartialReducer","layoutThumbnailSpec","TextProp","fieldName","layoutMetadata","useLayoutMetaContext","useUpdateLayoutMetadata","oldValue","ThumbnailUploader","thumbnail","onChangeImage","LayoutMetaContext","LayoutMetadataConfig","expandAdvanced","setExpandAdvanced","LayoutMetadataCustomComponentConfig","defaultLight","defaultDark","darkIcons","iconSpec","ImageUploader","toolbox_item","toolboxIcon","newToolboxIcon","IconUploader","useUpdateToolboxItem","newItem","Title","Group","groups","ToolboxSettings","custom_component","showInToolbox","getNewProperties","Events","expandFeature","useExpandedItems","setExpandedKeys","addOrUpdateEvent","updatedEvent","isNewEvent","newProperties","newEvents","ev","newEvent","addExpandKey","deleteEvent","useDeletePropEvent","HelpText","helpText","newHelpText","setNewHelpText","updateHelpText","DELETE_IF_FALSE","NEW_PROPERTY","Properties","addOrUpdateProperty","updatedProperty","isNew","newProp","propName","deleteProperty","PROP_TYPES_TO_DISPLAY","CustomComponentContext","CustomComponentBody","canUseClassic","customComponents","getCustomComponentForms","useUpdateCustomComponent","custom_component_container","slots","layout_metadata","help_text","toggleCustomComponent","toggleContainer","showCustomContainerToggle","PROP_TYPES","PROP_TYPES_V3","rerender","useRerender","onToggleLayout","toggleIsLayout","hasSlots","itemItem","propReturnName","nullVal","setState","prevState","setPrevState","itemRef","propEventItems","propKey","getNewItem","SUPPORTED_PROP_TYPE","StringConfigProp","TextInput","NumberConfigProp","BooleanConfigProp","setChecked","_onChange","StringListConfigProp","placeholderText","StaleComponent","removeStaleConfig","EnumConfigProp","onClear","ddValue","optionValue","DependencyProp","schemaProp","yamlValues","onChangeBooleanProperty","updateDependencyConfig","onChangeTextProp","removeDependencyConfig","onChangeNumberProp","propEditor","DependencyConfigBody","yaml","propItems","refDep","appConfig","getAppConfig","depCode","activeDepAppId","dependencyAndIdentifier","config_schema","configItems","specs","staleComponents","sOpen","setSOpen","faSliders","saveIfDependencyConfigHasChanged","ConfigureRunner","setStartupUrl","startupUrl","appName","setInput","schemaName","onSelect","onCreate","createLabel","additionalOptions","_value","includePersonal","uiPrefs","appPackageName","setBranch","registryHost","setRegistryHost","registryUser","setRegistryUser","registryPassword","setRegistryPassword","repoPath","setRepoPath","exportTask","setExportTask","doExport","taskId","exportAppToDocker","watchIDETask","faDocker","faSync","BranchSelector","anvilHostName","port","currentCommit","real","appUrls","setCommitId","defaultProdUrl","defaultUatUrl","prodUrl","setProdUrl","uatUrl","setUatUrl","deploymentTime","setDeploymentTime","queued","setQueued","deploy","postJson","DateTimePicker","Intl","asset","getLayoutsFromYaml","customLayout","updateEnableHtmlLayout","updateHtmlLayoutMetadata","layoutContextValue","EMPTY_OBJECT","INIT_VIDEO_STATE","videoStateReducer","videoRef","videoState","dispatchVideoEvent","onComplete","cancelTimeout","onDataLoaded","onPlayVideo","canRestart","faCodeMerge","faExternalLinkAlt","getAllAvailableServices","useChooseService","inApp","features","getFeatures","serviceType","featureSupported","ServiceCard","chooseService","onDeleteService","useDeleteService","getServiceIcon","availableServices","appServices","feature","appService","onDeleteScheduledService","parseCommitMessage","safeMessage","rawSummary","bodyLines","commitMessage","updateCommitMessage","buildCommitMessage","summaryText","descriptionText","isMalleable","handleSubmit","targetBranch","diffData","setDiffData","defaultCommitMessage","n_commits","fromTime","toTime","authors","authorEmails","authorEmailDesc","setCommitMessage","textboxRef","CommitDetail","Loading","showNewDesignerPref","getShowNewDesigner","showNewDesigner","onToggleNewDesigner","setUserAlwaysShowNewDesigner","faCandleHolder","setOfDepAppIds","alreadyBroken","dep","activeDepCode","dependencyName","getDependencyDisplayName","resolutionHints","getDependencyHints","thirdParty","setThirdParty","depAppId","setDepAppId","onSelectApp","setDepInfo","setDepError","depInfo","depError","suggestedDepInfo","setSuggestedDepInfo","suggestedAppId","suggestedInfo","faArrowRightArrowLeft","SecondaryNavAlert","ThirdParty","MyApps","Action","describeOnDelete","getIndexTitle","requiredChanges","TableauDebugModal","tableauDebugConnector","debugEnvironment","trexUrl","copyLink","useCopyWithTooltip","copyUrl","showCloudInstructions","setShowCloudInstructions","isValidTableauDashboardUrl","faDownload","faSpinnerThird","envUrl","TableauPublishModal","tableauPublishConnector","selectVersion","testInTableau","getSelectedUplinkId","selectedUplinkId","configUi","environmentsSorted","selectUplink","setSelectedUplinkId","gotoEnvironment","envId","defaultUplinkDisplay","createAndEnableFirstEnv","createDefaultEnvironment","enableEnvironmentUplink","enableInEnv","envBranch","EnvironmentUplinkConfig","EnvironmentHeaderTemplate","loadYaml","jsYaml","AppInfo","appYaml","setSource","setFileName","setAppYaml","pastedYaml","setPastedYaml","onFileChange","parsedApp","onImport","createAppFromYaml","typesWithTarget","typeDescriptionEntries","setType","setTarget","setOnDelete","needsTarget","finalColSpec","cleanLinkedColumnForOldTables","nameInputRef","initRowIds","rowSelection","setRowSelection","hasSelectedRows","selectedRowIds","liveObjectArray","rowTitle","getTableFromId","RowLinkSingle","newSelection","TableView","useDeploymentPoolDropdowns","deploymentPools","getDeploymentPools","hasDeploymentPools","selectedPoolId","setSelectedPoolId","ddPoolOptions","CloneDatabase","copyMedia","setCopyMedia","cloneDatabaseToPool","RestoreDatabase","setTargetTime","targetTimeError","restoreDatabaseToPool","CreateNewDatabaseInPool","proposedName","newMapping","EditColumn","isSplit","needsOnDelete","newColSpec","colTypeToReadableNameLookup","indexDraftStatetoTableIndex","TableIndexesContext","useTableIndexesContext","TableIndexesProvider","tableIndexes","useTableIndexes","all_indexes","flashIndex","setFlashIndex","draftState","setDraftState","tableIndexIdentifier","newIndexType","setNewIndexType","indexingColumns","setIndexingColumns","bTreeTypes","indexableColTypesItems","availableTypes","columnId","selectedTypes","onChangeNewIndexType","indexableCols","onChangeSingleCol","onChangeMultiCols","clearForm","onClickAddIndex","newIndex","draftIndex","onClickRemoveIndex","tableIndex","toRemove","toAdd","colNameFromId","NewIndexForm","ColumnNamePill","identifierFn","TableIndexRow","indexKey","shouldFlash","rowRef","div","flash","faArrowRotateLeft","faTrashCanUndo","ExistingIndexes","TableIndexesModalBody","onCancelClick","toAddNum","toRemoveNum","faArrowsMinimize","DNSRequiredNotification","sanitizeDomain","useEnvUrlCommon","newUrl","urlBuffer","setUrlBuffer","newUrlBuffer","markEnvironmentUnsaved","forceAlias","updatedEnv","isSavedEnvironment","onCancel","EnvUrlPublic","saveClickable","setSaveClickable","urlInputRef","handleSavePublicDomainButton","onGenerateNewUrl","PublishLink","ESCAPE_REGEX","DNS_REGEX","VALID_SUBDOMAIN_REGEX","EnvUrlCustom","preLink","postLink","publicRegex","useCustomDomainValidation","escapedPostLink","underscoreError","setUnderscoreError","tryToSaveCustomDomain","updateGlobalLoadingIndicator","getCustomDomainStatus","handleSaveCustomDomainButton","shouldBePublic","subdomain","PrivateRepoError","allowPrivate","setUrl","setUsername","getRepo","html_url","GithubAuth","githubAuthConnector","githubRepo","managePermissions","targetId","accountName","login","installGithubApp","faExternalLink","faRotate","loadGithubConnection","_setUrl","authOptions","selectedAuth","setSelectedAuth","creds","publicRepo","enableClone","appRefs","remoteCreds","githubRemoteCreds","remoteRef","resetToRemote","mergeIntoRemote","mergeBranchIntoRemote","startNewBranch","forcePush","forcePushRemote","configureRemotes","OutOfSyncIndicatorAndActions","connected","promptForReset","promptForForcePush","promptForMerge","remotesMap","reloadRemotes","expandedRemotes","setExpandedRemotes","isUserGithubRemoteCreds","createGithubRemote","addHttpRemote","addRemote","deleteRemote","githubReconnect","gitHubUser","updateGithubCredentialsForRemote","hasUnreachableRepoBranches","repoName","refName","installationsAllowingCreation","inst","hasLicenceAlready","appHasLicenceFile","supportsPrivateRepos","setSelection","goPrivate","goPublic","licenceDescriptions","assetPrefix","getImageFromSrc","Image","getImageFromAsset","codeAsset","getDataUriForAsset","canvasToFile","canvas","File","reduceImageSize","scale","ctx","w","newW","newH","useCheckImageShouldBeOptimized","msgEnd","maxSize","onModalReturn","useOnModalReturn","checkImageShouldBeOptimized","optimizeAsset","useOptimizeAsset","assetName","dot","rawName","rawType","optimizedFile","pkgPrefix","uploadAsset","logo","imgAsset","onCheckValidity","useCheckValidity","uriSpec","UriUploader","exampleApps","useExampleApps","createApp","currentTableMapping","tableItems","doApiKeyLogin","setView","setToken","submitLogin","cleanedKey","UrlElicitation","elicitation","sessionIsRunning","didRequestChatgptLogin","doLogin","openLoginWithElicitation","onApiLoginClick","modalContent","UsageRow","EXTRA_USAGE_LABELS","AGENT_NAMES","managedCodex","contextUsage","contextUsedPercent","contextLeft","providerUsage","left","reset","LazyJsonEditorModal","getIdeModals","commonModalTypes","AccountModal","UplinkModal","NewServiceModal","AppHistoryModal","EnvironmentsModal","HawthornDeployModal","ChooseFormTypeModal","AddAssetModal","SizedImageModal","DirectSQLAccessModal","DeleteSecretModal","SecretConfiguredModal","ChooseAppTheme","CreateTag","SaveConflict","DeleteApp","UpgradePromptOnOpenApp","ConfigureOrUpgradePromptOnRuntimeFeatureRequired","CustomComponent","Git","GitRemotes","AddHTTPRemote","GitDesync","GithubAccountChooser","GitCloneApp","GithubChooseVisibilityAndLicence","PreMergeModal","PreCommitModal","SchemaMismatchModal","ScheduledTaskModal","MergeCompletionConflict","PipAudit","ViewSecretModal","GoogleServiceModal","AppCta","TableauCTA","TableIndexes","DockerExportModal","DeleteAllRows","SortModal","AddColumn","AddLinkedRow","TextEditor","RemapDependency","ConfigureDependency","PreviewV3Designer","ClaimedAchievement","IdeTutorialIntro","UploadAppYaml","TemplatesModal","WelcomeModal","QuickSwitcher","CodeLocationsModal","HtmlLayoutModal","UpdateFormItemType","IntroVideoModal","ApiKeyLoginModal","AgentCodexLogin","AgentClaudeLogin","AgentZaiLogin","AgentCustomModelProvider","AgentUsage","ConfirmRemoveTesting","managerModals","getManagerModals","genButtonVariant","outlined","dropdownTrigger","bg","hoverBg","activeBg","disabledBg","disabledColor","variants","small","large","tiny","margin","iconRight","iconSpin","menuLabel","titlePosition","titleDelay","preventDefaultClick","linkClassName","linkStyle","isIconButton","restProps","iconOnly","buttonRef","faEllipsisV","groupTheme","ButtonGroupItem","selectedVariant","longPressHandlers","allowReselect","selectedValues","Breadcrumbs","isSlotParent","normalizeParent","extractParentFromLocation","renderParentDisplay","formatDiffItemId","structureChangeLabels","structureChangeValueLabels","renderDataBindingState","wasAdded","writeback","CodeWithMarkers","addedBackground","removedBackground","renderSummary","parentDisplay","toParentLocation","fromParentLocation","parentsEqual","renderDetails","DiffItem","diffItem","structureChanges","navigateOrPopUp","describeItem","showDetails","allCodeNames","trimmedMessage","commitIdA","commitIdB","forMerge","copyTextToClipboard","textArea","copiedTimeout","copied","setCopied","useCopiedHighlight","doCopy","faClone","MenuBody","renderedItems","onClickItem","localRef","render","onSelectItem","align","onShow","onHide","hideOnNoItems","anchorToTrigger","menuClassName","renderMenu","setRenderMenu","setVisible","overridePos","setOverridePos","menuRef","clickRef","pointReference","floatingStyles","useFloating","autoUpdate","floatingOffset","flip","shift","floatingRef","getMouseEventOrTouch","referenceTarget","targetRect","onWindowFocus","itemOrFn","dropdownMenuRoot","ManagerInstanceGlobalsContext","every","ReactDOM","initialState","prevProps","lastDeps","newDeps","fallback","Suspense","innerClassName","refOuter","refInner","initialHeight","doneOpeningTimeout","wasOpen","outer","wasAuto","nativeInvalid","containerClassName","iconClassName","faSolidChevronDown","faCheckSquare","faSquare","faCircleDot","useTextStyles","titleClasses","subtitleClasses","inline","onClick_","openInNewTab","pathRegex","fileIcons","fasUserFriends","falUserFriends","farUserFriends","fasDatabase","falDatabase","farDatabase","fasCube","falCube","farCube","fasCode","falCode","farCode","fasFileAlt","falFileAlt","farFileAlt","fasFileCode","falFileCode","farFileCode","fasFolder","falFolder","farFolder","fasHashtag","falHashtag","farHashtag","fasImage","falImage","farImage","fasCog","falCog","farCog","fasLock","falLock","farLock","fasClock","falClock","farClock","fasPaintBrush","falPaintBrush","farPaintBrush","fasStream","falStream","farStream","fasMailBulk","falMailBulk","farMailBulk","fasServer","falServer","farServer","fasPlay","falPlay","farPlay","filePathMatch","faJs","getTestFileIcon","useFileIcon","faPython","faTv","faMicrosoft","faStripe","faFacebook","faGoogle","faFolders","faJenkins","_onClick","onClickOverrideNav","disableMetaClick","waitForSave","useHref","lastClickTime","SidebarLink","hideOverlayOnClick","clickTimeoutRef","hideIfOverlay","onDoubleClick_","EmbeddedBlockGrowthContext","STATUS_LABELS","STATUS_PILL_CLASSES","finalStatusToDisplay","finalStatus","RunnerBgTaskWidget","getRunnerBgTask","stopTooltip","rootRef","prevHeightRef","prevOutputLenRef","onBlockGrowth","outputLen","displayStatus","useDisplayStatus","polledTasks","useBackgroundTasks","polled","INACTIVE_TASK_TYPES","isStoppable","stopRunnerBgTask","faChevronRightSolid","FILEMATCHER","JUMPMATCHER","SLASH","TraceBackLink","tracebackNavigate","lineno","colno","getTracebackCodeItem","getTraceItems","itemName","jumpToMatch","TraceBack","traceItems","restoreRunnerView","BindingTraceBack","bindingErrors","stopAppAndNavigate","component_name","getInPlaceEditTarget","PythonError","errType","isCreatingConversation","getIsCreatingConversation","getAIhelpForError","tracebackText","RuntimeError","ReplCommand","StdOut","LiveOutputSearchStore","ExternalStore","currentHighlight","useLiveOutputSearchStore","createExternalStoreHooks","SearchHighlights","useProcessHighlights","messageBodyRef","findHighlights","term","messageBody","messageRect","scrollTop","searchText","allHighlights","viewportBottom","nearestHighlightIndex","highlightTop","SearchControls","isSearchOpen","processMessageBody","useSearchHistory","outputSearchHistoryStore","showHistoryHint","resetNavigation","updateSearchTerm","onSearchTerm","onSearchKeyDown","useSearchHistoryKeyDown","onEscape","prevHeightFromBottom","outputBody","heightFromBottom","scrollingUp","MessageElements","renderMessage","log","onEmbeddedBlockGrowth","blockEl","blockEndAfter","blockEndBefore","onCopyAll","useCopyAllKeyBinding","DelayedLoadingSpinner","showSpinner","setShowSpinner","indicator","localClasses","useModalStyles","skChase","skChaseDot","skChaseDotBefore","LoadingSpinnerInternal","sizeRem","loadingIndicator","getLoadingIndicator","NodeRenamer","onRename","initialSelectionStart","initialSelectionEnd","NavNodeRenamer","InitSaveIndicatorState","saveIndicatorReducer","saveError","showSaving","setSaveError","showSavingTimeout","SidebarButton","narrow","disableEsc","onKeyDown_","EncryptedTextInput","encryptedTextInputConnector","hideText","secretRestrict","settingValue","setSettingValue","_onSave","encrypted","ref_","autoExpand","labelClassName","keydown","inputEl","alias","FileUploader","formatStructuralValue","json","isMultilineStructuralValue","markerForType","classForType","fromIsMultiline","toIsMultiline","getStructuralLineDiff","fromLines","toLines","addPart","remainingProps","saveKey","inputType","textBoxClassName","changed","setChanged","blockNavigation","unblockNavigation","labelProps","wrapInput","textAreaRef","textInputRef","changeValueFn","lowerBound","upperBound","parsed","isNaN","faMinus","lastOpened","Tooltip","sticky","useMouseX","getCurrentDelay","timeout","tooltipRoot","delayTooltip","mouseEnter","currentTooltip","getPos","abs","tooltipBounds","tooltipWrapperRef","mouseLeave","scrollHandler","currentAnchor","currentEl","removeRef","stickyHover","EMPTY_STYLE","_delay","_prev","setActive","copyTooltipRef","toggleTooltip","featurePlan","RunAppButton","runMode","isMaximized","tooltipAnchor","NumErrorWarningBtn","numErrors","numErrorsWarningMsg","errorsAnchor","errorsRef","onToggleZenMode","toggleZenMod","timeTypes","timeDef","initializeTimeBuffers","init","INIT_DATE","createMonth","viewing","eachWeekOfInterval","startOfMonth","endOfMonth","week","eachDayOfInterval","startOfWeek","endOfWeek","formatDateWithOffset","formatDate","DEFAULT_FORMAT","DatePickerStore","dateFromDateAndTime","datePart","timePart","newViewing","addMonths","subMonths","buffer","bound","setter","newBuffer","asInt","newNum","initialize","timeBuffers","month","DatePickerContext","useStoreContext","store","useDatePickerSelector","selector","useStoreSelector","useDatePicker","DAYS","StandardButton","WeekHeadings","day","MonthGrid","currentMonth","updateDate","useDatePickerActions","min","isAfter","yearA","yearB","monthA","monthB","isBefore","YEARS","CURRENT_YEAR","YearGrid","setSelectingYear","selectedDate","setViewing","selectedYear","selectedEl","year","Calendar","viewNextMonth","viewPreviousMonth","selectingYear","DateInput","showIcon","faCalendar","GenericPicker","defaultOpen","collisionBoundary","useInitializeDatePickerStore","onOffsetChange","storeValue","storeOffset","storeFormat","triggerRef","triggerVisible","setTriggerVisible","onEscapeKeyDown","onOpenChange","DatePicker","TimeInput","updateTimeBuffer","incTimeBuffer","decTimeBuffer","TimePicker","sep","Fragment","DateTimeCalendar","showSec","showMil","offsets","OffsetPicker","updateOffset","localOffsets","DateTimePickerWithOffset","dropDownClassName","explicitClose","orderMatters","onItemSelect","currentSelected","selectedElementsRef","badgeRef","titleRef","showBadge","setShowBadge","onResize","titleContainer","selectedElementContainer","badgeContainer","badgeElement","selectedElements","notShown","totalWidth","useResizeObserverTimeout","SelectDropDown","ItemTile","single","emptyItemsMessage","getIndexFromValue","getContainer","horizontal","handleAtStart","handleVisible","handleSize","hitZoneSize","onFinishDrag","rootClasses","closed","containerLevel","minSize","snapToMinAtSize","dragStartMousePos","dragStartComponentValue","dragStartBound","showShield","setShield","startDrag","isMultiTouch","stopDrag","pageX","pageY","dx","panelWidth","newWidth","dy","panelHeight","newHeight","finalStyle","handleStyle","handleHitZoneStyle","useFileExpanded","treeType","hasChildren","allowEmptyExpansion","codeNavState","getCodeNavState","savedExpanded","setFileExpanded","usePrefersStandalone","isIdentifier","checkIsNested","canBeNested","typeA","typeB","nextPart","contextMenuItems","onDragCallback","inPlaceEdit","fileNavTarget","appStartupItem","getAppStartupItem","renaming","setRenaming","onCancelRename","useRenamingFile","useStore","fileRenamingId","setGlobalFileRenamingId","fileRenamingIdAtom","prefersStandalone","useContextMenu","fileInput","onReplaceAsset","faPencil","duplicateForm","updateCodeNavState","setIsPackage","setAppStartupItem","faBolt","useFileIconAndClass","sortedChildren","canHaveChildren","EMPTY_ARRAY","nodeSelected","editingNestedForm","useExpandWhenNodeSelected","globalSelectedFile","globalEditingContext","useSelectedFileContext","expandToNestedFile","selectedFile","editingFile","dragOverlayClass","useFileDrop","navLinkRef","FileTreeBranch","reserveExpanderSpace","CodeSection","sectionTitle","defaultMenuOption","defaultMenuFunction","showHeaderButton","headerButton","allowRootDrop","rootDropTarget","showAssetsInCodeNav","getShowAssetsInCodeNav","sortedFiles","asFile","isOverBody","canDropBody","dropRefBody","isOverHeader","canDropHeader","dropRefHeader","draggingClass","highlightState","setHighlightState","handleDragFile","_assetState","setCodeNavSectionExpanded","renderedFiles","Section","SelectedFileContext","walkFiles","pred","SelectedFileProvider","selectedFileValue","editingPath","topLevelFormClassName","clientCode","serverCode","scripts","findMatchingCodePath","findFormContext","DependenciesSection","getShowDependenciesInCodeNav","currentTargetType","renameOnAdd","useRenameOnAddCodeItem","setRenamingId","clientContextMenuItems","addFormWithModal","addNew","collapseAllFiles","faSquareMinus","serverContextMenuItems","faFilePlus","scriptContextMenuItems","assetContextMenuItems","addAssetWithModal","faFolderPlus","useShowHeaderButton","secondaryNavWidth","getSecondaryNavWidth","setShowHeaderButton","minWidth","contents","mime","emailjsMimeParser","regex","decoder","TextDecoder","encoder","TextEncoder","substituted","base64url","Blob","contentB64","addCodeItem","generateItemId","useExtraFileDrop","onMove","expandTimeout","canDropExtraFile","destination","sourceParent","ExtraFileTreeRow","getIcon","iconCircleClassName","getMenuItems","canRenameItem","canDragItem","isDirectory","canRename","onStartRename","faFolder","selectedPath","selectedFullName","canDrag","rowMenuItems","extensionStart","serverTestRootDropItem","SERVER_TEST_ROOT","testingIconClass","serverTestRoot","hasServerTestRoot","SERVER_TEST_REQUIREMENTS_PATH","expandConfig","setExpandConfig","serverTests","hasTestDirectories","hasRequirements","hasEmptyRootInitializer","SERVER_TEST_INITIALIZER_PATH","onMoveTestEntry","moveExtraFileEntry","rootHeaderDrop","rootHeaderDropRef","rootBodyDrop","rootBodyDropRef","highlightRootDrop","onRunTestsAtPath","extraFilePath","testTarget","onDiscoverAllTests","onClearResults","onAddEntry","getSuggestedEntryName","createExtraFile","createExtraDirectory","onCreateRequirements","createServerTestRequirements","ensureServerTestRoot","getTestRowMenuItems","isRoot","isPlainDirectory","isTestFile","added","faFolderGear","convertExtraDirectoryToPackage","deleteFromTestingSuite","renameExtraFile","StatusDot","SidebarConversation","closeSidebarConversation","CheckedIcon","faCheckCircle","AgentSidebar","getNavMode","newConversation","hasConversations","selectedConversationPid","renamingConversation","beginRename","cancelRename","commitRename","openConversationFromList","useConversationListInteractions","setRenamingConversation","pendingSidebarConversationOpen","pendingRenamePid","cancelPendingSidebarConversationOpen","getCachedConversation","previousTitle","latestConversation","bottomPanelCurrentTab","sidebarConversation","useExternalStateSelector","activeSidebarConversation","setAgentChatsLocationAndMoveOpenConversations","faLeftToLine","faDownToLine","getAgentManagementMenuItems","isRenaming","isBottomSelected","newTitle","timeAgoShort","tableMappingConnector","getExpandedTableMappings","SharedTableIndicator","warning","TableMapping","supportsDirectSqlAccess","supportsMultipleDatabases","shared","expandedTableMappings","allowRestrictedTableMappingUpdates","tablesInUnrestrictedMappings","getTablesInUnrestrictedMappings","tooltipText","isDebug","dpPoolName","sharedToolTip","sharedAnchor","inSyncToolTip","syncAnchor","outOfSyncToolTip","outSyncAnchor","devDbTooltip","devDbAnchorRef","deploymentPoolTooltip","deploymentPoolAnchorRef","ideTasks","getIDETasks","cloneStatus","cloneTask","looseIdeTasks","appCloneTask","closeStatusWasComplete","showSyncStatus","cloneStatusTooltip","cloneStatusAnchorRef","renamingTableId","setRenamingTableId","inFlightTableRenames","setInFlightTableRenames","addTable","newTable","updateCtaKey","onRenameTable","rs","renameTable","_removed","onDeleteTable","isSharedTable","confirmWithCheckBox","renamerRef","setRestricted","onRestrictedChange","newRestricted","finishEditingMappingName","some","removed","removeTableMapping","doDelete","deleted","updateExpandedMappings","openSQLAccessModal","openAddExistingTableModal","onOpenCloneDBModal","onOpenRestoreDBModal","select","faStar","faRetweet","faClockRotateLeft","faInfoCircle","databaseNavConnector","getAppDBSchema","appSchema","chooseEnvironmentMapping","setCurrentTableMapping","checkForStagingDatabases","createNew","baseName","widthTest","checkPanelWidth","isSharedMapping","tableMappingsWithMismatches","faSitemap","DbCTA","LOG_ITEMS_NO_ACCOUNTING","LOG_ITEMS","logItems","getSearchTerm","getSearchIsCaseSensitive","getSearchIsRegex","getSearchFocusInput","getSearchExpanded","CompiledResults","MatchItem","MatchLink","resultKey","setSelectedResult","selectedResult","onResultClick","matchLine","matchHtml","activate","searchExpanded","iconClassGetter","fileIcon","updateExpanded","updateSearchExpanded","matchProps","isCaseSensitive","isRegex","focusInput","isSearching","useAppSearch","showSearching","searchData","searchResultsAsArray","truncated","skippedFiles","setSearchInput","searchHistoryStore","onResultsKeyDown","allCollapsed","delaySearchDispatch","useDelayDispatch","defaultDelay","setDelayDispatch","dispatchFn","pendingHistoryTerm","numFiles","totalResults","withCase","withRegex","recordHistory","updateSearchQuery","len","mult","onCollapseAll","collapseAllSearchResults","onCaseSensitive","onRegex","currentResultKey","searchInputEl","caseTT","caseTTRef","regexTT","regexTTRef","refreshTT","refreshTTRef","expandAllTT","expandAllTTRef","faFontCase","faPlusSquare","faMinusSquare","useDeleteLinkStyles","isOwner","getIsOwner","currentSection","THEME_ITEMS_NO_COLORS","THEME_ITEMS","getAppColorsIncludingDependencies","themeItems","servicesOrder","endingRe","removeService","PrimaryLink","subNav","actionCreator","primary","canRemove","primarySection","secondaryNavOpen","triggered","setTriggered","tooltipEl","evaluateSecondaryNavState","primaryNav","SecondaryNavContainer","secondaryNavRef","useScrollWhenDragging","getPrimarySection","getSecondaryNavOpen","getInvalidYaml","navMode","invalidYaml","orderBy","overlayModeTooltip","overlayModeTooltipRef","secondaryNavContent","CodeNav","SearchNav","DatabaseNav","SettingsNav","LogsNav","ThemeNav","TestingNav","setDocked","docked","openNav","setNavModeToDocked","closeNav","setNavModeToOverlay","secondaryNavContainer","faChevronsLeft","canScrollUp","setCanScrollUp","sidebarScroller","checkScrollDirections","containerHeight","contentHeight","scroll","onFinishResizeSecondaryNav","secondaryNavResize","resizePanel","secondaryNav","faThumbtack","enableAgents","isAINewFeature","useIsAINewFeature","hasAlreadyCreatedAgentConversation","getUserHasCreatedConversation","daysRegistered","daysSinceLaunch","faFolderTree","maybeDecideToOpenOpenConversation","faCog","navigateToTabMatchingTarget","faListUl","keyAndServiceProps","serviceToProps","ending","ret","serviceProps","addServiceWithModal","getEmailService","getPublishInfo","getAppOrigins","emailService","publishInfo","origins","customHost","setCustomHost","customPort","setCustomPort","customEncryption","setCustomEncryption","customUsername","setCustomUsername","customPassword","setCustomPassword","saveEncryptionIndicator","setEncryptionSaved","settingsTested","setSettingsTested","connectionSucceed","setConnectionSucceed","settingPassword","setSettingPassword","savePasswordIndicator","setPasswordSaved","disableTest","setDisableTest","passwordRef","privateEnvs","publicEnvs","customEnvs","isPublished","useUpdateTabTitle","handleSetPassword","testMode","customMailServer","testModeBanner","toggleSetting","customServerBanner","updatedValue","updateService","updateCustomSMTPSetting","testSettings","success","updateEncryptionSetting","handlePasswordSave","customMailServerForm","setQuotas","showOneEnv","domain","oneOfManyEnvs","domains","allPublicEnvs","EmailServiceCTA","getFacebookServiceSpec","getFacebookService","fbServiceSpec","fbService","fbAppId","setFbAppId","fbAppSecretSet","setFbAppSecretSet","updateFbServerSetting","saveAppSecret","FileOrFolder","isChild","setIsExpanded","canExpand","getFileService","fileService","debugTableMapping","selectedTableMapping","setSelectedTableMapping","fileTable","fileTableCols","colsByName","requireFileTableContext","pathColId","fileColId","fileVersionColId","fileTableContext","invalidateFileTableData","invalidateTableDataQuery","createFileTable","ensureRequiredFileServiceColsExist","fileRowsQuery","useTableRowsInfiniteQuery","flatFiles","page","fullPath","initial","newParent","refreshFilesNow","uploader","uploadPath","setUploadPath","upload","uploadFiles","filesToUpload","conflict","ff","uploadAborter","errors","tableContext","overwrite","overwriteRowId","tableApi","uuid","percentUploaded","chooseFile","map","isDropping","setIsDropping","dragEnter","dragLeave","dragOver","droppedFileEntries","readPage","processedFiles","onDeleteNode","onRenameNode","newPath","selectedNode","setSelectedNode","readGoogleError","encryptAndSaveRefreshToken","unencrypted","reloadAppConfig","markAppPathUnsaved","updateAppFileProperty","fileId","getGoogleService","pythonifyName","pythonifyPackageName","getGoogleFiles","accessToken","folderId","nextLink","getGoogleFile","addFileFromDriveToGoogleService","driveFile","appFiles","pythonName","generateNewPythonName","fileTitle","allPythonNames","re","numbers","nameN","createItemInDrive","parentFolderId","folderName","permissionOptions","faEyeSlash","openURL","googleModalStyles","isFolder","GoogleModalFileRow","setFolder","breadCrumbPath","setBreadCrumbPath","addfileAndCloseModal","openFolder","faFolderOpen","BreadCrumbs","goToFolder","goToSearch","crumbLength","childIndicator","hiddenFolders","hiddenFoldersEllipsis","createTooltip","createTooltipRef","currentFolderId","setCurrentFolderId","setLoaded","googleFiles","setGoogleFiles","nextPageOfFiles","setNextPageOfFiles","nextPageInSearch","setNextPageInSearch","setSelectedFile","searchApiCalled","setSearchApiCalled","clearSearch","getAndSetFilesInFolder","upOneFolder","getSearchResults","upFolder","changeSearchTerm","safeSearch","debouncedSearchResults","promptAndCreate","createMenuItems","faFileSpreadsheet","getNextPageOfFiles","maybeNoResults","FileRow","pythonAppNames","removeTooltip","removeTooltipAnchorRef","settingName","setSettingName","copyPythonName","copyToolTip","exportLinks","exportDropDown","permissionsIcon","permissionsDropDown","PythonNameBox","setPythonName","saveNewName","saveName","googleService","formClasses","authDefer","window_onMessage","doAuth","defer","authUrl","URLSearchParams","windowFeatures","strWindowFeatures","mapsApiKey","setMapsApiKey","clientId","setClientId","appOriginRedirect","saveRedirectIndicator","setRedirectSaved","clientSecretSet","setClientSecretSet","saveClientSecret","updateGoogleSetting","refreshToken","setAccessToken","accessTokenRef","tokenError","setTokenError","mailEnabled","useMemoAsync","permissions","updateRedirectAndSave","initialLogin","unenc_refreshToken","addFileFromPicker","gapi","pick","drive","google","sharedDrives","picker","picked","fileIds","fullFile","addNewFile","addExistingButtonHandler","successfulToken","getAccess","loginThenOpenModal","addNewButtonHandler","newFileType","getGoogleDelegatedAccessToken","isClientConfig","faGoogleDrive","faUnlink","faShare","deploymentFields","getSchemaFields","parseAndValidateDeploymentDocument","parseDocument","isMap","isScalar","readDeploymentFields","saveFieldValue","patchDeploymentField","CST","insertion","missing","subtree","lastItem","trailingComma","stringify","showFields","setShowFields","copyingTemplate","setCopyingTemplate","fileExists","copyTemplateFile","restore","copyExtraAppFileFromTemplate","HawthornDeploymentFields","getMicrosoftService","microsoftService","updateMicrosoftServerSetting","azureAppId","setAzureAppId","linkAzureApp","setLinkAzureApp","updateUserProvidedApp","azureAppSecretSet","setAzureAppSecretSet","saveAzureAppSecret","tenantType","setTenantType","singleTenantId","setSingleTenantId","updateTenantId","requestExtraOAuth","setRequestExtraOAuth","extraOAthScopes","setExtraOAthScopes","updateExtraScopes","getSAMLService","samlService","appOrigins","updateSAMLServerSetting","typedDispatch","updatePropertyAndSave","setIndicator","entityId","setEntityId","ssoUrl","setSsoUrl","signingCert","setSigningCert","emailAttribute","setEmailAttribute","shareSAMLConfig","forceAuth","signatureAlgorithm","saveShareIndicator","setSaveShareIndicator","saveForceAuthIndicator","setForceAuthIndicator","saveSignatureIndicator","setSaveSignatureIndicator","signatureAlgorithmOptions","samlMetadata","faLock","tableAccessTitle","getIndexKey","getNamedTableSchema","tableName","tableSchema","Schema","TableSchema","onDeleteDisplay","onDeleteVal","ColumnSchema","displayType","ClientHiddenIcon","columnUtils","columnA","columnB","faUserSlash","ColumnInfo","IndexInfo","useColumnTooltip","MigrationButton","TableItemContainer","showMigrateButton","disableMigrationButton","hasDiff","hasTableInSchema","hasTableInOtherSchema","buttonPosition","buttonVariant","onMigrate","extraClassName","containerClasses","ColDiffs","appColumn","currentColumn","hasTableInAppSchema","hasTableInCurrentSchema","updateAppSchema","changeDBTT","changeDBTTRef","changeAppTT","changeAppTTRef","IndexDiffs","currentIndex","indexAllowedInDb","indexAllowedForUser","changeDbToolTipText","actionText","TableDiffs","currentSchema","hasTableUpdate","hasNewTableInASchema","entireAppSchema","supportsDbIndexes","supportsDbIndexesSplit","tableSidebySide","allColumns","twoTables","columnName","tableIndexesSideBySide","appIndexes","currentIndexes","accumulateIndexesByKey","all","appIndexesByKey","currentIndexesByKey","allKeys","pairs","getAvailableIndexTypesForSingleColumn","existingColumnIndex","sameName","currentIndexKey","client","newPythonName","updateAppDBSchema","tableColumns","colName","colData","metaDiffs","appTitleTT","appTitleTTRef","appNameTT","appNameTTRef","appClientTT","appClientTTRef","appServerTT","appServerTTRef","appTableTT","appTableTTRef","currentTitleTT","currentTitleTTRef","currentNameTT","currentNameTTRef","currentClientTT","currentClientTTRef","currentServerTT","currentServerTTRef","currentTableTT","currentTableTTRef","debugTableMappingId","getDebugEnvironmentTableMappingId","tableMappingName","getTableMappingDisplayName","getRequiredSchemaDiffs","mappingSchema","diffsOfTables","organizedDiffs","sideBySide","exclusive","toRemoveFromList","inclusive","appSchemaTableNames","currentSchemaTableNames","allTableNames","twoSchemas","changedTables","deletedTables","createdTables","appTableName","schemaDiffs","updateApp","maybeMigrateAppOrDB","getStripeAccount","stripeUserId","fetchStripeAccount","account","loadStripeAccount","getStripeService","stripeService","localStripeError","setLocalStripeError","stripeAccountQuery","stripeAccount","refreshFailed","stripeError","clearConnection","connectAccount","register","sleep","liveMode","liveKey","setLiveKey","testKey","setTestKey","updateKeys","toggleMode","WrappedTabContext","wrappedTabContentRef","TabContent","tabs","orderedTabs","TabBar","leftSide","allowScroll","DBUplinkConfig","dbUplinkConnector","disableEnvironmentUplink","debugEnv","loadTableauLicence","publishToTableau","TableauUsers","$getNearestNodeOfType","klass","editorTheme","ToolBarButton","captureSelectionData","$isRangeSelection","restoreSelection","selectionData","$createRangeSelection","$setSelection","editLink","selectLinkNode","currentUrl","$getSelection","anchorNode","$isLinkNode","firstChild","lastChild","$isTextNode","trimmedUrl","TOGGLE_LINK_COMMAND","formattedUrl","hasProtocol","NORMAL_BLOCK","faParagraph","BLOCK_TYPE_OPTIONS","faH1","faH2","faH3","DEFAULT_TOOLBAR_STATE","ToolbarPlugin","useLexicalComposerContext","toolbarState","setToolbarState","updateToolbar","parentList","ListNode","parentHeading","HeadingNode","$isListNode","$isHeadingNode","handleFormat","FORMAT_TEXT_COMMAND","handleLink","currentBlock","getCurrentBlockLabel","opt","REMOVE_LIST_COMMAND","INSERT_UNORDERED_LIST_COMMAND","INSERT_ORDERED_LIST_COMMAND","$setBlocksType","$createParagraphNode","$createHeadingNode","faBold","faItalic","faUnderline","DoubleClickLinkPlugin","handleDoubleClick","linkNode","rootElement","prevRootElement","HTML_SYNC_TAG","HtmlSyncPlugin","HTML","onHTMLChange","lastHtmlRef","htmlToLoad","$getRoot","parser","DOMParser","$generateNodesFromDOM","formattedHtml","formatHtml","html","blockTags","indentedLines","$generateHtmlFromNodes","EditablePlugin","stripClassesFromExport","exportMap","TextNode","HTMLSpanElement","LinkNode","ListItemNode","ParagraphNode","LexicalEditor","initialConfig","LexicalComposer","RichTextPlugin","ContentEditable","LexicalErrorBoundary","HistoryPlugin","LinkPlugin","ListPlugin","findColumnByName","usersTable","columnSpec","UserServiceTable","usersService","getUsersService","getUsersTable","useUserRowMenu","mutation","useUpdateRowMutation","resetPasswordCallback","pw1","pw2","passwordColId","emailConfirmedColId","colCount","addedPasswordCol","addTableColumn","addedEmailConfirmedCol","clearRememberedLoginsCallback","rememberedColId","resetMfaCallback","mfaColId","emailColId","forceMfaOnNextLoginCallback","mfaData","maxHeight","isRepairing","setRepairing","repairUserTableConfig","ensureUsersServiceTableConfigured","availableUsersTables","repairUserTableLabel","hasConventionalUsersTable","chooseExistingUserTable","updateUsersService","addExistingTableToDebugDatabase","configuredTable","EmptyUsersClientConfig","EmptyUsersServerConfig","clientConfig","updateUsersConfig","add_service","requireFeatureOnSubscription","config_name","use_service","getServiceSourceFromName","addService","toggleAllowRememberMe","toggleRequireMfa","toggleUseEmail","UserServiceCTA","UserEmailTemplate","supportsCustomUserEmails","serverConfig","emailTypes","emailId","fromAddress","setFromAddress","updateFromAddress","useUpdateServerConfig","onChangeFromAddress","EmailEditorHeader","EmailEditor","currentVal","EMAIL_BODY_EDIT_OPTIONS","getAppName","usersServiceEmails","thisEmailDefaults","thisEmailContent","defaultSubject","defaultBody","emailSubject","setEmailSubject","emailBody","setEmailBody","htmlBody","setHtmlBody","updateServerConfigSubject","updateServerConfigBody","onSubjectChange","subject","onResetSubject","onResetBody","htmlTimeout","onHtmlChange","onChangeBody","editOption","htmlEditor","IconWithPreview","isHovering","setIsHovering","EmailPreview","shadowBodyRef","setScale","shadowRoot","shadowEl","EventEmitter","listener","g","done","undone","prevTime","cloned","clone","stateKeys","editingForm","INIT_STATE","HistoryStore","historyStore","useHistoryStore","useHistoryStoreSelector","ID","hasFocus","setFocus","updateHistory","canUndo","canRedo","ELEMENTS_WITH_OWN_HISTORY","useUndoRedoKeydown","onUndo","onRedo","isMac","useGlobalUndoRedo","onMaybeUndoRedo","BreadcrumbNavLink","useFormEditorContext","navigateToEditingForm","ShortClassName","BreadcrumbNav","rpc","useRpcContext","useRpcState","selectedBreadcrumbRef","hiddenDesigner","FormEditorContext","GrabComponentPortal","creatingObject","initialX","initialY","mousePosition","setMousePosition","updateMousePosition","previewSrc","useComponentIconSrc","requestedView","DEFAULT_VIEW","editHistory","codeToolsPane","setCodeToolsPane","codeToolsState","codeToolsContainer","setCodeToolsContainer","designerPanelDocked","getDesignerPanelDocked","preventDocking","getIsPySpace","useRpcView","splitMinWidth","useMinPixelsToSplit","viewControlsMinWidth","isSmallScreen","useIsSmallScreen","isMobileIde","canUseSplitView","formEditorRef","rightToolbarControlsRef","viewControlsAreNarrow","setViewControlsAreNarrow","updateViewControlsWidth","formEditor","rightToolbarControlsWidth","useCompactViewControls","requestReload","setRequestReload","jumpRequest","setJumpRequest","jumpRequestAtom","onRequestJumpToCode","lastCodeView","showCodeSnippets","showDesignerToolbox","showSnippetOverlay","setShowSnippetOverlay","propertiesPanelTooltip","propertiesPanelTooltipRef","codeSnippetsTooltip","codeSnippetsTooltipRef","setLastCodeView","wrapWithPersist","useWrapWithPersistTab","editingFormCodePath","editingFormClassName","syncHtmlFormAfterMutation","notifyUpdatedCodeItem","formHtmlPropertyType","setFormHtmlPropertyType","useEditHtmlTemplateHtmlProperty","htmlPropertyAvailable","lastCodeViewBool","normalizeFormEditorView","designerOverlayDiv","newView","saveToCache","getNumViews","setSplitCodeEditorRatio","viewToCache","queueMicrotask","setSingleViewMode","setShowOverlayPanel","createSingleView","setPresetView","preset","createPresetView","toggleViewMode","nextView","getPreferredSingleViewMode","useEnsureFormEditorViewNormalized","is3ViewMode","viewMatchesPreset","VIEW_PRESETS","formClassIsMissing","onSetHtmlView","onSetHtmlPropertyView","bindingView","resetBindingView","isReady","selectedObjects","preferSingleSections","setPreferSingleSections","skinnySidePanel","setSkinnySidePanel","componentName","bindingIsSelected","selectedObject","setPanelSectionExpanded","snippetState","setSnippetState","moduleEditor","codeEditorView","htmlTemplateEditorView","htmlPropertyEditorView","htmlTemplateEditor","htmlTemplateEditorResizePanel","htmlPropertyEditor","htmlPropertyEditorResizePanel","combinedDesignRightPane","codeViewSnippetPanel","useFormEditorUsage","darkMode","_setDarkMode","enableDarkMode","_setCreatingObject","initialGrabPosition","setInitialGrabPosition","setCreatingObject","onOpenCustomComponentModal","onToggleCustomComponent","migrateToRuntimeV3","onChooseLayout","form_event_bindings","event_bindings","copyProps","omitBy","isUndefined","isTopLevel","formMenuItems","faBrowser","faArrowUpFromSquare","undoRedo","useUndoRedo","setCanRedo","setCanUndo","showOverlayPanel","inSplitView","numViews","codeToolsOverlay","showCodeOverlay","onCloseCodeOverlay","codeToolsPanel","CodeToolsPane","Designer","splitViewMenuItems","isSplitPresetActive","viewMenuItems","splitItem","viewItem","viewMatchesSingleMode","splitItems","viewItems","compactViewMenuItems","isValidCustomLayout","grabbingFile","draggingFileDropRef","useFileDragOverNewFormEditor","formEditorContext","setDesignerPanelDocked","RpcContext","MobileFormToolbar","pythonCodeMenuItems","faPaperPlane","faAlignLeft","faHtmlCode","faUndo","faSidebar","FormFormatButton","ConflictNavigator","CodeToolsButton","updateCodeTabPrefs","CodeSnippets","SYNTHETIC_MAIN_APP_PACKAGE","componentYamlTypeFromToolboxType","toolboxType","customComponentSpecForToolboxType","packageContext","customComponentSpecForForm","formSpecTargetForPackageQualifiedToolboxType","dependenciesByPackageName","unknownPackage","PACKAGE_QUALIFIED_FORM_NAME","normalizeToolboxItemComponentTypes","componentWithCustomComponentSpecs","createForms","formSpec","createFormsUpdate","toolboxQualifiedNameFromComponentYamlType","componentYamlType","legacyMatch","moveObjectsInForm","objects","dropInfo","updateComponentByNameInside","cleanupLayoutProperties","componentIdx","moveTarget","sameTarget","selectedComponents","moving","slotDefsByTarget","childIdx","dropPosition","movedSlotNames","movedComponents","deletedFromContainers","slots_set_layout_properties","applyOtherLayoutUpdates","inArray","parentName","parentType","adjustSlotsForDeletion","siblingSlots","insertMovedComponents","adjustChildIdxAndSlotsForInsertion","layout_properties","resequenceSlotOrderForTarget","cleanupChangedYaml","getYamlEventBinding","findComponentByName","resolved","getComponentOrContainerOrLayout","isLayout","eventBindings","isWithLayoutFormEvent","getDecoratedEventHandler","formEventHandlers","resolveEventHandlerRequest","decoratedHandlerMethod","yamlHandlerMethod","existingHandlerMethod","RpcState","updateComponentInTree","predicate","updateComponentByNameInTree","containingArray","getErrorObject","innerError","getAllComponentNames","insideComponent","getNewComponentName","nameRoot","otherNamesToAvoid","isCopy","allNames","exists","splitNameRootAndIndex","getNewSlotName","preferRaw","otherLayoutUpdates","mergedChildIdx","movedSlots","movedSlotNameSet","peers","compareSlotDefs","insertionPoint","insertAt","virtualPosition","insertingType","nInserting","maxIdx","listIdx","slotsInList","targetType","targetName","_name","renameSlot","oldName","sibling","FIXED_HEIGHT","RowEl","getRowSize","readonly","updateSelectedRows","rowDivRef","onfinish","flexRender","tableBodyRef","getVirtualItems","getTotalSize","paddingTop","paddingBottom","virtualRow","TableFooter","footerGroup","headerGroup","ToolbarButton","tip","btnRef","accessLevel","faBan","faPen","Permissions","meta","itemDescriptors","getAccessMenuItems","accessFromTable","ingestOldIDESchemaUpdate","invalidateTableSchema","PythonName","setKey","toSafePythonName","alreadyExists","DeleteButton","footerId","isSomeCellSelected","isSomeColSelected","selectedCells","selectedCols","hasSelectedCells","hasSelectedCols","deleteSelectedRows","useDeleteRows","deleteSelectedCols","useDeleteCols","deleteSelectedCells","useDeleteCells","onDeleteClick","hasSelected","getToolTip","total","Sort","numSorts","faArrowUpArrowDown","HiddenColumnsContent","columnOrderedByName","colNames","HiddenColumns","hiddenColumns","numHidden","faTableColumns","mappingTables","currentTableIndex","supportsIndexing","openTableIndexesModal","Reset","setHiddenColumns","hasSortedFields","hasHiddenColumns","faTimesCircle","ExtraMenuOptions","onDeleteAllRows","onDownload","onInsertColumn","useInsertColumn","Separator","canScrollLeft","setCanScrollLeft","canScrollRight","setCanScrollRight","contentWidth","scrollLeft","onScrollClick","canScroll","storageModeTooltip","storageModeTooltipAnchorRef","faCaretLeft","faRefresh","faRectangleHistoryCirclePlus","faRectangleHistory","refocus","mutate","changedRows","prevData","rowIds","newPages","pages","pageData","newRows","cellIdentifier","NullCell","LinkedRowBadge","namedColId","RowLink","shortenString","JsonCell","StringCell","CellData","MediaCell","isoToDateAndOffset","CellInner","updateSelectedCells","isCellSelected","isEditingCell","resetSelected","isColSelected","tableContainerRef","focusValue","onUpdateSelectedCell","isLoadedRef","isEditing","isMedia","cellRef","focusCellEffect","onDeleteCells","onEditMode","colIsSelected","isLastRow","onContextMenu","EditingCell","numCells","faEdit","useSetCachedEditState","setCachedEditState","useInputKeyDown","getQueryKeyParts","markSaved","variables","queryData","useOnSaveOnBlur","convert","onSettled","convertedValue","newData","useAutoFocus","useResizableEditingCellRef","tableBody","tableContainer","tableBottom","tableContainerRight","cellBottom","cellRight","marginBottomRequired","paddingRightRequired","dataValue","getCachedEditState","expandRef","onExpand","onBlurIfExpanded","relatedTarget","TA","faArrowsMaximize","NumberEditor","BoolEditor","onBlur_","DateEditor","valueRef","INIT_OFFSET","iso","DateTimeEditor","valueOffset","updateValueOffset","RowLinkEditorCommon","getData","isEditingLinkedRow","setIsEditingLinkedRow","RowLinkEditor","LazyJsonEditor","FooterReducer","INIT_FOOTER_ID","useFooterId","updateFooterId","CellCheckbox","MediaFooterCell","FooterEditCell","newFooterId","useAddRowMutation","LazyJsonFooterEditor","MediaUploadButton","getRowData","fileLoaderRef","_e","newRow","rowData","MediaUpload","MediaUploadFooter","mutateAsync","MediaBadge","typeToIcon","faFileImage","faFileText","faFilePdf","faFileExcel","faFileCsv","columnOrder","getNewOrder","colIndex","prevColId","prevCol","currCol","prevColOrder","columnNames","columnSpecs","maybeColSpec","AddColumnHeaderCell","emptyColumns","AddColumnDef","LINKED_COLUMNS","useColumns","HeaderWrapper","ReadOnlyColumnHeader","DraggableColumnHeader","columnHelper","createColumnHelper","columnDefs","admin_ui","getNamedColId","Cell","FooterCell","ColumnHeader","SelectMultiple","SelectSingle","SelectRow","reorderColumn","draggedColumnId","targetColumnId","useColumnOrder","currentColumnOrder","itemA","itemB","setColumnOrder","columnPinning","SELECT_ID","ROW_MENU_ID","deleteRowMutation","failed","numFailed","errorMessages","confirmDelete","rowIdentifier","numRows","SelectRowCellInner","onClickDD","SelectRowCell","deleteItem","SelectLinkRow","useColumnSorting","uiSortPrefs","updateSort","useHiddenColumns","uiHiddenPrefs","getHiddenColumns","prevHiddenColumns","hiddenColumnState","updateHiddenColumns_","updateHiddenColumns","updatedHiddenColumns","resetHiddenColumns","INIT_SELECTED_STATE","KNOWN_TYPES","canEdit","getSelectedCols","colAnchorId","colOrder","useSelected","cachedEditStateRef","selectedDispatch","rowSelectedReducer","additive","rowAnchorId","selectedUiRows","rowAnchor","uiRows","toSelectUiRows","toSelectedIds","toToggle","uiRow","cellSelectedReducer","moveCellSelection","currRowId","currColId","dir","colIdx","nextRowIdx","isEditMode","prevId","newId","cells","newCells","newSelectedCols","newSelectedRows","getSelectedRows","newSelectedCells","selectedIdx","colSelectedReducer","useActionOnStateChange","updateSelectedCols","numSelected","INIT_ROW_SIZING_STATE","isTouchStartEvent","useRowResizing","rowSizingInfoState","setRowSizingInfoState","rowSizing","setRowSizing","rowSizingRef","getRowHeight","getIsRowResizing","getRowResizeHandler","startSize","eventType","clientYPos","deltaOffset","deltaPercentage","onEnd","mouseEvents","touchEvents","sortable","colType","indexTypes","indexType","getTableName","table_id","IndexMenuItem","validPlan","hasSingleColumnIndex","lookForKey","modifyIndex","useItems","onDeleteColumn","onEditColumn","useEditColumn","currentlySorted","maybeOpenTableIndexesModal","isInAnIndex","faArrowUpAZ","descending","faArrowDownZA","mkClear","faSlash","faICursor","availableIndexTypes","ColumnDropDown","ColumnHeaderInner","onSaveName","updatedColSpec","updateCol","uiTypName","getUiType","colSorting","clientHidden","onColumnSortingClick","faArrowUpLong","faArrowDownLong","numCols","allItems","columnIdentifier","fixedTypes","draggedColumn","newColumnOrder","nextColId","nextCol","onSizeChange","colIds","newWidths","dragHandleRef","onDeleteColumns","useDoubleClickResize","maxWidth","measureText","currentWidth","dispatchUpdates","addDispatch","headRef","deleteScheduledTaskWithModal","onEdit","formatTimeSpec","ScheduledTaskLastRunInfo","newTask","getCurrentBranch","environmentsUi","isPyspace","getAppIsPyspace","scheduledTasksNotEnabled","anySuspended","taskInfoResults","useQueries","getScheduledTaskInfo","onReactivate","restartScheduledTasks","onAddTask","selectedEnvId","setSelectedEnvId","selectEnvironment","enableScheduledTasks","EnvironmentScheduledTaskConfig","ScheduledTaskItem","ErrorEvent","err","bindingDescription","navigateToBinding","MatchEvent","logText","matchStart","matchLen","matchEnd","log_text","matchRef","onServer","units","launched","LogImportSummary","callCount","importEvent","totalImportDuration","EventData","DependencyExpandButton","DependencyErrorWarning","DependencyChildren","dependencyGraph","ancestors","DependencyChild","childrenId","repeated","hasChildErrors","hasDependencyErrors","updateAppConfig","normalisePackageName","packageNameFromRequirement","requirement","eggFragment","PythonAndPackagesConfigLoaded","customPackagesAvailable","getCustomPackagesAvailable","hasLegacyAppEnvironments","hasLegacyEnvironments","enableScripts","clientVersion","setClientVersion","serverSpec","setServerSpec","migrating","setMigrating","selectionError","setSelectionError","clientSaveIndicator","setClientSaved","serverSaveIndicator","setServerSaved","requirementsSaveIndicator","setRequirementsSaved","updateClientVersion","onSavedCallbacks","updateServerSpec","onSaved","updateRequirements","requirements","updatePreInstallScript","pre_install_script","updatePostInstallScript","post_install_script","serverSpecTimeout","serverSpecInitialised","callbacks","sourceImage","managedRuntimes","runtime","usingManagedRuntime","previousImageSpec","hasCustomPackagesOrScripts","switchManagedRuntime","promptIfRuntimeMissing","nextSpec","applyChange","previousSpec","bundledRequirements","unknownBundle","confirmAndMigrateApp","mergeMigrationRequirements","migrationRequirements","existing","existingLines","packageNames","directives","directive","advancedOptionsInDefaultState","showAdvanced","setShowAdvanced","currentEnvironment","PythonEnvironmentSelector","PackageRequirementsEditor","shown","InstallScriptsSettings","OtherRuntimeSettings","hasDependencyConfiguration","visited","isPythonImageEndOfLife","usePackageVersions","usePackageCompletions","parseSimpleRequirements","formatSimpleRequirements","role","renamingRole","setRenamingRole","roleName","setRoleName","newComponentName","setNewComponentName","displayInToolbox","setDisplayInToolbox","roleTitle","setRoleTitle","saveTitleIndicator","setTitleSaved","saveNameIndicator","setNameSaver","saveTimeoutRef","onSaveDisplayTitle","updateRole","onRenaming","deleteRole","onNewComponentNameChange","onAddNewComponent","addRoleComponent","onDeleteComponent","deleteRoleComponent","onRemoveAllComponents","onRestrictComponents","onDisplayInToolboxChange","IDE_APP_LIST_QUERY_KEY","invalidateIdeAppListQueries","snapshotIdeAppListQueries","restoreIdeAppListQueries","transform","oldData","oldApps","nextApps","APP_ITEM_DEFAULTS","insertIdeAppIntoListQueriesOptimistically","snapshots","shouldOptimisticallyInsert","firstPage","cappedApps","currentAppId","ac","workerConstructor","initWorkerRPC","nextCallId","outstandingCalls","fnName","fn","callId","Worker","domNodeRefCache","DOM_NODE_TAG_ATTR_RE","annotateFormForAutocomplete","serializedHtml","fingerprint","fingerprintDomNodeAttrs","collectDomNodeRefs","extractDomNodeRefs","acStateStore","updateHttpEndpointsAndRoutes","serverModuleName","updateEventHandlers","endpoint","route","renameComponentEventHandlers","addEventHandler","handlersForForm","existingHandler","resetApp","abFlags","server_modules","jsComponentDefinitions","getJsCustomComponents","sm","provideJsCustomComponentsToAutocompleter","jsComponents","typeToCamelCase","synchronizeLegacySources","autoComplete","lineNo","charIndex","identifier","HIDDEN_FORM","publishLegacyMetadata","itemForAutocomplete","formItem","moduleItem","renameItem","newTableMappingId","getDefinedBackgroundTasks","updateFormItemType","parseDependencyCode","DEBUG_HTML_PARSING","logHtmlParsingDebug","payload","stack","captureHtmlParsingDebugStack","copyJsonPayload","_cacheKey","_cache","oldKey","newKey","generateTitleFromCodeTabItem","itemTypeFromCodePath","HIDDEN_CODE_ITEM","HIDDEN_CODE_PATH","cache","getItemCache","clearCodeItemCache","rebuildCodeStructureAndSyncCache","changedCodePaths","itemCache","syncCacheToInitialCode","buildCodeStructureFromInitialCode","clearCacheForChangedPaths","cacheKeyStr","cacheIdx","removeDeletedItemFromInitialCode","writeCachedItemToInitialCode","cloneDeep","getCodePathSequenceNumber","getEditorSequenceNumbers","updateSerializedHtmlWithResult","debugContext","suppressDebug","indentSize","serializeFormLayoutWithResult","serializeFormContainerWithResult","formForPreview","canonicalizeFormSpecsInFormYaml","previewResult","updateSerializedHtml","structuralHtmlChanged","setSerializedFormHtml","inflateHtmlFormYamlForDesigner","parseSerializedHtml","prepareFormForDesigner","deflateHtmlFormYamlForPersistence","serializeFormLayout","serializeFormContainer","deflated","enqueueRecentCodeItem","viewCache","recentCodeItemCodePaths","popped","cachedItem","conflictType","conflictIdx","cname","cacheRuntimeParsedHtmlFormYaml","_key","openRuntimeFormItem","getRuntimeParsedHtmlFormYaml","mutateItem","updatedItem","hasOpenConflicts","conflictItem","restoringMerge","cachedConflict","updateCodeStructureCustomComponent","cacheItem","structureItem","structureItemsByName","stateUpdateForceReloadAllForms","stateUpdateForceReloadOpenTabs","autocompleter","structPath","existingCache","scriptItem","assetItem","addToFileHierarchy","structureRootByItemType","CODE_TYPES","requireConfirmation","startupItemFullName","possibleStartupItems","getDeleteItemStateChanges","getTabByCodePath","forceCloseTabs","rootItem","removeFromFileHierarchy","getItemCodePath","newStartupItem","scriptConfig","deletedScriptNames","newScriptConfig","updatedFormCodePaths","updateYaml","updatedFormItem","objPath","dropRight","lastKey","updateAllForms","loadAllForms","iconToFullName","objectPath","layoutThumbnail","newLayoutMetaData","hasThumbnail","checkThumbnail","hasLightIcon","hasDarkIcon","newComponent","markAppPathsUnsaved","clearInPlaceEditTarget","updateTab","addForm","pathSep","newFullName","doFullRename","dropFileAndRestructure","rootName","targetFullName","oldLogo","getAppMetadata","newLogo","appAssets","appAssetFolders","allCodeItemNames","oldFullName","newPrefix","currentPrefix","escapeRegExp","navTargetReplacement","oldToNewFullNames","cacheEntriesToRename","renameItemAndChildrenReturningChangedAppPaths","isParent","codeItemsToUpdate","nameKey","changedAppPaths","cacheEntry","renameFormCode","newAppPath","newCacheKey","itemEditHistory","recentlyOpenedUpdater","currentStartupItem","currentStartupModule","renameCustomComponentSpecForLocalFormRename","renameLocalFormInCustomComponentSpec","renamedLayoutSpec","renamedContainerSpec","componentTypeName","itemTemplate","renamedItemTemplate","renameLocalFormInFormPropertySpec","slot_components","slotDef","newThumbnail","newIcon","namePrefix","splitCodePath","isNewDesigner","oldNames","updateInPlaceEditTarget","childCodePath","structurePath","existingItem","findInCodeStructure","finder","walkAndFind","subStructure","arrayMatchesPrefix","arr","targetEditingPathPrefix","navTargetUpdates","newTargetEditingPathPrefix","class_name","asExtraDirectory","buildExtraDirectory","directoryPath","hasInitializer","initialCode","templateMatchesForm","templateSpec","formClassName","redirectLinkForm","inPlaceEditFormEditingPath","inPlaceEditFormEditingPathV3","childName","formsUsingTemplate","newRedirectLinkForm","newRepeatingPanelName","testsDirectory","serverTestFiles","rootPath","initializer","initializerPath","getDefaultItemName","fromTemplate","allForms","allModules","allServerModules","allAssets","allAssetFolders","nth","codeStructureItem","isPackage","prepareModuleConversion","firstDot","ownName","imported","own","wildcard","ownImports","linePrefix","following","setIsLayout","formCodePath","formNode","TEMPLATE_RE","leaf","updateTemplateImport","templateLine","templateName","spaces","CLASS_DEF_RENAME","otherBases","otherArgs","STAR_IMPORT","TEMPLATE_IMPORT","applyPrelude","currentCode","prelude","subkey","preludeStr","getPrelude","numLines","removePrelude","codeBefore","newCode","numLinesBefore","newBreakPoints","bp","applyTabSizing","targetVersion","reformat","applyAllPreludes","forceServerImport","serviceSpecs","getServiceSpecs","getHasTables","code_prelude","uplinkVisible","getIsUplinkVisible","applyPreludeToItem","sourceName","currentBreakpoints","applyCodePreludeEverywhere","visitCodeStructureNodesAsync","templateForm","navigateAfterAdd","postponeReloadAll","initialView","templateMode","defaultMinimalFormCode","newForm","forceName","forceCode","structuredCodeItem","minimalTemplate","newModule","newServerModule","allScriptNames","newScript","newFolder","formNodes","uploads","findAssetPathConflict","createAsset","generateValidAssetName","ext","newAsset","redirect","newContent","fileToBase64Content","promptForGoodFileName","allowOverwrite","existingAsset","replaceAsset","currentItem","saveNativeLibraries","nativeLibraryCodeString","saveImportMap","importMapCodeString","EMPTY_CODE_STRUCTURE","EMPTY_DEP_CODE","createSelector","mkStructureWalker","structureArray","walkForms","walkModules","walkServerModules","walkAssets","getScripts","getDependencyForms","allDependencyForms","renderItem","findLogicalDepIdForDepAppId","allDependencyAssets","newHistory","currentHistory","getAndMaybeCreateCodeNavState","codeNavStateForTree","codeNavFileState","requestSetFormProperty","propertyName","topLevelProperties","defaultCodeNavState","codeNavStateObject","getClientCodeStructure","getFormsBy","depStructure","getCustomLayoutForms","getToolboxSections","getHideClassicComponents","hideInThisApp","useAsLayout","existingLayoutIdx","existingLayout","getCustomComponentAndLayoutForms","DEFAULT_SERVER_TEST_REQUIREMENTS","hasExtraFileConflictAtPath","conflictPath","validateExtraEntryName","requestedName","hasControlCharacters","setExtraFileContent","encodeAssetContent","createIfMissing","previousContent","initializerVisibilityChanged","existingConflict","deleteExtraFileEntry","parentParts","relocateExtraFileEntry","oldParts","newParts","oldParentPath","newParentPath","oldParent","isAffected","renamedPath","fileMoves","collectFiles","historyMoves","move","activePath","nextActivePath","raiseEvent","movingBetweenDirectories","createOldParentGitkeep","removeNewParentGitkeep","sourceDirectory","destinationDirectory","movingEntry","recentTabs","updatedPath","treeState","oldPrefix","destinationPath","initialContent","replaceExisting","getExtraAppFileTemplates","addMissingExtraAppFilesFromTemplate","availableExtraFiles","addedPaths","mergeMissingExtraFiles","existingFilePaths","occupiedFiles","occupiedPaths","getExistingFilePaths","modulePath","testsEntry","serverTestsEntry","exampleTestsFile","createInitializer","createExampleTestsFile","requirementsContent","hasPytest","serverTestsDirectory","initializerCacheKey","removeGitkeep","dependencyCodeEntries","customFormInfo","originalSpec","isDependency","packageQualifiedFormName","componentYamlTypeInfoForEditor","getDepAppIdForPackageName","depAppIdFromCode","leftType","rightType","right","oldFormatMatch","formPropertySpec","LEGACY_CUSTOM_COMPONENT_SPEC_PREFIX","makeCustomComponentSpec","makeFormPropertySpec","malleableCommitTimeout","getBranchForDependencyVersionSpec","versionSpec","getDependencyBranchWatches","dependencyOrder","watches","reloadDependenciesFromRepoUpdate","reloadDependencies","isWatchedDependencyBranchUpdate","dependencyBranchWatches","watch","requireApp","isCodeIncrementalChange","cleanupMalleableCommits","earliestMalleable","updatedTime","dt","earliestTimeout","setMalleableCommits","updateMalleableCommits","freezeCommit","withSuppressReloadingOnBranchMove","handleVersionUpdate","ref_update","is_malleable","replaced_commit","incremental","suppressReload","refSpec","movedOurBranch","replacedCommitIdx","syncLoadedBranchToRef","envsOnBranch","envs","getEnvironments","envsOnTag","commitInLoadedHistory","loadedCommitCount","keepMalleable","edit_session","edit_state","dependency_graph","resetAppState","maybeShowGitDesyncModal","applyIncrementalUpdate","incrementalData","from_commit","to_commit","to_commit_info","appSchemaChanged","mutableConfig","mutableThemeConfig","change_type","item_type","appSchemaBefore","mutableThemeConfigForIncremental","existingIdx","existingForm","moduleIdx","formIdx","serverModule","script","assetId","parents","reachedTarget","versions","revalidateAndReloadOpenTabs","currentCommitSha","saveCompleted","waitForSavingComplete","clearUnsaved","possibleRefs","possibleBranches","possibleMerge","checkoutBranch","tryIncrementalCheckout","loadingMessage","editContext","newEditState","mergeThisCommitId","fromThisBranch","intoThisBranch_","myBranch","intoThisBranch","removeCommitIfOrphaned","orphaned","appVersion","sourceBranch","sourceCommitId","ingestRefUpdate","saveSeqSession","fromAnvilSync","currentApp","newCommitSha","expectedFromCommit","tryWsIncrementalUpdate","tryHttpIncrementalUpdate","useHistoryWebsocketEventListener","reloadEditState","websocketListeners","refreshedState","useWebsocketEventListeners","handleRepoUpdateEvent","invalid_yaml","stateApp","maxCommits","currentCommitHistory","getAppPathForConflictItem","mutateItemByMergeItem","saveIssued","configPath","commitIds","possiblyOutOfDateConflicts","branchName","localBranch","tagEntries","aName","bName","aVersion","semver","bVersion","nonUserBranches","nonCollaboratorBranches","resolvingMerges","loadAppPermissions","permissionsFromApi","updateShareWithOrganisation","addAppCollaborator","updateCollaboratorPermissionPreset","collaborator","removeCollaborator","removingSelf","accessible","nullApp","getAppPermissions","NO_TASKS","isMyRunningDebugTask","myActiveDebugTasksOnly","lastUpdate","tasks","getBackgroundTasks","dateA","dateB","invalidateBackgroundTasks","optimisticallyKillMyRunningDebugTasks","set","isBottomPanelRepl","tabA","tabB","isBottomPanelScriptRun","isBottomPanelDebugger","getAbTutorialsInIde","getHasExitedTutorialTab","getAbGetStartedRoadmap","getAbVideoIntro","getWhereToStartTutorialTab","getDesignerHasOutput","getBottomPanelConversationPids","getShowTalkToUsOffer","tutorialsInIDE","hasExitedTutorialTab","introVideoFlag","whereToStartTutorialTab","designerHasOutput","conversationPids","showTalkToUsOffer","WHERE_TO_START_TUTORIAL_TAB_TITLES","runnerRepls","serverRepls","tableauRepls","categorizeRepls","categories","replId","_1","sortedHyperStacks","idA","idB","fallbackStack","bottomTabStack","getBottomPanelTabStack","openOrFocusBottomPanelConversation","currentConvs","requireAppId","updateDBAppState","_getDBAppSchema","_getAppNameOrDefault","findMapping","getTableSchema","isLinkedCol","diffHasOnlyIndexChanges","reloadAppTableMappings","getTableIdHints","toSafeTablePythonName","inFlightOps","totalOps","notifySchemaUpdate","withTableOp","requireTotalOps","onIdle","getAllDesignerRpcObjects","hasTables","tableToLink","flatLinkedTable","tm","mappingInAccess","mappingWithTable","getCreateSplitTables","isCurrentMapping","createdTable","flatCreatedTable","updatedTable","sanitise","oldAccess","newAccess","tableToUpdate","mappingToUpdate","closeTabFromNavTarget","liveObjectTypes","addedColumn","addedColumnSpec","isLiveObject","didSchemaUpdate","updatedSchema","colSpecToColSchema","sortMappings","linkedAccessMapping","dts","_appId","updatedMapping","accessibleMapping","currentState","toUpdate","latestTableMapping","debug","_getDBConfig","loadAppAccessibleTableMappings","tableCounts","updateType","isDebugInSync","appMappings","currentTables","tableInMapping","tablePythonName","touchedDebugDB","colItem","mappingTableSchema","debugTableSchema","makeKey","schemas","filterSchemas","removeCount","newColName","schemaType","addTaskIfMissing","removedIndex","customArrayMerge","objValue","srcValue","targetTable","rawIndexesToAppSchemaIndexes","allIndexes","updatedIndexes","colDef","originalName","mergeWith","updateSpecFromServer","schemaColumns","schemaIdx","columnIndex","EMPTY_SORT","validCols","cleanedSortedArray","updateUiPrefs","EMPTY","realHiddenColumns","enable_v2","enable_split","getTablesService","sendServerDebugRequest","debugLocation","reference","sendRunnerDebugRequest","df","sendRunnerDebugBroadcast","sendDebuggerRequest","augmentStack","onDebuggerUpdate","serverDebuggingAllowed","clientDebugger","innermostFrame","pausedDebugger","existingHyperStack","hasExistingHyperStack","newHyperStack","replaceEqualDeep","sendKeepalive","exec_id","serverReplReturn","restoreRunner","getIsRunnerPaused","getPausedServerReplHyperstackId","mostRecentMatch","hyperStacks","debugExec","cmdId","expandedFrame","useDebuggerWebsocketEventListener","hyperStackId","debuggerId","getDebugEnvBreakpointsForRunner","getDebugEnvironment","setEnvironmentBreakpoints","existingBreakIndex","finalBreakpoints","hyperStack","toggleBreakpoint","hs","ns","walktype","updateStackFrameObject","applyPackageRenamesToFormSpecs","packageRenames","changedFormCodePaths","refreshedPreviewCodePaths","yamlChanged","renamePackagesInFormSpecs","previousSerializedHtml","addDependency","newDep","dep_id","depId","findDependencyAndIdentifier","dependencyList","propType","originalDep","deleteDependency","depIds","getDependencyOrder","getLogicalDependencyIds","applyPreludeChanges","ensureNoNewerDependencyRuntime","saveBeforeReload","previousDependencyCode","previousDependencyIds","thisApp","ensureNoNewerDeps","makeAfterReload","dependencyPackageRenames","getDependencyPackageRenamesForFormSpecs","dependencyVersionChange","matchingDepIndex","matchingDep","updatePackageName","oldPackageName","getAppDependencies","getDependencyGraph","previousDep","remapDependency","reorderDependencies","fromDep","toDep","toIndex","correctDependencyIds","ldi","hasRoutingDependency","PANEL_SECTIONS","useToolboxPackagesOrganizedByType","toolboxPackages","lib","makeItem","pkgName","itemsOrSections","DesignerRefStore","setRpcObject","tabId","clearRpcObject","useDesignerRpcByTabId","editPath","editPathFrom","editPathTo","preNavigateToEditingForm","maybeInsertFormTabAfter","updateOrCreateHiddenTab","scrollPosition","recordDesignerOutput","output","setDesignerPanelWidth","panelSections","togglePanelSectionExclusive","preExclusiveState","updateExpandedToolboxSections","updateExpandedPropertyGroups","DEFAULT_PANEL_SECTIONS","getDesignerPanelWidth","getDesignerPanelSections","getExpandedToolboxSections","getExpandedPropertyGroups","setJSCustomComponents","layoutMapper","layouts","layoutSpec","jsLayouts","customLayoutForms","yamlLayouts","layoutSpecFromFormStructure","fromDependency","formPackageName","canonicalBuiltinComponentType","unqualifiedType","componentIconType","canonicalType","loadDocs","docs","getBuiltinComponentDoc","componentDocs","instanceDocs","propertyDocs","useDocs","useWatchRuntimeSpec","runtimeSpec","setSpecHash","useGlobalWebsocketEventListener","dynamicDownlinkStates","imageState","watchRuntimeSpec","unwatchRuntimeSpec","getDynamicDownlinkStates","isLegacyAppError","HttpError","appIdParam","allEnvs","leave","toUnblockInvalid","toUnblockUnsaved","eId","lastGood","getEnvironmentById","me","userEnvs","realEnvCount","concat","named","defaultPublishedEnv","getEnvironmentOrigins","migratedEnv","envUpdates","$saveError","$lastGood","$unsaved","$saving","toSave","isLegacyApp","updatesToReapply","savedEnv","isErrorObject","setEnvironmentRestricted","lastEnv","environmentCreations","creationComplete","creations","creation","mergeConfig","isNil","firstEnvWithServerKey","server_keys","resetEnvironmentUplinkKey","useEnvironmentWebsocketEventListener","isKnown","attributeRanges","moduleSources","TUTORIAL_APP","getAbIdeTutorial","getUserHasAchievement","getTutorialAppId","px","tutorialAppId","firstCommitId","useMaybeStartIdeTutorial","flag","tracker","tutorialAppQuery","existingTutorialApp","dispatchIDETutorialModalThenFocusBottomPanelOnQuit","modalIfNotAlreadyOpen","markTutorialStepIfInTutorial","useDetectTutorialModeCode","opts","tutorialStepsDone","isValidComponentPropertyAtPos","debounceRunId","debouncedRun","runId","hits","findTutorialPropertyAssignments","ast","parseAutocompleteModule","encodedLines","byte","encoded","parseModule","normalizePositions","spelling","statement","inEventHandler","nextInHandler","inner","valid","taskPromises","augmentTask","useIdeTaskWebsocketListener","scriptNameFromSessionStart","insertLogEventBySeq","nextModalId","modalPropsCache","LOG_MODALS","modalPromise","why","modals","ModalCancel","getModals","hasModals","deleteAppModal","addOssLicence","licence","licenceText","reloadUserIfOfferRedeemed","upgradeDetails","reloadUser","getPaymentEmail","DarkTheme","LightTheme","stripe","stripePromise","clientSecret","setupIntent","reloadSubscriptionInManagerOrIde","reloadSubscription","chargeItem","initialPlan","isIde","upgradeAttempt","licenceKeyOfNewOrg","paymentMethod","pmError","paymentIntentClientSecret","newLicenceKey","secure","leaveSubscription","loadRecordSchemas","getRecordSchemas","lastClientReplId","nextReplIdx","replaceExistingId","websocket","keepAliveWorker","getRepl","replKeepalive","initialReplState","replState","prevServerReplHistory","initialHistory","historyStart","prevRepls","replOutput","isPaused","outputIsError","thisRepl","lastCmdId","runningCommands","replReturn","outputIndex","updateReplHistory","storeCodeMirrorState","codeMirrorState","maybeWalkChild","walkPaths","attr","getFrameExpandedState","replCommand","replTerminated","replInterrupt","closeRepl","_d","_g","replLocked","destroyRunnerRepls","destroyRepls","includeHistory","serverReplHistory","clearRepl","clearRunnerBgTasks","restartRepl","newTab","oldTab","setPreserveReplLogs","incrementImportTimeTracking","importTime","importTimeTracking","getImportTimeTracking","dismissReplBanner","find","getTableauRepl","getPreserveReplLogs","useReplWebsocketEventListener","stripTaskPrefix","markLiveRunnerBgTasksMissingOutput","handleRunnerBgTaskEvent","applyRunnerBgTaskEvent","runnerConnectionStateChanged","connState","applyRunnerConnectionState","runnerBgTasks","maximiseRunner","newDebugSession","sessionToken","endDebugSession","sessionTokenToKill","getDebugSessionToken","maybeConfigureOrUpgradeOnImportFailure","modname","runtimeAvailable","configuredToCustom","getRunnerSavedInMaximised","getIsRunning","getIsRunningAsInline","addScheduledTask","updateScheduledTask","existingTask","deleteScheduledTask","cleanupBackgroundTasks","lastUpdateTime","removeScheduledTasks","MINUTE","HOUR","DAY","WEEK","MONTH","SUFFIXES","PERIODS","namePeriod","getOrdinalSuffix","relevantDigits","makeValidator","Validate","taskReducer","timeSpec","atSpec","minute","hour","at","when","isPlaceholder","session_id","task_id","sessionScriptName","useScriptWebsocketEventListener","isAppSecretValue","getScopedSecretValue","secretValue","environmentPid","environmentType","appValue","environmentValue","appDefault","agentsCanReadSecret","setScopedSecretValue","encryptedValue","allowAgents","appSecretValue","_default","_all","hasEnvironmentSecretValue","clearEnvironmentSecretValue","environmentValues","hasTestSecretValue","clearTestSecretValue","_test","isServerTestLogEvent","setTaskName","taskName","applyServerTestLogEvent","logs","pruneServerTestLogs","completeSessionIds","maxLength","newTestRunTracker","run_id","applyEventToRun","seqno","test_event","_type","test_id","applyHeldEvents","applyTestRunSnapshot","layerCache","EMPTY_OVERLAY","createServerTestPanelState","DEFAULT_SERVER_TEST_PANEL_STATE","panelState","getLatestServerTestRunTracker","clearedRunIds","getServerTestRunsInOrder","runIds","discovered","getRawServerTestResults","overlay","layerTestRun","baseRow","visibleResults","displayedResults","requestedTargets","activeTargets","requestedIds","activeIds","requestedByClient","waitingForBackend","selectedIds","getWatchedServerTestRunIds","requestedRun","snapshotReadsInFlight","fetchServerTestRunSnapshot","updateServerTestRun","needsSnapshot","serverTestRuns","alertServerTestsFailure","normalizedOptions","testTargets","useServerTestsWebsocketEventListener","test_run_ids","shallowEqual","enabledAppId","watchingRuns","interval","setInterval","clearInterval","applyTestEvent","serverTestSessionLogs","latestState","latestEntry","tabIds","knownServiceTypes","getKnownServiceType","getServicesConfig","loadServiceSpecs","alreadyLoaded","urls","loadAvailableServices","addAvailableService","forceVisible","selectNewService","forceAdd","ss","newService","setConfigToDefaults","config_properties","cp","getConventionalUsersTable","getFileTable","ensureRequiredUsersServiceColsExist","isTestingService","testingTabIds","startupItem","tableau_dashboard","ensureDataTablesServiceIsAdded","tablesServiceToAdd","updateTablesService","currentServiceConfig","columnList","requiredColumns","requiredCol","removeAndSlimObject","setIn","serviceName","usersTableName","appTables","createServiceSelector","getSecretsService","getTestingService","testingService","getHawthornDeploymentService","fileTableName","getService","serviceNameToSource","toggleShowSecondaryNav","sidebar","runningInline","showHideSecondaryNav","inlineNavMode","inlineShow","getTableDataQueryKey","columnSortingKey","useInfiniteQuery","pageParam","cleanTableSortParam","asc","lastPage","keepPreviousData","refetchFirstTableDataPage","getTableauService","maybeOpenOrResetTableauRepl","preserveReplLogs","useTableauWebsocketListener","tableauSessionStart","tableauDebugOutput","navTargetsMatch","navTargetA","navTargetB","tnt","nextTabId","recentlyOpenedTabs","updateOnly","recentlyOpenedIndex","createNewTabAndPushUpdater","dropOldHiddenTabsUpdater","threshold","created","navTargetUpdater","getExistingTab","existingTab","openOrFocusTab","preserveExistingNavTarget","existingTabId","closeOldestTabUpdater","oldestId","activeTabId","tempTabIds","temp","createHiddenFormEditor","updateTabsInView","updateCodeTabView","sum","hasHiddenFormEditor","go","currentTabIdx","newTabIdx","clamp","openTabToLeft","openTabToRight","allTabs","closingTab","getPreviousTabId","prevTab","newTarget","openTab","closeAllTabs","closeOtherTabs","targetTab","getTabService","shouldReloadForAppVersionChange","allCodeItems","closeTabs","getTabById","updatedTab","persistTemporaryTab","weakCache","tabRef","wrapped","availableSpace","cachedView","getCachedView","splitCodeEditorWidth","getSplitCodeEditorRatio","essentialType","currentFocus","essentialViewValue","updateCodeTabTitle","updateTabTitle","updateCodeTabIcon","codeTabPrefs","defaultOpened","recentlyOpened","moveTab","fromTab","maybeToTab","toTab","moveTabWithCodePath","fromCodePath","moveToEnd","openCodePath","adjacentToCodePath","adjacentToTabIndex","openDefaultTabs","hasTabsAlready","showHelpTab","getAbFlag","showStartupItem","TALK_TO_US_BANNER_ARMS","getOfferWindowMs","getBannerArm","forcedDeadline","getDeadline","registrationDate","registeredAt","NaN","deadline","forceOffer","getTalkToUsOfferCandidate","appLoaded","setNow","timer","msRemaining","formatCountdown","placement","bannerVariant","getTalkToUsSchedulingUrl","AGENT_TYPE_IDS","getDefaultAgent","builtInDefault","preferred","editorOption","updatedPrefs","newKeys","apiKeys","reloadUserServerRuntimes","serverRuntimes","startTrial","joinOrgWithLicenseKey","licenseKey","acceptOrgInvite","getUserName","abCache","flagName","setAbArm","ab","achievementName","newStepId","stepId","complete","achievementId","confetti","achievements","chooseAbFlag","ctaKey","getCtaKey","getUserWasShownWelcomeModal","getUserWasShownIntroVideo","aborters","registerAborter","abortPrevious","getEditorType","getIsIde","withoutLoadingIndicator","currentLoadingIndicator","WHERE_TO_START_TUTORIALS_SIGNUP_CUTOFF","TUTORIAL_FOR_ANSWER","override","getUserSignedUpAfterCutoff","getSurveyAnswer","answers","byPrefixAndName","faAnvilLogoSolid","emailsMatch","handleRemoveDeveloper","handleAssignMyUser","isAssigningMyUser","pendingInvitations","isLoadingInvitations","getPendingInvitations","revokeInvitationMutation","revokeDeveloperInvite","previousInvitations","invite","_email","handleRevokeInvitation","inviteDeveloperMutation","inviteDeveloper","handleInviteDeveloper","loading","supportsCollaboration","isNonManagerDev","totalSeats","usedSeats","pendingInvites","canInvite","hasIdeUser","managerAlreadyAssigned","developer","canAssignMyUser","onAddSeats","addSeatsButton","faSort","UserRow","onAddManager","addManager","isAdmin","isCurrentUser","unRemovable","removeManager","NavItem","setCurrentTab","tabsWithoutQuotas","enableAccounting","Organisation","getOrgQuota","NavBar","currentTabContent","Developers","OrgSummary","getTableauInfo","users","usedLicences","totalLicences","unusedLicences","removeTableauUser","onUpdateTableauLicences","enableMobileViewport","viewport","duplicate","NotificationsButton","newNotifications","seenNotifications","setSeenNotifications","pendingNotifications","pySpaceApi","faBell","PySpaceTextInput","forceImageToSizeAndType","blobUrl","imgElt","useMasterEnvironmentOrigin","getCurrentNavTarget","loggerMiddleware","createLogger","logEntry","dispatchOnIdleMiddleware","queuedActions","ON_IDLE","ON_IDLE_CANCEL","eventSystemMiddleware","ON_EVENT","OFF_EVENT","RAISE_EVENT","persistLocalStateMiddleware","persistTimeout","db","indexedDB","persist","persistPaths","persistState","persistObject","tx","previousState","base64EncStr","seenErrors","errorDetail","stateUpdaterMiddleware","_store","timing","producer","restArgs","UPDATE_STATE","baseProducer","LOAD_PREVIOUS_STATE","initStore","rootReducer","createStore","applyMiddleware","thunk","looksLikeTest","faVial","faCircleMinus","faCircleNotch","muted","faCircleStop","lightPalette","Color","darkPalette","Base","Dark","Light","PySpaceLight","PySpaceLightTheme","PySpaceDarkTheme","VIEW_MODES","base64DecToArr","base64EncArr","roots","slash","deferred","formatDiscountDuration","keepBigger","tierScoped","anyTier","isTouchEvent","ANY","CURRENT_DROP_REF","dragStore","useDragStore","onDrag","isDraggingRef","setIsDragging","dragImageRef","generatePreview","useDragImageFactory","previewRefCallback","dragImage","useDragImage","defaultRef","getInheritedBackgroundColor","bgColor","computedStyle","dragRefCallback","useDragRef","onDragStart","onTouchEnd","onTouchMove","onTouchStart","onCleanup","currentDragRef","initX","initY","offsetWidth","offsetHeight","initOffsetX","initOffsetY","cancelDrag","onDragMove","onDragEnd","onDragEndCancel","keyDown","clientX","offsetX","offsetY","elemBelow","prevDropRef","dropElem","DROP_REFS","canDropCb","onOverCb","dropEffect","onHover","setIsOver","setCanDrop","dropItem","onOverChange","monitor","checkCanDrop","currentDropRef","animationFrameRef","baseScrollSpeed","dragY","checkForAutoScroll","clientHeight","scrollHeight","relativeY","scrollAmount","featureId","JSON_HEADER","PARAM_HEADER","searchParams","pickBy","handleResponse","postParams","isJson","getBooleanUserAbFlag","getUserAbFlag","getAbServerTests","getAbMobileIde","Uint8Array","cssify","loadingMime","useValidAssetList","parsedAccept","loadedMime","useLazyMimeTypesModule","mod","any","mimeTypes","extensions","assetMime","EMPTY_ASSETS","getEmptyAssets","useAssets","parseAccept","depAssets","dark","isDarkTheme","fallbackIcon","imgRef","setAttempt","prevSrc","setPrevSrc","onError","onLoad","getThumbnail","faHashtag","faFileVideo","faFileAudio","useThumbnails","useEditSequenceNumbersChanged","currentEditSequenceNumbers","prevEditSequenceNumbers","incSequenceNumber","myPaths","mySequenceNumbersRef","getSequenceNumbers","sequenceNumbers","mySequenceNumbers","useEditSequenceNumbers","prevSeq","setPrevSeq","setMySequenceNumbers","mutateObject","obj1","obj2","useGlobalKeyBindings","cancelOnIdle","openSearchNav","getSelectedText","initialQuery","pageSize","page_size","debounceMs","validDependencyOf","effectivePageSize","debouncedQuery","setDebouncedQuery","queryResult","previousData","wait","fnRef","debounced","debounce","delayMs","initialFlag","delayedValue","setDelayedValue","organisations","getManagerOrganisations","getDevelopers","removeDevMutation","previousDevs","dev","getPermissionsOfAppsSharedByUser","assignMyUserMutation","loadOrganisations","ownsOtherActiveOrg","org","wrappedCallback","currentRef","useThrottleFn","throttled","throttle","timerCallback","timerRef","clear","faAnvilXCircle","lazyLoadIconSet","iconset","IMAGE_MIME_TYPES","ms","faMailBulk","faUserSecret","urlMap","convertToHash","essentialView","newHash","timeoutMs","pollIntervalMs","pointers","pointer","defaultVal","sessionTypeTitle","loadStripe","isFirefox","selectionStart","selectionEnd","THEME_PREFIX","isThemeAsset","getTemplateName","isAnvilProd","importFn","LazyComponent","lazy","LazyFc","Plotly","createPlotlyComponent","pythonVersion","QueryClient","isPlainArray","array","isPlainObject","aItems","aSize","bItems","bSize","copy","equalItems","ObjectProto","proto","SearchHistoryStore","terms","editorSearchHistoryStore","sessionSearchHistoryStore","hasHistory","isFocused","setIsFocused","navigation","navigateHistory","previousTerms","cursor","onRecall","timeAgoString","durationString","durationMs","totalSeconds","agoString","agoStringShort","timeAgo","then","useNowWithRefresh","refreshInterval","dateOptions","expires","stableRef","arguments","onStart","onFinish","wrappedStart","wrappedFinish","wrappedCancel","getLongPressCallbacks","timerId","isLongPressActive","isPressed","ACTIVE_SURVEYS","ALL_ONBOARDING_SURVEYS","hasCompletedOnboardingSurvey","completedSurveys","hasChosenWhereToStart","SEARCH_RESULT_LIMIT","sBase64","nBlocksSize","nChr","nMod3","nMod4","sB64Enc","nInLen","nOutLen","taBytes","nUint24","nOutIdx","nInIdx","b64ToUint6","uint6ToB64","nUint6","aBytes","nLen","nIdx","base64DecToStr","compareNamedSlotDefs","nameA","slotA","nameB","slotB","indexDiff","slotOrderA","slotOrderB","slotOrderDiff"],"mappings":"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"}