Full Code of prostgles/ui for AI

master 90ad3340a3a3 cached
1271 files
5.9 MB
1.6M tokens
2152 symbols
1 requests
Download .txt
Showing preview only (6,507K chars total). Download the full file or copy to clipboard to get everything.
Repository: prostgles/ui
Branch: master
Commit: 90ad3340a3a3
Files: 1271
Total size: 5.9 MB

Directory structure:
gitextract_slssybq4/

├── .dockerignore
├── .eslintrc.common.js
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── BUG.yml
│   │   ├── CUSTOM.yml
│   │   ├── FEATURE.yml
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   ├── custom.md
│   │   └── feature_request.md
│   └── workflows/
│       ├── docker_test.yml
│       ├── electron_build_linux.yml
│       ├── electron_build_macos.yml
│       ├── electron_build_windows.yml
│       ├── electron_linux_test.yml
│       ├── electron_macos_test.yml
│       ├── linux_test.yml
│       ├── macos_test.yml
│       ├── on_release.yml
│       ├── package_version_increased.yml
│       └── windows_test.yml
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .vscode/
│   └── settings.json
├── DB-Dockerfile
├── Dockerfile
├── LICENSE
├── PRIVACY
├── README.md
├── SECURITY.md
├── changelog/
│   ├── v1.0.0.md
│   ├── v2.0.0.md
│   ├── v2.2.0.md
│   ├── v2.2.1.md
│   ├── v2.2.2.md
│   ├── v2.2.3.md
│   └── v2.2.4.md
├── client/
│   ├── .babelrc
│   ├── .gitignore
│   ├── build.sh
│   ├── eslint.config.mjs
│   ├── package.json
│   ├── public/
│   │   ├── manifest.json
│   │   └── robots.txt
│   ├── setup-icons.js
│   ├── src/
│   │   ├── App.css
│   │   ├── App.tsx
│   │   ├── Testing.ts
│   │   ├── WithPrgl.tsx
│   │   ├── app/
│   │   │   ├── CommandPalette/
│   │   │   │   ├── CommandPalette.css
│   │   │   │   ├── CommandPalette.tsx
│   │   │   │   ├── Documentation.css
│   │   │   │   ├── Documentation.tsx
│   │   │   │   ├── getDocumentation.ts
│   │   │   │   ├── getUIDocShortestPath.ts
│   │   │   │   ├── useGoToUI.tsx
│   │   │   │   ├── useHighlightDocItem.ts
│   │   │   │   └── utils.ts
│   │   │   ├── UIDocs/
│   │   │   │   ├── UIInstallationUIDoc.ts
│   │   │   │   ├── accountUIDoc.ts
│   │   │   │   ├── commandPaletteUIDoc.ts
│   │   │   │   ├── connection/
│   │   │   │   │   ├── AIAssistantUIDoc.ts
│   │   │   │   │   ├── config/
│   │   │   │   │   │   ├── accessControlUIDoc.ts
│   │   │   │   │   │   ├── apiUIDoc.ts
│   │   │   │   │   │   ├── backupAndRestoreUIDoc.ts
│   │   │   │   │   │   └── fileStorageUIDoc.ts
│   │   │   │   │   ├── connectionConfigUIDoc.ts
│   │   │   │   │   ├── dashboard/
│   │   │   │   │   │   ├── dashboardContentUIDoc.ts
│   │   │   │   │   │   ├── dashboardMenuUIDoc.ts
│   │   │   │   │   │   ├── mapUIDoc.ts
│   │   │   │   │   │   ├── serverSideFunctionUIDoc.ts
│   │   │   │   │   │   ├── sqlEditorUIDoc.ts
│   │   │   │   │   │   ├── table/
│   │   │   │   │   │   │   ├── addColumnMenuUIDoc.ts
│   │   │   │   │   │   │   ├── columnMenuUIDoc.ts
│   │   │   │   │   │   │   ├── paginationUIDoc.ts
│   │   │   │   │   │   │   ├── smartFilterBarUIDoc.ts
│   │   │   │   │   │   │   ├── smartFormUIDoc.ts
│   │   │   │   │   │   │   ├── tableMenuUIDoc.ts
│   │   │   │   │   │   │   └── tableUIDoc.ts
│   │   │   │   │   │   └── timechartUIDoc.ts
│   │   │   │   │   ├── dashboardUIDoc.ts
│   │   │   │   │   └── getCommonViewHeaderUIDoc.ts
│   │   │   │   ├── connectionsUIDoc.ts
│   │   │   │   ├── desktopInstallation.ts
│   │   │   │   ├── editConnectionUIDoc.ts
│   │   │   │   ├── navbarUIDoc.ts
│   │   │   │   ├── overviewUIDoc.ts
│   │   │   │   └── serverSettingsUIDoc.ts
│   │   │   ├── UIDocs.ts
│   │   │   ├── XRealIpSpoofableAlert.tsx
│   │   │   └── domToSVG/
│   │   │       ├── SVGif/
│   │   │       │   ├── addSVGifCaption.ts
│   │   │       │   ├── addSVGifPointer.ts
│   │   │       │   ├── addSVGifTimelineControls.ts
│   │   │       │   ├── animations/
│   │   │       │   │   ├── getSVGifCursorAnimationHandler.ts
│   │   │       │   │   ├── getSVGifTypeAnimation.ts
│   │   │       │   │   └── getSVGifZoomToAnimation.ts
│   │   │       │   ├── compressSVGif.ts
│   │   │       │   ├── getSVGif.ts
│   │   │       │   ├── getSVGifAnimations.ts
│   │   │       │   ├── getSVGifParsedScenes.ts
│   │   │       │   ├── getSVGifRevealKeyframes.ts
│   │   │       │   └── getSVGifTargetBBox.ts
│   │   │       ├── addFragmentViewBoxes.ts
│   │   │       ├── containers/
│   │   │       │   ├── addOverflowClipPath.ts
│   │   │       │   ├── bgAndBorderToSVG.ts
│   │   │       │   ├── deduplicateSVGPaths.ts
│   │   │       │   ├── elementToSVG.ts
│   │   │       │   ├── rectangleToSVG.ts
│   │   │       │   └── shadowToSVG.ts
│   │   │       ├── domToSVG.ts
│   │   │       ├── domToThemeAwareSVG.ts
│   │   │       ├── getCorrespondingDarkNode.ts
│   │   │       ├── graphics/
│   │   │       │   ├── fontIconToSVG.ts
│   │   │       │   ├── getForeignObject.ts
│   │   │       │   └── imgToSVG.ts
│   │   │       ├── recordDomChanges.ts
│   │   │       ├── setThemeForSVGScreenshot.ts
│   │   │       ├── text/
│   │   │       │   ├── getTextForSVG.ts
│   │   │       │   └── textToSVG.ts
│   │   │       └── utils/
│   │   │           ├── addNewChildren.ts
│   │   │           ├── canvasToDataURL.ts
│   │   │           ├── copyAnimationStylesToSvg.ts
│   │   │           ├── getWhatToRenderOnSVG.ts
│   │   │           ├── isElementVisible.ts
│   │   │           └── toFixed.ts
│   │   ├── appUtils.ts
│   │   ├── components/
│   │   │   ├── AlertProvider.tsx
│   │   │   ├── Animations.css
│   │   │   ├── Animations.tsx
│   │   │   ├── Btn.css
│   │   │   ├── Btn.tsx
│   │   │   ├── ButtonBar.tsx
│   │   │   ├── ButtonGroup.tsx
│   │   │   ├── Chat/
│   │   │   │   ├── Chat.css
│   │   │   │   ├── Chat.tsx
│   │   │   │   ├── ChatFileAttachments/
│   │   │   │   │   └── ChatFileAttachments.tsx
│   │   │   │   ├── ChatMessage.tsx
│   │   │   │   ├── ChatSendControls.tsx
│   │   │   │   ├── ChatSpeech/
│   │   │   │   │   ├── ChatSpeech.tsx
│   │   │   │   │   ├── ChatSpeechSetup.tsx
│   │   │   │   │   ├── hooks/
│   │   │   │   │   │   ├── SpeechRecorder.ts
│   │   │   │   │   │   ├── renderSpeechAudioLevelsIcon.ts
│   │   │   │   │   │   ├── useSpeechRecorder.ts
│   │   │   │   │   │   └── useSpeechToTextWeb.ts
│   │   │   │   │   └── useChatSpeechSetup.ts
│   │   │   │   ├── Marked.css
│   │   │   │   ├── Marked.tsx
│   │   │   │   ├── MonacoCodeInMarkdown/
│   │   │   │   │   ├── MarkdownMonacoCodeHeader.tsx
│   │   │   │   │   ├── MonacoCodeInMarkdown.tsx
│   │   │   │   │   └── useOnRunSQL.ts
│   │   │   │   ├── useChatOnPaste.ts
│   │   │   │   └── useChatState.ts
│   │   │   ├── Checkbox.css
│   │   │   ├── Checkbox.tsx
│   │   │   ├── Chip.css
│   │   │   ├── Chip.tsx
│   │   │   ├── ClickCatch.tsx
│   │   │   ├── ClickCatchOverlay.css
│   │   │   ├── ClickCatchOverlay.tsx
│   │   │   ├── ConfirmationDialog.tsx
│   │   │   ├── CopyToClipboardBtn.tsx
│   │   │   ├── DragOverUpload/
│   │   │   │   ├── DragOverUpload.css
│   │   │   │   └── DragOverUpload.tsx
│   │   │   ├── DraggableLI.tsx
│   │   │   ├── ErrorComponent.tsx
│   │   │   ├── ExpandSection.tsx
│   │   │   ├── Expander.tsx
│   │   │   ├── FileBrowser/
│   │   │   │   ├── FileBrowser.tsx
│   │   │   │   └── FileBrowserCurrentDirectory.tsx
│   │   │   ├── FileInput/
│   │   │   │   ├── DropZone.tsx
│   │   │   │   ├── FileInput.tsx
│   │   │   │   ├── FileInputMedia.tsx
│   │   │   │   └── useFileDropZone.ts
│   │   │   ├── FlashMessage.tsx
│   │   │   ├── Flex.tsx
│   │   │   ├── FormField/
│   │   │   │   ├── FormField.css
│   │   │   │   ├── FormField.tsx
│   │   │   │   ├── FormFieldCodeEditor.tsx
│   │   │   │   ├── FormFieldDebounced.tsx
│   │   │   │   ├── FormFieldSkeleton.tsx
│   │   │   │   └── onFormFieldKeyDown.ts
│   │   │   ├── Hotkey.css
│   │   │   ├── Hotkey.tsx
│   │   │   ├── Icon/
│   │   │   │   └── Icon.tsx
│   │   │   ├── IconPalette/
│   │   │   │   └── IconPalette.tsx
│   │   │   ├── InfoRow.tsx
│   │   │   ├── Input.tsx
│   │   │   ├── JSONBSchema/
│   │   │   │   ├── JSONBSchema.tsx
│   │   │   │   ├── JSONBSchemaAllowedOptions.tsx
│   │   │   │   ├── JSONBSchemaArray.tsx
│   │   │   │   ├── JSONBSchemaLookup.tsx
│   │   │   │   ├── JSONBSchemaObject.tsx
│   │   │   │   ├── JSONBSchemaOneOfType.tsx
│   │   │   │   ├── JSONBSchemaPrimitive.tsx
│   │   │   │   ├── JSONBSchemaRecord.tsx
│   │   │   │   └── isCompleteJSONB.ts
│   │   │   ├── JsonRenderer.tsx
│   │   │   ├── Label.css
│   │   │   ├── Label.tsx
│   │   │   ├── LabeledRow.tsx
│   │   │   ├── List.css
│   │   │   ├── List.tsx
│   │   │   ├── Loader/
│   │   │   │   ├── Loading.css
│   │   │   │   ├── Loading.tsx
│   │   │   │   ├── SpinnerV2.tsx
│   │   │   │   ├── SpinnerV3.tsx
│   │   │   │   └── SpinnerV4.tsx
│   │   │   ├── MediaViewer/
│   │   │   │   ├── MediaViewer.tsx
│   │   │   │   └── RenderMedia.tsx
│   │   │   ├── MenuList.css
│   │   │   ├── MenuList.tsx
│   │   │   ├── MenuListItem.tsx
│   │   │   ├── MonacoEditor/
│   │   │   │   ├── MonacoEditor.tsx
│   │   │   │   ├── useMonacoEditorAddActions.ts
│   │   │   │   └── useWhyDidYouUpdate.ts
│   │   │   ├── MonacoLogRenderer/
│   │   │   │   └── MonacoLogRenderer.tsx
│   │   │   ├── NavBar/
│   │   │   │   ├── NavBar.css
│   │   │   │   ├── NavBar.tsx
│   │   │   │   ├── NavBarWrapper.tsx
│   │   │   │   └── useNavBarItems.ts
│   │   │   ├── Pan.tsx
│   │   │   ├── Popup/
│   │   │   │   ├── Footer.tsx
│   │   │   │   ├── FooterButtons.tsx
│   │   │   │   ├── Popup.css
│   │   │   │   ├── Popup.tsx
│   │   │   │   ├── PopupHeader.tsx
│   │   │   │   ├── getPopupPosition.ts
│   │   │   │   ├── getPopupStyle.ts
│   │   │   │   └── popupCheckPosition.ts
│   │   │   ├── PopupMenu.tsx
│   │   │   ├── PopupMenuList.tsx
│   │   │   ├── PostgresInstallationInstructions.tsx
│   │   │   ├── ProgressBar.css
│   │   │   ├── ProgressBar.tsx
│   │   │   ├── QRCodeImage.tsx
│   │   │   ├── Scheduler.css
│   │   │   ├── Scheduler.tsx
│   │   │   ├── ScrollFade/
│   │   │   │   ├── ScrollFade.tsx
│   │   │   │   └── useResizeObserver.ts
│   │   │   ├── SearchList/
│   │   │   │   ├── SearchInput.tsx
│   │   │   │   ├── SearchList.css
│   │   │   │   ├── SearchList.tsx
│   │   │   │   ├── SearchListContent.tsx
│   │   │   │   ├── SearchListItems.tsx
│   │   │   │   ├── SearchListRowContent.tsx
│   │   │   │   ├── getSearchListMatchAndHighlight.tsx
│   │   │   │   ├── hooks/
│   │   │   │   │   ├── useSearchListItems.tsx
│   │   │   │   │   ├── useSearchListItemsSorting.ts
│   │   │   │   │   ├── useSearchListOnClick.ts
│   │   │   │   │   ├── useSearchListOnKeyUpDown.ts
│   │   │   │   │   └── useSearchListSearch.ts
│   │   │   │   └── searchMatchUtils/
│   │   │   │       ├── getItemSearchRank.ts
│   │   │   │       └── getSearchRanking.ts
│   │   │   ├── Section.tsx
│   │   │   ├── Select/
│   │   │   │   ├── Select.css
│   │   │   │   ├── Select.tsx
│   │   │   │   └── SelectTriggerButton.tsx
│   │   │   ├── ShorterText.tsx
│   │   │   ├── SidePanel.tsx
│   │   │   ├── Slider.css
│   │   │   ├── Slider.tsx
│   │   │   ├── StatusChip.tsx
│   │   │   ├── Stepper.tsx
│   │   │   ├── SvgIcon.tsx
│   │   │   ├── SwitchToggle.css
│   │   │   ├── SwitchToggle.tsx
│   │   │   ├── Table/
│   │   │   │   ├── Pagination.tsx
│   │   │   │   ├── Table.css
│   │   │   │   ├── Table.tsx
│   │   │   │   ├── TableBody.tsx
│   │   │   │   ├── TableHeader.tsx
│   │   │   │   ├── TableRow.tsx
│   │   │   │   └── useVirtualisedRows.ts
│   │   │   ├── Tabs.tsx
│   │   │   └── Tooltip.tsx
│   │   ├── dashboard/
│   │   │   ├── API/
│   │   │   │   └── zip.ts
│   │   │   ├── AccessControl/
│   │   │   │   ├── AccessControl.tsx
│   │   │   │   ├── AccessControlRuleEditor.tsx
│   │   │   │   ├── AccessRuleEditorFooter.tsx
│   │   │   │   ├── AccessRuleSummary.tsx
│   │   │   │   ├── ContextDataSelector.tsx
│   │   │   │   ├── ContextFilter.tsx
│   │   │   │   ├── ExistingAccessRules.tsx
│   │   │   │   ├── Methods/
│   │   │   │   │   ├── ArgumentDefinition.tsx
│   │   │   │   │   ├── MethodDefinition.tsx
│   │   │   │   │   ├── MethodDefinitionEditAsJson.tsx
│   │   │   │   │   ├── MethodFunctionDefinition.tsx
│   │   │   │   │   ├── ReferencesDefinition.tsx
│   │   │   │   │   └── useCodeEditorTsTypes.ts
│   │   │   │   ├── OptionControllers/
│   │   │   │   │   ├── DynamicFields.tsx
│   │   │   │   │   ├── FieldFilterControl.tsx
│   │   │   │   │   └── FilterControl.tsx
│   │   │   │   ├── PasswordlessSetup.tsx
│   │   │   │   ├── PermissionTypes/
│   │   │   │   │   ├── PAllTables.tsx
│   │   │   │   │   ├── PCustomTables.tsx
│   │   │   │   │   └── PRunSQL.tsx
│   │   │   │   ├── PublishedWorkspaceSelector.tsx
│   │   │   │   ├── RuleTypeControls/
│   │   │   │   │   ├── ComparablePGPolicies.tsx
│   │   │   │   │   ├── DeleteRuleControl.tsx
│   │   │   │   │   ├── ExampleComparablePolicy.tsx
│   │   │   │   │   ├── InsertRuleControl.tsx
│   │   │   │   │   ├── RuleToggle.tsx
│   │   │   │   │   ├── SelectRuleControl.tsx
│   │   │   │   │   ├── SyncRuleControl.tsx
│   │   │   │   │   ├── UpdateRuleControl.tsx
│   │   │   │   │   └── getComparablePGPolicy.ts
│   │   │   │   ├── TableRules/
│   │   │   │   │   ├── FileTableAccessControlInfo.tsx
│   │   │   │   │   ├── TablePermissionControls.tsx
│   │   │   │   │   ├── TableRulesPopup.tsx
│   │   │   │   │   └── useLocalTableRulesErrors.ts
│   │   │   │   ├── UserStats.tsx
│   │   │   │   ├── UserSyncConfig.tsx
│   │   │   │   ├── UserTypeSelect.tsx
│   │   │   │   ├── useAccessControlSearchParams.ts
│   │   │   │   └── useEditedAccessRule.ts
│   │   │   ├── AskLLM/
│   │   │   │   ├── AskLLM.tsx
│   │   │   │   ├── Chat/
│   │   │   │   │   ├── AskLLMChat.tsx
│   │   │   │   │   ├── AskLLMChatHeader.tsx
│   │   │   │   │   ├── AskLLMChatMessages/
│   │   │   │   │   │   ├── LLMChatMessage/
│   │   │   │   │   │   │   ├── LLMChatMessage.tsx
│   │   │   │   │   │   │   ├── LLMChatMessageContent.tsx
│   │   │   │   │   │   │   ├── LLMChatMessageContentText.tsx
│   │   │   │   │   │   │   ├── LLMChatMessageHeader.tsx
│   │   │   │   │   │   │   ├── LLMGroupedToolCallsMessage.tsx
│   │   │   │   │   │   │   └── LLMSingleChatMessage.tsx
│   │   │   │   │   │   ├── ProstglesToolUseMessage/
│   │   │   │   │   │   │   ├── ProstglesMCPTools/
│   │   │   │   │   │   │   │   ├── DockerSandboxCreateContainer.tsx
│   │   │   │   │   │   │   │   ├── ExecuteSQL.tsx
│   │   │   │   │   │   │   │   ├── LoadSuggestedDashboards.tsx
│   │   │   │   │   │   │   │   ├── LoadSuggestedToolsAndPrompt/
│   │   │   │   │   │   │   │   │   ├── LoadSuggestedToolsAndPrompt.tsx
│   │   │   │   │   │   │   │   │   └── LoadSuggestedToolsAndPromptLoadBtn.tsx
│   │   │   │   │   │   │   │   ├── LoadSuggestedWorkflow.tsx
│   │   │   │   │   │   │   │   ├── WebSearch/
│   │   │   │   │   │   │   │   │   ├── Favicon.tsx
│   │   │   │   │   │   │   │   │   └── WebSearch.tsx
│   │   │   │   │   │   │   │   └── common/
│   │   │   │   │   │   │   │       ├── DatabaseAccessPermissions.tsx
│   │   │   │   │   │   │   │       ├── HeaderList.tsx
│   │   │   │   │   │   │   │       └── useTypedToolUseResultData.ts
│   │   │   │   │   │   │   └── ProstglesToolUseMessage.tsx
│   │   │   │   │   │   ├── ToolUseChatMessage/
│   │   │   │   │   │   │   ├── PopupSection.tsx
│   │   │   │   │   │   │   ├── ToolUseChatMessage.tsx
│   │   │   │   │   │   │   ├── ToolUseChatMessageBtn.tsx
│   │   │   │   │   │   │   ├── ToolUseChatMessageBtnTextSummary.tsx
│   │   │   │   │   │   │   ├── ToolUseChatMessageJSONData.tsx
│   │   │   │   │   │   │   ├── ToolUseChatMessageResult.tsx
│   │   │   │   │   │   │   ├── useToolUseChatMessage.ts
│   │   │   │   │   │   │   └── utils/
│   │   │   │   │   │   │       └── getToolUseResult.ts
│   │   │   │   │   │   └── hooks/
│   │   │   │   │   │       ├── useLLMChatMessageGrouper.tsx
│   │   │   │   │   │       └── useLLMChatMessages.tsx
│   │   │   │   │   ├── AskLLMChatOptions.tsx
│   │   │   │   │   ├── useAskLLMChatSend.ts
│   │   │   │   │   ├── useLLMChat.tsx
│   │   │   │   │   └── useLLMSchemaStr.ts
│   │   │   │   ├── ChatActionBar/
│   │   │   │   │   ├── AskLLMChatActionBar.tsx
│   │   │   │   │   ├── AskLLMChatActionBarDatabaseAccess.tsx
│   │   │   │   │   ├── AskLLMChatActionBarMCPTools.tsx
│   │   │   │   │   ├── AskLLMChatActionBarMCPToolsBtn.tsx
│   │   │   │   │   ├── AskLLMChatActionBarModelSelector.tsx
│   │   │   │   │   └── AskLLMChatActionBarPromptSelector.tsx
│   │   │   │   ├── Setup/
│   │   │   │   │   ├── AddLLMPromptForm.tsx
│   │   │   │   │   ├── AskLLMAccessControl.tsx
│   │   │   │   │   ├── LLMProviderSetup.tsx
│   │   │   │   │   ├── ProstglesSignup.tsx
│   │   │   │   │   ├── SetupLLMCredentials.tsx
│   │   │   │   │   └── useLLMSetupState.ts
│   │   │   │   ├── Tools/
│   │   │   │   │   ├── AskLLMToolApprover.tsx
│   │   │   │   │   ├── loadGeneratedWorkspaces/
│   │   │   │   │   │   ├── loadGeneratedBarchart.ts
│   │   │   │   │   │   ├── loadGeneratedMap.ts
│   │   │   │   │   │   ├── loadGeneratedTimechart.ts
│   │   │   │   │   │   └── loadGeneratedWorkspaces.ts
│   │   │   │   │   └── useLLMToolsApprover.tsx
│   │   │   │   └── useLocalLLM.ts
│   │   │   ├── BackupAndRestore/
│   │   │   │   ├── AutomaticBackups.tsx
│   │   │   │   ├── BackupsControls.tsx
│   │   │   │   ├── BackupsInProgress.tsx
│   │   │   │   ├── CloudStorageCredentialSelector.tsx
│   │   │   │   ├── CodeConfirmation.tsx
│   │   │   │   ├── CompletedBackups.tsx
│   │   │   │   ├── DumpLocationOptions.tsx
│   │   │   │   ├── DumpRestoreAlerts.tsx
│   │   │   │   ├── PGDumpOptions.tsx
│   │   │   │   ├── RenderBackupLogs.tsx
│   │   │   │   ├── RenderBackupStatus.tsx
│   │   │   │   ├── Restore/
│   │   │   │   │   ├── Restore.tsx
│   │   │   │   │   └── RestoreOptions.tsx
│   │   │   │   └── useBackupsControlsState.ts
│   │   │   ├── Charts/
│   │   │   │   ├── CanvasChart.ts
│   │   │   │   ├── TimeChart/
│   │   │   │   │   ├── TimeChart.tsx
│   │   │   │   │   ├── getBinValueLabels.ts
│   │   │   │   │   ├── getTimeAxisTicks.ts
│   │   │   │   │   ├── getTimechartBinSize.ts
│   │   │   │   │   ├── getTimechartTooltipIntersections.ts
│   │   │   │   │   ├── getTimechartTooltipShapes.ts
│   │   │   │   │   ├── measureText.ts
│   │   │   │   │   ├── onDeltaTimechart.ts
│   │   │   │   │   ├── onRenderTimechart.ts
│   │   │   │   │   └── prepareTimechartData.ts
│   │   │   │   ├── createHiPPICanvas.ts
│   │   │   │   ├── drawMonotoneXCurve.ts
│   │   │   │   ├── drawShapes/
│   │   │   │   │   ├── drawLinkLine.ts
│   │   │   │   │   ├── drawShapes.ts
│   │   │   │   │   ├── drawShapesOnSVG.ts
│   │   │   │   │   ├── findShortestPathAroundRectangles.ts
│   │   │   │   │   ├── getTimechartGradientPeakSections.ts
│   │   │   │   │   └── shortestLinkLineV2.ts
│   │   │   │   └── roundRect.ts
│   │   │   ├── Charts.tsx
│   │   │   ├── CodeEditor/
│   │   │   │   ├── CodeEditor.tsx
│   │   │   │   ├── CodeEditorWithSaveButton.tsx
│   │   │   │   ├── monacoTsLibs.ts
│   │   │   │   ├── registerLogLang.ts
│   │   │   │   └── utils/
│   │   │   │       ├── getMonacoJsonSchemas.ts
│   │   │   │       ├── setMonacoErrorMarkers.ts
│   │   │   │       ├── useSetMonacoJsonSchemas.ts
│   │   │   │       └── useSetMonacoTsLibraries.ts
│   │   │   ├── CodeExample.tsx
│   │   │   ├── ConnectionConfig/
│   │   │   │   ├── APIDetails/
│   │   │   │   │   ├── APICodeExamples.tsx
│   │   │   │   │   ├── APIDetails.tsx
│   │   │   │   │   ├── APIDetailsHttp.tsx
│   │   │   │   │   ├── APIDetailsTokens.tsx
│   │   │   │   │   ├── APIDetailsWs.tsx
│   │   │   │   │   └── AllowedOriginCheck.tsx
│   │   │   │   ├── ConnectionConfig.tsx
│   │   │   │   ├── ServerSideFunctions.tsx
│   │   │   │   └── useConnectionConfigSearchParams.ts
│   │   │   ├── ConnectionSelector.tsx
│   │   │   ├── Dashboard/
│   │   │   │   ├── CloseSaveSQLPopup.tsx
│   │   │   │   ├── DBS.ts
│   │   │   │   ├── Dashboard.tsx
│   │   │   │   ├── DashboardCenteredLayoutResizer.tsx
│   │   │   │   ├── PALETTE.ts
│   │   │   │   ├── ViewRenderer.tsx
│   │   │   │   ├── cloneWorkspace.ts
│   │   │   │   ├── dashboardUtils.ts
│   │   │   │   ├── debuggingUtils.ts
│   │   │   │   ├── getTables.ts
│   │   │   │   ├── getViewRendererUtils.ts
│   │   │   │   └── loadTable.ts
│   │   │   ├── DashboardMenu/
│   │   │   │   ├── CreateTable.tsx
│   │   │   │   ├── DashboardHotkeys.tsx
│   │   │   │   ├── DashboardMenu.tsx
│   │   │   │   ├── DashboardMenuContent.tsx
│   │   │   │   ├── DashboardMenuHeader.tsx
│   │   │   │   ├── DashboardMenuHotkeys.tsx
│   │   │   │   ├── DashboardMenuResizer.tsx
│   │   │   │   ├── DashboardMenuSettings.tsx
│   │   │   │   ├── NewTableMenu.tsx
│   │   │   │   ├── SettingsSection.tsx
│   │   │   │   └── useTableSizeInfo.ts
│   │   │   ├── DetailedFilterControl/
│   │   │   │   ├── DetailedFilterBaseControl.tsx
│   │   │   │   ├── DetailedFilterBaseControlRouter.tsx
│   │   │   │   ├── DetailedFilterBaseTypes/
│   │   │   │   │   ├── AgeFilter.tsx
│   │   │   │   │   ├── GeoFilter.tsx
│   │   │   │   │   ├── ListFilter/
│   │   │   │   │   │   ├── ListFilter.tsx
│   │   │   │   │   │   └── fetchListFilterOptions.ts
│   │   │   │   │   └── NumberOrDateFilter.tsx
│   │   │   │   ├── DetailedFilterControl.tsx
│   │   │   │   ├── FTS_LANGUAGES.ts
│   │   │   │   ├── FilterWrapper.css
│   │   │   │   ├── FilterWrapper.tsx
│   │   │   │   └── validateFilter.ts
│   │   │   ├── Feedback.tsx
│   │   │   ├── FileImporter/
│   │   │   │   ├── FileImporter.tsx
│   │   │   │   ├── FileImporterFooter.tsx
│   │   │   │   ├── checkCSVColumnDataTypes.tsx
│   │   │   │   ├── importFile.ts
│   │   │   │   ├── parseCSVFile.ts
│   │   │   │   └── setFile.ts
│   │   │   ├── FileTableControls/
│   │   │   │   ├── CreateFileColumn.tsx
│   │   │   │   ├── FileColumnConfigControls.tsx
│   │   │   │   ├── FileColumnConfigEditor.tsx
│   │   │   │   ├── FileStorageControls.tsx
│   │   │   │   ├── FileStorageDelete.tsx
│   │   │   │   ├── FileStorageReferencedTablesConfig.tsx
│   │   │   │   ├── FileTableConfigControls.tsx
│   │   │   │   └── useFileTableConfigControls.ts
│   │   │   ├── JSONBColumnEditor.tsx
│   │   │   ├── LinkMenu.tsx
│   │   │   ├── Map/
│   │   │   │   ├── DeckGLFeatureEditor.tsx
│   │   │   │   ├── DeckGLMap.css
│   │   │   │   ├── DeckGLMap.tsx
│   │   │   │   ├── DeckGLWrapped.ts
│   │   │   │   ├── InMapControls.tsx
│   │   │   │   ├── fitBounds.ts
│   │   │   │   ├── mapDrawUtils.ts
│   │   │   │   └── mapUtils.ts
│   │   │   ├── RTComp.tsx
│   │   │   ├── RenderFilter.tsx
│   │   │   ├── SQLEditor/
│   │   │   │   ├── SQLCompletion/
│   │   │   │   │   ├── CommonMatchImports.ts
│   │   │   │   │   ├── KEYWORDS.ts
│   │   │   │   │   ├── MacthCreate/
│   │   │   │   │   │   ├── MatchCreate.ts
│   │   │   │   │   │   ├── MatchCreateView.ts
│   │   │   │   │   │   ├── matchCreateIndex.ts
│   │   │   │   │   │   ├── matchCreatePolicy.ts
│   │   │   │   │   │   ├── matchCreateRule.tsx
│   │   │   │   │   │   ├── matchCreateTable.ts
│   │   │   │   │   │   └── matchCreateTrigger.ts
│   │   │   │   │   ├── MatchAlter/
│   │   │   │   │   │   ├── MatchAlter.tsx
│   │   │   │   │   │   ├── matchAlterPolicy.ts
│   │   │   │   │   │   ├── matchAlterTable.ts
│   │   │   │   │   │   └── matchCreateOrAlterUser.tsx
│   │   │   │   │   ├── MatchComment.ts
│   │   │   │   │   ├── MatchCopy.ts
│   │   │   │   │   ├── MatchDrop.ts
│   │   │   │   │   ├── MatchFirst.ts
│   │   │   │   │   ├── MatchGrant.ts
│   │   │   │   │   ├── MatchInsert.tsx
│   │   │   │   │   ├── MatchLast.ts
│   │   │   │   │   ├── MatchPublication.ts
│   │   │   │   │   ├── MatchReassign.ts
│   │   │   │   │   ├── MatchReindex.ts
│   │   │   │   │   ├── MatchSelect.ts
│   │   │   │   │   ├── MatchSet.ts
│   │   │   │   │   ├── MatchSubscription.ts
│   │   │   │   │   ├── MatchUpdate.ts
│   │   │   │   │   ├── MatchVacuum.ts
│   │   │   │   │   ├── MatchWith.ts
│   │   │   │   │   ├── MathDelete.ts
│   │   │   │   │   ├── PSQL.ts
│   │   │   │   │   ├── STARTING_KEYWORDS.ts
│   │   │   │   │   ├── TableKWDs.ts
│   │   │   │   │   ├── completionUtils/
│   │   │   │   │   │   ├── checkIfInsideDollarFunctionDefinition.ts
│   │   │   │   │   │   ├── checkIfUnfinishedParenthesis.ts
│   │   │   │   │   │   ├── getCodeBlock.ts
│   │   │   │   │   │   ├── getQueryReturnType.ts
│   │   │   │   │   │   ├── getTableExpressionReturnTypes.ts
│   │   │   │   │   │   ├── getTabularExpressions.ts
│   │   │   │   │   │   └── getTokens.ts
│   │   │   │   │   ├── getExpected.ts
│   │   │   │   │   ├── getJoinSuggestions.ts
│   │   │   │   │   ├── getMatch.ts
│   │   │   │   │   ├── getPGObjects.ts
│   │   │   │   │   ├── getPrevTokensNoParantheses.ts
│   │   │   │   │   ├── jsonbPathSuggest.ts
│   │   │   │   │   ├── monacoSQLSetup/
│   │   │   │   │   │   ├── registerHover.ts
│   │   │   │   │   │   └── registerSuggestions.ts
│   │   │   │   │   ├── suggestColumnLike.ts
│   │   │   │   │   ├── suggestCondition.ts
│   │   │   │   │   ├── suggestFuncArgs.ts
│   │   │   │   │   ├── suggestTableLike.ts
│   │   │   │   │   ├── suggestValue.ts
│   │   │   │   │   └── withKWDs.ts
│   │   │   │   ├── SQLEditorSuggestions.ts
│   │   │   │   ├── SQLSmartEditor.tsx
│   │   │   │   ├── SQL_SNIPPETS.ts
│   │   │   │   ├── W_SQLEditor.css
│   │   │   │   ├── W_SQLEditor.tsx
│   │   │   │   ├── addSqlEditorFunctions.ts
│   │   │   │   ├── defineCustomMonacoSQLTheme.ts
│   │   │   │   ├── getFormattedSql.ts
│   │   │   │   ├── registerFunctionSuggestions.ts
│   │   │   │   └── utils/
│   │   │   │       ├── scrollToLineIfNeeded.ts
│   │   │   │       └── setMonacEditorError.ts
│   │   │   ├── SampleSchemas.tsx
│   │   │   ├── SchemaGraph/
│   │   │   │   ├── ERDSchema/
│   │   │   │   │   ├── ERDSchema.tsx
│   │   │   │   │   ├── getInitialPlacement.ts
│   │   │   │   │   ├── useCanvasPanZoom.ts
│   │   │   │   │   ├── useDrawSchemaShapes.ts
│   │   │   │   │   ├── useFetchSchemaForDiagram.ts
│   │   │   │   │   ├── usePanShapes.ts
│   │   │   │   │   └── useSchemaShapes.ts
│   │   │   │   ├── SchemaGraph.tsx
│   │   │   │   ├── SchemaGraphControls.tsx
│   │   │   │   └── types.ts
│   │   │   ├── SearchAll/
│   │   │   │   ├── SearchAll.tsx
│   │   │   │   ├── SearchAllContent.tsx
│   │   │   │   ├── SearchAllHeader.tsx
│   │   │   │   ├── SearchMatchRow.tsx
│   │   │   │   └── hooks/
│   │   │   │       ├── useSearchAllState.ts
│   │   │   │       ├── useSearchListProps.tsx
│   │   │   │       ├── useSearchTables.tsx
│   │   │   │       └── useTablesAndViewsSearchItems.ts
│   │   │   ├── SilverGrid/
│   │   │   │   ├── SilverGrid.tsx
│   │   │   │   ├── SilverGridChild.tsx
│   │   │   │   ├── SilverGridChildHeader.tsx
│   │   │   │   ├── SilverGridResizer.tsx
│   │   │   │   └── TreeBuilder.ts
│   │   │   ├── SmartCard/
│   │   │   │   ├── SmartCard.tsx
│   │   │   │   ├── SmartCardActions.tsx
│   │   │   │   ├── SmartCardColumn.tsx
│   │   │   │   ├── getSelectForFieldConfigs.ts
│   │   │   │   ├── getSmartCardColumns.ts
│   │   │   │   ├── parseFieldConfigs.tsx
│   │   │   │   └── useFieldConfigParser.ts
│   │   │   ├── SmartCardList/
│   │   │   │   ├── SmartCardList.tsx
│   │   │   │   ├── SmartCardListHeaderControls.tsx
│   │   │   │   ├── SmartCardListJoinedNewRecords.tsx
│   │   │   │   └── useSmartCardListState.ts
│   │   │   ├── SmartFilter/
│   │   │   │   ├── AddJoinFilter.tsx
│   │   │   │   ├── MinimisedFilter.css
│   │   │   │   ├── MinimisedFilter.tsx
│   │   │   │   ├── SmartAddFilter.tsx
│   │   │   │   ├── SmartFilter.tsx
│   │   │   │   ├── SmartSearch/
│   │   │   │   │   ├── SmartSearch.css
│   │   │   │   │   ├── SmartSearch.tsx
│   │   │   │   │   ├── getSmartSearchRows.ts
│   │   │   │   │   └── onSearchItems.tsx
│   │   │   │   ├── SortByControl.tsx
│   │   │   │   └── smartFilterUtils.ts
│   │   │   ├── SmartFilterBar/
│   │   │   │   ├── SmartFilterBar.tsx
│   │   │   │   ├── SmartFilterBarFilters.tsx
│   │   │   │   ├── SmartFilterBarRightActions.tsx
│   │   │   │   ├── SmartFilterBarSearch.tsx
│   │   │   │   ├── SmartFilterBarSort.tsx
│   │   │   │   └── useSmartFilterBarState.ts
│   │   │   ├── SmartForm/
│   │   │   │   ├── ChipArrayEditor.tsx
│   │   │   │   ├── InsertButton.tsx
│   │   │   │   ├── JoinedRecords/
│   │   │   │   │   ├── JoinedRecords.tsx
│   │   │   │   │   ├── JoinedRecordsAddRow.tsx
│   │   │   │   │   ├── JoinedRecordsSection.tsx
│   │   │   │   │   ├── getJoinFilter.ts
│   │   │   │   │   ├── useJoinedRecordsSections.ts
│   │   │   │   │   └── useJoinedSectionFieldConfigs.tsx
│   │   │   │   ├── SmartForm.tsx
│   │   │   │   ├── SmartFormField/
│   │   │   │   │   ├── RenderValue.tsx
│   │   │   │   │   ├── SmartFormField.tsx
│   │   │   │   │   ├── SmartFormFieldFileSection.tsx
│   │   │   │   │   ├── SmartFormFieldForeignKey.tsx
│   │   │   │   │   ├── SmartFormFieldLinkedData.tsx
│   │   │   │   │   ├── SmartFormFieldLinkedDataInsert/
│   │   │   │   │   │   ├── SmartFormFieldLinkedDataInsert.tsx
│   │   │   │   │   │   └── useSmartFormFieldLinkedDataInsert.tsx
│   │   │   │   │   ├── SmartFormFieldLinkedDataSearch.tsx
│   │   │   │   │   ├── SmartFormFieldRightButtons.tsx
│   │   │   │   │   ├── ViewMoreSmartCardList.tsx
│   │   │   │   │   ├── fetchColumnValueSuggestions.ts
│   │   │   │   │   ├── fetchForeignKeyOptions.tsx
│   │   │   │   │   ├── fieldUtils.ts
│   │   │   │   │   ├── useFormData.ts
│   │   │   │   │   ├── useNestedInsertDefaultData.ts
│   │   │   │   │   ├── useSmartFormFieldAsJSON.tsx
│   │   │   │   │   └── useSmartFormFieldOnChange.ts
│   │   │   │   ├── SmartFormFieldList.tsx
│   │   │   │   ├── SmartFormFileSection.tsx
│   │   │   │   ├── SmartFormFooter/
│   │   │   │   │   ├── SmartFormFooterButtons.tsx
│   │   │   │   │   └── useSmartFormActions.ts
│   │   │   │   ├── SmartFormNewRowDataHandler.ts
│   │   │   │   ├── SmartFormPopup/
│   │   │   │   │   └── SmartFormPopupWrapper.tsx
│   │   │   │   ├── SmartFormUpperFooter/
│   │   │   │   │   ├── SmartFormUpperFooter.tsx
│   │   │   │   │   └── useActiveJoinedRecordsTab.ts
│   │   │   │   ├── useNewRowDataHandler.ts
│   │   │   │   ├── useSmartForm.ts
│   │   │   │   ├── useSmartFormColumns.ts
│   │   │   │   └── useSmartFormMode.ts
│   │   │   ├── SmartSelect.tsx
│   │   │   ├── SmartTable.tsx
│   │   │   ├── StatusMonitor/
│   │   │   │   ├── StatusMonitor.tsx
│   │   │   │   ├── StatusMonitorConnections.tsx
│   │   │   │   ├── StatusMonitorInfoHeader/
│   │   │   │   │   ├── StatusMonitorInfoHeader.tsx
│   │   │   │   │   ├── StatusMonitorInfoHeaderCpu.tsx
│   │   │   │   │   └── StatusMonitorInfoHeaderMemory.tsx
│   │   │   │   ├── StatusMonitorProcList.tsx
│   │   │   │   └── StatusMonitorProcListControlsHeader.tsx
│   │   │   ├── TableConfig/
│   │   │   │   ├── ProcessLogs.tsx
│   │   │   │   └── TableConfig.tsx
│   │   │   ├── TimeSeries.tsx
│   │   │   ├── UserManager.tsx
│   │   │   ├── W_Barchart/
│   │   │   │   ├── W_Barchart.tsx
│   │   │   │   ├── fetchSQLBarchartData.ts
│   │   │   │   └── useBarchartData.ts
│   │   │   ├── W_Map/
│   │   │   │   ├── OSM/
│   │   │   │   │   ├── OverpassQuery.tsx
│   │   │   │   │   ├── fetchOSMCountryBoundary.ts
│   │   │   │   │   ├── getOSMData.ts
│   │   │   │   │   ├── osmToGeoJSON.ts
│   │   │   │   │   └── osmTypes.ts
│   │   │   │   ├── W_Map.tsx
│   │   │   │   ├── W_MapMenu.tsx
│   │   │   │   ├── controls/
│   │   │   │   │   ├── MapBasemapOptions.tsx
│   │   │   │   │   ├── MapInfoSection.tsx
│   │   │   │   │   ├── MapOSMQuery.tsx
│   │   │   │   │   └── MapOpacityMenu.tsx
│   │   │   │   ├── fetchData/
│   │   │   │   │   ├── fetchMapLayerData.ts
│   │   │   │   │   ├── getMapData.ts
│   │   │   │   │   ├── getMapDataExtent.ts
│   │   │   │   │   └── getMapLayerQueries.ts
│   │   │   │   ├── getMapFeatureStyle.ts
│   │   │   │   └── onMapHover.ts
│   │   │   ├── W_Method/
│   │   │   │   ├── FunctionLabel.tsx
│   │   │   │   ├── NewMethod.tsx
│   │   │   │   ├── PublishedMethods.tsx
│   │   │   │   ├── W_Method.tsx
│   │   │   │   ├── W_MethodControls.tsx
│   │   │   │   └── W_MethodMenu.tsx
│   │   │   ├── W_QuickMenu.tsx
│   │   │   ├── W_SQL/
│   │   │   │   ├── CSVRender.tsx
│   │   │   │   ├── CopyResultBtn.tsx
│   │   │   │   ├── MonacoLanguageRegister.ts
│   │   │   │   ├── SQLHotkeys.tsx
│   │   │   │   ├── TestSQL.ts
│   │   │   │   ├── W_SQL.tsx
│   │   │   │   ├── W_SQLBottomBar/
│   │   │   │   │   ├── W_SQLBottomBar.tsx
│   │   │   │   │   └── W_SQLBottomBarProcStats.tsx
│   │   │   │   ├── W_SQLMenu.tsx
│   │   │   │   ├── W_SQLResults.tsx
│   │   │   │   ├── customRenderers.tsx
│   │   │   │   ├── demoScripts/
│   │   │   │   │   ├── createTables.ts
│   │   │   │   │   ├── mainTestScripts.ts
│   │   │   │   │   ├── testBugs.ts
│   │   │   │   │   ├── testMiscAndBugs.ts
│   │   │   │   │   └── testSqlCharts.ts
│   │   │   │   ├── getChartableSQL.ts
│   │   │   │   ├── getDemoUtils.ts
│   │   │   │   ├── getSQLResultTableColumns.ts
│   │   │   │   ├── monacoEditorTypes.ts
│   │   │   │   ├── parseExplainResult.ts
│   │   │   │   ├── parseSQLError.ts
│   │   │   │   ├── parseSqlResultCols.ts
│   │   │   │   ├── runSQL/
│   │   │   │   │   ├── getQueryTotalRowCount.ts
│   │   │   │   │   └── runSQL.ts
│   │   │   │   └── runSQLErrorHints.ts
│   │   │   ├── W_Table/
│   │   │   │   ├── CardView/
│   │   │   │   │   ├── CardView.tsx
│   │   │   │   │   ├── CardViewColumn.tsx
│   │   │   │   │   ├── CardViewKanban.tsx
│   │   │   │   │   ├── CardViewRow.tsx
│   │   │   │   │   ├── DragHeader.tsx
│   │   │   │   │   ├── useCardViewState.ts
│   │   │   │   │   └── useDragHeader.ts
│   │   │   │   ├── ColumnMenu/
│   │   │   │   │   ├── AddColumnMenu.tsx
│   │   │   │   │   ├── AddComputedColumn/
│   │   │   │   │   │   ├── AddComputedColMenu.tsx
│   │   │   │   │   │   ├── FunctionColumnList.tsx
│   │   │   │   │   │   ├── QuickAddComputedColumn.tsx
│   │   │   │   │   │   └── useAddComputedColumn.ts
│   │   │   │   │   ├── AlterColumn/
│   │   │   │   │   │   ├── AlterColumn.tsx
│   │   │   │   │   │   ├── AlterColumnFileOptions.tsx
│   │   │   │   │   │   ├── ColumnEditor.tsx
│   │   │   │   │   │   ├── CreateColumn.tsx
│   │   │   │   │   │   ├── ReferenceEditor.tsx
│   │   │   │   │   │   └── alterColumnUtilts.ts
│   │   │   │   │   ├── ColorPicker.tsx
│   │   │   │   │   ├── ColumnDisplayFormat/
│   │   │   │   │   │   ├── ChipStylePalette.tsx
│   │   │   │   │   │   ├── ColumnDisplayFormat.tsx
│   │   │   │   │   │   ├── ConditionalCellIconStyleControls.tsx
│   │   │   │   │   │   ├── ConditionalCellStyleControls.tsx
│   │   │   │   │   │   ├── NestedColumnRender.tsx
│   │   │   │   │   │   └── columnFormatUtils.tsx
│   │   │   │   │   ├── ColumnList.tsx
│   │   │   │   │   ├── ColumnMenu.tsx
│   │   │   │   │   ├── ColumnQuickStats/
│   │   │   │   │   │   ├── ColumnQuickStats.tsx
│   │   │   │   │   │   └── useColumnQuickStats.ts
│   │   │   │   │   ├── ColumnSelect/
│   │   │   │   │   │   ├── ColumnSelect.tsx
│   │   │   │   │   │   └── getColumnListItem.tsx
│   │   │   │   │   ├── ColumnSortMenu.tsx
│   │   │   │   │   ├── ColumnStyleControls/
│   │   │   │   │   │   ├── ColumnStyleControls.tsx
│   │   │   │   │   │   └── getValueColors.ts
│   │   │   │   │   ├── ColumnsMenu.tsx
│   │   │   │   │   ├── FunctionSelector/
│   │   │   │   │   │   ├── FunctionExtraArguments.tsx
│   │   │   │   │   │   ├── FunctionSelector.tsx
│   │   │   │   │   │   └── functions.ts
│   │   │   │   │   ├── JoinPathSelectorV2.tsx
│   │   │   │   │   ├── LinkedColumn/
│   │   │   │   │   │   ├── LinkedColumn.tsx
│   │   │   │   │   │   ├── LinkedColumnFooter.tsx
│   │   │   │   │   │   └── LinkedColumnSelect.tsx
│   │   │   │   │   ├── NestedTimechartControls.tsx
│   │   │   │   │   ├── SummariseColumns.tsx
│   │   │   │   │   ├── getNestedColumnTable.ts
│   │   │   │   │   └── rgba2hex.ts
│   │   │   │   ├── JoinPathSelector/
│   │   │   │   │   ├── JoinPathItem.tsx
│   │   │   │   │   ├── JoinPathSelector.tsx
│   │   │   │   │   └── getJoinTree.ts
│   │   │   │   ├── NodeCountChecker.tsx
│   │   │   │   ├── ProstglesTable.css
│   │   │   │   ├── QuickFilterGroupsControl.tsx
│   │   │   │   ├── RowCard.tsx
│   │   │   │   ├── TableMenu/
│   │   │   │   │   ├── AddChartMenu.tsx
│   │   │   │   │   ├── AutoRefreshMenu.tsx
│   │   │   │   │   ├── W_TableMenu.tsx
│   │   │   │   │   ├── W_TableMenu_AccessRules.tsx
│   │   │   │   │   ├── W_TableMenu_Constraints.tsx
│   │   │   │   │   ├── W_TableMenu_CurrentQuery.tsx
│   │   │   │   │   ├── W_TableMenu_DisplayOptions.tsx
│   │   │   │   │   ├── W_TableMenu_Indexes.tsx
│   │   │   │   │   ├── W_TableMenu_Policies.tsx
│   │   │   │   │   ├── W_TableMenu_TableInfo.tsx
│   │   │   │   │   ├── W_TableMenu_Triggers.tsx
│   │   │   │   │   ├── getAndFixWColumnsConfig.tsx
│   │   │   │   │   ├── getChartCols.ts
│   │   │   │   │   └── getTableMeta.ts
│   │   │   │   ├── TooManyColumnsWarning.tsx
│   │   │   │   ├── W_Table.tsx
│   │   │   │   ├── W_Table_Content.tsx
│   │   │   │   ├── colorBlend.ts
│   │   │   │   ├── getTableData/
│   │   │   │   │   ├── getTableData.ts
│   │   │   │   │   └── getTableFilter.ts
│   │   │   │   └── tableUtils/
│   │   │   │       ├── StyledTableColumn.tsx
│   │   │   │       ├── getColWInfo.ts
│   │   │   │       ├── getColWidth.ts
│   │   │   │       ├── getEditColumn.tsx
│   │   │   │       ├── getFullColumnConfig.ts
│   │   │   │       ├── getJoinPaths.ts
│   │   │   │       ├── getRowFilter.ts
│   │   │   │       ├── getTableCols.tsx
│   │   │   │       ├── getTableSelect.ts
│   │   │   │       ├── onRenderColumn.tsx
│   │   │   │       ├── prepareColsForRender.ts
│   │   │   │       └── tableUtils.ts
│   │   │   ├── W_TimeChart/
│   │   │   │   ├── AddTimeChartFilter.tsx
│   │   │   │   ├── W_TimeChart.tsx
│   │   │   │   ├── W_TimeChartHeaderControls.tsx
│   │   │   │   ├── W_TimeChartLayerLegend.tsx
│   │   │   │   ├── W_TimeChartMenu.tsx
│   │   │   │   └── fetchData/
│   │   │   │       ├── constants.ts
│   │   │   │       ├── fetchAndSetTimechartLayerData.ts
│   │   │   │       ├── fetchTimechartLayer.ts
│   │   │   │       ├── getTimeChartData.ts
│   │   │   │       ├── getTimeChartLayers.ts
│   │   │   │       ├── getTimeChartLayersWithBins.ts
│   │   │   │       ├── getTimeChartSelectParams.ts
│   │   │   │       ├── getTimeLayerDataSignature.ts
│   │   │   │       └── getTimechartExtentFilter.ts
│   │   │   ├── Window.tsx
│   │   │   ├── WindowControls/
│   │   │   │   ├── AddChartLayer.tsx
│   │   │   │   ├── ColorByLegend/
│   │   │   │   │   ├── ColorByLegend.tsx
│   │   │   │   │   └── getGroupByValueColor.ts
│   │   │   │   ├── DataLayerManager/
│   │   │   │   │   ├── DataLayer.tsx
│   │   │   │   │   ├── DataLayerManager.tsx
│   │   │   │   │   └── useSortedLayerQueries.ts
│   │   │   │   ├── LayerColorPicker.tsx
│   │   │   │   ├── MapLayerStyling.tsx
│   │   │   │   ├── OSMLayerOptions.tsx
│   │   │   │   ├── SQLChartLayerEditor.tsx
│   │   │   │   └── TimeChartLayerOptions.tsx
│   │   │   ├── WorkspaceMenu/
│   │   │   │   ├── WorkspaceAddBtn.tsx
│   │   │   │   ├── WorkspaceDeleteBtn.tsx
│   │   │   │   ├── WorkspaceMenu.css
│   │   │   │   ├── WorkspaceMenu.tsx
│   │   │   │   ├── WorkspaceMenuDropDown.tsx
│   │   │   │   ├── WorkspaceSettings.tsx
│   │   │   │   └── useWorkspaces.ts
│   │   │   ├── joinUtils.ts
│   │   │   ├── localSettings.ts
│   │   │   ├── setPan.ts
│   │   │   └── shortestPath.ts
│   │   ├── demo/
│   │   │   ├── AppVideoDemo.tsx
│   │   │   ├── MousePointer.tsx
│   │   │   ├── demoUtils.ts
│   │   │   ├── recordDemoUtils.ts
│   │   │   └── scripts/
│   │   │       ├── AIAssistantDemo.ts
│   │   │       ├── accessControlDemo.ts
│   │   │       ├── backupDemo.ts
│   │   │       ├── dashboardDemo.ts
│   │   │       ├── fileDemo.ts
│   │   │       ├── schemaDiagramDemo.ts
│   │   │       ├── sqlVideoDemo.ts
│   │   │       └── videoDemoAccessControlScripts.ts
│   │   ├── exports.ts
│   │   ├── hooks/
│   │   │   ├── useDebouncedCallback.ts
│   │   │   ├── useThrottledCallback.ts
│   │   │   └── useTypedSearchParams.ts
│   │   ├── i18n/
│   │   │   ├── LanguageSelector.tsx
│   │   │   ├── i18nUtils.ts
│   │   │   └── translations/
│   │   │       ├── de.json
│   │   │       ├── es.json
│   │   │       ├── fr.json
│   │   │       ├── hi.json
│   │   │       ├── ru.json
│   │   │       ├── translations.ts
│   │   │       └── zh.json
│   │   ├── index.css
│   │   ├── index.html.ejs
│   │   ├── index.tsx
│   │   ├── pages/
│   │   │   ├── Account/
│   │   │   │   ├── Account.tsx
│   │   │   │   ├── ChangePassword.tsx
│   │   │   │   ├── Sessions.tsx
│   │   │   │   └── Setup2FA.tsx
│   │   │   ├── AccountMenu.tsx
│   │   │   ├── Alerts.tsx
│   │   │   ├── ComponentList.tsx
│   │   │   ├── Connections/
│   │   │   │   ├── Connection.tsx
│   │   │   │   ├── ConnectionActionBar.tsx
│   │   │   │   ├── Connections.tsx
│   │   │   │   ├── ConnectionsOptions.tsx
│   │   │   │   ├── CreateConnection/
│   │   │   │   │   ├── CreateConnection.tsx
│   │   │   │   │   └── useCreateConnection.ts
│   │   │   │   ├── CreatePostgresUser.tsx
│   │   │   │   ├── useConnectionServersList.ts
│   │   │   │   └── useConnections.ts
│   │   │   ├── ElectronSetup/
│   │   │   │   ├── ElectronSetup.tsx
│   │   │   │   ├── ElectronSetupStateDB.tsx
│   │   │   │   └── useElectronSetup.ts
│   │   │   ├── Login/
│   │   │   │   ├── AuthNotifPopup.tsx
│   │   │   │   ├── Login.tsx
│   │   │   │   ├── LoginTotpForm.tsx
│   │   │   │   ├── LoginWithProviders.tsx
│   │   │   │   ├── SocialIcons.css
│   │   │   │   ├── SocialIcons.tsx
│   │   │   │   └── useLoginState.ts
│   │   │   ├── NewConnection/
│   │   │   │   ├── NewConnectionFormFields.tsx
│   │   │   │   ├── NewConnnectionForm.tsx
│   │   │   │   ├── SchemaFilter.tsx
│   │   │   │   └── newConnectionUtils.ts
│   │   │   ├── NonHTTPSWarning.tsx
│   │   │   ├── NotFound.tsx
│   │   │   ├── ProjectConnection/
│   │   │   │   ├── PrglContextProvider.tsx
│   │   │   │   ├── ProjectConnection.tsx
│   │   │   │   ├── ProjectConnectionError.tsx
│   │   │   │   └── useProjectDb.ts
│   │   │   ├── ProjectLogs.tsx
│   │   │   ├── ServerSettings/
│   │   │   │   ├── AuthProvidersSetup.tsx
│   │   │   │   ├── EmailAuthSetup.tsx
│   │   │   │   ├── EmailAuthSetupIngredients/
│   │   │   │   │   ├── EmailSMTPAndTemplateSetup.tsx
│   │   │   │   │   ├── EmailSMTPSetup.tsx
│   │   │   │   │   └── EmailTemplateSetup.tsx
│   │   │   │   ├── MCPServers/
│   │   │   │   │   ├── MCPServerConfig/
│   │   │   │   │   │   ├── MCPServerConfig.tsx
│   │   │   │   │   │   ├── MCPServerConfigButton.tsx
│   │   │   │   │   │   ├── useMCPServerConfigState.tsx
│   │   │   │   │   │   └── useMCPServerEnable.ts
│   │   │   │   │   ├── MCPServerFooterActions/
│   │   │   │   │   │   ├── MCPServerFooterActions.tsx
│   │   │   │   │   │   └── MCPServersInstall.tsx
│   │   │   │   │   ├── MCPServerHeaderCheckbox.tsx
│   │   │   │   │   ├── MCPServerTools/
│   │   │   │   │   │   ├── MCPServerTools.tsx
│   │   │   │   │   │   └── MCPServerToolsGroupToggle.tsx
│   │   │   │   │   ├── MCPServers.tsx
│   │   │   │   │   ├── MCPServersHeader.tsx
│   │   │   │   │   ├── MCPServersToolbar/
│   │   │   │   │   │   ├── AddMCPServer.tsx
│   │   │   │   │   │   ├── MCPServersToolbar.tsx
│   │   │   │   │   │   └── useAddMCPServer.ts
│   │   │   │   │   ├── useMCPChatAllowedTools.ts
│   │   │   │   │   └── useMCPServersListProps.tsx
│   │   │   │   ├── OAuthProviderSetup.tsx
│   │   │   │   ├── ServerSettings.tsx
│   │   │   │   ├── Services.tsx
│   │   │   │   └── useEditableData.ts
│   │   │   ├── TopControls.tsx
│   │   │   └── projectUtils.ts
│   │   ├── theme/
│   │   │   ├── ThemeSelector.tsx
│   │   │   ├── useAppTheme.ts
│   │   │   └── useSystemTheme.ts
│   │   ├── useAppState/
│   │   │   ├── dbsConnectionOptions.ts
│   │   │   ├── useAppState.ts
│   │   │   ├── useDBSClient.ts
│   │   │   └── useServerState.ts
│   │   └── utils/
│   │       ├── colorUtils.ts
│   │       ├── hashCode.ts
│   │       └── utils.ts
│   ├── static/
│   │   └── util.css
│   ├── tsconfig.eslint.json
│   ├── tsconfig.json
│   ├── tsconfig_lib.json
│   ├── tsconfig_rollup.json
│   └── tslint.json
├── common/
│   ├── DBGeneratedSchema.d.ts
│   ├── DashboardTypes.d.ts
│   ├── DashboardTypes.js
│   ├── DashboardTypes.ts
│   ├── OAuthUtils.d.ts
│   ├── OAuthUtils.js
│   ├── OAuthUtils.ts
│   ├── dashboardTypesContent.d.ts
│   ├── dashboardTypesContent.js
│   ├── dashboardTypesContent.ts
│   ├── electronInitTypes.d.ts
│   ├── electronInitTypes.js
│   ├── electronInitTypes.ts
│   ├── filterUtils.d.ts
│   ├── filterUtils.js
│   ├── filterUtils.ts
│   ├── llmUtils.d.ts
│   ├── llmUtils.js
│   ├── llmUtils.ts
│   ├── mcp.d.ts
│   ├── mcp.js
│   ├── mcp.ts
│   ├── prostglesMcp.d.ts
│   ├── prostglesMcp.js
│   ├── prostglesMcp.ts
│   ├── psql_queries.json
│   ├── publishUtils.d.ts
│   ├── publishUtils.js
│   ├── publishUtils.ts
│   ├── tsconfig.json
│   ├── utils.d.ts
│   ├── utils.js
│   └── utils.ts
├── docker-compose.yml
├── docs/
│   ├── 01_Overview.md
│   ├── 02_Installation.md
│   ├── 03_Installation_(Desktop_Version).md
│   ├── 04_Navigation_bar.md
│   ├── 05_Connections.md
│   ├── 06_Connection_dashboard.md
│   ├── 07_Import_file.md
│   ├── 08_Schema_diagram.md
│   ├── 09_SQL_editor.md
│   ├── 10_Table_view.md
│   ├── 11_Map_view.md
│   ├── 12_Timechart_view.md
│   ├── 13_AI_Assistant.md
│   ├── 14_Connection_configuration.md
│   ├── 15_Access_control.md
│   ├── 16_File_storage.md
│   ├── 17_Backup_and_Restore.md
│   ├── 18_API.md
│   ├── 19_Server_Settings.md
│   ├── 20_Account.md
│   └── 21_Command_Palette.md
├── e2e/
│   ├── .gitignore
│   ├── package.json
│   ├── playwright.config.js
│   ├── playwright.config.ts
│   ├── test-local.sh
│   ├── tests/
│   │   ├── Testing.ts
│   │   ├── command_palette.spec.ts
│   │   ├── createReceipt.ts
│   │   ├── create_docs.spec.ts
│   │   ├── create_load_test_users.spec.ts
│   │   ├── demo_video.spec.ts
│   │   ├── demo_video_setup.spec.ts
│   │   ├── load_test.spec.ts
│   │   ├── main.spec.ts
│   │   ├── mockSMTPServer.ts
│   │   ├── sampleToolUseData.ts
│   │   ├── speechToTextTest.ts
│   │   ├── svgScreenshots/
│   │   │   ├── SVG_SCREENSHOT_DETAILS.ts
│   │   │   ├── account.svgif.ts
│   │   │   ├── aiAssistant.svgif.ts
│   │   │   ├── backupAndRestore.svgif.ts
│   │   │   ├── commandPalette.svgif.ts
│   │   │   ├── dashboard.svgif.ts
│   │   │   ├── electronSetup.svgif.ts
│   │   │   ├── fileImporter.svgif.ts
│   │   │   ├── getOverviewSvgifSpecs.svgif.ts
│   │   │   ├── map.svgif.ts
│   │   │   ├── navbar.svgif.ts
│   │   │   ├── newConnection.svgif.ts
│   │   │   ├── schemaDiagram.svgif.ts
│   │   │   ├── smartForm.svgif.ts
│   │   │   ├── sqlEditor.svgif.ts
│   │   │   ├── table.svgif.ts
│   │   │   ├── timechart.svgif.ts
│   │   │   └── utils/
│   │   │       ├── constants.ts
│   │   │       ├── getFilesFromDir.ts
│   │   │       ├── getSceneUtils.ts
│   │   │       ├── saveSVGScreenshot.ts
│   │   │       ├── saveSVGifs.ts
│   │   │       ├── saveSVGs.ts
│   │   │       ├── svgScreenshotsCompleteReferenced.ts
│   │   │       └── typeSendAddScenes.ts
│   │   ├── testAskLLM.ts
│   │   ├── tsconfig.json
│   │   └── utils/
│   │       ├── constants.ts
│   │       ├── goTo.ts
│   │       ├── isPortFree.ts
│   │       └── utils.ts
│   └── tsconfig.json
├── electron/
│   ├── .gitignore
│   ├── README.md
│   ├── build.sh
│   ├── e2e-electron/
│   │   ├── electron.spec.tsx
│   │   └── tsconfig.json
│   ├── forge.config.js
│   ├── getProtocolHandler.ts
│   ├── images/
│   │   ├── generate_from_svg.sh
│   │   └── loading-effect.css
│   ├── loadingHTML.ts
│   ├── main.ts
│   ├── mainWindow.ts
│   ├── package.json
│   ├── playwright.config.ts
│   ├── screenCapture.bat
│   ├── setContextMenu.ts
│   ├── start.sh
│   ├── test-linux-macos.sh
│   ├── test-linux.sh
│   ├── test-setup.js
│   ├── test-w-debug.sh
│   ├── test.sh
│   ├── tsconfig.json
│   ├── win-inno-setup.ts
│   └── win.js
├── package.json
├── releases/
│   ├── v1.0.0.md
│   ├── v2.0.0.md
│   ├── v2.2.2.md
│   ├── v2.2.3.md
│   └── v2.2.4.md
├── scripts/
│   ├── demo/
│   │   ├── SCREEN RECORD.txt
│   │   ├── record-local.sh
│   │   └── split-video.sh
│   ├── get_version.sh
│   ├── release.sh
│   ├── start-dev-electron.sh
│   ├── start-dev.sh
│   ├── start-prod.sh
│   └── test.sh
└── server/
    ├── .gitignore
    ├── .vscode/
    │   └── settings.json
    ├── eslint.config.mjs
    ├── licenses.json
    ├── package.json
    ├── proj-prgl.js
    ├── sample_schemas/
    │   ├── _crypto.sql
    │   ├── cleaning.sql
    │   ├── cloud_computing.sql
    │   ├── countries.sql
    │   ├── crypto/
    │   │   ├── onMount.ts
    │   │   ├── tableConfig.ts
    │   │   └── workspaceConfig.ts
    │   ├── financial.sql
    │   ├── food_delivery/
    │   │   ├── connection.ts
    │   │   ├── databaseConfig.ts
    │   │   ├── onInit.sql
    │   │   ├── onMount.ts
    │   │   └── workspaceConfig.ts
    │   ├── lodging.sql
    │   ├── maps.sql
    │   ├── property_management/
    │   │   ├── onMount.ts
    │   │   └── workspaceConfig.ts
    │   ├── sales.sql
    │   ├── sample.sql
    │   ├── testschema.ts
    │   └── weather/
    │       └── onMount.ts
    ├── src/
    │   ├── BackupManager/
    │   │   ├── BackupManager.ts
    │   │   ├── checkAutomaticBackup.ts
    │   │   ├── getInstalledPrograms.ts
    │   │   ├── pgDump.ts
    │   │   ├── pgRestore.ts
    │   │   ├── pipeFromCommand.ts
    │   │   ├── pipeToCommand.ts
    │   │   └── utils.ts
    │   ├── ConnectionManager/
    │   │   ├── ConnectionManager.ts
    │   │   ├── ForkedPrglProcRunner/
    │   │   │   ├── ForkedPrglProcRunner.ts
    │   │   │   ├── createProc.ts
    │   │   │   └── forkedProcess.ts
    │   │   ├── connectionManagerUtils.ts
    │   │   ├── getConnectionPublish.ts
    │   │   ├── getConnectionPublishMethods.ts
    │   │   ├── getInitiatedPostgresqlPIDs.ts
    │   │   ├── initConnectionManager.ts
    │   │   ├── saveCertificates.ts
    │   │   └── startConnection.ts
    │   ├── Logger.ts
    │   ├── McpHub/
    │   │   ├── AnthropicMcpHub/
    │   │   │   ├── McpHub.ts
    │   │   │   ├── McpTypes.ts
    │   │   │   ├── connectToMCPServer.ts
    │   │   │   ├── fetchMCPResourceTemplatesList.ts
    │   │   │   ├── fetchMCPResourcesList.ts
    │   │   │   ├── fetchMCPToolsList.ts
    │   │   │   ├── installMCPServer.ts
    │   │   │   ├── runShellCommand.ts
    │   │   │   └── startMcpHub.ts
    │   │   ├── DefaultMCPServers/
    │   │   │   ├── DefaultMCPServers.ts
    │   │   │   └── mcpGithub.ts
    │   │   ├── ProstglesMcpHub/
    │   │   │   ├── ProstglesMCPServerTypes.ts
    │   │   │   ├── ProstglesMCPServers/
    │   │   │   │   ├── DockerSandbox/
    │   │   │   │   │   ├── createContainer.spec.ts
    │   │   │   │   │   ├── createContainer.ts
    │   │   │   │   │   ├── dockerMCPServerProxy/
    │   │   │   │   │   │   ├── dockerContainerAuthRegistry.ts
    │   │   │   │   │   │   ├── dockerMCPServerProxy.ts
    │   │   │   │   │   │   └── isPortFree.ts
    │   │   │   │   │   ├── executeDockerCommand.ts
    │   │   │   │   │   ├── fetchTools.ts
    │   │   │   │   │   ├── getContainerLogs.ts
    │   │   │   │   │   ├── getDockerGatewayIP.ts
    │   │   │   │   │   └── getDockerRunArgs.ts
    │   │   │   │   ├── DockerSandbox.mcp.ts
    │   │   │   │   └── WebSearch.mcp.ts
    │   │   │   ├── ProstglesMCPServers.ts
    │   │   │   └── ProstglesMcpHub.ts
    │   │   ├── callMCPServerTool.ts
    │   │   ├── fetchMCPServerConfigs.ts
    │   │   ├── insertServerList.ts
    │   │   ├── reloadMcpServerTools.ts
    │   │   └── testMCPServerConfig.ts
    │   ├── SecurityManager/
    │   │   └── initUsers.ts
    │   ├── ServiceManager/
    │   │   ├── ServiceManager.spec.ts
    │   │   ├── ServiceManager.ts
    │   │   ├── ServiceManagerTypes.ts
    │   │   ├── buildService.ts
    │   │   ├── dockerInspect.ts
    │   │   ├── enableService.ts
    │   │   ├── getDockerBuildHash.ts
    │   │   ├── getSelectedConfigEnvs.ts
    │   │   ├── getServiceEndoints.ts
    │   │   ├── initialiseServices.ts
    │   │   ├── services/
    │   │   │   ├── speechToText/
    │   │   │   │   ├── speechToText.service.ts
    │   │   │   │   └── src/
    │   │   │   │       ├── Dockerfile
    │   │   │   │       ├── app.py
    │   │   │   │       └── requirements.txt
    │   │   │   └── webSearchSearxng/
    │   │   │       ├── src/
    │   │   │       │   ├── Dockerfile
    │   │   │       │   ├── limiter.toml
    │   │   │       │   └── settings.yml
    │   │   │       └── webSearchSearxng.service.ts
    │   │   ├── startService.ts
    │   │   └── stopService.ts
    │   ├── authConfig/
    │   │   ├── OAuthProviders/
    │   │   │   ├── getOAuthLoginProviders.ts
    │   │   │   └── loginWithProvider.ts
    │   │   ├── authUtils.ts
    │   │   ├── createPasswordlessAdminSessionIfNeeded.ts
    │   │   ├── createPublicUserSessionIfAllowed.ts
    │   │   ├── emailProvider/
    │   │   │   ├── getEmailAuthProvider.ts
    │   │   │   ├── getEmailSenderWithMockTest.ts
    │   │   │   └── onEmailRegistration.ts
    │   │   ├── getActiveSession.ts
    │   │   ├── getAuth.ts
    │   │   ├── getLogin.ts
    │   │   ├── getUser.ts
    │   │   ├── onMagicLinkOrOTP.ts
    │   │   ├── onUseOrSocketConnected.ts
    │   │   ├── sessionUtils.ts
    │   │   ├── startRateLimitedLoginAttempt.ts
    │   │   ├── subscribeToAuthSetupChanges.ts
    │   │   └── upsertSession.ts
    │   ├── cloudClients/
    │   │   └── cloudClients.ts
    │   ├── connectionUtils/
    │   │   ├── getConnectionDetails.ts
    │   │   ├── testDBConnection.ts
    │   │   └── validateConnection.ts
    │   ├── electronConfig.ts
    │   ├── envVars.ts
    │   ├── getPSQLQueries.ts
    │   ├── index.ts
    │   ├── init/
    │   │   ├── cleanupTestDatabases.ts
    │   │   ├── initExpressAndIOServers.ts
    │   │   ├── insertStateDatabase.ts
    │   │   ├── isRetryableError.ts
    │   │   ├── logOutgoingHttpRequests.ts
    │   │   ├── onProstglesReady.ts
    │   │   ├── setDBSRoutesForElectron.ts
    │   │   ├── startDevHotReloadNotifier.ts
    │   │   ├── startProstgles.ts
    │   │   ├── testDashboardTypesContent.ts
    │   │   └── tryStartProstgles.ts
    │   ├── init.sql
    │   ├── methods/
    │   │   ├── getPidStats.ts
    │   │   ├── getPidStatsFromProc.ts
    │   │   └── statusMonitorUtils.ts
    │   ├── publish/
    │   │   ├── getPublishLLM.ts
    │   │   └── publish.ts
    │   ├── publishMethods/
    │   │   ├── applySampleSchema.ts
    │   │   ├── askLLM/
    │   │   │   ├── LLMResponseTypes.ts
    │   │   │   ├── askLLM.ts
    │   │   │   ├── checkLLMLimit.ts
    │   │   │   ├── checkMaxCostLimitForChat.ts
    │   │   │   ├── fetchLLMResponse.ts
    │   │   │   ├── getFullPrompt.ts
    │   │   │   ├── getLLMRequestBody.ts
    │   │   │   ├── getLLMToolsAllowedInThisChat.ts
    │   │   │   ├── getLLMUsageCost.ts
    │   │   │   ├── getUserMessageCost.ts
    │   │   │   ├── parseLLMResponseObject.ts
    │   │   │   ├── prostglesLLMTools/
    │   │   │   │   ├── getMCPServerTools.ts
    │   │   │   │   ├── getProstglesDBTools.ts
    │   │   │   │   ├── getProstglesLLMTools.ts
    │   │   │   │   ├── getPublishedMethodsTools.ts
    │   │   │   │   ├── prostglesMcpTools.ts
    │   │   │   │   └── runProstglesDBTool.ts
    │   │   │   ├── readFetchStream.ts
    │   │   │   ├── refreshModels.ts
    │   │   │   ├── runApprovedTools/
    │   │   │   │   ├── runApprovedTools.ts
    │   │   │   │   └── validateLastMessageToolUseRequests.ts
    │   │   │   └── setupLLM.ts
    │   │   ├── deleteConnection.ts
    │   │   ├── getConnectionAndDatabaseConfig.ts
    │   │   ├── getNodeTypes.ts
    │   │   ├── prostglesSignup.ts
    │   │   ├── publishMethods.ts
    │   │   └── setFileStorage.ts
    │   ├── tableConfig/
    │   │   ├── tableConfig.ts
    │   │   ├── tableConfigAccessControl.ts
    │   │   ├── tableConfigBackups.ts
    │   │   ├── tableConfigConnections.ts
    │   │   ├── tableConfigGlobalSettings.ts
    │   │   ├── tableConfigLinks.ts
    │   │   ├── tableConfigLlm/
    │   │   │   ├── tableConfigLlm.ts
    │   │   │   ├── tableConfigLlmChats.ts
    │   │   │   └── tableConfigLlmExtraRequestData.ts
    │   │   ├── tableConfigMCPServers.ts
    │   │   ├── tableConfigMigrations.ts
    │   │   ├── tableConfigPublishedMethods.ts
    │   │   ├── tableConfigUsers.ts
    │   │   ├── tableConfigWindows.ts
    │   │   └── tableConfigWorkspaces.ts
    │   ├── testElectron.ts
    │   └── upsertConnection.ts
    ├── tsconfig.json
    └── tslint.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
.git
.env
.github
.vscode
scripts/demo
e2e
electron
releases
**/node_modules
**/dist
**/prostgles_backups
**/prostgles_media
**/prostgles_storage
**/prostgles_mcp

================================================
FILE: .eslintrc.common.js
================================================
/**
 * @type {import('eslint').Linter.Config}
 */
module.exports = {
  // "root": true,
  parserOptions: {
    ecmaVersion: "latest",
    sourceType: "module",
    allowImportExportEverywhere: true,
    project: ["./tsconfig.json"],
    // "tsconfigRootDir": __dirname,
  },
  // "ingorePatterns": "**/*.d.ts, **/*.js",

  ignores: [
    "node_modules",
    "dist",
    "examples",
    "**/*.d.ts",
    "**/*.js",
    "tests",
    ".eslintrc.js",
    ".eslint.config.js",
    "*.json",
    "**/*.json",
  ],
  parser: "@typescript-eslint/parser",
  plugins: ["@typescript-eslint"],
  extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
  rules: {
    "@typescript-eslint/no-misused-spread": [
      "error",
      {
        allow: [
          "CSSStyleDeclaration",
          "Partial<CSSStyleDeclaration>",
          "DOMStringMap",
        ],
      },
    ],
    "no-cond-assign": "error",
    "@typescript-eslint/no-namespace": "off",
    "@typescript-eslint/no-explicit-any": "off",
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/ban-types": "off",
    "@typescript-eslint/ban-ts-comment": "off",
    "no-async-promise-executor": "off",
    "@typescript-eslint/no-var-requires": "off",
    "@typescript-eslint/no-unused-vars": "off",
    "@typescript-eslint/no-empty-function": "off",
    "@typescript-eslint/prefer-promise-reject-errors": "off",
    "no-unused-vars": "off",
    "no-empty": "off",
    "no-constant-condition": "error",
    "@typescript-eslint/no-unnecessary-condition": "error",
    "@typescript-eslint/consistent-type-imports": [
      "error",
      {
        disallowTypeAnnotations: false,
      },
    ],
    quotes: [
      "error",
      "double",
      {
        avoidEscape: true,
        allowTemplateLiterals: true,
      },
    ],
  },
};


================================================
FILE: .gitattributes
================================================
# Never modify line endings of bash scripts
*.sh -crlf

================================================
FILE: .github/ISSUE_TEMPLATE/BUG.yml
================================================
name: Bug Report
description: File a bug report
title: "[Bug]: "
labels: ["bug", "triage"]
assignees:
  - octocat
body:
  - type: markdown
    attributes:
      value: |
        Thanks for taking the time to fill out this bug report!
  - type: textarea
    id: what-happened
    attributes:
      label: What happened?
      description: Also tell us, what did you expect to happen?
      placeholder: Tell us what you see!
      value: "A bug happened!"
    validations:
      required: true
  - type: dropdown
    id: product
    attributes:
      label: Which product are you seeing the problem on?
      multiple: true
      options:
        - UI
        - Prostgles-Desktop
  - type: dropdown
    id: os
    attributes:
      label: What OS are you seeing the problem on?
      multiple: true
      options:
        - Android
        - iOS
        - Windows
        - Linux
  - type: dropdown
    id: browsers
    attributes:
      label: What browsers are you seeing the problem on?
      multiple: true
      options:
        - Firefox
        - Chrome
        - Safari
        - Microsoft Edge
  - type: textarea
    id: logs
    attributes:
      label: Relevant log output
      description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
      render: shell


================================================
FILE: .github/ISSUE_TEMPLATE/CUSTOM.yml
================================================
name: Custom issue
description: File a feature request
title: "[Title]"
assignees:
  - prostgles
body:
  - type: textarea
    id: details
    attributes:
      label: Issue details
      value: "Description ..."
    validations:
      required: true


================================================
FILE: .github/ISSUE_TEMPLATE/FEATURE.yml
================================================
name: Feature request
description: File a feature request
title: "[Feature]: "
labels: ["feature"]
assignees:
  - prostgles
body:
  - type: markdown
    attributes:
      value: |
        Thanks for taking the time to fill out this feature request!
  - type: textarea
    id: details
    attributes:
      label: Requested Behavior
      description: What do you want to be able to do
      value: "I need to "
    validations:
      required: true
  - type: textarea
    id: current-approach
    attributes:
      label: How to achieve this now
      description: Current work arounds to accomplish requested behavior
      value: "You have to "
    validations:
      required: false


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
### Actual Behavior

### Expected Behavior

### Steps to reproduce the issue

#### Data used

#### Config


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false


================================================
FILE: .github/ISSUE_TEMPLATE/custom.md
================================================
## Issue title

## Details


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
## Requested Behavior

## Use Cases

## Current work arounds to accomplish requested behavior


================================================
FILE: .github/workflows/docker_test.yml
================================================
name: Test docker scripts
on:
  pull_request:
    branches: [main, master]
  merge_group:
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
jobs:
  test_docker:
    name: Test docker scripts
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Docker run
        run: |
          docker run -d -p 127.0.0.1:5432:5432 -e POSTGRES_PASSWORD=postgres postgres
          TEST_SCRIPT=$(awk '/```docker-run.sh/{f=1;next} /```/{f=0} f' README.md)
          echo $TEST_SCRIPT
          eval "$TEST_SCRIPT"
      - name: Test Docker run
        run: |
          sleep 15
          docker ps 
          pg_container_name=$(docker ps --format '{{.Names}}\t{{.Image}}' | grep 'prostgles' | head -1 | awk '{print $1}')
          echo $pg_container_name
          eval "docker logs $pg_container_name"
          result=$(curl -b -i -L  -v  localhost:3004)
          echo $result
          echo $result | grep -q "Prostgles UI"; echo $?
          docker stop $(docker ps -a -q)

      - name: Docker compose
        run: |
          TEST_SCRIPT=$(awk '/```docker-compose.sh/{f=1;next} /```/{f=0} f' README.md)
          echo $TEST_SCRIPT
          eval "$TEST_SCRIPT"
      - name: Test Docker compose
        run: |
          sleep 10
          docker ps
          result=$(curl -b -i -L  -v  localhost:3004)
          echo $result | grep -q "Prostgles UI"; echo $?


================================================
FILE: .github/workflows/electron_build_linux.yml
================================================
name: Electron build & test linux
on: workflow_dispatch
jobs:
  electron_build:
    timeout-minutes: 20
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: Install dependencies, build and test
        run: |
          sudo apt-get update && \
          cd electron && npm run build-linux

      - name: Install dependencies for testing
        run: |
          sudo apt-get update
          cd electron && sudo apt-get install -y x11-xserver-utils scrot libnotify4  libnss3-dev libatk1.0-0 libatk-bridge2.0-0 libgdk-pixbuf2.0-0 libgtk-3-0 gconf-service gconf2
          DEBIAN_FRONTEND=noninteractive sudo apt install -y x11-apps xvfb gdebi-core
      - name: Install the app
        run: |
          cd electron
          sha256sum ./dist/*.deb > ./dist/checksum.txt
          cat ./dist/checksum.txt
          sudo dpkg -i ./dist/*.deb
      - name: Test installation file
        run: |
          cd electron
          xvfb-run --server-num=98 --server-args="-screen 0 1920x1080x24" -- bash -c "QTWEBENGINE_CHROMIUM_FLAGS=--disable-gpu prostgles-desktop & sleep 5 && scrot ./dist/screenshot.png && exit" && exit
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: installers
          path: electron/dist
          compression-level: 0
          retention-days: 10


================================================
FILE: .github/workflows/electron_build_macos.yml
================================================
name: Electron build & test macOs
on: workflow_dispatch
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
jobs:
  electron_build_macos:
    timeout-minutes: 25
    runs-on: macos-12-large
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 22 # node 20 is too slow
      - name: Install dependencies
        run: |
          cd electron 
          npm run build-macos
          rm -rf ./dist/mac-universal
      - name: Test DMG file installations and run
        run: |
          shasum -a 256 electron/dist/*.dmg > electron/dist/checksum.txt
          cat electron/dist/checksum.txt
          hdiutil attach electron/dist/*.dmg
          ls -la /Volumes
          sudo cp -r /Volumes/Prostgles*/*.app /Applications
          open /Applications/Prostgles*.app
          sleep 10
          screencapture electron/dist/picture.png
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: installers
          path: electron/dist
          compression-level: 0
          retention-days: 10


================================================
FILE: .github/workflows/electron_build_windows.yml
================================================
name: Electron build & test windows
on: workflow_dispatch
jobs:
  electron_build_windows:
    timeout-minutes: 12
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: Build
        run: |
          cd electron && npm run build-win

      - name: Test build
        shell: cmd
        run: |
          cd electron\dist
          for /r %%f in (*.exe) DO certutil -hashfile "%%f" SHA256 > windows.checksums
          type windows.checksums
          for /r %%f in (*.exe) DO "%%f" /S --force-run
          cd ..
          waitfor SomethingThatIsNeverHappening /t 3 2>NUL
          call screenCapture.bat .\dist\screen1.png

      - uses: actions/upload-artifact@v3
        if: always()
        with:
          name: installers
          path: electron/dist
          compression-level: 0
          retention-days: 10


================================================
FILE: .github/workflows/electron_linux_test.yml
================================================
name: Electron test linux (deprecated)
on: workflow_dispatch
jobs:
  electron_build:
    timeout-minutes: 20
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: Install dependencies, build and test
        run: |
          sudo apt-get install xvfb -y &&
          cd electron && npm run test-linux

      - uses: actions/upload-artifact@v3
        if: always()
        with:
          name: installers
          path: electron/dist
          retention-days: 10


================================================
FILE: .github/workflows/electron_macos_test.yml
================================================
name: Electron test macos (deprecated)
on: workflow_dispatch
jobs:
  electron_build:
    timeout-minutes: 20
    runs-on: macos-12-large

    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: Install dependencies, build and test
        run: |
          sleep 60 && \
          screencapture -v electron/dist/vid.mov & \
          cd electron && npm run test-macos

      - uses: actions/upload-artifact@v3
        if: always()
        with:
          name: test-results
          path: electron/dist
          retention-days: 10


================================================
FILE: .github/workflows/linux_test.yml
================================================
name: Linux & Electron test
on:
  pull_request:
    branches: [main, master]
  merge_group:
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
jobs:
  test_linux:
    runs-on: ubuntu-latest
    timeout-minutes: 45
    services:
      postgres:
        image: postgis/postgis:15-3.3
        env:
          POSTGRES_DB: db
          POSTGRES_PASSWORD: psw
          POSTGRES_USER: usr
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 10
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20
          fetch-depth: 2 # Fetch at least 2 commits to ensure doc checks work

      - name: Install curl inside postgres container for video needed for demo
        run: |
          pg_container_name=$(docker ps --format '{{.Names}}\t{{.Image}}' | grep 'postgis' | head -1 | awk '{print $1}') && \
          echo $pg_container_name && \
          docker ps -a && \
          docker exec $pg_container_name /bin/sh -c "apt-get update && apt install curl -y"

      - name: Wait for PostgreSQL to be ready and create prostgles_desktop_db
        run: |
          until pg_isready -h localhost -U usr -d db; do
            sleep 1
          done
          PGPASSWORD=psw psql -h localhost -U usr -d db -c "CREATE DATABASE prostgles_desktop_db;"

      - name: Install dependencies (psql with pg_dump)
          pg_dump version must be >= pg servers version to ensure backup/restore works
        run: |
          cd client && npm ci && \
          cd ../server && npm ci && \
          cd ../e2e && npm ci && npx playwright install && \
          sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' && \
          sudo apt-get -y install wget ca-certificates && \
          wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - && \
          sudo apt-get update && \
          sudo apt-get -y install postgresql-client-16
          # Install uv tool for MCP tools
          curl -LsSf https://astral.sh/uv/install.sh | sh
          npm cache clean --force

      - name: Run test
        run: |
          npm test

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: |
            e2e/electron-report/
            e2e/playwright-report/
          retention-days: 10
  test_desktop_on_macos:
    runs-on: macos-latest
    timeout-minutes: 15
    if: success()
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20
      - name: Install curl inside postgres container for video needed for demo
        run: |
          ls -la /Applications/

      - name: Install dependencies (psql with pg_dump) pg_dump version must be >= pg servers version to ensure backup/restore works
        run: |
          /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" && \
          brew install postgresql@14
          brew services restart postgresql@14
          export PATH="/opt/homebrew/opt/postgresql@14/bin:$PATH"
          /opt/homebrew/opt/postgresql@14/bin/psql --version
          /opt/homebrew/opt/postgresql@14/bin/pg_dump --version
          until pg_isready
          do
            echo "Waiting for postgres to start..."
            sleep 1
          done
          /opt/homebrew/opt/postgresql@14/bin/createuser -s postgres
          sudo psql -U postgres -c "CREATE USER usr WITH LOGIN SUPERUSER ENCRYPTED PASSWORD 'psw'"
          sudo psql -U postgres -c "CREATE DATABASE prostgles_desktop_db OWNER usr"
          brew install postgis
          brew services restart postgresql 

          psql --version
          cd electron
          npm run test-macos

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report-electron
          path: e2e/electron-report/
          retention-days: 10


================================================
FILE: .github/workflows/macos_test.yml
================================================
name: MacOS test
on: workflow_dispatch
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
jobs:
  test_macos:
    runs-on: macos-latest
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20
      - name: Install curl inside postgres container for video needed for demo
        run: |
          ls -la /Applications/

      - name: Install dependencies (psql with pg_dump) pg_dump version must be >= pg servers version to ensure backup/restore works
        run: |
          /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" && \
          brew install postgresql@14
          brew services restart postgresql@14
          export PATH="/opt/homebrew/opt/postgresql@14/bin:$PATH"
          /opt/homebrew/opt/postgresql@14/bin/psql --version
          /opt/homebrew/opt/postgresql@14/bin/pg_dump --version
          until pg_isready
          do
            echo "Waiting for postgres to start..."
            sleep 1
          done
          /opt/homebrew/opt/postgresql@14/bin/createuser -s postgres
          sudo psql -U postgres -c "CREATE USER usr WITH LOGIN SUPERUSER ENCRYPTED PASSWORD 'psw'"
          sudo psql -U postgres -c "CREATE DATABASE db OWNER usr"
          brew install postgis
          brew services restart postgresql 

          psql --version
          cd client && npm ci && \
          cd ../server && npm ci && \
          cd ../e2e && npm ci && npx playwright install
      - name: Run test
        run: |
          npm test

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: e2e/playwright-report/
          retention-days: 10

          # brew install pcre
          # sudo ln -s /opt/homebrew/Cellar/postgresql@16/16.0/bin/postgres /usr/local/bin/postgres
          # wget https://download.osgeo.org/postgis/source/postgis-3.4.0.tar.gz
          # tar -xvzf postgis-3.4.0.tar.gz
          # rm postgis-3.4.0.tar.gz
          # cd postgis-3.4.0
          # ./configure --with-projdir=/opt/homebrew/opt/proj --with-protobufdir=/opt/homebrew/opt/protobuf-c --with-pgconfig=/opt/homebrew/opt/postgresql@16/bin/pg_config --with-jsondir=/opt/homebrew/opt/json-c --with-sfcgal=/opt/homebrew/opt/sfcgal/bin/sfcgal-config --with-pcredir=/opt/homebrew/opt/pcre "LDFLAGS=$LDFLAGS -L/opt/homebrew/Cellar/gettext/0.22.2/lib" "CFLAGS=-I/opt/homebrew/Cellar/gettext/0.22.2/include"
          # make
          # make install

          # export PATH="/opt/homebrew/opt/postgresql@16/bin:$PATH" && \


================================================
FILE: .github/workflows/on_release.yml
================================================
name: On Release
on:
  push:
    tags:
      - "v*"
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
jobs:
  build_docker_images:
    timeout-minutes: 20
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false # Optional: Prevent other matrix jobs from being cancelled if one fails
      matrix:
        include: # Define the specific combinations you need
          - image_name: ui
            dockerfile: Dockerfile
          - image_name: ui-db
            dockerfile: DB-Dockerfile
          # Add more entries here if you have more images to build
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Extract version
        id: extract_version
        run: |
          VERSION=$(./scripts/get_version.sh)
          echo "version=v$VERSION" >> $GITHUB_OUTPUT
          echo "Extracted version: v$VERSION"

      - name: Ensure release file exists
        run: |
          pr_version=$(./scripts/get_version.sh) 
          base_ref="${{ github.base_ref }}"
          release_file_path="./releases/v${pr_version}.md"

          echo "Checking for release file: ${release_file_path}"

          if [ -f "$release_file_path" ]; then
            echo "Release file found: ${release_file_path}"
          else

            echo "Release file not found for v${pr_version}"
            echo "Ensure this file exists: ${release_file_path}"

            exit 1
          fi

      - name: Ensure docker-compose.yml image tags are updated
        run: |
          pr_version=$(./scripts/get_version.sh) 
          expected_tag="v${pr_version}"
          docker_compose_file="./docker-compose.yml"

          echo "Checking docker-compose.yml for correct image tags..."

          if grep -q "image: prostgles/ui:${expected_tag}" "$docker_compose_file" && \
             grep -q "image: prostgles/ui-db:${expected_tag}" "$docker_compose_file"; then
            echo "docker-compose.yml uses the correct image tags: ${expected_tag}"
          else
            echo "docker-compose.yml does not use the correct image tags."
            echo "Expected tags: prostgles/ui:${expected_tag} and prostgles/ui-db:${expected_tag}"
            exit 1
          fi

      - name: Create Release with Notes
        uses: softprops/action-gh-release@v2
        with:
          body_path: ./releases/${{ steps.extract_version.outputs.version }}.md
          draft: false

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build and push ui
        uses: docker/build-push-action@v6
        with:
          context: .
          file: ${{ matrix.dockerfile }}
          platforms: linux/amd64
          push: true
          tags: |
            prostgles/${{ matrix.image_name }}:latest
            prostgles/${{ matrix.image_name }}:${{ steps.extract_version.outputs.version }}

  build_linux:
    timeout-minutes: 20
    runs-on: ubuntu-latest
    needs: build_docker_images
    if: success()
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20
      - name: Build Linux
        run: |
          sudo apt-get install rpm -y && \
          cd electron && npm run build-linux
          cd dist
          sha256sum *.* > linux.checksums
          echo linux.checksums
      - name: Release Linux
        uses: softprops/action-gh-release@v2
        with:
          files: |
            electron/dist/**/*.deb
            electron/dist/**/*.rpm
            electron/dist/**/*.AppImage
            electron/dist/**/*.checksums
  build_windows:
    timeout-minutes: 20
    needs: build_docker_images
    runs-on: windows-latest
    if: success()
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20
      - name: Build Windows
        shell: cmd
        run: |
          cd electron 
          npm run build-win
          cd dist
          for /r %%f in (*.exe) DO certutil -hashfile "%%f" SHA256 > windows.checksums
          type windows.checksums
      - name: Release Windows
        uses: softprops/action-gh-release@v2
        with:
          files: |
            electron/dist/**/*.exe
            electron/dist/**/*.checksums
  build_macos:
    timeout-minutes: 20
    needs: build_docker_images
    runs-on: macos-latest
    if: success()
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - name: Build MacOS
        run: |
          cd electron 
          npm run build-macos
          rm -rf ./dist/mac-universal
          cd dist
          shasum -a 256 *.* > macos.checksums
          cat macos.checksums
      - name: Release MacOS
        uses: softprops/action-gh-release@v2
        with:
          files: |
            electron/dist/**/*.dmg
            electron/dist/**/*.checksums


================================================
FILE: .github/workflows/package_version_increased.yml
================================================
name: Ensure package version is higher
on:
  pull_request:
    branches: [main, master]
  merge_group:
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
jobs:
  test_docker:
    name: Run test suite
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Get versions
        id: pr-version
        run: |
          sudo apt  install jq
          ./scripts/get_version.sh > pr_version.txt
          git fetch origin ${{ github.base_ref }} --depth=1
          git checkout origin/${{ github.base_ref }} -- package.json ./electron/package.json
          ./scripts/get_version.sh > current_version.txt

      - name: Compare versions
        run: |
          current_version=$(cat current_version.txt)
          pr_version=$(cat pr_version.txt) 
          if [ "$(printf '%s\n' "$current_version" "$pr_version" | sort -V | head -n1)" = "$pr_version" ]; then
            echo "Version in package.json is not greater than the version in the base branch: $current_version <= $pr_version"
            exit 1
          else
            echo "Version check passed: $current_version <= $pr_version"
          fi

      - name: Ensure Changelog exists
        if: success() # Ensure version comparison passed
        run: |
          pr_version=$(cat pr_version.txt) 
          base_ref="${{ github.base_ref }}"
          release_file_path="./changelog/v${pr_version}.md"

          echo "Checking for changelog file: ${release_file_path}"

          if [ -f "$release_file_path" ]; then
            echo "Changelog file found: ${release_file_path}"
          else

            echo "Changelog file not found for v${pr_version}."
            echo "Ensure this file exists: ${release_file_path}"

            exit 1
          fi


================================================
FILE: .github/workflows/windows_test.yml
================================================
name: Windows test
on: workflow_dispatch
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
jobs:
  test_windows:
    runs-on: windows-latest
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20
      - uses: nyurik/action-setup-postgis@v2
        with:
          username: postgres
          password: postgres
          database: postgres
          port: 5432
        id: postgres
      - name: Install postgres
        run: |
          cd "C:\Program Files\PostgreSQL\14\bin"
          .\psql.exe -c "CREATE EXTENSION postgis;" "postgresql://postgres:postgres@127.0.0.1:5432/postgres"
          .\psql.exe -c "CREATE USER usr WITH LOGIN SUPERUSER ENCRYPTED PASSWORD 'psw'" "postgresql://postgres:postgres@127.0.0.1:5432/postgres"
          .\psql.exe -c "CREATE DATABASE db OWNER usr" "postgresql://postgres:postgres@127.0.0.1:5432/postgres"

      - name: Install test dependencies
        run: |
          npm config set script-shell "C:\\Program Files\\Git\\bin\\bash.exe"
          cd client
          npm ci
          cd ../server 
          npm ci
          cd ../e2e 
          npm ci 
          npx playwright install
      - name: Run test
        run: |
          npm test

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: e2e/playwright-report/
          retention-days: 10


================================================
FILE: .gitignore
================================================
node_modules
prostgles_media
prostgles_storage
prostgles_backups
prostgles_certificates
prostgles_mcp
.electron-auth.json
**/.electron-auth.json
.prostgles-desktop-config.json
**/.prostgles-desktop-config.json

scripts/demo/dist
client/build
client/static/icons
server/dist
server/media

BACKUP
.Trash-1000/
.npmrc
.npmignore
media
log.txt
ui
.aider*
.env
configs
debug
docs/screenshots/svgif-scenes

================================================
FILE: .prettierignore
================================================
e2e/playwright-report/trace/
server/*.json
client/*.json
.vscode/
*.d.ts


================================================
FILE: .prettierrc
================================================
{
  "experimentalTernaries": true
}


================================================
FILE: .vscode/settings.json
================================================
{
  "git.terminalAuthentication": false,
  "git.autofetch": false,
  "git.ignoreLimitWarning": true,
  "typescript.tsdk": "./node_modules/typescript/lib",
  "editor.formatOnSave": true,
  "prettier.experimentalTernaries": true,
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "prettier.printWidth": 100
}


================================================
FILE: DB-Dockerfile
================================================
FROM postgis/postgis:17-3.4

# Switch to root user to install packages
USER root

# procps needed for stat monitoring
RUN apt-get update && apt-get install -y procps && \
    rm -rf /var/lib/apt/lists/*

# Switch back to the default postgres user
USER postgres 

================================================
FILE: Dockerfile
================================================
FROM node:20-slim AS base

WORKDIR /usr/src/app

COPY . .

# Install latest pg_dump (psql v17) to ensure backup/restore works
RUN apt-get update && \
    apt-get install -y --no-install-recommends gnupg wget ca-certificates lsb-release && \ 
    apt-get upgrade -y && \
    sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'  && \
    wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \
    apt-get update && \
    apt-get install -y --no-install-recommends postgresql-client-17 && \
    pg_dump --version && \
    psql --version && \
    # Clean up
    apt-get clean && \
    apt-get purge -y --auto-remove gnupg wget lsb-release && \
    rm -rf /var/lib/apt/lists/*

FROM base AS deps 

WORKDIR /usr/src/app/client

RUN npm run build && cd ../server && npm run build

ENV NODE_ENV=production
ENV IS_DOCKER=yes

CMD ["node", "/usr/src/app/server/dist/server/src/index.js"]

================================================
FILE: LICENSE
================================================
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    Prostgles Desktop
    Copyright (C) 2024  Stefan L

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source.  For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code.  There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.


================================================
FILE: PRIVACY
================================================
<p>
With the exception of information you voluntarily submit via the "Send feedback" feature, Prostgles does not collect, transmit, or store any of your data on our servers.
</p>

<p>All your data is stored only in the following locations, depending on how you use the software:</p>
<ol>
  <li>
    <strong>Your connected database:</strong> Metadata such as database connections, dashboard settings, SQL queries, etc., are stored within the database you provide and connect to. Depending on the variant:
    <ul>
      <li><strong>Electron/Desktop app:</strong> Data is in the connection titled <strong>Prostgles Desktop state</strong>.</li>
      <li><strong>Source/Docker/Node.js app:</strong> Data is in the connection titled <strong>Prostgles UI state</strong>.</li>
    </ul>
  </li>
  <li>
    <strong>Your local machine:</strong> 
    <ul>
      <li><strong>Electron/Desktop app:</strong> Stores files, backups and encrypted state database connection details in your user data directory (Windows: <code>%APPDATA%/prostgles-desktop</code>, macOS: <code>~/Library/Application Support/prostgles-desktop</code>, Linux: <code>~/.config/prostgles-desktop</code>).</li>
      <li><strong>Source/Docker/Node.js app:</strong> Stores files, backups and state state database configuration in the directory where the software is run (current working directory) unless otherwise configured.</li>
    </ul>
  </li>
  <li>
    <strong>Optional cloud storage providers:</strong> If you configure file storage or backups, these providers store your data according to your setup.
  </li>
</ol>

<p>
To the best of our knowledge, all third-party libraries used in Prostgles do not collect, transmit, or store your data on their servers.
</p>


================================================
FILE: README.md
================================================
# Prostgles UI

SQL Editor and internal tool builder for Postgres

[Live demo](https://playground.prostgles.com/)

### Screenshots

[More](https://prostgles.com/ui)

<p float="left">
  <img src="https://prostgles.com/static/images/screenshot_crypto.png" width="100%"/>  
</p>

### Features

- SQL Editor with context-aware schema auto-completion and documentation extracts and hints
- Realtime data exploration dashboard with versatile layout system (tab and side-by-side view)
- Table view with controls to view related data, sort, filter and cross-filter
- Map and Time charts with aggregations
- Data insert/update forms with autocomplete
- Role based access control rules
- Isomorphic TypeScript API with schema types, end to end type safety and React hooks
- File upload (locally or to cloud)
- Search all tables from public schema
- Media file display (audio/video/image/html/svg)
- Data import (CSV, JSON and GeoJSON)
- Backup/Restore (locally or to cloud)
- TypeScript server-side functions (experimental)
- Mobile friendly
- LISTEN NOTIFY support

### Installation - Docker compose (recommended)

Download the source code:

```bash
git clone https://github.com/prostgles/ui.git
cd ui
```

Docker setup. By default the app will be accessible at [localhost:3004](http://localhost:3004).
Omit "--build" to use our published images.

```docker-compose.sh
docker compose up -d --build
```

To use a custom port (3099 for example) and/or a custom binding address (0.0.0.0 for example):

```bash
PRGL_DOCKER_IP=0.0.0.0 PRGL_DOCKER_PORT=3099 docker compose up --build
```

To use with docker mcp experimental feature:

```bash
docker compose --profile=docker-mcp up --build
```

### Installation - use existing PostgreSQL instance

Use this method if you want to use your existing database to store Prostgles metadata

Download the source code:

```bash
git clone https://github.com/prostgles/ui.git prostgles
cd prostgles
```

Build and run our docker image:

```docker-run.sh
docker build -t prostgles .
docker run --network=host -d -p 127.0.0.1:3004:3004 \
  -e POSTGRES_HOST=127.0.0.1 \
  -e POSTGRES_PORT=5432 \
  -e POSTGRES_DB=postgres \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=postgres \
  -e PROSTGLES_UI_HOST=0.0.0.0 \
  -e IS_DOCKER=yes \
  -e NODE_ENV=production \
  prostgles

```

Your server will be running on [localhost:3004](http://localhost:3004).

### Development

#### 1. Install dependencies:

- [NodeJS](https://nodejs.org/en/download)
- [Postgres](https://www.postgresql.org/download/): For full features **postgresql-17-postgis-3.4** is recommended

#### 2. Create a database and user update `.env`. All prostgles state and metadata will be stored in this database

    sudo su - postgres
    createuser --superuser usr
    psql -c "alter user usr with encrypted password 'psw'"
    createdb db -O usr

#### 3. Start app in dev mode (will install npm packages)

    npm run dev

### Testing

Ensure the app is running in development mode and:

    cd e2e && npm test-local


================================================
FILE: SECURITY.md
================================================
# Security Policy

### Reporting a Vulnerability

Please report (suspected) security vulnerabilities to security@prostgles.com

- You will receive a response from us within 7 working days.
- If the issue is confirmed, we will release a patch as soon as possible depending on complexity but historically within a few days.


================================================
FILE: changelog/v1.0.0.md
================================================
Prostgles UI v1.0.0

Workspaces
Each database connection now allows multiple workspaces. You can create and switch between different dashboards



================================================
FILE: changelog/v2.0.0.md
================================================
Prostgles UI v2

Improved UI
- Referenced tables tab
- SQL code blocks
- SQL snippets

Access control
- Role-based access rules
- API

File storage
- Saved locally or to S3
- File type and size rules

Backup and Restore
- Automatic or manual
- Saved locally or to S3

Security
- App based 2 factor-authentication
- IP subnet rules
- CORS




================================================
FILE: changelog/v2.2.0.md
================================================
- Schema Diagram
  - Link colouring modes to better understand related tables and foreign key properties
  - Filtering by relationship type, schema
- Command and settings quick search (Ctrl+K). Access any command, setting, or action through our new command palette
- AI Assistant:
  - Data access controls. Allow the assistant to execute sql with rollback, commit or specify allowed tables and commands for each chat
  - Dashboard Generation: Create dashboards from your database schema and requirements
  - Create task mode: Get suggested tools and data access permissions for the chat
  - MCP Server Tools support: Install and allow the assistant to access Model Context Protocol server tools.
  - File upload support
  - Execute sql snippets directly in chat
  - Real-time cost tracking per chat and configurable spending limits
- Improved setup for Prostgles Desktop: "Quick setup" mode handles the creation of a state database and user.


================================================
FILE: changelog/v2.2.1.md
================================================
- Maintenance and fixes:
  - Fixed docker release pipeline
  - Updated electron packages
  - Remove dead code


================================================
FILE: changelog/v2.2.2.md
================================================
- Improve documentation
- Maintenance and fixes:
  - Tidy release workflows


================================================
FILE: changelog/v2.2.3.md
================================================
- Improve documentation
- Improve Docker MCP server


================================================
FILE: changelog/v2.2.4.md
================================================
- Improve documentation
- Improve Tool use message UI
- Fix parallel MCP requests bug


================================================
FILE: client/.babelrc
================================================
{
  "presets": [
    [
      "@babel/env",
      {
        "targets": {
          "esmodules": true
        },
        "modules": false,
        "bugfixes": true
      }
    ],
    "@babel/preset-react",
    "@babel/preset-typescript"
  ],
  "plugins": ["dynamic-import-node"],
  "env": {
    "production": {
      "presets": [
        [
          "minify",
          {
            "builtIns": false,
            "evaluate": false,
            "mangle": false
          }
        ]
      ]
    }
  }
}


================================================
FILE: client/.gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*


BACKUP
dist
/configs/last_compiled.txt

================================================
FILE: client/build.sh
================================================
npm i && export NODE_ENV=production && export BABEL_ENV=production && export NODE_OPTIONS=--max-old-space-size=2048 && npm run build-start


================================================
FILE: client/eslint.config.mjs
================================================
// @ts-check
import commonConfig from "../.eslintrc.common.js";
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
import { defineConfig } from "eslint/config";
import eslintPluginReact from "eslint-plugin-react";
import eslintPluginReactHooks from "eslint-plugin-react-hooks";
// import typescriptEslint from "@typescript-eslint/eslint-plugin";

export default defineConfig(
  eslint.configs.recommended,
  tseslint.configs.recommended,
  tseslint.configs.recommendedTypeChecked,
  {
    ignores: [
      "node_modules",
      "dist",
      "examples",
      "**/*.d.ts",
      "tests",
      "docs",
      "*.mjs",
      "sample_schemas",
      "**/*.d.ts",
      "**/*.js",
    ],
  },
  {
    files: ["**/*.{ts,tsx}"],
    languageOptions: {
      parser: tseslint.parser,
      parserOptions: {
        ecmaVersion: "latest",
        sourceType: "module",
        // projectService: {
        //   allowDefaultProject: ["*.js", "*.mjs"],
        // },
        project: ["./tsconfig.eslint.json"],
        tsconfigRootDir: import.meta.dirname,
      },
    },
    plugins: {
      "@typescript-eslint": tseslint.plugin,
      react: eslintPluginReact,
      "react-hooks": eslintPluginReactHooks,
    },
    settings: {
      react: {
        version: "detect",
      },
    },
    rules: {
      ...commonConfig.rules,
      "react/no-unescaped-entities": "off",
      "react/display-name": "off",
      "react/no-children-prop": "off",
      "react/prop-types": "off",
      "react/no-unused-prop-types": "off",
      "react-hooks/exhaustive-deps": [
        "warn",
        {
          additionalHooks:
            "(usePromise|useEffectAsync|useProstglesClient|useAsyncEffectQueue|useEffectDeep)",
        },
      ],
      "no-cond-assign": "error",
      "@typescript-eslint/no-namespace": "off",
      "@typescript-eslint/no-explicit-any": "off",
      "@typescript-eslint/no-non-null-assertion": "off",
      "@typescript-eslint/ban-types": "off",
      "@typescript-eslint/ban-ts-comment": "off",
      "@typescript-eslint/no-unused-expressions": "off",
      "@typescript-eslint/no-require-imports": "off",
      "@typescript-eslint/no-empty-object-type": "off",
      "no-async-promise-executor": "off",
      "@typescript-eslint/no-var-requires": "off",
      "@typescript-eslint/no-unnecessary-condition": "error",
      "@typescript-eslint/no-floating-promises": "warn",
      "no-unused-vars": "off",
      "no-empty": "off",
      "@typescript-eslint/only-throw-error": "off",
      "@typescript-eslint/prefer-promise-reject-errors": "off",
      "@typescript-eslint/restrict-template-expressions": [
        "warn",
        {
          allowNumber: true,
          allowBoolean: true,
          allowNullish: true,
          allowArray: true,
        },
      ],
      "@typescript-eslint/no-misused-promises": [
        "warn",
        { checksVoidReturn: false },
      ],
      "@typescript-eslint/no-unsafe-assignment": "warn",
      "@typescript-eslint/no-unsafe-argument": "warn",
      "@typescript-eslint/no-unsafe-return": "warn",
      "@typescript-eslint/await-thenable": "warn",
      "@typescript-eslint/no-unsafe-member-access": "warn",
      "@typescript-eslint/no-unsafe-call": "warn",
      "@typescript-eslint/no-unused-vars": [
        "warn",
        {
          argsIgnorePattern: "^_",
          varsIgnorePattern: "^_",
          caughtErrorsIgnorePattern: "^_",
        },
      ],
    },
  },
);


================================================
FILE: client/package.json
================================================
{
  "name": "prostgles-ui-client",
  "dependencies": {
    "@mdi/js": "^7.4.47",
    "@types/dom-speech-recognition": "^0.0.6",
    "d3": "^7.9.0",
    "deck.gl": "^9.1.14",
    "loaders.gl": "^0.3.5",
    "monaco-editor": "^0.53.0",
    "papaparse": "^5.4.1",
    "prostgles-client": "^4.0.270",
    "qrcode": "^1.5.1",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-flip-move": "^3.0.5",
    "react-markdown": "^10.1.0",
    "react-router-dom": "^7.5.2",
    "rehype-raw": "^7.0.0",
    "remark-gfm": "^4.0.1",
    "sanitize-html": "^2.13.0",
    "socket.io-client": "^4.8.1",
    "sql-formatter": "^15.3.2",
    "strip-ansi": "^7.1.2",
    "tsconfig-paths-webpack-plugin": "^4.2.0"
  },
  "scripts": {
    "prod": "NODE_ENV=production BABEL_ENV=production webpack",
    "start": "node scripts/start.js --no-cache",
    "build-start": "rm -rf ./build && webpack --config=configs/prod.js && rm -rf ./node_modules",
    "build": "bash ./build.sh",
    "dev": "npm i --no-audit --quiet && NODE_OPTIONS='--max-old-space-size=4048' && webpack --watch --config=configs/dev.js",
    "lib": "rm -rf ./dist && tsc --project tsconfig_lib.json && npm run copyf",
    "copyf": "cd ./src && find . -name '*.css' -type f -exec cp --parents {} ../dist/ \\; ",
    "copyf2": "find ./src/. -name '*.css' | cpio -pdm ./dist/",
    "lint": "eslint . --quiet --fix",
    "tsc": "tsc --noEmit"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@babel/core": "^7.28.5",
    "@babel/plugin-transform-runtime": "^7.28.5",
    "@babel/plugin-transform-typescript": "^7.28.5",
    "@babel/preset-env": "^7.28.5",
    "@babel/preset-react": "^7.28.5",
    "@babel/preset-typescript": "^7.28.5",
    "@babel/runtime": "^7.28.4",
    "@eslint/js": "^9.39.1",
    "@types/d3": "^7.4.3",
    "@types/dom-mediacapture-record": "^1.0.10",
    "@types/papaparse": "^5.3.1",
    "@types/qrcode": "^1.4.2",
    "@types/react": "^18.3.7",
    "@types/react-dom": "^18.3.0",
    "@types/react-router-dom": "^5.1.5",
    "@types/resize-observer-browser": "^0.1.6",
    "@types/sanitize-html": "^2.6.2",
    "@types/webpack": "^4.41.25",
    "@typescript-eslint/eslint-plugin": "^8.48.0",
    "@typescript-eslint/parser": "^8.48.0",
    "babel-loader": "^9.1.3",
    "babel-plugin-dynamic-import-node": "^2.3.3",
    "babel-plugin-named-asset-import": "^0.3.8",
    "babel-preset-minify": "^0.5.1",
    "circular-dependency-plugin": "^5.2.2",
    "copy-webpack-plugin": "^12.0.2",
    "css-loader": "^6.8.1",
    "eslint": "^9.39.1",
    "eslint-plugin-react": "^7.37.5",
    "eslint-plugin-react-hooks": "^7.0.1",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.6.3",
    "interpolate-html-plugin": "^4.0.0",
    "mini-css-extract-plugin": "^2.7.1",
    "monaco-editor-webpack-plugin": "^7.1.0",
    "postcss": "^8.5.3",
    "postcss-flexbugs-fixes": "^5.0.2",
    "postcss-loader": "^7.3.4",
    "postcss-normalize": "^10.0.1",
    "postcss-preset-env": "^7.8.3",
    "postcss-safe-parser": "^6.0.0",
    "prettier": "^3.4.2",
    "sass-loader": "^16.0.4",
    "style-loader": "^4.0.0",
    "ts-loader": "^9.5.1",
    "typescript": "^5.9.3",
    "typescript-eslint": "^8.48.0",
    "url-loader": "^4.1.1",
    "webpack": "^5.99.7",
    "webpack-bundle-analyzer": "^4.10.2",
    "webpack-cli": "^6.0.1",
    "webpack-manifest-plugin": "^5.0.0",
    "webpack-merge": "^6.0.1",
    "webpack-shell-plugin-next": "^2.3.2"
  }
}


================================================
FILE: client/public/manifest.json
================================================
{
  "name": "Prostgles UI",
  "short_name": "Prostgles UI",
  "description": "Dashboard and SQL editor for PostgreSQL.",
  "display": "standalone",
  "icons": [
    {
      "src": "/prostgles-logo.svg",
      "sizes": "any"
    }
  ]
}


================================================
FILE: client/public/robots.txt
================================================
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:


================================================
FILE: client/setup-icons.js
================================================
/** Save all mdi icons as xml */
const fs = require("fs");
const path = require("path");
const icons = require("@mdi/js");

const saveMdiIcons = () => {
  const iconEntries = Object.entries(icons);
  const iconsDestinationFolder = path.join(__dirname, "/static/icons");
  if (fs.existsSync(iconsDestinationFolder)) {
    const contents = fs.readdirSync(iconsDestinationFolder);
    if (contents.length >= iconEntries.length) {
      return;
    }
    fs.rm(iconsDestinationFolder, { recursive: true }, console.log);
  }
  fs.mkdirSync(iconsDestinationFolder, { recursive: true });
  if (!iconEntries.length) {
    console.error("No icons found. Did you run npm i ?!");
    process.exit(1);
  }

  const iconNames = [];
  iconEntries.forEach(([name, iconPathD]) => {
    const nameWithoutMdi = name.slice(3);
    iconNames.push(nameWithoutMdi);
    const iconSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="presentation">
      <path d=${JSON.stringify(iconPathD)} style="fill: currentcolor;"></path>
    </svg>`;
    fs.writeFileSync(
      path.join(iconsDestinationFolder, `${name.slice(3)}.svg`),
      iconSvg,
      { encoding: "utf8" },
    );
  });
  console.log(` Saved ${iconEntries.length} icons`);
  fs.writeFileSync(
    path.join(iconsDestinationFolder, "_meta.json"),
    JSON.stringify(iconNames, null, 2),
    { encoding: "utf8" },
  );
};

setTimeout(saveMdiIcons, 1000);

class SaveMdiIcons {
  apply(compiler) {
    compiler.hooks.afterEmit.tap(
      "Save Mdi icons plugin afterEmit",
      (_stats) => {
        setTimeout(saveMdiIcons, 1000);
      },
    );
    compiler.hooks.done.tap("Save Mdi icons plugin done", (_stats) => {
      setTimeout(saveMdiIcons, 1000);
    });
  }
}

module.exports = { SaveMdiIcons };


================================================
FILE: client/src/App.css
================================================
*,
body,
html {
  box-sizing: border-box;
}

body {
  overflow: hidden;
}

.page-content {
  padding-top: 1em;
}

.active-code-block-decoration {
  background: lightblue;
  width: 5px !important;
  margin-left: 3px;
}

.active-code-block-play {
  margin-left: 4px;
}

.dark-theme .active-code-block-decoration {
  background: #14708f;
}

.dark-theme * {
  color-scheme: dark;
}


================================================
FILE: client/src/App.tsx
================================================
import type { ReactChild } from "react";
import React, { useMemo, useState } from "react";
import { Navigate, Route, Routes as Switch } from "react-router-dom";
import "./App.css";
import Loading from "./components/Loader/Loading";
import type { CommonWindowProps } from "./dashboard/Dashboard/Dashboard";
import { t } from "./i18n/i18nUtils";
import { Connections } from "./pages/Connections/Connections";
import NewConnnection from "./pages/NewConnection/NewConnnectionForm";
import { NotFound } from "./pages/NotFound";
import { ProjectConnection } from "./pages/ProjectConnection/ProjectConnection";

import ErrorComponent from "./components/ErrorComponent";
import UserManager from "./dashboard/UserManager";
import { Account } from "./pages/Account/Account";
import { ServerSettings } from "./pages/ServerSettings/ServerSettings";

import type { ProstglesState } from "@common/electronInitTypes";
import type { DBSSchema } from "@common/publishUtils";
import { fixIndent, ROUTES } from "@common/utils";
import type { AuthHandler } from "prostgles-client/dist/getAuthHandler";
import {
  type DBHandlerClient,
  type MethodHandler,
} from "prostgles-client/dist/prostgles";
import { type Socket } from "socket.io-client";
import { CommandPalette } from "./app/CommandPalette/CommandPalette";
import { Documentation } from "./app/CommandPalette/Documentation";
import { XRealIpSpoofableAlert } from "./app/XRealIpSpoofableAlert";
import { createReactiveState, useReactiveState } from "./appUtils";
import { AlertProvider } from "./components/AlertProvider";
import { FlexCol, FlexRow } from "./components/Flex";
import { InfoRow } from "./components/InfoRow";
import { NavBarWrapper } from "./components/NavBar/NavBarWrapper";
import { PostgresInstallationInstructions } from "./components/PostgresInstallationInstructions";
import type { DBS, DBSMethods } from "./dashboard/Dashboard/DBS";
import { MousePointer } from "./demo/MousePointer";
import { ComponentList } from "./pages/ComponentList";
import { ElectronSetup } from "./pages/ElectronSetup/ElectronSetup";
import { Login } from "./pages/Login/Login";
import { NonHTTPSWarning } from "./pages/NonHTTPSWarning";
import { useAppTheme } from "./theme/useAppTheme";
import { useAppState } from "./useAppState/useAppState";

export type ClientUser = {
  sid: string;
  uid: string;
  type: string;
  has_2fa: boolean;
} & DBSSchema["users"];

export type ClientAuth = {
  user?: ClientUser;
};
export type Theme = "dark" | "light";
export type PrglReadyState = {
  /**
   * Used to re-render dashboard on dbs reconnect
   */
  dbsKey: string;
  dbs: DBS;
  dbsTables: CommonWindowProps["tables"];
  dbsMethods: DBSMethods;
  dbsSocket: Socket;
  auth: AuthHandler<ClientUser>;
  isAdminOrSupport: boolean;
  sid: string | undefined;
};
export type ExtraProps = PrglReadyState & {
  setTitle: (content: string | ReactChild) => void;
  user: DBSSchema["users"] | undefined;
  dbsSocket: Socket;
  theme: Theme;
} & Pick<Required<AppState>, "serverState">;

export type PrglStateCore = Pick<
  ExtraProps,
  "dbs" | "dbsMethods" | "dbsTables"
>;
export type PrglState = ExtraProps;

export type PrglCore = {
  db: DBHandlerClient;
  methods: MethodHandler;
  tables: CommonWindowProps["tables"];
};
export type PrglProject = PrglCore & {
  dbKey: string;
  connectionId: string;
  databaseId: number;
  projectPath: string;
  connection: DBSSchema["connections"];
};
export type Prgl = PrglState & PrglProject;

export type AppState = {
  prglState?: PrglReadyState;
  user: DBSSchema["users"] | undefined;
  serverState?: ProstglesState;
  title: React.ReactNode;
  isConnected: boolean;
};

export const r_useAppVideoDemo = createReactiveState({ demoStarted: false });

export const App = () => {
  const [isDisconnected, setIsDisconnected] = useState(false);
  const state = useAppState(setIsDisconnected);
  const [title, setTitle] = useState<React.ReactNode>("");
  const {
    state: { demoStarted },
  } = useReactiveState(r_useAppVideoDemo);

  const { theme, userThemeOption } = useAppTheme(state);
  const extraProps: PrglState | undefined = useMemo(
    () =>
      state.prglState &&
      state.serverState && {
        ...state.prglState,
        setTitle: (content: ReactChild) => {
          if (title !== content) setTitle(content);
        },
        user: state.user,
        theme,
        serverState: state.serverState,
      },
    [state, theme, title],
  );

  const { initState } = state.serverState ?? {};
  const initStateError = initState?.state === "error" ? initState : undefined;
  if (
    state.serverState?.isElectron &&
    ((state.state !== "loading" && state.state !== "ok") ||
      !state.serverState.electronCredsProvided ||
      initStateError)
  ) {
    return <ElectronSetup serverState={state.serverState} />;
  }

  const unknownErrorMessage =
    "Something went wrong with initialising the server. Check console for more details";
  const error =
    state.dbsClientError ||
    (initState?.state === "error" ?
      initState.error || unknownErrorMessage
    : undefined);

  const { prglState, serverState, state: _state } = state;
  if (!error && (!prglState || !serverState || _state === "loading")) {
    return (
      <div className="flex-row m-auto ai-center jc-center  p-2">
        <Loading id="main" message="Connecting to state database..." />
      </div>
    );
  }

  if (error || !prglState || !serverState || !extraProps) {
    const hint =
      state.dbsClientError ?
        errorHints.dbsClientError
      : initStateError?.errorType && errorHints[initStateError.errorType];
    return (
      <FlexCol className="m-auto ai-center jc-center max-w-700 p-2">
        <FlexRow>
          <ErrorComponent
            error={error}
            variant="outlined"
            className="p-2"
            withIcon={true}
          />
          {initStateError?.errorType === "connection" && (
            <PostgresInstallationInstructions placement="state-db" os="linux" />
          )}
        </FlexRow>
        {hint && (
          <InfoRow color="warning" variant="naked">
            {hint}
          </InfoRow>
        )}
      </FlexCol>
    );
  }
  const isElectron = !!serverState.isElectron;
  return (
    <AlertProvider>
      <FlexCol key={prglState.dbsKey} className={`App gap-0 f-1 min-h-0`}>
        <CommandPalette isElectron={isElectron} />
        <XRealIpSpoofableAlert {...state} />
        {demoStarted && <MousePointer />}
        {isDisconnected && (
          <Loading
            message={t.App["Reconnecting..."]}
            variant="cover"
            style={{ zIndex: 467887 }}
          />
        )}
        <NonHTTPSWarning {...prglState} />
        <Switch>
          <Route
            key="0"
            path="/"
            element={<Navigate to={ROUTES.CONNECTIONS} replace />}
          />
          <Route
            key="1"
            path={ROUTES.CONNECTIONS}
            element={
              <NavBarWrapper
                extraProps={extraProps}
                needsUser={true}
                userThemeOption={userThemeOption}
              >
                <Connections {...extraProps} />
              </NavBarWrapper>
            }
          />
          <Route
            key="2"
            path={ROUTES.USERS}
            element={
              <NavBarWrapper
                extraProps={extraProps}
                needsUser={false}
                userThemeOption={userThemeOption}
              >
                <UserManager {...extraProps} />
              </NavBarWrapper>
            }
          />
          <Route
            key="3"
            path={ROUTES.ACCOUNT}
            element={
              <NavBarWrapper
                extraProps={extraProps}
                needsUser={false}
                userThemeOption={userThemeOption}
              >
                <Account {...extraProps} />
              </NavBarWrapper>
            }
          />
          <Route
            key="4"
            path={`${ROUTES.CONNECTIONS}/:connectionId`}
            element={<ProjectConnection prglState={extraProps} />}
          />
          <Route
            key="5"
            path={ROUTES.NEW_CONNECTION}
            element={
              <NewConnnection
                connectionId={undefined}
                db={undefined}
                prglState={extraProps}
                showTitle={true}
              />
            }
          />
          <Route
            key="6"
            path={`${ROUTES.EDIT_CONNECTION}/:id`}
            element={
              <NewConnnection
                connectionId={undefined}
                db={undefined}
                prglState={extraProps}
                showTitle={true}
              />
            }
          />
          <Route
            key="7"
            path={`${ROUTES.CONFIG}/:connectionId`}
            element={
              <ProjectConnection
                prglState={extraProps}
                showConnectionConfig={true}
              />
            }
          />
          <Route
            key="8"
            path={ROUTES.SERVER_SETTINGS}
            element={
              <NavBarWrapper
                extraProps={extraProps}
                needsUser={true}
                userThemeOption={userThemeOption}
              >
                <ServerSettings {...extraProps} />
              </NavBarWrapper>
            }
          />
          <Route
            key="9"
            path={ROUTES.COMPONENT_LIST}
            element={
              <NavBarWrapper
                extraProps={extraProps}
                needsUser={false}
                userThemeOption={userThemeOption}
              >
                <ComponentList />
              </NavBarWrapper>
            }
          />
          <Route
            key="10"
            path={ROUTES.LOGIN}
            element={<Login {...extraProps} />}
          />
          <Route
            key="11"
            path={ROUTES.DOCUMENTATION}
            element={
              <NavBarWrapper
                extraProps={extraProps}
                needsUser={false}
                userThemeOption={userThemeOption}
              >
                <Documentation isElectron={isElectron} />
              </NavBarWrapper>
            }
          />
          <Route key="12" path="*" element={<NotFound />} />
        </Switch>
      </FlexCol>
    </AlertProvider>
  );
};

const errorHints = {
  connection: fixIndent(`
    Could not connect to state database. Ensure /server/.env file (or
    environment variables) point to a running and accessible postgres
    server database`),
  init: "Failed to start Prostgles",
  dbsClientError:
    "Failed to connect to state database. Try refreshing the page or restarting the app.",
};

export * from "./appUtils";


================================================
FILE: client/src/Testing.ts
================================================
export const COMMANDS = {
  "NewConnectionForm.connectionName": "Connection name input field",
  "NewConnectionForm.connectionType": "Connection type select field",
  "NewConnectionForm.db_conn": "Database connection input field",
  "NewConnectionForm.db_host": "Database host input field",
  "NewConnectionForm.db_port": "Database port input field",
  "NewConnectionForm.db_user": "Database user input field",
  "NewConnectionForm.db_pass": "Database password input field",
  "NewConnectionForm.db_name": "Database name input field",
  "NewConnectionForm.MoreOptionsToggle": "",
  "NewConnectionForm.schemaFilter": "",
  "NewConnectionForm.connectionTimeout": "Connection timeout input field",
  "NewConnectionForm.sslMode": "SSL mode select field",
  "NewConnectionForm.watchSchema": "Watch schema toggle",
  "NewConnectionForm.realtime": "Realtime toggle",
  "NewConnectionForm.testConnection": "Test connection button",

  "config.goToConnDashboard": "Go to connection workspace ",
  "config.details": "",
  "config.bkp": "",
  "config.tableConfig": "",
  "config.bkp.create": "",
  "config.bkp.create.name": "Backup name input field",
  "config.bkp.create.start": "",
  "config.bkp.AutomaticBackups": "",
  "config.bkp.AutomaticBackups.toggle": "",
  "config.ac": { desc: "", uiOnly: true },
  "config.status": "",
  "config.ac.create": "",
  "config.ac.save": "",
  "config.ac.removeRule": "",
  "config.ac.cancel": "",
  "config.ac.createDefault": "",
  "config.ac.edit.user": "Opens select/edit access rule user types",
  "config.ac.edit.user.select": "User type select search box",
  "config.ac.edit.user.select.create":
    "Creates a user type when the search did not yield any results",
  "config.ac.edit.user.select.done": "Closes create user popup",

  "config.ac.edit.type":
    "Rule type button group. Each button.value will contain the type",

  "config.ac.edit.dataAccess": "Data access section with tables/runsql",

  "config.ac.edit.createWorkspaces": "",
  "config.ac.edit.publishedWorkspaces": "",

  "config.ac.edit.typeCustom.tables": "",
  "config.ac.edit.typeAll": "",
  "config.ac.edit.typeSQL": "",
  "config.files": "",
  "config.files.toggle": "",
  "config.files.toggle.confirm": "",
  "config.api": { desc: "", uiOnly: true },
  "config.methods": "",

  "dashboard.window.rowInsert": "Open row insert panel",
  "dashboard.window.rowInsertTop": "Open row insert panel from top filter bar",

  "W_SQLMenu.name": "",
  "W_SQLMenu.renderDisplayMode": "",
  "W_SQLMenu.saveQuery": "",
  "W_SQLMenu.openSQLFile": "",
  "W_SQLMenu.deleteQuery": "",

  "W_SQLEditor.executeStatement": "Executes the current SQL statement",
  W_SQLEditor: "",
  W_SQLBottomBar: "",
  "W_SQLBottomBar.runQuery":
    "Executes the current query (selected, block or full)",
  "W_SQLBottomBar.limit": "",
  "W_SQLBottomBar.queryDuration": "",
  "W_SQLBottomBar.cancelQuery": "Cancels the current query",
  "W_SQLBottomBar.terminateQuery": "Terminates the current query",
  "W_SQLBottomBar.stopListen": "Terminates the current LISTEN query",
  "W_SQLBottomBar.toggleTable": "",
  "W_SQLBottomBar.toggleCodeEditor": "",
  "W_SQLBottomBar.toggleNotices": "",
  "W_SQLBottomBar.stopLoopQuery": "Stop loop query",
  "W_SQLBottomBar.copyResults": "Copy results",
  "W_SQLBottomBar.rowCount": "Row count",
  "W_SQLBottomBar.sqlError": "SQL error",

  W_SQLResults: "",
  "Window.W_QuickMenu": "Quick menu for the current window",
  "Window.ChildChart": "",
  "Window.ChildChart.toolbar": "",

  "dashboard.window.fullscreen": "fullscreen",
  "dashboard.window.close": "close",
  "dashboard.window.collapse": "collapse",
  "dashboard.window.viewEditRow": "",
  "dashboard.window.toggleFilterBar": "",
  "dashboard.window.menu": "",

  "dashboard.window.detachChart": "",
  "dashboard.window.collapseChart": "",
  "dashboard.window.closeChart": "",
  "dashboard.window.chartMenu": "",
  "dashboard.window.restoreMinimisedCharts": "",

  "dashboard.goToConnConfig": "Go to connection config",
  "dashboard.menu.settingsToggle": "",
  "dashboard.menu.settings.defaultLayoutType": "",
  "dashboard.menu.settings": "",
  "dashboard.menu": "",
  "dashboard.menu.sqlEditor": "",
  "dashboard.menu.quickSearch": "",
  "dashboard.menu.resize": "",
  "dashboard.centered-layout.resize": "",
  "dashboard.menu.fileTable": "",
  "dashboard.menu.savedQueriesList": "",
  "dashboard.menu.tablesSearchList": "",
  "dashboard.menu.tablesSearchListInput": "",
  "dashboard.menu.serverSideFunctionsList": "",
  "dashboard.menu.create": "",
  "dashboard.menu.createTable": "",
  "dashboard.menu.createTable.tableName": "",
  "dashboard.menu.createTable.addColumn": "",
  "dashboard.menu.createTable.addColumn.confirm": "",
  "dashboard.menu.createTable.confirm": "",

  "W_TableMenu_TableInfo.name": "",
  "W_TableMenu_TableInfo.comment": "",
  "W_TableMenu_TableInfo.oid": "",
  "W_TableMenu_TableInfo.type": "",
  "W_TableMenu_TableInfo.owner": "",
  "W_TableMenu_TableInfo.sizeInfo": "",
  "W_TableMenu_TableInfo.viewDefinition": "",
  "W_TableMenu_TableInfo.vacuum": "",
  "W_TableMenu_TableInfo.vacuumFull": "",
  "W_TableMenu_TableInfo.drop": "",

  "W_TableMenu_ColumnList.alter": "",
  "W_TableMenu_ColumnList.linkedColumnOptions": "",
  "W_TableMenu_ColumnList.removeComputedColumn": "",

  TableHeader: "",
  "TableHeader.resizeHandle": "",

  "FormField.clear": "Clear a FormField",

  SmartForm: "",
  "SmartForm.header.tableIconAndName": "",
  "SmartForm.header.previousRow": "",
  "SmartForm.header.nextRow": "",

  "SmartForm.close": "Close dialog",
  "SmartForm.delete": "Deletes row",
  "SmartForm.delete.confirm": "Confirms Deleting a row",
  "SmartForm.update": "update row",
  "SmartForm.update.confirm": "Confirms update a row",
  "SmartForm.insert": "Confirms Deleting a row",
  "SmartForm.clone": "Confirms Deleting a row",

  "SQLSmartEditor.Run": "Run the sql statement",

  "SearchList.toggleAll": "",
  "SearchList.List": "",
  "SearchList.Input": "",
  ViewMoreSmartCardList: "",
  "Section.toggleFullscreen": "",
  FieldFilterControl: "",
  "FieldFilterControl.type": "",
  "FieldFilterControl.type.custom": "",
  "FieldFilterControl.type.except": "",
  "FieldFilterControl.select": "",
  "RenderFilter.edit": "",
  "RenderFilter.done": "",

  ForcedFilterControl: "",
  "ForcedFilterControl.type": "",
  "ForcedFilterControl.type.disabled": "",
  "ForcedFilterControl.type.enabled": "",

  CheckFilterControl: "",
  "CheckFilterControl.type": "",
  "CheckFilterControl.type.disabled": "",
  "CheckFilterControl.type.enabled": "",

  selectRule: "",
  selectRuleAdvanced: "",
  updateRule: "",
  updateRuleAdvanced: "",
  deleteRule: "",
  deleteRuleAdvanced: "",
  insertRule: "",
  insertRuleAdvanced: "",
  syncRule: "",
  syncRuleAdvanced: "",

  SearchAll: "",
  SmartAddFilter: "",
  FilterWrapper: "",
  "FilterWrapper.typeSelect": "",
  FileBtn: "",

  "ForcedDataControl.toggle": "",
  "ForcedDataControl.addColumn": "",
  "TablePermissionControls.close": "",
  "TablePermissionControls.done": "",

  Connections: "",
  "Connections.add": "add",
  "Connections.new": " ",
  "Connection.openConnection": "Open connection",
  "Connection.workspaceList": "Connection workspace list",

  "Connection.closeAllWindows": "",
  "Connection.statusMonitor": "",
  "Connection.configure": "",
  "Connection.edit": "",
  "Connection.edit.updateOrCreateConfirm": "",
  "Connection.edit.delete": "",
  "Connection.edit.delete.dropDatabase": "",
  "Connection.edit.delete.confirm": "",

  "Connection.disconnect": "",

  "ConnectionServer.add": "",
  "ConnectionServer.add.newDatabase": "",
  "ConnectionServer.add.existingDatabase": "",
  "ConnectionServer.NewDbName": "",
  "ConnectionServer.add.confirm": "",

  "SmartFilterBar.toggle": "",
  "SmartFilterBar.rightOptions.show": "",
  "SmartFilterBar.rightOptions.update": "",
  "SmartFilterBar.rightOptions.delete": "",

  "ColumnEditor.name": "",
  "ColumnEditor.dataType": "",

  AddColumnMenu: "",

  WorkspaceAddBtn: "",
  WorkspaceMenuDropDown: "",
  "WorkspaceMenuDropDown.WorkspaceAddBtn": "",
  "WorkspaceMenu.SearchList": "",
  "WorkspaceMenu.CloneWorkspace": "",
  "WorkspaceMenu.toggleWorkspaceLayoutMode": "",
  WorkspaceDeleteBtn: "",
  "WorkspaceDeleteBtn.Confirm": "",

  JoinPathSelectorV2: "",
  "LinkedColumn.Add": "",
  "LinkedColumn.ColumnList.toggle": "",

  "SummariseColumn.toggle": "",
  FunctionSelector: "",
  "SummariseColumn.apply": "",
  "Popup.header": "",
  "Popup.close": "",
  "Popup.content": "",
  "Popup.footer": "",
  "Popup.toggleFullscreen": "",
  "PopupSection.fullscreen": "",
  "PopupSection.content": "",
  "LinkedColumn.ColumnListMenu": "",
  "AddChartMenu.Map": "",
  "AddChartMenu.Timechart": "",
  W_TimeChart: "",
  "W_TimeChart.ActiveRow": "",
  "W_TimeChart.AddTimeChartFilter": "",
  SmartFormField: "",

  "CloseSaveSQLPopup.delete": "",

  SchemaGraph: "",
  "SchemaGraph.TopControls": "",
  "SchemaGraph.TopControls.tableRelationsFilter": "",
  "SchemaGraph.TopControls.columnRelationsFilter": "",
  "SchemaGraph.TopControls.linkColorMode": "",
  "SchemaGraph.TopControls.resetLayout": "",
  AddColumnReference: "",
  "SmartFormFieldOptions.AttachFile": "",
  RuleToggle: "",
  "table.options.displayMode": "",
  "table.options.cardView.groupBy": "",
  "table.options.cardView.orderBy": "",
  "CardView.row": "",
  "CardView.group": "",
  "CardView.DragHeader": "",

  "CreateFileColumn.confirm": "",
  "AppDemo.start": "",
  MenuList: "",
  ComparablePGPolicies: "",
  "ConnectionServer.SampleSchemas": "",
  "dashboard.goToConnections": "",
  QuickAddComputedColumn: "",
  "SmartSelect.Done": "",
  "SmartAddFilter.JoinTo": "",
  "SmartAddFilter.toggleIncludeLinkedColumns": "",
  ContextDataSelector: "",
  ClickCatchOverlay: "",
  "BackupControls.Restore": "",
  ChartLayerManager: "",
  "App.colorScheme": "",
  "ElectronSetup.Next": "",
  "ElectronSetup.Back": "",
  PostgresInstallationInstructions: "",
  "PostgresInstallationInstructions.Close": "",
  "ElectronSetup.Done": "",
  SmartCardList: "",
  "AutomaticBackups.destination": "",
  "AutomaticBackups.frequency": "",
  "AutomaticBackups.hourOfDay": "",
  "WorkspaceAddBtn.Create": "",
  MapOpacityMenu: "",
  MapBasemapOptions: "",
  "InMapControls.goToDataBounds": "",
  "InMapControls.showCursorCoords": "",
  LayerColorPicker: "",
  "W_TimeChart.resetExtent": "",
  TimeChartFilter: "",
  "ChartLayerManager.toggleLayer": "",
  "ChartLayerManager.removeLayer": "",
  "ChartLayerManager.AddChartLayer.addLayer": "",
  "ChartLayerManager.AddChartLayer.addOSMLayer": "",
  ConnectionSelector: "",
  "Setup2FA.Enable": "",
  "Setup2FA.Enable.GenerateQR": "",
  "Setup2FA.Enable.CantScanQR": "",
  "Setup2FA.Enable.Base64Secret": "",
  "Setup2FA.Enable.ConfirmCode": "",
  "Setup2FA.Enable.Confirm": "",
  "Setup2FA.Disable": "",
  "Setup2FA.error": "",
  "DashboardMenuHeader.togglePinned": "",
  "BackupControls.DeleteAll": "",
  "BackupControls.DeleteAll.Confirm": "",
  "ProjectConnection.error": "",
  NotFound: "",
  "NotFound.goHome": "",
  "ConnectionServer.NewUserName": "",
  "ConnectionServer.NewUserPassword": "",
  "ConnectionServer.NewUserPermissionType": "",
  "ConnectionServer.withNewOwnerToggle": "",
  "W_Table.TableNotFound": "",
  JoinedRecords: "",
  "JoinedRecords.AddRow": "",
  "JoinedRecords.SectionToggle": "",
  "JoinedRecords.Section": "",
  "SmartCard.viewEditRow": "",
  "TimeChartLayerOptions.yAxis": "",
  "TimeChartLayerOptions.aggFunc": "",
  "TimeChartLayerOptions.aggFunc.select": "",
  "TimeChartLayerOptions.groupBy": "",
  "TimeChartLayerOptions.numericColumn": "",
  "AgeFilter.comparator": "",
  "AgeFilter.argsLeftToRight": "",
  "Login.error": "",
  AskLLMAccessControl: "",
  "AskLLMAccessControl.AllowAll": "",
  "Chat.messageList": "",
  "Chat.sendWrapper": "",
  "Chat.send": "",
  "Chat.sendStop": "",
  "Chat.addFiles": "",
  "Chat.textarea": "",
  "Chat.speech": "",
  AskLLM: "",
  "AskLLM.popup": "",
  SetupLLMCredentials: "",
  "SetupLLMCredentials.free": "",
  "SetupLLMCredentials.api": "",
  "AskLLMAccessControl.llm_daily_limit": "",

  DeckGLFeatureEditor: "",
  "MapBasemapOptions.Projection": "",

  SmartFilterBar: "",
  SearchList: "",
  "SearchList.MatchCase": "",
  AddJoinFilter: "",
  Pagination: "",
  "Pagination.page": "",
  "Pagination.lastPage": "",
  "Pagination.nextPage": "",
  "Pagination.prevPage": "",
  "Pagination.firstPage": "",
  "Pagination.pageCountInfo": "",
  "Pagination.pageSize": "",
  MapExtentBehavior: "",
  AddLLMCredentialForm: "",
  "AddLLMCredentialForm.Save": "",
  "AddLLMCredentialForm.Provider": "",
  "App.LanguageSelector": "",
  "EmailAuthSetup.SignupType": "",
  EmailAuthSetup: "",
  "EmailAuthSetup.error": "",
  "EmailAuthSetup.toggle": "",
  EmailSMTPAndTemplateSetup: "",
  "EmailSMTPAndTemplateSetup.save": "",
  "Login.toggle": "",
  AuthNotifPopup: "",
  "ProstglesSignup.continue": "",
  "PublishedMethods.deleteFunction": "",
  "SmartFormFieldOptions.NestedInsert": "",

  "Btn.ClickConfirmation": "",
  "Btn.ClickConfirmation.Confirm": "",
  AddMCPServer: "",
  "AddMCPServer.Open": "",
  "AddMCPServer.Add": "",
  "LLMChatOptions.MCPTools": "",
  "LLMChatOptions.DatabaseAccess": "",
  "MCPServersToolbar.stopAllToggle": "",
  "MCPServersToolbar.searchTools": "",
  ConnectionsOptions: "",
  "ConnectionsOptions.showStateDatabase": "",
  "ConnectionsOptions.showDatabaseNames": "",
  "AuthProviderSetup.websiteURL": "",
  "AuthProviderSetup.defaultUserType": "",
  "AuthProviders.list": "",
  EmailSMTPSetup: "",
  EmailTemplateSetup: "",
  "WorkspaceMenu.list": "",
  WorkspaceSettings: "",
  "LLMChatOptions.toggle": "",
  "LLMChat.select": "",
  "LLMChatOptions.Prompt": "",
  "LLMChatOptions.Model": "",
  "AskLLMChat.NewChat": "",
  "AskLLMChat.LoadSuggestedToolsAndPrompt": "",
  "AskLLMChat.LoadSuggestedDashboards": "",
  "AskLLMChat.UnloadSuggestedDashboards": "",
  "AskLLMToolApprover.AllowAlways": "",
  "AskLLMToolApprover.AllowOnce": "",
  "AskLLMToolApprover.Deny": "",
  MonacoEditor: "",
  MCPServerTools: "",
  "MCPServerFooterActions.logs": "",
  "MCPServerFooterActions.config": "",
  "MCPServerFooterActions.enableToggle": "",
  "MCPServerFooterActions.refreshTools": "",
  MCPServerConfigButton: "",
  MCPServerConfig: "",
  "MCPServerConfig.save": "",
  "MCPServers.toggleAutoApprove": "",
  Feedback: "",
  "FileImporterFooter.import": "",

  Sessions: "Active sessions list",
  "Account.ChangePassword": "Change password",
  NavBar: "",
  "NavBar.mobileMenuToggle": "",
  "NavBar.logout": "",
  CommandPalette: "",
  "Chat.attachedFiles": "",
  "Window.W_QuickMenu.addCrossFilteredTable": "Add cross-filtered table",
  Alert: "Alert popup",
  ErrorComponent: "",
  ToolUseMessage: "",
  "ToolUseMessage.toggle": "",
  "ToolUseMessage.Popup": "",
  MarkdownMonacoCode: "",
  "MCPServersInstall.install": "",
  NewConnectionForm: "",
  "BackupsControls.Completed": "Completed backups list",
  "AllowedOriginCheck.FormField": "",
  "APIDetailsWs.Examples": "",
  "APIDetailsHttp.Examples": "",
  AllowedOriginCheck: "",
  "APIDetailsTokens.CreateToken": "",
  "APIDetailsTokens.CreateToken.daysUntilExpiration": "",
  "APIDetailsTokens.CreateToken.generate": "",
  APIDetailsTokens: "",
  "AskLLM.DeleteMessage": "",
  "DockerSandboxCreateContainer.Logs": "",
  TableBody: "",
  "ServerSideFunctions.onMountEnabled": "",
  DashboardMenu: "",
  "SearchAll.Popup": "",

  AddComputedColMenu: "",
  "AddComputedColMenu.countOfAllRows": "",
  "AddComputedColMenu.addBtn": "",
  "AddComputedColMenu.name": "",
  "AddComputedColMenu.addTo": "",
  "LinkedColumn.joinType": "",
  "LinkedColumn.layoutType": "",
  "CreateColumn.next": "",
  FileColumnConfigEditor: "",
  "FileColumnConfigEditor.maxFileSizeMB": "",
  "FileColumnConfigEditor.contentMode": "",
  CreateFileColumn: "",
  ColumnQuickStats: "",
  "ColumnQuickStats.addFilter": "",
  "QuickAddComputedColumn.Add": "",
  "QuickAddComputedColumn.name": "",
  "LLMChatOptions.Prompt.Preview": "",
  "FunctionColumnList.SearchInput": "",
  "LLMChatOptions.Model.AddCredentials": "",
  QuickFilterGroupsControl: "",
  LinkedColumn: "",
  CreateColumn: "",
  "ToolUseMessage.toggleGroup": "",
  "PGDumpOptions.format": "",
  "PGDumpOptions.destination": "",
  "PGDumpOptions.numberOfJobs": "",
  "PGDumpOptions.compressionLevel": "",
  "PGDumpOptions.excludeSchema": "",
  "PGDumpOptions.noOwner": "",
  "PGDumpOptions.create": "",
  "PGDumpOptions.globalsOnly": "",
  "PGDumpOptions.rolesOnly": "",
  "PGDumpOptions.schemaOnly": "",
  "PGDumpOptions.encoding": "",
  "PGDumpOptions.clean": "",
  "PGDumpOptions.dataOnly": "",
  "PGDumpOptions.ifExists": "",
  "PGDumpOptions.keepLogs": "",
  "BackupControls.backupsInProgress": "",
  "BackupsControls.Completed.delete": "",
  "BackupsControls.Completed.download": "",
  "BackupsControls.Completed.restore": "",
  "BackupsControls.Completed.deleteAll": "",
  "BackupsControls.restoreFromFile": "",
  BackupLogs: "",
  FilterWrapper_FieldName: "",
  FilterWrapper_Field: "",
  "CloudStorageCredentialSelector.selectCredential": "",
  DashboardMenuContent: "",
} as const satisfies Record<
  string,
  | string
  | {
      desc: string;
      uiOnly?: true;
    }
>;
export type Command = keyof typeof COMMANDS;

export type TestSelectors = {
  "data-command"?: Command;
  "data-key"?: string;
  id?: string;
};

export const dataCommand = (cmd: Command): { "data-command": Command } => ({
  "data-command": cmd,
});
export const getCommandElemSelector = (cmd: Command) => {
  return `[data-command=${JSON.stringify(cmd)}]`;
};
export const getDataKeyElemSelector = (key: string) => {
  return `[data-key=${JSON.stringify(key)}]`;
};
export const getDataLabelElemSelector = (key: string) => {
  return `[data-label=${JSON.stringify(key)}]`;
};

export const COMMAND_SEARCH_ATTRIBUTE_NAME = "data-command-search-ended";

export const MOCK_ELECTRON_WINDOW_ATTR = "MOCK_ELECTRON_WINDOW_ATTR" as const;

declare module "react" {
  interface HTMLAttributes<T> {
    "data-command"?: Command;
  }
}

export declare namespace SVGif {
  export type CursorAnimation =
    | {
        elementSelector: string;
        offset?: { x: number; y: number };
        duration: number;
        type: "click" | "clickAppearOnHover";

        /**
         * Time to wait before clicking after reaching the final position
         * */
        waitBeforeClick?: number;
        /**
         * Time to stay on the final position after clicking
         */
        lingerMs?: number;
      }
    | {
        type: "moveTo";
        xy: [number, number];
        duration: number;
      };
  export type Animation =
    | CursorAnimation
    | {
        elementSelector: string;
        duration: number;
        type: "type";
        extraAnimation?:
          | { type: "zoomToElement" }
          | { type: "bringToFront"; elementSelector: string };
        /**
         * Maximum scale to zoom in while typing
         */
        maxScale?: number;
      }
    | {
        elementSelector: string;
        duration: number;
        type: "zoomToElement" | "bringToFront";
        bringToFrontSelector?: string;
        /**
         * Maximum scale to zoom in
         */
        maxScale?: number;
      }
    | {
        elementSelector: string;
        duration: number;
        type: "fadeIn" | "growIn";
      }
    | {
        type: "wait";
        duration: number;
      };
  export type Scene = {
    svgFileName: string;
    caption?: string;
    animations: Animation[];
  };
}

/**
 * TODO: Forbid imports to ensure this file is portable
 */


================================================
FILE: client/src/WithPrgl.tsx
================================================
import React from "react";
import type { Prgl } from "./App";
import { createReactiveState, useReactiveState } from "./appUtils";
export const prgl_R = createReactiveState<Prgl | undefined>(undefined);

export const WithPrgl = ({
  onRender,
}: {
  onRender: (prgl: Prgl) => React.ReactNode;
}): JSX.Element => {
  const { state: prgl } = useReactiveState(prgl_R);

  if (!prgl) return <></>;
  const res = onRender(prgl);
  return <>{res}</>;
};


================================================
FILE: client/src/app/CommandPalette/CommandPalette.css
================================================
.flicker {
  animation: flicker .5s infinite ;
}
.flicker-slow {
  animation: flicker 1.5s infinite ;
}
@keyframes flicker {
  0% { opacity: .75; }
  50% { opacity: 0.1; }
  100% { opacity: .75; }
}

================================================
FILE: client/src/app/CommandPalette/CommandPalette.tsx
================================================
import { FlashMessage } from "@components/FlashMessage";
import { Icon } from "@components/Icon/Icon";
import Popup from "@components/Popup/Popup";
import { SearchList } from "@components/SearchList/SearchList";
import {
  mdiArrowSplitVertical,
  mdiButtonPointer,
  mdiCardTextOutline,
  mdiChartLine,
  mdiCheckboxOutline,
  mdiFileUploadOutline,
  mdiFormatListBulleted,
  mdiFormSelect,
  mdiFormTextbox,
  mdiKeyboard,
  mdiLink,
  mdiListBoxOutline,
  mdiMenu,
  mdiNumeric,
  mdiTextLong,
} from "@mdi/js";
import React, { useEffect, useState } from "react";
import { NavLink } from "react-router-dom";
import { flatUIDocs, type UIDoc, type UIDocInputElement } from "../UIDocs";
import "./CommandPalette.css";
import { Documentation } from "./Documentation";
import { useGoToUI } from "./useGoToUI";
import { getItemSearchRank } from "@components/SearchList/searchMatchUtils/getItemSearchRank";
import { isPlaywrightTest } from "src/i18n/i18nUtils";
import { getProperty } from "@common/utils";

/**
 * By pressing Ctrl+K, the user to search and go to functionality in the UI.
 */
export const CommandPalette = ({ isElectron }: { isElectron: boolean }) => {
  const { showSection, setShowSection } = useOnKeyDown();
  const [highlights, setHighlights] = useState<CommandSearchHighlight[]>([]);
  const { message, setMessage, goToUIDocItem } = useGoToUI(setHighlights);

  return (
    <>
      {highlights.map((h, i) => (
        <div
          key={i}
          style={{
            position: "fixed",
            zIndex: 9999,
            left: `${h.left}px`,
            top: `${h.top}px`,
            width: `${h.width}px`,
            height: `${h.height}px`,
            background: "var(--active-hover)",
            borderRadius: h.borderRadius,
            pointerEvents: "none",
            touchAction: "none",
          }}
          className={
            "CommandPalette_Highlighter " +
            (h.flickerSlow ? "flicker-slow" : "flicker")
          }
        />
      ))}
      {message ?
        <FlashMessage {...message} onFinished={() => setMessage(undefined)} />
      : showSection && (
          <Popup
            key={showSection}
            title={
              showSection === "commands" ? undefined : (
                <NavLink to={"/documentation"}>Documentation</NavLink>
              )
            }
            data-command="CommandPalette"
            clickCatchStyle={{ opacity: 1 }}
            positioning={showSection === "commands" ? "top-center" : "center"}
            onClose={() => setShowSection(undefined)}
            contentClassName={
              "flex-col gap-2 " + (showSection === "docs" ? " p-2" : "p-1")
            }
            contentStyle={
              showSection === "docs" ?
                {
                  textAlign: "left",
                }
              : {
                  width: "min(100vw, 700px)",
                  maxHeight: "min(100vh, 500px)",
                }
            }
          >
            {showSection === "commands" ?
              <SearchList
                placeholder="Search actions..."
                autoFocus={true}
                limit={100}
                items={flatUIDocs.map((data) => {
                  const iconKey =
                    data.type === "input" ?
                      `${data.type}-${data.inputType}`
                    : data.type;
                  const iconPath =
                    data.iconPath ?? getProperty(UIDocTypeToIcon, iconKey);
                  if (!iconPath) {
                    console.warn("No icon for UIDoc type", iconKey, data);
                  }
                  return {
                    key: data.title,
                    parentLabels: data.parentTitles,
                    label: data.title,
                    subLabel: data.description,
                    contentLeft:
                      iconPath ?
                        <Icon
                          path={iconPath}
                          title={data.type}
                          className="text-1 f-0"
                        />
                      : undefined,
                    onPress: async () => {
                      setShowSection(undefined);
                      await goToUIDocItem(data);
                    },
                    ranking: (searchTerm) =>
                      getItemSearchRank(
                        {
                          title: data.title,
                          subTitle: data.description,
                          level: data.parentTitles.length,
                        },
                        searchTerm,
                      ),
                    data,
                  };
                })}
              />
            : <Documentation isElectron={isElectron} />}
          </Popup>
        )
      }
    </>
  );
};

export type CommandSearchHighlight = {
  left: number;
  top: number;
  width: number;
  height: number;
  borderRadius: string;
  flickerSlow?: boolean;
};

const useOnKeyDown = () => {
  const [showSection, setShowSection] = useState<"commands" | "docs">();
  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === "F1") {
        event.preventDefault();
        setShowSection("docs");
      }
      if (event.ctrlKey && event.key === "k") {
        event.preventDefault();
        setShowSection("commands");
      }
      if (event.key === "Escape") {
        setShowSection(undefined);
      }
    };

    window.addEventListener("keydown", handleKeyDown);
    return () => {
      window.removeEventListener("keydown", handleKeyDown);
    };
  }, [showSection]);
  return { showSection, setShowSection };
};

const UIDocTypeToIcon: Partial<
  Record<
    `${UIDocInputElement["type"]}-${UIDocInputElement["inputType"]}`,
    string
  > &
    Record<Exclude<UIDoc["type"], "input">, string>
> = {
  link: mdiLink,
  button: mdiButtonPointer,
  popup: mdiButtonPointer,
  select: mdiButtonPointer,
  "input-text": mdiFormTextbox,
  "input-checkbox": mdiCheckboxOutline,
  "input-file": mdiFileUploadOutline,
  "input-number": mdiNumeric,
  "input-select": mdiFormSelect,
  smartform: mdiListBoxOutline,
  "smartform-popup": mdiListBoxOutline,
  list: mdiFormatListBulleted,
  section: mdiCardTextOutline,
  tab: mdiCardTextOutline,
  "accordion-item": mdiCardTextOutline,
  "drag-handle": mdiArrowSplitVertical,
  "hotkey-popup": mdiKeyboard,
  navbar: mdiMenu,
  text: mdiTextLong,
  canvas: mdiChartLine,
  // page: mdiGrid,
};

if (isPlaywrightTest) {
  flatUIDocs.forEach(({ title: searchTerm }) => {
    let lowestRank = { value: Infinity, title: "" };
    flatUIDocs.forEach(({ title, description, parentTitles }) => {
      const rank = getItemSearchRank(
        {
          title,
          subTitle: description,
          level: parentTitles.length,
        },
        searchTerm,
      );

      if (rank < lowestRank.value) {
        lowestRank = { value: rank, title };
      }
    });

    if (searchTerm !== lowestRank.title) {
      throw new Error(
        `Search rank test failed for term "${searchTerm}". Expected "${searchTerm}" to rank highest, but got "${lowestRank.title}"`,
      );
    }
  });
}


================================================
FILE: client/src/app/CommandPalette/Documentation.css
================================================
.Documentation img {
  max-width: 100%;
}


================================================
FILE: client/src/app/CommandPalette/Documentation.tsx
================================================
import React, { useMemo } from "react";
import Markdown from "react-markdown";
import rehypeRaw from "rehype-raw";
import "./Documentation.css";

import Btn from "@components/Btn";
import { FlexCol, FlexRow } from "@components/Flex";
import { ScrollFade } from "@components/ScrollFade/ScrollFade";
import { useTypedSearchParams } from "src/hooks/useTypedSearchParams";
import { getDocumentationFiles } from "./getDocumentation";
import remarkGfm from "remark-gfm";

type P = {
  isElectron: boolean;
};
export const Documentation = ({ isElectron }: P) => {
  const { docFiles, docFilesMap } = useMemo(() => {
    const docFiles = getDocumentationFiles(isElectron).map((d) => ({
      ...d,
      text: d.text.replaceAll(`="./screenshots/`, `="/screenshots/`),
    }));
    const docFilesMap = new Map(docFiles.map((d) => [d.id, d]));
    return {
      docFiles,
      docFilesMap,
    };
  }, [isElectron]);

  const [{ documentation_section: section = docFiles[0]?.id }, setParams] =
    useTypedSearchParams({
      documentation_section: { type: "string", optional: true },
    });

  const currentDocFile = section ? docFilesMap.get(section) : undefined;

  const WrappingElement = window.isLowWidthScreen ? FlexCol : FlexRow;

  return (
    <FlexCol className="Documentation min-s-0 bg-color-0 p-1">
      <WrappingElement className="ai-start min-s-0 f-1">
        <ScrollFade role="navigation">
          {docFiles.map((docFile) => (
            <Btn
              role="menuitem"
              style={{ width: "100%" }}
              key={docFile.id}
              aria-current={section === docFile.id}
              variant={section === docFile.id ? "faded" : undefined}
              onClick={() => setParams({ documentation_section: docFile.id })}
            >
              {docFile.title}
            </Btn>
          ))}
        </ScrollFade>
        <ScrollFade
          scrollRestore={true}
          style={{
            width: "min(100vw, 850px)",
            gap: 0,
            height: "100%",
            overflowY: "auto",
            lineHeight: 1.5,
          }}
        >
          {!currentDocFile ? null : (
            <Markdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>
              {currentDocFile.text}
            </Markdown>
          )}
        </ScrollFade>
      </WrappingElement>
    </FlexCol>
  );
};


================================================
FILE: client/src/app/CommandPalette/getDocumentation.ts
================================================
import { isObject } from "@common/publishUtils";
import { fixIndent } from "../../demo/scripts/sqlVideoDemo";
import { COMMANDS } from "../../Testing";
import { UIDocs, type UIDoc, type UIDocElement } from "../UIDocs";

type SeparatePage = { doc: UIDoc; parentDocs: UIDoc[]; depth: number };

const asList = (
  children: UIDocElement[],
  parentDocs: UIDoc[],
  separatePageDepth: number | undefined,
  isElectron: boolean,
) => {
  const depth = parentDocs.length;
  const listItemDepth = depth - (separatePageDepth ?? 1);

  const separatePages: SeparatePage[] = [];

  const listContent: string = children
    .map((child) => {
      const moveToNewPage = Boolean(child.docs);
      if (moveToNewPage) {
        separatePages.push({ doc: child, depth, parentDocs });
      }

      const listTitle =
        moveToNewPage ?
          `<a href=${JSON.stringify(`#${toSnakeCase(child.title)}`)}>${child.title}</a>`
        : `**${child.title}**`;
      const listItem = `${"  ".repeat(listItemDepth)}- ${listTitle}: ${child.description}  `;
      if (moveToNewPage) {
        return listItem;
      }
      const items = getChildren(child, isElectron);
      if (items.length) {
        const nestedList = asList(
          items,
          [...parentDocs, child],
          separatePageDepth,
          isElectron,
        );
        nestedList.separatePages.forEach((sp) => separatePages.push(sp));
        return listItem + "\n" + nestedList.listContent;
      }
      return listItem;
    })
    .join("\n");

  return {
    listContent,
    separatePages,
  };
};

const getUIDocAsMarkdown = (
  doc: UIDoc,
  parentDocs: UIDoc[],
  separatePageDepth: number | undefined,
  isElectron: boolean,
): {
  title: string;
  content: string;
  doc: UIDoc;
}[] => {
  const { docOptions } = doc;
  const depth = docOptions ? 0 : Math.min(3, parentDocs.length);
  if (isElectron && doc.uiVersionOnly) {
    return [];
  }
  const { listContent: childrenContent, separatePages } = asList(
    getChildren(doc, isElectron),
    [...parentDocs, doc],
    separatePageDepth,
    isElectron,
  );

  const separatePagesWithContent = separatePages.flatMap((sp) =>
    getUIDocAsMarkdown(sp.doc, sp.parentDocs, sp.depth, isElectron),
  );

  if (doc.uiVersionOnly) {
    const sel = "selectorCommand" in doc ? doc.selectorCommand : undefined;
    const cmdInfo = sel && COMMANDS[sel];
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
    if (!cmdInfo || !isObject(cmdInfo) || !cmdInfo.uiOnly) {
      throw new Error(
        `UI Version Only documentation for "${doc.title}" does not have a valid selectorCommand.`,
      );
    }
  }

  const hDepth = depth + 1;
  const childrenTitle =
    doc.childrenTitle ?? (doc.type === "navbar" ? "Navbar items" : undefined);

  const displayTitle = isObject(docOptions) ? docOptions.title : doc.title;
  const content = [
    `<h${hDepth} id=${JSON.stringify(toSnakeCase(doc.title))}> ${displayTitle} </h${hDepth}> \n`,
    doc.uiVersionOnly ? `>  Not available on Desktop version\n  ` : "",
    `${doc.docs ? fixIndent(doc.docs) : doc.description}\n`,
    childrenTitle ? `### ${childrenTitle}` : "",
    childrenContent,
  ]
    .filter(Boolean)
    .join("\n");

  return [
    {
      title: doc.title,
      doc,
      content,
    },
  ].concat(separatePagesWithContent);
};

export type DocumentationFile = {
  id: string;
  fileName: string;
  title: string;
  text: string;
};
export const getDocumentationFiles = (isElectron: boolean) => {
  const documentationPages: DocumentationFile[] = [];
  UIDocs.forEach((doc) => {
    const docItems = getUIDocAsMarkdown(doc, [], undefined, isElectron);

    const pushFile = (title: string, text: string) => {
      const index = documentationPages.length + 1;
      documentationPages.push({
        fileName: `${index.toString().padStart(2, "0")}_${title.replaceAll(" ", "_")}.md`,
        title,
        id: toSnakeCase(title),
        text,
      });
    };
    if (documentationPages.length) {
      pushFile(doc.title, "");
    }
    do {
      const lastFile = documentationPages.at(-1);
      const currDocItem = docItems.shift();
      if (!currDocItem) {
        continue;
      }
      const asSeparateFile = currDocItem.doc.docOptions === "asSeparateFile";
      if (!lastFile || asSeparateFile) {
        const title = asSeparateFile ? currDocItem.doc.title : doc.title;
        pushFile(title, currDocItem.content + "\n\n");
      } else {
        lastFile.text += currDocItem.content + "\n\n";
      }
    } while (docItems.length);
  });

  return documentationPages;
};

const toSnakeCase = (str: string) =>
  str.toLowerCase().trim().replaceAll(/ /g, "_");

const getChildren = (doc: UIDoc, isElectron: boolean) => {
  if (doc.docOptions === "hideChildren") return [];
  const items =
    "children" in doc ? doc.children
    : "itemContent" in doc ? doc.itemContent
    : "pageContent" in doc ? (doc.pageContent ?? [])
    : [];

  if (isElectron) {
    return items.filter((item) => !item.uiVersionOnly);
  }
  return items;
};

window.documentation = getDocumentationFiles(false);


================================================
FILE: client/src/app/CommandPalette/getUIDocShortestPath.ts
================================================
import { filterArr } from "@common/llmUtils";
import type { UIDoc, UIDocPage } from "../UIDocs";
import { getCommandElemSelector } from "src/Testing";
import { isDefined } from "prostgles-types";

export const getUIDocShortestPath = (
  currentPage: UIDocPage,
  prevParents: UIDoc[],
): undefined | UIDoc[] => {
  const currentPageLinks = filterArr(currentPage.children, {
    type: "link",
  } as const);
  const shortcut = prevParents.slice().map((doc, index) => {
    if (doc.type === "popup") {
      if (
        doc.contentSelectorCommand &&
        document.querySelectorAll(
          getCommandElemSelector(doc.contentSelectorCommand),
        ).length === 1
      ) {
        return { index };
      }
      const selector =
        doc.selector ?? getCommandElemSelector(doc.selectorCommand);
      if (index > 0 && document.querySelectorAll(selector).length === 1) {
        return { index: index - 1 };
      }
    } else if (doc.type === "page" || doc.type === "link") {
      const matchingLink = currentPageLinks.find((link) => {
        return (
          link.path === doc.path &&
          link.pathItem?.tableName === doc.pathItem?.tableName
        );
      });
      if (!matchingLink) {
        const isAlreadyOnPage =
          currentPage.path === doc.path &&
          currentPage.pathItem?.tableName === doc.pathItem?.tableName;
        if (!isAlreadyOnPage) {
          return undefined;
        }
        return { index };
      }
      return { matchingLink, index };
    } else if (doc.type !== "info") {
      if (
        (doc.selector &&
          document.querySelectorAll(doc.selector).length === 1) ||
        (doc.selectorCommand &&
          document.querySelectorAll(getCommandElemSelector(doc.selectorCommand))
            .length === 1)
      ) {
        return { index };
      }
    }
  });
  const bestShortcut = shortcut.findLast(isDefined);
  if (bestShortcut) {
    const { matchingLink, index } = bestShortcut;
    return [matchingLink, ...prevParents.slice(index + 1)].filter(isDefined);
  }
};


================================================
FILE: client/src/app/CommandPalette/useGoToUI.tsx
================================================
import { useCallback, useMemo } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { COMMAND_SEARCH_ATTRIBUTE_NAME } from "../../Testing";
import { useAlert } from "@components/AlertProvider";
import { click } from "../../demo/demoUtils";
import { isPlaywrightTest } from "../../i18n/i18nUtils";
import { tout } from "../../utils/utils";
import {
  flatUIDocs,
  type UIDoc,
  type UIDocFlat,
  type UIDocPage,
} from "../UIDocs";
import type { CommandSearchHighlight } from "./CommandPalette";
import { useHighlightDocItem } from "./useHighlightDocItem";
import {
  getDocPagePath,
  getUIDocElements,
  getUIDocElementsAndAlertIfEmpty,
} from "./utils";
import { includes } from "../../dashboard/W_SQL/W_SQLBottomBar/W_SQLBottomBar";
import { getUIDocShortestPath } from "./getUIDocShortestPath";

export type DocItemHighlightItemPosition = "mid" | "last";

export const useGoToUI = (
  setHighlights: (h: CommandSearchHighlight[]) => void,
) => {
  const navigate = useNavigate();

  const { addAlert } = useAlert();
  const { highlight, message, setMessage, showMultiHighlight } =
    useHighlightDocItem(setHighlights);

  const location = useLocation();
  const currentPage = useMemo(() => {
    return flatUIDocs.find((doc) => {
      if (doc.type === "page") {
        const matchInfo = getDocPagePath(doc, location.pathname);
        return matchInfo.isExactMatch;
      }
    }) as UIDocPage | undefined;
  }, [location.pathname]);

  const clickOneOrHighlight = useCallback(
    async (doc: UIDoc, duration: DocItemHighlightItemPosition) => {
      if (doc.type === "info") return;

      const { items, fullSelector } = getUIDocElements(doc);
      if (items.length === 1) {
        await highlight(doc, duration);
        await click("", fullSelector);
      } else if (items.length > 1) {
        await showMultiHighlight(doc, duration);
      }
    },
    [highlight, showMultiHighlight],
  );

  const goToUI = useCallback(
    async (doc: UIDoc): Promise<undefined | boolean> => {
      const nonIteractableContainers: UIDoc["type"][] = [
        "info",
        "list",
        "page",
        "navbar",
        "section",
      ];
      if (doc.type === "info") return;

      if (doc.type === "hotkey-popup") {
        const [maybeCtrl, charKey] = doc.hotkey;
        const ctrlKEvent = new KeyboardEvent("keydown", {
          key: charKey.toLowerCase(),
          code: "Key" + charKey,
          ctrlKey: maybeCtrl === "Ctrl",
          altKey: maybeCtrl === "Alt",
          shiftKey: maybeCtrl === "Shift",
          bubbles: true,
        });

        // Dispatch it on the document
        document.dispatchEvent(ctrlKEvent);
      } else if (doc.type === "page" || doc.type === "navbar") {
        const { isExactMatch, paths } = getDocPagePath(doc, location.pathname);
        if (!isExactMatch) {
          navigate(paths[0]!);
          await tout(400);
          if (doc.type === "page" && doc.pathItem) {
            await highlight(doc, "mid");
          }
          await tout(400);
        }
      } else if (nonIteractableContainers.includes(doc.type)) {
        // Do not highlight non-interactable container types
        const { items } = getUIDocElementsAndAlertIfEmpty(doc, addAlert);
        return !items.length;
      } else if (
        doc.type === "popup" ||
        doc.type === "tab" ||
        doc.type === "accordion-item" ||
        doc.type === "link" ||
        doc.type === "smartform-popup"
      ) {
        await clickOneOrHighlight(doc, "mid");
      } else {
        await highlight(doc, "mid");
      }
    },
    [location.pathname, navigate, clickOneOrHighlight, highlight, addAlert],
  );

  const goToUIDocItem = useCallback(
    async (data: UIDocFlat) => {
      const prevParents = data.parentDocs;
      const shortcut =
        currentPage ?
          getUIDocShortestPath(currentPage, prevParents)
        : undefined;
      const pathItems = shortcut ?? prevParents;
      const shouldBeOpened = includes(data.type, [
        "link",
        "page",
        "tab",
        "popup",
        "smartform-popup",
      ]);
      const finalPathItems =
        data.type === "hotkey-popup" ? [data]
        : shouldBeOpened ? [...pathItems, data]
        : pathItems;
      for (const parent of finalPathItems) {
        const shouldStop = await goToUI(parent);
        if (!isPlaywrightTest && shouldStop) {
          return;
        }
        await tout(200);
      }
      if (!shouldBeOpened) {
        await highlight(data, "last");
      }
      window.document.body.setAttribute(
        COMMAND_SEARCH_ATTRIBUTE_NAME,
        data.title,
      );
    },
    [currentPage, highlight, goToUI],
  );

  return {
    message,
    setMessage,
    goToUIDocItem,
  };
};


================================================
FILE: client/src/app/CommandPalette/useHighlightDocItem.ts
================================================
import { useCallback, useState } from "react";
import { useAlert } from "@components/AlertProvider";
import { isDefined } from "prostgles-types";
import { getUIDocElementsAndAlertIfEmpty } from "./utils";
import type { UIDocNonInfo } from "../UIDocs";
import { scrollIntoViewIfNeeded, tout } from "../../utils/utils";
import type { CommandSearchHighlight } from "./CommandPalette";
import { isInParentViewport } from "../domToSVG/utils/isElementVisible";
import { isPlaywrightTest } from "../../i18n/i18nUtils";
import type { DocItemHighlightItemPosition } from "./useGoToUI";

export const useHighlightDocItem = (
  setHighlights: (h: CommandSearchHighlight[]) => void,
) => {
  const { addAlert } = useAlert();
  const [message, setMessage] = useState<{
    text: string;
    left: number;
    top: number;
  }>();
  const highlight = useCallback(
    async (doc: UIDocNonInfo, itemPosition: DocItemHighlightItemPosition) => {
      const { items } = getUIDocElementsAndAlertIfEmpty(doc, addAlert);
      const firstElem = items[0];
      firstElem && scrollIntoViewIfNeeded(firstElem);
      await tout(500);
      const mustChooseOne = items.length > 1 && itemPosition !== "last";
      const highlights = Array.from(items)
        .map((el) => {
          const rect = el.getBoundingClientRect();
          const isVisible = isInParentViewport(el, rect);
          if (!isVisible) {
            return;
          }
          return {
            left: rect.left,
            top: rect.top,
            width: rect.width,
            height: rect.height,
            borderRadius: getComputedStyle(el).borderRadius,
            flickerSlow: itemPosition === "last" || mustChooseOne,
          };
        })
        .filter(isDefined);

      const firstItem = highlights[0];
      setHighlights(highlights);
      let waitedForClick = false;
      if (firstItem && mustChooseOne) {
        const { left, top } = firstItem;
        setMessage({ text: "Chose one", left, top: top - 70 });
        if (isPlaywrightTest) {
          items[0]?.scrollIntoView();
          items[0]?.click();
        } else {
          await new Promise((resolve) => {
            window.addEventListener("click", resolve, { once: true });
            window.addEventListener("keydown", resolve, { once: true });
          });
        }
        waitedForClick = true;
      }
      if (!waitedForClick) {
        await tout(
          isPlaywrightTest ? 0
          : itemPosition === "mid" ? 500
          : 2000,
        );
      }
      setHighlights([]);
      setMessage(undefined);
      return Array.from(items);
    },
    [addAlert, setHighlights],
  );
  const showMultiHighlight = useCallback(
    async (doc: UIDocNonInfo, duration: DocItemHighlightItemPosition) => {
      const [firstItem] = await highlight(doc, duration);
      if (!firstItem) {
        addAlert({
          children: `No items found in the ${JSON.stringify(doc.title)} list.`,
        });
        return;
      }
    },
    [highlight, addAlert],
  );
  return { highlight, message, setMessage, showMultiHighlight };
};


================================================
FILE: client/src/app/CommandPalette/utils.ts
================================================
import { isObject } from "@common/publishUtils";
import type { AlertContext } from "@components/AlertProvider";
import { includes } from "../../dashboard/W_SQL/W_SQLBottomBar/W_SQLBottomBar";
import { waitForElement } from "../../demo/demoUtils";
import { isPlaywrightTest } from "../../i18n/i18nUtils";
import { getCommandElemSelector, type Command } from "../../Testing";
import { isDefined } from "../../utils/utils";
import type { UIDoc, UIDocNonInfo } from "../UIDocs";

export const focusElement = async (
  testId: Command | "",
  endSelector?: string,
) => {
  const elem = await waitForElement<HTMLDivElement>(testId, endSelector);
  elem.scrollIntoView({ behavior: "smooth", block: "center" });
  elem.focus();
  return elem;
};

export const getUIDocElements = (doc: Exclude<UIDoc, { type: "info" }>) => {
  const selectors = doc.type === "page" ? doc.pathItem : doc;
  const { selectorCommand, selector = "" } = selectors ?? {};

  const childSelector = doc.type === "list" ? doc.itemSelector : "";
  let fullSelector =
    (selectorCommand ? getCommandElemSelector(selectorCommand) : "") +
    " " +
    selector +
    " " +
    childSelector;
  if (!fullSelector.trim() && doc.type === "page") {
    fullSelector = "body";
  }
  const items = document.querySelectorAll<HTMLDivElement>(fullSelector);
  return {
    items,
    fullSelector,
  };
};

export const highlightItems = (doc: Exclude<UIDoc, { type: "info" }>) => {
  const listItems = getUIDocElements(doc).items;
  listItems.forEach((el) => {
    el.style.border = "2px solid var(--text-warning)";
  });
  return Array.from(listItems);
};

const PATH_JOIN_CHARS = ["/", "#", "?"] as const;
export const getDocPagePath = (
  doc: Extract<UIDoc, { type: "page" | "navbar" }>,
  pathname: string,
) => {
  const paths =
    doc.type === "page" ?
      [doc.pathItem?.selectorPath, doc.path].filter(isDefined)
    : doc.paths;
  const matchedPage = paths.find((pathWopts) => {
    const path = isObject(pathWopts) ? pathWopts.route : pathWopts;
    const exact = isObject(pathWopts) && pathWopts.exact;
    if (exact) {
      return pathname === path;
    }
    const endChar = pathname[path.length];
    return (
      pathname.startsWith(path) &&
      (!endChar || includes(endChar, PATH_JOIN_CHARS))
    );
  });
  let isOnPage = !!matchedPage;
  let currentPathItem: string | undefined;
  if (matchedPage && doc.type === "page" && doc.pathItem) {
    const matchedPagePath =
      isObject(matchedPage) ? matchedPage.route : matchedPage;
    currentPathItem = pathname
      .slice(matchedPagePath.length + 1)
      .split(`/[${PATH_JOIN_CHARS.join("")}]/`)
      .pop();
    isOnPage = isOnPage && !!currentPathItem;
  }

  const isExactMatch =
    !isOnPage ? false
    : doc.type === "navbar" ? true
    : doc.pathItem ? Boolean(currentPathItem)
    : doc.path === pathname;
  return {
    isOnPage,
    isExactMatch,
    matchedPage,
    paths: paths.map((pathWopts) =>
      isObject(pathWopts) ? pathWopts.route : pathWopts,
    ),
  };
};

export const getUIDocElementsAndAlertIfEmpty = (
  doc: UIDocNonInfo,
  addAlert: AlertContext["addAlert"],
) => {
  const result = getUIDocElements(doc);
  if (!result.items.length && !isPlaywrightTest) {
    addAlert({
      children: [
        `Could not find a ${JSON.stringify(doc.title)} item.`,
        `Selector used: ${JSON.stringify(result.fullSelector)}`,
      ].join("\n"),
    });
  }
  return result;
};


================================================
FILE: client/src/app/UIDocs/UIInstallationUIDoc.ts
================================================
import type { UIDoc } from "../UIDocs";

export const UIInstallation = {
  title: "Installation",
  type: "info",
  description: "A guide to help you get started with the application.",
  docs: `
    The quickest way to start is with Docker. 
    If you don't have Docker installed, please follow the official 
    <a href="https://docs.docker.com/engine/install/" target="_blank">Docker installation guide</a>
 
    Download the source code:

    \`\`\`bash
    git clone https://github.com/prostgles/ui.git
    cd ui
    \`\`\`

    Start the application:

    \`\`\`docker-compose.sh
    docker compose up -d --build
    \`\`\` 
    
    Once running, Prostgles UI will be available at [localhost:3004](http://localhost:3004)

    ### Initial Setup & Authentication

    When first launching Prostgles UI, an admin user will be created automatically:
    - If \`PRGL_USERNAME\` and \`PRGL_PASSWORD\` environment variables are provided, an admin user is created with these credentials. 
    - Otherwise, a passwordless admin user is created. 
    It gets assigned to the first client that accesses the app. 
    Subsequent clients accessing the app will be rejected with an appropriate error message detailing that the passwordless admin user has already been assigned.

    To setup multiple users, the passwordless admin user must be converted to a normal admin account by setting up a password.
    This will allow accessing /users page where you can manage users.

    Users login using their username and password. Two-factor authentication is provided through TOTP (Time-based One-Time Password) and can be enabled in the account section.

    Email and third-party (OAuth) authentication can be configured in Server Settings section. It allows users to register and log in using their email address or third-party accounts like Google, GitHub, etc.
   
    `,
} satisfies UIDoc;


================================================
FILE: client/src/app/UIDocs/accountUIDoc.ts
================================================
import { mdiAccountOutline, mdiApplicationBracesOutline } from "@mdi/js";
import { ROUTES } from "@common/utils";
import { getDataKeyElemSelector } from "../../Testing";
import type { UIDocContainers } from "../UIDocs";

export const accountUIDoc = {
  type: "page",
  path: ROUTES.ACCOUNT,
  title: "Account",
  iconPath: mdiAccountOutline,
  description:
    "Manage your account settings, security preferences, and API access.",
  docs: `
    Manage your account settings, security preferences, and API access.
    
    <img src="./screenshots/account.svgif.svg" alt="Account Page" />
  `,
  children: [
    {
      type: "tab",
      title: "Account details",
      selector: getDataKeyElemSelector("details"),
      description: "View and update your account information.",
      children: [
        {
          type: "smartform",
          title: "Account information",
          description:
            "View all account details and associated data (workspaces, dashboards, views, etc.)",
          tableName: "users",
          selectorCommand: "SmartForm",
        },
      ],
    },
    {
      type: "tab",
      title: "Security",
      selector: getDataKeyElemSelector("security"),
      description: "Manage your account security settings.",
      children: [
        {
          type: "popup",
          title: "Two-factor authentication",
          description:
            "Set up and manage two-factor authentication for enhanced security.",
          selectorCommand: "Setup2FA.Enable",
          children: [
            {
              type: "button",
              title: "Generate QR Code",
              description:
                "Generate a QR code to set up 2FA with your authenticator app.",
              selectorCommand: "Setup2FA.Enable.GenerateQR",
            },
            {
              type: "button",
              title: "Can't scan QR code",
              description:
                "View manual setup instructions if you can't scan the QR code.",
              selectorCommand: "Setup2FA.Enable.CantScanQR",
            },
            {
              type: "input",
              inputType: "text",
              title: "Confirm code",
              description:
                "Enter the code from your authenticator app to enable 2FA.",
              selectorCommand: "Setup2FA.Enable.ConfirmCode",
            },
            {
              type: "button",
              title: "Enable 2FA",
              description:
                "Complete the 2FA setup process by confirming the code.",
              selectorCommand: "Setup2FA.Enable.Confirm",
            },
            {
              type: "text",
              title: "Base64 secret",
              description:
                "Manual setup secret key for your authenticator app.",
              selectorCommand: "Setup2FA.Enable.Base64Secret",
            },
          ],
        },
        {
          type: "button",
          title: "Disable 2FA",
          description: "Turn off two-factor authentication for your account.",
          selectorCommand: "Setup2FA.Disable",
        },
        {
          type: "popup",
          title: "Change password",
          description: "Change your account password.",
          selectorCommand: "Account.ChangePassword",
          children: [],
        },
        {
          type: "list",
          title: "Active sessions",
          description: "View and manage your active web sessions.",
          selectorCommand: "Sessions",
          itemContent: [],
          itemSelector: ``,
        },
      ],
    },
    {
      type: "tab",
      title: "API",
      selector: getDataKeyElemSelector("api"),
      iconPath: mdiApplicationBracesOutline,
      description: "View and manage your API access settings.",
      children: [
        {
          type: "section",
          title: "API Details",
          description: "View your API credentials and configuration.",
          selectorCommand: "config.api",
          uiVersionOnly: true,
          children: [],
        },
      ],
    },
  ],
} satisfies UIDocContainers;


================================================
FILE: client/src/app/UIDocs/commandPaletteUIDoc.ts
================================================
import { getCommandElemSelector } from "src/Testing";
import type { UIDocContainers } from "../UIDocs";

export const commandPaletteUIDoc = {
  type: "hotkey-popup",
  hotkey: ["Ctrl", "K"],
  title: "Command Palette",
  description: "Go to command/action quickly",
  docs: `
    Keyboard-driven navigation to different parts of the application without having to browse through menus or panels. 

    Press <kbd>Ctrl+K</kbd> to open the command palette popup. Type to search through the documentation for functionality, settings, and other sections.
    <img src="./screenshots/command_palette.svgif.svg" alt="Command Palette" />
  `,
  selectorCommand: "CommandPalette",
  children: [
    {
      type: "input",
      inputType: "text",
      title: "Search commands input",
      description: "Type to search for commands and actions",
      selector:
        getCommandElemSelector("CommandPalette") +
        " " +
        getCommandElemSelector("SearchList.Input"),
    },
    {
      type: "list",
      title: "Search results",
      description:
        "List of matching commands and actions. Press Enter to execute/go to the selected command.",
      selector:
        getCommandElemSelector("CommandPalette") +
        " " +
        getCommandElemSelector("SearchList.List"),
      itemSelector: "[data-key]",
      itemContent: [],
    },
  ],
} satisfies UIDocContainers;


================================================
FILE: client/src/app/UIDocs/connection/AIAssistantUIDoc.ts
================================================
import { mdiMagnify, mdiPlus, mdiStop, mdiTools } from "@mdi/js";
import { fixIndent } from "../../../demo/scripts/sqlVideoDemo";
import { getCommandElemSelector } from "../../../Testing";
import type { UIDocElement } from "../../UIDocs";
import { DEFAULT_MCP_SERVER_NAMES } from "@common/mcp";

export const AIAssistantUIDoc = {
  type: "popup",
  selectorCommand: "AskLLM",
  title: "AI Assistant",
  description:
    "Opens an AI assistant to help generate SQL queries, understand database schema, or perform other tasks.",
  docs: fixIndent(`
    The AI assistant is an intelligent companion that helps you work more efficiently with your PostgreSQL databases. 
    It can generate SQL queries, explain database schemas, analyze data patterns, and assist with various database-related tasks through a conversational interface.
    MCP Servers can be used to extend the AI capabilities with custom tools and integrations.

    <img src="./screenshots/ai_assistant.svgif.svg" alt="AI assistant popup screenshot" />
 
    Supported AI Providers: OpenAI, Anthropic, Google Gemini, OpenRouter, and Local Models. 

    *Note: AI providers are configured by administrators in Server Settings > LLM Providers*
  `),
  docOptions: "asSeparateFile",
  children: [
    {
      type: "section",
      title: "Header actions",
      description: "Actions available in the header of the AI assistant popup.",
      selector: getCommandElemSelector("Popup.header"),
      children: [
        {
          type: "smartform-popup",
          selector: getCommandElemSelector("LLMChatOptions.toggle"),
          title: "Chat settings",
          tableName: "llm_chats",
          description:
            "Allows editing all chat settings and data as well deleting or cloning the current chat.",
        },
        {
          type: "input",
          inputType: "select",
          selector: getCommandElemSelector("LLMChat.select"),
          title: "Select chat",
          description:
            "Selects a chat from the list of available chats. Each chat represents a separate conversation with the AI assistant.",
        },
        {
          type: "button",
          selector: getCommandElemSelector("AskLLMChat.NewChat"),
          title: "New chat",
          description: "Creates a new chat with the AI assistant.",
        },
        {
          type: "button",
          selector: getCommandElemSelector("Popup.toggleFullscreen"),
          title: "Toggle fullscreen",
          description:
            "Toggles the fullscreen mode for the AI assistant popup.",
        },
        {
          type: "button",
          selector: getCommandElemSelector("Popup.close"),
          title: "Close popup",
          description: "Closes the AI assistant popup.",
        },
      ],
    },
    {
      type: "list",
      title: "Chat messages",
      description: "List of messages in the current chat.",
      selector: getCommandElemSelector("Chat.messageList"),
      itemContent: [],
      itemSelector: getCommandElemSelector("Chat.messageList") + " > .message",
    },
    {
      type: "section",
      title: "Message input",
      description:
        "Input field for entering messages to the AI assistant and quick actions.",
      docs: fixIndent(`
        The message input area allows you to write text, attach files and control other aspects of the AI assistant (change model, add/remove tools, speech to text). 

      `),
      selector: getCommandElemSelector("Chat.sendWrapper"),
      children: [
        {
          type: "input",
          inputType: "text",
          title: "Message input",
          description:
            "Input field for entering messages to the AI assistant. Pressing Shift+Enter creates a new line.",
          selector: getCommandElemSelector("Chat.textarea"),
        },
        {
          type: "popup",
          title: "MCP tools allowed",
          iconPath: mdiTools,
          description: `Opens the MCP tools menu for the current chat. Default tools: ${DEFAULT_MCP_SERVER_NAMES.join(", ")}`,
          docs: `
            MCP Servers extend the capabilities of the AI assistant by providing custom tools and integrations.
          `,
          selector: getCommandElemSelector("LLMChatOptions.MCPTools"),
          children: [
            {
              type: "popup",
              selector: getCommandElemSelector("AddMCPServer.Open"),
              title: "Add MCP server",
              iconPath: mdiPlus,
              description:
                "Opens the form to add a new MCP server for the current chat.",
              children: [
                {
                  type: "input",
                  inputType: "text",
                  title: "MCP tool json config",
                  description:
                    "JSON configuration for the MCP tool to be added.",
                  selector:
                    getCommandElemSelector("AddMCPServer") +
                    " " +
                    getCommandElemSelector("MonacoEditor"),
                },
                {
                  type: "popup",
                  title: "Add MCP server",
                  description:
                    "Adds the specified MCP server to the current chat.",
                  selector: getCommandElemSelector("AddMCPServer.Add"),
                  children: [],
                },
              ],
            },
            {
              type: "button",
              title: "Stop/Start all MCP Servers",
              description: "Quick way to stop/restart all MCP servers.",
              selector: getCommandElemSelector(
                "MCPServersToolbar.stopAllToggle",
              ),
              iconPath: mdiStop,
            },
            {
              type: "button",
              title: "Search tools",
              description:
                "Searches for specific MCP tools in the list of available tools.",
              selector: getCommandElemSelector("MCPServersToolbar.searchTools"),
              iconPath: mdiMagnify,
            },
            {
              type: "list",
              title: "MCP tools",
              iconPath: mdiTools,
              description:
                "List of available MCP tools. To allow a tool to be used in the current chat it must be ticked. Each tool represents a specific functionality or integration.",
              selector:
                getCommandElemSelector("LLMChatOptions.MCPTools") +
                " " +
                getCommandElemSelector("SmartCardList"),
              itemSelector: ".SmartCard",
              itemContent: [
                {
                  type: "text",
                  title: "MCP server name",
                  description:
                    "Name of the parent MCP server associated with the tool.",
                  selector: "div",
                },
                {
                  type: "list",
                  title: "MCP server tools",
                  description:
                    "List of available tools for the selected MCP server. Click to enable or disable a specific tool for the current chat.",
                  selector: getCommandElemSelector("MCPServerTools"),
                  itemSelector: ".SmartCard",
                  itemContent: [],
                },
                {
                  type: "popup",
                  title: "MCP Server Logs",
                  description:
                    "Opens the logs for the selected MCP server, allowing you to view its activity and status.",
                  selector: getCommandElemSelector(
                    "MCPServerFooterActions.logs",
                  ),
                  children: [],
                },
                {
                  type: "popup",
                  title: "MCP Server Config",
                  description:
                    "Opens the configuration for the selected MCP server, allowing you to manage its settings.",
                  selector: getCommandElemSelector("MCPServerConfigButton"),
                  children: [
                    {
                      type: "button",
                      title: "Save config",
                      description:
                        "Saves the configuration for the selected MCP server.",
                      selector: getCommandElemSelector("MCPServerConfig.save"),
                    },
                  ],
                },
                {
                  type: "button",
                  title: "Reload MCP tools",
                  description:
                    "Reloads the MCP tools for the selected MCP server, updating the list of available tools.",
                  selectorCommand: "MCPServerFooterActions.refreshTools",
                },
                {
                  type: "button",
                  title: "Enable/Disable MCP server",
                  description:
                    "Enables or disables the selected MCP server for all chats. If configuration is required a popup will be shown.",
                  selector: getCommandElemSelector(
                    "MCPServerFooterActions.enableToggle",
                  ),
                },
              ],
            },
          ],
        },
        {
          type: "smartform-popup",
          selector: getCommandElemSelector("LLMChatOptions.DatabaseAccess"),
          title: "Database access",
          description:
            "Opens the database access settings for the current chat. This controls how the AI assistant can interact with the current database.",
          tableName: "llm_chats",
          fieldNames: ["db_data_permissions", "db_schema_permissions"],
        },
        {
          type: "popup",
          title: "Prompt Selector",
          description:
            "Opens the prompt details for the current chat, allowing you to manage the prompt template and other related settings.",
          selector: getCommandElemSelector("LLMChatOptions.Prompt"),
          children: [
            {
              type: "popup",
              selectorCommand: "LLMChatOptions.Prompt.Preview",
              title: "Prompt preview",
              description:
                "Preview of the prompt with context variables filled in.",
              children: [],
            },
          ],
        },
        {
          type: "popup",
          title: "LLM Model",
          description:
            "Selects the LLM model to be used for the current chat. Different models may have different capabilities and performance. ",
          selector: getCommandElemSelector("LLMChatOptions.Model"),
          children: [
            {
              type: "button",
              selector: `${getCommandElemSelector("LLMChatOptions.Model")} .LABELWRAPPER`,
              title: "Select model",
              description: "Selects this LLM model for the current chat.",
            },
            {
              type: "smartform-popup",
              title: "Add model credentials",
              description:
                "Opens the form to add llm provider credentials for the selected LLM model.",
              selectorCommand: "LLMChatOptions.Model.AddCredentials",
              tableName: "llm_credentials",
            },
          ],
        },
        {
          type: "input",
          inputType: "file",
          selectorCommand: "Chat.addFiles",
          title: "Attach files",
          description:
            "Attaches files to be sent to the AI assistant along with the message. Supported file types may vary depending on the AI model and configuration.",
        },
        {
          type: "popup",
          title: "Speech to Text",
          selectorCommand: "Chat.speech",
          description:
            "Opens the speech-to-text input options, allowing you to send audio recordings or transcribe audio messages to send to the AI assistant. Right click to open speech-to-text settings.",
          children: [],
        },
        {
          type: "button",
          title: "Send message",
          description: "Sends the entered message to the AI assistant.",
          selector: getCommandElemSelector("Chat.send"),
        },
      ],
    },
  ],
} satisfies UIDocElement;


================================================
FILE: client/src/app/UIDocs/connection/config/accessControlUIDoc.ts
================================================
import { mdiAccountMultiple } from "@mdi/js";
import { fixIndent } from "../../../../demo/scripts/sqlVideoDemo";
import type { UIDoc } from "../../../UIDocs";

export const accessControlUIDoc = {
  type: "tab",
  selectorCommand: "config.ac",
  uiVersionOnly: true,
  title: "Access control",
  iconPath: mdiAccountMultiple,
  description:
    "Manage user permissions and access rules for this database connection.",
  docs: fixIndent(`
    Manage user permissions and access rules for this database connection.
    <img src="./screenshots/access_control.svgif.svg" alt="Access control" />
  `),
  docOptions: "asSeparateFile",
  children: [
    {
      type: "button",
      selectorCommand: "config.ac.create",
      title: "Create Access Rule",
      description: "Add a new access control rule to define user permissions.",
    },
    {
      type: "button",
      selectorCommand: "config.ac.save",
      title: "Save Access Rule",
      description: "Save changes to the current access control rule.",
    },
    {
      type: "button",
      selectorCommand: "config.ac.cancel",
      title: "Cancel Changes",
      description: "Cancel editing the current access control rule.",
    },
    {
      type: "button",
      selectorCommand: "config.ac.removeRule",
      title: "Remove Rule",
      description: "Delete the selected access control rule.",
    },
  ],
} satisfies UIDoc;


================================================
FILE: client/src/app/UIDocs/connection/config/apiUIDoc.ts
================================================
import { mdiApplicationBracesOutline } from "@mdi/js";
import type { UIDocElement } from "../../../UIDocs";

export const apiUIDoc = {
  type: "tab",
  selectorCommand: "config.api",
  iconPath: mdiApplicationBracesOutline,
  title: "API",
  description: "Configure API access settings and view API documentation.",
  docs: `
  The API section allows you to configure the API access settings for your application.
  This enables programmatic access to your application's data and functionality via HTTP or WebSocket protocols.
  Generated database types can be used to interact with the API in a type-safe manner through our TypeScript client library.
  Code snippets are provided to help you get started with using the API in your applications.
  You can also manage API tokens for authentication and access control.
  
  You can set the URL path for the API, manage allowed origins for CORS requests, and create or view API tokens for accessing the API. The API supports both WebSocket and HTTP protocols.`,
  docOptions: "asSeparateFile",
  children: [
    {
      type: "input",
      inputType: "text",
      selector: "input#url_path",
      title: "API URL Path",
      description:
        "Set the URL path for the API. This is the base path for all API endpoints.",
    },
    {
      type: "popup",
      title: "Allowed Origin Alert",
      selectorCommand: "AllowedOriginCheck",
      description: "Will only appear if the allowed origin is not set.",
      children: [
        {
          type: "input",
          inputType: "text",
          selectorCommand: "AllowedOriginCheck.FormField",
          title: "Allowed Origin",
          description:
            "Set the allowed origin for CORS requests. This controls which domains can make cross-origin requests to this app by setting the Access-Control-Allow-Origin header.",
        },
      ],
    },
    {
      type: "popup",
      selectorCommand: "APIDetailsWs.Examples",
      title: "Websocket API usage examples",
      description:
        "View examples of how to use the API using typescript and javascript",
      children: [],
    },
    {
      type: "popup",
      selectorCommand: "APIDetailsHttp.Examples",
      title: "HTTP API usage examples",
      description:
        "View examples of how to use the API using typescript and javascript",
      children: [],
    },
    {
      type: "section",
      selectorCommand: "APIDetailsTokens",
      title: "API Tokens",
      description:
        "Shows existing API tokens and allows you to create new ones.",
      children: [
        {
          type: "popup",
          selectorCommand: "APIDetailsTokens.CreateToken",
          title: "Create API Token",
          description:
            "Create a new API token for accessing the API. Tokens can be used for both WebSocket and HTTP API access.",
          children: [
            {
              type: "input",
              inputType: "number",
              selectorCommand:
                "APIDetailsTokens.CreateToken.daysUntilExpiration",
              title: "Expires in (days)",
              description:
                "Set the number of days until the token expires. After expiration, the token will no longer be valid.",
            },
            {
              type: "button",
              selectorCommand: "APIDetailsTokens.CreateToken.generate",
              title: "Generate Token",
              description:
                "Click to generate a new API token. The token will be displayed once generated. After generation, the code examples will be updated to include the new token.",
            },
          ],
        },
      ],
    },
  ],
} satisfies UIDocElement;


================================================
FILE: client/src/app/UIDocs/connection/config/backupAndRestoreUIDoc.ts
================================================
import { mdiDatabaseSync } from "@mdi/js";
import type { UIDoc } from "../../../UIDocs";

export const backupAndRestoreUIDoc = {
  type: "tab",
  selectorCommand: "config.bkp",
  title: "Backup and Restore",
  description: "Manage database backups and restore operations.",
  docOptions: "asSeparateFile",
  iconPath: mdiDatabaseSync,
  docs: `
    Manage database backups and restore operations for this PostgreSQL connection. 
    Create reliable backups using PostgreSQL's native tools and restore 
    your data when needed.

    Backups can be saved to a local file system or to cloud storage to AWS S3.
    Similarly, you can restore backups from local files or from AWS S3.

    <img src="./screenshots/backup_and_restore.svgif.svg" alt="Backup and Restore" />
  `,
  children: [
    {
      type: "popup",
      selectorCommand: "config.bkp.create",
      title: "Create Backup",
      description: "Start a new database backup operation.",
      children: [
        {
          type: "input",
          inputType: "text",
          selectorCommand: "config.bkp.create.name",
          title: "Backup Name",
          description:
            "Optional name for the backup to help identify it later.",
        },
        {
          type: "select",
          selectorCommand: "PGDumpOptions.format",
          title: "Backup Format",
          description:
            "Choose the backup format: Custom, Plain SQL, Tar, or Directory.",
        },
        {
          type: "input",
          inputType: "checkbox",
          selectorCommand: "PGDumpOptions.schemaOnly",
          title: "Schema Only",
          description: "Backup only the database schema without data.",
        },
        {
          type: "input",
          inputType: "checkbox",
          selectorCommand: "PGDumpOptions.dataOnly",
          title: "Data Only",
          description: "Backup only the data without schema.",
        },
        {
          type: "select",
          selectorCommand: "PGDumpOptions.destination",
          title: "Backup Destination",
          description:
            "Choose where to save the backup: Local filesystem or AWS S3.",
        },
        {
          selectorCommand: "PGDumpOptions.numberOfJobs",
          type: "input",
          inputType: "number",
          title: "Number of Jobs",
          description:
            "Specify the number of parallel jobs to use for the backup process.",
        },
        {
          selectorCommand: "PGDumpOptions.compressionLevel",
          type: "input",
          inputType: "number",
          title: "Compression Level",
          description:
            "Set the compression level for the backup (0-9). Higher values mean better compression but slower performance.",
        },
        {
          selectorCommand: "PGDumpOptions.excludeSchema",
          type: "input",
          inputType: "text",
          title: "Exclude Schema",
          description: "Specify a schema to exclude from the backup.",
        },
        {
          selectorCommand: "PGDumpOptions.noOwner",
          type: "input",
          inputType: "checkbox",
          title: "No Owner",
          description:
            "Do not output commands to set ownership of objects to match the original database. Useful when restoring to a different database user.",
        },
        {
          selectorCommand: "PGDumpOptions.create",
          type: "input",
          inputType: "checkbox",
          title: "Create",
          description: "Include commands to create the database in the backup.",
        },
        {
          selectorCommand: "PGDumpOptions.globalsOnly",
          type: "input",
          inputType: "checkbox",
          title: "Globals Only",
          description:
            "Backup only global objects such as roles and tablespaces.",
        },
        {
          selectorCommand: "PGDumpOptions.rolesOnly",
          type: "input",
          inputType: "checkbox",
          title: "Roles Only",
          description: "Backup only roles (users) from the database.",
        },
        {
          selectorCommand: "PGDumpOptions.schemaOnly",
          type: "input",
          inputType: "checkbox",
          title: "Schema Only",
          description: "Backup only the database schema without data.",
        },
        {
          selectorCommand: "PGDumpOptions.encoding",
          type: "input",
          inputType: "text",
          title: "Encoding",
          description: "Specify the character encoding to use in the backup.",
        },
        {
          selectorCommand: "PGDumpOptions.clean",
          type: "input",
          inputType: "checkbox",
          title: "Clean",
          description:
            "Include commands to drop database objects before recreating them.",
        },
        {
          selectorCommand: "PGDumpOptions.dataOnly",
          type: "input",
          inputType: "checkbox",
          title: "Data Only",
          description: "Backup only the data without schema.",
        },
        {
          selectorCommand: "PGDumpOptions.ifExists",
          type: "input",
          inputType: "checkbox",
          title: "If Exists",
          description:
            "Use IF EXISTS clauses in the backup to avoid errors when dropping objects that do not exist.",
        },
        {
          selectorCommand: "PGDumpOptions.keepLogs",
          type: "input",
          inputType: "checkbox",
          title: "Keep Logs",
          description: "Retain log files generated during the backup process.",
        },

        {
          type: "button",
          selectorCommand: "config.bkp.create.start",
          title: "Start Backup",
          description: "Begin the backup process with the selected options.",
        },
      ],
    },
    {
      type: "popup",
      selectorCommand: "config.bkp.AutomaticBackups",
      title: "Automatic Backups",
      description: "Configure scheduled automatic backups for this database.",
      children: [
        {
          type: "input",
          inputType: "checkbox",
          selectorCommand: "config.bkp.AutomaticBackups.toggle",
          title: "Enable Automatic Backups",
          description: "Enable or disable automatic backup scheduling.",
        },
      ],
    },
    {
      type: "section",
      selectorCommand: "BackupControls.backupsInProgress",
      title: "Backups in Progress",
      description: "Monitor and manage ongoing backup operations.",
      children: [
        {
          selectorCommand: "BackupLogs",
          type: "button",
          title: "View Logs",
          description: "View real-time logs of the ongoing backup operation.",
        },
      ],
    },
    {
      selectorCommand: "BackupsControls.restoreFromFile",
      type: "button",
      title: "Restore from File",
      description:
        "Initiate a database restore operation from a local backup file.",
    },
    {
      type: "list",
      selectorCommand: "BackupsControls.Completed",
      title: "Completed Backups",
      description: "View and manage completed backup operations.",
      itemSelector: `[data-key]`,
      itemContent: [
        {
          type: "button",
          selectorCommand: "BackupsControls.Completed.delete",
          title: "Delete Backup",
          description:
            "Delete the selected backup file from storage. Will ask for confirmation.",
        },
        {
          type: "button",
          selectorCommand: "BackupsControls.Completed.download",
          title: "Download Backup",
          description:
            "Download the selected backup file to your local system.",
        },
        {
          type: "button",
          selectorCommand: "BackupsControls.Completed.restore",
          title: "Restore Backup",
          description:
            "Restore a database from a selected backup file. Will ask for confirmation.",
        },
      ],
    },
  ],
} satisfies UIDoc;


================================================
FILE: client/src/app/UIDocs/connection/config/fileStorageUIDoc.ts
================================================
import { mdiImage } from "@mdi/js";
import type { UIDoc } from "../../../UIDocs";

export const fileStorageUIDoc = {
  type: "tab",
  selectorCommand: "config.files",
  title: "File storage",
  description:
    "Configure file upload and storage settings for this connection.",
  docOptions: "asSeparateFile",
  iconPath: mdiImage,
  docs: `
    Configure file upload and storage settings for this connection.

    <img src="./screenshots/file_storage.svg" alt="File Storage Configuration" />
  `,
  children: [
    {
      type: "input",
      inputType: "checkbox",
      selectorCommand: "config.files.toggle",
      title: "Enable File Storage",
      description:
        "Enable file upload and storage capabilities for this connection.",
    },
  ],
} satisfies UIDoc;


================================================
FILE: client/src/app/UIDocs/connection/connectionConfigUIDoc.ts
================================================
import { mdiChartLine, mdiDatabaseCogOutline } from "@mdi/js";
import { fixIndent, ROUTES } from "@common/utils";
import type { UIDocContainers } from "../../UIDocs";
import { editConnectionUIDoc } from "../editConnectionUIDoc";
import { accessControlUIDoc } from "./config/accessControlUIDoc";
import { apiUIDoc } from "./config/apiUIDoc";
import { backupAndRestoreUIDoc } from "./config/backupAndRestoreUIDoc";
import { fileStorageUIDoc } from "./config/fileStorageUIDoc";

export const connectionConfigUIDoc = {
  type: "page",
  path: ROUTES.CONFIG,
  iconPath: mdiDatabaseCogOutline,
  pathItem: {
    tableName: "connections",
    selectorCommand: "Connection.configure",
    selectorPath: ROUTES.CONNECTIONS,
  },
  title: "Connection configuration",
  description:
    "Configure the selected database connection. Set connection details, manage users, and customize settings.",
  docs: fixIndent(`
    Configure the selected database connection. Set connection details, manage users, and customize settings.
    <img src="./screenshots/connection_config.svgif.svg" alt="Connection configuration" />
  `),
  children: [
    {
      type: "tab",
      selectorCommand: "config.details",
      title: "Connection details",
      description:
        "Edit connection parameters such as host, port, database name, and other connection settings.",
      docs: editConnectionUIDoc.docs,
      iconPath: mdiDatabaseCogOutline,
      children: [],
    },
    {
      type: "tab",
      selectorCommand: "config.status",
      title: "Status monitor",
      iconPath: mdiChartLine,
      description:
        "View real-time connection status, running queries, and system resource usage.",
      children: [],
    },
    accessControlUIDoc,
    fileStorageUIDoc,
    backupAndRestoreUIDoc,
    apiUIDoc,
    {
      type: "tab",
      selectorCommand: "config.tableConfig",
      title: "Table config",
      description:
        "Advanced table configuration using TypeScript (experimental feature).",
      children: [],
    },
    {
      type: "tab",
      selectorCommand: "config.methods",
      title: "Server-side functions",
      description:
        "Configure and manage server-side functions (experimental feature).",
      children: [],
    },
  ],
} satisfies UIDocContainers;


================================================
FILE: client/src/app/UIDocs/connection/dashboard/dashboardContentUIDoc.ts
================================================
import type { UIDocElement } from "../../../UIDocs";
import { mapUIDoc } from "./mapUIDoc";
import { sqlEditorUIDoc } from "./sqlEditorUIDoc";
import { tableUIDoc } from "./table/tableUIDoc";
import { timechartUIDoc } from "./timechartUIDoc";

export const dashboardContentUIDoc = {
  type: "section",
  selector: ".Dashboard_MainContentWrapper",
  title: "Workspace area",
  description:
    "Main content area of the dashboard, where the tables, views, SQL editors and other visualisations are displayed.",
  docs: `
    The workspace area is the main place for interacting with your data. 
    It includes the SQL editor, data tables, maps, and timecharts, allowing you to execute queries, visualize data, and manage database objects.`,
  children: [sqlEditorUIDoc, tableUIDoc, mapUIDoc, timechartUIDoc],
} satisfies UIDocElement;


================================================
FILE: client/src/app/UIDocs/connection/dashboard/dashboardMenuUIDoc.ts
================================================
import {
  getDataKeyElemSelector,
  getDataLabelElemSelector,
} from "../../../../Testing";
import type { UIDocElement } from "../../../UIDocs";

export const dashboardMenuUIDoc = {
  type: "popup",
  selectorCommand: "dashboard.menu",
  title: "Dashboard menu",
  description:
    "Allows opening tables and views, schema diagram, importing files, managing saved queries, and accessing dashboard settings.",
  docs: `
    The dashboard menu is the entry point in exploring your database.
    The layout adapts to the screen size by pinning the menu to keep it open when there is enough space. 
    For wider screens the centered layout mode can be enabled through the settings. 

    `,
  contentSelectorCommand: "DashboardMenuContent",
  children: [
    {
      type: "button",
      selectorCommand: "dashboard.menu.sqlEditor",
      title: "Open an SQL editor",
      description: "Opens an SQL editor view in the workspace area.",
    },
    {
      type: "popup",
      selectorCommand: "dashboard.menu.quickSearch",
      title: "Quick search",
      description:
        "Opens the quick search menu for searching across all available tables and views from the current database.",
      children: [],
    },
    {
      type: "smartform-popup",
      tableName: "workspaces",
      fieldNames: ["options"],
      selectorCommand: "dashboard.menu.settings",
      title: "Settings",
      description:
        "Opens the settings menu for configuring dashboard layout preferences.",
    },
    {
      type: "button",
      selectorCommand: "DashboardMenuHeader.togglePinned",
      title: "Pin/Unpin menu",
      description:
        "Toggles the pinning of the dashboard menu. Pinned menus remain open until unpinned or accessing from a low width screen.",
    },
    {
      type: "drag-handle",
      direction: "x",
      title: "Resize menu",
      description:
        "Allows resizing the dashboard menu. Drag to adjust the width of the menu.",
      selectorCommand: "dashboard.menu.resize",
    },
    {
      type: "drag-handle",
      direction: "x",
      selectorCommand: "dashboard.centered-layout.resize",
      title: "Resize centered layout",
      description:
        "Allows resizing the workspace area when centered layout is enabled. Drag to adjust the width of the centered layout.",
    },

    {
      type: "list",
      selectorCommand: "dashboard.menu.savedQueriesList",
      title: "Saved queries",
      description:
        "List of saved queries of the current user from the current workspace. Click to open a saved query.",
      itemContent: [],
      itemSelector: "li",
    },
    {
      type: "list",
      selectorCommand: "dashboard.menu.tablesSearchList",
      title: "Tables and views",
      description:
        "List of tables and views from the current database. Click to open a table or view. By default only the tables from the public schema are shown. Schema list from the connection settings controls which schemas are shown.",
      itemSelector: "li",
      itemContent: [],
    },
    {
      type: "list",
      selectorCommand: "dashboard.menu.serverSideFunctionsList",
      title: "Server-side functions",
      description:
        "List of server-side functions for the current database. Click to open a function.",
      itemSelector: "li",
      itemContent: [],
    },
    {
      type: "popup",
      selectorCommand: "dashboard.menu.create",
      title: "Create/Import",
      description:
        "Opens the menu for creating new tables, server-side functions or importing csv/json files.",
      docs: `
        Create new tables, server-side functions or import files into the current database.`,
      children: [
        {
          type: "popup",
          selector: getDataKeyElemSelector("new table"),
          title: "Create new table",
          description:
            "Opens the form to create a new table in the current database.",
          children: [],
        },
        {
          type: "popup",
          selector: getDataKeyElemSelector("import file"),
          title: "Import file",
          description:
            "Opens the form to import a file into the current database.",
          docs: `
            Import files into the current database. Supported file types include CSV, GeoJSON, and JSON.
            The import process allows you to specify the table name, infer column data types, and choose how to insert JSON/GeoJSON data into the table.  
            
            <img src="./screenshots/file_importer.svgif.svg" alt="File Importer screenshot" />
          `,
          docOptions: "asSeparateFile",
          childrenTitle: "Import file options",
          children: [
            {
              type: "input",
              inputType: "file",
              selectorCommand: "FileBtn",
              title: "Import file",
              description:
                "Input field for selecting a file to import. Supported types: csv/geojson/json.",
            },
            {
              type: "input",
              inputType: "text",
              selector: getDataLabelElemSelector("Table name"),
              title: "Table name",
              description:
                "New/existing table name into which data is to be imported.",
            },
            {
              type: "input",
              inputType: "checkbox",
              selector: getDataLabelElemSelector(
                "Try to infer and apply column data types",
              ),
              title: "Try to infer and apply column data types",
              description:
                "Checkbox for inferring and applying column data types during import. If checked, the system will attempt to determine the appropriate data types for each column based on the imported file. If unchecked, TEXT data type will be used for all columns.",
            },
            {
              type: "input",
              inputType: "checkbox",
              selector: getDataLabelElemSelector("Drop table if exists"),
              title: "Drop table if exists",
              description:
                "Checkbox for dropping the table if it already exists in the database. If checked, the existing table will be deleted before importing the new file.",
            },
            {
              type: "select",
              selector: getDataLabelElemSelector("Insert as"),
              title: "Insert as",
              description:
                "Select list for choosing the method of inserting JSON/GeoJSON data into the table. Options include: Single text value, JSONB rows, and Properties with geometry.",
            },
            {
              type: "button",
              selectorCommand: "FileImporterFooter.import",
              title: "Import",
              description:
                "Button to initiate the import process. Click to start importing the selected file into the specified table.",
            },
          ],
        },
        {
          type: "popup",
          selector: getDataKeyElemSelector("new function"),
          title: "Create TS Function",
          description:
            "Opens the form to create a new server-side TypeScript function for the current database.",
          children: [],
        },
      ],
    },
    {
      type: "popup",
      selectorCommand: "SchemaGraph",
      title: "Schema diagram",
      description:
        "Opens the schema diagram for visualizing the relationships between tables in the current database.",
      docs: `
        Explore your database structure visually through the schema diagram. This tool lets you:
        - **Select schemas** — Choose one or multiple schemas to display
        - **Navigate freely** — Pan and zoom to focus on specific areas
        - **View table relationships** — See how tables connect through foreign keys
        - **Filter your view** — Show or hide tables and columns by relationship type
        - **Color links by root table** — Trace relationships back to their source at a glance. Links inherit the color of the table that defines the relationship (e.g., all user_id foreign keys match the users table color)
        - **Reset the layout** — Return to the default view which auto-arranges tables ensuring the most linked tables are central

        It allows you to explore the schema structure, view table relationships, and manage the layout of the schema diagram.
        You can pan and zoom the diagram, select schemas, filter tables and columns based on their relationship types, reset the layout.
        Link color modes allow you to better understand related tables and foreign key properties.
        
        <img src="./screenshots/schema_diagram.svgif.svg" alt="Schema diagram screenshot" />

        ## Controls
      `,
      docOptions: "asSeparateFile",
      childrenTitle: "Top controls",
      children: [
        {
          type: "select",
          selectorCommand: "SchemaGraph.TopControls.tableRelationsFilter",
          title: "Table relationship filter",
          description:
            "Display tables based on their relationship type. Options include: all, linked (with relationships), orphaned (without relationships).",
        },
        {
          type: "select",
          selectorCommand: "SchemaGraph.TopControls.columnRelationsFilter",
          title: "Column relationship filter",
          description:
            "Display columns based on their relationship type. Options include: all, references (with relationships), none (no columns/only table names will be shown).",
        },
        {
          type: "select",
          title: "Link colour mode",
          selectorCommand: "SchemaGraph.TopControls.linkColorMode",
          description:
            "Colour links by: default (fixed colour), root table (the colour of the table the relationship tree originates from), on-delete/on-update (colour based on constraint referential action).",
        },
        {
          type: "button",
          selectorCommand: "SchemaGraph.TopControls.resetLayout",
          title: "Reset layout",
          description:
            "Moving tables is persisted the state database. Clicking this resets the schema diagram layout to its initial state.",
        },
        {
          type: "button",
          selectorCommand: "Popup.close",
          title: "Close schema diagram",
          description:
            "Closes the schema diagram and returns to the dashboard menu.",
        },
      ],
    },
  ],
} satisfies UIDocElement;


================================================
FILE: client/src/app/UIDocs/connection/dashboard/mapUIDoc.ts
================================================
import { fixIndent } from "../../../../demo/scripts/sqlVideoDemo";
import {
  getCommandElemSelector,
  getDataKeyElemSelector,
} from "../../../../Testing";
import type { UIDocElement } from "../../../UIDocs";
import { getCommonViewHeaderUIDoc } from "../getCommonViewHeaderUIDoc";

export const mapUIDoc = {
  type: "section",
  selector: `.SilverGridChild[data-view-type="map"]`,
  title: "Map view",
  description:
    "Displays a map visualization based on the Table/SQL query results.",
  docOptions: "asSeparateFile",
  docs: fixIndent(`
    The map view allows you to visualize geographical data from your database.
    It requires the [PostGIS](https://postgis.net/) extension to be installed on your PostgreSQL database.
    It can display points, lines, and polygons based on geometry or geography columns in your tables or views.
    It supports multiple layers, custom basemaps, and various map controls for interaction.

    <img src="./screenshots/map.svgif.svg" alt="Map view screenshot" />
    
  `),
  children: [
    getCommonViewHeaderUIDoc(
      "Shows the table/view name together with the geometry/geography column name used for the map visualization.",
      {
        title: "Map view menu",
        docs: fixIndent(`
          The map view menu provides options for configuring the map visualization, including data refresh, basemap settings, and layer management.
          
        `),
        description: "Data refresh and display options.",
        children: [
          {
            type: "tab",
            selector:
              getCommandElemSelector("MenuList") +
              " " +
              getDataKeyElemSelector("Data refresh"),
            title: "Data refresh",
            description:
              "Allows setting subscriptions or data refresh rates. By default every table subscribes to data changes.",
            children: [],
          },
          {
            type: "tab",
            selector:
              getCommandElemSelector("MenuList") +
              " " +
              getDataKeyElemSelector("Basemap"),
            title: "Basemap",
            description: "Allows setting the map tiles and projection.",
            children: [
              {
                type: "select",
                selectorCommand: "MapBasemapOptions.Projection",
                title: "Projection",
                description:
                  "Allows setting the map projection: Mercator (default) or Orthographic (allows a setting custom tile image for plan drawings).",
              },
            ],
          },
          {
            type: "tab",
            selector:
              getCommandElemSelector("MenuList") +
              " " +
              getDataKeyElemSelector("Layers"),
            title: "Layers",
            description:
              "Allows setting the map layers data source and style. The map supports multiple layers.",
            children: [],
          },
          {
            type: "tab",
            selector:
              getCommandElemSelector("MenuList") +
              " " +
              getDataKeyElemSelector("Settings"),
            title: "Settings",
            description:
              "Allows setting the map layout options: aggregation limit, click behavior, etc.",
            children: [],
          },
        ],
      },
      "chart",
    ),
    {
      type: "section",
      selector: ".Window",
      title: "Map window with controls",
      description:
        "Map visualization and controls for interacting with the map.",
      docs: fixIndent(`
        The map window contains the map visualization and controls for interacting with the map.
        It allows you to add layers, set the map extent behavior, and toggle
Download .txt
gitextract_slssybq4/

├── .dockerignore
├── .eslintrc.common.js
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── BUG.yml
│   │   ├── CUSTOM.yml
│   │   ├── FEATURE.yml
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   ├── custom.md
│   │   └── feature_request.md
│   └── workflows/
│       ├── docker_test.yml
│       ├── electron_build_linux.yml
│       ├── electron_build_macos.yml
│       ├── electron_build_windows.yml
│       ├── electron_linux_test.yml
│       ├── electron_macos_test.yml
│       ├── linux_test.yml
│       ├── macos_test.yml
│       ├── on_release.yml
│       ├── package_version_increased.yml
│       └── windows_test.yml
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .vscode/
│   └── settings.json
├── DB-Dockerfile
├── Dockerfile
├── LICENSE
├── PRIVACY
├── README.md
├── SECURITY.md
├── changelog/
│   ├── v1.0.0.md
│   ├── v2.0.0.md
│   ├── v2.2.0.md
│   ├── v2.2.1.md
│   ├── v2.2.2.md
│   ├── v2.2.3.md
│   └── v2.2.4.md
├── client/
│   ├── .babelrc
│   ├── .gitignore
│   ├── build.sh
│   ├── eslint.config.mjs
│   ├── package.json
│   ├── public/
│   │   ├── manifest.json
│   │   └── robots.txt
│   ├── setup-icons.js
│   ├── src/
│   │   ├── App.css
│   │   ├── App.tsx
│   │   ├── Testing.ts
│   │   ├── WithPrgl.tsx
│   │   ├── app/
│   │   │   ├── CommandPalette/
│   │   │   │   ├── CommandPalette.css
│   │   │   │   ├── CommandPalette.tsx
│   │   │   │   ├── Documentation.css
│   │   │   │   ├── Documentation.tsx
│   │   │   │   ├── getDocumentation.ts
│   │   │   │   ├── getUIDocShortestPath.ts
│   │   │   │   ├── useGoToUI.tsx
│   │   │   │   ├── useHighlightDocItem.ts
│   │   │   │   └── utils.ts
│   │   │   ├── UIDocs/
│   │   │   │   ├── UIInstallationUIDoc.ts
│   │   │   │   ├── accountUIDoc.ts
│   │   │   │   ├── commandPaletteUIDoc.ts
│   │   │   │   ├── connection/
│   │   │   │   │   ├── AIAssistantUIDoc.ts
│   │   │   │   │   ├── config/
│   │   │   │   │   │   ├── accessControlUIDoc.ts
│   │   │   │   │   │   ├── apiUIDoc.ts
│   │   │   │   │   │   ├── backupAndRestoreUIDoc.ts
│   │   │   │   │   │   └── fileStorageUIDoc.ts
│   │   │   │   │   ├── connectionConfigUIDoc.ts
│   │   │   │   │   ├── dashboard/
│   │   │   │   │   │   ├── dashboardContentUIDoc.ts
│   │   │   │   │   │   ├── dashboardMenuUIDoc.ts
│   │   │   │   │   │   ├── mapUIDoc.ts
│   │   │   │   │   │   ├── serverSideFunctionUIDoc.ts
│   │   │   │   │   │   ├── sqlEditorUIDoc.ts
│   │   │   │   │   │   ├── table/
│   │   │   │   │   │   │   ├── addColumnMenuUIDoc.ts
│   │   │   │   │   │   │   ├── columnMenuUIDoc.ts
│   │   │   │   │   │   │   ├── paginationUIDoc.ts
│   │   │   │   │   │   │   ├── smartFilterBarUIDoc.ts
│   │   │   │   │   │   │   ├── smartFormUIDoc.ts
│   │   │   │   │   │   │   ├── tableMenuUIDoc.ts
│   │   │   │   │   │   │   └── tableUIDoc.ts
│   │   │   │   │   │   └── timechartUIDoc.ts
│   │   │   │   │   ├── dashboardUIDoc.ts
│   │   │   │   │   └── getCommonViewHeaderUIDoc.ts
│   │   │   │   ├── connectionsUIDoc.ts
│   │   │   │   ├── desktopInstallation.ts
│   │   │   │   ├── editConnectionUIDoc.ts
│   │   │   │   ├── navbarUIDoc.ts
│   │   │   │   ├── overviewUIDoc.ts
│   │   │   │   └── serverSettingsUIDoc.ts
│   │   │   ├── UIDocs.ts
│   │   │   ├── XRealIpSpoofableAlert.tsx
│   │   │   └── domToSVG/
│   │   │       ├── SVGif/
│   │   │       │   ├── addSVGifCaption.ts
│   │   │       │   ├── addSVGifPointer.ts
│   │   │       │   ├── addSVGifTimelineControls.ts
│   │   │       │   ├── animations/
│   │   │       │   │   ├── getSVGifCursorAnimationHandler.ts
│   │   │       │   │   ├── getSVGifTypeAnimation.ts
│   │   │       │   │   └── getSVGifZoomToAnimation.ts
│   │   │       │   ├── compressSVGif.ts
│   │   │       │   ├── getSVGif.ts
│   │   │       │   ├── getSVGifAnimations.ts
│   │   │       │   ├── getSVGifParsedScenes.ts
│   │   │       │   ├── getSVGifRevealKeyframes.ts
│   │   │       │   └── getSVGifTargetBBox.ts
│   │   │       ├── addFragmentViewBoxes.ts
│   │   │       ├── containers/
│   │   │       │   ├── addOverflowClipPath.ts
│   │   │       │   ├── bgAndBorderToSVG.ts
│   │   │       │   ├── deduplicateSVGPaths.ts
│   │   │       │   ├── elementToSVG.ts
│   │   │       │   ├── rectangleToSVG.ts
│   │   │       │   └── shadowToSVG.ts
│   │   │       ├── domToSVG.ts
│   │   │       ├── domToThemeAwareSVG.ts
│   │   │       ├── getCorrespondingDarkNode.ts
│   │   │       ├── graphics/
│   │   │       │   ├── fontIconToSVG.ts
│   │   │       │   ├── getForeignObject.ts
│   │   │       │   └── imgToSVG.ts
│   │   │       ├── recordDomChanges.ts
│   │   │       ├── setThemeForSVGScreenshot.ts
│   │   │       ├── text/
│   │   │       │   ├── getTextForSVG.ts
│   │   │       │   └── textToSVG.ts
│   │   │       └── utils/
│   │   │           ├── addNewChildren.ts
│   │   │           ├── canvasToDataURL.ts
│   │   │           ├── copyAnimationStylesToSvg.ts
│   │   │           ├── getWhatToRenderOnSVG.ts
│   │   │           ├── isElementVisible.ts
│   │   │           └── toFixed.ts
│   │   ├── appUtils.ts
│   │   ├── components/
│   │   │   ├── AlertProvider.tsx
│   │   │   ├── Animations.css
│   │   │   ├── Animations.tsx
│   │   │   ├── Btn.css
│   │   │   ├── Btn.tsx
│   │   │   ├── ButtonBar.tsx
│   │   │   ├── ButtonGroup.tsx
│   │   │   ├── Chat/
│   │   │   │   ├── Chat.css
│   │   │   │   ├── Chat.tsx
│   │   │   │   ├── ChatFileAttachments/
│   │   │   │   │   └── ChatFileAttachments.tsx
│   │   │   │   ├── ChatMessage.tsx
│   │   │   │   ├── ChatSendControls.tsx
│   │   │   │   ├── ChatSpeech/
│   │   │   │   │   ├── ChatSpeech.tsx
│   │   │   │   │   ├── ChatSpeechSetup.tsx
│   │   │   │   │   ├── hooks/
│   │   │   │   │   │   ├── SpeechRecorder.ts
│   │   │   │   │   │   ├── renderSpeechAudioLevelsIcon.ts
│   │   │   │   │   │   ├── useSpeechRecorder.ts
│   │   │   │   │   │   └── useSpeechToTextWeb.ts
│   │   │   │   │   └── useChatSpeechSetup.ts
│   │   │   │   ├── Marked.css
│   │   │   │   ├── Marked.tsx
│   │   │   │   ├── MonacoCodeInMarkdown/
│   │   │   │   │   ├── MarkdownMonacoCodeHeader.tsx
│   │   │   │   │   ├── MonacoCodeInMarkdown.tsx
│   │   │   │   │   └── useOnRunSQL.ts
│   │   │   │   ├── useChatOnPaste.ts
│   │   │   │   └── useChatState.ts
│   │   │   ├── Checkbox.css
│   │   │   ├── Checkbox.tsx
│   │   │   ├── Chip.css
│   │   │   ├── Chip.tsx
│   │   │   ├── ClickCatch.tsx
│   │   │   ├── ClickCatchOverlay.css
│   │   │   ├── ClickCatchOverlay.tsx
│   │   │   ├── ConfirmationDialog.tsx
│   │   │   ├── CopyToClipboardBtn.tsx
│   │   │   ├── DragOverUpload/
│   │   │   │   ├── DragOverUpload.css
│   │   │   │   └── DragOverUpload.tsx
│   │   │   ├── DraggableLI.tsx
│   │   │   ├── ErrorComponent.tsx
│   │   │   ├── ExpandSection.tsx
│   │   │   ├── Expander.tsx
│   │   │   ├── FileBrowser/
│   │   │   │   ├── FileBrowser.tsx
│   │   │   │   └── FileBrowserCurrentDirectory.tsx
│   │   │   ├── FileInput/
│   │   │   │   ├── DropZone.tsx
│   │   │   │   ├── FileInput.tsx
│   │   │   │   ├── FileInputMedia.tsx
│   │   │   │   └── useFileDropZone.ts
│   │   │   ├── FlashMessage.tsx
│   │   │   ├── Flex.tsx
│   │   │   ├── FormField/
│   │   │   │   ├── FormField.css
│   │   │   │   ├── FormField.tsx
│   │   │   │   ├── FormFieldCodeEditor.tsx
│   │   │   │   ├── FormFieldDebounced.tsx
│   │   │   │   ├── FormFieldSkeleton.tsx
│   │   │   │   └── onFormFieldKeyDown.ts
│   │   │   ├── Hotkey.css
│   │   │   ├── Hotkey.tsx
│   │   │   ├── Icon/
│   │   │   │   └── Icon.tsx
│   │   │   ├── IconPalette/
│   │   │   │   └── IconPalette.tsx
│   │   │   ├── InfoRow.tsx
│   │   │   ├── Input.tsx
│   │   │   ├── JSONBSchema/
│   │   │   │   ├── JSONBSchema.tsx
│   │   │   │   ├── JSONBSchemaAllowedOptions.tsx
│   │   │   │   ├── JSONBSchemaArray.tsx
│   │   │   │   ├── JSONBSchemaLookup.tsx
│   │   │   │   ├── JSONBSchemaObject.tsx
│   │   │   │   ├── JSONBSchemaOneOfType.tsx
│   │   │   │   ├── JSONBSchemaPrimitive.tsx
│   │   │   │   ├── JSONBSchemaRecord.tsx
│   │   │   │   └── isCompleteJSONB.ts
│   │   │   ├── JsonRenderer.tsx
│   │   │   ├── Label.css
│   │   │   ├── Label.tsx
│   │   │   ├── LabeledRow.tsx
│   │   │   ├── List.css
│   │   │   ├── List.tsx
│   │   │   ├── Loader/
│   │   │   │   ├── Loading.css
│   │   │   │   ├── Loading.tsx
│   │   │   │   ├── SpinnerV2.tsx
│   │   │   │   ├── SpinnerV3.tsx
│   │   │   │   └── SpinnerV4.tsx
│   │   │   ├── MediaViewer/
│   │   │   │   ├── MediaViewer.tsx
│   │   │   │   └── RenderMedia.tsx
│   │   │   ├── MenuList.css
│   │   │   ├── MenuList.tsx
│   │   │   ├── MenuListItem.tsx
│   │   │   ├── MonacoEditor/
│   │   │   │   ├── MonacoEditor.tsx
│   │   │   │   ├── useMonacoEditorAddActions.ts
│   │   │   │   └── useWhyDidYouUpdate.ts
│   │   │   ├── MonacoLogRenderer/
│   │   │   │   └── MonacoLogRenderer.tsx
│   │   │   ├── NavBar/
│   │   │   │   ├── NavBar.css
│   │   │   │   ├── NavBar.tsx
│   │   │   │   ├── NavBarWrapper.tsx
│   │   │   │   └── useNavBarItems.ts
│   │   │   ├── Pan.tsx
│   │   │   ├── Popup/
│   │   │   │   ├── Footer.tsx
│   │   │   │   ├── FooterButtons.tsx
│   │   │   │   ├── Popup.css
│   │   │   │   ├── Popup.tsx
│   │   │   │   ├── PopupHeader.tsx
│   │   │   │   ├── getPopupPosition.ts
│   │   │   │   ├── getPopupStyle.ts
│   │   │   │   └── popupCheckPosition.ts
│   │   │   ├── PopupMenu.tsx
│   │   │   ├── PopupMenuList.tsx
│   │   │   ├── PostgresInstallationInstructions.tsx
│   │   │   ├── ProgressBar.css
│   │   │   ├── ProgressBar.tsx
│   │   │   ├── QRCodeImage.tsx
│   │   │   ├── Scheduler.css
│   │   │   ├── Scheduler.tsx
│   │   │   ├── ScrollFade/
│   │   │   │   ├── ScrollFade.tsx
│   │   │   │   └── useResizeObserver.ts
│   │   │   ├── SearchList/
│   │   │   │   ├── SearchInput.tsx
│   │   │   │   ├── SearchList.css
│   │   │   │   ├── SearchList.tsx
│   │   │   │   ├── SearchListContent.tsx
│   │   │   │   ├── SearchListItems.tsx
│   │   │   │   ├── SearchListRowContent.tsx
│   │   │   │   ├── getSearchListMatchAndHighlight.tsx
│   │   │   │   ├── hooks/
│   │   │   │   │   ├── useSearchListItems.tsx
│   │   │   │   │   ├── useSearchListItemsSorting.ts
│   │   │   │   │   ├── useSearchListOnClick.ts
│   │   │   │   │   ├── useSearchListOnKeyUpDown.ts
│   │   │   │   │   └── useSearchListSearch.ts
│   │   │   │   └── searchMatchUtils/
│   │   │   │       ├── getItemSearchRank.ts
│   │   │   │       └── getSearchRanking.ts
│   │   │   ├── Section.tsx
│   │   │   ├── Select/
│   │   │   │   ├── Select.css
│   │   │   │   ├── Select.tsx
│   │   │   │   └── SelectTriggerButton.tsx
│   │   │   ├── ShorterText.tsx
│   │   │   ├── SidePanel.tsx
│   │   │   ├── Slider.css
│   │   │   ├── Slider.tsx
│   │   │   ├── StatusChip.tsx
│   │   │   ├── Stepper.tsx
│   │   │   ├── SvgIcon.tsx
│   │   │   ├── SwitchToggle.css
│   │   │   ├── SwitchToggle.tsx
│   │   │   ├── Table/
│   │   │   │   ├── Pagination.tsx
│   │   │   │   ├── Table.css
│   │   │   │   ├── Table.tsx
│   │   │   │   ├── TableBody.tsx
│   │   │   │   ├── TableHeader.tsx
│   │   │   │   ├── TableRow.tsx
│   │   │   │   └── useVirtualisedRows.ts
│   │   │   ├── Tabs.tsx
│   │   │   └── Tooltip.tsx
│   │   ├── dashboard/
│   │   │   ├── API/
│   │   │   │   └── zip.ts
│   │   │   ├── AccessControl/
│   │   │   │   ├── AccessControl.tsx
│   │   │   │   ├── AccessControlRuleEditor.tsx
│   │   │   │   ├── AccessRuleEditorFooter.tsx
│   │   │   │   ├── AccessRuleSummary.tsx
│   │   │   │   ├── ContextDataSelector.tsx
│   │   │   │   ├── ContextFilter.tsx
│   │   │   │   ├── ExistingAccessRules.tsx
│   │   │   │   ├── Methods/
│   │   │   │   │   ├── ArgumentDefinition.tsx
│   │   │   │   │   ├── MethodDefinition.tsx
│   │   │   │   │   ├── MethodDefinitionEditAsJson.tsx
│   │   │   │   │   ├── MethodFunctionDefinition.tsx
│   │   │   │   │   ├── ReferencesDefinition.tsx
│   │   │   │   │   └── useCodeEditorTsTypes.ts
│   │   │   │   ├── OptionControllers/
│   │   │   │   │   ├── DynamicFields.tsx
│   │   │   │   │   ├── FieldFilterControl.tsx
│   │   │   │   │   └── FilterControl.tsx
│   │   │   │   ├── PasswordlessSetup.tsx
│   │   │   │   ├── PermissionTypes/
│   │   │   │   │   ├── PAllTables.tsx
│   │   │   │   │   ├── PCustomTables.tsx
│   │   │   │   │   └── PRunSQL.tsx
│   │   │   │   ├── PublishedWorkspaceSelector.tsx
│   │   │   │   ├── RuleTypeControls/
│   │   │   │   │   ├── ComparablePGPolicies.tsx
│   │   │   │   │   ├── DeleteRuleControl.tsx
│   │   │   │   │   ├── ExampleComparablePolicy.tsx
│   │   │   │   │   ├── InsertRuleControl.tsx
│   │   │   │   │   ├── RuleToggle.tsx
│   │   │   │   │   ├── SelectRuleControl.tsx
│   │   │   │   │   ├── SyncRuleControl.tsx
│   │   │   │   │   ├── UpdateRuleControl.tsx
│   │   │   │   │   └── getComparablePGPolicy.ts
│   │   │   │   ├── TableRules/
│   │   │   │   │   ├── FileTableAccessControlInfo.tsx
│   │   │   │   │   ├── TablePermissionControls.tsx
│   │   │   │   │   ├── TableRulesPopup.tsx
│   │   │   │   │   └── useLocalTableRulesErrors.ts
│   │   │   │   ├── UserStats.tsx
│   │   │   │   ├── UserSyncConfig.tsx
│   │   │   │   ├── UserTypeSelect.tsx
│   │   │   │   ├── useAccessControlSearchParams.ts
│   │   │   │   └── useEditedAccessRule.ts
│   │   │   ├── AskLLM/
│   │   │   │   ├── AskLLM.tsx
│   │   │   │   ├── Chat/
│   │   │   │   │   ├── AskLLMChat.tsx
│   │   │   │   │   ├── AskLLMChatHeader.tsx
│   │   │   │   │   ├── AskLLMChatMessages/
│   │   │   │   │   │   ├── LLMChatMessage/
│   │   │   │   │   │   │   ├── LLMChatMessage.tsx
│   │   │   │   │   │   │   ├── LLMChatMessageContent.tsx
│   │   │   │   │   │   │   ├── LLMChatMessageContentText.tsx
│   │   │   │   │   │   │   ├── LLMChatMessageHeader.tsx
│   │   │   │   │   │   │   ├── LLMGroupedToolCallsMessage.tsx
│   │   │   │   │   │   │   └── LLMSingleChatMessage.tsx
│   │   │   │   │   │   ├── ProstglesToolUseMessage/
│   │   │   │   │   │   │   ├── ProstglesMCPTools/
│   │   │   │   │   │   │   │   ├── DockerSandboxCreateContainer.tsx
│   │   │   │   │   │   │   │   ├── ExecuteSQL.tsx
│   │   │   │   │   │   │   │   ├── LoadSuggestedDashboards.tsx
│   │   │   │   │   │   │   │   ├── LoadSuggestedToolsAndPrompt/
│   │   │   │   │   │   │   │   │   ├── LoadSuggestedToolsAndPrompt.tsx
│   │   │   │   │   │   │   │   │   └── LoadSuggestedToolsAndPromptLoadBtn.tsx
│   │   │   │   │   │   │   │   ├── LoadSuggestedWorkflow.tsx
│   │   │   │   │   │   │   │   ├── WebSearch/
│   │   │   │   │   │   │   │   │   ├── Favicon.tsx
│   │   │   │   │   │   │   │   │   └── WebSearch.tsx
│   │   │   │   │   │   │   │   └── common/
│   │   │   │   │   │   │   │       ├── DatabaseAccessPermissions.tsx
│   │   │   │   │   │   │   │       ├── HeaderList.tsx
│   │   │   │   │   │   │   │       └── useTypedToolUseResultData.ts
│   │   │   │   │   │   │   └── ProstglesToolUseMessage.tsx
│   │   │   │   │   │   ├── ToolUseChatMessage/
│   │   │   │   │   │   │   ├── PopupSection.tsx
│   │   │   │   │   │   │   ├── ToolUseChatMessage.tsx
│   │   │   │   │   │   │   ├── ToolUseChatMessageBtn.tsx
│   │   │   │   │   │   │   ├── ToolUseChatMessageBtnTextSummary.tsx
│   │   │   │   │   │   │   ├── ToolUseChatMessageJSONData.tsx
│   │   │   │   │   │   │   ├── ToolUseChatMessageResult.tsx
│   │   │   │   │   │   │   ├── useToolUseChatMessage.ts
│   │   │   │   │   │   │   └── utils/
│   │   │   │   │   │   │       └── getToolUseResult.ts
│   │   │   │   │   │   └── hooks/
│   │   │   │   │   │       ├── useLLMChatMessageGrouper.tsx
│   │   │   │   │   │       └── useLLMChatMessages.tsx
│   │   │   │   │   ├── AskLLMChatOptions.tsx
│   │   │   │   │   ├── useAskLLMChatSend.ts
│   │   │   │   │   ├── useLLMChat.tsx
│   │   │   │   │   └── useLLMSchemaStr.ts
│   │   │   │   ├── ChatActionBar/
│   │   │   │   │   ├── AskLLMChatActionBar.tsx
│   │   │   │   │   ├── AskLLMChatActionBarDatabaseAccess.tsx
│   │   │   │   │   ├── AskLLMChatActionBarMCPTools.tsx
│   │   │   │   │   ├── AskLLMChatActionBarMCPToolsBtn.tsx
│   │   │   │   │   ├── AskLLMChatActionBarModelSelector.tsx
│   │   │   │   │   └── AskLLMChatActionBarPromptSelector.tsx
│   │   │   │   ├── Setup/
│   │   │   │   │   ├── AddLLMPromptForm.tsx
│   │   │   │   │   ├── AskLLMAccessControl.tsx
│   │   │   │   │   ├── LLMProviderSetup.tsx
│   │   │   │   │   ├── ProstglesSignup.tsx
│   │   │   │   │   ├── SetupLLMCredentials.tsx
│   │   │   │   │   └── useLLMSetupState.ts
│   │   │   │   ├── Tools/
│   │   │   │   │   ├── AskLLMToolApprover.tsx
│   │   │   │   │   ├── loadGeneratedWorkspaces/
│   │   │   │   │   │   ├── loadGeneratedBarchart.ts
│   │   │   │   │   │   ├── loadGeneratedMap.ts
│   │   │   │   │   │   ├── loadGeneratedTimechart.ts
│   │   │   │   │   │   └── loadGeneratedWorkspaces.ts
│   │   │   │   │   └── useLLMToolsApprover.tsx
│   │   │   │   └── useLocalLLM.ts
│   │   │   ├── BackupAndRestore/
│   │   │   │   ├── AutomaticBackups.tsx
│   │   │   │   ├── BackupsControls.tsx
│   │   │   │   ├── BackupsInProgress.tsx
│   │   │   │   ├── CloudStorageCredentialSelector.tsx
│   │   │   │   ├── CodeConfirmation.tsx
│   │   │   │   ├── CompletedBackups.tsx
│   │   │   │   ├── DumpLocationOptions.tsx
│   │   │   │   ├── DumpRestoreAlerts.tsx
│   │   │   │   ├── PGDumpOptions.tsx
│   │   │   │   ├── RenderBackupLogs.tsx
│   │   │   │   ├── RenderBackupStatus.tsx
│   │   │   │   ├── Restore/
│   │   │   │   │   ├── Restore.tsx
│   │   │   │   │   └── RestoreOptions.tsx
│   │   │   │   └── useBackupsControlsState.ts
│   │   │   ├── Charts/
│   │   │   │   ├── CanvasChart.ts
│   │   │   │   ├── TimeChart/
│   │   │   │   │   ├── TimeChart.tsx
│   │   │   │   │   ├── getBinValueLabels.ts
│   │   │   │   │   ├── getTimeAxisTicks.ts
│   │   │   │   │   ├── getTimechartBinSize.ts
│   │   │   │   │   ├── getTimechartTooltipIntersections.ts
│   │   │   │   │   ├── getTimechartTooltipShapes.ts
│   │   │   │   │   ├── measureText.ts
│   │   │   │   │   ├── onDeltaTimechart.ts
│   │   │   │   │   ├── onRenderTimechart.ts
│   │   │   │   │   └── prepareTimechartData.ts
│   │   │   │   ├── createHiPPICanvas.ts
│   │   │   │   ├── drawMonotoneXCurve.ts
│   │   │   │   ├── drawShapes/
│   │   │   │   │   ├── drawLinkLine.ts
│   │   │   │   │   ├── drawShapes.ts
│   │   │   │   │   ├── drawShapesOnSVG.ts
│   │   │   │   │   ├── findShortestPathAroundRectangles.ts
│   │   │   │   │   ├── getTimechartGradientPeakSections.ts
│   │   │   │   │   └── shortestLinkLineV2.ts
│   │   │   │   └── roundRect.ts
│   │   │   ├── Charts.tsx
│   │   │   ├── CodeEditor/
│   │   │   │   ├── CodeEditor.tsx
│   │   │   │   ├── CodeEditorWithSaveButton.tsx
│   │   │   │   ├── monacoTsLibs.ts
│   │   │   │   ├── registerLogLang.ts
│   │   │   │   └── utils/
│   │   │   │       ├── getMonacoJsonSchemas.ts
│   │   │   │       ├── setMonacoErrorMarkers.ts
│   │   │   │       ├── useSetMonacoJsonSchemas.ts
│   │   │   │       └── useSetMonacoTsLibraries.ts
│   │   │   ├── CodeExample.tsx
│   │   │   ├── ConnectionConfig/
│   │   │   │   ├── APIDetails/
│   │   │   │   │   ├── APICodeExamples.tsx
│   │   │   │   │   ├── APIDetails.tsx
│   │   │   │   │   ├── APIDetailsHttp.tsx
│   │   │   │   │   ├── APIDetailsTokens.tsx
│   │   │   │   │   ├── APIDetailsWs.tsx
│   │   │   │   │   └── AllowedOriginCheck.tsx
│   │   │   │   ├── ConnectionConfig.tsx
│   │   │   │   ├── ServerSideFunctions.tsx
│   │   │   │   └── useConnectionConfigSearchParams.ts
│   │   │   ├── ConnectionSelector.tsx
│   │   │   ├── Dashboard/
│   │   │   │   ├── CloseSaveSQLPopup.tsx
│   │   │   │   ├── DBS.ts
│   │   │   │   ├── Dashboard.tsx
│   │   │   │   ├── DashboardCenteredLayoutResizer.tsx
│   │   │   │   ├── PALETTE.ts
│   │   │   │   ├── ViewRenderer.tsx
│   │   │   │   ├── cloneWorkspace.ts
│   │   │   │   ├── dashboardUtils.ts
│   │   │   │   ├── debuggingUtils.ts
│   │   │   │   ├── getTables.ts
│   │   │   │   ├── getViewRendererUtils.ts
│   │   │   │   └── loadTable.ts
│   │   │   ├── DashboardMenu/
│   │   │   │   ├── CreateTable.tsx
│   │   │   │   ├── DashboardHotkeys.tsx
│   │   │   │   ├── DashboardMenu.tsx
│   │   │   │   ├── DashboardMenuContent.tsx
│   │   │   │   ├── DashboardMenuHeader.tsx
│   │   │   │   ├── DashboardMenuHotkeys.tsx
│   │   │   │   ├── DashboardMenuResizer.tsx
│   │   │   │   ├── DashboardMenuSettings.tsx
│   │   │   │   ├── NewTableMenu.tsx
│   │   │   │   ├── SettingsSection.tsx
│   │   │   │   └── useTableSizeInfo.ts
│   │   │   ├── DetailedFilterControl/
│   │   │   │   ├── DetailedFilterBaseControl.tsx
│   │   │   │   ├── DetailedFilterBaseControlRouter.tsx
│   │   │   │   ├── DetailedFilterBaseTypes/
│   │   │   │   │   ├── AgeFilter.tsx
│   │   │   │   │   ├── GeoFilter.tsx
│   │   │   │   │   ├── ListFilter/
│   │   │   │   │   │   ├── ListFilter.tsx
│   │   │   │   │   │   └── fetchListFilterOptions.ts
│   │   │   │   │   └── NumberOrDateFilter.tsx
│   │   │   │   ├── DetailedFilterControl.tsx
│   │   │   │   ├── FTS_LANGUAGES.ts
│   │   │   │   ├── FilterWrapper.css
│   │   │   │   ├── FilterWrapper.tsx
│   │   │   │   └── validateFilter.ts
│   │   │   ├── Feedback.tsx
│   │   │   ├── FileImporter/
│   │   │   │   ├── FileImporter.tsx
│   │   │   │   ├── FileImporterFooter.tsx
│   │   │   │   ├── checkCSVColumnDataTypes.tsx
│   │   │   │   ├── importFile.ts
│   │   │   │   ├── parseCSVFile.ts
│   │   │   │   └── setFile.ts
│   │   │   ├── FileTableControls/
│   │   │   │   ├── CreateFileColumn.tsx
│   │   │   │   ├── FileColumnConfigControls.tsx
│   │   │   │   ├── FileColumnConfigEditor.tsx
│   │   │   │   ├── FileStorageControls.tsx
│   │   │   │   ├── FileStorageDelete.tsx
│   │   │   │   ├── FileStorageReferencedTablesConfig.tsx
│   │   │   │   ├── FileTableConfigControls.tsx
│   │   │   │   └── useFileTableConfigControls.ts
│   │   │   ├── JSONBColumnEditor.tsx
│   │   │   ├── LinkMenu.tsx
│   │   │   ├── Map/
│   │   │   │   ├── DeckGLFeatureEditor.tsx
│   │   │   │   ├── DeckGLMap.css
│   │   │   │   ├── DeckGLMap.tsx
│   │   │   │   ├── DeckGLWrapped.ts
│   │   │   │   ├── InMapControls.tsx
│   │   │   │   ├── fitBounds.ts
│   │   │   │   ├── mapDrawUtils.ts
│   │   │   │   └── mapUtils.ts
│   │   │   ├── RTComp.tsx
│   │   │   ├── RenderFilter.tsx
│   │   │   ├── SQLEditor/
│   │   │   │   ├── SQLCompletion/
│   │   │   │   │   ├── CommonMatchImports.ts
│   │   │   │   │   ├── KEYWORDS.ts
│   │   │   │   │   ├── MacthCreate/
│   │   │   │   │   │   ├── MatchCreate.ts
│   │   │   │   │   │   ├── MatchCreateView.ts
│   │   │   │   │   │   ├── matchCreateIndex.ts
│   │   │   │   │   │   ├── matchCreatePolicy.ts
│   │   │   │   │   │   ├── matchCreateRule.tsx
│   │   │   │   │   │   ├── matchCreateTable.ts
│   │   │   │   │   │   └── matchCreateTrigger.ts
│   │   │   │   │   ├── MatchAlter/
│   │   │   │   │   │   ├── MatchAlter.tsx
│   │   │   │   │   │   ├── matchAlterPolicy.ts
│   │   │   │   │   │   ├── matchAlterTable.ts
│   │   │   │   │   │   └── matchCreateOrAlterUser.tsx
│   │   │   │   │   ├── MatchComment.ts
│   │   │   │   │   ├── MatchCopy.ts
│   │   │   │   │   ├── MatchDrop.ts
│   │   │   │   │   ├── MatchFirst.ts
│   │   │   │   │   ├── MatchGrant.ts
│   │   │   │   │   ├── MatchInsert.tsx
│   │   │   │   │   ├── MatchLast.ts
│   │   │   │   │   ├── MatchPublication.ts
│   │   │   │   │   ├── MatchReassign.ts
│   │   │   │   │   ├── MatchReindex.ts
│   │   │   │   │   ├── MatchSelect.ts
│   │   │   │   │   ├── MatchSet.ts
│   │   │   │   │   ├── MatchSubscription.ts
│   │   │   │   │   ├── MatchUpdate.ts
│   │   │   │   │   ├── MatchVacuum.ts
│   │   │   │   │   ├── MatchWith.ts
│   │   │   │   │   ├── MathDelete.ts
│   │   │   │   │   ├── PSQL.ts
│   │   │   │   │   ├── STARTING_KEYWORDS.ts
│   │   │   │   │   ├── TableKWDs.ts
│   │   │   │   │   ├── completionUtils/
│   │   │   │   │   │   ├── checkIfInsideDollarFunctionDefinition.ts
│   │   │   │   │   │   ├── checkIfUnfinishedParenthesis.ts
│   │   │   │   │   │   ├── getCodeBlock.ts
│   │   │   │   │   │   ├── getQueryReturnType.ts
│   │   │   │   │   │   ├── getTableExpressionReturnTypes.ts
│   │   │   │   │   │   ├── getTabularExpressions.ts
│   │   │   │   │   │   └── getTokens.ts
│   │   │   │   │   ├── getExpected.ts
│   │   │   │   │   ├── getJoinSuggestions.ts
│   │   │   │   │   ├── getMatch.ts
│   │   │   │   │   ├── getPGObjects.ts
│   │   │   │   │   ├── getPrevTokensNoParantheses.ts
│   │   │   │   │   ├── jsonbPathSuggest.ts
│   │   │   │   │   ├── monacoSQLSetup/
│   │   │   │   │   │   ├── registerHover.ts
│   │   │   │   │   │   └── registerSuggestions.ts
│   │   │   │   │   ├── suggestColumnLike.ts
│   │   │   │   │   ├── suggestCondition.ts
│   │   │   │   │   ├── suggestFuncArgs.ts
│   │   │   │   │   ├── suggestTableLike.ts
│   │   │   │   │   ├── suggestValue.ts
│   │   │   │   │   └── withKWDs.ts
│   │   │   │   ├── SQLEditorSuggestions.ts
│   │   │   │   ├── SQLSmartEditor.tsx
│   │   │   │   ├── SQL_SNIPPETS.ts
│   │   │   │   ├── W_SQLEditor.css
│   │   │   │   ├── W_SQLEditor.tsx
│   │   │   │   ├── addSqlEditorFunctions.ts
│   │   │   │   ├── defineCustomMonacoSQLTheme.ts
│   │   │   │   ├── getFormattedSql.ts
│   │   │   │   ├── registerFunctionSuggestions.ts
│   │   │   │   └── utils/
│   │   │   │       ├── scrollToLineIfNeeded.ts
│   │   │   │       └── setMonacEditorError.ts
│   │   │   ├── SampleSchemas.tsx
│   │   │   ├── SchemaGraph/
│   │   │   │   ├── ERDSchema/
│   │   │   │   │   ├── ERDSchema.tsx
│   │   │   │   │   ├── getInitialPlacement.ts
│   │   │   │   │   ├── useCanvasPanZoom.ts
│   │   │   │   │   ├── useDrawSchemaShapes.ts
│   │   │   │   │   ├── useFetchSchemaForDiagram.ts
│   │   │   │   │   ├── usePanShapes.ts
│   │   │   │   │   └── useSchemaShapes.ts
│   │   │   │   ├── SchemaGraph.tsx
│   │   │   │   ├── SchemaGraphControls.tsx
│   │   │   │   └── types.ts
│   │   │   ├── SearchAll/
│   │   │   │   ├── SearchAll.tsx
│   │   │   │   ├── SearchAllContent.tsx
│   │   │   │   ├── SearchAllHeader.tsx
│   │   │   │   ├── SearchMatchRow.tsx
│   │   │   │   └── hooks/
│   │   │   │       ├── useSearchAllState.ts
│   │   │   │       ├── useSearchListProps.tsx
│   │   │   │       ├── useSearchTables.tsx
│   │   │   │       └── useTablesAndViewsSearchItems.ts
│   │   │   ├── SilverGrid/
│   │   │   │   ├── SilverGrid.tsx
│   │   │   │   ├── SilverGridChild.tsx
│   │   │   │   ├── SilverGridChildHeader.tsx
│   │   │   │   ├── SilverGridResizer.tsx
│   │   │   │   └── TreeBuilder.ts
│   │   │   ├── SmartCard/
│   │   │   │   ├── SmartCard.tsx
│   │   │   │   ├── SmartCardActions.tsx
│   │   │   │   ├── SmartCardColumn.tsx
│   │   │   │   ├── getSelectForFieldConfigs.ts
│   │   │   │   ├── getSmartCardColumns.ts
│   │   │   │   ├── parseFieldConfigs.tsx
│   │   │   │   └── useFieldConfigParser.ts
│   │   │   ├── SmartCardList/
│   │   │   │   ├── SmartCardList.tsx
│   │   │   │   ├── SmartCardListHeaderControls.tsx
│   │   │   │   ├── SmartCardListJoinedNewRecords.tsx
│   │   │   │   └── useSmartCardListState.ts
│   │   │   ├── SmartFilter/
│   │   │   │   ├── AddJoinFilter.tsx
│   │   │   │   ├── MinimisedFilter.css
│   │   │   │   ├── MinimisedFilter.tsx
│   │   │   │   ├── SmartAddFilter.tsx
│   │   │   │   ├── SmartFilter.tsx
│   │   │   │   ├── SmartSearch/
│   │   │   │   │   ├── SmartSearch.css
│   │   │   │   │   ├── SmartSearch.tsx
│   │   │   │   │   ├── getSmartSearchRows.ts
│   │   │   │   │   └── onSearchItems.tsx
│   │   │   │   ├── SortByControl.tsx
│   │   │   │   └── smartFilterUtils.ts
│   │   │   ├── SmartFilterBar/
│   │   │   │   ├── SmartFilterBar.tsx
│   │   │   │   ├── SmartFilterBarFilters.tsx
│   │   │   │   ├── SmartFilterBarRightActions.tsx
│   │   │   │   ├── SmartFilterBarSearch.tsx
│   │   │   │   ├── SmartFilterBarSort.tsx
│   │   │   │   └── useSmartFilterBarState.ts
│   │   │   ├── SmartForm/
│   │   │   │   ├── ChipArrayEditor.tsx
│   │   │   │   ├── InsertButton.tsx
│   │   │   │   ├── JoinedRecords/
│   │   │   │   │   ├── JoinedRecords.tsx
│   │   │   │   │   ├── JoinedRecordsAddRow.tsx
│   │   │   │   │   ├── JoinedRecordsSection.tsx
│   │   │   │   │   ├── getJoinFilter.ts
│   │   │   │   │   ├── useJoinedRecordsSections.ts
│   │   │   │   │   └── useJoinedSectionFieldConfigs.tsx
│   │   │   │   ├── SmartForm.tsx
│   │   │   │   ├── SmartFormField/
│   │   │   │   │   ├── RenderValue.tsx
│   │   │   │   │   ├── SmartFormField.tsx
│   │   │   │   │   ├── SmartFormFieldFileSection.tsx
│   │   │   │   │   ├── SmartFormFieldForeignKey.tsx
│   │   │   │   │   ├── SmartFormFieldLinkedData.tsx
│   │   │   │   │   ├── SmartFormFieldLinkedDataInsert/
│   │   │   │   │   │   ├── SmartFormFieldLinkedDataInsert.tsx
│   │   │   │   │   │   └── useSmartFormFieldLinkedDataInsert.tsx
│   │   │   │   │   ├── SmartFormFieldLinkedDataSearch.tsx
│   │   │   │   │   ├── SmartFormFieldRightButtons.tsx
│   │   │   │   │   ├── ViewMoreSmartCardList.tsx
│   │   │   │   │   ├── fetchColumnValueSuggestions.ts
│   │   │   │   │   ├── fetchForeignKeyOptions.tsx
│   │   │   │   │   ├── fieldUtils.ts
│   │   │   │   │   ├── useFormData.ts
│   │   │   │   │   ├── useNestedInsertDefaultData.ts
│   │   │   │   │   ├── useSmartFormFieldAsJSON.tsx
│   │   │   │   │   └── useSmartFormFieldOnChange.ts
│   │   │   │   ├── SmartFormFieldList.tsx
│   │   │   │   ├── SmartFormFileSection.tsx
│   │   │   │   ├── SmartFormFooter/
│   │   │   │   │   ├── SmartFormFooterButtons.tsx
│   │   │   │   │   └── useSmartFormActions.ts
│   │   │   │   ├── SmartFormNewRowDataHandler.ts
│   │   │   │   ├── SmartFormPopup/
│   │   │   │   │   └── SmartFormPopupWrapper.tsx
│   │   │   │   ├── SmartFormUpperFooter/
│   │   │   │   │   ├── SmartFormUpperFooter.tsx
│   │   │   │   │   └── useActiveJoinedRecordsTab.ts
│   │   │   │   ├── useNewRowDataHandler.ts
│   │   │   │   ├── useSmartForm.ts
│   │   │   │   ├── useSmartFormColumns.ts
│   │   │   │   └── useSmartFormMode.ts
│   │   │   ├── SmartSelect.tsx
│   │   │   ├── SmartTable.tsx
│   │   │   ├── StatusMonitor/
│   │   │   │   ├── StatusMonitor.tsx
│   │   │   │   ├── StatusMonitorConnections.tsx
│   │   │   │   ├── StatusMonitorInfoHeader/
│   │   │   │   │   ├── StatusMonitorInfoHeader.tsx
│   │   │   │   │   ├── StatusMonitorInfoHeaderCpu.tsx
│   │   │   │   │   └── StatusMonitorInfoHeaderMemory.tsx
│   │   │   │   ├── StatusMonitorProcList.tsx
│   │   │   │   └── StatusMonitorProcListControlsHeader.tsx
│   │   │   ├── TableConfig/
│   │   │   │   ├── ProcessLogs.tsx
│   │   │   │   └── TableConfig.tsx
│   │   │   ├── TimeSeries.tsx
│   │   │   ├── UserManager.tsx
│   │   │   ├── W_Barchart/
│   │   │   │   ├── W_Barchart.tsx
│   │   │   │   ├── fetchSQLBarchartData.ts
│   │   │   │   └── useBarchartData.ts
│   │   │   ├── W_Map/
│   │   │   │   ├── OSM/
│   │   │   │   │   ├── OverpassQuery.tsx
│   │   │   │   │   ├── fetchOSMCountryBoundary.ts
│   │   │   │   │   ├── getOSMData.ts
│   │   │   │   │   ├── osmToGeoJSON.ts
│   │   │   │   │   └── osmTypes.ts
│   │   │   │   ├── W_Map.tsx
│   │   │   │   ├── W_MapMenu.tsx
│   │   │   │   ├── controls/
│   │   │   │   │   ├── MapBasemapOptions.tsx
│   │   │   │   │   ├── MapInfoSection.tsx
│   │   │   │   │   ├── MapOSMQuery.tsx
│   │   │   │   │   └── MapOpacityMenu.tsx
│   │   │   │   ├── fetchData/
│   │   │   │   │   ├── fetchMapLayerData.ts
│   │   │   │   │   ├── getMapData.ts
│   │   │   │   │   ├── getMapDataExtent.ts
│   │   │   │   │   └── getMapLayerQueries.ts
│   │   │   │   ├── getMapFeatureStyle.ts
│   │   │   │   └── onMapHover.ts
│   │   │   ├── W_Method/
│   │   │   │   ├── FunctionLabel.tsx
│   │   │   │   ├── NewMethod.tsx
│   │   │   │   ├── PublishedMethods.tsx
│   │   │   │   ├── W_Method.tsx
│   │   │   │   ├── W_MethodControls.tsx
│   │   │   │   └── W_MethodMenu.tsx
│   │   │   ├── W_QuickMenu.tsx
│   │   │   ├── W_SQL/
│   │   │   │   ├── CSVRender.tsx
│   │   │   │   ├── CopyResultBtn.tsx
│   │   │   │   ├── MonacoLanguageRegister.ts
│   │   │   │   ├── SQLHotkeys.tsx
│   │   │   │   ├── TestSQL.ts
│   │   │   │   ├── W_SQL.tsx
│   │   │   │   ├── W_SQLBottomBar/
│   │   │   │   │   ├── W_SQLBottomBar.tsx
│   │   │   │   │   └── W_SQLBottomBarProcStats.tsx
│   │   │   │   ├── W_SQLMenu.tsx
│   │   │   │   ├── W_SQLResults.tsx
│   │   │   │   ├── customRenderers.tsx
│   │   │   │   ├── demoScripts/
│   │   │   │   │   ├── createTables.ts
│   │   │   │   │   ├── mainTestScripts.ts
│   │   │   │   │   ├── testBugs.ts
│   │   │   │   │   ├── testMiscAndBugs.ts
│   │   │   │   │   └── testSqlCharts.ts
│   │   │   │   ├── getChartableSQL.ts
│   │   │   │   ├── getDemoUtils.ts
│   │   │   │   ├── getSQLResultTableColumns.ts
│   │   │   │   ├── monacoEditorTypes.ts
│   │   │   │   ├── parseExplainResult.ts
│   │   │   │   ├── parseSQLError.ts
│   │   │   │   ├── parseSqlResultCols.ts
│   │   │   │   ├── runSQL/
│   │   │   │   │   ├── getQueryTotalRowCount.ts
│   │   │   │   │   └── runSQL.ts
│   │   │   │   └── runSQLErrorHints.ts
│   │   │   ├── W_Table/
│   │   │   │   ├── CardView/
│   │   │   │   │   ├── CardView.tsx
│   │   │   │   │   ├── CardViewColumn.tsx
│   │   │   │   │   ├── CardViewKanban.tsx
│   │   │   │   │   ├── CardViewRow.tsx
│   │   │   │   │   ├── DragHeader.tsx
│   │   │   │   │   ├── useCardViewState.ts
│   │   │   │   │   └── useDragHeader.ts
│   │   │   │   ├── ColumnMenu/
│   │   │   │   │   ├── AddColumnMenu.tsx
│   │   │   │   │   ├── AddComputedColumn/
│   │   │   │   │   │   ├── AddComputedColMenu.tsx
│   │   │   │   │   │   ├── FunctionColumnList.tsx
│   │   │   │   │   │   ├── QuickAddComputedColumn.tsx
│   │   │   │   │   │   └── useAddComputedColumn.ts
│   │   │   │   │   ├── AlterColumn/
│   │   │   │   │   │   ├── AlterColumn.tsx
│   │   │   │   │   │   ├── AlterColumnFileOptions.tsx
│   │   │   │   │   │   ├── ColumnEditor.tsx
│   │   │   │   │   │   ├── CreateColumn.tsx
│   │   │   │   │   │   ├── ReferenceEditor.tsx
│   │   │   │   │   │   └── alterColumnUtilts.ts
│   │   │   │   │   ├── ColorPicker.tsx
│   │   │   │   │   ├── ColumnDisplayFormat/
│   │   │   │   │   │   ├── ChipStylePalette.tsx
│   │   │   │   │   │   ├── ColumnDisplayFormat.tsx
│   │   │   │   │   │   ├── ConditionalCellIconStyleControls.tsx
│   │   │   │   │   │   ├── ConditionalCellStyleControls.tsx
│   │   │   │   │   │   ├── NestedColumnRender.tsx
│   │   │   │   │   │   └── columnFormatUtils.tsx
│   │   │   │   │   ├── ColumnList.tsx
│   │   │   │   │   ├── ColumnMenu.tsx
│   │   │   │   │   ├── ColumnQuickStats/
│   │   │   │   │   │   ├── ColumnQuickStats.tsx
│   │   │   │   │   │   └── useColumnQuickStats.ts
│   │   │   │   │   ├── ColumnSelect/
│   │   │   │   │   │   ├── ColumnSelect.tsx
│   │   │   │   │   │   └── getColumnListItem.tsx
│   │   │   │   │   ├── ColumnSortMenu.tsx
│   │   │   │   │   ├── ColumnStyleControls/
│   │   │   │   │   │   ├── ColumnStyleControls.tsx
│   │   │   │   │   │   └── getValueColors.ts
│   │   │   │   │   ├── ColumnsMenu.tsx
│   │   │   │   │   ├── FunctionSelector/
│   │   │   │   │   │   ├── FunctionExtraArguments.tsx
│   │   │   │   │   │   ├── FunctionSelector.tsx
│   │   │   │   │   │   └── functions.ts
│   │   │   │   │   ├── JoinPathSelectorV2.tsx
│   │   │   │   │   ├── LinkedColumn/
│   │   │   │   │   │   ├── LinkedColumn.tsx
│   │   │   │   │   │   ├── LinkedColumnFooter.tsx
│   │   │   │   │   │   └── LinkedColumnSelect.tsx
│   │   │   │   │   ├── NestedTimechartControls.tsx
│   │   │   │   │   ├── SummariseColumns.tsx
│   │   │   │   │   ├── getNestedColumnTable.ts
│   │   │   │   │   └── rgba2hex.ts
│   │   │   │   ├── JoinPathSelector/
│   │   │   │   │   ├── JoinPathItem.tsx
│   │   │   │   │   ├── JoinPathSelector.tsx
│   │   │   │   │   └── getJoinTree.ts
│   │   │   │   ├── NodeCountChecker.tsx
│   │   │   │   ├── ProstglesTable.css
│   │   │   │   ├── QuickFilterGroupsControl.tsx
│   │   │   │   ├── RowCard.tsx
│   │   │   │   ├── TableMenu/
│   │   │   │   │   ├── AddChartMenu.tsx
│   │   │   │   │   ├── AutoRefreshMenu.tsx
│   │   │   │   │   ├── W_TableMenu.tsx
│   │   │   │   │   ├── W_TableMenu_AccessRules.tsx
│   │   │   │   │   ├── W_TableMenu_Constraints.tsx
│   │   │   │   │   ├── W_TableMenu_CurrentQuery.tsx
│   │   │   │   │   ├── W_TableMenu_DisplayOptions.tsx
│   │   │   │   │   ├── W_TableMenu_Indexes.tsx
│   │   │   │   │   ├── W_TableMenu_Policies.tsx
│   │   │   │   │   ├── W_TableMenu_TableInfo.tsx
│   │   │   │   │   ├── W_TableMenu_Triggers.tsx
│   │   │   │   │   ├── getAndFixWColumnsConfig.tsx
│   │   │   │   │   ├── getChartCols.ts
│   │   │   │   │   └── getTableMeta.ts
│   │   │   │   ├── TooManyColumnsWarning.tsx
│   │   │   │   ├── W_Table.tsx
│   │   │   │   ├── W_Table_Content.tsx
│   │   │   │   ├── colorBlend.ts
│   │   │   │   ├── getTableData/
│   │   │   │   │   ├── getTableData.ts
│   │   │   │   │   └── getTableFilter.ts
│   │   │   │   └── tableUtils/
│   │   │   │       ├── StyledTableColumn.tsx
│   │   │   │       ├── getColWInfo.ts
│   │   │   │       ├── getColWidth.ts
│   │   │   │       ├── getEditColumn.tsx
│   │   │   │       ├── getFullColumnConfig.ts
│   │   │   │       ├── getJoinPaths.ts
│   │   │   │       ├── getRowFilter.ts
│   │   │   │       ├── getTableCols.tsx
│   │   │   │       ├── getTableSelect.ts
│   │   │   │       ├── onRenderColumn.tsx
│   │   │   │       ├── prepareColsForRender.ts
│   │   │   │       └── tableUtils.ts
│   │   │   ├── W_TimeChart/
│   │   │   │   ├── AddTimeChartFilter.tsx
│   │   │   │   ├── W_TimeChart.tsx
│   │   │   │   ├── W_TimeChartHeaderControls.tsx
│   │   │   │   ├── W_TimeChartLayerLegend.tsx
│   │   │   │   ├── W_TimeChartMenu.tsx
│   │   │   │   └── fetchData/
│   │   │   │       ├── constants.ts
│   │   │   │       ├── fetchAndSetTimechartLayerData.ts
│   │   │   │       ├── fetchTimechartLayer.ts
│   │   │   │       ├── getTimeChartData.ts
│   │   │   │       ├── getTimeChartLayers.ts
│   │   │   │       ├── getTimeChartLayersWithBins.ts
│   │   │   │       ├── getTimeChartSelectParams.ts
│   │   │   │       ├── getTimeLayerDataSignature.ts
│   │   │   │       └── getTimechartExtentFilter.ts
│   │   │   ├── Window.tsx
│   │   │   ├── WindowControls/
│   │   │   │   ├── AddChartLayer.tsx
│   │   │   │   ├── ColorByLegend/
│   │   │   │   │   ├── ColorByLegend.tsx
│   │   │   │   │   └── getGroupByValueColor.ts
│   │   │   │   ├── DataLayerManager/
│   │   │   │   │   ├── DataLayer.tsx
│   │   │   │   │   ├── DataLayerManager.tsx
│   │   │   │   │   └── useSortedLayerQueries.ts
│   │   │   │   ├── LayerColorPicker.tsx
│   │   │   │   ├── MapLayerStyling.tsx
│   │   │   │   ├── OSMLayerOptions.tsx
│   │   │   │   ├── SQLChartLayerEditor.tsx
│   │   │   │   └── TimeChartLayerOptions.tsx
│   │   │   ├── WorkspaceMenu/
│   │   │   │   ├── WorkspaceAddBtn.tsx
│   │   │   │   ├── WorkspaceDeleteBtn.tsx
│   │   │   │   ├── WorkspaceMenu.css
│   │   │   │   ├── WorkspaceMenu.tsx
│   │   │   │   ├── WorkspaceMenuDropDown.tsx
│   │   │   │   ├── WorkspaceSettings.tsx
│   │   │   │   └── useWorkspaces.ts
│   │   │   ├── joinUtils.ts
│   │   │   ├── localSettings.ts
│   │   │   ├── setPan.ts
│   │   │   └── shortestPath.ts
│   │   ├── demo/
│   │   │   ├── AppVideoDemo.tsx
│   │   │   ├── MousePointer.tsx
│   │   │   ├── demoUtils.ts
│   │   │   ├── recordDemoUtils.ts
│   │   │   └── scripts/
│   │   │       ├── AIAssistantDemo.ts
│   │   │       ├── accessControlDemo.ts
│   │   │       ├── backupDemo.ts
│   │   │       ├── dashboardDemo.ts
│   │   │       ├── fileDemo.ts
│   │   │       ├── schemaDiagramDemo.ts
│   │   │       ├── sqlVideoDemo.ts
│   │   │       └── videoDemoAccessControlScripts.ts
│   │   ├── exports.ts
│   │   ├── hooks/
│   │   │   ├── useDebouncedCallback.ts
│   │   │   ├── useThrottledCallback.ts
│   │   │   └── useTypedSearchParams.ts
│   │   ├── i18n/
│   │   │   ├── LanguageSelector.tsx
│   │   │   ├── i18nUtils.ts
│   │   │   └── translations/
│   │   │       ├── de.json
│   │   │       ├── es.json
│   │   │       ├── fr.json
│   │   │       ├── hi.json
│   │   │       ├── ru.json
│   │   │       ├── translations.ts
│   │   │       └── zh.json
│   │   ├── index.css
│   │   ├── index.html.ejs
│   │   ├── index.tsx
│   │   ├── pages/
│   │   │   ├── Account/
│   │   │   │   ├── Account.tsx
│   │   │   │   ├── ChangePassword.tsx
│   │   │   │   ├── Sessions.tsx
│   │   │   │   └── Setup2FA.tsx
│   │   │   ├── AccountMenu.tsx
│   │   │   ├── Alerts.tsx
│   │   │   ├── ComponentList.tsx
│   │   │   ├── Connections/
│   │   │   │   ├── Connection.tsx
│   │   │   │   ├── ConnectionActionBar.tsx
│   │   │   │   ├── Connections.tsx
│   │   │   │   ├── ConnectionsOptions.tsx
│   │   │   │   ├── CreateConnection/
│   │   │   │   │   ├── CreateConnection.tsx
│   │   │   │   │   └── useCreateConnection.ts
│   │   │   │   ├── CreatePostgresUser.tsx
│   │   │   │   ├── useConnectionServersList.ts
│   │   │   │   └── useConnections.ts
│   │   │   ├── ElectronSetup/
│   │   │   │   ├── ElectronSetup.tsx
│   │   │   │   ├── ElectronSetupStateDB.tsx
│   │   │   │   └── useElectronSetup.ts
│   │   │   ├── Login/
│   │   │   │   ├── AuthNotifPopup.tsx
│   │   │   │   ├── Login.tsx
│   │   │   │   ├── LoginTotpForm.tsx
│   │   │   │   ├── LoginWithProviders.tsx
│   │   │   │   ├── SocialIcons.css
│   │   │   │   ├── SocialIcons.tsx
│   │   │   │   └── useLoginState.ts
│   │   │   ├── NewConnection/
│   │   │   │   ├── NewConnectionFormFields.tsx
│   │   │   │   ├── NewConnnectionForm.tsx
│   │   │   │   ├── SchemaFilter.tsx
│   │   │   │   └── newConnectionUtils.ts
│   │   │   ├── NonHTTPSWarning.tsx
│   │   │   ├── NotFound.tsx
│   │   │   ├── ProjectConnection/
│   │   │   │   ├── PrglContextProvider.tsx
│   │   │   │   ├── ProjectConnection.tsx
│   │   │   │   ├── ProjectConnectionError.tsx
│   │   │   │   └── useProjectDb.ts
│   │   │   ├── ProjectLogs.tsx
│   │   │   ├── ServerSettings/
│   │   │   │   ├── AuthProvidersSetup.tsx
│   │   │   │   ├── EmailAuthSetup.tsx
│   │   │   │   ├── EmailAuthSetupIngredients/
│   │   │   │   │   ├── EmailSMTPAndTemplateSetup.tsx
│   │   │   │   │   ├── EmailSMTPSetup.tsx
│   │   │   │   │   └── EmailTemplateSetup.tsx
│   │   │   │   ├── MCPServers/
│   │   │   │   │   ├── MCPServerConfig/
│   │   │   │   │   │   ├── MCPServerConfig.tsx
│   │   │   │   │   │   ├── MCPServerConfigButton.tsx
│   │   │   │   │   │   ├── useMCPServerConfigState.tsx
│   │   │   │   │   │   └── useMCPServerEnable.ts
│   │   │   │   │   ├── MCPServerFooterActions/
│   │   │   │   │   │   ├── MCPServerFooterActions.tsx
│   │   │   │   │   │   └── MCPServersInstall.tsx
│   │   │   │   │   ├── MCPServerHeaderCheckbox.tsx
│   │   │   │   │   ├── MCPServerTools/
│   │   │   │   │   │   ├── MCPServerTools.tsx
│   │   │   │   │   │   └── MCPServerToolsGroupToggle.tsx
│   │   │   │   │   ├── MCPServers.tsx
│   │   │   │   │   ├── MCPServersHeader.tsx
│   │   │   │   │   ├── MCPServersToolbar/
│   │   │   │   │   │   ├── AddMCPServer.tsx
│   │   │   │   │   │   ├── MCPServersToolbar.tsx
│   │   │   │   │   │   └── useAddMCPServer.ts
│   │   │   │   │   ├── useMCPChatAllowedTools.ts
│   │   │   │   │   └── useMCPServersListProps.tsx
│   │   │   │   ├── OAuthProviderSetup.tsx
│   │   │   │   ├── ServerSettings.tsx
│   │   │   │   ├── Services.tsx
│   │   │   │   └── useEditableData.ts
│   │   │   ├── TopControls.tsx
│   │   │   └── projectUtils.ts
│   │   ├── theme/
│   │   │   ├── ThemeSelector.tsx
│   │   │   ├── useAppTheme.ts
│   │   │   └── useSystemTheme.ts
│   │   ├── useAppState/
│   │   │   ├── dbsConnectionOptions.ts
│   │   │   ├── useAppState.ts
│   │   │   ├── useDBSClient.ts
│   │   │   └── useServerState.ts
│   │   └── utils/
│   │       ├── colorUtils.ts
│   │       ├── hashCode.ts
│   │       └── utils.ts
│   ├── static/
│   │   └── util.css
│   ├── tsconfig.eslint.json
│   ├── tsconfig.json
│   ├── tsconfig_lib.json
│   ├── tsconfig_rollup.json
│   └── tslint.json
├── common/
│   ├── DBGeneratedSchema.d.ts
│   ├── DashboardTypes.d.ts
│   ├── DashboardTypes.js
│   ├── DashboardTypes.ts
│   ├── OAuthUtils.d.ts
│   ├── OAuthUtils.js
│   ├── OAuthUtils.ts
│   ├── dashboardTypesContent.d.ts
│   ├── dashboardTypesContent.js
│   ├── dashboardTypesContent.ts
│   ├── electronInitTypes.d.ts
│   ├── electronInitTypes.js
│   ├── electronInitTypes.ts
│   ├── filterUtils.d.ts
│   ├── filterUtils.js
│   ├── filterUtils.ts
│   ├── llmUtils.d.ts
│   ├── llmUtils.js
│   ├── llmUtils.ts
│   ├── mcp.d.ts
│   ├── mcp.js
│   ├── mcp.ts
│   ├── prostglesMcp.d.ts
│   ├── prostglesMcp.js
│   ├── prostglesMcp.ts
│   ├── psql_queries.json
│   ├── publishUtils.d.ts
│   ├── publishUtils.js
│   ├── publishUtils.ts
│   ├── tsconfig.json
│   ├── utils.d.ts
│   ├── utils.js
│   └── utils.ts
├── docker-compose.yml
├── docs/
│   ├── 01_Overview.md
│   ├── 02_Installation.md
│   ├── 03_Installation_(Desktop_Version).md
│   ├── 04_Navigation_bar.md
│   ├── 05_Connections.md
│   ├── 06_Connection_dashboard.md
│   ├── 07_Import_file.md
│   ├── 08_Schema_diagram.md
│   ├── 09_SQL_editor.md
│   ├── 10_Table_view.md
│   ├── 11_Map_view.md
│   ├── 12_Timechart_view.md
│   ├── 13_AI_Assistant.md
│   ├── 14_Connection_configuration.md
│   ├── 15_Access_control.md
│   ├── 16_File_storage.md
│   ├── 17_Backup_and_Restore.md
│   ├── 18_API.md
│   ├── 19_Server_Settings.md
│   ├── 20_Account.md
│   └── 21_Command_Palette.md
├── e2e/
│   ├── .gitignore
│   ├── package.json
│   ├── playwright.config.js
│   ├── playwright.config.ts
│   ├── test-local.sh
│   ├── tests/
│   │   ├── Testing.ts
│   │   ├── command_palette.spec.ts
│   │   ├── createReceipt.ts
│   │   ├── create_docs.spec.ts
│   │   ├── create_load_test_users.spec.ts
│   │   ├── demo_video.spec.ts
│   │   ├── demo_video_setup.spec.ts
│   │   ├── load_test.spec.ts
│   │   ├── main.spec.ts
│   │   ├── mockSMTPServer.ts
│   │   ├── sampleToolUseData.ts
│   │   ├── speechToTextTest.ts
│   │   ├── svgScreenshots/
│   │   │   ├── SVG_SCREENSHOT_DETAILS.ts
│   │   │   ├── account.svgif.ts
│   │   │   ├── aiAssistant.svgif.ts
│   │   │   ├── backupAndRestore.svgif.ts
│   │   │   ├── commandPalette.svgif.ts
│   │   │   ├── dashboard.svgif.ts
│   │   │   ├── electronSetup.svgif.ts
│   │   │   ├── fileImporter.svgif.ts
│   │   │   ├── getOverviewSvgifSpecs.svgif.ts
│   │   │   ├── map.svgif.ts
│   │   │   ├── navbar.svgif.ts
│   │   │   ├── newConnection.svgif.ts
│   │   │   ├── schemaDiagram.svgif.ts
│   │   │   ├── smartForm.svgif.ts
│   │   │   ├── sqlEditor.svgif.ts
│   │   │   ├── table.svgif.ts
│   │   │   ├── timechart.svgif.ts
│   │   │   └── utils/
│   │   │       ├── constants.ts
│   │   │       ├── getFilesFromDir.ts
│   │   │       ├── getSceneUtils.ts
│   │   │       ├── saveSVGScreenshot.ts
│   │   │       ├── saveSVGifs.ts
│   │   │       ├── saveSVGs.ts
│   │   │       ├── svgScreenshotsCompleteReferenced.ts
│   │   │       └── typeSendAddScenes.ts
│   │   ├── testAskLLM.ts
│   │   ├── tsconfig.json
│   │   └── utils/
│   │       ├── constants.ts
│   │       ├── goTo.ts
│   │       ├── isPortFree.ts
│   │       └── utils.ts
│   └── tsconfig.json
├── electron/
│   ├── .gitignore
│   ├── README.md
│   ├── build.sh
│   ├── e2e-electron/
│   │   ├── electron.spec.tsx
│   │   └── tsconfig.json
│   ├── forge.config.js
│   ├── getProtocolHandler.ts
│   ├── images/
│   │   ├── generate_from_svg.sh
│   │   └── loading-effect.css
│   ├── loadingHTML.ts
│   ├── main.ts
│   ├── mainWindow.ts
│   ├── package.json
│   ├── playwright.config.ts
│   ├── screenCapture.bat
│   ├── setContextMenu.ts
│   ├── start.sh
│   ├── test-linux-macos.sh
│   ├── test-linux.sh
│   ├── test-setup.js
│   ├── test-w-debug.sh
│   ├── test.sh
│   ├── tsconfig.json
│   ├── win-inno-setup.ts
│   └── win.js
├── package.json
├── releases/
│   ├── v1.0.0.md
│   ├── v2.0.0.md
│   ├── v2.2.2.md
│   ├── v2.2.3.md
│   └── v2.2.4.md
├── scripts/
│   ├── demo/
│   │   ├── SCREEN RECORD.txt
│   │   ├── record-local.sh
│   │   └── split-video.sh
│   ├── get_version.sh
│   ├── release.sh
│   ├── start-dev-electron.sh
│   ├── start-dev.sh
│   ├── start-prod.sh
│   └── test.sh
└── server/
    ├── .gitignore
    ├── .vscode/
    │   └── settings.json
    ├── eslint.config.mjs
    ├── licenses.json
    ├── package.json
    ├── proj-prgl.js
    ├── sample_schemas/
    │   ├── _crypto.sql
    │   ├── cleaning.sql
    │   ├── cloud_computing.sql
    │   ├── countries.sql
    │   ├── crypto/
    │   │   ├── onMount.ts
    │   │   ├── tableConfig.ts
    │   │   └── workspaceConfig.ts
    │   ├── financial.sql
    │   ├── food_delivery/
    │   │   ├── connection.ts
    │   │   ├── databaseConfig.ts
    │   │   ├── onInit.sql
    │   │   ├── onMount.ts
    │   │   └── workspaceConfig.ts
    │   ├── lodging.sql
    │   ├── maps.sql
    │   ├── property_management/
    │   │   ├── onMount.ts
    │   │   └── workspaceConfig.ts
    │   ├── sales.sql
    │   ├── sample.sql
    │   ├── testschema.ts
    │   └── weather/
    │       └── onMount.ts
    ├── src/
    │   ├── BackupManager/
    │   │   ├── BackupManager.ts
    │   │   ├── checkAutomaticBackup.ts
    │   │   ├── getInstalledPrograms.ts
    │   │   ├── pgDump.ts
    │   │   ├── pgRestore.ts
    │   │   ├── pipeFromCommand.ts
    │   │   ├── pipeToCommand.ts
    │   │   └── utils.ts
    │   ├── ConnectionManager/
    │   │   ├── ConnectionManager.ts
    │   │   ├── ForkedPrglProcRunner/
    │   │   │   ├── ForkedPrglProcRunner.ts
    │   │   │   ├── createProc.ts
    │   │   │   └── forkedProcess.ts
    │   │   ├── connectionManagerUtils.ts
    │   │   ├── getConnectionPublish.ts
    │   │   ├── getConnectionPublishMethods.ts
    │   │   ├── getInitiatedPostgresqlPIDs.ts
    │   │   ├── initConnectionManager.ts
    │   │   ├── saveCertificates.ts
    │   │   └── startConnection.ts
    │   ├── Logger.ts
    │   ├── McpHub/
    │   │   ├── AnthropicMcpHub/
    │   │   │   ├── McpHub.ts
    │   │   │   ├── McpTypes.ts
    │   │   │   ├── connectToMCPServer.ts
    │   │   │   ├── fetchMCPResourceTemplatesList.ts
    │   │   │   ├── fetchMCPResourcesList.ts
    │   │   │   ├── fetchMCPToolsList.ts
    │   │   │   ├── installMCPServer.ts
    │   │   │   ├── runShellCommand.ts
    │   │   │   └── startMcpHub.ts
    │   │   ├── DefaultMCPServers/
    │   │   │   ├── DefaultMCPServers.ts
    │   │   │   └── mcpGithub.ts
    │   │   ├── ProstglesMcpHub/
    │   │   │   ├── ProstglesMCPServerTypes.ts
    │   │   │   ├── ProstglesMCPServers/
    │   │   │   │   ├── DockerSandbox/
    │   │   │   │   │   ├── createContainer.spec.ts
    │   │   │   │   │   ├── createContainer.ts
    │   │   │   │   │   ├── dockerMCPServerProxy/
    │   │   │   │   │   │   ├── dockerContainerAuthRegistry.ts
    │   │   │   │   │   │   ├── dockerMCPServerProxy.ts
    │   │   │   │   │   │   └── isPortFree.ts
    │   │   │   │   │   ├── executeDockerCommand.ts
    │   │   │   │   │   ├── fetchTools.ts
    │   │   │   │   │   ├── getContainerLogs.ts
    │   │   │   │   │   ├── getDockerGatewayIP.ts
    │   │   │   │   │   └── getDockerRunArgs.ts
    │   │   │   │   ├── DockerSandbox.mcp.ts
    │   │   │   │   └── WebSearch.mcp.ts
    │   │   │   ├── ProstglesMCPServers.ts
    │   │   │   └── ProstglesMcpHub.ts
    │   │   ├── callMCPServerTool.ts
    │   │   ├── fetchMCPServerConfigs.ts
    │   │   ├── insertServerList.ts
    │   │   ├── reloadMcpServerTools.ts
    │   │   └── testMCPServerConfig.ts
    │   ├── SecurityManager/
    │   │   └── initUsers.ts
    │   ├── ServiceManager/
    │   │   ├── ServiceManager.spec.ts
    │   │   ├── ServiceManager.ts
    │   │   ├── ServiceManagerTypes.ts
    │   │   ├── buildService.ts
    │   │   ├── dockerInspect.ts
    │   │   ├── enableService.ts
    │   │   ├── getDockerBuildHash.ts
    │   │   ├── getSelectedConfigEnvs.ts
    │   │   ├── getServiceEndoints.ts
    │   │   ├── initialiseServices.ts
    │   │   ├── services/
    │   │   │   ├── speechToText/
    │   │   │   │   ├── speechToText.service.ts
    │   │   │   │   └── src/
    │   │   │   │       ├── Dockerfile
    │   │   │   │       ├── app.py
    │   │   │   │       └── requirements.txt
    │   │   │   └── webSearchSearxng/
    │   │   │       ├── src/
    │   │   │       │   ├── Dockerfile
    │   │   │       │   ├── limiter.toml
    │   │   │       │   └── settings.yml
    │   │   │       └── webSearchSearxng.service.ts
    │   │   ├── startService.ts
    │   │   └── stopService.ts
    │   ├── authConfig/
    │   │   ├── OAuthProviders/
    │   │   │   ├── getOAuthLoginProviders.ts
    │   │   │   └── loginWithProvider.ts
    │   │   ├── authUtils.ts
    │   │   ├── createPasswordlessAdminSessionIfNeeded.ts
    │   │   ├── createPublicUserSessionIfAllowed.ts
    │   │   ├── emailProvider/
    │   │   │   ├── getEmailAuthProvider.ts
    │   │   │   ├── getEmailSenderWithMockTest.ts
    │   │   │   └── onEmailRegistration.ts
    │   │   ├── getActiveSession.ts
    │   │   ├── getAuth.ts
    │   │   ├── getLogin.ts
    │   │   ├── getUser.ts
    │   │   ├── onMagicLinkOrOTP.ts
    │   │   ├── onUseOrSocketConnected.ts
    │   │   ├── sessionUtils.ts
    │   │   ├── startRateLimitedLoginAttempt.ts
    │   │   ├── subscribeToAuthSetupChanges.ts
    │   │   └── upsertSession.ts
    │   ├── cloudClients/
    │   │   └── cloudClients.ts
    │   ├── connectionUtils/
    │   │   ├── getConnectionDetails.ts
    │   │   ├── testDBConnection.ts
    │   │   └── validateConnection.ts
    │   ├── electronConfig.ts
    │   ├── envVars.ts
    │   ├── getPSQLQueries.ts
    │   ├── index.ts
    │   ├── init/
    │   │   ├── cleanupTestDatabases.ts
    │   │   ├── initExpressAndIOServers.ts
    │   │   ├── insertStateDatabase.ts
    │   │   ├── isRetryableError.ts
    │   │   ├── logOutgoingHttpRequests.ts
    │   │   ├── onProstglesReady.ts
    │   │   ├── setDBSRoutesForElectron.ts
    │   │   ├── startDevHotReloadNotifier.ts
    │   │   ├── startProstgles.ts
    │   │   ├── testDashboardTypesContent.ts
    │   │   └── tryStartProstgles.ts
    │   ├── init.sql
    │   ├── methods/
    │   │   ├── getPidStats.ts
    │   │   ├── getPidStatsFromProc.ts
    │   │   └── statusMonitorUtils.ts
    │   ├── publish/
    │   │   ├── getPublishLLM.ts
    │   │   └── publish.ts
    │   ├── publishMethods/
    │   │   ├── applySampleSchema.ts
    │   │   ├── askLLM/
    │   │   │   ├── LLMResponseTypes.ts
    │   │   │   ├── askLLM.ts
    │   │   │   ├── checkLLMLimit.ts
    │   │   │   ├── checkMaxCostLimitForChat.ts
    │   │   │   ├── fetchLLMResponse.ts
    │   │   │   ├── getFullPrompt.ts
    │   │   │   ├── getLLMRequestBody.ts
    │   │   │   ├── getLLMToolsAllowedInThisChat.ts
    │   │   │   ├── getLLMUsageCost.ts
    │   │   │   ├── getUserMessageCost.ts
    │   │   │   ├── parseLLMResponseObject.ts
    │   │   │   ├── prostglesLLMTools/
    │   │   │   │   ├── getMCPServerTools.ts
    │   │   │   │   ├── getProstglesDBTools.ts
    │   │   │   │   ├── getProstglesLLMTools.ts
    │   │   │   │   ├── getPublishedMethodsTools.ts
    │   │   │   │   ├── prostglesMcpTools.ts
    │   │   │   │   └── runProstglesDBTool.ts
    │   │   │   ├── readFetchStream.ts
    │   │   │   ├── refreshModels.ts
    │   │   │   ├── runApprovedTools/
    │   │   │   │   ├── runApprovedTools.ts
    │   │   │   │   └── validateLastMessageToolUseRequests.ts
    │   │   │   └── setupLLM.ts
    │   │   ├── deleteConnection.ts
    │   │   ├── getConnectionAndDatabaseConfig.ts
    │   │   ├── getNodeTypes.ts
    │   │   ├── prostglesSignup.ts
    │   │   ├── publishMethods.ts
    │   │   └── setFileStorage.ts
    │   ├── tableConfig/
    │   │   ├── tableConfig.ts
    │   │   ├── tableConfigAccessControl.ts
    │   │   ├── tableConfigBackups.ts
    │   │   ├── tableConfigConnections.ts
    │   │   ├── tableConfigGlobalSettings.ts
    │   │   ├── tableConfigLinks.ts
    │   │   ├── tableConfigLlm/
    │   │   │   ├── tableConfigLlm.ts
    │   │   │   ├── tableConfigLlmChats.ts
    │   │   │   └── tableConfigLlmExtraRequestData.ts
    │   │   ├── tableConfigMCPServers.ts
    │   │   ├── tableConfigMigrations.ts
    │   │   ├── tableConfigPublishedMethods.ts
    │   │   ├── tableConfigUsers.ts
    │   │   ├── tableConfigWindows.ts
    │   │   └── tableConfigWorkspaces.ts
    │   ├── testElectron.ts
    │   └── upsertConnection.ts
    ├── tsconfig.json
    └── tslint.json
Download .txt
SYMBOL INDEX (2152 symbols across 688 files)

FILE: client/setup-icons.js
  class SaveMdiIcons (line 45) | class SaveMdiIcons {
    method apply (line 46) | apply(compiler) {

FILE: client/src/App.tsx
  type ClientUser (line 45) | type ClientUser = {
  type ClientAuth (line 52) | type ClientAuth = {
  type Theme (line 55) | type Theme = "dark" | "light";
  type PrglReadyState (line 56) | type PrglReadyState = {
  type ExtraProps (line 69) | type ExtraProps = PrglReadyState & {
  type PrglStateCore (line 76) | type PrglStateCore = Pick<
  type PrglState (line 80) | type PrglState = ExtraProps;
  type PrglCore (line 82) | type PrglCore = {
  type PrglProject (line 87) | type PrglProject = PrglCore & {
  type Prgl (line 94) | type Prgl = PrglState & PrglProject;
  type AppState (line 96) | type AppState = {

FILE: client/src/Testing.ts
  constant COMMANDS (line 1) | const COMMANDS = {
  type Command (line 534) | type Command = keyof typeof COMMANDS;
  type TestSelectors (line 536) | type TestSelectors = {
  constant COMMAND_SEARCH_ATTRIBUTE_NAME (line 555) | const COMMAND_SEARCH_ATTRIBUTE_NAME = "data-command-search-ended";
  constant MOCK_ELECTRON_WINDOW_ATTR (line 557) | const MOCK_ELECTRON_WINDOW_ATTR = "MOCK_ELECTRON_WINDOW_ATTR" as const;
  type HTMLAttributes (line 560) | interface HTMLAttributes<T> {
  type CursorAnimation (line 566) | type CursorAnimation =
  type Animation (line 587) | type Animation =
  type Scene (line 620) | type Scene = {

FILE: client/src/app/CommandPalette/CommandPalette.tsx
  type CommandSearchHighlight (line 144) | type CommandSearchHighlight = {

FILE: client/src/app/CommandPalette/Documentation.tsx
  type P (line 13) | type P = {

FILE: client/src/app/CommandPalette/getDocumentation.ts
  type SeparatePage (line 6) | type SeparatePage = { doc: UIDoc; parentDocs: UIDoc[]; depth: number };
  type DocumentationFile (line 116) | type DocumentationFile = {

FILE: client/src/app/CommandPalette/useGoToUI.tsx
  type DocItemHighlightItemPosition (line 24) | type DocItemHighlightItemPosition = "mid" | "last";

FILE: client/src/app/CommandPalette/utils.ts
  constant PATH_JOIN_CHARS (line 49) | const PATH_JOIN_CHARS = ["/", "#", "?"] as const;

FILE: client/src/app/UIDocs.ts
  type UIDocCommon (line 32) | type UIDocCommon = {
  type UIDocBase (line 78) | type UIDocBase<T> = (
  type Route (line 94) | type Route = (typeof ROUTES)[keyof typeof ROUTES];
  type UIDocInputElement (line 96) | type UIDocInputElement = UIDocBase<{
  type UIDocElement (line 101) | type UIDocElement =
  type UIDocPage (line 164) | type UIDocPage = UIDocCommon & {
  type UIDocContainers (line 175) | type UIDocContainers =
  type UIDocNavbar (line 183) | type UIDocNavbar = UIDocBase<{
  type UIDoc (line 193) | type UIDoc = UIDocContainers | UIDocElement | UIDocNavbar;
  type UIDocNonInfo (line 251) | type UIDocNonInfo = Exclude<UIDoc, { type: "info" }>;
  type UIDocFlat (line 252) | type UIDocFlat = UIDocNonInfo & {

FILE: client/src/app/XRealIpSpoofableAlert.tsx
  type P (line 11) | type P = Pick<ReturnType<typeof useAppState>, "serverState" | "user">;

FILE: client/src/app/domToSVG/SVGif/getSVGifAnimations.ts
  type SceneNodeAnimation (line 251) | type SceneNodeAnimation = {

FILE: client/src/app/domToSVG/SVGif/getSVGifParsedScenes.ts
  type SVGifParsedScene (line 35) | type SVGifParsedScene = ReturnType<typeof parseSVGWithViewBox> &

FILE: client/src/app/domToSVG/containers/bgAndBorderToSVG.ts
  function hasBorder (line 5) | function hasBorder(style: CSSStyleDeclaration) {
  function getBackgroundColor (line 110) | function getBackgroundColor(style: CSSStyleDeclaration) {

FILE: client/src/app/domToSVG/containers/elementToSVG.ts
  type SVGContext (line 16) | type SVGContext = {
  type SVGNodeLayout (line 27) | type SVGNodeLayout = {

FILE: client/src/app/domToSVG/containers/rectangleToSVG.ts
  constant BORDER_ELEMENT_TYPES (line 8) | const BORDER_ELEMENT_TYPES = ["rect", "path", "line"] as const;

FILE: client/src/app/domToSVG/domToSVG.ts
  constant SVG_NAMESPACE (line 8) | const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
  type Element (line 207) | interface Element {

FILE: client/src/app/domToSVG/domToThemeAwareSVG.ts
  type CSSProperty (line 28) | type CSSProperty = "color" | "shadow" | "opacity" | "fontFamily" | "href";
  type SVGGElement (line 310) | interface SVGGElement {
  type SVGScreenshotNodeType (line 322) | type SVGScreenshotNodeType = (

FILE: client/src/app/domToSVG/graphics/fontIconToSVG.ts
  function findFontURL (line 109) | function findFontURL(fontFamily: string) {

FILE: client/src/app/domToSVG/recordDomChanges.ts
  type DOMChange (line 56) | type DOMChange =

FILE: client/src/app/domToSVG/setThemeForSVGScreenshot.ts
  function getUniqueSelector (line 95) | function getUniqueSelector(element: HTMLElement): string {

FILE: client/src/app/domToSVG/text/getTextForSVG.ts
  type TextForSVG (line 8) | type TextForSVG = {

FILE: client/src/app/domToSVG/text/textToSVG.ts
  constant TEXT_WIDTH_ATTR (line 8) | const TEXT_WIDTH_ATTR = "data-text-width";
  constant TEXT_HEIGHT_ATTR (line 9) | const TEXT_HEIGHT_ATTR = "data-text-height";

FILE: client/src/app/domToSVG/utils/getWhatToRenderOnSVG.ts
  type WhatToRenderOnSVG (line 19) | type WhatToRenderOnSVG = Awaited<

FILE: client/src/appUtils.ts
  type Unsubscribe (line 9) | type Unsubscribe = {
  type OnStateChange (line 13) | type OnStateChange<S> = (newState: S) => void;
  type Subscribe (line 14) | type Subscribe<S> = (sc: OnStateChange<S>) => Unsubscribe;
  type ReactiveState (line 16) | type ReactiveState<S> = {
  type Window (line 88) | interface Window {
  type HTMLDivElement (line 114) | interface HTMLDivElement {

FILE: client/src/components/AlertProvider.tsx
  type AlertDialogProps (line 12) | type AlertDialogProps = Pick<
  type AlertContext (line 17) | type AlertContext = {

FILE: client/src/components/Animations.tsx
  type DivProps (line 7) | type DivProps = React.DetailedHTMLProps<
  class SuccessSVG (line 32) | class SuccessSVG extends React.Component<React.SVGProps<SVGSVGElement>> {
    method render (line 33) | render() {
  type FlashMessageProps (line 80) | type FlashMessageProps = {

FILE: client/src/components/Btn.tsx
  type ClickMessage (line 17) | type ClickMessage = (
  type ClickMessageArgs (line 22) | type ClickMessageArgs = (msg: ClickMessage, onEnd?: () => void) => void;
  type BtnCustomProps (line 24) | type BtnCustomProps = (
  type KeysOfUnion (line 103) | type KeysOfUnion<T> = T extends T ? keyof T : never;
  type OmmitedKeys (line 105) | type OmmitedKeys =
  constant CUSTOM_ATTRS (line 112) | const CUSTOM_ATTRS: OmmitedKeys[] = [
  type BtnProps (line 142) | type BtnProps<HREF extends string | void = void> = TestSelectors &
  type BtnState (line 156) | type BtnState = {
  class Btn (line 166) | class Btn<HREF extends string | void = void> extends RTComp<
    method render (line 255) | render() {

FILE: client/src/components/ButtonBar.tsx
  type P (line 6) | type P = {

FILE: client/src/components/ButtonGroup.tsx
  type P (line 12) | type P<Option extends string> = TestSelectors & {
  class ButtonGroup (line 33) | class ButtonGroup<Option extends string> extends React.Component<
    method render (line 37) | render() {

FILE: client/src/components/Chat/Chat.tsx
  type Message (line 10) | type Message = {
  type ChatProps (line 19) | type ChatProps = {

FILE: client/src/components/Chat/ChatMessage.tsx
  type ChatMessageProps (line 6) | type ChatMessageProps = {

FILE: client/src/components/Chat/ChatSendControls.tsx
  type ChatSendControlsProps (line 13) | type ChatSendControlsProps = Pick<

FILE: client/src/components/Chat/ChatSpeech/ChatSpeech.tsx
  type P (line 23) | type P = {

FILE: client/src/components/Chat/ChatSpeech/hooks/SpeechRecorder.ts
  constant MINIMUM_VARIANCE (line 3) | const MINIMUM_VARIANCE = 20;
  constant MINIMUM_SPEECH_THRESHOLD (line 4) | const MINIMUM_SPEECH_THRESHOLD = 15;
  constant SILENCE_DURATION (line 14) | const SILENCE_DURATION = 1500;
  constant SUSTAINED_SPEECH_DURATION (line 15) | const SUSTAINED_SPEECH_DURATION = 200;
  constant INITIAL_PAUSE_DURATION (line 16) | const INITIAL_PAUSE_DURATION = isPlaywrightTest ? 100 : 1000;
  type SpeechRecorderConfig (line 18) | type SpeechRecorderConfig = {
  type SpeechRecorderCallbacks (line 24) | type SpeechRecorderCallbacks = {
  constant MIME_TYPE (line 36) | const MIME_TYPE =
  class SpeechRecorder (line 42) | class SpeechRecorder {
    method constructor (line 59) | constructor(
    method start (line 72) | async start(): Promise<void> {
    method stop (line 112) | stop(): void {
    method reset (line 120) | private reset(): void {
    method cleanup (line 130) | private async cleanup() {
    method getAudioLevel (line 140) | private getAudioLevel(): number {
    method getVariance (line 169) | private getVariance(values: number[]): number {
    method elapsed (line 175) | get elapsed(): number {
    method justStarted (line 183) | get justStarted(): boolean {
    method handleStop (line 279) | private async handleStop() {
    method handleError (line 291) | private async handleError(error: Error) {

FILE: client/src/components/Chat/ChatSpeech/hooks/renderSpeechAudioLevelsIcon.ts
  constant BAR_COUNT (line 7) | const BAR_COUNT = 5;
  constant BAR_SPACING (line 8) | const BAR_SPACING = 4;
  constant X_PADDING (line 9) | const X_PADDING = 4;

FILE: client/src/components/Chat/ChatSpeech/hooks/useSpeechRecorder.ts
  type SpeechRecorderConfig (line 4) | type SpeechRecorderConfig = {
  type UseSpeechRecorderState (line 16) | type UseSpeechRecorderState =
  function useSpeechRecorder (line 20) | function useSpeechRecorder(

FILE: client/src/components/Chat/ChatSpeech/hooks/useSpeechToTextWeb.ts
  type SpeechToTextState (line 3) | type SpeechToTextState =

FILE: client/src/components/Chat/ChatSpeech/useChatSpeechSetup.ts
  type ChatSpeechSetupState (line 106) | type ChatSpeechSetupState = ReturnType<typeof useChatSpeechSetup>;

FILE: client/src/components/Chat/Marked.tsx
  type MarkedProps (line 13) | type MarkedProps = DivProps &

FILE: client/src/components/Chat/MonacoCodeInMarkdown/MonacoCodeInMarkdown.tsx
  constant LANGUAGE_FALLBACK (line 17) | const LANGUAGE_FALLBACK = new Map<string, string>([
  type MonacoCodeInMarkdownProps (line 22) | type MonacoCodeInMarkdownProps = {

FILE: client/src/components/Chat/MonacoCodeInMarkdown/useOnRunSQL.ts
  type SQLResult (line 64) | type SQLResult =

FILE: client/src/components/Chat/useChatState.ts
  type ChatState (line 9) | type ChatState = ReturnType<typeof useChatState>;
  function blobToBase64 (line 134) | function blobToBase64(blob: File): Promise<string> {

FILE: client/src/components/Checkbox.tsx
  type P (line 9) | type P = TestSelectors & {

FILE: client/src/components/Chip.tsx
  type ChipProps (line 10) | type ChipProps = TestSelectors &
  class Chip (line 35) | class Chip extends React.Component<ChipProps> {
    method render (line 36) | render() {

FILE: client/src/components/ClickCatch.tsx
  type P (line 3) | type P = Pick<
  class ClickCatch (line 13) | class ClickCatch extends React.Component<P, any> {
    method render (line 16) | render() {

FILE: client/src/components/ConfirmationDialog.tsx
  type ConfirmDialogProps (line 10) | type ConfirmDialogProps = Pick<
  type S (line 29) | type S = {};
  class ConfirmationDialog (line 31) | class ConfirmationDialog extends RTComp<ConfirmDialogProps, S> {
    method render (line 34) | render() {

FILE: client/src/components/DragOverUpload/DragOverUpload.tsx
  type P (line 5) | type P = {

FILE: client/src/components/DraggableLI.tsx
  type P (line 5) | type P<T> = TestSelectors &
  type ListParent (line 28) | type ListParent =

FILE: client/src/components/ErrorComponent.tsx
  type P (line 11) | type P = TestSelectors & {
  class ErrorComponent (line 31) | class ErrorComponent extends React.Component<P> {
    method componentDidMount (line 40) | componentDidMount() {
    method componentDidUpdate (line 43) | componentDidUpdate() {
    method render (line 46) | render() {
  class ErrorTrap (line 124) | class ErrorTrap extends React.Component<
    method componentDidCatch (line 133) | componentDidCatch(error, errorInfo) {
    method render (line 137) | render() {

FILE: client/src/components/ExpandSection.tsx
  type ExpandSectionProps (line 6) | type ExpandSectionProps = {

FILE: client/src/components/Expander.tsx
  type ExpanderProps (line 3) | type ExpanderProps = {
  function Expander (line 9) | function Expander({ children, getButton }: ExpanderProps) {

FILE: client/src/components/FileBrowser/FileBrowser.tsx
  type P (line 26) | type P = {
  constant FILE_EXTENSION_TO_ICON_INFO (line 120) | const FILE_EXTENSION_TO_ICON_INFO: Record<

FILE: client/src/components/FileBrowser/FileBrowserCurrentDirectory.tsx
  type P (line 9) | type P = {

FILE: client/src/components/FileInput/FileInput.tsx
  type SavedMedia (line 10) | type SavedMedia = {
  type LocalMedia (line 17) | type LocalMedia = {
  type Media (line 22) | type Media = SavedMedia | LocalMedia;
  type S (line 32) | type S = {
  class FileInput (line 40) | class FileInput extends RTComp<
    method onMount (line 66) | onMount(): void {
    method render (line 103) | render() {

FILE: client/src/components/FlashMessage.tsx
  type P (line 4) | type P = {

FILE: client/src/components/Flex.tsx
  type DivProps (line 4) | type DivProps = React.HTMLAttributes<HTMLDivElement> & TestSelectors;
  type FlexDivProps (line 10) | type FlexDivProps = DivProps & {

FILE: client/src/components/FormField/FormField.tsx
  type FormFieldTypes (line 27) | type FormFieldTypes =
  type FormFieldNullOpt (line 38) | type FormFieldNullOpt<Nullable = false, Optional = false> =
  type FormFieldValueType (line 42) | type FormFieldValueType<
  type FormFieldProps (line 54) | type FormFieldProps<
  type FormFieldState (line 117) | type FormFieldState = {
  class FormField (line 124) | class FormField<
    method componentDidMount (line 175) | componentDidMount() {
    method componentWillUnmount (line 180) | componentWillUnmount() {
    method componentDidUpdate (line 185) | componentDidUpdate(prevProps: FormFieldProps<T, Nullable, Optional>) {
    method render (line 257) | render(): React.ReactNode {

FILE: client/src/components/FormField/FormFieldCodeEditor.tsx
  type P (line 11) | type P = Pick<FormFieldProps<"text">, "value" | "onChange" | "readOnly">...

FILE: client/src/components/FormField/FormFieldDebounced.tsx
  type S (line 6) | type S = {
  class FormFieldDebounced (line 11) | class FormFieldDebounced<
    method constructor (line 16) | constructor(props) {
    method render (line 46) | render(): React.ReactNode {

FILE: client/src/components/FormField/FormFieldSkeleton.tsx
  constant INPUT_WRAPPER_CLASS (line 11) | const INPUT_WRAPPER_CLASS = "input-wrapper";
  type FormFieldCommonProps (line 13) | type FormFieldCommonProps = {
  type FormFieldSkeletonProps (line 28) | type FormFieldSkeletonProps = TestSelectors &

FILE: client/src/components/FormField/onFormFieldKeyDown.ts
  function onFormFieldKeyDown (line 4) | function onFormFieldKeyDown(

FILE: client/src/components/Hotkey.tsx
  type P (line 4) | type P = {

FILE: client/src/components/Icon/Icon.tsx
  type IconProps (line 4) | type IconProps = {

FILE: client/src/components/IconPalette/IconPalette.tsx
  type P (line 14) | type P = {

FILE: client/src/components/InfoRow.tsx
  type InfoRowProps (line 6) | type InfoRowProps = {
  function InfoRow (line 16) | function InfoRow(props: InfoRowProps) {

FILE: client/src/components/Input.tsx
  type P (line 3) | type P = React.HTMLProps<HTMLInputElement> & {

FILE: client/src/components/JSONBSchema/JSONBSchema.tsx
  type Schema (line 23) | type Schema = JSONB.JSONBSchema & { optional?: boolean };
  type JSONBSchemaCommonProps (line 24) | type JSONBSchemaCommonProps = Pick<Prgl, "db" | "tables"> & {
  type P (line 40) | type P<S extends Schema> = JSONBSchemaCommonProps & {

FILE: client/src/components/JSONBSchema/JSONBSchemaAllowedOptions.tsx
  type Schema (line 9) | type Schema = JSONB.BasicType;
  type P (line 10) | type P = JSONBSchemaCommonProps & {

FILE: client/src/components/JSONBSchema/JSONBSchemaArray.tsx
  type Schema (line 12) | type Schema = JSONB.ArrayOf;
  type P (line 13) | type P = JSONBSchemaCommonProps & {

FILE: client/src/components/JSONBSchema/JSONBSchemaLookup.tsx
  type Schema (line 13) | type Schema = JSONB.Lookup;
  type P (line 14) | type P = JSONBSchemaCommonProps & {

FILE: client/src/components/JSONBSchema/JSONBSchemaObject.tsx
  type Schema (line 12) | type Schema = JSONB.ObjectType;
  type P (line 13) | type P = JSONBSchemaCommonProps & {

FILE: client/src/components/JSONBSchema/JSONBSchemaOneOfType.tsx
  type Schema (line 8) | type Schema = Extract<
  type P (line 12) | type P = JSONBSchemaCommonProps & {

FILE: client/src/components/JSONBSchema/JSONBSchemaPrimitive.tsx
  type Schema (line 10) | type Schema = JSONB.BasicType | JSONB.EnumType;
  type P (line 11) | type P = JSONBSchemaCommonProps & {

FILE: client/src/components/JSONBSchema/JSONBSchemaRecord.tsx
  type Schema (line 10) | type Schema = JSONB.RecordType;
  type P (line 11) | type P = JSONBSchemaCommonProps & {

FILE: client/src/components/JsonRenderer.tsx
  type P (line 3) | type P = {

FILE: client/src/components/Label.tsx
  type NormalLabelProps (line 10) | type NormalLabelProps = {
  type HeaderLabelProps (line 20) | type HeaderLabelProps = {
  type LabelPropsCommon (line 27) | type LabelPropsCommon = React.DetailedHTMLProps<
  type LabelPropsNormal (line 37) | type LabelPropsNormal = LabelPropsCommon & NormalLabelProps;
  type LabelPropsHeader (line 38) | type LabelPropsHeader = LabelPropsCommon & HeaderLabelProps;
  type LabelProps (line 40) | type LabelProps = LabelPropsNormal | LabelPropsHeader;

FILE: client/src/components/LabeledRow.tsx
  type P (line 5) | type P = {

FILE: client/src/components/List.tsx
  type Items (line 7) | type Items = {
  type ListProps (line 22) | type ListProps = {
  class List (line 36) | class List extends React.Component<ListProps, any> {
    method render (line 39) | render() {

FILE: client/src/components/Loader/Loading.tsx
  type P (line 15) | type P = {
  type S (line 51) | type S = {
  class Loading (line 55) | class Loading extends RTComp<P, S> {
    method show (line 61) | get show() {
    method onMount (line 70) | onMount() {
    method onDelta (line 88) | onDelta(
    method render (line 116) | render() {

FILE: client/src/components/MediaViewer/MediaViewer.tsx
  type P (line 13) | type P = {

FILE: client/src/components/MediaViewer/RenderMedia.tsx
  type ValidContentType (line 7) | type ValidContentType = (typeof ContentTypes)[number];
  type UrlInfo (line 8) | type UrlInfo = {

FILE: client/src/components/MenuList.tsx
  type MenuListProps (line 12) | type MenuListProps = TestSelectors & {
  function textContent (line 225) | function textContent(elem: React.ReactElement | string): string {

FILE: client/src/components/MenuListItem.tsx
  type MenuListitem (line 7) | type MenuListitem = {
  type Props (line 27) | type Props = Pick<MenuListProps, "activeKey" | "variant"> & {

FILE: client/src/components/MonacoEditor/MonacoEditor.tsx
  type MonacoEditorProps (line 18) | type MonacoEditorProps = Pick<TestSelectors, "data-command"> & {
  constant MONACO_READONLY_DEFAULT_OPTIONS (line 300) | const MONACO_READONLY_DEFAULT_OPTIONS = {

FILE: client/src/components/MonacoEditor/useWhyDidYouUpdate.ts
  function useWhyDidYouUpdate (line 3) | function useWhyDidYouUpdate(props) {
  type ReactInternals (line 66) | type ReactInternals = {
  type RenderedComponentInfo (line 75) | type RenderedComponentInfo = {

FILE: client/src/components/NavBar/NavBar.tsx
  type P (line 13) | type P = {

FILE: client/src/components/NavBar/NavBarWrapper.tsx
  type NavBarWrapperProps (line 13) | type NavBarWrapperProps = {

FILE: client/src/components/Pan.tsx
  type PanProps (line 5) | type PanProps = TestSelectors &

FILE: client/src/components/Popup/Footer.tsx
  type FooterProps (line 6) | type FooterProps = TestSelectors & {

FILE: client/src/components/Popup/FooterButtons.tsx
  type FooterButton (line 8) | type FooterButton =
  type FooterButtonsProps (line 18) | type FooterButtonsProps = TestSelectors &

FILE: client/src/components/Popup/Popup.tsx
  constant POPUP_CLASSES (line 35) | const POPUP_CLASSES = {
  constant POPUP_ZINDEX (line 45) | const POPUP_ZINDEX = 5;
  type PopupProps (line 46) | type PopupProps = TestSelectors & {
  constant FOCUSABLE_ELEMS_SELECTOR (line 122) | const FOCUSABLE_ELEMS_SELECTOR =
  type PopupState (line 125) | type PopupState = {
  class Popup (line 132) | class Popup extends RTComp<PopupProps, PopupState> {
    method onMount (line 184) | onMount() {
    method onDelta (line 242) | onDelta(deltaP: DeltaOf<PopupProps>, deltaS: DeltaOf<PopupState>): void {
    method onUnmount (line 249) | onUnmount() {
    method render (line 291) | render() {
  constant DATA_NULLABLE (line 438) | const DATA_NULLABLE = "data-nullable";
  constant DATA_HAS_VALUE (line 439) | const DATA_HAS_VALUE = "data-has-value";

FILE: client/src/components/Popup/PopupHeader.tsx
  type PopupHeaderProps (line 13) | type PopupHeaderProps = PopupProps & {

FILE: client/src/components/Popup/getPopupPosition.ts
  type Args (line 5) | type Args = {

FILE: client/src/components/Popup/getPopupStyle.ts
  type Args (line 4) | type Args = {

FILE: client/src/components/PopupMenu.tsx
  type P (line 8) | type P<State extends AnyObject> = {

FILE: client/src/components/PopupMenuList.tsx
  type PopupMenuListProps (line 9) | type PopupMenuListProps = (

FILE: client/src/components/PostgresInstallationInstructions.tsx
  constant OPERATING_SYSTEMS (line 13) | const OPERATING_SYSTEMS = [
  type OS (line 18) | type OS = (typeof OPERATING_SYSTEMS)[number]["key"];
  type P (line 20) | type P = {

FILE: client/src/components/ProgressBar.tsx
  type P (line 6) | type P = {
  constant MINI_BARCHART_COLOR (line 12) | const MINI_BARCHART_COLOR = "var(--active)";
  type CellBarchartProps (line 54) | type CellBarchartProps = {

FILE: client/src/components/QRCodeImage.tsx
  type QRCodeImageProps (line 5) | type QRCodeImageProps = {

FILE: client/src/components/ScrollFade/ScrollFade.tsx
  type P (line 10) | type P = TestSelectors &
  type Sides (line 17) | type Sides = Record<"top" | "bottom" | "left" | "right", boolean>;

FILE: client/src/components/ScrollFade/useResizeObserver.ts
  type Size (line 4) | type Size = {
  type UseResizeObserverOptions (line 9) | type UseResizeObserverOptions<T extends HTMLElement = HTMLElement> = {
  function useResizeObserver (line 20) | function useResizeObserver<T extends HTMLElement = HTMLElement>(
  type BoxSizesKey (line 74) | type BoxSizesKey = keyof Pick<
  function extractSize (line 79) | function extractSize(

FILE: client/src/components/SearchList/SearchInput.tsx
  type SearchInputProps (line 11) | type SearchInputProps = Pick<

FILE: client/src/components/SearchList/SearchList.tsx
  type SearchListItemContent (line 11) | type SearchListItemContent = {
  type SearchListItem (line 18) | type SearchListItem = TestSelectors & {
  type ParsedListItem (line 50) | type ParsedListItem = SearchListItem & {
  type SearchListProps (line 55) | type SearchListProps<M extends boolean = false> = TestSelectors & {

FILE: client/src/components/SearchList/SearchListItems.tsx
  type SearchListItemsProps (line 20) | type SearchListItemsProps = Pick<

FILE: client/src/components/SearchList/hooks/useSearchListItems.tsx
  type SearchListItemsState (line 10) | type SearchListItemsState = ReturnType<typeof useSearchListItems>;

FILE: client/src/components/SearchList/hooks/useSearchListOnClick.ts
  type P (line 4) | type P = {

FILE: client/src/components/SearchList/hooks/useSearchListOnKeyUpDown.ts
  constant SEARCH_LIST_INPUT_CLASSNAME (line 4) | const SEARCH_LIST_INPUT_CLASSNAME = "search-list-comp-input";
  type SearchListOnKeyUpDownProps (line 6) | type SearchListOnKeyUpDownProps = Pick<

FILE: client/src/components/SearchList/hooks/useSearchListSearch.ts
  type SearchListState (line 211) | type SearchListState = ReturnType<typeof useSearchListSearch>;

FILE: client/src/components/SearchList/searchMatchUtils/getItemSearchRank.ts
  type SearchItem (line 3) | type SearchItem = { title: string; subTitle: string; level: number };

FILE: client/src/components/Section.tsx
  type SectionProps (line 10) | type SectionProps = TestSelectors & {

FILE: client/src/components/Select/Select.tsx
  type OptionKey (line 19) | type OptionKey = string | number | boolean | Date | null | undefined;
  type FullOption (line 20) | type FullOption<O extends OptionKey = string> = Pick<
  type E (line 42) | type E =
  type SelectProps (line 55) | type SelectProps<
  type SelectState (line 119) | type SelectState = {
  class Select (line 131) | class Select<
    method render (line 145) | render() {

FILE: client/src/components/Select/SelectTriggerButton.tsx
  type P (line 9) | type P<

FILE: client/src/components/ShorterText.tsx
  type P (line 6) | type P = {

FILE: client/src/components/SidePanel.tsx
  type P (line 4) | type P = {
  class SidePanel (line 11) | class SidePanel extends React.Component<P, any> {
    method render (line 12) | render() {

FILE: client/src/components/Slider.tsx
  type P (line 7) | type P = {

FILE: client/src/components/Stepper.tsx
  type MyProps (line 3) | type MyProps = {
  class Stepper (line 11) | class Stepper extends React.Component<MyProps, any> {
    method render (line 12) | render() {

FILE: client/src/components/SvgIcon.tsx
  type SvgIconFromURLProps (line 89) | type SvgIconFromURLProps = DivProps & {

FILE: client/src/components/SwitchToggle.tsx
  type SwitchToggleProps (line 11) | type SwitchToggleProps = TestSelectors & {

FILE: client/src/components/Table/Pagination.tsx
  type PaginationProps (line 14) | type PaginationProps = {

FILE: client/src/components/Table/Table.tsx
  constant PAGE_SIZES (line 16) | const PAGE_SIZES = [5, 10, 15, 20, 25, 50, 100, 200] as const;
  type PageSize (line 17) | type PageSize = (typeof PAGE_SIZES)[number];
  type OnColRenderRowInfo (line 19) | type OnColRenderRowInfo = {
  type OnColRender (line 30) | type OnColRender = (rowInfo: OnColRenderRowInfo) => any;
  type TableColumn (line 32) | type TableColumn = {
  type TableProps (line 78) | type TableProps<Sort extends ColumnSortSQL> = {
  type TableState (line 110) | type TableState = {
  function closest (line 176) | function closest<Num extends number>(
  function closestIndexOf (line 184) | function closestIndexOf<Num extends number>(

FILE: client/src/components/Table/TableHeader.tsx
  type TableHeaderProps (line 20) | type TableHeaderProps<Sort extends ColumnSortSQL> = Pick<
  type TableHeaderState (line 28) | type TableHeaderState = Pick<TableState, "draggedCol"> & {
  class TableHeader (line 34) | class TableHeader<Sort extends ColumnSortSQL> extends React.Component<
    method render (line 42) | render(): React.ReactNode {
  function iosContextMenuPolyfill (line 429) | function iosContextMenuPolyfill(): {

FILE: client/src/components/Table/TableRow.tsx
  type TableRowProps (line 9) | type TableRowProps<Sort extends ColumnSortSQL> = {

FILE: client/src/components/Table/useVirtualisedRows.ts
  type RowNodeWithInfo (line 4) | type RowNodeWithInfo = HTMLDivElement & {
  type P (line 9) | type P = {

FILE: client/src/components/Tabs.tsx
  type TabItem (line 14) | type TabItem = Partial<
  type TabItems (line 20) | type TabItems<K extends string = string> = {
  type TabsProps (line 24) | type TabsProps<T extends TabItems = TabItems> = {
  type S (line 57) | type S<T> = {
  class Tabs (line 63) | class Tabs<T extends TabItems = TabItems> extends RTComp<
    method onUnmount (line 74) | onUnmount() {
    method onDelta (line 103) | onDelta(
    method render (line 124) | render() {

FILE: client/src/components/Tooltip.tsx
  type P (line 4) | type P = {

FILE: client/src/dashboard/API/zip.ts
  class Zip (line 4) | class Zip {
    method constructor (line 5) | constructor(name: string) {
    method fecth2zip (line 45) | fecth2zip(filesArray, folder = "") {
    method str2zip (line 65) | str2zip(name: string, content: string, folder = "") {
    method files2zip (line 73) | files2zip(files, folder = "") {
    method makeZip (line 85) | makeZip() {

FILE: client/src/dashboard/AccessControl/AccessControl.tsx
  type P (line 16) | type P = ReturnType<typeof useAccessControlSearchParams> & {
  type AccessRule (line 21) | type AccessRule = Required<DBSSchema["access_control"]> & {
  type EditedAccessRule (line 37) | type EditedAccessRule = Omit<
  type AccessControlAction (line 42) | type AccessControlAction =
  constant ACCESS_CONTROL_SELECT (line 153) | const ACCESS_CONTROL_SELECT = {

FILE: client/src/dashboard/AccessControl/AccessControlRuleEditor.tsx
  constant ACCESS_TYPES (line 45) | const ACCESS_TYPES = ["Custom", "All views/tables", "Run SQL"] as const;
  type PermissionEditProps (line 46) | type PermissionEditProps = Pick<
  type TableErrors (line 56) | type TableErrors = Record<string, TableRulesErrors> | string;
  type UserGroupRuleEditorProps (line 58) | type UserGroupRuleEditorProps = Pick<CommonWindowProps, "prgl"> & {

FILE: client/src/dashboard/AccessControl/AccessRuleEditorFooter.tsx
  type P (line 17) | type P = {

FILE: client/src/dashboard/AccessControl/AccessRuleSummary.tsx
  type TableRuleSummary (line 10) | type TableRuleSummary = {
  type P (line 18) | type P = {
  constant ACCESS_RULE_METHODS (line 23) | const ACCESS_RULE_METHODS = [

FILE: client/src/dashboard/AccessControl/ContextDataSelector.tsx
  type P (line 10) | type P = {

FILE: client/src/dashboard/AccessControl/ContextFilter.tsx
  constant CONTEXT_FILTER_OPERANDS (line 9) | const CONTEXT_FILTER_OPERANDS = [
  type ContextFilterVal (line 18) | type ContextFilterVal = {
  type ContextFilterProps (line 24) | type ContextFilterProps = {
  type AddContextFilterProps (line 101) | type AddContextFilterProps = Pick<

FILE: client/src/dashboard/AccessControl/ExistingAccessRules.tsx
  type ExistingAccessRulesProps (line 14) | type ExistingAccessRulesProps = {

FILE: client/src/dashboard/AccessControl/Methods/ArgumentDefinition.tsx
  type ArgumentDefinitionProps (line 9) | type ArgumentDefinitionProps = ArgDef & {

FILE: client/src/dashboard/AccessControl/Methods/MethodDefinition.tsx
  type MethodDefinitionProps (line 13) | type MethodDefinitionProps = {

FILE: client/src/dashboard/AccessControl/Methods/MethodFunctionDefinition.tsx
  function useCallbackDeep (line 65) | function useCallbackDeep<T extends (...args: any[]) => any>(

FILE: client/src/dashboard/AccessControl/Methods/useCodeEditorTsTypes.ts
  type Props (line 10) | type Props = Pick<
  type FetchMethodDefinitionTypesArgs (line 105) | type FetchMethodDefinitionTypesArgs = Pick<Props, "tables" | "dbs"> &

FILE: client/src/dashboard/AccessControl/OptionControllers/DynamicFields.tsx
  type P (line 19) | type P = Pick<

FILE: client/src/dashboard/AccessControl/OptionControllers/FieldFilterControl.tsx
  type FieldFilterControlProps (line 11) | type FieldFilterControlProps = {

FILE: client/src/dashboard/AccessControl/OptionControllers/FilterControl.tsx
  type ContextDataSchema (line 23) | type ContextDataSchema = {
  type SingleGroupFilter (line 28) | type SingleGroupFilter =
  type ForcedFilterControlProps (line 32) | type ForcedFilterControlProps = {
  constant OPTS (line 49) | const OPTS = [
  constant OPTS_CHECK (line 61) | const OPTS_CHECK = [

FILE: client/src/dashboard/AccessControl/PasswordlessSetup.tsx
  type NewUser (line 9) | type NewUser = Partial<ClientUser & { passwordconfirm?: string }>;

FILE: client/src/dashboard/AccessControl/PermissionTypes/PCustomTables.tsx
  type DBPermissionCustomTables (line 14) | type DBPermissionCustomTables<
  type DBPermissionEditorProps (line 18) | type DBPermissionEditorProps<

FILE: client/src/dashboard/AccessControl/PublishedWorkspaceSelector.tsx
  type P (line 19) | type P = Pick<CommonWindowProps, "prgl"> & {
  type WorspaceTableAndColumns (line 192) | type WorspaceTableAndColumns = {

FILE: client/src/dashboard/AccessControl/RuleTypeControls/DeleteRuleControl.tsx
  type P (line 17) | type P = Pick<

FILE: client/src/dashboard/AccessControl/RuleTypeControls/ExampleComparablePolicy.tsx
  type P (line 16) | type P = Pick<SelectRuleControlProps, "table" | "userTypes" | "prgl"> &

FILE: client/src/dashboard/AccessControl/RuleTypeControls/InsertRuleControl.tsx
  type P (line 17) | type P = Pick<

FILE: client/src/dashboard/AccessControl/RuleTypeControls/SelectRuleControl.tsx
  type SelectRuleControlProps (line 25) | type SelectRuleControlProps = Pick<

FILE: client/src/dashboard/AccessControl/RuleTypeControls/SyncRuleControl.tsx
  type P (line 12) | type P = Pick<

FILE: client/src/dashboard/AccessControl/RuleTypeControls/UpdateRuleControl.tsx
  type P (line 24) | type P = Pick<

FILE: client/src/dashboard/AccessControl/RuleTypeControls/getComparablePGPolicy.ts
  type GetComparablePGPolicyArgs (line 10) | type GetComparablePGPolicyArgs = Pick<

FILE: client/src/dashboard/AccessControl/TableRules/FileTableAccessControlInfo.tsx
  type FileTableAccessControlInfoProps (line 11) | type FileTableAccessControlInfoProps = {

FILE: client/src/dashboard/AccessControl/TableRules/TablePermissionControls.tsx
  type TableInfoWithRules (line 20) | type TableInfoWithRules = DBSchemaTablesWJoins[number] & {
  type TablePermissionControlsProps (line 24) | type TablePermissionControlsProps = Pick<CommonWindowProps, "prgl"> & {
  constant TABLE_RULE_LABELS (line 48) | const TABLE_RULE_LABELS = {
  type EditedRuleType (line 71) | type EditedRuleType = keyof typeof TABLE_RULE_LABELS;

FILE: client/src/dashboard/AccessControl/TableRules/TableRulesPopup.tsx
  type TableRulesPopupProps (line 23) | type TableRulesPopupProps = TablePermissionControlsProps & {

FILE: client/src/dashboard/AccessControl/TableRules/useLocalTableRulesErrors.ts
  type Args (line 6) | type Args = Pick<TablePermissionControlsProps, "contextData" | "table"> &

FILE: client/src/dashboard/AccessControl/UserStats.tsx
  type UserStatsProps (line 10) | type UserStatsProps = Pick<

FILE: client/src/dashboard/AccessControl/UserTypeSelect.tsx
  type P (line 11) | type P = {

FILE: client/src/dashboard/AccessControl/useAccessControlSearchParams.ts
  constant SEARCH_PARAMS (line 5) | const SEARCH_PARAMS = {

FILE: client/src/dashboard/AccessControl/useEditedAccessRule.ts
  type P (line 17) | type P = Pick<PermissionEditProps, "action" | "prgl">;
  type TableErrors (line 19) | type TableErrors = Record<string, TableRulesErrors>;
  type UserType (line 38) | type UserType = DBSSchema["user_types"]["id"];
  type ValidEditedAccessRuleState (line 40) | type ValidEditedAccessRuleState = (
  type EditedAccessRuleState (line 80) | type EditedAccessRuleState =

FILE: client/src/dashboard/AskLLM/AskLLM.tsx
  type P (line 11) | type P = Prgl & {

FILE: client/src/dashboard/AskLLM/Chat/AskLLMChat.tsx
  constant CHAT_WIDTH (line 15) | const CHAT_WIDTH = 900;
  type AskLLMChatProps (line 17) | type AskLLMChatProps = Pick<

FILE: client/src/dashboard/AskLLM/Chat/AskLLMChatMessages/LLMChatMessage/LLMChatMessage.tsx
  type LLMChatMessageCommonProps (line 12) | type LLMChatMessageCommonProps = Pick<
  type P (line 17) | type P = LLMChatMessageCommonProps & {

FILE: client/src/dashboard/AskLLM/Chat/AskLLMChatMessages/ProstglesToolUseMessage/ProstglesMCPTools/DockerSandboxCreateContainer.tsx
  type DockerSandboxCreateContainerData (line 34) | type DockerSandboxCreateContainerData = JSONB.GetObjectType<

FILE: client/src/dashboard/AskLLM/Chat/AskLLMChatMessages/ProstglesToolUseMessage/ProstglesMCPTools/ExecuteSQL.tsx
  type InputSchema (line 10) | type InputSchema = JSONB.GetObjectType<

FILE: client/src/dashboard/AskLLM/Chat/AskLLMChatMessages/ProstglesToolUseMessage/ProstglesMCPTools/common/HeaderList.tsx
  type P (line 5) | type P = {

FILE: client/src/dashboard/AskLLM/Chat/AskLLMChatMessages/ProstglesToolUseMessage/ProstglesToolUseMessage.tsx
  type ProstglesMCPToolsProps (line 66) | type ProstglesMCPToolsProps = {

FILE: client/src/dashboard/AskLLM/Chat/AskLLMChatMessages/ToolUseChatMessage/ToolUseChatMessage.tsx
  type LLMMessageContent (line 81) | type LLMMessageContent = DBSSchema["llm_messages"]["message"][number];
  type ToolUseMessage (line 82) | type ToolUseMessage = Extract<LLMMessageContent, { type: "tool_use" }>;
  type ToolResultMessage (line 83) | type ToolResultMessage = Extract<

FILE: client/src/dashboard/AskLLM/Chat/AskLLMChatMessages/ToolUseChatMessage/useToolUseChatMessage.ts
  type ToolUseMessageProps (line 9) | type ToolUseMessageProps = Pick<UseLLMChatProps, "mcpServerIcons"> & {
  type ToolUseChatMessageState (line 50) | type ToolUseChatMessageState = Exclude<

FILE: client/src/dashboard/AskLLM/Chat/AskLLMChatMessages/hooks/useLLMChatMessageGrouper.tsx
  type P (line 7) | type P = {
  type LLMSingleMessage (line 120) | type LLMSingleMessage = {
  type LLMMessageGroup (line 126) | type LLMMessageGroup = {
  type LLMMessageItem (line 137) | type LLMMessageItem = LLMSingleMessage | LLMMessageGroup;

FILE: client/src/dashboard/AskLLM/Chat/AskLLMChatMessages/hooks/useLLMChatMessages.tsx
  type P (line 13) | type P = UseLLMChatProps & {

FILE: client/src/dashboard/AskLLM/Chat/AskLLMChatOptions.tsx
  type LLMChatOptionsProps (line 12) | type LLMChatOptionsProps = {

FILE: client/src/dashboard/AskLLM/Chat/useAskLLMChatSend.ts
  type P (line 12) | type P = Pick<AskLLMChatProps, "askLLM" | "stopAskLLM"> &

FILE: client/src/dashboard/AskLLM/Chat/useLLMChat.tsx
  type UseLLMChatProps (line 8) | type UseLLMChatProps = LLMSetupStateReady &
  type LLMChatState (line 14) | type LLMChatState = ReturnType<typeof useLLMChat>;

FILE: client/src/dashboard/AskLLM/Chat/useLLMSchemaStr.ts
  type P (line 6) | type P = Pick<Prgl, "connection" | "db" | "tables"> & {

FILE: client/src/dashboard/AskLLM/Setup/AskLLMAccessControl.tsx
  type P (line 17) | type P = Prgl & {

FILE: client/src/dashboard/AskLLM/Setup/SetupLLMCredentials.tsx
  type SetupLLMCredentialsProps (line 15) | type SetupLLMCredentialsProps = Pick<

FILE: client/src/dashboard/AskLLM/Setup/useLLMSetupState.ts
  type LLMSetupState (line 5) | type LLMSetupState = ReturnType<typeof useLLMSetupState>;
  type LLMSetupStateReady (line 6) | type LLMSetupStateReady = Extract<LLMSetupState, { state: "ready" }>;

FILE: client/src/dashboard/AskLLM/Tools/AskLLMToolApprover.tsx
  type AskLLMToolsProps (line 21) | type AskLLMToolsProps = {

FILE: client/src/dashboard/AskLLM/Tools/loadGeneratedWorkspaces/loadGeneratedWorkspaces.ts
  type WindowInsertModel (line 220) | type WindowInsertModel = Omit<
  type LinkOption (line 225) | type LinkOption = DBSSchema["links"]["options"];

FILE: client/src/dashboard/AskLLM/Tools/useLLMToolsApprover.tsx
  type ToolApproval (line 14) | type ToolApproval = {
  type ApproveRequest (line 95) | type ApproveRequest = AllowedChatTool;

FILE: client/src/dashboard/BackupAndRestore/AutomaticBackups.tsx
  constant DESTINATIONS (line 9) | const DESTINATIONS = [
  constant BACKUP_FREQUENCIES (line 14) | const BACKUP_FREQUENCIES = [
  constant DAYS_OF_WEEK (line 20) | const DAYS_OF_WEEK = [
  type P (line 36) | type P = Pick<Prgl, "db" | "dbs" | "dbsMethods" | "dbsTables"> & {

FILE: client/src/dashboard/BackupAndRestore/BackupsControls.tsx
  type DeleteAllBackupsProps (line 282) | type DeleteAllBackupsProps = {

FILE: client/src/dashboard/BackupAndRestore/CloudStorageCredentialSelector.tsx
  type P (line 16) | type P = {
  function CloudStorageCredentialSelector (line 27) | function CloudStorageCredentialSelector({
  constant SAMPLE_BUCKET_POLICY (line 200) | const SAMPLE_BUCKET_POLICY = `

FILE: client/src/dashboard/BackupAndRestore/CodeConfirmation.tsx
  type CodeConfirmationProps (line 10) | type CodeConfirmationProps = TestSelectors & {
  type CodeCheckerProps (line 118) | type CodeCheckerProps = Pick<
  function CodeChecker (line 124) | function CodeChecker({

FILE: client/src/dashboard/BackupAndRestore/DumpLocationOptions.tsx
  type P (line 8) | type P = Pick<DumpOptionsProps, "dbs" | "dbsTables" | "dbsMethods"> & {

FILE: client/src/dashboard/BackupAndRestore/PGDumpOptions.tsx
  constant FORMATS (line 13) | const FORMATS = [
  constant DUMP_COMMANDS (line 28) | const DUMP_COMMANDS = [
  constant DEFAULT_DUMP_OPTS (line 41) | const DEFAULT_DUMP_OPTS: PGDumpParams = {
  constant DEFAULT_DUMP_ALL_OPTS (line 53) | const DEFAULT_DUMP_ALL_OPTS: PGDumpParams = {
  type DumpOptionsProps (line 63) | type DumpOptionsProps = Pick<

FILE: client/src/dashboard/BackupAndRestore/Restore/Restore.tsx
  type RestoreOpts (line 17) | type RestoreOpts = DBSSchema["backups"]["restore_options"];
  constant DEFAULT_RESTORE_OPTS (line 19) | const DEFAULT_RESTORE_OPTS: RestoreOpts = {
  type RestoreProps (line 31) | type RestoreProps = Pick<Prgl, "dbsMethods" | "db"> & {
  type FileOrMaybeItsNothing (line 63) | type FileOrMaybeItsNothing = File | null | undefined;
  method start (line 97) | start(controller) {}
  method write (line 98) | async write(chunk, controller) {
  method close (line 107) | async close() {
  method abort (line 112) | abort(reason) {

FILE: client/src/dashboard/BackupAndRestore/Restore/RestoreOptions.tsx
  type P (line 8) | type P = {

FILE: client/src/dashboard/BackupAndRestore/useBackupsControlsState.ts
  type BackupsControlsState (line 3) | type BackupsControlsState = ReturnType<typeof useBackupsControlsState>;
  constant BACKUP_FILTER_OPTS (line 30) | const BACKUP_FILTER_OPTS = [

FILE: client/src/dashboard/Charts.tsx
  constant MILLISECOND (line 7) | const MILLISECOND = 1;
  constant SECOND (line 8) | const SECOND = MILLISECOND * 1000;
  constant MINUTE (line 9) | const MINUTE = SECOND * 60;
  constant HOUR (line 10) | const HOUR = MINUTE * 60;
  constant DAY (line 11) | const DAY = HOUR * 24;
  constant MONTH (line 12) | const MONTH = DAY * 30;
  constant YEAR (line 13) | const YEAR = DAY * 365;
  function onPinchZoom (line 26) | function onPinchZoom(
  type Point (line 84) | type Point = [number, number];
  type Coords (line 85) | type Coords = Point | Point[];
  type ChartD (line 87) | type ChartD = {
  class Chart (line 92) | class Chart extends RTComp<
    method onMount (line 112) | onMount() {
    method render (line 138) | render() {
  function roundToNearest (line 176) | function roundToNearest(val: number, increment: number, maxVal: number) {
  function clamp (line 210) | function clamp(num: number, min: number, max: number) {

FILE: client/src/dashboard/Charts/CanvasChart.ts
  type StrokeProps (line 13) | type StrokeProps = {
  type FillProps (line 17) | type FillProps = {
  type ShapeBase (line 20) | type ShapeBase<T = void> = {
  type Circle (line 26) | type Circle<T = any> = ShapeBase<T> &
  type Rectangle (line 34) | type Rectangle<T = any, C = void> = ShapeBase<T> &
  type ChartedText (line 45) | type ChartedText<T = any> = ShapeBase<T> &
  type MultiLine (line 60) | type MultiLine<T = any> = ShapeBase<T> &
  type LinkLine (line 67) | type LinkLine<T = any> = ShapeBase<T> &
  type Image (line 76) | type Image<T = any> = ShapeBase<T> & {
  type Polygon (line 84) | type Polygon<T = any> = ShapeBase<T> &
  type Shape (line 91) | type Shape<T = any> =
  type TextMeasurement (line 98) | type TextMeasurement = {
  type ChartView (line 104) | type ChartView = {
  type CanvasChartViewDataExtent (line 113) | type CanvasChartViewDataExtent = {
  type GetShapes (line 129) | type GetShapes = (opts: CanvasChartViewDataExtent) => Shape[];
  type TimeChartZoomPanEvents (line 131) | type TimeChartZoomPanEvents = Partial<PanListeners> & {
  type ChartOptions (line 137) | type ChartOptions = {
  class CanvasChart (line 155) | class CanvasChart {
    method clampScale (line 174) | static clampScale(newScale: number): number {
    method events (line 181) | get events() {
    method constructor (line 187) | constructor(opts: ChartOptions) {
    method setView (line 304) | setView(view: Partial<ChartView>) {
    method init (line 345) | init() {
    method getWH (line 391) | getWH() {
    method parseData (line 464) | private parseData(_shapes: (Shape | GetShapes)[]): Shape[] {
    method render (line 478) | render(_shapes?: (Shape | GetShapes)[]) {
  constant PIXEL_STEP (line 671) | const PIXEL_STEP = 10;
  constant LINE_HEIGHT (line 672) | const LINE_HEIGHT = 40;
  constant PAGE_HEIGHT (line 673) | const PAGE_HEIGHT = 800;
  function normalizeWheel (line 674) | function normalizeWheel(event: WheelEvent): {

FILE: client/src/dashboard/Charts/TimeChart/TimeChart.tsx
  type ChartDate (line 1) | type ChartDate = { v: number; x: number; date: Date };
  type DataItem (line 18) | type DataItem = {
  type TimeChartLayer (line 22) | type TimeChartLayer = {
  type TimeChartProps (line 51) | type TimeChartProps = Pick<
  type XYFunc (line 88) | type XYFunc = {
  type TimeChartD (line 93) | type TimeChartD = {
  class TimeChart (line 99) | class TimeChart extends RTComp<
    method render (line 172) | render() {

FILE: client/src/dashboard/Charts/TimeChart/getBinValueLabels.ts
  type GetBinValueLabelArgs (line 7) | type GetBinValueLabelArgs = Pick<

FILE: client/src/dashboard/Charts/TimeChart/getTimeAxisTicks.ts
  type GetTimeTicksOpts (line 18) | type GetTimeTicksOpts = DateExtent & {
  type DateIncrementer (line 29) | type DateIncrementer = {
  function getTimeAxisTicks (line 37) | function getTimeAxisTicks(args: GetTimeTicksOpts): ChartedText[] {

FILE: client/src/dashboard/Charts/TimeChart/getTimechartBinSize.ts
  type Bin (line 4) | type Bin = {
  type SizePart (line 12) | type SizePart = {
  type DateExtent (line 91) | type DateExtent = {
  type GetTimechartBinSizeArgs (line 96) | type GetTimechartBinSizeArgs = {

FILE: client/src/dashboard/Charts/TimeChart/getTimechartTooltipIntersections.ts
  type IntersectedLayers (line 4) | type IntersectedLayers = {

FILE: client/src/dashboard/Charts/TimeChart/onRenderTimechart.ts
  function onRenderTimechart (line 22) | function onRenderTimechart(
  function getYTickValues (line 297) | function getYTickValues(args: {
  function getNicestVal (line 324) | function getNicestVal(min: number, max: number): number {

FILE: client/src/dashboard/Charts/drawMonotoneXCurve.ts
  function drawMonotoneXCurve (line 3) | function drawMonotoneXCurve(

FILE: client/src/dashboard/Charts/drawShapes/drawShapes.ts
  type ShapeV2 (line 8) | type ShapeV2<T = void> = Shape<T> | LinkLine<T> | Image<T>;
  function allLowerCase (line 197) | function allLowerCase(str) {

FILE: client/src/dashboard/Charts/drawShapes/drawShapesOnSVG.ts
  function allLowerCase (line 494) | function allLowerCase(str: string) {

FILE: client/src/dashboard/Charts/drawShapes/findShortestPathAroundRectangles.ts
  type Point (line 2) | type Point = { x: number; y: number };
  type Rectangle (line 3) | type Rectangle = {
  function findShortestPathAroundRectangles (line 13) | function findShortestPathAroundRectangles(
  class MinPriorityQueue (line 133) | class MinPriorityQueue<T> {
    method enqueue (line 135) | enqueue(element: T, priority: number) {
    method dequeue (line 139) | dequeue() {
    method isEmpty (line 142) | isEmpty() {
  function distance (line 149) | function distance(p1: Point, p2: Point) {
  function getOrientation (line 157) | function getOrientation(p: Point, q: Point, r: Point) {
  function onSegment (line 164) | function onSegment(p, q, r) {
  function doSegmentsIntersect (line 174) | function doSegmentsIntersect(p1, q1, p2, q2) {
  function isSegmentIntersectingRect (line 199) | function isSegmentIntersectingRect(p1, p2, rect, padding) {
  function isSegmentIntersectingRectangles (line 225) | function isSegmentIntersectingRectangles(

FILE: client/src/dashboard/Charts/drawShapes/shortestLinkLineV2.ts
  constant LINK_SEGMENT_LENGTH (line 153) | const LINK_SEGMENT_LENGTH = 50;

FILE: client/src/dashboard/Charts/roundRect.ts
  constant DEFAULT_SHADOW (line 3) | const DEFAULT_SHADOW = {
  function roundRect (line 10) | function roundRect(

FILE: client/src/dashboard/CodeEditor/CodeEditor.tsx
  type Suggestion (line 28) | type Suggestion = {
  type MonacoError (line 35) | type MonacoError = {
  type MonacoJSONSchema (line 50) | type MonacoJSONSchema = {
  type TSLibrary (line 82) | type TSLibrary = {
  type LanguageConfig (line 94) | type LanguageConfig =
  type CodeEditorJsonSchema (line 113) | type CodeEditorJsonSchema = { id: string; schema: any };
  type CodeEditorProps (line 115) | type CodeEditorProps = Pick<

FILE: client/src/dashboard/CodeEditor/CodeEditorWithSaveButton.tsx
  type P (line 13) | type P = {

FILE: client/src/dashboard/CodeEditor/registerLogLang.ts
  constant LOG_LANGUAGE_ID (line 6) | const LOG_LANGUAGE_ID = "log";
  constant LOG_LANGUAGE_THEME (line 7) | const LOG_LANGUAGE_THEME = "logview";

FILE: client/src/dashboard/CodeEditor/utils/useSetMonacoTsLibraries.ts
  type MonacoEditorImport (line 6) | type MonacoEditorImport = typeof import("monaco-editor");

FILE: client/src/dashboard/CodeExample.tsx
  type P (line 5) | type P = CodeEditorProps & {

FILE: client/src/dashboard/ConnectionConfig/APIDetails/APICodeExamples.tsx
  function getCodeSamples (line 116) | function getCodeSamples({

FILE: client/src/dashboard/ConnectionConfig/APIDetails/APIDetails.tsx
  type APIDetailsProps (line 13) | type APIDetailsProps = PrglState & {

FILE: client/src/dashboard/ConnectionConfig/ConnectionConfig.tsx
  type ConnectionConfigProps (line 34) | type ConnectionConfigProps = Pick<

FILE: client/src/dashboard/ConnectionSelector.tsx
  type P (line 9) | type P = {

FILE: client/src/dashboard/Dashboard/CloseSaveSQLPopup.tsx
  type P (line 8) | type P = {

FILE: client/src/dashboard/Dashboard/DBS.ts
  type DBSMethods (line 20) | type DBSMethods = Partial<{
  type DBS (line 209) | type DBS = DBHandlerClient<DBGeneratedSchema> & {
  type AsOptional (line 213) | type AsOptional<T, Keys extends keyof Partial<T> & string> = Omit<T, Key...
  type DbsByUserType (line 217) | type DbsByUserType = AsOptional<DBS, (typeof AdminTableNames)[number]>;

FILE: client/src/dashboard/Dashboard/Dashboard.tsx
  constant FORCED_REFRESH_PREFIX (line 49) | const FORCED_REFRESH_PREFIX = "force-" as const;
  constant CENTERED_WIDTH_CSS_VAR (line 50) | const CENTERED_WIDTH_CSS_VAR = "--centered-width";
  type DashboardProps (line 51) | type DashboardProps = {
  type DashboardState (line 58) | type DashboardState = {
  type DashboardData (line 80) | type DashboardData = {
  class _Dashboard (line 91) | class _Dashboard extends RTComp<
    method onUnmount (line 109) | onUnmount() {
    method render (line 403) | render() {
  type CommonWindowProps (line 612) | type CommonWindowProps<T extends ChartType = ChartType> = Pick<

FILE: client/src/dashboard/Dashboard/PALETTE.ts
  constant PALETTE (line 10) | const PALETTE = fromEntries(

FILE: client/src/dashboard/Dashboard/ViewRenderer.tsx
  type ViewRendererProps (line 42) | type ViewRendererProps = Pick<DashboardProps, "prgl"> &
  type ViewRendererState (line 54) | type ViewRendererState = {
  type D (line 62) | type D = {
  class ViewRenderer (line 66) | class ViewRenderer extends RTComp<
    method getLinkChain (line 75) | getLinkChain(w1_id: string, w2_id: string): string[] | undefined {
    method getOpenedLinksAndWindows (line 96) | getOpenedLinksAndWindows() {
    method render (line 108) | render() {

FILE: client/src/dashboard/Dashboard/dashboardUtils.ts
  type ChartType (line 28) | type ChartType =
  type DBSSchemaForHandlers (line 37) | type DBSSchemaForHandlers = {
  type ChartLink (line 49) | type ChartLink = DBSSchema["links"]["options"];
  type LinkableCharts (line 50) | type LinkableCharts = "table" | "map" | "timechart";
  type Link (line 52) | type Link = DBSSchema["links"];
  type NewChartOpts (line 54) | type NewChartOpts = {
  type OnAddChart (line 59) | type OnAddChart = (args: NewChartOpts) => void;
  type Query (line 61) | type Query = {
  type JoinFilter (line 74) | type JoinFilter = {
  type WQuery (line 79) | type WQuery = Query & {
  type MapExtent (line 84) | type MapExtent = [[number, number], [number, number]];
  type ChartOptions (line 86) | type ChartOptions<CType extends ChartType = "table"> =
  type Windows (line 240) | type Windows = Required<DBSSchema>["windows"];
  type WindowData (line 244) | type WindowData<CType extends ChartType = ChartType> = Omit<
  type ChartsObj (line 292) | type ChartsObj = {
  type ChartsObjOfUnion (line 295) | type ChartsObjOfUnion<U extends ChartType> = { [K in U]: ChartsObj[K] }[U];
  type WindowSyncItem (line 297) | type WindowSyncItem<T extends ChartType = ChartType> =
  type LinkSyncItem (line 299) | type LinkSyncItem = SyncDataItem<Link, true>;
  type WorkspaceSchema (line 301) | type WorkspaceSchema = DBSSchema["workspaces"];
  type Workspace (line 303) | type Workspace = Required<WorkspaceSchema>;
  type WorkspaceSyncItem (line 305) | type WorkspaceSyncItem = SyncDataItem<Workspace, true>;
  type UserData (line 307) | type UserData = Omit<DBSSchema["users"], "password">;
  type UserFilter (line 312) | type UserFilter = Record<keyof UserData, any>;
  type UserGroupData (line 314) | type UserGroupData = {
  type UserTypeData (line 318) | type UserTypeData = {
  type AcessControlUserTypes (line 322) | type AcessControlUserTypes = DBSSchema["access_control_user_types"];
  type Backups (line 324) | type Backups = DBSSchema["backups"];
  type LoadedSuggestions (line 326) | type LoadedSuggestions = {
  type Join (line 338) | type Join = {
  type JoinV2 (line 343) | type JoinV2 = Omit<Join, "on"> & { on: [string, string][][] };
  type DBSchemaTableColumn (line 345) | type DBSchemaTableColumn = ValidatedColumnInfo & {
  type TableOptions (line 350) | type TableOptions = NonNullable<
  type DBSchemaTableWJoins (line 353) | type DBSchemaTableWJoins = Omit<DBSchemaTable, "columns"> & {
  type DBSchemaTablesWJoins (line 359) | type DBSchemaTablesWJoins = DBSchemaTableWJoins[];
  type QuickFilterGroups (line 365) | type QuickFilterGroups = {

FILE: client/src/dashboard/Dashboard/debuggingUtils.ts
  function observeObjectChanges (line 15) | function observeObjectChanges<T extends object>(
  function stackTrace (line 96) | function stackTrace(arg, check?: (chain: string) => void): void {

FILE: client/src/dashboard/Dashboard/getViewRendererUtils.ts
  type Args (line 21) | type Args = ViewRendererProps & {
  type ClickRowOpts (line 202) | type ClickRowOpts =

FILE: client/src/dashboard/Dashboard/loadTable.ts
  type LoadTableArgs (line 5) | type LoadTableArgs = Pick<Prgl, "db" | "dbs"> & {

FILE: client/src/dashboard/DashboardMenu/DashboardHotkeys.tsx
  type P (line 6) | type P = {

FILE: client/src/dashboard/DashboardMenu/DashboardMenu.tsx
  type DashboardMenuProps (line 20) | type DashboardMenuProps = Pick<DashboardProps, "prgl"> & {
  type DashboardMenuState (line 27) | type DashboardMenuState = {

FILE: client/src/dashboard/DashboardMenu/DashboardMenuContent.tsx
  type P (line 34) | type P = DashboardMenuProps & {

FILE: client/src/dashboard/DashboardMenu/DashboardMenuHeader.tsx
  type P (line 16) | type P = Pick<DashboardMenuProps, "prgl" | "loadTable" | "workspace"> & {

FILE: client/src/dashboard/DashboardMenu/DashboardMenuHotkeys.tsx
  type P (line 7) | type P = Pick<DashboardMenuProps, "loadTable"> & {

FILE: client/src/dashboard/DashboardMenu/DashboardMenuResizer.tsx
  type P (line 6) | type P = {

FILE: client/src/dashboard/DashboardMenu/DashboardMenuSettings.tsx
  type P (line 25) | type P = Pick<DashboardProps, "prgl"> & {

FILE: client/src/dashboard/DashboardMenu/useTableSizeInfo.ts
  type Args (line 10) | type Args = Pick<DashboardMenuProps, "workspace" | "tables"> & {
  type TablesWithInfo (line 13) | type TablesWithInfo = (DBSchemaTablesWJoins[number] & {

FILE: client/src/dashboard/DetailedFilterControl/DetailedFilterBaseControl.tsx
  type DetailedFilterBaseControlProps (line 11) | type DetailedFilterBaseControlProps = BaseFilterProps &

FILE: client/src/dashboard/DetailedFilterControl/DetailedFilterBaseControlRouter.tsx
  type FilterProps (line 20) | type FilterProps = BaseFilterProps &

FILE: client/src/dashboard/DetailedFilterControl/DetailedFilterBaseTypes/AgeFilter.tsx
  type FilterProps (line 13) | type FilterProps = BaseFilterProps;

FILE: client/src/dashboard/DetailedFilterControl/DetailedFilterBaseTypes/GeoFilter.tsx
  type ST_DWithinFilterValue (line 32) | type ST_DWithinFilterValue = {

FILE: client/src/dashboard/DetailedFilterControl/DetailedFilterBaseTypes/ListFilter/ListFilter.tsx
  type ListFilterProps (line 14) | type ListFilterProps = BaseFilterProps;
  type ListFilterState (line 16) | type ListFilterState = {
  class ListFilter (line 27) | class ListFilter extends RTComp<ListFilterProps, ListFilterState> {
    method render (line 132) | render(): React.ReactNode {

FILE: client/src/dashboard/DetailedFilterControl/DetailedFilterBaseTypes/ListFilter/fetchListFilterOptions.ts
  type Args (line 5) | type Args = Pick<

FILE: client/src/dashboard/DetailedFilterControl/DetailedFilterBaseTypes/NumberOrDateFilter.tsx
  type NumberOrDateFilterProps (line 11) | type NumberOrDateFilterProps = BaseFilterProps & {
  type Limits (line 16) | type Limits = {
  type NumberOrDateFilterState (line 20) | type NumberOrDateFilterState = {
  class NumberOrDateFilter (line 24) | class NumberOrDateFilter extends RTComp<
    method render (line 163) | render() {

FILE: client/src/dashboard/DetailedFilterControl/DetailedFilterControl.tsx
  type P (line 16) | type P = {

FILE: client/src/dashboard/DetailedFilterControl/FTS_LANGUAGES.ts
  constant FTS_LANGUAGES (line 5) | const FTS_LANGUAGES = [

FILE: client/src/dashboard/DetailedFilterControl/FilterWrapper.tsx
  type FilterWrapperProps (line 42) | type FilterWrapperProps = {
  type FilterWrapperState (line 64) | type FilterWrapperState = {
  class FilterWrapper (line 72) | class FilterWrapper extends RTComp<
    method render (line 82) | render() {

FILE: client/src/dashboard/FileImporter/FileImporter.tsx
  type Papa (line 24) | type Papa = typeof import("papaparse");
  type FileImporterProps (line 28) | type FileImporterProps = {
  type HeaderType (line 40) | type HeaderType = "First row" | "Custom";
  constant INSERT_AS (line 42) | const INSERT_AS = [
  type FileImporterState (line 48) | type FileImporterState = {
  class FileImporter (line 137) | class FileImporter extends RTComp<FileImporterProps, FileImporterState> {
    method onMount (line 175) | onMount() {
    method onUnmount (line 179) | onUnmount() {
    method render (line 317) | render() {
  function getRowsPerBatch (line 583) | function getRowsPerBatch(maxCharsPerRow, bytesPerChar = 4) {
  type StreamFileArgs (line 611) | type StreamFileArgs = Omit<

FILE: client/src/dashboard/FileImporter/FileImporterFooter.tsx
  type P (line 6) | type P = FileImporterState &

FILE: client/src/dashboard/FileImporter/checkCSVColumnDataTypes.tsx
  type SuggestedColumnDataType (line 8) | type SuggestedColumnDataType = {
  type P (line 74) | type P = {

FILE: client/src/dashboard/FileImporter/importFile.ts
  type ImportProgress (line 11) | type ImportProgress = {
  type Args (line 21) | type Args = Pick<

FILE: client/src/dashboard/FileImporter/parseCSVFile.ts
  type Col (line 7) | type Col = { key: string; dataType: string; escapedName: string };
  function parseCSVFile (line 9) | async function parseCSVFile(

FILE: client/src/dashboard/FileImporter/setFile.ts
  function parseJSONFile (line 101) | async function parseJSONFile(file: File): Promise<{

FILE: client/src/dashboard/FileTableControls/CreateFileColumn.tsx
  type CreateReferencedColumnProps (line 15) | type CreateReferencedColumnProps = Omit<PrglCore, "methods"> & {

FILE: client/src/dashboard/FileTableControls/FileColumnConfigControls.tsx
  type FileTableConfigReferences (line 14) | type FileTableConfigReferences = Record<
  type FileColumnConfigControlsProps (line 19) | type FileColumnConfigControlsProps = {

FILE: client/src/dashboard/FileTableControls/FileColumnConfigEditor.tsx
  constant CONTENT_MODES (line 16) | const CONTENT_MODES = [
  type FileColumnConfigProps (line 22) | type FileColumnConfigProps = {

FILE: client/src/dashboard/FileTableControls/FileStorageControls.tsx
  constant STORAGE_TYPES (line 18) | const STORAGE_TYPES = [
  type FileStorageControlsProps (line 27) | type FileStorageControlsProps = Pick<

FILE: client/src/dashboard/FileTableControls/FileStorageDelete.tsx
  type P (line 12) | type P = Pick<

FILE: client/src/dashboard/FileTableControls/FileStorageReferencedTablesConfig.tsx
  type FileStorageReferencedTablesConfigProps (line 11) | type FileStorageReferencedTablesConfigProps = Pick<PrglCore, "tables" | ...

FILE: client/src/dashboard/FileTableControls/FileTableConfigControls.tsx
  type FileTableConfigControlsProps (line 12) | type FileTableConfigControlsProps = {
  type ConnectionTableConfig (line 18) | type ConnectionTableConfig =

FILE: client/src/dashboard/FileTableControls/useFileTableConfigControls.ts
  type UseFileTableConfigControlsArgs (line 7) | type UseFileTableConfigControlsArgs = Pick<

FILE: client/src/dashboard/JSONBColumnEditor.tsx
  type P (line 9) | type P = {

FILE: client/src/dashboard/LinkMenu.tsx
  type P (line 19) | type P = {
  type S (line 36) | type S = {
  class LinkMenu (line 42) | class LinkMenu extends RTComp<P, S> {
    method render (line 265) | render() {

FILE: client/src/dashboard/Map/DeckGLFeatureEditor.tsx
  type DeckGLFeatureEditorProps (line 19) | type DeckGLFeatureEditorProps = {
  type DrawnShape (line 42) | type DrawnShape =
  type GetDrawnLayerArgs (line 530) | type GetDrawnLayerArgs = {

FILE: client/src/dashboard/Map/DeckGLMap.tsx
  type Extent (line 12) | type Extent = [number, number, number, number];
  type OnClickEvent (line 14) | type OnClickEvent = {
  type Point (line 45) | type Point = [number, number];
  type DeckGlColor (line 54) | type DeckGlColor =
  type GeoJSONFeature (line 58) | type GeoJSONFeature = Omit<Feature, "properties"> & {
  type GeoJsonLayerProps (line 78) | type GeoJsonLayerProps = {
  type MapState (line 103) | type MapState = {
  type MapHandler (line 119) | type MapHandler = {
  type HoverCoords (line 125) | type HoverCoords = {
  type MapExtentBehavior (line 149) | type MapExtentBehavior = (typeof MapExtentBehavior)[number]["key"];
  type DecKGLMapProps (line 151) | type DecKGLMapProps = {
  type DeckGLMapState (line 201) | type DeckGLMapState = {
  type D (line 216) | type D = {
  type DeckGLMapDivDemoControls (line 220) | type DeckGLMapDivDemoControls = HTMLDivElement & {
  class DeckGLMap (line 256) | class DeckGLMap extends RTComp<DecKGLMapProps, DeckGLMapState, D> {
    method rootSizeKey (line 358) | get rootSizeKey(): string {
    method onUnmount (line 362) | onUnmount(): void {
    method onViewStateChange (line 389) | onViewStateChange(viewState) {
    method render (line 538) | render() {

FILE: client/src/dashboard/Map/DeckGLWrapped.ts
  type DeckGlLib (line 28) | type DeckGlLib = Awaited<ReturnType<typeof getDeckLibs>>["lib"];
  type DeckGlLibs (line 29) | type DeckGlLibs = Awaited<ReturnType<typeof getDeckLibs>>;
  type ViewState (line 31) | type ViewState = MapViewState | OrthographicViewState;
  type DeckWrappedOpts (line 32) | type DeckWrappedOpts = (
  class DeckWrapped (line 52) | class DeckWrapped {
    method constructor (line 62) | constructor(node: HTMLDivElement, opts: DeckWrappedOpts, lib: DeckGlLi...
    method render (line 203) | render(props: DeckProps<OrthographicView[] | MapView[]>) {
  type Bounds (line 234) | type Bounds = [[number, number], [number, number]];
  function debounce (line 236) | function debounce<Params extends any[]>(
  type ViewType (line 270) | type ViewType = DeckWrappedOpts["type"];
  type GetViewsResult (line 271) | type GetViewsResult<T extends ViewType> = {

FILE: client/src/dashboard/Map/InMapControls.tsx
  type P (line 12) | type P = Pick<

FILE: client/src/dashboard/Map/fitBounds.ts
  function fitBounds (line 4) | function fitBounds(options: {
  function getPaddingObject (line 52) | function getPaddingObject(padding = 0) {

FILE: client/src/dashboard/Map/mapDrawUtils.ts
  type NebulaLib (line 33) | type NebulaLib = Awaited<ReturnType<typeof getNebulaLib>>;
  type DrawModes (line 35) | type DrawModes = NebulaLib;
  constant MODE_KEYS (line 36) | const MODE_KEYS = [
  type AllDrawModes (line 47) | type AllDrawModes = Pick<DrawModes, (typeof MODE_KEYS)[number]>;
  constant NEBULA_GL_EDIT_TYPES (line 80) | const NEBULA_GL_EDIT_TYPES = [

FILE: client/src/dashboard/Map/mapUtils.ts
  constant DEFAULT_TILE_URLS (line 5) | const DEFAULT_TILE_URLS = [
  function makeTileLayer (line 14) | function makeTileLayer(
  type MakeImageLayerArgs (line 141) | type MakeImageLayerArgs = {
  function makeImageLayer (line 149) | function makeImageLayer({

FILE: client/src/dashboard/RTComp.tsx
  type DeepPartial (line 3) | type DeepPartial<T> =
  type CombinedPartial (line 11) | type CombinedPartial<P, S, D> = Partial<
  type DeltaOfData (line 15) | type DeltaOfData<T> = T | DeepPartial<T> | undefined;
  type DeltaOf (line 16) | type DeltaOf<T> = Partial<T> | undefined;
  class RTComp (line 18) | class RTComp<
    method componentDidMount (line 31) | async componentDidMount() {
    method onMount (line 44) | onMount() {
    method onUnmount (line 56) | onUnmount() {
    method onUpdated (line 81) | onUpdated(prevProps: P, prevState: S) {
    method onDelta (line 137) | onDelta(deltaP: DeltaOf<P>, deltaS: DeltaOf<S>, deltaD: DeltaOfData<D>) {
    method onDeltaCombined (line 141) | onDeltaCombined(
    method setState (line 148) | setState<K extends keyof S>(

FILE: client/src/dashboard/RenderFilter.tsx
  type RenderFilterProps (line 17) | type RenderFilterProps = {

FILE: client/src/dashboard/SQLEditor/SQLCompletion/CommonMatchImports.ts
  type MinimalSnippet (line 12) | type MinimalSnippet = {
  constant STARTING_KEYWORDS (line 72) | const STARTING_KEYWORDS = [
  constant PG_OBJECTS (line 127) | const PG_OBJECTS = [
  constant CREATE_OR_REPLACE (line 187) | const CREATE_OR_REPLACE = [
  constant CREATE_POLICY_DOCS (line 197) | const CREATE_POLICY_DOCS = `Define how a user interacts with rows within...
  constant CREATE_SNIPPETS (line 258) | const CREATE_SNIPPETS = [
  constant POLICY_FOR (line 345) | const POLICY_FOR = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/KEYWORDS.ts
  type TopKeyword (line 4) | type TopKeyword = {
  constant STARTING_KWDS (line 15) | const STARTING_KWDS = [
  function getTopKeywords (line 52) | function getTopKeywords(): TopKeyword[] {
  constant TOP_KEYWORDS (line 448) | const TOP_KEYWORDS = getTopKeywords();

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MacthCreate/MatchCreate.ts
  constant LOCALES (line 220) | const LOCALES = ["en_US.UTF-8", "C.UTF-8"];
  constant CREATE_DB_KWDS (line 222) | const CREATE_DB_KWDS = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MatchAlter/MatchAlter.tsx
  constant ALTED_DB_ACTIONS (line 250) | const ALTED_DB_ACTIONS = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MatchAlter/matchAlterTable.ts
  constant ALTER_TABLE_KWD (line 83) | const ALTER_TABLE_KWD = [
  constant ALTER_TABLE_ACTIONS (line 171) | const ALTER_TABLE_ACTIONS = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MatchAlter/matchCreateOrAlterUser.tsx
  constant ROLE_OPTIONS (line 110) | const ROLE_OPTIONS = [
  constant USER_OPTIONS (line 177) | const USER_OPTIONS = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MatchComment.ts
  constant COMMENT_ON (line 41) | const COMMENT_ON = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MatchCopy.ts
  type DirOrFile (line 206) | type DirOrFile = {
  type DirFilesResult (line 216) | type DirFilesResult = {

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MatchFirst.ts
  constant EXPLAIN_KWDS (line 289) | const EXPLAIN_KWDS = [
  constant TO_CHAR_PATTERNS (line 349) | const TO_CHAR_PATTERNS: { label: string; docs: string }[] = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MatchGrant.ts
  type ONOption (line 95) | type ONOption = Extract<{ label: string }, MinimalSnippet>;
  constant PRIVILEGES (line 243) | const PRIVILEGES = {

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MatchInsert.tsx
  constant KWDS (line 9) | const KWDS = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MatchReassign.ts
  constant KWDS (line 4) | const KWDS = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MatchSelect.ts
  constant AGG_FUNC_NAMES (line 24) | const AGG_FUNC_NAMES = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MatchWith.ts
  constant DATA_MODIF_INFO (line 20) | const DATA_MODIF_INFO = `Trying to update the same row twice in a single...

FILE: client/src/dashboard/SQLEditor/SQLCompletion/MathDelete.ts
  constant KWDS (line 4) | const KWDS = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/PSQL.ts
  constant COMMANDS (line 1) | const COMMANDS = [
  constant ENCODINGS (line 75) | const ENCODINGS = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/STARTING_KEYWORDS.ts
  constant STARTING_KEYWORDS (line 15) | const STARTING_KEYWORDS = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/TableKWDs.ts
  constant PG_COLUMN_CONSTRAINTS (line 6) | const PG_COLUMN_CONSTRAINTS = [
  constant PG_TABLE_CONSTRAINTS (line 72) | const PG_TABLE_CONSTRAINTS = [
  constant REFERENCES_COL_OPTS (line 91) | const REFERENCES_COL_OPTS = [
  constant REF_OPTS (line 128) | const REF_OPTS = [
  constant REFERENCE_CONSTRAINT_OPTIONS_KWDS (line 159) | const REFERENCE_CONSTRAINT_OPTIONS_KWDS = [
  constant TABLE_CONS_TYPES (line 180) | const TABLE_CONS_TYPES = PG_TABLE_CONSTRAINTS.map((c) => c.kwd);
  constant ALTER_COL_ACTIONS (line 182) | const ALTER_COL_ACTIONS = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/completionUtils/checkIfInsideDollarFunctionDefinition.ts
  type LineInfo (line 4) | type LineInfo = {
  type Args (line 10) | type Args = {

FILE: client/src/dashboard/SQLEditor/SQLCompletion/completionUtils/getCodeBlock.ts
  type CodeBlock (line 18) | type CodeBlock = {
  type GetCurrentCodeBlockOpts (line 63) | type GetCurrentCodeBlockOpts = {
  method prevTopKWDs (line 400) | get prevTopKWDs() {
  constant MAIN_KEYWORDS (line 564) | const MAIN_KEYWORDS = [

FILE: client/src/dashboard/SQLEditor/SQLCompletion/completionUtils/getQueryReturnType.ts
  type ExpressionResult (line 97) | type ExpressionResult =

FILE: client/src/dashboard/SQLEditor/SQLCompletion/completionUtils/getTableExpressionReturnTypes.ts
  type GetTableExpressionSuggestionsArgs (line 15) | type GetTableExpressionSuggestionsArgs = Pick<

FILE: client/src/dashboard/SQLEditor/SQLCompletion/completionUtils/getTabularExpressions.ts
  type TabularExpression (line 47) | type TabularExpression = {

FILE: client/src/dashboard/SQLEditor/SQLCompletion/completionUtils/getTokens.ts
  type TokenInfo (line 5) | type TokenInfo = Pick<Token, "offset"> & {
  type GetTokensArgs (line 35) | type GetTokensArgs = {
  type GetTokensResult (line 45) | type GetTokensResult = {

FILE: client/src/dashboard/SQLEditor/SQLCompletion/getExpected.ts
  type RawExpect (line 11) | type RawExpect = string | string[] | readonly string[];

FILE: client/src/dashboard/SQLEditor/SQLCompletion/getJoinSuggestions.ts
  type Args (line 8) | type Args = {

FILE: client/src/dashboard/SQLEditor/SQLCompletion/getMatch.ts
  type MatchFilter (line 42) | type MatchFilter = (keyof typeof SQLMatchers)[];

FILE: client/src/dashboard/SQLEditor/SQLCompletion/getPGObjects.ts
  type PGDatabase (line 9) | type PGDatabase = {
  type CASCADE (line 23) | type CASCADE =
  type PGConstraint (line 29) | type PGConstraint = {
  type PG_Role (line 47) | type PG_Role = {
  type PG_Index (line 62) | type PG_Index = {
  type PG_Trigger (line 81) | type PG_Trigger = {
  type PG_Rule (line 98) | type PG_Rule = {
  type PG_Policy (line 107) | type PG_Policy = {
  type PG_EventTrigger (line 121) | type PG_EventTrigger = {
  type PG_Extension (line 133) | type PG_Extension = {
  type PG_Keyword (line 141) | type PG_Keyword = {
  type PG_Publication (line 157) | type PG_Publication = {
  type PG_Subscription (line 170) | type PG_Subscription = {
  type PG_Schema (line 186) | type PG_Schema = {
  type PG_Function (line 195) | type PG_Function = {
  function getFuncs (line 232) | async function getFuncs(args: {
  type PG_Table (line 384) | type PG_Table = {
  type TableStats (line 423) | type TableStats = {
  function getTablesViewsAndCols (line 473) | async function getTablesViewsAndCols(
  constant TOP_DATA_TYPES (line 588) | const TOP_DATA_TYPES = [
  type PG_DataType (line 608) | type PG_DataType = {
  function getDataTypes (line 616) | async function getDataTypes(db: DB): Promise<PG_DataType[]> {
  type PG_Setting (line 661) | type PG_Setting = {
  type PGOperator (line 710) | type PGOperator = {
  constant PRIORITISED_OPERATORS (line 719) | const PRIORITISED_OPERATORS = ["=", ">", "LIKE", "ILIKE", "IN"];
  constant PG_OBJECT_QUERIES (line 818) | const PG_OBJECT_QUERIES = {
  type PG_OBJECT_DATA (line 1247) | type PG_OBJECT_DATA = {
  type DB (line 1251) | type DB = { sql: SQLHandler };

FILE: client/src/dashboard/SQLEditor/SQLCompletion/getPrevTokensNoParantheses.ts
  type NestEndMatcher (line 125) | type NestEndMatcher = (t: TokenInfo, i: number) => boolean;

FILE: client/src/dashboard/SQLEditor/SQLCompletion/monacoSQLSetup/registerSuggestions.ts
  type MonacoSuggestion (line 33) | type MonacoSuggestion = PRGLMetaInfo &
  type ParsedSQLSuggestion (line 36) | type ParsedSQLSuggestion = MonacoSuggestion &
  type SQLMatchContext (line 39) | type SQLMatchContext = {
  type GetKind (line 45) | type GetKind = (type: SQLSuggestion["type"]) => number;
  type SuggestionItem (line 46) | type SuggestionItem =
  type SQLMatcherResultType (line 50) | type SQLMatcherResultType = {
  type SQLMatcherResultArgs (line 53) | type SQLMatcherResultArgs = SQLMatchContext & {
  type SQLMatcher (line 62) | type SQLMatcher = {
  type PRGLMetaInfo (line 69) | type PRGLMetaInfo = {
  type Kind (line 74) | type Kind = {
  type Args (line 113) | type Args = {
  constant KNDS (line 236) | let KNDS = {} as Kind;
  function registerSuggestions (line 238) | function registerSuggestions(args: Args) {
  function isUpperCase (line 451) | function isUpperCase(str) {

FILE: client/src/dashboard/SQLEditor/SQLCompletion/suggestColumnLike.ts
  type Args (line 11) | type Args = Pick<

FILE: client/src/dashboard/SQLEditor/SQLCompletion/withKWDs.ts
  type ExpectString (line 17) | type ExpectString = SQLSuggestion["type"] | "condition" | "number" | "st...
  type KWD (line 18) | type KWD = {
  type Opts (line 58) | type Opts = {
  type WithKwdArgs (line 64) | type WithKwdArgs = SQLMatchContext & {

FILE: client/src/dashboard/SQLEditor/SQLEditorSuggestions.ts
  type DB (line 20) | type DB = { sql: SQLHandler };
  type TP (line 417) | type TP = Record<
  constant KEYWORD_TYPED (line 742) | const KEYWORD_TYPED = [

FILE: client/src/dashboard/SQLEditor/SQLSmartEditor.tsx
  type SQLSmartEditorProps (line 14) | type SQLSmartEditorProps = {

FILE: client/src/dashboard/SQLEditor/SQL_SNIPPETS.ts
  constant SQL_SNIPPETS (line 3) | const SQL_SNIPPETS: { label: string; info: string; query: string }[] = [

FILE: client/src/dashboard/SQLEditor/W_SQLEditor.tsx
  constant LANG (line 8) | const LANG = "sql";
  constant SUGGESTION_TYPES (line 24) | const SUGGESTION_TYPES = [
  constant SUGGESTION_TYPE_DOCS (line 52) | const SUGGESTION_TYPE_DOCS: Record<
  constant DB_OBJ_LABELS (line 94) | const DB_OBJ_LABELS: Record<keyof typeof SUGGESTION_TYPES, string> =
  type CodeBlockSignature (line 103) | type CodeBlockSignature = {
  type SQLSuggestion (line 110) | type SQLSuggestion = {
  type MonacoError (line 172) | type MonacoError = Pick<
  type SQLEditorRef (line 224) | type SQLEditorRef = {
  type P (line 230) | type P = {
  type S (line 256) | type S = {
  class W_SQLEditor (line 261) | class W_SQLEditor extends RTComp<P, S> {
    method constructor (line 267) | constructor(props) {
    method onMount (line 275) | onMount() {
    method onUnmount (line 285) | async onUnmount() {
    method canExecuteBlocks (line 380) | get canExecuteBlocks() {
    method editorOptions (line 414) | get editorOptions() {
    method render (line 485) | render() {
  type Args (line 665) | type Args = {
  type HTMLAttributes (line 732) | interface HTMLAttributes<T> {

FILE: client/src/dashboard/SQLEditor/defineCustomMonacoSQLTheme.ts
  constant CUSTOM_MONACO_SQL_THEMES (line 4) | const CUSTOM_MONACO_SQL_THEMES = {
  type TokenColors (line 10) | type TokenColors = {

FILE: client/src/dashboard/SQLEditor/registerFunctionSuggestions.ts
  type GetFuncs (line 13) | type GetFuncs = (
  function registerFunctionSuggestions (line 19) | function registerFunctionSuggestions(

FILE: client/src/dashboard/SampleSchemas.tsx
  type P (line 10) | type P = {

FILE: client/src/dashboard/SchemaGraph/ERDSchema/ERDSchema.tsx
  type ColumnDisplayMode (line 10) | type ColumnDisplayMode = "none" | "all" | "references";
  type ColumnColorMode (line 11) | type ColumnColorMode = "default" | "root" | "on-update" | "on-delete";
  type ERDSchemaProps (line 12) | type ERDSchemaProps = Omit<

FILE: client/src/dashboard/SchemaGraph/ERDSchema/getInitialPlacement.ts
  type Shape (line 10) | type Shape = SchemaShape;

FILE: client/src/dashboard/SchemaGraph/ERDSchema/useDrawSchemaShapes.ts
  type HTMLCanvasElement (line 208) | interface HTMLCanvasElement {

FILE: client/src/dashboard/SchemaGraph/ERDSchema/useSchemaShapes.ts
  type SchemaShape (line 19) | type SchemaShape =

FILE: client/src/dashboard/SchemaGraph/SchemaGraph.tsx
  type SchemaGraphProps (line 16) | type SchemaGraphProps = Pick<Prgl, "connectionId" | "theme"> & {

FILE: client/src/dashboard/SchemaGraph/SchemaGraphControls.tsx
  constant DISPLAY_MODES (line 163) | const DISPLAY_MODES = [
  constant COLUMN_COLOR_MODES (line 169) | const COLUMN_COLOR_MODES = [
  constant COLUMN_FILTER (line 176) | const COLUMN_FILTER = [
  constant CASCADE_LEGEND (line 182) | const CASCADE_LEGEND = {
  type SchemaGraphDisplayMode (line 210) | type SchemaGraphDisplayMode = (typeof DISPLAY_MODES)[number]["key"];

FILE: client/src/dashboard/SchemaGraph/types.ts
  type SchemaGraphNode (line 1) | type SchemaGraphNode = {
  type SchemaGraphLink (line 20) | type SchemaGraphLink = {

FILE: client/src/dashboard/SearchAll/SearchAll.tsx
  constant SEARCH_TYPES (line 13) | const SEARCH_TYPES = [
  type DBObject (line 18) | type DBObject = {
  type SearchAllSuggestion (line 25) | type SearchAllSuggestion = Pick<
  type SearchAllProps (line 33) | type SearchAllProps = Pick<Prgl, "db" | "methods" | "tables"> & {

FILE: client/src/dashboard/SearchAll/SearchAllHeader.tsx
  constant SEARCH_TYPES (line 7) | const SEARCH_TYPES = [

FILE: client/src/dashboard/SearchAll/SearchMatchRow.tsx
  type SearchMatch (line 8) | type SearchMatch = {
  type P (line 12) | type P = {

FILE: client/src/dashboard/SearchAll/hooks/useSearchAllState.ts
  type SearchAllState (line 46) | type SearchAllState = ReturnType<typeof useSearchAllState>;

FILE: client/src/dashboard/SilverGrid/SilverGrid.tsx
  type CustomHeaderClassNames (line 25) | type CustomHeaderClassNames = {
  type ReactSilverGridNode (line 32) | type ReactSilverGridNode = ReactElement<{
  type SilverGridProps (line 38) | type SilverGridProps = {
  type S (line 71) | type S = {
  class SilverGridReact (line 77) | class SilverGridReact extends RTComp<SilverGridProps, S, any> {
    method render (line 460) | render() {
  function isTouchDevice (line 500) | function isTouchDevice() {

FILE: client/src/dashboard/SilverGrid/SilverGridChild.tsx
  type SilverGridChildProps (line 16) | type SilverGridChildProps = {
  type SilverGridChildState (line 45) | type SilverGridChildState = {
  class SilverGridChild (line 50) | class SilverGridChild extends RTComp<
    method onDelta (line 73) | onDelta(
    method siblings (line 284) | get siblings() {
    method render (line 303) | render() {
  type Box (line 391) | type Box = { x: number; y: number; width: number; height: number };

FILE: client/src/dashboard/SilverGrid/SilverGridChildHeader.tsx
  type P (line 17) | type P = SilverGridChildProps & {
  constant TITLE_ID_ATTRNAME (line 46) | const TITLE_ID_ATTRNAME = "data-title-item-id" as const;

FILE: client/src/dashboard/SilverGrid/SilverGridResizer.tsx
  type LayoutSize (line 9) | type LayoutSize = Pick<LayoutItem, "id" | "size">;
  type SilverGridResizerProps (line 11) | type SilverGridResizerProps = {
  class SilverGridResizer (line 17) | class SilverGridResizer extends RTComp<
    method onDelta (line 28) | onDelta() {
    method render (line 95) | render() {

FILE: client/src/dashboard/SilverGrid/TreeBuilder.ts
  type TreeLayout (line 6) | type TreeLayout = LayoutConfig & { parent?: TreeLayout };
  class TreeBuilder (line 7) | class TreeBuilder {
    method constructor (line 10) | constructor(l: LayoutConfig, onChange: (newLayout: LayoutConfig) => vo...
    method build (line 15) | private build(l: LayoutConfig) {

FILE: client/src/dashboard/SmartCard/SmartCard.tsx
  type NestedSmartCardProps (line 18) | type NestedSmartCardProps = Pick<SmartCardProps, "footer" | "excludeNull...
  type NestedSmartFormProps (line 19) | type NestedSmartFormProps = Pick<
  type FieldConfigTable (line 24) | type FieldConfigTable = FieldConfigBase & {
  type FieldConfigNested (line 35) | type FieldConfigNested = FieldConfig<any> | FieldConfigTable;
  type ParsedNestedFieldConfig (line 37) | type ParsedNestedFieldConfig = ParsedFieldConfig | FieldConfigTable;
  type FieldConfigBase (line 39) | type FieldConfigBase<T extends AnyObject | void = void> = {
  type FieldConfigRender (line 49) | type FieldConfigRender<T extends AnyObject = AnyObject> = (
  type ParsedFieldConfig (line 54) | type ParsedFieldConfig<T extends AnyObject = AnyObject> =
  type FieldConfig (line 66) | type FieldConfig<T extends AnyObject = AnyObject> =
  type SmartCardCommonProps (line 70) | type SmartCardCommonProps = {};
  type SmartCardProps (line 72) | type SmartCardProps<T extends AnyObject = AnyObject> = Pick<
  constant DEFAULT_VARIANT (line 120) | const DEFAULT_VARIANT = "row-wrap";

FILE: client/src/dashboard/SmartCard/SmartCardColumn.tsx
  type SmartCardColumnProps (line 6) | type SmartCardColumnProps = {

FILE: client/src/dashboard/SmartCard/getSmartCardColumns.ts
  type Args (line 4) | type Args = Pick<SmartCardListProps<AnyObject>, "tableName" | "db">;

FILE: client/src/dashboard/SmartCardList/SmartCardList.tsx
  type SmartCardListProps (line 26) | type SmartCardListProps<T extends AnyObject = AnyObject> = Pick<

FILE: client/src/dashboard/SmartCardList/SmartCardListJoinedNewRecords.tsx
  type P (line 19) | type P = Pick<Prgl, "db" | "tables" | "methods"> &

FILE: client/src/dashboard/SmartCardList/useSmartCardListState.ts
  type SmartCardListState (line 9) | type SmartCardListState = ReturnType<typeof useSmartCardListState>;

FILE: client/src/dashboard/SmartFilter/AddJoinFilter.tsx
  type JoinOpts (line 17) | type JoinOpts = { path: JoinV2[]; type: DetailedJoinedFilter["type"] };
  type AddJoinFilterProps (line 18) | type AddJoinFilterProps = {
  constant JOIN_FILTER_TYPES (line 26) | const JOIN_FILTER_TYPES = [

FILE: client/src/dashboard/SmartFilter/MinimisedFilter.tsx
  type P (line 10) | type P = FilterWrapperProps &

FILE: client/src/dashboard/SmartFilter/SmartAddFilter.tsx
  type SmartAddFilterProps (line 29) | type SmartAddFilterProps = {

FILE: client/src/dashboard/SmartFilter/SmartFilter.tsx
  type Operand (line 17) | type Operand = "AND" | "OR";
  type SmartFilterProps (line 18) | type SmartFilterProps = Pick<FilterWrapperProps, "variant"> & {

FILE: client/src/dashboard/SmartFilter/SmartSearch/SmartSearch.tsx
  type SmartSearchOnChangeArgs (line 19) | type SmartSearchOnChangeArgs = {
  type P (line 35) | type P = {
  type S (line 83) | type S = {
  class SmartSearch (line 88) | class SmartSearch extends RTComp<P, S> {
    method filterableCols (line 99) | get filterableCols(): Pick<
    method defaultValue (line 128) | get defaultValue() {
    method column (line 137) | get column() {
    method render (line 150) | render() {

FILE: client/src/dashboard/SmartFilter/SmartSearch/getSmartSearchRows.ts
  type Args (line 16) | type Args = {
  type SmartSearchResultRows (line 29) | type SmartSearchResultRows = {

FILE: client/src/dashboard/SmartFilter/SmartSearch/onSearchItems.tsx
  function onSearchItems (line 12) | async function onSearchItems(

FILE: client/src/dashboard/SmartFilter/SortByControl.tsx
  type SortByControlProps (line 8) | type SortByControlProps = Pick<

FILE: client/src/dashboard/SmartFilter/smartFilterUtils.ts
  type TableColumn (line 44) | type TableColumn = ValidatedColumnInfo & {
  type ComputedColumn (line 47) | type ComputedColumn = Pick<
  type FilterColumn (line 56) | type FilterColumn = TableColumn | ComputedColumn;
  type BaseFilterProps (line 58) | type BaseFilterProps = Pick<FilterWrapperProps, "variant"> & {
  constant DEFAULT_VALIDATED_COLUMN_INFO (line 80) | const DEFAULT_VALIDATED_COLUMN_INFO = {

FILE: client/src/dashboard/SmartFilterBar/SmartFilterBar.tsx
  type SmartFilterBarProps (line 26) | type SmartFilterBarProps = PrglCore & {

FILE: client/src/dashboard/SmartFilterBar/SmartFilterBarFilters.tsx
  type P (line 8) | type P = Pick<SmartFilterBarProps, "db" | "tables" | "extraFilters"> & {

FILE: client/src/dashboard/SmartFilterBar/SmartFilterBarSearch.tsx
  type P (line 11) | type P = Pick<SmartFilterBarProps, "db" | "tables" | "style"> & {

FILE: client/src/dashboard/SmartFilterBar/SmartFilterBarSort.tsx
  type P (line 12) | type P = SmartFilterBarProps & {

FILE: client/src/dashboard/SmartForm/ChipArrayEditor.tsx
  type P (line 11) | type P = {
  type InputChipProps (line 115) | type InputChipProps = Pick<P, "elemTsType" | "elemUdtName" | "inputType"...

FILE: client/src/dashboard/SmartForm/InsertButton.tsx
  type InsertButtonProps (line 10) | type InsertButtonProps = {

FILE: client/src/dashboard/SmartForm/JoinedRecords/JoinedRecords.tsx
  type JoinedRecordsProps (line 17) | type JoinedRecordsProps = Pick<Prgl, "db" | "tables" | "methods"> &

FILE: client/src/dashboard/SmartForm/JoinedRecords/JoinedRecordsAddRow.tsx
  type P (line 10) | type P = Omit<JoinedRecordsProps, "newRowDataHandler"> & {

FILE: client/src/dashboard/SmartForm/JoinedRecords/useJoinedRecordsSections.ts
  type JoinedRecordSection (line 24) | type JoinedRecordSection = {

FILE: client/src/dashboard/SmartForm/SmartForm.tsx
  type getErrorsHook (line 24) | type getErrorsHook = (
  type GetRefHooks (line 30) | type GetRefHooks = {
  type GetRefCB (line 37) | type GetRefCB = (hooks: GetRefHooks) => void;
  type ColumnDisplayConfig (line 39) | type ColumnDisplayConfig = {
  type SmartFormProps (line 45) | type SmartFormProps = Pick<Prgl, "db" | "tables" | "methods"> & {
  type SmartFormColumnConfig (line 166) | type SmartFormColumnConfig =

FILE: client/src/dashboard/SmartForm/SmartFormField/RenderValue.tsx
  type P (line 10) | type P = {

FILE: client/src/dashboard/SmartForm/SmartFormField/SmartFormField.tsx
  type SmartFormFieldValue (line 40) | type SmartFormFieldValue =
  type SmartFormFieldProps (line 49) | type SmartFormFieldProps = Pick<
  type SmartColumnInfo (line 74) | type SmartColumnInfo = DBSchemaTableColumn & ColumnDisplayConfig;

FILE: client/src/dashboard/SmartForm/SmartFormField/SmartFormFieldFileSection.tsx
  type P (line 8) | type P = {

FILE: client/src/dashboard/SmartForm/SmartFormField/SmartFormFieldForeignKey.tsx
  type SmartFormFieldForeignKeyProps (line 25) | type SmartFormFieldForeignKeyProps = Pick<

FILE: client/src/dashboard/SmartForm/SmartFormField/SmartFormFieldLinkedData.tsx
  type SmartFormFieldLinkedDataProps (line 14) | type SmartFormFieldLinkedDataProps = Pick<
  type SmartFieldForeignKeyOptionsState (line 155) | type SmartFieldForeignKeyOptionsState = ReturnType<
  type SmartFormFieldLinkedDataInsertState (line 200) | type SmartFormFieldLinkedDataInsertState = {

FILE: client/src/dashboard/SmartForm/SmartFormField/SmartFormFieldLinkedDataInsert/SmartFormFieldLinkedDataInsert.tsx
  type P (line 13) | type P = Pick<

FILE: client/src/dashboard/SmartForm/SmartFormField/SmartFormFieldLinkedDataInsert/useSmartFormFieldLinkedDataInsert.tsx
  type P (line 6) | type P = Pick<SmartFormFieldLinkedDataProps, "column" | "action"> & {

FILE: client/src/dashboard/SmartForm/SmartFormField/SmartFormFieldLinkedDataSearch.tsx
  type P (line 12) | type P = Pick<

FILE: client/src/dashboard/SmartForm/SmartFormField/SmartFormFieldRightButtons.tsx
  type P (line 8) | type P = Omit<SmartFormFieldProps, "onChange"> & {

FILE: client/src/dashboard/SmartForm/SmartFormField/ViewMoreSmartCardList.tsx
  type ViewMoreSmartCardListProps (line 13) | type ViewMoreSmartCardListProps = Pick<

FILE: client/src/dashboard/SmartForm/SmartFormField/fetchColumnValueSuggestions.ts
  constant OPTIONS_LIMIT (line 6) | const OPTIONS_LIMIT = 20;

FILE: client/src/dashboard/SmartForm/SmartFormField/fetchForeignKeyOptions.tsx
  type FetchForeignKeyOptionsArgs (line 19) | type FetchForeignKeyOptionsArgs = Pick<
  type GetRootFkeyTableArgs (line 26) | type GetRootFkeyTableArgs = Pick<
  type Args (line 224) | type Args = {
  constant OPTIONS_LIMIT (line 338) | const OPTIONS_LIMIT = 20;

FILE: client/src/dashboard/SmartForm/SmartFormField/fieldUtils.ts
  type PG_T (line 219) | type PG_T = keyof typeof PG_Types;

FILE: client/src/dashboard/SmartForm/SmartFormField/useFormData.ts
  type InsertData (line 113) | type InsertData = {

FILE: client/src/dashboard/SmartForm/SmartFormField/useSmartFormFieldAsJSON.tsx
  type P (line 14) | type P = Pick<
  type AsJSON (line 19) | type AsJSON = {

FILE: client/src/dashboard/SmartForm/SmartFormFieldList.tsx
  type P (line 21) | type P = Pick<

FILE: client/src/dashboard/SmartForm/SmartFormFileSection.tsx
  type P (line 10) | type P = {

FILE: client/src/dashboard/SmartForm/SmartFormFooter/SmartFormFooterButtons.tsx
  type P (line 13) | type P = SmartFormState &

FILE: client/src/dashboard/SmartForm/SmartFormFooter/useSmartFormActions.ts
  type ConfirmationPopup (line 9) | type ConfirmationPopup = Pick<
  type Args (line 14) | type Args = Pick<
  type SmartFormActionsState (line 265) | type SmartFormActionsState = ReturnType<typeof useSmartFormActions>;

FILE: client/src/dashboard/SmartForm/SmartFormNewRowDataHandler.ts
  type NewRow (line 10) | type NewRow = Record<string, ColumnData>;
  type Opts (line 12) | type Opts = {
  class NewRowDataHandler (line 20) | class NewRowDataHandler {
    method constructor (line 24) | constructor(newRow: NewRow | undefined, opts: Opts) {
  type ColumnData (line 143) | type ColumnData =

FILE: client/src/dashboard/SmartForm/SmartFormPopup/SmartFormPopupWrapper.tsx
  type P (line 17) | type P = Pick<SmartFormProps, "onPrevOrNext" | "prevNext" | "asPopup"> & {

FILE: client/src/dashboard/SmartForm/SmartFormUpperFooter/SmartFormUpperFooter.tsx
  type SmartFormUpperFooterProps (line 12) | type SmartFormUpperFooterProps = Omit<SmartFormProps, "columns"> &

FILE: client/src/dashboard/SmartForm/useNewRowDataHandler.ts
  type Args (line 25) | type Args = {
  type SmartFormNewRowState (line 382) | type SmartFormNewRowState = ReturnType<typeof useNewRowDataHandler>;

FILE: client/src/dashboard/SmartForm/useSmartForm.ts
  type SmartFormState (line 16) | type SmartFormState = {

FILE: client/src/dashboard/SmartForm/useSmartFormColumns.ts
  type UseSmartFormColumnsProps (line 10) | type UseSmartFormColumnsProps = Pick<
  type SmartFormColumnState (line 127) | type SmartFormColumnState = ReturnType<typeof useSmartFormColumns>;

FILE: client/src/dashboard/SmartForm/useSmartFormMode.ts
  type SmartFormMode (line 15) | type SmartFormMode =
  type ModeOrError (line 54) | type ModeOrError = SmartFormMode | string;
  type SmartFormModeState (line 56) | type SmartFormModeState = Omit<

FILE: client/src/dashboard/SmartSelect.tsx
  type SmartSelectProps (line 22) | type SmartSelectProps<

FILE: client/src/dashboard/SmartTable.tsx
  type SmartTableProps (line 25) | type SmartTableProps = Pick<Prgl, "db" | "tables" | "methods"> & {
  type S (line 47) | type S = {
  class SmartTable (line 58) | class SmartTable extends RTComp<SmartTableProps, S> {
    method columns (line 78) | get columns(): ProstglesColumn[] {
    method onMount (line 129) | onMount() {
    method onUnmount (line 133) | async onUnmount() {
    method onDelta (line 138) | onDelta(deltaP: Partial<SmartTableProps> | undefined): void {
    method filter (line 171) | get filter() {
    method render (line 214) | render() {

FILE: client/src/dashboard/StatusMonitor/StatusMonitor.tsx
  type StatusMonitorProps (line 8) | type StatusMonitorProps = Pick<

FILE: client/src/dashboard/StatusMonitor/StatusMonitorConnections.tsx
  type P (line 11) | type P = Pick<StatusMonitorProps, "dbsMethods" | "connectionId"> & {

FILE: client/src/dashboard/StatusMonitor/StatusMonitorProcList.tsx
  type StatusMonitorViewType (line 32) | type StatusMonitorViewType =
  type FieldConfigs (line 154) | type FieldConfigs = Required<SmartCardListProps>["fieldConfigs"];

FILE: client/src/dashboard/StatusMonitor/StatusMonitorProcListControlsHeader.tsx
  type P (line 12) | type P = StatusMonitorProps & {

FILE: client/src/dashboard/TableConfig/ProcessLogs.tsx
  type P (line 15) | type P = Pick<Prgl, "dbsMethods" | "connectionId" | "dbs"> & {

FILE: client/src/dashboard/TableConfig/TableConfig.tsx
  type P (line 8) | type P = {

FILE: client/src/dashboard/TimeSeries.tsx
  type P (line 4) | type P = {
  class TimeSeries (line 16) | class TimeSeries extends RTComp<P, any> {
    method onMount (line 20) | onMount() {
    method render (line 25) | render() {

FILE: client/src/dashboard/UserManager.tsx
  type Users (line 11) | type Users = {
  type S (line 21) | type S = {
  class UserManager (line 26) | class UserManager extends RTComp<ExtraProps, S> {
    method onUnmount (line 44) | onUnmount() {}
    method render (line 46) | render() {

FILE: client/src/dashboard/W_Barchart/W_Barchart.tsx
  type W_BarchartProps (line 13) | type W_BarchartProps = Omit<CommonWindowProps, "w"> & {

FILE: client/src/dashboard/W_Map/OSM/OverpassQuery.tsx
  type P (line 4) | type P = {

FILE: client/src/dashboard/W_Map/OSM/getOSMData.ts
  constant OVERPASS_URL (line 5) | const OVERPASS_URL = "https://overpass-api.de/api/interpreter";
  type OSMElementType (line 7) | type OSMElementType = "node" | "way" | "relation";
  type OSMElementBase (line 9) | type OSMElementBase = {
  type OSMNode (line 15) | type OSMNode = OSMElementBase & {
  type OSMWay (line 21) | type OSMWay = Omit<OSMElementBase, "type"> & {
  type OSMRelationMemberWay (line 26) | type OSMRelationMemberWay = {
  type OSMRelationMemberNode (line 31) | type OSMRelationMemberNode = {
  type OSMRelationMember (line 36) | type OSMRelationMember = OSMRelationMemberWay | OSMRelationMemberNode;
  type OSMRelation (line 38) | type OSMRelation = OSMElementBase & {
  type OSMElement (line 43) | type OSMElement = OSMNode | OSMWay | OSMRelation;

FILE: client/src/dashboard/W_Map/W_Map.tsx
  type LayerBase (line 37) | type LayerBase = {
  type LayerOSM (line 68) | type LayerOSM = LayerBase & {
  type LayerSQL (line 73) | type LayerSQL = LayerBase & {
  type LayerTable (line 80) | type LayerTable = LayerBase & {
  type LayerQuery (line 97) | type LayerQuery = LayerTable | LayerSQL | LayerOSM;
  type W_MapProps (line 99) | type W_MapProps = CommonWindowProps<"map"> & {
  type MapLayerExtras (line 105) | type MapLayerExtras = Record<
  type ClickedItem (line 110) | type ClickedItem = GeoJSONFeature & {
  type W_MapState (line 132) | type W_MapState = {
  type D (line 154) | type D = {
  class W_Map (line 158) | class W_Map extends RTComp<W_MapProps, W_MapState, D> {
    method getDataSignature (line 178) | getDataSignature(
    method onMount (line 195) | onMount() {
    method onUnmount (line 204) | onUnmount() {
    method render (line 408) | render() {

FILE: client/src/dashboard/W_Map/W_MapMenu.tsx
  constant MAP_PROJECTIONS (line 22) | const MAP_PROJECTIONS = ["mercator", "orthographic"] as const;
  type ProstglesMapMenuProps (line 24) | type ProstglesMapMenuProps = W_MapProps & {

FILE: client/src/dashboard/W_Map/controls/MapBasemapOptions.tsx
  type P (line 19) | type P = {

FILE: client/src/dashboard/W_Map/controls/MapInfoSection.tsx
  type P (line 8) | type P = {

FILE: client/src/dashboard/W_Map/controls/MapOSMQuery.tsx
  type DataType (line 18) | type DataType = keyof typeof predefinedOsmQueries;
  type MapOSMQueryOSMQueryProps (line 47) | type MapOSMQueryOSMQueryProps = {

FILE: client/src/dashboard/W_Map/controls/MapOpacityMenu.tsx
  type P (line 7) | type P = {

FILE: client/src/dashboard/W_Map/fetchData/fetchMapLayerData.ts
  constant DEFAULT_GET_COLOR (line 16) | const DEFAULT_GET_COLOR: Pick<

FILE: client/src/dashboard/W_Map/fetchData/getMapData.ts
  constant WITH_LAST_SELECT_ALIAS (line 13) | const WITH_LAST_SELECT_ALIAS = "prostgles_chart_data";
  constant MAP_SELECT_COLUMNS (line 41) | const MAP_SELECT_COLUMNS = {
  type MapDataResult (line 46) | type MapDataResult = {

FILE: client/src/dashboard/W_Map/fetchData/getMapLayerQueries.ts
  type Args (line 17) | type Args = {

FILE: client/src/dashboard/W_Map/onMapHover.ts
  type HoveredObject (line 9) | type HoveredObject = {
  function onMapHover (line 22) | function onMapHover(

FILE: client/src/dashboard/W_Method/NewMethod.tsx
  type Method (line 9) | type Method = DBSSchema["published_methods"] & {
  type P (line 13) | type P = Pick<

FILE: client/src/dashboard/W_Method/PublishedMethods.tsx
  type P (line 22) | type P = {

FILE: client/src/dashboard/W_Method/W_Method.tsx
  type W_MethodProps (line 10) | type W_MethodProps = Omit<CommonWindowProps, "w"> & {

FILE: client/src/dashboard/W_Method/W_MethodControls.tsx
  type P (line 22) | type P = Pick<Prgl, "db" | "methods" | "tables"> & {

FILE: client/src/dashboard/W_QuickMenu.tsx
  type ProstglesQuickMenuProps (line 21) | type ProstglesQuickMenuProps = Pick<

FILE: client/src/dashboard/W_SQL/CSVRender.tsx
  type P (line 7) | type P = Pick<W_SQLState, "cols" | "rows">;

FILE: client/src/dashboard/W_SQL/CopyResultBtn.tsx
  type Outputs (line 31) | type Outputs = {

FILE: client/src/dashboard/W_SQL/TestSQL.ts
  constant VIDEO_DEMO_DB_NAME (line 13) | const VIDEO_DEMO_DB_NAME = "prostgles_video_demo";

FILE: client/src/dashboard/W_SQL/W_SQL.tsx
  type W_SQLProps (line 48) | type W_SQLProps = Omit<CommonWindowProps, "w"> & {
  constant SQL_NOT_ALLOWED (line 59) | const SQL_NOT_ALLOWED =
  type ProstglesColumn (line 62) | type ProstglesColumn = TableColumn & { computed: boolean } & Pick<
  type W_SQL_ActiveQuery (line 67) | type W_SQL_ActiveQuery = {
  type SQLResultCols (line 99) | type SQLResultCols = Required<W_SQLProps>["w"]["options"]["sqlResultCols"];
  type W_SQLState (line 101) | type W_SQLState = {
  type D (line 162) | type D = {
  class W_SQL (line 168) | class W_SQL extends RTComp<W_SQLProps, W_SQLState, D> {
    method onMount (line 197) | onMount() {
    method onUnmount (line 234) | async onUnmount() {
    method saveQuery (line 247) | saveQuery() {
    method render (line 319) | render() {
  function download (line 605) | function download(
  type CounterProps (line 630) | type CounterProps = TestSelectors & {

FILE: client/src/dashboard/W_SQL/W_SQLBottomBar/W_SQLBottomBar.tsx
  type W_SQLBottomBarProps (line 40) | type W_SQLBottomBarProps = {
  function hideKeyboard (line 460) | function hideKeyboard(element: HTMLElement) {

FILE: client/src/dashboard/W_SQL/W_SQLMenu.tsx
  type P (line 40) | type P = {
  constant REFRESH_OPTIONS (line 52) | const REFRESH_OPTIONS = ["Realtime", "Custom", "None"] as const;
  type Unpromise (line 53) | type Unpromise<T extends Promise<any>> =
  type RefreshOptions (line 56) | type RefreshOptions = {
  type S (line 61) | type S = {
  type D (line 87) | type D = {
  class ProstglesSQLMenu (line 91) | class ProstglesSQLMenu extends RTComp<P, S, D> {
    method render (line 135) | render() {
  function getFileText (line 375) | function getFileText(file: File): Promise<string> {
  function sha256 (line 388) | async function sha256(message) {

FILE: client/src/dashboard/W_SQL/W_SQLResults.tsx
  type W_SQLResultsProps (line 13) | type W_SQLResultsProps = Pick<

FILE: client/src/dashboard/W_SQL/customRenderers.tsx
  constant SHORT_NAMES (line 6) | const SHORT_NAMES = [
  type PG_Interval (line 17) | type PG_Interval = Partial<
  type StyledIntervalProps (line 59) | type StyledIntervalProps = {

FILE: client/src/dashboard/W_SQL/demoScripts/mainTestScripts.ts
  constant SQL_TESTING_SCRIPTS (line 247) | const SQL_TESTING_SCRIPTS = {
  type SqlTestingScripts (line 267) | type SqlTestingScripts = typeof SQL_TESTING_SCRIPTS;

FILE: client/src/dashboard/W_SQL/getChartableSQL.ts
  type ChartableSQL (line 12) | type ChartableSQL = {

FILE: client/src/dashboard/W_SQL/getDemoUtils.ts
  type TypeOpts (line 7) | type TypeOpts = {
  type TypeAutoOpts (line 12) | type TypeAutoOpts = {
  type DemoUtils (line 45) | type DemoUtils = ReturnType<typeof getDemoUtils>;
  type DemoScript (line 46) | type DemoScript = (utils: DemoUtils) => Promise<void>;

FILE: client/src/dashboard/W_SQL/monacoEditorTypes.ts
  type Monaco (line 1) | type Monaco = typeof import(

FILE: client/src/dashboard/W_SQL/runSQL/runSQL.ts
  function runSQL (line 16) | async function runSQL(this: W_SQL, sort: ColumnSortSQL[] = []) {
  function hashFnv32a (line 410) | function hashFnv32a(str, asString, seed?) {

FILE: client/src/dashboard/W_Table/CardView/CardView.tsx
  type CardViewProps (line 17) | type CardViewProps = {
  type IndexedRow (line 31) | type IndexedRow = {

FILE: client/src/dashboard/W_Table/CardView/CardViewColumn.tsx
  type CardViewColumnProps (line 7) | type CardViewColumnProps = Pick<

FILE: client/src/dashboard/W_Table/CardView/CardViewKanban.tsx
  constant MAX_NUMBER_OF_GROUPS (line 10) | const MAX_NUMBER_OF_GROUPS = 20;
  type P (line 11) | type P = Pick<CardViewProps, "state"> &

FILE: client/src/dashboard/W_Table/CardView/CardViewRow.tsx
  type CardViewRowProps (line 13) | type CardViewRowProps = Pick<
  type KanBanDraggedRow (line 33) | type KanBanDraggedRow = IndexedRow & {

FILE: client/src/dashboard/W_Table/CardView/DragHeader.tsx
  type DragHeaderProps (line 8) | type DragHeaderProps = Pick<

FILE: client/src/dashboard/W_Table/CardView/useCardViewState.ts
  type CardViewState (line 50) | type CardViewState = ReturnType<typeof useCardViewState>;

FILE: client/src/dashboard/W_Table/ColumnMenu/AddColumnMenu.tsx
  type AddColumnMenuProps (line 54) | type AddColumnMenuProps = {

FILE: client/src/dashboard/W_Table/ColumnMenu/AddComputedColumn/AddComputedColMenu.tsx
  type AddComputedColMenuP (line 40) | type AddComputedColMenuP = Pick<Prgl, "db"> & {
  type AddComputedColMenuS (line 51) | type AddComputedColMenuS = {
  class AddComputedColMenu (line 69) | class AddComputedColMenu extends RTComp<
    method onDelta (line 78) | onDelta(deltaP?: Partial<AddComputedColMenuP>): void {
    method table (line 119) | get table() {
    method render (line 124) | render() {

FILE: client/src/dashboard/W_Table/ColumnMenu/AddComputedColumn/FunctionColumnList.tsx
  type P (line 9) | type P = Pick<

FILE: client/src/dashboard/W_Table/ColumnMenu/AddComputedColumn/QuickAddComputedColumn.tsx
  type QuickAddComputedColumnProps (line 15) | type QuickAddComputedColumnProps = {

FILE: client/src/dashboard/W_Table/ColumnMenu/AddComputedColumn/useAddComputedColumn.ts
  type ValidatedColumnInfoWithJoin (line 169) | type ValidatedColumnInfoWithJoin = ValidatedColumnInfo & {
  type AddComputedColumnState (line 173) | type AddComputedColumnState = ReturnType<

FILE: client/src/dashboard/W_Table/ColumnMenu/AlterColumn/AlterColumn.tsx
  type AlterColumnProps (line 23) | type AlterColumnProps = Pick<CommonWindowProps, "suggestions"> & {
  type S (line 30) | type S = {
  method onDeltaCombined (line 85) | onDeltaCombined(delta: DeltaOf<AlterColumnProps> & DeltaOf<S>) {

FILE: client/src/dashboard/W_Table/ColumnMenu/AlterColumn/AlterColumnFileOptions.tsx
  type P (line 10) | type P = Pick<Prgl, "db" | "tables" | "dbsMethods" | "dbs" | "connection...

FILE: client/src/dashboard/W_Table/ColumnMenu/AlterColumn/ColumnEditor.tsx
  type ColumnOptions (line 22) | type ColumnOptions = {
  type P (line 31) | type P = Pick<CommonWindowProps, "suggestions"> &
  type Item (line 68) | type Item = { key: string; label: string; subLabel?: string };

FILE: client/src/dashboard/W_Table/ColumnMenu/AlterColumn/CreateColumn.tsx
  type CreateColumnProps (line 16) | type CreateColumnProps = Pick<CommonWindowProps, "suggestions"> & {

FILE: client/src/dashboard/W_Table/ColumnMenu/AlterColumn/ReferenceEditor.tsx
  constant FKEY_DOCS (line 14) | const FKEY_DOCS =
  type ColumnReference (line 17) | type ColumnReference = {
  type ReferenceEditorProps (line 23) | type ReferenceEditorProps = ColumnReference & {
  type P (line 78) | type P = ColumnOptions & {
  type ReferencedColumn (line 134) | type ReferencedColumn = {
  type AddColumnReferenceProps (line 138) | type AddColumnReferenceProps = {

FILE: client/src/dashboard/W_Table/ColumnMenu/AlterColumn/alterColumnUtilts.ts
  type ColumnConstraint (line 3) | type ColumnConstraint = {

FILE: client/src/dashboard/W_Table/ColumnMenu/ColorPicker.tsx
  type S (line 16) | type S = {
  class ColorPicker (line 20) | class ColorPicker extends React.Component<
    method render (line 65) | render() {
  constant COLORS (line 206) | const COLORS = {
  constant COLOR_PALETTE (line 218) | const COLOR_PALETTE = Object.values(COLORS);
  constant COLOR_PALETTE_RGB (line 220) | const COLOR_PALETTE_RGB = COLOR_PALETTE.map(

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnDisplayFormat/ChipStylePalette.tsx
  type ChipStylePaletteProps (line 5) | type ChipStylePaletteProps = {
  constant CHIP_COLOR_NAMES (line 81) | const CHIP_COLOR_NAMES = {

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnDisplayFormat/ColumnDisplayFormat.tsx
  type P (line 11) | type P = {

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnDisplayFormat/ConditionalCellIconStyleControls.tsx
  type P (line 13) | type P = StyleColumnProps & {

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnDisplayFormat/ConditionalCellStyleControls.tsx
  constant CONDITION_OPERATORS (line 17) | const CONDITION_OPERATORS = [
  type P (line 31) | type P = StyleColumnProps & {

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnDisplayFormat/NestedColumnRender.tsx
  constant NESTED_LIMIT (line 16) | const NESTED_LIMIT = 10;
  type NestedTimeChartMeta (line 18) | type NestedTimeChartMeta = {
  type P (line 22) | type P = {

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnDisplayFormat/columnFormatUtils.tsx
  type ColumnFormat (line 219) | type ColumnFormat = JSONB.GetSchemaType<typeof ColumnFormatSchema>;
  type ColumnRenderer (line 227) | type ColumnRenderer = {
  type FormattedColRender (line 240) | type FormattedColRender<F extends ColumnFormat> = Pick<
  constant DISPLAY_FORMATS (line 283) | const DISPLAY_FORMATS = [
  function getFormatOptions (line 439) | function getFormatOptions(

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnList.tsx
  type P (line 22) | type P = {

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnMenu.tsx
  type ColumnConfig (line 67) | type ColumnConfig = {
  type P (line 127) | type P = Pick<CommonWindowProps, "suggestions" | "tables" | "prgl"> & {
  type ColumnSortSQL (line 134) | type ColumnSortSQL = {
  type ColumnSort (line 140) | type ColumnSort = Omit<ColumnSortSQL, "key"> & {

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnQuickStats/ColumnQuickStats.tsx
  type ColumnQuickStatsProps (line 14) | type ColumnQuickStatsProps = {

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnSelect/ColumnSelect.tsx
  type P (line 18) | type P = TestSelectors & {

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnSortMenu.tsx
  constant SORT_NULLS_OPTIONS (line 12) | const SORT_NULLS_OPTIONS = [
  constant SORT_OPTIONS (line 18) | const SORT_OPTIONS = [
  type ColumnSortMenuProps (line 24) | type ColumnSortMenuProps = {

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnStyleControls/ColumnStyleControls.tsx
  type ColumnValue (line 17) | type ColumnValue = string | number | Date | null | undefined | boolean;
  type BasicConditionFilter (line 19) | type BasicConditionFilter = {
  type ConditionFilter (line 24) | type ConditionFilter =
  type ChipStyle (line 31) | type ChipStyle = {
  type ConditionalStyle (line 38) | type ConditionalStyle = {
  type ConditionalStyleIcons (line 43) | type ConditionalStyleIcons = {
  type FixedStyle (line 48) | type FixedStyle = {
  type ScaleStyle (line 52) | type ScaleStyle = {
  type BarchartStyle (line 58) | type BarchartStyle = {
  type StyleColumnProps (line 64) | type StyleColumnProps = Pick<Prgl, "db" | "tables"> & {

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnStyleControls/getValueColors.ts
  type DefaultConditionalStyleArgs (line 7) | type DefaultConditionalStyleArgs =

FILE: client/src/dashboard/W_Table/ColumnMenu/ColumnsMenu.tsx
  type P (line 25) | type P = {
  type S (line 34) | type S = {
  class ColumnsMenu (line 44) | class ColumnsMenu extends RTComp<P, S> {
    method tableName (line 62) | get tableName() {
    method render (line 73) | render() {

FILE: client/src/dashboard/W_Table/ColumnMenu/FunctionSelector/FunctionExtraArguments.tsx
  type FuncArgs (line 13) | type FuncArgs = NonNullable<
  type P (line 17) | type P = {

FILE: client/src/dashboard/W_Table/ColumnMenu/FunctionSelector/FunctionSelector.tsx
  type P (line 13) | type P = {

FILE: client/src/dashboard/W_Table/ColumnMenu/FunctionSelector/functions.ts
  type FuncDef (line 14) | type FuncDef = {
  constant FUCTION_DEFINITIONS (line 438) | const FUCTION_DEFINITIONS = [...getAggFuncs(), ...getFuncs()];

FILE: client/src/dashboard/W_Table/ColumnMenu/JoinPathSelectorV2.tsx
  type P (line 13) | type P = {

FILE: client/src/dashboard/W_Table/ColumnMenu/LinkedColumn/LinkedColumn.tsx
  type LinkedColumnProps (line 23) | type LinkedColumnProps = {
  constant JOIN_TYPES (line 29) | const JOIN_TYPES = [
  constant NESTED_COLUMN_DISPLAY_MODES (line 42) | const NESTED_COLUMN_DISPLAY_MODES = [

FILE: client/src/dashboard/W_Table/ColumnMenu/LinkedColumn/LinkedColumnFooter.tsx
  constant NEW_COL_POSITIONS (line 11) | const NEW_COL_POSITIONS = [
  type P (line 16) | type P = LinkedColumnProps & {

FILE: client/src/dashboard/W_Table/ColumnMenu/LinkedColumn/LinkedColumnSelect.tsx
  type P (line 19) | type P = LinkedColumnProps & {

FILE: client/src/dashboard/W_Table/ColumnMenu/NestedTimechartControls.tsx
  constant SORTABLE_CHART_COLUMNS (line 16) | const SORTABLE_CHART_COLUMNS = ["date", "value"];
  type ColTimeChart (line 18) | type ColTimeChart = Required<ColumnConfigWInfo>["nested"]["chart"];
  type P (line 19) | type P = {

FILE: client/src/dashboard/W_Table/ColumnMenu/SummariseColumns.tsx
  type SummariseColumnProps (line 11) | type SummariseColumnProps = {

FILE: client/src/dashboard/W_Table/ColumnMenu/getNestedColumnTable.ts
  type Result (line 9) | type Result = {
  type ErrorResult (line 14) | type ErrorResult = Partial<Record<keyof Result, undefined>>;
  type MaybeResult (line 16) | type MaybeResult =
  type NestedColumnOpts (line 20) | type NestedColumnOpts =

FILE: client/src/dashboard/W_Table/ColumnMenu/rgba2hex.ts
  function rgba2hex (line 1) | function rgba2hex(color: string): string {

FILE: client/src/dashboard/W_Table/JoinPathSelector/JoinPathItem.tsx
  type JoinPathItemProps (line 10) | type JoinPathItemProps = JoinV2 & {

FILE: client/src/dashboard/W_Table/JoinPathSelector/JoinPathSelector.tsx
  type P (line 11) | type P = {

FILE: client/src/dashboard/W_Table/JoinPathSelector/getJoinTree.ts
  type JoinTree (line 3) | type JoinTree = {

FILE: client/src/dashboard/W_Table/RowCard.tsx
  type RowPanelProps (line 12) | type RowPanelProps =
  type RowCardProps (line 24) | type RowCardProps = Pick<CommonWindowProps, "prgl"> & {

FILE: client/src/dashboard/W_Table/TableMenu/AddChartMenu.tsx
  type P (line 26) | type P = Pick<CommonWindowProps, "myLinks" | "childWindows"> & {

FILE: client/src/dashboard/W_Table/TableMenu/W_TableMenu.tsx
  type W_TableMenuProps (line 44) | type W_TableMenuProps = Pick<
  type Unpromise (line 55) | type Unpromise<T extends Promise<any>> =
  type RefreshOptions (line 58) | type RefreshOptions = {
  type W_TableMenuState (line 65) | type W_TableMenuState = {
  type D (line 99) | type D = {
  type W_TableMenuMetaProps (line 103) | type W_TableMenuMetaProps = W_TableMenuProps & {
  class W_TableMenu (line 108) | class W_TableMenu extends RTComp<W_TableMenuProps, W_TableMenuState, D> {
    method getTableInfo (line 133) | getTableInfo() {
    method render (line 169) | render() {

FILE: client/src/dashboard/W_Table/TableMenu/W_TableMenu_Constraints.tsx
  type P (line 11) | type P = W_TableMenuProps & {

FILE: client/src/dashboard/W_Table/TableMenu/W_TableMenu_CurrentQuery.tsx
  constant QUERY_TYPES (line 10) | const QUERY_TYPES = ["SQL", "Prostgles API", "Full config"] as const;
  type QueryType (line 11) | type QueryType = (typeof QUERY_TYPES)[number];

FILE: client/src/dashboard/W_Table/TableMenu/W_TableMenu_DisplayOptions.tsx
  type P (line 9) | type P = W_TableMenuProps;

FILE: client/src/dashboard/W_Table/TableMenu/W_TableMenu_Indexes.tsx
  type P (line 12) | type P = W_TableMenuProps & {

FILE: client/src/dashboard/W_Table/TableMenu/W_TableMenu_Policies.tsx
  type P (line 15) | type P = W_TableMenuProps & {

FILE: client/src/dashboard/W_Table/TableMenu/W_TableMenu_Triggers.tsx
  type P (line 13) | type P = W_TableMenuProps & {

FILE: client/src/dashboard/W_Table/TableMenu/getChartCols.ts
  type ColInfo (line 12) | type ColInfo = Pick<
  type JoinedChartColumn (line 16) | type JoinedChartColumn = {
  type NormalChartColumn (line 23) | type NormalChartColumn = {
  type ChartColumn (line 28) | type ChartColumn = JoinedChartColumn | NormalChartColumn;
  type Args (line 34) | type Args =

FILE: client/src/dashboard/W_Table/TableMenu/getTableMeta.ts
  type W_TableInfo (line 7) | type W_TableInfo = {

FILE: client/src/dashboard/W_Table/TooManyColumnsWarning.tsx
  type P (line 8) | type P = {

FILE: client/src/dashboard/W_Table/W_Table.tsx
  type W_TableProps (line 67) | type W_TableProps = Omit<CommonWindowProps, "w"> & {
  type ActiveRow (line 81) | type ActiveRow = {
  type MinMax (line 95) | type MinMax<T = number> = {
  type MinMaxVals (line 102) | type MinMaxVals = Record<string, MinMax>;
  function getFilter (line 104) | function getFilter(filter: any = {}, activeRow?: ActiveRow): any {
  type ProstglesColumn (line 121) | type ProstglesColumn = TableColumn & { computed?: boolean } & Pick<
  type W_TableState (line 126) | type W_TableState = {
  type ProstglesTableD (line 172) | type ProstglesTableD = {
  type ColumnConfigWInfo (line 180) | type ColumnConfigWInfo = ColumnConfig & { info?: ValidatedColumnInfo };
  class W_Table (line 182) | class W_Table extends RTComp<
    method onMount (line 222) | onMount() {
    method onUnmount (line 234) | async onUnmount() {
    method getTableDataRequestSignature (line 243) | static getTableDataRequestSignature(
    method getPagination (line 449) | getPagination() {
    method render (line 522) | render() {
  function kFormatter (line 812) | function kFormatter(num: number) {

FILE: client/src/dashboard/W_Table/W_Table_Content.tsx
  type P (line 4) | type P = Pick<DivProps, "children"> & {

FILE: client/src/dashboard/W_Table/colorBlend.ts
  function toRGBA (line 3) | function toRGBA(d) {
  function blend (line 34) | function blend(from: string, to: string, perc = 0.5) {

FILE: client/src/dashboard/W_Table/getTableData/getTableData.ts
  function getTableData (line 10) | async function getTableData(

FILE: client/src/dashboard/W_Table/tableUtils/StyledTableColumn.tsx
  type P (line 19) | type P = OnColRenderRowInfo &

FILE: client/src/dashboard/W_Table/tableUtils/getEditColumn.tsx
  type RowSiblingData (line 30) | type RowSiblingData = {
  type OnClickEditRow (line 36) | type OnClickEditRow = (
  type GetMenuColumnArgs (line 43) | type GetMenuColumnArgs = {
  type CoreColInfo (line 111) | type CoreColInfo = Pick<

FILE: client/src/dashboard/W_Table/tableUtils/getJoinPaths.ts
  type TargetPath (line 59) | type TargetPath = {

FILE: client/src/dashboard/W_Table/tableUtils/getTableCols.tsx
  type ProstglesTableColumn (line 26) | type ProstglesTableColumn = ProstglesColumn & ColumnConfigWInfo;
  type GetTableColsArgs (line 28) | type GetTableColsArgs = Pick<W_TableProps["prgl"], "db" | "tables"> &

FILE: client/src/dashboard/W_Table/tableUtils/onRenderColumn.tsx
  type RenderedColumn (line 18) | type RenderedColumn = ColumnConfigWInfo &
  type OnRenderColumnProps (line 21) | type OnRenderColumnProps = {

FILE: client/src/dashboard/W_Table/tableUtils/tableUtils.ts
  constant COLUMN_CONFIG_KEYS (line 15) | const COLUMN_CONFIG_KEYS: Record<keyof ColumnConfig, 1> = {

FILE: client/src/dashboard/W_TimeChart/AddTimeChartFilter.tsx
  type DateFilter (line 20) | type DateFilter = { min: Date; max: Date };
  type P (line 21) | type P = {
  type TimestampFilterProps (line 307) | type TimestampFilterProps = {

FILE: client/src/dashboard/W_TimeChart/W_TimeChart.tsx
  type TimeChartLinkOptions (line 27) | type TimeChartLinkOptions = Extract<
  type LinkDataOptions (line 32) | type LinkDataOptions =
  type ProstglesTimeChartLayer (line 40) | type ProstglesTimeChartLayer = Pick<
  type W_TimeChartProps (line 62) | type W_TimeChartProps = Omit<CommonWindowProps, "w"> & {
  type W_TimeChartStateLayer (line 73) | type W_TimeChartStateLayer = TimeChartLayer & {
  type W_TimeChartState (line 85) | type W_TimeChartState = {
  type D (line 101) | type D = {
  class W_TimeChart (line 110) | class W_TimeChart extends RTComp<W_TimeChartProps, W_TimeChartState, D> {
    method onMount (line 127) | onMount() {
    method onUnmount (line 138) | onUnmount() {
    method onDelta (line 145) | onDelta(
    method setVisibleExtent (line 215) | setVisibleExtent(
    method layerQueries (line 234) | get layerQueries() {
    method render (line 250) | render() {

FILE: client/src/dashboard/W_TimeChart/W_TimeChartHeaderControls.tsx
  type P (line 19) | type P = Pick<

FILE: client/src/dashboard/W_TimeChart/W_TimeChartLayerLegend.tsx
  type P (line 18) | type P = Pick<CommonWindowProps, "getLinksAndWindows" | "myLinks"> & {

FILE: client/src/dashboard/W_TimeChart/W_TimeChartMenu.tsx
  type P (line 13) | type P = {
  constant BIN_LABEL_OPTIONS (line 18) | const BIN_LABEL_OPTIONS = [
  type ShowBinLabelsMode (line 24) | type ShowBinLabelsMode = (typeof BIN_LABEL_OPTIONS)[number]["key"];
  type TooltipPosition (line 33) | type TooltipPosition = (typeof TooltipPositions)[number]["key"];
  type MissingBinsOption (line 43) | type MissingBinsOption = (typeof MissingBinsOptions)[number]["key"];
  type TimechartRenderStyle (line 51) | type TimechartRenderStyle =
  constant TIMECHART_BIN_SIZES (line 190) | const TIMECHART_BIN_SIZES = [
  type TimeChartBinSize (line 218) | type TimeChartBinSize = (typeof TIMECHART_BIN_SIZES)[number]["key"];
  constant TIMECHART_STAT_TYPES (line 219) | const TIMECHART_STAT_TYPES = [
  type StatType (line 226) | type StatType = (typeof TIMECHART_STAT_TYPES)[number]["label"];
  type StatFunction (line 227) | type StatFunction = (typeof TIMECHART_STAT_TYPES)[number]["func"];

FILE: client/src/dashboard/W_TimeChart/fetchData/constants.ts
  constant TIMECHART_FIELD_NAMES (line 1) | const TIMECHART_FIELD_NAMES = {

FILE: client/src/dashboard/W_TimeChart/fetchData/fetchAndSetTimechartLayerData.ts
  type HTMLElement (line 134) | interface HTMLElement {

FILE: client/src/dashboard/W_TimeChart/fetchData/fetchTimechartLayer.ts
  type getTChartLayerArgs (line 26) | type getTChartLayerArgs = Pick<
  function fetchTimechartLayer (line 38) | async function fetchTimechartLayer({

FILE: client/src/dashboard/W_TimeChart/fetchData/getTimeChartData.ts
  type TChartLayer (line 19) | type TChartLayer = W_TimeChartState["layers"][number];
  type TChartLayers (line 20) | type TChartLayers = TChartLayer[];
  type FetchedLayerData (line 22) | type FetchedLayerData = {
  function getTimeChartData (line 29) | async function getTimeChartData(

FILE: client/src/dashboard/W_TimeChart/fetchData/getTimeChartLayers.ts
  type Args (line 11) | type Args = {

FILE: client/src/dashboard/W_TimeChart/fetchData/getTimeChartLayersWithBins.ts
  type TimeChartLayerWithBinError (line 35) | type TimeChartLayerWithBinError = ProstglesTimeChartLayer & {
  type TimeChartLayerWithBin (line 40) | type TimeChartLayerWithBin = ProstglesTimeChartLayer & {
  type TimeChartLayerWithBinOrError (line 52) | type TimeChartLayerWithBinOrError =
  function getTimeChartLayerWithBin (line 56) | async function getTimeChartLayerWithBin(
  function getTimeChartLayersWithBins (line 231) | async function getTimeChartLayersWithBins(this: W_TimeChart) {
  type GetDesiredTimeChartBinSizeArgs (line 266) | type GetDesiredTimeChartBinSizeArgs = {

FILE: client/src/dashboard/W_TimeChart/fetchData/getTimeChartSelectParams.ts
  type GetTimeChartSelectArgs (line 13) | type GetTimeChartSelectArgs = Pick<

FILE: client/src/dashboard/W_TimeChart/fetchData/getTimechartExtentFilter.ts
  type TimechartExtentFilter (line 6) | type TimechartExtentFilter = {

FILE: client/src/dashboard/Window.tsx
  type P (line 26) | type P<W extends WindowSyncItem> = {
  type S (line 38) | type S<W extends WindowSyncItem> = {
  type D (line 43) | type D = {
  class Window (line 48) | class Window<W extends WindowSyncItem> extends RTComp<
    method getTitle (line 59) | static getTitle(_w: WindowSyncItem) {
    method getTitleIcon (line 105) | getTitleIcon() {
    method render (line 118) | render(): ReactSilverGridNode | null {

FILE: client/src/dashboard/WindowControls/ColorByLegend/ColorByLegend.tsx
  type P (line 22) | type P = DivProps &

FILE: client/src/dashboard/WindowControls/DataLayerManager/DataLayer.tsx
  type ChartLinkOptions (line 28) | type ChartLinkOptions = Exclude<
  type P (line 32) | type P =

FILE: client/src/dashboard/WindowControls/DataLayerManager/DataLayerManager.tsx
  type MapLayerManagerProps (line 20) | type MapLayerManagerProps = (

FILE: client/src/dashboard/WindowControls/DataLayerManager/useSortedLayerQueries.ts
  type Args (line 6) | type Args<T extends ProstglesTimeChartLayer[] | LayerQuery[]> = {

FILE: client/src/dashboard/WindowControls/LayerColorPicker.tsx
  type LayerColorPickerProps (line 7) | type LayerColorPickerProps = {
  type Array (line 61) | interface Array<T> {

FILE: client/src/dashboard/WindowControls/MapLayerStyling.tsx
  type P (line 12) | type P = Pick<LayerColorPickerProps, "column" | "title"> & {

FILE: client/src/dashboard/WindowControls/OSMLayerOptions.tsx
  type P (line 11) | type P = {

FILE: client/src/dashboard/WindowControls/SQLChartLayerEditor.tsx
  type P (line 6) | type P = {

FILE: client/src/dashboard/WindowControls/TimeChartLayerOptions.tsx
  type TimeChartLayerOptionsProps (line 21) | type TimeChartLayerOptionsProps = Pick<

FILE: client/src/dashboard/WorkspaceMenu/WorkspaceAddBtn.tsx
  type WorkspaceDeleteBtnProps (line 13) | type WorkspaceDeleteBtnProps = Pick<Prgl, "dbs"> & {

FILE: client/src/dashboard/WorkspaceMenu/WorkspaceDeleteBtn.tsx
  type WorkspaceDeleteBtnProps (line 11) | type WorkspaceDeleteBtnProps = Pick<Prgl, "dbs"> &

FILE: client/src/dashboard/WorkspaceMenu/WorkspaceMenu.tsx
  type P (line 14) | type P = {

FILE: client/src/dashboard/WorkspaceMenu/WorkspaceMenuDropDown.tsx
  type P (line 23) | type P = {

FILE: client/src/dashboard/WorkspaceMenu/WorkspaceSettings.tsx
  type WorkspaceSettingsProps (line 14) | type WorkspaceSettingsProps = Pick<Prgl, "dbs" | "dbsMethods"> & {

FILE: client/src/dashboard/joinUtils.ts
  type SyncWindow (line 14) | type SyncWindow =
  type CrossFilters (line 20) | type CrossFilters = {
  type CrossFilterWindow (line 25) | type CrossFilterWindow =
  type GetJoinFiltersResult (line 30) | type GetJoinFiltersResult = {

FILE: client/src/dashboard/localSettings.ts
  type LocalSettings (line 4) | type LocalSettings = {
  type LocalSettingsListener (line 12) | type LocalSettingsListener = (s: LocalSettings) => void;
  constant LOCALSTORAGE_KEY (line 16) | const LOCALSTORAGE_KEY = "localSettings" as const;

FILE: client/src/dashboard/setPan.ts
  type PanEvent (line 3) | type PanEvent = {
  type PanListeners (line 27) | type PanListeners = {
  function setPan (line 71) | function setPan(node: HTMLDivElement, evs: PanListeners) {
  function addEvent (line 341) | function addEvent(node: HTMLElement, type, func) {

FILE: client/src/dashboard/shortestPath.ts
  type Graph (line 13) | type Graph = {

FILE: client/src/demo/AppVideoDemo.tsx
  constant VIDEO_DEMO_SCRIPTS (line 23) | const VIDEO_DEMO_SCRIPTS = {
  type DEMO_NAME (line 34) | type DEMO_NAME = keyof typeof VIDEO_DEMO_SCRIPTS;

FILE: client/src/demo/demoUtils.ts
  type GetElemOpts (line 32) | type GetElemOpts = {
  type ClickOpts (line 53) | type ClickOpts = GetElemOpts & {

FILE: client/src/demo/recordDemoUtils.ts
  type ClickedNode (line 15) | type ClickedNode = {

FILE: client/src/i18n/i18nUtils.ts
  type TranslationsType (line 36) | type TranslationsType<T> = {
  type TranslationFile (line 42) | type TranslationFile = TranslationsType<typeof translations>;
  type LanguageWithoutEn (line 53) | type LanguageWithoutEn = Exclude<Language, "en">;
  type TemplatedTranslation (line 54) | type TemplatedTranslation = {
  type Translation (line 58) | type Translation = undefined | TemplatedTranslation;
  type TranslationGroup (line 59) | type TranslationGroup = Record<string, Translation>;
  method get (line 113) | get(_, secondKey: string) {
  type BaseTranslation (line 148) | type BaseTranslation = typeof translations;
  type TranslationHandler (line 150) | type TranslationHandler = {

FILE: client/src/i18n/translations/translations.ts
  constant LANGUAGES (line 3) | const LANGUAGES = [
  type Language (line 13) | type Language = (typeof LANGUAGES)[number]["key"];

FILE: client/src/pages/Account/Account.tsx
  type AccountProps (line 19) | type AccountProps = ExtraProps;

FILE: client/src/pages/Account/Sessions.tsx
  type SessionsProps (line 31) | type SessionsProps = Pick<Prgl, "dbs" | "dbsTables" | "user" | "dbsMetho...
  function isMobileUserAgent (line 213) | function isMobileUserAgent(v: string) {
  type StatusDotCircleIconProps (line 229) | type StatusDotCircleIconProps = {

FILE: client/src/pages/AccountMenu.tsx
  type P (line 19) | type P = {

FILE: client/src/pages/Connections/Connection.tsx
  type ConnectionProps (line 18) | type ConnectionProps = (

FILE: client/src/pages/Connections/ConnectionsOptions.tsx
  type P (line 11) | type P = Pick<PrglState, "dbs" | "user"> & ReturnType<typeof useConnecti...

FILE: client/src/pages/Connections/CreateConnection/CreateConnection.tsx
  type CreateConnectionProps (line 19) | type CreateConnectionProps = Required<

FILE: client/src/pages/Connections/CreateConnection/useCreateConnection.ts
  type CreateConnectionType (line 10) | type CreateConnectionType = [

FILE: client/src/pages/Connections/CreatePostgresUser.tsx
  type NewPostgresUser (line 11) | type NewPostgresUser = {
  type P (line 29) | type P = {
  type Args (line 160) | type Args = {

FILE: client/src/pages/Connections/useConnectionServersList.ts
  type ServerUser (line 5) | type ServerUser = Pick<
  type P (line 10) | type P = Pick<

FILE: client/src/pages/Connections/useConnections.ts
  type CommonConnectionInfo (line 8) | type CommonConnectionInfo = Pick<DBSSchema["connections"], "created"> & {
  type BasicConnectionModel (line 15) | type BasicConnectionModel = Pick<
  type AdminConnectionModel (line 21) | type AdminConnectionModel = Required<DBSSchema["connections"]> &
  type IConnection (line 24) | type IConnection = BasicConnectionModel | AdminConnectionModel;

FILE: client/src/pages/ElectronSetup/ElectronSetup.tsx
  type ElectronSetup (line 12) | type ElectronSetup = {

FILE: client/src/pages/ElectronSetup/useElectronSetup.ts
  type ElectronSetup (line 11) | type ElectronSetup = {

FILE: client/src/pages/Login/Login.tsx
  type LoginFormProps (line 12) | type LoginFormProps = Pick<Prgl, "auth">;

FILE: client/src/pages/Login/useLoginState.ts
  type PasswordLoginDataAndFunc (line 13) | type PasswordLoginDataAndFunc = {
  type PasswordRegisterDataAndFunc (line 18) | type PasswordRegisterDataAndFunc = {
  type FormData (line 23) | type FormData =
  type FormStates (line 34) | type FormStates = FormData["type"];
  constant ERR_CODE_MESSAGES (line 265) | const ERR_CODE_MESSAGES = {
  constant SIGNUP_CODE_MESSAGES (line 297) | const SIGNUP_CODE_MESSAGES = {

FILE: client/src/pages/NewConnection/NewConnectionFormFields.tsx
  type DBProps (line 21) | type DBProps = {
  type NewConnectionFormProps (line 28) | type NewConnectionFormProps = {

FILE: client/src/pages/NewConnection/NewConnnectionForm.tsx
  type Connection (line 66) | type Connection = Omit<
  constant DEFAULT_CONNECTION (line 71) | const DEFAULT_CONNECTION = {
  type NewConnectionProps (line 88) | type NewConnectionProps = {
  type NewConnectionState (line 101) | type NewConnectionState = {
  class NewConnection (line 116) | class NewConnection extends RTComp<NewConnectionProps, NewConnectionStat...
    method conId (line 128) | get conId() {
    method render (line 193) | render() {

FILE: client/src/pages/NewConnection/SchemaFilter.tsx
  type P (line 9) | type P = Pick<Connection, "db_schema_filter"> & {

FILE: client/src/pages/NewConnection/newConnectionUtils.ts
  constant SSL_MODES (line 3) | const SSL_MODES = [

FILE: client/src/pages/ProjectConnection/ProjectConnection.tsx
  type Connections (line 20) | type Connections = DBSSchema["connections"];
  type ProjectProps (line 21) | type ProjectProps = {
  type FullExtraProps (line 26) | type FullExtraProps = ExtraProps & {

FILE: client/src/pages/ProjectConnection/ProjectConnectionError.tsx
  type P (line 14) | type P = {

FILE: client/src/pages/ProjectConnection/useProjectDb.ts
  type PrglProjectStateError (line 14) | type PrglProjectStateError = {
  type PrglProjectState (line 19) | type PrglProjectState =
  type P (line 35) | type P = {

FILE: client/src/pages/ServerSettings/AuthProvidersSetup.tsx
  type AuthProvidersConfig (line 12) | type AuthProvidersConfig = Extract<
  type UseProviderPropsArgs (line 17) | type UseProviderPropsArgs = {
  type AuthProviderProps (line 48) | type AuthProviderProps = ReturnType<typeof useProviderProps>;

FILE: client/src/pages/ServerSettings/EmailAuthSetupIngredients/EmailSMTPAndTemplateSetup.tsx
  type EmailConfig (line 20) | type EmailConfig = Extract<
  type EmailSMTPCofig (line 24) | type EmailSMTPCofig = EmailConfig["smtp"];
  type EmailTemplateCofig (line 25) | type EmailTemplateCofig = EmailConfig["emailTemplate"];
  type P (line 33) | type P = {
  constant DEFAULT_SMTP_CONFIG (line 151) | const DEFAULT_SMTP_CONFIG = {

FILE: client/src/pages/ServerSettings/EmailAuthSetupIngredients/EmailSMTPSetup.tsx
  type P (line 8) | type P = Pick<DivProps, "style" | "className"> & {

FILE: client/src/pages/ServerSettings/EmailAuthSetupIngredients/EmailTemplateSetup.tsx
  type EmailTemplateConfig (line 10) | type EmailTemplateConfig = {
  type P (line 16) | type P = {

FILE: client/src/pages/ServerSettings/MCPServers/MCPServerConfig/MCPServerConfig.tsx
  type MCPServerEnabledConfig (line 11) | type MCPServerEnabledConfig = { configId: number };
  type MCPServerConfigProps (line 13) | type MCPServerConfigProps = {
  type MCPServerConfigContext (line 132) | type MCPServerConfigContext = {

FILE: client/src/pages/ServerSettings/MCPServers/MCPServerConfig/useMCPServerEnable.ts
  type MCPServerChatContext (line 9) | type MCPServerChatContext = {

FILE: client/src/pages/ServerSettings/MCPServers/MCPServerFooterActions/MCPServerFooterActions.tsx
  type MCPServerFooterActionsProps (line 20) | type MCPServerFooterActionsProps = Pick<

FILE: client/src/pages/ServerSettings/MCPServers/MCPServers.tsx
  type MCPServersProps (line 21) | type MCPServersProps = Omit<ServerSettingsProps, "auth"> & {

FILE: client/src/pages/ServerSettings/MCPServers/MCPServersHeader.tsx
  type MCPServersProps (line 5) | type MCPServersProps = Pick<ServerSettingsProps, "dbsMethods">;

FILE: client/src/pages/ServerSettings/MCPServers/MCPServersToolbar/useAddMCPServer.ts
  type NewMCPServer (line 5) | type NewMCPServer = Pick<
  type MCPConfig (line 124) | type MCPConfig = {
  type MCPServerConfig (line 130) | type MCPServerConfig = {
  type ArgDef (line 134) | type ArgDef =

FILE: client/src/pages/ServerSettings/MCPServers/useMCPChatAllowedTools.ts
  type MCPChatAllowedTools (line 24) | type MCPChatAllowedTools = NonNullable<

FILE: client/src/pages/ServerSettings/MCPServers/useMCPServersListProps.tsx
  type MCPServerWithToolAndConfigs (line 10) | type MCPServerWithToolAndConfigs = DBSSchema["mcp_servers"] & {

FILE: client/src/pages/ServerSettings/OAuthProviderSetup.tsx
  type P (line 22) | type P = AuthProviderProps & {
  constant PROVIDER_INFO (line 230) | const PROVIDER_INFO = {

FILE: client/src/pages/ServerSettings/ServerSettings.tsx
  type ServerSettingsProps (line 29) | type ServerSettingsProps = Pick<

FILE: client/src/pages/ServerSettings/Services.tsx
  type P (line 17) | type P = Pick<Prgl, "dbs" | "dbsMethods" | "dbsTables"> & {

FILE: client/src/pages/TopControls.tsx
  type TopControlsProps (line 26) | type TopControlsProps = {
  type ConnectionConfigBtnProps (line 121) | type ConnectionConfigBtnProps = Pick<FullExtraProps, "user"> & {
  type DashboardMenuBtnProps (line 160) | type DashboardMenuBtnProps<HREF extends string | void> = BtnProps<HREF>;

FILE: client/src/theme/ThemeSelector.tsx
  type ThemeOption (line 7) | type ThemeOption = "light" | "dark" | "from-system";
  type P (line 8) | type P = Pick<ExtraProps, "dbs"> & {

FILE: client/src/theme/useAppTheme.ts
  constant THEMES (line 6) | const THEMES = ["light", "dark", "from-system"] as const;
  constant THEME_SETTING_NAME (line 7) | const THEME_SETTING_NAME = "theme" as const;

FILE: client/src/utils/colorUtils.ts
  type RGBA (line 47) | type RGBA = [number, number, number, number];

FILE: client/src/utils/utils.ts
  function filterObj (line 14) | function filterObj<T extends AnyObject, K extends keyof T>(
  function ifEmpty (line 40) | function ifEmpty<V, R>(v: V, replaceValue: R): R | V {
  function nFormatter (line 44) | function nFormatter(num: number, digits: number): string {
  type StrFormat (line 67) | type StrFormat = {
  function getStringFormat (line 75) | function getStringFormat(s: string | undefined): StrFormat[] {
  function quickClone (line 128) | function quickClone<T>(obj: T): T {

FILE: common/DBGeneratedSchema.d.ts
  type DBGeneratedSchema (line 3) | type DBGeneratedSchema = {

FILE: common/DashboardTypes.d.ts
  type LayoutItem (line 5) | type LayoutItem = {
  type LayoutGroup (line 24) | type LayoutGroup = {
  type LayoutConfig (line 45) | type LayoutConfig = LayoutItem | LayoutGroup;
  type LinkedDataChart (line 50) | type LinkedDataChart = {
  type LinkedDataTable (line 64) | type LinkedDataTable = {
  type TableJoin (line 71) | type TableJoin = {
  type LinkedData (line 91) | type LinkedData = {
  type Comparator (line 99) | type Comparator = "$eq" | "$ne" | "$lt" | "$lte" | "$gt" | "$gte";
  type BasicFilter (line 100) | type BasicFilter = {
  type ComplexColumnFilterFunction (line 116) | type ComplexColumnFilterFunction = {
  type ComplexColumnFilter (line 139) | type ComplexColumnFilter = {
  type ColumnFilter (line 142) | type ColumnFilter = BasicFilter | ComplexColumnFilter;
  type JoinedFilter (line 146) | type JoinedFilter = {
  type FilterItem (line 155) | type FilterItem = ColumnFilter | JoinedFilter;
  type Filter (line 156) | type Filter = FilterItem | {
  type Filtering (line 161) | type Filtering = {
  type TableColumn (line 179) | type TableColumn = {
  type CardLayoutRowColumnValue (line 255) | type CardLayoutRowColumnValue = {
  type CardLayout (line 271) | type CardLayout = {
  type TableWindowInsertModel (line 279) | type TableWindowInsertModel = Filtering & {
  type LayerDataSource (line 305) | type LayerDataSource = (Filtering & {
  type MapWindowInsertModel (line 320) | type MapWindowInsertModel = {
  type SqlWindowInsertModel (line 335) | type SqlWindowInsertModel = {
  type TimechartWindowInsertModel (line 344) | type TimechartWindowInsertModel = {
  type BarchartWindowInsertModel (line 358) | type BarchartWindowInsertModel = ((Filtering & {
  type WindowInsertModel (line 377) | type WindowInsertModel = MapWindowInsertModel | SqlWindowInsertModel | T...
  type WorkspaceInsertModel (line 378) | type WorkspaceInsertModel = {

FILE: common/DashboardTypes.ts
  type LayoutItem (line 6) | type LayoutItem = {
  type LayoutGroup (line 25) | type LayoutGroup = {
  type LayoutConfig (line 50) | type LayoutConfig = LayoutItem | LayoutGroup;
  type LinkedDataChart (line 56) | type LinkedDataChart = {
  type LinkedDataTable (line 71) | type LinkedDataTable = {
  type TableJoin (line 79) | type TableJoin = {
  type LinkedData (line 100) | type LinkedData = {
  type Comparator (line 109) | type Comparator = "$eq" | "$ne" | "$lt" | "$lte" | "$gt" | "$gte";
  type BasicFilter (line 111) | type BasicFilter = {
  type ComplexColumnFilterFunction (line 132) | type ComplexColumnFilterFunction =
  type ComplexColumnFilter (line 157) | type ComplexColumnFilter = {
  type ColumnFilter (line 161) | type ColumnFilter = BasicFilter | ComplexColumnFilter;
  type JoinedFilter (line 166) | type JoinedFilter = {
  type FilterItem (line 176) | type FilterItem = ColumnFilter | JoinedFilter;
  type Filter (line 178) | type Filter =
  type Filtering (line 187) | type Filtering = {
  type TableColumn (line 207) | type TableColumn = {
  type CardLayoutRowColumnValue (line 305) | type CardLayoutRowColumnValue = {
  type CardLayout (line 322) | type CardLayout = {
  type TableWindowInsertModel (line 331) | type TableWindowInsertModel = Filtering & {
  type LayerDataSource (line 362) | type LayerDataSource =
  type MapWindowInsertModel (line 380) | type MapWindowInsertModel = {
  type SqlWindowInsertModel (line 396) | type SqlWindowInsertModel = {
  type TimechartWindowInsertModel (line 406) | type TimechartWindowInsertModel = {
  type BarchartWindowInsertModel (line 422) | type BarchartWindowInsertModel = (
  type WindowInsertModel (line 445) | type WindowInsertModel =
  type WorkspaceInsertModel (line 452) | type WorkspaceInsertModel = {

FILE: common/OAuthUtils.d.ts
  type TemplateData (line 38) | type TemplateData = Record<string, {

FILE: common/OAuthUtils.js
  constant EMAIL_CONFIRMED_SEARCH_PARAM (line 131) | const EMAIL_CONFIRMED_SEARCH_PARAM = "email-confirmed";
  constant PASSWORDLESS_ADMIN_USERNAME (line 132) | const PASSWORDLESS_ADMIN_USERNAME = "passwordless_admin";
  constant MOCK_SMTP_HOST (line 164) | const MOCK_SMTP_HOST = "prostgles-test-mock";
  constant DEFAULT_EMAIL_VERIFICATION_TEMPLATE (line 165) | const DEFAULT_EMAIL_VERIFICATION_TEMPLATE = {
  constant DEFAULT_MAGIC_LINK_TEMPLATE (line 185) | const DEFAULT_MAGIC_LINK_TEMPLATE = {
  constant ELECTRON_USER_AGENT (line 227) | const ELECTRON_USER_AGENT = "electron";
  constant DOCKER_USER_AGENT (line 228) | const DOCKER_USER_AGENT = "docker-mcp";

FILE: common/OAuthUtils.ts
  constant EMAIL_CONFIRMED_SEARCH_PARAM (line 138) | const EMAIL_CONFIRMED_SEARCH_PARAM = "email-confirmed" as const;
  constant PASSWORDLESS_ADMIN_USERNAME (line 140) | const PASSWORDLESS_ADMIN_USERNAME = "passwordless_admin";
  type TemplateData (line 142) | type TemplateData = Record<
  constant MOCK_SMTP_HOST (line 193) | const MOCK_SMTP_HOST = "prostgles-test-mock";
  constant DEFAULT_EMAIL_VERIFICATION_TEMPLATE (line 195) | const DEFAULT_EMAIL_VERIFICATION_TEMPLATE = {
  constant DEFAULT_MAGIC_LINK_TEMPLATE (line 216) | const DEFAULT_MAGIC_LINK_TEMPLATE = {
  constant ELECTRON_USER_AGENT (line 284) | const ELECTRON_USER_AGENT = "electron";
  constant DOCKER_USER_AGENT (line 285) | const DOCKER_USER_AGENT = "docker-mcp";

FILE: common/electronInitTypes.d.ts
  type ProstglesInitState (line 1) | type ProstglesInitState<T extends Record<string, unknown> = Record<strin...
  type ProstglesState (line 12) | type ProstglesState<T extends Record<string, unknown> = Record<string, u...
  type OS (line 27) | type OS = "Windows" | "Linux" | "Mac" | "";
  type InstalledPrograms (line 29) | type InstalledPrograms = {

FILE: common/electronInitTypes.js
  constant DEFAULT_ELECTRON_CONNECTION (line 9) | const DEFAULT_ELECTRON_CONNECTION = {

FILE: common/electronInitTypes.ts
  type ProstglesInitState (line 1) | type ProstglesInitState<
  type ProstglesState (line 18) | type ProstglesState<
  type OS (line 36) | type OS = "Windows" | "Linux" | "Mac" | "";
  type InstalledPrograms (line 45) | type InstalledPrograms = {
  constant DEFAULT_ELECTRON_CONNECTION (line 50) | const DEFAULT_ELECTRON_CONNECTION = {

FILE: common/filterUtils.d.ts
  type AnyObject (line 2) | type AnyObject = Record<string, any>;
  type FilterType (line 106) | type FilterType = (typeof CORE_FILTER_TYPES)[number]["key"] | (typeof FT...
  type BaseFilter (line 107) | type BaseFilter = {
  type ComplexFilterDetailed (line 112) | type ComplexFilterDetailed = {
  type DetailedFilterBase (line 122) | type DetailedFilterBase = BaseFilter & {
  type JoinPath (line 132) | type JoinPath = {
  type DetailedJoinedFilter (line 136) | type DetailedJoinedFilter = BaseFilter & {
  type DetailedFilter (line 141) | type DetailedFilter = DetailedFilterBase | DetailedJoinedFilter;
  type DetailedGroupFilter (line 142) | type DetailedGroupFilter = {
  type InfoType (line 149) | type InfoType = "pg";
  type GetFinalFilterOpts (line 154) | type GetFinalFilterOpts = {
  type GroupedDetailedFilter (line 165) | type GroupedDetailedFilter = {

FILE: common/filterUtils.js
  constant CORE_FILTER_TYPES (line 2) | const CORE_FILTER_TYPES = [
  constant FTS_FILTER_TYPES (line 13) | const FTS_FILTER_TYPES = [
  constant TEXT_FILTER_TYPES (line 36) | const TEXT_FILTER_TYPES = [
  constant NUMERIC_FILTER_TYPES (line 51) | const NUMERIC_FILTER_TYPES = [
  constant DATE_FILTER_TYPES (line 62) | const DATE_FILTER_TYPES = [
  constant GEO_FILTER_TYPES (line 67) | const GEO_FILTER_TYPES = [
  constant JOINED_FILTER_TYPES (line 70) | const JOINED_FILTER_TYPES = [

FILE: common/filterUtils.ts
  type AnyObject (line 3) | type AnyObject = Record<string, any>;
  constant CORE_FILTER_TYPES (line 8) | const CORE_FILTER_TYPES = [
  constant FTS_FILTER_TYPES (line 20) | const FTS_FILTER_TYPES = [
  constant TEXT_FILTER_TYPES (line 48) | const TEXT_FILTER_TYPES = [
  constant NUMERIC_FILTER_TYPES (line 64) | const NUMERIC_FILTER_TYPES = [
  constant DATE_FILTER_TYPES (line 76) | const DATE_FILTER_TYPES = [
  constant GEO_FILTER_TYPES (line 82) | const GEO_FILTER_TYPES = [
  type FilterType (line 86) | type FilterType =
  type BaseFilter (line 94) | type BaseFilter = {
  constant JOINED_FILTER_TYPES (line 98) | const JOINED_FILTER_TYPES = [
  type ComplexFilterDetailed (line 102) | type ComplexFilterDetailed =
  type DetailedFilterBase (line 114) | type DetailedFilterBase = BaseFilter & {
  type JoinPath (line 124) | type JoinPath = {
  type DetailedJoinedFilter (line 128) | type DetailedJoinedFilter = BaseFilter & {
  type DetailedFilter (line 133) | type DetailedFilter = DetailedFilterBase | DetailedJoinedFilter;
  type DetailedGroupFilter (line 134) | type DetailedGroupFilter =
  type InfoType (line 143) | type InfoType = "pg";
  type GetFinalFilterOpts (line 251) | type GetFinalFilterOpts = {
  type GroupedDetailedFilter (line 434) | type GroupedDetailedFilter =

FILE: common/llmUtils.d.ts
  type LLMMessage (line 2) | type LLMMessage = DBSSchema["llm_messages"];
  type FilterMatch (line 38) | type FilterMatch<T, U> = T extends U ? T : never;
  type FilterUnMatch (line 39) | type FilterUnMatch<T, U> = T extends U ? never : T;

FILE: common/llmUtils.js
  constant LLM_PROMPT_VARIABLES (line 50) | const LLM_PROMPT_VARIABLES = {

FILE: common/llmUtils.ts
  type LLMMessage (line 3) | type LLMMessage = DBSSchema["llm_messages"];
  type FilterMatch (line 46) | type FilterMatch<T, U> = T extends U ? T : never;
  type FilterUnMatch (line 47) | type FilterUnMatch<T, U> = T extends U ? never : T;
  constant LLM_PROMPT_VARIABLES (line 85) | const LLM_PROMPT_VARIABLES = {

FILE: common/mcp.d.ts
  type MCPServerInfo (line 2) | type MCPServerInfo = Omit<DBSSchemaForInsert["mcp_servers"], "id" | "cwd...
  type McpToolCallResponse (line 5) | type McpToolCallResponse = {

FILE: common/mcp.js
  constant DEFAULT_MCP_SERVER_NAMES (line 1) | const DEFAULT_MCP_SERVER_NAMES = [

FILE: common/mcp.ts
  type MCPServerInfo (line 3) | type MCPServerInfo = Omit<
  type McpToolCallResponse (line 13) | type McpToolCallResponse = {
  constant DEFAULT_MCP_SERVER_NAMES (line 45) | const DEFAULT_MCP_SERVER_NAMES = [

FILE: common/prostglesMcp.d.ts
  type ProstglesMcpTools (line 384) | type ProstglesMcpTools = typeof PROSTGLES_MCP_SERVERS_AND_TOOLS;
  type ProstglesMcpTool (line 385) | type ProstglesMcpTool = {

FILE: common/prostglesMcp.js
  constant PROSTGLES_MCP_SERVERS_AND_TOOLS (line 36) | const PROSTGLES_MCP_SERVERS_AND_TOOLS = {
  constant MCP_TOOL_NAME_SEPARATOR (line 349) | const MCP_TOOL_NAME_SEPARATOR = "--";

FILE: common/prostglesMcp.ts
  constant PROSTGLES_MCP_SERVERS_AND_TOOLS (line 45) | const PROSTGLES_MCP_SERVERS_AND_TOOLS = {
  type ProstglesMcpTools (line 388) | type ProstglesMcpTools = typeof PROSTGLES_MCP_SERVERS_AND_TOOLS;
  type ProstglesMcpTool (line 389) | type ProstglesMcpTool = {
  constant MCP_TOOL_NAME_SEPARATOR (line 396) | const MCP_TOOL_NAME_SEPARATOR = "--";
  type AllowedChatTool (line 422) | type AllowedChatTool = {

FILE: common/publishUtils.d.ts
  type CustomTableRules (line 3) | type CustomTableRules = {
  type DataTypes (line 10) | type DataTypes = (typeof OBJ_DEF_TYPES)[number];
  type ArgObjDef (line 11) | type ArgObjDef = {
  type _ObjDef (line 40) | type _ObjDef = DataTypes | ArgObjDef;
  type ObjDef (line 41) | type ObjDef = _ObjDef | {
  type ArgDef (line 46) | type ArgDef = ArgObjDef & {
  type ParamDef (line 49) | type ParamDef = ObjDef;
  type UXParamDefinition (line 50) | type UXParamDefinition = {
  type MethodClientDef (line 57) | type MethodClientDef = {
  type ContextValue (line 63) | type ContextValue = {
  type ForcedData (line 67) | type ForcedData = {
  type SelectRule (line 75) | type SelectRule = {
  type UpdateRule (line 84) | type UpdateRule = {
  type InsertRule (line 100) | type InsertRule = {
  type DeleteRule (line 107) | type DeleteRule = {
  type DBSSchema (line 113) | type DBSSchema = {
  type DBSSchemaForInsert (line 116) | type DBSSchemaForInsert = {
  type SyncRule (line 119) | type SyncRule = {
  type TableRules (line 126) | type TableRules = {
  type BasicTablePermissions (line 136) | type BasicTablePermissions = Partial<Record<Exclude<keyof TableRules, "s...
  type AnyObject (line 137) | type AnyObject = Record<string, any>;
  type PublishedResultUpdate (line 138) | type PublishedResultUpdate = {
  type PublishedResult (line 153) | type PublishedResult = boolean | {
  type FieldFilter (line 175) | type FieldFilter = "" | "*" | string[] | Record<string, 1 | true> | Reco...
  type ParsedFilter (line 185) | type ParsedFilter = {
  type ParsedRuleFilters (line 190) | type ParsedRuleFilters = {
  type ContextDataObject (line 195) | type ContextDataObject = {
  type TableRulesErrors (line 199) | type TableRulesErrors = Partial<Record<keyof TableRules, any>> & {

FILE: common/publishUtils.js
  constant OBJ_DEF_TYPES (line 2) | const OBJ_DEF_TYPES = [
  function isObject (line 12) | function isObject(obj) {

FILE: common/publishUtils.ts
  type CustomTableRules (line 9) | type CustomTableRules = {
  constant OBJ_DEF_TYPES (line 16) | const OBJ_DEF_TYPES = [
  type DataTypes (line 26) | type DataTypes = (typeof OBJ_DEF_TYPES)[number];
  type ArgObjDef (line 28) | type ArgObjDef = {
  type _ObjDef (line 60) | type _ObjDef = DataTypes | ArgObjDef;
  type ObjDef (line 62) | type ObjDef = _ObjDef | { oneOf: readonly _ObjDef[] } | { arrayOf: _ObjD...
  type ArgDef (line 69) | type ArgDef = ArgObjDef & {
  type ParamDef (line 72) | type ParamDef = ObjDef;
  type UXParamDefinition (line 74) | type UXParamDefinition =
  type MethodClientDef (line 84) | type MethodClientDef = {
  type ContextValue (line 91) | type ContextValue = {
  type ForcedData (line 96) | type ForcedData =
  type SelectRule (line 107) | type SelectRule = {
  type UpdateRule (line 116) | type UpdateRule = {
  type InsertRule (line 134) | type InsertRule = {
  type DeleteRule (line 141) | type DeleteRule = {
  type DBSSchema (line 148) | type DBSSchema = {
  type DBSSchemaForInsert (line 152) | type DBSSchemaForInsert = {
  type SyncRule (line 156) | type SyncRule = {
  type TableRules (line 164) | type TableRules = {
  type BasicTablePermissions (line 177) | type BasicTablePermissions = Partial<
  type AnyObject (line 181) | type AnyObject = Record<string, any>;
  type PublishedResultUpdate (line 183) | type PublishedResultUpdate = {
  type PublishedResult (line 200) | type PublishedResult =
  function isObject (line 232) | function isObject<T extends Record<string, any>>(obj: any): obj is T {
  type FieldFilter (line 236) | type FieldFilter =
  type ParsedFilter (line 281) | type ParsedFilter = { $and: AnyObject[] } | { $or: AnyObject[] };
  type ParsedRuleFilters (line 282) | type ParsedRuleFilters = {
  type ContextDataObject (line 346) | type ContextDataObject = {
  type TableRulesErrors (line 510) | type TableRulesErrors = Partial<Record<keyof TableRules, any>> & {

FILE: common/utils.d.ts
  type AGE (line 8) | type AGE = {
  type DumpOpts (line 36) | type DumpOpts = DBSSchema["backups"]["options"];
  type PGDumpParams (line 37) | type PGDumpParams = {
  type DeepWriteable (line 44) | type DeepWriteable<T> = {
  type AnyObject (line 47) | type AnyObject = Record<string, any>;
  type WithUndef (line 48) | type WithUndef<T extends AnyObject | undefined> = T extends AnyObject ? {
  type GetElementType (line 51) | type GetElementType<T extends any[] | readonly any[]> = T extends (infer...
  type OmitDistributive (line 52) | type OmitDistributive<T, K extends keyof any> = T extends any ? Omit<T, ...
  type PG_STAT_ACTIVITY (line 53) | type PG_STAT_ACTIVITY = {
  type PG_STAT_DATABASE (line 77) | type PG_STAT_DATABASE = {
  type IOStats (line 100) | type IOStats = {
  type ServerStatus (line 116) | type ServerStatus = {
  type ConnectionStatus (line 128) | type ConnectionStatus = {
  type SampleSchema (line 138) | type SampleSchema = {
  type SampleSchemaDir (line 145) | type SampleSchemaDir = {
  type ProcStats (line 156) | type ProcStats = {
  type ColType (line 164) | type ColType = {
  type FileTable (line 216) | type FileTable = {

FILE: common/utils.js
  constant SECOND (line 2) | const SECOND = 1000;
  constant MINUTE (line 3) | const MINUTE = SECOND * 60;
  constant HOUR (line 4) | const HOUR = MINUTE * 60;
  constant DAY (line 5) | const DAY = HOUR * 24;
  constant MONTH (line 6) | const MONTH = DAY * 30;
  constant YEAR (line 7) | const YEAR = DAY * 365;
  constant EXCLUDE_FROM_SCHEMA_WATCH (line 8) | const EXCLUDE_FROM_SCHEMA_WATCH = "prostgles internal query that should ...
  constant STATUS_MONITOR_IGNORE_QUERY (line 9) | const STATUS_MONITOR_IGNORE_QUERY = "prostgles-status-monitor-query";
  constant DESTINATIONS (line 49) | const DESTINATIONS = [
  function matchObj (line 53) | function matchObj(obj1, obj2) {
  function sliceText (line 59) | function sliceText(_text, maxLen, ellipseText = "...", midEllipse = fals...
  constant RELOAD_NOTIFICATION (line 68) | const RELOAD_NOTIFICATION = "Prostgles UI accessible at";
  function throttle (line 69) | function throttle(func, timeout) {
  constant SPOOF_TEST_VALUE (line 92) | const SPOOF_TEST_VALUE = "trustme";
  constant CONNECTION_CONFIG_SECTIONS (line 97) | const CONNECTION_CONFIG_SECTIONS = [
  constant API_ENDPOINTS (line 136) | const API_ENDPOINTS = {
  constant ROUTES (line 141) | const ROUTES = {
  constant PROSTGLES_CLOUD_URL (line 164) | const PROSTGLES_CLOUD_URL = "https://cloud1.prostgles.com";
  constant FORKED_PROC_ENV_NAME (line 165) | const FORKED_PROC_ENV_NAME = "IS_FORKED_PROC";
  function debouncePromise (line 166) | function debouncePromise(promiseFuncDef) {

FILE: common/utils.ts
  constant SECOND (line 4) | const SECOND = 1000;
  constant MINUTE (line 5) | const MINUTE = SECOND * 60;
  constant HOUR (line 6) | const HOUR = MINUTE * 60;
  constant DAY (line 7) | const DAY = HOUR * 24;
  constant MONTH (line 8) | const MONTH = DAY * 30;
  constant YEAR (line 9) | const YEAR = DAY * 365;
  type AGE (line 11) | type AGE = {
  constant EXCLUDE_FROM_SCHEMA_WATCH (line 21) | const EXCLUDE_FROM_SCHEMA_WATCH =
  constant STATUS_MONITOR_IGNORE_QUERY (line 23) | const STATUS_MONITOR_IGNORE_QUERY = "prostgles-status-monitor-query";
  constant DESTINATIONS (line 69) | const DESTINATIONS = [
  type DumpOpts (line 74) | type DumpOpts = DBSSchema["backups"]["options"];
  type PGDumpParams (line 76) | type PGDumpParams = {
  type DeepWriteable (line 84) | type DeepWriteable<T> = {
  type AnyObject (line 87) | type AnyObject = Record<string, any>;
  type WithUndef (line 89) | type WithUndef<T extends AnyObject | undefined> =
  type GetElementType (line 96) | type GetElementType<T extends any[] | readonly any[]> =
  type OmitDistributive (line 99) | type OmitDistributive<T, K extends keyof any> =
  type PG_STAT_ACTIVITY (line 102) | type PG_STAT_ACTIVITY = {
  type PG_STAT_DATABASE (line 127) | type PG_STAT_DATABASE = {
  type IOStats (line 151) | type IOStats = {
  type ServerStatus (line 168) | type ServerStatus = {
  type ConnectionStatus (line 181) | type ConnectionStatus = {
  type SampleSchema (line 192) | type SampleSchema = {
  type SampleSchemaDir (line 202) | type SampleSchemaDir = {
  type ProcStats (line 222) | type ProcStats = {
  function matchObj (line 229) | function matchObj(
  function sliceText (line 239) | function sliceText<T extends string | undefined>(
  type ColType (line 254) | type ColType = {
  constant RELOAD_NOTIFICATION (line 262) | const RELOAD_NOTIFICATION = "Prostgles UI accessible at";
  function throttle (line 264) | function throttle<Params extends any[]>(
  constant SPOOF_TEST_VALUE (line 290) | const SPOOF_TEST_VALUE = "trustme";
  constant CONNECTION_CONFIG_SECTIONS (line 300) | const CONNECTION_CONFIG_SECTIONS = [
  constant API_ENDPOINTS (line 349) | const API_ENDPOINTS = {
  constant ROUTES (line 355) | const ROUTES = {
  constant PROSTGLES_CLOUD_URL (line 382) | const PROSTGLES_CLOUD_URL = "https://cloud1.prostgles.com";
  constant FORKED_PROC_ENV_NAME (line 384) | const FORKED_PROC_ENV_NAME = "IS_FORKED_PROC" as const;
  function debouncePromise (line 386) | function debouncePromise<Args extends any[], T>(
  type FileTable (line 416) | type FileTable = {

FILE: e2e/tests/Testing.ts
  constant COMMANDS (line 1) | const COMMANDS = {
  type Command (line 534) | type Command = keyof typeof COMMANDS;
  type TestSelectors (line 536) | type TestSelectors = {
  constant COMMAND_SEARCH_ATTRIBUTE_NAME (line 555) | const COMMAND_SEARCH_ATTRIBUTE_NAME = "data-command-search-ended";
  constant MOCK_ELECTRON_WINDOW_ATTR (line 557) | const MOCK_ELECTRON_WINDOW_ATTR = "MOCK_ELECTRON_WINDOW_ATTR" as const;
  type HTMLAttributes (line 560) | interface HTMLAttributes<T> {
  type CursorAnimation (line 566) | type CursorAnimation =
  type Animation (line 587) | type Animation =
  type Scene (line 620) | type Scene = {

FILE: e2e/tests/command_palette.spec.ts
  constant IS_PIPELINE (line 18) | const IS_PIPELINE = process.env.CI === "true";

FILE: e2e/tests/create_docs.spec.ts
  constant IS_PIPELINE (line 29) | const IS_PIPELINE = process.env.CI === "true";

FILE: e2e/tests/main.spec.ts
  constant DB_NAMES (line 59) | const DB_NAMES = {

FILE: e2e/tests/mockSMTPServer.ts
  method onAuth (line 9) | onAuth(auth, session, callback) {
  method onConnect (line 24) | onConnect(session, callback) {
  method onMailFrom (line 30) | onMailFrom(address, session, callback) {
  method onRcptTo (line 36) | onRcptTo(address, session, callback) {
  method onData (line 42) | onData(stream, session, callback) {
  method onClose (line 58) | onClose(session) {

FILE: e2e/tests/svgScreenshots/SVG_SCREENSHOT_DETAILS.ts
  type OnBeforeScreenshot (line 21) | type OnBeforeScreenshot = (
  constant SVG_SCREENSHOT_DETAILS (line 27) | const SVG_SCREENSHOT_DETAILS = {

FILE: e2e/tests/svgScreenshots/utils/constants.ts
  constant DOCS_DIR (line 4) | const DOCS_DIR = path.join(__dirname, "../../../../docs/");
  constant SCREENSHOTS_PATH (line 9) | const SCREENSHOTS_PATH = "/screenshots";
  constant SVGIF_SCENES_PATH (line 10) | const SVGIF_SCENES_PATH = "/svgif-scenes";
  constant SVG_SCREENSHOT_DIR (line 12) | const SVG_SCREENSHOT_DIR = path.join(DOCS_DIR, SCREENSHOTS_PATH);
  constant SVGIF_SCENES_DIR (line 13) | const SVGIF_SCENES_DIR = path.join(
  type SVGifScene (line 19) | type SVGifScene = SVGif.Scene;

FILE: e2e/tests/svgScreenshots/utils/saveSVGifs.ts
  type SVGIfSpec (line 11) | type SVGIfSpec = {

FILE: e2e/tests/testAskLLM.ts
  type ToolUse (line 31) | type ToolUse = {
  function dedent (line 327) | function dedent(str: string) {

FILE: e2e/tests/utils/constants.ts
  type USERS (line 1) | enum USERS {
  constant TEST_DB_NAME (line 10) | const TEST_DB_NAME = "Prostgles UI automated tests database";
  constant QUERIES (line 13) | const QUERIES = {

FILE: e2e/tests/utils/utils.ts
  type FuncNamesReturningLocatorObj (line 11) | type FuncNamesReturningLocatorObj = {
  type FuncNames (line 22) | type FuncNames = keyof FuncNamesReturningLocatorObj;
  type LocatorFuncNamesReturningLocatorObj (line 23) | type LocatorFuncNamesReturningLocatorObj = {
  type LocatorFuncNames (line 35) | type LocatorFuncNames = keyof LocatorFuncNamesReturningLocatorObj;
  type PageWIds (line 36) | type PageWIds = Omit<PG, FuncNames | "getByTestId"> & {
  type LocatorOverridenFuncNames (line 45) | type LocatorOverridenFuncNames = "getByTestId" | "all" | "last";
  type LocatorWIds (line 46) | type LocatorWIds = Omit<
  type KeyPress (line 88) | type KeyPress = "Control" | "Shift";
  type InputKey (line 89) | type InputKey =
  type ArrowKey (line 97) | type ArrowKey = "ArrowUp" | "ArrowDown" | "ArrowLeft" | "ArrowRight";
  type ArrowKeyCombinations (line 98) | type ArrowKeyCombinations = `${KeyPress}+${ArrowKey | InputKey}`;
  type KeyPressOrCombination (line 99) | type KeyPressOrCombination = InputKey | ArrowKeyCombinations | ArrowKey;
  type FFilter (line 364) | type FFilter = { fieldName: string; value: string }[];
  type FData (line 365) | type FData = Record<string, string>;
  constant MINUTE (line 584) | const MINUTE = 60e3;

FILE: electron/e2e-electron/electron.spec.tsx
  constant MINUTE (line 172) | const MINUTE = 60e3;

FILE: electron/main.ts
  type SafeStorageHandles (line 34) | type SafeStorageHandles = Pick<SafeStorage, "encryptString" | "decryptSt...
  type StartParams (line 36) | type StartParams = {
  function initApp (line 66) | function initApp() {

FILE: electron/win-inno-setup.ts
  function getInnoConfig (line 31) | function getInnoConfig(rootFiles: fs.Dirent[], rootLocationWin: string) {

FILE: server/sample_schemas/_crypto.sql
  type user_statuses (line 1) | CREATE TABLE user_statuses (
  type users (line 8) | CREATE TABLE users (
  type registrations (line 16) | CREATE TABLE registrations (
  type idx_registrations_user_id (line 29) | CREATE INDEX idx_registrations_user_id ON registrations (user_id)
  type registration_statuses (line 31) | CREATE TABLE registration_statuses (
  type cryptocurrencies (line 42) | CREATE TABLE cryptocurrencies (
  type wallets (line 48) | CREATE TABLE wallets (
  type idx_wallets_user_id (line 54) | CREATE INDEX idx_wallets_user_id ON wallets (user_id)
  type trades (line 57) | CREATE TABLE trades (
  type idx_trades_user_id (line 65) | CREATE INDEX idx_trades_user_id ON trades (user_id)
  type idx_trades_cryptocurrency_id (line 66) | CREATE INDEX idx_trades_cryptocurrency_id ON trades (cryptocurrency_id)
  type audit_logs (line 68) | CREATE TABLE audit_logs (
  type support_tickets (line 76) | CREATE TABLE support_tickets (
  type idx_support_tickets_user_id (line 84) | CREATE INDEX idx_support_tickets_user_id ON support_tickets (user_id)
  type support_replies (line 87) | CREATE TABLE support_replies (
  type idx_support_replies_support_ticket_id (line 94) | CREATE INDEX idx_support_replies_support_ticket_id ON support_replies (s...

FILE: server/sample_schemas/cleaning.sql
  type users (line 1) | CREATE TABLE users (
  type cleaners (line 8) | CREATE TABLE cleaners (
  type houses (line 18) | CREATE TABLE houses (
  type appointments (line 24) | CREATE TABLE appointments (
  type idx_appointments_date (line 33) | CREATE INDEX idx_appointments_date ON appointments (start_time)
  type payments (line 35) | CREATE TABLE payments (
  type reviews (line 42) | CREATE TABLE reviews (

FILE: server/sample_schemas/cloud_computing.sql
  type users (line 2) | CREATE TABLE users (
  type vm_status_values (line 12) | CREATE TABLE vm_status_values (
  type vms (line 28) | CREATE TABLE vms (
  type ssh_keys (line 40) | CREATE TABLE ssh_keys (
  type domains (line 48) | CREATE TABLE domains (
  type dns_records (line 56) | CREATE TABLE dns_records (

FILE: server/sample_schemas/countries.sql
  type countries (line 3) | CREATE TABLE countries (
  type country_goejson (line 11) | CREATE TABLE country_goejson (

FILE: server/sample_schemas/crypto/onMount.ts
  constant SECOND (line 1) | const SECOND = 1e3;
  constant FUNDING_SYMBOLS (line 4) | const FUNDING_SYMBOLS = [
  constant HISTORICAL_DATA_START (line 172) | const HISTORICAL_DATA_START = Date.now() - 7 * 24 * 60 * 60 * 1000;
  constant MARKETS (line 276) | const MARKETS = {

FILE: server/sample_schemas/crypto/tableConfig.ts
  type TableConfig (line 1) | type TableConfig = Record<

FILE: server/sample_schemas/crypto/workspaceConfig.ts
  type WorkspaceConfig (line 4) | type WorkspaceConfig = {

FILE: server/sample_schemas/financial.sql
  type users (line 2) | CREATE TABLE users (
  type institutions (line 12) | CREATE TABLE institutions (
  type accounts (line 19) | CREATE TABLE accounts (
  type transactions (line 29) | CREATE TABLE transactions (
  type registrations (line 43) | CREATE TABLE registrations (

FILE: server/sample_schemas/food_delivery/onInit.sql
  type customers_info_view (line 773) | CREATE OR REPLACE VIEW customers_info_view AS
  function setof_fake_contacts (line 778) | CREATE OR REPLACE FUNCTION setof_fake_contacts(num int4) RETURNS SETOF c...
  type user_types (line 792) | CREATE TABLE user_types (
  type addresses (line 803) | CREATE TABLE addresses (
  type idx_addresses (line 813) | CREATE INDEX idx_addresses ON addresses USING gist (geog)
  type users (line 816) | CREATE TABLE users (
  type idx_users_email (line 828) | create index idx_users_email on users (email)
  type idx_users_id_email (line 829) | create index idx_users_id_email on users (id, email)
  type idx_users_id_type (line 830) | create index idx_users_id_type on users (id, type)
  type idx_users_type (line 831) | create index idx_users_type on users (type)
  type user_addresses (line 833) | CREATE TABLE user_addresses (
  type restaurants (line 839) | CREATE TABLE restaurants (
  type idx_restaurants_address_id (line 848) | CREATE INDEX idx_restaurants_address_id ON restaurants ( address_id )
  type idx_restaurants_id_address_id (line 849) | CREATE INDEX idx_restaurants_id_address_id ON restaurants ( id, address_...
  type restaurant_managers (line 851) | CREATE TABLE restaurant_managers (
  type menu_items (line 857) | CREATE TABLE menu_items (
  type delivery_status_types (line 868) | CREATE TABLE delivery_status_types (
  type order_status_types (line 879) | CREATE TABLE order_status_types (
  type orders (line 893) | CREATE TABLE orders (
  type orders (line 909) | CREATE INDEX ON orders (restaurant_id)
  type orders (line 910) | CREATE INDEX ON orders (customer_id)
  type orders (line 911) | CREATE INDEX ON orders (deliverer_id)
  type orders (line 912) | CREATE INDEX ON orders (created_at)
  type orders (line 913) | CREATE INDEX ON orders (status, created_at)
  type orders (line 914) | CREATE INDEX ON orders (customer_id, created_at)
  type orders (line 915) | CREATE INDEX ON orders (deliverer_id, created_at)
  type order_items (line 917) | CREATE TABLE order_items (
  type order_updates (line 926) | CREATE TABLE order_updates (
  type delivery_status_changes (line 934) | CREATE TABLE delivery_status_changes (
  type ratings (line 941) | CREATE TABLE ratings (
  type "london_restaurants.geojson" (line 992) | CREATE TABLE IF NOT EXISTS "london_restaurants.geojson" (
  type idx_london (line 1005) | CREATE INDEX IF NOT EXISTS idx_london
  type customers (line 1160) | CREATE OR REPLACE VIEW customers AS
  type v_riders (line 1177) | CREATE OR REPLACE VIEW v_riders AS
  type v_restaurants (line 1191) | CREATE OR REPLACE  VIEW v_restaurants AS

FILE: server/sample_schemas/food_delivery/workspaceConfig.ts
  type WorkspaceConfig (line 4) | type WorkspaceConfig = {

FILE: server/sample_schemas/lodging.sql
  type users (line 2) | CREATE TABLE users (
  type listings (line 14) | CREATE TABLE listings (
  type reservations (line 30) | CREATE TABLE reservations (
  type reviews (line 41) | CREATE TABLE reviews (

FILE: server/sample_schemas/maps.sql
  type users (line 1) | CREATE TABLE users (
  type places (line 12) | CREATE TABLE places (
  type opening_hours (line 29) | CREATE TABLE opening_hours (
  type place_types (line 38) | CREATE TABLE place_types (
  type place_type_icons (line 46) | CREATE TABLE place_type_icons (
  type photos (line 53) | CREATE TABLE photos (
  type reviews (line 65) | CREATE TABLE reviews (

FILE: server/sample_schemas/property_management/workspaceConfig.ts
  type WorkspaceConfig (line 5) | type WorkspaceConfig = {

FILE: server/sample_schemas/sales.sql
  type users (line 2) | CREATE TABLE users (
  type accounts (line 13) | CREATE TABLE accounts (
  type contacts (line 22) | CREATE TABLE contacts (
  type opportunities (line 32) | CREATE TABLE opportunities (
  type tasks (line 43) | CREATE TABLE tasks (

FILE: server/sample_schemas/sample.sql
  type account_statuses (line 4) | CREATE TABLE account_statuses (
  type customers (line 12) | CREATE TABLE customers (
  type products (line 50) | CREATE TABLE products (
  type orders (line 58) | CREATE TABLE orders (
  type order_items (line 66) | CREATE TABLE order_items (

FILE: server/sample_schemas/weather/onMount.ts
  type ForecastDetails (line 135) | type ForecastDetails = {
  type TimeSeriesEntry (line 143) | type TimeSeriesEntry = {
  type ForecastResponse (line 160) | type ForecastResponse = {
  constant EUROPE_BBOX (line 187) | const EUROPE_BBOX = "(34,-25,72,45)";

FILE: server/src/BackupManager/BackupManager.ts
  type Backups (line 9) | type Backups = Required<DBGeneratedSchema["backups"]>["columns"];
  type DumpOpts (line 10) | type DumpOpts = Backups["options"];
  type DumpOptsServer (line 11) | type DumpOptsServer = DumpOpts & { initiator: string };
  type Users (line 13) | type Users = Required<DBGeneratedSchema["users"]["columns"]>;
  type Connections (line 14) | type Connections = Required<DBGeneratedSchema["connections"]["columns"]>;
  type DBS (line 15) | type DBS = DBOFullyTyped<DBGeneratedSchema>;
  constant HOUR (line 31) | const HOUR = 3600 * 1000;
  class BackupManager (line 33) | class BackupManager {
    method constructor (line 44) | constructor(
    method destroy (line 93) | async destroy() {

FILE: server/src/BackupManager/checkAutomaticBackup.ts
  function checkAutomaticBackup (line 6) | async function checkAutomaticBackup(

FILE: server/src/BackupManager/pgDump.ts
  function pgDump (line 16) | async function pgDump(

FILE: server/src/BackupManager/pgRestore.ts
  function pgRestore (line 11) | async function pgRestore(

FILE: server/src/BackupManager/pipeFromCommand.ts
  type EnvVars (line 5) | type EnvVars = Record<string, string> | {};
  function pipeFromCommand (line 14) | function pipeFromCommand(params: {

FILE: server/src/BackupManager/utils.ts
  function getFileMgr (line 16) | async function getFileMgr(dbs: DBS, credId: number | null) {
  function getBkp (line 38) | async function getBkp(
  function bytesToSize (line 54) | function bytesToSize(bytes: number) {
  type Basics (line 61) | type Basics = string | number | boolean;
  function addOptions (line 62) | function addOptions(
  type ConnectionEnvVars (line 82) | type ConnectionEnvVars = {

FILE: server/src/ConnectionManager/ConnectionManager.ts
  type Unpromise (line 35) | type Unpromise<T extends Promise<any>> =
  type ConnectionTableConfig (line 38) | type ConnectionTableConfig = Pick<FileTableConfig, "referencedTables"> &
  type User (line 41) | type User = DBSSchema["users"];
  type DBWithUsers (line 52) | type DBWithUsers = { users?: Partial<DBS["users"]> };
  type PRGLInstance (line 54) | type PRGLInstance = {
  type HotReloadConfigOptions (line 73) | type HotReloadConfigOptions = Pick<
  class ConnectionManager (line 98) | class ConnectionManager {
    method constructor (line 108) | constructor(http: httpServer, app: Express) {
    method setUpWSS (line 398) | setUpWSS() {
    method getFileFolderPath (line 416) | getFileFolderPath(conId?: string) {
    method getConnectionDb (line 425) | getConnectionDb(
    method getNewConnectionDb (line 431) | async getNewConnectionDb(
    method getConnection (line 438) | getConnection(
    method getConnections (line 448) | getConnections() {
    method disconnect (line 452) | async disconnect(conId: string): Promise<boolean> {
    method getConnectionData (line 467) | async getConnectionData(connection_id: string) {

FILE: server/src/ConnectionManager/ForkedPrglProcRunner/ForkedPrglProcRunner.ts
  type ForkedProcMessageCommon (line 11) | type ForkedProcMessageCommon = {
  type PrglInitOptions (line 15) | type PrglInitOptions = Omit<ProstglesInitOptions, "onReady">;
  type ForkedProcMessageStart (line 17) | type ForkedProcMessageStart = ForkedProcMessageCommon & {
  type ForkedProcRunArgs (line 21) | type ForkedProcRunArgs =
  type ForkedProcMessageRun (line 32) | type ForkedProcMessageRun = ForkedProcMessageCommon & ForkedProcRunArgs;
  type ForkedProcMCPResult (line 33) | type ForkedProcMCPResult = ForkedProcMessageCommon & {
  type ForkedProcMessage (line 40) | type ForkedProcMessage =
  type ForkedProcMessageError (line 45) | type ForkedProcMessageError = {
  type ForkedProcMessageResult (line 51) | type ForkedProcMessageResult =
  type Opts (line 67) | type Opts = {
  class ForkedPrglProcRunner (line 91) | class ForkedPrglProcRunner {
    method constructor (line 106) | private constructor(proc: ChildProcess, opts: Opts) {
  function debounce (line 331) | function debounce<Params extends any[]>(

FILE: server/src/ConnectionManager/ForkedPrglProcRunner/forkedProcess.ts
  method get (line 23) | get(target, prop: keyof OnReadyParamsBasic, receiver) {
  function checkForImportBug (line 144) | function checkForImportBug() {

FILE: server/src/ConnectionManager/connectionManagerUtils.ts
  type ParseTableConfigArgs (line 20) | type ParseTableConfigArgs = {
  type TableDbConfig (line 160) | type TableDbConfig = Pick<DatabaseConfigs, "table_config" | "table_confi...
  type CompiledTableConfig (line 161) | type CompiledTableConfig = { tableConfig: TableConfig; dashboardConfig?:...
  type FileTableConfigReferences (line 179) | type FileTableConfigReferences = Record<
  type AlertIfReferencedFileColumnsRemovedArgs (line 184) | type AlertIfReferencedFileColumnsRemovedArgs = {

FILE: server/src/ConnectionManager/getConnectionPublish.ts
  type Args (line 14) | type Args = {

FILE: server/src/ConnectionManager/getConnectionPublishMethods.ts
  type Args (line 17) | type Args = {

FILE: server/src/ConnectionManager/initConnectionManager.ts
  function initConnectionManager (line 10) | async function initConnectionManager(

FILE: server/src/ConnectionManager/saveCertificates.ts
  constant PROSTGLES_CERTS_FOLDER (line 46) | const PROSTGLES_CERTS_FOLDER = "prostgles_certificates";
  function getSSLEnvVars (line 55) | function getSSLEnvVars(c: Connections): EnvVars {

FILE: server/src/McpHub/AnthropicMcpHub/McpHub.ts
  type McpConnection (line 19) | type McpConnection = {
  class McpHub (line 31) | class McpHub {
    method constructor (line 35) | constructor() {}
    method getServers (line 43) | getServers(): McpServer[] {
    method connectToServer (line 50) | private async connectToServer(initInfo: MCPServerInitInfo): Promise<vo...
    method destroyConnection (line 71) | private async destroyConnection(name: string): Promise<void> {
    method setServerConnections (line 79) | async setServerConnections(serversConfig: ServersConfig): Promise<void> {
    method readResource (line 131) | async readResource(
    method callTool (line 155) | async callTool(
    method destroy (line 186) | async destroy(): Promise<void> {

FILE: server/src/McpHub/AnthropicMcpHub/McpTypes.ts
  type McpMode (line 4) | type McpMode = "full" | "server-use-only" | "off";
  type McpServer (line 6) | type McpServer = {
  type McpTool (line 17) | type McpTool = ListToolsResult["tools"][number];
  type McpResource (line 19) | type McpResource = {
  type McpResourceTemplate (line 26) | type McpResourceTemplate = {
  type McpResourceResponse (line 33) | type McpResourceResponse = {
  type McpMarketplaceItem (line 43) | interface McpMarketplaceItem {
  type McpMarketplaceCatalog (line 64) | interface McpMarketplaceCatalog {
  type McpDownloadResponse (line 68) | interface McpDownloadResponse {
  type McpServerEvents (line 79) | type McpServerEvents = {
  type McpConfigWithEvents (line 88) | type McpConfigWithEvents = StdioServerParameters & McpServerEvents;
  type ServersConfig (line 90) | type ServersConfig = Record<

FILE: server/src/McpHub/AnthropicMcpHub/connectToMCPServer.ts
  type MCPServerInitInfo (line 22) | type MCPServerInitInfo = McpServerEvents & {

FILE: server/src/McpHub/ProstglesMcpHub/ProstglesMCPServerTypes.ts
  type ProstglesMcpServerDefinition (line 7) | type ProstglesMcpServerDefinition = {
  type JSONBTypeIfDefined (line 22) | type JSONBTypeIfDefined<Schema extends JSONB.FieldType | undefined> =
  type MaybePromise (line 25) | type MaybePromise<T> = T | Promise<T>;
  type McpCallContext (line 27) | type McpCallContext = {
  type ProstglesMcpServerHandler (line 33) | type ProstglesMcpServerHandler = {
  type ProstglesMcpServerHandlerInstance (line 39) | type ProstglesMcpServerHandlerInstance = {
  type ProstglesMcpServerHandlerTyped (line 57) | type ProstglesMcpServerHandlerTyped<

FILE: server/src/McpHub/ProstglesMcpHub/ProstglesMCPServers/DockerSandbox/createContainer.ts
  type CreateContainerResult (line 10) | type CreateContainerResult = JSONBTypeIfDefined<

FILE: server/src/McpHub/ProstglesMcpHub/ProstglesMCPServers/DockerSandbox/dockerMCPServerProxy/dockerContainerAuthRegistry.ts
  constant DOCKER_CONTAINER_NAME_PREFIX (line 5) | const DOCKER_CONTAINER_NAME_PREFIX = "prostgles-docker-mcp-sandbox";
  type CreateContainerContext (line 7) | type CreateContainerContext = {
  type ContainerAuthInfo (line 12) | type ContainerAuthInfo = {

FILE: server/src/McpHub/ProstglesMcpHub/ProstglesMCPServers/DockerSandbox/dockerMCPServerProxy/dockerMCPServerProxy.ts
  constant PREFERRED_PORT (line 15) | const PREFERRED_PORT = 3009;
  constant DOCKER_MCP_ENDPOINT (line 16) | const DOCKER_MCP_ENDPOINT = "/db";
  constant ROUTE (line 17) | const ROUTE = `${DOCKER_MCP_ENDPOINT}/:endpoint`;
  type ChatPermissions (line 19) | type ChatPermissions = Pick<
  type AuhtContext (line 24) | type AuhtContext = {
  type GetAuthContext (line 29) | type GetAuthContext = (ip: string) => AuhtContext | undefined;

FILE: server/src/McpHub/ProstglesMcpHub/ProstglesMCPServers/DockerSandbox/executeDockerCommand.ts
  type ProcessLog (line 3) | type ProcessLog = {
  type ExecutionResult (line 7) | interface ExecutionResult {

FILE: server/src/McpHub/ProstglesMcpHub/ProstglesMCPServers/DockerSandbox/fetchTools.ts
  type CreateContainerParams (line 56) | type CreateContainerParams = JSONB.GetSchemaType<

FILE: server/src/McpHub/ProstglesMcpHub/ProstglesMCPServers/DockerSandbox/getDockerRunArgs.ts
  constant CUSTOM_BRIDGE_NETWORK_NAME (line 3) | const CUSTOM_BRIDGE_NETWORK_NAME = "prostgles-bridge-net";
  constant LABEL (line 4) | const LABEL = "prostgles-docker-sandbox";
  type LocalDockerParams (line 6) | type LocalDockerParams = {

FILE: server/src/SecurityManager/initUsers.ts
  constant EMPTY_PASSWORD (line 13) | const EMPTY_PASSWORD = "";

FILE: server/src/ServiceManager/ServiceManager.ts
  class ServiceManager (line 14) | class ServiceManager {
    method constructor (line 16) | constructor(dbs: DBS | undefined) {
    method getActiveService (line 39) | getActiveService<Status extends ServiceInstance["status"]>(
    method getService (line 52) | getService<

FILE: server/src/ServiceManager/ServiceManagerTypes.ts
  type DockerGPUS (line 10) | type DockerGPUS = "none" | "all" | number | number[];
  type ProstglesService (line 12) | type ProstglesService = {
  type RunningServiceInstance (line 60) | type RunningServiceInstance<
  type ServiceInstance (line 76) | type ServiceInstance<
  type OnServiceLogs (line 105) | type OnServiceLogs = (logs: ProcessLog[]) => void;

FILE: server/src/ServiceManager/buildService.ts
  function buildService (line 19) | async function buildService(

FILE: server/src/ServiceManager/dockerInspect.ts
  type DockerInspectResult (line 27) | type DockerInspectResult = {

FILE: server/src/ServiceManager/enableService.ts
  function enableService (line 5) | async function enableService(

FILE: server/src/ServiceManager/services/speechToText/src/app.py
  function get_model (line 28) | def get_model():
  function transcribe (line 37) | def transcribe():
  function health (line 107) | def health():

FILE: server/src/ServiceManager/startService.ts
  function startService (line 21) | async function startService(

FILE: server/src/ServiceManager/stopService.ts
  function stopService (line 6) | function stopService(

FILE: server/src/authConfig/OAuthProviders/getOAuthLoginProviders.ts
  type AuthProviders (line 6) | type AuthProviders = DBSSchema["global_settings"]["auth_providers"];

FILE: server/src/authConfig/OAuthProviders/loginWithProvider.ts
  type LoginReturnType (line 12) | type LoginReturnType = ReturnType<

FILE: server/src/authConfig/authUtils.ts
  constant ITERATIONS (line 4) | const ITERATIONS = 1e5;
  constant KEY_LENGTH (line 5) | const KEY_LENGTH = 512;

FILE: server/src/authConfig/emailProvider/getEmailSenderWithMockTest.ts
  type EmailClient (line 26) | type EmailClient = Unpromise<
  type EmailData (line 92) | type EmailData = {

FILE: server/src/authConfig/getActiveSession.ts
  type AuthType (line 7) | type AuthType =

FILE: server/src/authConfig/getAuth.ts
  type WithOrigin (line 35) | type WithOrigin = {
  type GetAuthResult (line 53) | type GetAuthResult = Awaited<ReturnType<typeof getAuth>>;

FILE: server/src/authConfig/getUser.ts
  type GetUser (line 18) | type GetUser = NonNullable<AuthConfig<DBGeneratedSchema, SUser>["getUser...
  type NewRedirectSession (line 101) | type NewRedirectSession = {

FILE: server/src/authConfig/sessionUtils.ts
  type Sessions (line 16) | type Sessions = DBSSchema["sessions"];
  type SUser (line 59) | type SUser = {
  constant PASSWORDLESS_ADMIN_ALREADY_EXISTS_ERROR (line 142) | const PASSWORDLESS_ADMIN_ALREADY_EXISTS_ERROR =

FILE: server/src/authConfig/startRateLimitedLoginAttempt.ts
  type FailedAttemptsInfo (line 9) | type FailedAttemptsInfo =
  type AuthAttepmt (line 70) | type AuthAttepmt =

FILE: server/src/authConfig/subscribeToAuthSetupChanges.ts
  type AuthSetupData (line 11) | type AuthSetupData = {
  type AuthSetupDataListener (line 23) | type AuthSetupDataListener = Promise<{

FILE: server/src/authConfig/upsertSession.ts
  type CreateSessionArgs (line 8) | type CreateSessionArgs = {

FILE: server/src/cloudClients/cloudClients.ts
  type S3Config (line 17) | type S3Config = {

FILE: server/src/connectionUtils/getConnectionDetails.ts
  type Connections (line 2) | type Connections = Required<DBGeneratedSchema["connections"]["columns"]>;
  type ConnectionDetails (line 6) | type ConnectionDetails = Required<

FILE: server/src/connectionUtils/testDBConnection.ts
  type Connections (line 4) | type Connections = Required<DBGeneratedSchema["connections"]["columns"]>;
  constant NO_SSL_SUPPORT_ERROR (line 13) | const NO_SSL_SUPPORT_ERROR = "The server does not support SSL connections";

FILE: server/src/connectionUtils/validateConnection.ts
  type Connections (line 4) | type Connections = Required<DBGeneratedSchema["connections"]["columns"]>;
  type ConnectionInsert (line 5) | type ConnectionInsert = DBGeneratedSchema["connections"]["columns"];
  type ConnectionDefaults (line 7) | type ConnectionDefaults = Pick<
  type ValidatedConnectionDetails (line 20) | type ValidatedConnectionDetails = Required<ConnectionDefaults> & {
  type ConnectionInfo (line 25) | type ConnectionInfo = Partial<

FILE: server/src/electronConfig.ts
  type Connections (line 6) | type Connections = Required<DBGeneratedSchema["connections"]["columns"]>;
  type DBSConnectionInfo (line 7) | type DBSConnectionInfo = Pick<
  type OnServerReadyCallback (line 18) | type OnServerReadyCallback = (portNumber: number) => void;
  type SafeStorage (line 20) | type SafeStorage = {

FILE: server/src/envVars.ts
  constant DBS_CONNECTION_INFO (line 31) | const DBS_CONNECTION_INFO = validateConnection({

FILE: server/src/getPSQLQueries.ts
  constant COMMANDS (line 1) | const COMMANDS = [

FILE: server/src/index.ts
  constant PORT (line 38) | const PORT =
  constant LOCALHOST (line 42) | const LOCALHOST = "127.0.0.1";
  constant HOST (line 43) | const HOST =
  function restartProc (line 176) | function restartProc(cb?: VoidFunction) {
  type BareConnectionDetails (line 208) | type BareConnectionDetails = Pick<
  type DBS (line 220) | type DBS = DBOFullyTyped<DBGeneratedSchema>;
  type Users (line 221) | type Users = Required<DBGeneratedSchema["users"]["columns"]>;
  type Connections (line 222) | type Connections = Required<DBGeneratedSchema["connections"]["columns"]>;
  type DatabaseConfigs (line 223) | type DatabaseConfigs = DBSSchema["database_configs"];
  type OnServerReadyResult (line 232) | type OnServerReadyResult = {

FILE: server/src/init/logOutgoingHttpRequests.ts
  function requestLogger (line 1) | function requestLogger(httpModule: any) {

FILE: server/src/init/onProstglesReady.ts
  type AsyncCleanup (line 80) | type AsyncCleanup = () => Promise<{ cleanup: () => Promise<void> }>;

FILE: server/src/init/startProstgles.ts
  type StartArguments (line 24) | type StartArguments = {
  type InitExtra (line 33) | type InitExtra = {
  type ProstglesInitStateWithDBS (line 36) | type ProstglesInitStateWithDBS = ProstglesInitState<InitExtra>;

FILE: server/src/init/tryStartProstgles.ts
  type StartArguments (line 19) | type StartArguments = {
  type FinishedState (line 27) | type FinishedState = Exclude<ProstglesInitStateWithDBS, { state: "loadin...
  type StateListener (line 28) | type StateListener = (state: FinishedState) => void;
  constant RETRY_CONFIG (line 54) | const RETRY_CONFIG = {

FILE: server/src/methods/getPidStats.ts
  type PS_ProcInfo (line 16) | type PS_ProcInfo = {
  type ServerLoadStats (line 24) | type ServerLoadStats = {
  type PidStatProgs (line 155) | type PidStatProgs = keyof typeof pidStatsMethods;
  type PidStatMode (line 156) | type PidStatMode = PidStatProgs | "off";
  type ConnectionStatInfo (line 157) | type ConnectionStatInfo = {

FILE: server/src/publish/publish.ts
  type User (line 102) | type User = DBGeneratedSchema["users"]["columns"];

FILE: server/src/publishMethods/applySampleSchema.ts
  type Users (line 6) | type Users = Required<DBGeneratedSchema["users"]["columns"]>;
  type Connections (line 7) | type Connections = Required<DBGeneratedSchema["connections"]["columns"]>;

FILE: server/src/publishMethods/askLLM/LLMResponseTypes.ts
  type CompletionUsage (line 6) | type CompletionUsage = {
  type CompletionTokensDetails (line 41) | type CompletionTokensDetails = {
  type PromptTokensDetails (line 70) | type PromptTokensDetails = {
  type ErrorResponse (line 85) | type ErrorResponse = {
  type Choice (line 91) | type Choice = {
  type ChatCompletionMessage (line 132) | type ChatCompletionMessage = {
  type ChatCompletionMessageToolCall (line 163) | type ChatCompletionMessageToolCall = {
  type ChatCompletionAudio (line 198) | type ChatCompletionAudio = {
  type OpenAIChatCompletionResponse (line 225) | type OpenAIChatCompletionResponse = {
  type AnthropicTextResponse (line 258) | type AnthropicTextResponse = {
  type AnthropicToolUseResponse (line 262) | type AnthropicToolUseResponse = {
  type AnthropicChatCompletionResponse (line 268) | type AnthropicChatCompletionResponse = {
  type GoogleGeminiChatCompletionResponse (line 287) | type GoogleGeminiChatCompletionResponse = {

FILE: server/src/publishMethods/askLLM/askLLM.ts
  type LLMMessage (line 45) | type LLMMessage = DBSSchema["llm_messages"]["message"];
  type AskLLMArgs (line 47) | type AskLLMArgs = {

FILE: server/src/publishMethods/askLLM/fetchLLMResponse.ts
  type LLMMessageWithRole (line 14) | type LLMMessageWithRole = {
  type FetchLLMResponseArgs (line 18) | type FetchLLMResponseArgs = {

FILE: server/src/publishMethods/askLLM/getLLMToolsAllowedInThisChat.ts
  type GetLLMToolsArgs (line 18) | type GetLLMToolsArgs = {
  type MCPToolSchema (line 27) | type MCPToolSchema = {

FILE: server/src/publishMethods/askLLM/getUserMessageCost.ts
  constant TOKENS_PER_CHARACTER (line 5) | const TOKENS_PER_CHARACTER = 0.25;

FILE: server/src/publishMethods/askLLM/parseLLMResponseObject.ts
  type LLMResponseParser (line 16) | type LLMResponseParser<T = AnyObject> = (args: {
  type LLMParsedResponse (line 22) | type LLMParsedResponse = Pick<LLMMessageWithRole, "content"> & {

FILE: server/src/publishMethods/askLLM/prostglesLLMTools/getProstglesDBTools.ts
  type DBTool (line 10) | type DBTool = Extract<ProstglesMcpTool, { type: "prostgles-db" }> & {
  constant COMMANDS (line 80) | const COMMANDS = ["select", "update", "insert", "delete"] as const;

FILE: server/src/publishMethods/askLLM/prostglesLLMTools/runProstglesDBTool.ts
  type DbToolsInfo (line 25) | type DbToolsInfo = (typeof PROSTGLES_MCP_SERVERS_AND_TOOLS)["prostgles-d...

FILE: server/src/publishMethods/askLLM/refreshModels.ts
  constant LLM_PROVIDERS (line 84) | const LLM_PROVIDERS = ["OpenAI", "Anthropic", "Google"];
  type ModelInfo (line 86) | type ModelInfo = {

FILE: server/src/publishMethods/askLLM/runApprovedTools/runApprovedTools.ts
  type ToolUseMessage (line 24) | type ToolUseMessage = Extract<LLMMessage[number], { type: "tool_use" }>;
  type ToolUseMessageWithInfo (line 25) | type ToolUseMessageWithInfo =
  type ToolResultMessage (line 42) | type ToolResultMessage = Extract<LLMMessage[number], { type: "tool_resul...

FILE: server/src/publishMethods/askLLM/setupLLM.ts
  type ModelInfo (line 432) | type ModelInfo = {

FILE: server/src/publishMethods/getNodeTypes.ts
  type TypeFile (line 13) | interface TypeFile {
  function extractInstalledPackageTypes (line 24) | function extractInstalledPackageTypes(projectDir: string): TypeFile[] {
  function shouldWrapFile (line 166) | function shouldWrapFile(sourceFile: ts.SourceFile): boolean {
  function wrapIfNeeded (line 182) | function wrapIfNeeded(

FILE: server/src/publishMethods/publishMethods.ts
  type Users (line 11) | type Users = Required<DBGeneratedSchema["users"]["columns"]>;
  type Connections (line 12) | type Connections = Required<DBGeneratedSchema["connections"]["columns"]>;

FILE: server/src/tableConfig/tableConfig.ts
  constant UNIQUE_DB_COLS (line 17) | const UNIQUE_DB_COLS = ["db_name", "db_host", "db_port"] as const;
  constant UNIQUE_DB_FIELDLIST (line 18) | const UNIQUE_DB_FIELDLIST = UNIQUE_DB_COLS.join(", ");
  constant SESSION_TYPE (line 101) | const SESSION_TYPE = {

FILE: server/src/tableConfig/tableConfigBackups.ts
  constant DUMP_OPTIONS_SCHEMA (line 3) | const DUMP_OPTIONS_SCHEMA = {

FILE: server/src/tableConfig/tableConfigConnections.ts
  constant UNIQUE_DB_COLS (line 3) | const UNIQUE_DB_COLS = ["db_name", "db_host", "db_port"] as const;
  constant UNIQUE_DB_FIELDLIST (line 4) | const UNIQUE_DB_FIELDLIST = UNIQUE_DB_COLS.join(", ");
  constant DB_SSL_ENUM (line 6) | const DB_SSL_ENUM = [
Condensed preview — 1271 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (6,658K chars).
[
  {
    "path": ".dockerignore",
    "chars": 162,
    "preview": ".git\n.env\n.github\n.vscode\nscripts/demo\ne2e\nelectron\nreleases\n**/node_modules\n**/dist\n**/prostgles_backups\n**/prostgles_m"
  },
  {
    "path": ".eslintrc.common.js",
    "chars": 1827,
    "preview": "/**\n * @type {import('eslint').Linter.Config}\n */\nmodule.exports = {\n  // \"root\": true,\n  parserOptions: {\n    ecmaVersi"
  },
  {
    "path": ".gitattributes",
    "chars": 54,
    "preview": "# Never modify line endings of bash scripts\n*.sh -crlf"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/BUG.yml",
    "chars": 1343,
    "preview": "name: Bug Report\ndescription: File a bug report\ntitle: \"[Bug]: \"\nlabels: [\"bug\", \"triage\"]\nassignees:\n  - octocat\nbody:\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/CUSTOM.yml",
    "chars": 250,
    "preview": "name: Custom issue\ndescription: File a feature request\ntitle: \"[Title]\"\nassignees:\n  - prostgles\nbody:\n  - type: textare"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/FEATURE.yml",
    "chars": 686,
    "preview": "name: Feature request\ndescription: File a feature request\ntitle: \"[Feature]: \"\nlabels: [\"feature\"]\nassignees:\n  - prostg"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 106,
    "preview": "### Actual Behavior\n\n### Expected Behavior\n\n### Steps to reproduce the issue\n\n#### Data used\n\n#### Config\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 28,
    "preview": "blank_issues_enabled: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/custom.md",
    "chars": 27,
    "preview": "## Issue title\n\n## Details\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 94,
    "preview": "## Requested Behavior\n\n## Use Cases\n\n## Current work arounds to accomplish requested behavior\n"
  },
  {
    "path": ".github/workflows/docker_test.yml",
    "chars": 1490,
    "preview": "name: Test docker scripts\non:\n  pull_request:\n    branches: [main, master]\n  merge_group:\nconcurrency:\n  group: ${{ gith"
  },
  {
    "path": ".github/workflows/electron_build_linux.yml",
    "chars": 1421,
    "preview": "name: Electron build & test linux\non: workflow_dispatch\njobs:\n  electron_build:\n    timeout-minutes: 20\n    runs-on: ubu"
  },
  {
    "path": ".github/workflows/electron_build_macos.yml",
    "chars": 1166,
    "preview": "name: Electron build & test macOs\non: workflow_dispatch\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.pu"
  },
  {
    "path": ".github/workflows/electron_build_windows.yml",
    "chars": 927,
    "preview": "name: Electron build & test windows\non: workflow_dispatch\njobs:\n  electron_build_windows:\n    timeout-minutes: 12\n    ru"
  },
  {
    "path": ".github/workflows/electron_linux_test.yml",
    "chars": 575,
    "preview": "name: Electron test linux (deprecated)\non: workflow_dispatch\njobs:\n  electron_build:\n    timeout-minutes: 20\n    runs-on"
  },
  {
    "path": ".github/workflows/electron_macos_test.yml",
    "chars": 613,
    "preview": "name: Electron test macos (deprecated)\non: workflow_dispatch\njobs:\n  electron_build:\n    timeout-minutes: 20\n    runs-on"
  },
  {
    "path": ".github/workflows/linux_test.yml",
    "chars": 4206,
    "preview": "name: Linux & Electron test\non:\n  pull_request:\n    branches: [main, master]\n  merge_group:\nconcurrency:\n  group: ${{ gi"
  },
  {
    "path": ".github/workflows/macos_test.yml",
    "chars": 2701,
    "preview": "name: MacOS test\non: workflow_dispatch\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.pull_request.number"
  },
  {
    "path": ".github/workflows/on_release.yml",
    "chars": 5172,
    "preview": "name: On Release\non:\n  push:\n    tags:\n      - \"v*\"\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.ref }}\n  can"
  },
  {
    "path": ".github/workflows/package_version_increased.yml",
    "chars": 1853,
    "preview": "name: Ensure package version is higher\non:\n  pull_request:\n    branches: [main, master]\n  merge_group:\nconcurrency:\n  gr"
  },
  {
    "path": ".github/workflows/windows_test.yml",
    "chars": 1533,
    "preview": "name: Windows test\non: workflow_dispatch\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.pull_request.numb"
  },
  {
    "path": ".gitignore",
    "chars": 399,
    "preview": "node_modules\nprostgles_media\nprostgles_storage\nprostgles_backups\nprostgles_certificates\nprostgles_mcp\n.electron-auth.jso"
  },
  {
    "path": ".prettierignore",
    "chars": 73,
    "preview": "e2e/playwright-report/trace/\nserver/*.json\nclient/*.json\n.vscode/\n*.d.ts\n"
  },
  {
    "path": ".prettierrc",
    "chars": 36,
    "preview": "{\n  \"experimentalTernaries\": true\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 507,
    "preview": "{\n  \"git.terminalAuthentication\": false,\n  \"git.autofetch\": false,\n  \"git.ignoreLimitWarning\": true,\n  \"typescript.tsdk\""
  },
  {
    "path": "DB-Dockerfile",
    "chars": 261,
    "preview": "FROM postgis/postgis:17-3.4\n\n# Switch to root user to install packages\nUSER root\n\n# procps needed for stat monitoring\nRU"
  },
  {
    "path": "Dockerfile",
    "chars": 984,
    "preview": "FROM node:20-slim AS base\n\nWORKDIR /usr/src/app\n\nCOPY . .\n\n# Install latest pg_dump (psql v17) to ensure backup/restore "
  },
  {
    "path": "LICENSE",
    "chars": 34459,
    "preview": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C)"
  },
  {
    "path": "PRIVACY",
    "chars": 1730,
    "preview": "<p>\nWith the exception of information you voluntarily submit via the \"Send feedback\" feature, Prostgles does not collect"
  },
  {
    "path": "README.md",
    "chars": 3012,
    "preview": "# Prostgles UI\n\nSQL Editor and internal tool builder for Postgres\n\n[Live demo](https://playground.prostgles.com/)\n\n### S"
  },
  {
    "path": "SECURITY.md",
    "chars": 322,
    "preview": "# Security Policy\n\n### Reporting a Vulnerability\n\nPlease report (suspected) security vulnerabilities to security@prostgl"
  },
  {
    "path": "changelog/v1.0.0.md",
    "chars": 145,
    "preview": "Prostgles UI v1.0.0\n\nWorkspaces\nEach database connection now allows multiple workspaces. You can create and switch betwe"
  },
  {
    "path": "changelog/v2.0.0.md",
    "chars": 340,
    "preview": "Prostgles UI v2\n\nImproved UI\n- Referenced tables tab\n- SQL code blocks\n- SQL snippets\n\nAccess control\n- Role-based acces"
  },
  {
    "path": "changelog/v2.2.0.md",
    "chars": 942,
    "preview": "- Schema Diagram\n  - Link colouring modes to better understand related tables and foreign key properties\n  - Filtering b"
  },
  {
    "path": "changelog/v2.2.1.md",
    "chars": 110,
    "preview": "- Maintenance and fixes:\n  - Fixed docker release pipeline\n  - Updated electron packages\n  - Remove dead code\n"
  },
  {
    "path": "changelog/v2.2.2.md",
    "chars": 76,
    "preview": "- Improve documentation\n- Maintenance and fixes:\n  - Tidy release workflows\n"
  },
  {
    "path": "changelog/v2.2.3.md",
    "chars": 52,
    "preview": "- Improve documentation\n- Improve Docker MCP server\n"
  },
  {
    "path": "changelog/v2.2.4.md",
    "chars": 86,
    "preview": "- Improve documentation\n- Improve Tool use message UI\n- Fix parallel MCP requests bug\n"
  },
  {
    "path": "client/.babelrc",
    "chars": 502,
    "preview": "{\n  \"presets\": [\n    [\n      \"@babel/env\",\n      {\n        \"targets\": {\n          \"esmodules\": true\n        },\n        \""
  },
  {
    "path": "client/.gitignore",
    "chars": 350,
    "preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pn"
  },
  {
    "path": "client/build.sh",
    "chars": 139,
    "preview": "npm i && export NODE_ENV=production && export BABEL_ENV=production && export NODE_OPTIONS=--max-old-space-size=2048 && n"
  },
  {
    "path": "client/eslint.config.mjs",
    "chars": 3466,
    "preview": "// @ts-check\nimport commonConfig from \"../.eslintrc.common.js\";\nimport eslint from \"@eslint/js\";\nimport tseslint from \"t"
  },
  {
    "path": "client/package.json",
    "chars": 3627,
    "preview": "{\n  \"name\": \"prostgles-ui-client\",\n  \"dependencies\": {\n    \"@mdi/js\": \"^7.4.47\",\n    \"@types/dom-speech-recognition\": \"^"
  },
  {
    "path": "client/public/manifest.json",
    "chars": 236,
    "preview": "{\n  \"name\": \"Prostgles UI\",\n  \"short_name\": \"Prostgles UI\",\n  \"description\": \"Dashboard and SQL editor for PostgreSQL.\","
  },
  {
    "path": "client/public/robots.txt",
    "chars": 67,
    "preview": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "client/setup-icons.js",
    "chars": 1767,
    "preview": "/** Save all mdi icons as xml */\nconst fs = require(\"fs\");\nconst path = require(\"path\");\nconst icons = require(\"@mdi/js\""
  },
  {
    "path": "client/src/App.css",
    "chars": 378,
    "preview": "*,\nbody,\nhtml {\n  box-sizing: border-box;\n}\n\nbody {\n  overflow: hidden;\n}\n\n.page-content {\n  padding-top: 1em;\n}\n\n.activ"
  },
  {
    "path": "client/src/App.tsx",
    "chars": 10811,
    "preview": "import type { ReactChild } from \"react\";\nimport React, { useMemo, useState } from \"react\";\nimport { Navigate, Route, Rou"
  },
  {
    "path": "client/src/Testing.ts",
    "chars": 19537,
    "preview": "export const COMMANDS = {\n  \"NewConnectionForm.connectionName\": \"Connection name input field\",\n  \"NewConnectionForm.conn"
  },
  {
    "path": "client/src/WithPrgl.tsx",
    "chars": 447,
    "preview": "import React from \"react\";\nimport type { Prgl } from \"./App\";\nimport { createReactiveState, useReactiveState } from \"./a"
  },
  {
    "path": "client/src/app/CommandPalette/CommandPalette.css",
    "chars": 198,
    "preview": ".flicker {\n  animation: flicker .5s infinite ;\n}\n.flicker-slow {\n  animation: flicker 1.5s infinite ;\n}\n@keyframes flick"
  },
  {
    "path": "client/src/app/CommandPalette/CommandPalette.tsx",
    "chars": 7200,
    "preview": "import { FlashMessage } from \"@components/FlashMessage\";\nimport { Icon } from \"@components/Icon/Icon\";\nimport Popup from"
  },
  {
    "path": "client/src/app/CommandPalette/Documentation.css",
    "chars": 42,
    "preview": ".Documentation img {\n  max-width: 100%;\n}\n"
  },
  {
    "path": "client/src/app/CommandPalette/Documentation.tsx",
    "chars": 2360,
    "preview": "import React, { useMemo } from \"react\";\nimport Markdown from \"react-markdown\";\nimport rehypeRaw from \"rehype-raw\";\nimpor"
  },
  {
    "path": "client/src/app/CommandPalette/getDocumentation.ts",
    "chars": 5116,
    "preview": "import { isObject } from \"@common/publishUtils\";\nimport { fixIndent } from \"../../demo/scripts/sqlVideoDemo\";\nimport { C"
  },
  {
    "path": "client/src/app/CommandPalette/getUIDocShortestPath.ts",
    "chars": 2046,
    "preview": "import { filterArr } from \"@common/llmUtils\";\nimport type { UIDoc, UIDocPage } from \"../UIDocs\";\nimport { getCommandElem"
  },
  {
    "path": "client/src/app/CommandPalette/useGoToUI.tsx",
    "chars": 4772,
    "preview": "import { useCallback, useMemo } from \"react\";\nimport { useLocation, useNavigate } from \"react-router-dom\";\nimport { COMM"
  },
  {
    "path": "client/src/app/CommandPalette/useHighlightDocItem.ts",
    "chars": 3085,
    "preview": "import { useCallback, useState } from \"react\";\nimport { useAlert } from \"@components/AlertProvider\";\nimport { isDefined "
  },
  {
    "path": "client/src/app/CommandPalette/utils.ts",
    "chars": 3441,
    "preview": "import { isObject } from \"@common/publishUtils\";\nimport type { AlertContext } from \"@components/AlertProvider\";\nimport {"
  },
  {
    "path": "client/src/app/UIDocs/UIInstallationUIDoc.ts",
    "chars": 1888,
    "preview": "import type { UIDoc } from \"../UIDocs\";\n\nexport const UIInstallation = {\n  title: \"Installation\",\n  type: \"info\",\n  desc"
  },
  {
    "path": "client/src/app/UIDocs/accountUIDoc.ts",
    "chars": 4091,
    "preview": "import { mdiAccountOutline, mdiApplicationBracesOutline } from \"@mdi/js\";\nimport { ROUTES } from \"@common/utils\";\nimport"
  },
  {
    "path": "client/src/app/UIDocs/commandPaletteUIDoc.ts",
    "chars": 1385,
    "preview": "import { getCommandElemSelector } from \"src/Testing\";\nimport type { UIDocContainers } from \"../UIDocs\";\n\nexport const co"
  },
  {
    "path": "client/src/app/UIDocs/connection/AIAssistantUIDoc.ts",
    "chars": 12217,
    "preview": "import { mdiMagnify, mdiPlus, mdiStop, mdiTools } from \"@mdi/js\";\nimport { fixIndent } from \"../../../demo/scripts/sqlVi"
  },
  {
    "path": "client/src/app/UIDocs/connection/config/accessControlUIDoc.ts",
    "chars": 1392,
    "preview": "import { mdiAccountMultiple } from \"@mdi/js\";\nimport { fixIndent } from \"../../../../demo/scripts/sqlVideoDemo\";\nimport "
  },
  {
    "path": "client/src/app/UIDocs/connection/config/apiUIDoc.ts",
    "chars": 3686,
    "preview": "import { mdiApplicationBracesOutline } from \"@mdi/js\";\nimport type { UIDocElement } from \"../../../UIDocs\";\n\nexport cons"
  },
  {
    "path": "client/src/app/UIDocs/connection/config/backupAndRestoreUIDoc.ts",
    "chars": 7952,
    "preview": "import { mdiDatabaseSync } from \"@mdi/js\";\nimport type { UIDoc } from \"../../../UIDocs\";\n\nexport const backupAndRestoreU"
  },
  {
    "path": "client/src/app/UIDocs/connection/config/fileStorageUIDoc.ts",
    "chars": 776,
    "preview": "import { mdiImage } from \"@mdi/js\";\nimport type { UIDoc } from \"../../../UIDocs\";\n\nexport const fileStorageUIDoc = {\n  t"
  },
  {
    "path": "client/src/app/UIDocs/connection/connectionConfigUIDoc.ts",
    "chars": 2291,
    "preview": "import { mdiChartLine, mdiDatabaseCogOutline } from \"@mdi/js\";\nimport { fixIndent, ROUTES } from \"@common/utils\";\nimport"
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/dashboardContentUIDoc.ts",
    "chars": 834,
    "preview": "import type { UIDocElement } from \"../../../UIDocs\";\nimport { mapUIDoc } from \"./mapUIDoc\";\nimport { sqlEditorUIDoc } fr"
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/dashboardMenuUIDoc.ts",
    "chars": 10519,
    "preview": "import {\n  getDataKeyElemSelector,\n  getDataLabelElemSelector,\n} from \"../../../../Testing\";\nimport type { UIDocElement "
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/mapUIDoc.ts",
    "chars": 6398,
    "preview": "import { fixIndent } from \"../../../../demo/scripts/sqlVideoDemo\";\nimport {\n  getCommandElemSelector,\n  getDataKeyElemSe"
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/serverSideFunctionUIDoc.ts",
    "chars": 1057,
    "preview": "import { fixIndent } from \"../../../../demo/scripts/sqlVideoDemo\";\nimport type { UIDocElement } from \"../../../UIDocs\";\n"
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/sqlEditorUIDoc.ts",
    "chars": 11863,
    "preview": "import { fixIndent } from \"../../../../demo/scripts/sqlVideoDemo\";\nimport {\n  getCommandElemSelector,\n  getDataKeyElemSe"
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/table/addColumnMenuUIDoc.ts",
    "chars": 9534,
    "preview": "import type { UIDoc } from \"src/app/UIDocs\";\nimport { getCommandElemSelector } from \"src/Testing\";\n\nexport const addColu"
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/table/columnMenuUIDoc.ts",
    "chars": 4395,
    "preview": "import type { UIDoc } from \"src/app/UIDocs\";\nimport { getDataKeyElemSelector } from \"src/Testing\";\n\nexport const columnM"
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/table/paginationUIDoc.ts",
    "chars": 1684,
    "preview": "import type { UIDocElement } from \"../../../../UIDocs\";\n\nexport const paginationUIDoc: UIDocElement = {\n  selectorComman"
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/table/smartFilterBarUIDoc.ts",
    "chars": 4232,
    "preview": "import { fixIndent } from \"../../../../../demo/scripts/sqlVideoDemo\";\nimport { getDataKeyElemSelector } from \"../../../."
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/table/smartFormUIDoc.ts",
    "chars": 7686,
    "preview": "import type { UIDocElement } from \"src/app/UIDocs\";\nimport { getCommandElemSelector } from \"src/Testing\";\n\nexport const "
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/table/tableMenuUIDoc.ts",
    "chars": 7889,
    "preview": "import { fixIndent } from \"../../../../../demo/scripts/sqlVideoDemo\";\nimport {\n  getCommandElemSelector,\n  getDataKeyEle"
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/table/tableUIDoc.ts",
    "chars": 3990,
    "preview": "import { fixIndent } from \"src/demo/scripts/sqlVideoDemo\";\nimport type { UIDocElement } from \"../../../../UIDocs\";\nimpor"
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboard/timechartUIDoc.ts",
    "chars": 6838,
    "preview": "import { fixIndent } from \"../../../../demo/scripts/sqlVideoDemo\";\nimport { getCommandElemSelector } from \"../../../../T"
  },
  {
    "path": "client/src/app/UIDocs/connection/dashboardUIDoc.ts",
    "chars": 7249,
    "preview": "import { mdiMonitorDashboard } from \"@mdi/js\";\nimport { ROUTES } from \"@common/utils\";\nimport { getCommandElemSelector }"
  },
  {
    "path": "client/src/app/UIDocs/connection/getCommonViewHeaderUIDoc.ts",
    "chars": 5919,
    "preview": "import { isDefined } from \"../../../utils/utils\";\nimport type { UIDocElement } from \"../../UIDocs\";\n\nexport const getCom"
  },
  {
    "path": "client/src/app/UIDocs/connectionsUIDoc.ts",
    "chars": 10193,
    "preview": "import { ROUTES } from \"@common/utils\";\nimport { mdiDatabasePlusOutline, mdiFilter, mdiServerNetwork } from \"@mdi/js\";\ni"
  },
  {
    "path": "client/src/app/UIDocs/desktopInstallation.ts",
    "chars": 1701,
    "preview": "import { fixIndent } from \"../../demo/scripts/sqlVideoDemo\";\nimport type { UIDoc } from \"../UIDocs\";\n\nexport const deskt"
  },
  {
    "path": "client/src/app/UIDocs/editConnectionUIDoc.ts",
    "chars": 4377,
    "preview": "import { ROUTES } from \"@common/utils\";\nimport type { UIDocContainers } from \"../UIDocs\";\n\nexport const editConnectionUI"
  },
  {
    "path": "client/src/app/UIDocs/navbarUIDoc.ts",
    "chars": 4778,
    "preview": "import { mdiThemeLightDark, mdiTranslate } from \"@mdi/js\";\nimport { ROUTES } from \"@common/utils\";\nimport type { UIDocNa"
  },
  {
    "path": "client/src/app/UIDocs/overviewUIDoc.ts",
    "chars": 1384,
    "preview": "import type { UIDoc } from \"../UIDocs\";\n\nexport const overviewUIDoc = {\n  type: \"info\",\n  title: \"Overview\",\n  descripti"
  },
  {
    "path": "client/src/app/UIDocs/serverSettingsUIDoc.ts",
    "chars": 5722,
    "preview": "import { mdiServerSecurity, mdiTools } from \"@mdi/js\";\nimport { ROUTES } from \"@common/utils\";\nimport { getCommandElemSe"
  },
  {
    "path": "client/src/app/UIDocs.ts",
    "chars": 7366,
    "preview": "import { filterArrInverse } from \"@common/llmUtils\";\nimport type { DBSSchema } from \"@common/publishUtils\";\nimport type "
  },
  {
    "path": "client/src/app/XRealIpSpoofableAlert.tsx",
    "chars": 1338,
    "preview": "import { mdiAlertOutline } from \"@mdi/js\";\nimport React from \"react\";\nimport { NavLink } from \"react-router-dom\";\nimport"
  },
  {
    "path": "client/src/app/domToSVG/SVGif/addSVGifCaption.ts",
    "chars": 3241,
    "preview": "import { SVG_NAMESPACE } from \"../domToSVG\";\n\nexport const addSVGifCaption = ({\n  svgDom,\n  appendStyle,\n  height,\n  cap"
  },
  {
    "path": "client/src/app/domToSVG/SVGif/addSVGifPointer.ts",
    "chars": 1202,
    "preview": "import { SVG_NAMESPACE } from \"../domToSVG\";\nimport { getAnimationProperty } from \"./getSVGif\";\n\nexport const addSVGifPo"
  },
  {
    "path": "client/src/app/domToSVG/SVGif/addSVGifTimelineControls.ts",
    "chars": 3140,
    "preview": "import { SVG_NAMESPACE } from \"../domToSVG\";\nimport { getAnimationProperty } from \"./getSVGif\";\nimport type { getSVGifAn"
  },
  {
    "path": "client/src/app/domToSVG/SVGif/animations/getSVGifCursorAnimationHandler.ts",
    "chars": 5026,
    "preview": "import type { SVGif } from \"src/Testing\";\nimport type { SVGifParsedScene } from \"../getSVGifParsedScenes\";\nimport { getS"
  },
  {
    "path": "client/src/app/domToSVG/SVGif/animations/getSVGifTypeAnimation.ts",
    "chars": 3671,
    "preview": "import type { SVGif } from \"src/Testing\";\nimport type { SceneNodeAnimation } from \"../getSVGifAnimations\";\nimport type {"
  },
  {
    "path": "client/src/app/domToSVG/SVGif/animations/getSVGifZoomToAnimation.ts",
    "chars": 4078,
    "preview": "import { fixIndent } from \"@common/utils\";\nimport type { SVGif } from \"src/Testing\";\nimport { toFixed } from \"../../util"
  },
  {
    "path": "client/src/app/domToSVG/SVGif/compressSVGif.ts",
    "chars": 2877,
    "preview": "/**\n * Given an SVG with multiple SVG scenes inside <g id=\"all-scenes\">,\n * identify which g elements have the same data"
  },
  {
    "path": "client/src/app/domToSVG/SVGif/getSVGif.ts",
    "chars": 3214,
    "preview": "import { fixIndent } from \"@common/utils\";\nimport type { SVGif } from \"src/Testing\";\nimport { SVG_NAMESPACE } from \"../d"
  },
  {
    "path": "client/src/app/domToSVG/SVGif/getSVGifAnimations.ts",
    "chars": 8729,
    "preview": "import { fixIndent } from \"@common/utils\";\nimport { SVG_NAMESPACE } from \"../domToSVG\";\nimport { renderSvg } from \"../te"
  },
  {
    "path": "client/src/app/domToSVG/SVGif/getSVGifParsedScenes.ts",
    "chars": 1395,
    "preview": "import type { SVGif } from \"src/Testing\";\n\nconst parseSVGWithViewBox = (\n  svgFileName: string,\n  svgFiles: Map<string, "
  },
  {
    "path": "client/src/app/domToSVG/SVGif/getSVGifRevealKeyframes.ts",
    "chars": 1658,
    "preview": "import { toFixed } from \"../utils/toFixed\";\n\nexport const getSVGifRevealKeyframes = ({\n  fromPerc,\n  toPerc,\n  mode,\n}: "
  },
  {
    "path": "client/src/app/domToSVG/SVGif/getSVGifTargetBBox.ts",
    "chars": 751,
    "preview": "export const getSVGifTargetBBox = ({\n  elementSelector,\n  svgDom,\n  svgFileName,\n  width,\n  height,\n}: {\n  elementSelect"
  },
  {
    "path": "client/src/app/domToSVG/addFragmentViewBoxes.ts",
    "chars": 1394,
    "preview": "import { SVG_NAMESPACE } from \"./domToSVG\";\n\nexport const addFragmentViewBoxes = (svg: SVGSVGElement, padding = 10) => {"
  },
  {
    "path": "client/src/app/domToSVG/containers/addOverflowClipPath.ts",
    "chars": 3322,
    "preview": "import { includes } from \"../../../dashboard/W_SQL/W_SQLBottomBar/W_SQLBottomBar\";\nimport type { WhatToRenderOnSVG } fro"
  },
  {
    "path": "client/src/app/domToSVG/containers/bgAndBorderToSVG.ts",
    "chars": 5186,
    "preview": "import { SVG_NAMESPACE } from \"../domToSVG\";\nimport type { SVGScreenshotNodeType } from \"../domToThemeAwareSVG\";\nimport "
  },
  {
    "path": "client/src/app/domToSVG/containers/deduplicateSVGPaths.ts",
    "chars": 3957,
    "preview": "export const deduplicateSVGPaths = (svgElement: SVGElement) => {\n  // Get or create defs element\n  let defs = svgElement"
  },
  {
    "path": "client/src/app/domToSVG/containers/elementToSVG.ts",
    "chars": 7223,
    "preview": "import { getEntries } from \"@common/utils\";\nimport { drawShapesOnSVG } from \"../../../dashboard/Charts/drawShapes/drawSh"
  },
  {
    "path": "client/src/app/domToSVG/containers/rectangleToSVG.ts",
    "chars": 6674,
    "preview": "import { fromEntries, getEntries } from \"@common/utils\";\nimport { SVG_NAMESPACE } from \"../domToSVG\";\nimport type { SVGS"
  },
  {
    "path": "client/src/app/domToSVG/containers/shadowToSVG.ts",
    "chars": 1505,
    "preview": "import { isDefined } from \"src/utils/utils\";\n\n/**\n *   'rgba(255, 0, 0, 0.21) 0px 1px 2px 0px'\n *     or\n *   'rgba(255,"
  },
  {
    "path": "client/src/app/domToSVG/domToSVG.ts",
    "chars": 7629,
    "preview": "import { includes } from \"prostgles-types\";\nimport { tout } from \"src/utils/utils\";\nimport { elementToSVG, type SVGConte"
  },
  {
    "path": "client/src/app/domToSVG/domToThemeAwareSVG.ts",
    "chars": 11103,
    "preview": "import { hashCode } from \"src/utils/hashCode\";\nimport { isDefined } from \"src/utils/utils\";\nimport { domToSVG } from \"./"
  },
  {
    "path": "client/src/app/domToSVG/getCorrespondingDarkNode.ts",
    "chars": 3175,
    "preview": "import type { SVGScreenshotNodeType } from \"./domToThemeAwareSVG\";\n\nexport const getCorrespondingDarkNode = (\n  darkNode"
  },
  {
    "path": "client/src/app/domToSVG/graphics/fontIconToSVG.ts",
    "chars": 4585,
    "preview": "import { includes } from \"../../../dashboard/W_SQL/W_SQLBottomBar/W_SQLBottomBar\";\nimport type { SVGContext, SVGNodeLayo"
  },
  {
    "path": "client/src/app/domToSVG/graphics/getForeignObject.ts",
    "chars": 1543,
    "preview": "import { isImgNode } from \"../utils/isElementVisible\";\nimport { toFixed } from \"../utils/toFixed\";\n\nexport const isSVGEl"
  },
  {
    "path": "client/src/app/domToSVG/graphics/imgToSVG.ts",
    "chars": 3155,
    "preview": "import { hashCode } from \"src/utils/hashCode\";\nimport type { SVGContext, SVGNodeLayout } from \"../containers/elementToSV"
  },
  {
    "path": "client/src/app/domToSVG/recordDomChanges.ts",
    "chars": 3692,
    "preview": "import { isElementNode, isElementVisible } from \"./utils/isElementVisible\";\n\nexport const recordDomChanges = (targetNode"
  },
  {
    "path": "client/src/app/domToSVG/setThemeForSVGScreenshot.ts",
    "chars": 3706,
    "preview": "import { localSettings } from \"../../dashboard/localSettings\";\nimport { tout } from \"../../utils/utils\";\n\nexport const s"
  },
  {
    "path": "client/src/app/domToSVG/text/getTextForSVG.ts",
    "chars": 7501,
    "preview": "import { isDefined } from \"../../../utils/utils\";\nimport {\n  isElementNode,\n  isInputOrTextAreaNode,\n  isTextNode,\n} fro"
  },
  {
    "path": "client/src/app/domToSVG/text/textToSVG.ts",
    "chars": 8457,
    "preview": "import { includes } from \"prostgles-types\";\nimport { SVG_NAMESPACE } from \"../domToSVG\";\nimport type { SVGScreenshotNode"
  },
  {
    "path": "client/src/app/domToSVG/utils/addNewChildren.ts",
    "chars": 1639,
    "preview": "import { isDefined } from \"src/utils/utils\";\nimport {\n  displayNoneIfLight,\n  type SVGScreenshotNodeType,\n} from \"../dom"
  },
  {
    "path": "client/src/app/domToSVG/utils/canvasToDataURL.ts",
    "chars": 147,
    "preview": "export const canvasToDataURL = (\n  canvas: HTMLCanvasElement,\n  quality = 0.8,\n): string => {\n  return canvas.toDataURL("
  },
  {
    "path": "client/src/app/domToSVG/utils/copyAnimationStylesToSvg.ts",
    "chars": 3544,
    "preview": "import type { SVGContext } from \"../containers/elementToSVG\";\n\n/**\n * Extracts and clones CSS animations and keyframes f"
  },
  {
    "path": "client/src/app/domToSVG/utils/getWhatToRenderOnSVG.ts",
    "chars": 5192,
    "preview": "import { isDefined } from \"../../../utils/utils\";\nimport {\n  getBackdropFilter,\n  getBackgroundColor,\n} from \"../contain"
  },
  {
    "path": "client/src/app/domToSVG/utils/isElementVisible.ts",
    "chars": 3205,
    "preview": "import { includes } from \"../../../dashboard/W_SQL/W_SQLBottomBar/W_SQLBottomBar\";\n\nexport const isElementVisible = (ele"
  },
  {
    "path": "client/src/app/domToSVG/utils/toFixed.ts",
    "chars": 105,
    "preview": "export const toFixed = (num: number, precision = 2) => {\n  return parseFloat(num.toFixed(precision));\n};\n"
  },
  {
    "path": "client/src/appUtils.ts",
    "chars": 3293,
    "preview": "import { useEffect, useState } from \"react\";\nimport type { Theme } from \"./App\";\nimport { type DocumentationFile } from "
  },
  {
    "path": "client/src/components/AlertProvider.tsx",
    "chars": 2400,
    "preview": "import React, {\n  createContext,\n  useCallback,\n  useContext,\n  useMemo,\n  useState,\n} from \"react\";\nimport Popup, { typ"
  },
  {
    "path": "client/src/components/Animations.css",
    "chars": 3687,
    "preview": ".custom-animations.success-checkmark {\n  width: 80px;\n  height: 115px;\n  margin: 0 auto;\n}\n\n.custom-animations.success-c"
  },
  {
    "path": "client/src/components/Animations.tsx",
    "chars": 3040,
    "preview": "import React, { useEffect } from \"react\";\nimport \"./Animations.css\";\nimport type { TestSelectors } from \"../Testing\";\nim"
  },
  {
    "path": "client/src/components/Btn.css",
    "chars": 4316,
    "preview": "button.disabled {\n  cursor: not-allowed !important;\n}\nbutton.disabled:not(.no-fade):not(.hidden) {\n  opacity: 0.5 !impor"
  },
  {
    "path": "client/src/components/Btn.tsx",
    "chars": 14561,
    "preview": "import { mdiAlert, mdiCheck } from \"@mdi/js\";\nimport { omitKeys, pickKeys } from \"prostgles-types\";\nimport React from \"r"
  },
  {
    "path": "client/src/components/ButtonBar.tsx",
    "chars": 727,
    "preview": "import React from \"react\";\nimport type { BtnProps } from \"./Btn\";\nimport Btn from \"./Btn\";\nimport ErrorComponent from \"."
  },
  {
    "path": "client/src/components/ButtonGroup.tsx",
    "chars": 3479,
    "preview": "import React from \"react\";\nimport { isObject } from \"@common/publishUtils\";\nimport Btn from \"./Btn\";\nimport { FlexCol } "
  },
  {
    "path": "client/src/components/Chat/Chat.css",
    "chars": 2323,
    "preview": ".chat-container.chat-component .active-color {\n  color: rgb(5, 149, 252);\n}\n\n.chat-container.chat-component .bg-active-h"
  },
  {
    "path": "client/src/components/Chat/Chat.tsx",
    "chars": 4798,
    "preview": "import React, { useEffect, useRef } from \"react\";\nimport \"./Chat.css\";\n\nimport { classOverride, FlexCol } from \"../Flex\""
  },
  {
    "path": "client/src/components/Chat/ChatFileAttachments/ChatFileAttachments.tsx",
    "chars": 1832,
    "preview": "import React from \"react\";\nimport { mdiClose } from \"@mdi/js\";\nimport type { ChatState } from \"../useChatState\";\nimport "
  },
  {
    "path": "client/src/components/Chat/ChatMessage.tsx",
    "chars": 799,
    "preview": "import React from \"react\";\nimport { FlexCol } from \"../Flex\";\nimport Loading from \"../Loader/Loading\";\nimport type { Mes"
  },
  {
    "path": "client/src/components/Chat/ChatSendControls.tsx",
    "chars": 3202,
    "preview": "import React, { useCallback } from \"react\";\n\nimport { useOnErrorAlert } from \"@components/AlertProvider\";\nimport { mdiAr"
  },
  {
    "path": "client/src/components/Chat/ChatSpeech/ChatSpeech.tsx",
    "chars": 6081,
    "preview": "import React, {\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\n\nimport { useOnErrorAlert }"
  },
  {
    "path": "client/src/components/Chat/ChatSpeech/ChatSpeechSetup.tsx",
    "chars": 2281,
    "preview": "import React from \"react\";\n\nimport { Select } from \"@components/Select/Select\";\nimport { usePrgl } from \"@pages/ProjectC"
  },
  {
    "path": "client/src/components/Chat/ChatSpeech/hooks/SpeechRecorder.ts",
    "chars": 9054,
    "preview": "import { isPlaywrightTest } from \"src/i18n/i18nUtils\";\n\nconst MINIMUM_VARIANCE = 20;\nconst MINIMUM_SPEECH_THRESHOLD = 15"
  },
  {
    "path": "client/src/components/Chat/ChatSpeech/hooks/renderSpeechAudioLevelsIcon.ts",
    "chars": 1913,
    "preview": "import { createHiPPICanvas } from \"src/dashboard/Charts/createHiPPICanvas\";\nimport {\n  drawShapes,\n  type ShapeV2,\n} fro"
  },
  {
    "path": "client/src/components/Chat/ChatSpeech/hooks/useSpeechRecorder.ts",
    "chars": 1543,
    "preview": "import { useState, useRef, useCallback, useEffect } from \"react\";\nimport { SpeechRecorder } from \"./SpeechRecorder\";\n\nty"
  },
  {
    "path": "client/src/components/Chat/ChatSpeech/hooks/useSpeechToTextWeb.ts",
    "chars": 3368,
    "preview": "import { useState, useRef, useCallback, useEffect } from \"react\";\n\nexport type SpeechToTextState =\n  | {\n      isListeni"
  },
  {
    "path": "client/src/components/Chat/ChatSpeech/useChatSpeechSetup.ts",
    "chars": 2927,
    "preview": "import { useOnErrorAlert } from \"@components/AlertProvider\";\nimport type { FullOption } from \"@components/Select/Select\""
  },
  {
    "path": "client/src/components/Chat/Marked.css",
    "chars": 582,
    "preview": ".Marked p,\n.Marked ul,\n.Marked ol,\n/* .Marked h1,\n.Marked h2,\n.Marked h3,\n.Marked h4,\n.Marked h5, */\n.Marked blockquote,"
  },
  {
    "path": "client/src/components/Chat/Marked.tsx",
    "chars": 2594,
    "preview": "import { ScrollFade } from \"@components/ScrollFade/ScrollFade\";\nimport React, { useCallback } from \"react\";\nimport Markd"
  },
  {
    "path": "client/src/components/Chat/MonacoCodeInMarkdown/MarkdownMonacoCodeHeader.tsx",
    "chars": 5713,
    "preview": "import ErrorComponent from \"@components/ErrorComponent\";\nimport Popup from \"@components/Popup/Popup\";\nimport {\n  mdiDown"
  },
  {
    "path": "client/src/components/Chat/MonacoCodeInMarkdown/MonacoCodeInMarkdown.tsx",
    "chars": 4593,
    "preview": "import type { editor } from \"monaco-editor\";\nimport type { DBHandlerClient } from \"prostgles-client/dist/prostgles\";\nimp"
  },
  {
    "path": "client/src/components/Chat/MonacoCodeInMarkdown/useOnRunSQL.ts",
    "chars": 2153,
    "preview": "import { useCallback, useState } from \"react\";\nimport type { MonacoCodeInMarkdownProps } from \"./MonacoCodeInMarkdown\";\n"
  },
  {
    "path": "client/src/components/Chat/useChatOnPaste.ts",
    "chars": 2839,
    "preview": "import { useCallback } from \"react\";\nimport { tryCatchV2 } from \"prostgles-types\";\nimport { fixIndent } from \"../../demo"
  },
  {
    "path": "client/src/components/Chat/useChatState.ts",
    "chars": 3805,
    "preview": "import { useCallback, useEffect, useState } from \"react\";\n\nimport { usePromise } from \"prostgles-client\";\nimport { useFi"
  },
  {
    "path": "client/src/components/Checkbox.css",
    "chars": 633,
    "preview": ".checkbox input:checked {\n  /* background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='"
  },
  {
    "path": "client/src/components/Checkbox.tsx",
    "chars": 3770,
    "preview": "import { mdiCheckBold, mdiCheckboxBlankOutline } from \"@mdi/js\";\nimport React from \"react\";\nimport type { TestSelectors "
  },
  {
    "path": "client/src/components/Chip.css",
    "chars": 1340,
    "preview": ".chip {\n  padding-left: 0.625rem;\n  padding-right: 0.625rem;\n  padding-top: 0.125rem;\n  padding-bottom: 0.125rem;\n  line"
  },
  {
    "path": "client/src/components/Chip.tsx",
    "chars": 4129,
    "preview": "import { mdiClose } from \"@mdi/js\";\nimport React from \"react\";\nimport \"./Animations.css\";\nimport \"./Chip.css\";\nimport Bt"
  },
  {
    "path": "client/src/components/ClickCatch.tsx",
    "chars": 1122,
    "preview": "import React from \"react\";\n\ntype P = Pick<\n  React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElemen"
  },
  {
    "path": "client/src/components/ClickCatchOverlay.css",
    "chars": 109,
    "preview": ".ClickCatchOverlay {\n  background: #2c2c2c6b;\n}\n\n.dark-theme .ClickCatchOverlay {\n  background: #0000002e;\n}\n"
  },
  {
    "path": "client/src/components/ClickCatchOverlay.tsx",
    "chars": 678,
    "preview": "import React from \"react\";\nimport \"./ClickCatchOverlay.css\";\nimport { type DivProps, classOverride } from \"./Flex\";\nimpo"
  },
  {
    "path": "client/src/components/ConfirmationDialog.tsx",
    "chars": 2106,
    "preview": "import RTComp from \"../dashboard/RTComp\";\nimport React from \"react\";\nimport Btn from \"./Btn\";\nimport type { PopupProps }"
  },
  {
    "path": "client/src/components/CopyToClipboardBtn.tsx",
    "chars": 614,
    "preview": "import { mdiContentCopy } from \"@mdi/js\";\nimport React from \"react\";\nimport { t } from \"../i18n/i18nUtils\";\nimport Btn, "
  },
  {
    "path": "client/src/components/DragOverUpload/DragOverUpload.css",
    "chars": 796,
    "preview": "/* .DragOverUpload .DragOverUpload_Border {\n  animation: border-dance 4s infinite linear;\n} */\n\n.rotating-border {\n  /* "
  },
  {
    "path": "client/src/components/DragOverUpload/DragOverUpload.tsx",
    "chars": 1275,
    "preview": "import React, { useEffect, useState } from \"react\";\nimport { FlexCol } from \"../Flex\";\nimport \"./DragOverUpload.css\";\n\nt"
  },
  {
    "path": "client/src/components/DraggableLI.tsx",
    "chars": 5280,
    "preview": "import type { PropsWithChildren } from \"react\";\nimport React from \"react\";\nimport type { TestSelectors } from \"../Testin"
  },
  {
    "path": "client/src/components/ErrorComponent.tsx",
    "chars": 5894,
    "preview": "import { mdiAlertOutline, mdiClose } from \"@mdi/js\";\nimport type { ReactNode } from \"react\";\nimport React from \"react\";\n"
  },
  {
    "path": "client/src/components/ExpandSection.tsx",
    "chars": 1346,
    "preview": "import { mdiChevronDown } from \"@mdi/js\";\nimport React, { useState } from \"react\";\nimport type { BtnProps } from \"./Btn\""
  },
  {
    "path": "client/src/components/Expander.tsx",
    "chars": 466,
    "preview": "import React, { useState } from \"react\";\n\ntype ExpanderProps = {\n  style?: React.CSSProperties;\n  className?: string;\n  "
  },
  {
    "path": "client/src/components/FileBrowser/FileBrowser.tsx",
    "chars": 4508,
    "preview": "import { isDefined } from \"@common/filterUtils\";\nimport { FlexCol } from \"@components/Flex\";\nimport { Icon } from \"@comp"
  },
  {
    "path": "client/src/components/FileBrowser/FileBrowserCurrentDirectory.tsx",
    "chars": 3689,
    "preview": "import { useOnErrorAlert } from \"@components/AlertProvider\";\nimport Btn from \"@components/Btn\";\nimport { FlexRow, FlexRo"
  },
  {
    "path": "client/src/components/FileInput/DropZone.tsx",
    "chars": 599,
    "preview": "import React from \"react\";\nimport { FlexCol } from \"../Flex\";\nimport { useFileDropZone } from \"./useFileDropZone\";\n\nexpo"
  },
  {
    "path": "client/src/components/FileInput/FileInput.tsx",
    "chars": 10487,
    "preview": "import { mdiChevronLeft, mdiChevronRight, mdiPlus } from \"@mdi/js\";\nimport React from \"react\";\nimport RTComp from \"../.."
  },
  {
    "path": "client/src/components/FileInput/FileInputMedia.tsx",
    "chars": 3982,
    "preview": "import { mdiClose, mdiFileOutline } from \"@mdi/js\";\nimport React from \"react\";\nimport Btn from \"../Btn\";\nimport Chip fro"
  },
  {
    "path": "client/src/components/FileInput/useFileDropZone.ts",
    "chars": 1444,
    "preview": "import React, { useMemo, useRef } from \"react\";\nimport { type DivProps } from \"../Flex\";\nimport { isDefined } from \"@com"
  },
  {
    "path": "client/src/components/FlashMessage.tsx",
    "chars": 1544,
    "preview": "import React, { useEffect, useRef } from \"react\";\nimport { useLocation } from \"react-router-dom\";\n\ntype P = {\n  text: st"
  },
  {
    "path": "client/src/components/Flex.tsx",
    "chars": 2184,
    "preview": "import React from \"react\";\nimport type { TestSelectors } from \"../Testing\";\n\nexport type DivProps = React.HTMLAttributes"
  },
  {
    "path": "client/src/components/FormField/FormField.css",
    "chars": 2183,
    "preview": ".form-field input:not([type=\"checkbox\"]) {\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  /*"
  },
  {
    "path": "client/src/components/FormField/FormField.tsx",
    "chars": 21457,
    "preview": "import React from \"react\";\nimport \"./FormField.css\";\n\nimport { mdiClose, mdiFullscreen } from \"@mdi/js\";\nimport type { V"
  },
  {
    "path": "client/src/components/FormField/FormFieldCodeEditor.tsx",
    "chars": 2475,
    "preview": "import { useMemoDeep } from \"prostgles-client\";\nimport React, { useCallback, useMemo } from \"react\";\nimport { isObject }"
  },
  {
    "path": "client/src/components/FormField/FormFieldDebounced.tsx",
    "chars": 1463,
    "preview": "import React from \"react\";\nimport RTComp from \"../../dashboard/RTComp\";\nimport type { FormFieldProps, FormFieldTypes } f"
  },
  {
    "path": "client/src/components/FormField/FormFieldSkeleton.tsx",
    "chars": 6171,
    "preview": "import React, { forwardRef, type Ref } from \"react\";\nimport \"./FormField.css\";\n\nimport { isObject } from \"prostgles-type"
  },
  {
    "path": "client/src/components/FormField/onFormFieldKeyDown.ts",
    "chars": 4259,
    "preview": "import { getStringFormat } from \"../../utils/utils\";\nimport type FormField from \"./FormField\";\n\nexport function onFormFi"
  },
  {
    "path": "client/src/components/Hotkey.css",
    "chars": 232,
    "preview": ".hotkey {\n  border-radius: 6px;\n  background-color: var(--gray-100);\n  border: 1px solid var(--gray-300);\n  padding: 4px"
  },
  {
    "path": "client/src/components/Hotkey.tsx",
    "chars": 700,
    "preview": "import React from \"react\";\nimport \"./Hotkey.css\";\n\ntype P = {\n  keyStyle?: React.CSSProperties;\n  style?: React.CSSPrope"
  },
  {
    "path": "client/src/components/Icon/Icon.tsx",
    "chars": 3547,
    "preview": "import type { CSSProperties } from \"react\";\nimport * as React from \"react\";\n\nexport type IconProps = {\n  id?: string;\n  "
  },
  {
    "path": "client/src/components/IconPalette/IconPalette.tsx",
    "chars": 5124,
    "preview": "import { mdiChevronDown, mdiClose } from \"@mdi/js\";\nimport { usePromise } from \"prostgles-client\";\nimport React, { useEf"
  },
  {
    "path": "client/src/components/InfoRow.tsx",
    "chars": 1541,
    "preview": "import { mdiInformationOutline } from \"@mdi/js\";\nimport React from \"react\";\nimport { Icon } from \"./Icon/Icon\";\nimport {"
  },
  {
    "path": "client/src/components/Input.tsx",
    "chars": 2012,
    "preview": "import React, { useEffect, useState } from \"react\";\n\ntype P = React.HTMLProps<HTMLInputElement> & {\n  onNumLockAlert?: ("
  },
  {
    "path": "client/src/components/JSONBSchema/JSONBSchema.tsx",
    "chars": 4979,
    "preview": "import type { JSONB } from \"prostgles-types\";\nimport { isEqual, isObject } from \"prostgles-types\";\nimport React, { useCa"
  },
  {
    "path": "client/src/components/JSONBSchema/JSONBSchemaAllowedOptions.tsx",
    "chars": 2596,
    "preview": "import type { JSONB } from \"prostgles-types\";\nimport { isObject } from \"prostgles-types\";\nimport React from \"react\";\nimp"
  },
  {
    "path": "client/src/components/JSONBSchema/JSONBSchemaArray.tsx",
    "chars": 5364,
    "preview": "import { mdiClose, mdiPlus } from \"@mdi/js\";\nimport type { JSONB } from \"prostgles-types\";\nimport React, { useState } fr"
  },
  {
    "path": "client/src/components/JSONBSchema/JSONBSchemaLookup.tsx",
    "chars": 8062,
    "preview": "import type { JSONB } from \"prostgles-types\";\nimport { getKeys, isEmpty, isObject, pickKeys } from \"prostgles-types\";\nim"
  },
  {
    "path": "client/src/components/JSONBSchema/JSONBSchemaObject.tsx",
    "chars": 3855,
    "preview": "import { mdiClose, mdiDotsHorizontal } from \"@mdi/js\";\nimport type { JSONB } from \"prostgles-types\";\nimport { getKeys, i"
  },
  {
    "path": "client/src/components/JSONBSchema/JSONBSchemaOneOfType.tsx",
    "chars": 4809,
    "preview": "import type { JSONB } from \"prostgles-types\";\nimport { getKeys, isObject, omitKeys, pickKeys } from \"prostgles-types\";\ni"
  },
  {
    "path": "client/src/components/JSONBSchema/JSONBSchemaPrimitive.tsx",
    "chars": 4599,
    "preview": "import { FormFieldDebounced } from \"@components/FormField/FormFieldDebounced\";\nimport type { JSONB, ValidatedColumnInfo "
  },
  {
    "path": "client/src/components/JSONBSchema/JSONBSchemaRecord.tsx",
    "chars": 2259,
    "preview": "import { mdiPlus } from \"@mdi/js\";\nimport type { JSONB } from \"prostgles-types\";\nimport { getKeys, isObject, omitKeys } "
  },
  {
    "path": "client/src/components/JSONBSchema/isCompleteJSONB.ts",
    "chars": 1581,
    "preview": "import type { JSONB } from \"prostgles-types\";\nimport { isObject } from \"prostgles-types\";\nimport { getEntries } from \"@c"
  },
  {
    "path": "client/src/components/JsonRenderer.tsx",
    "chars": 702,
    "preview": "import React from \"react\";\n\ntype P = {\n  value: any;\n};\n\nexport const JsonRenderer: React.FC<P> = ({ value }) => {\n  con"
  },
  {
    "path": "client/src/components/Label.css",
    "chars": 148,
    "preview": ".Label_QuestionButton {\n  position: relative;\n}\n\n.Label_QuestionButton:hover::after {\n  content: \"?\";\n  position: absolu"
  },
  {
    "path": "client/src/components/Label.tsx",
    "chars": 3457,
    "preview": "import { mdiHelp, mdiInformationOutline } from \"@mdi/js\";\nimport React from \"react\";\nimport Btn from \"./Btn\";\nimport { C"
  }
]

// ... and 1071 more files (download for full content)

About this extraction

This page contains the full source code of the prostgles/ui GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1271 files (5.9 MB), approximately 1.6M tokens, and a symbol index with 2152 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!