@vertesia/ui 1.0.0-dev.20260128.144200 → 1.0.0-dev.20260225.024852Z
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/core/components/InputList.js +1 -1
- package/lib/esm/core/components/InputList.js.map +1 -1
- package/lib/esm/core/components/Overlay.js +1 -1
- package/lib/esm/core/components/Overlay.js.map +1 -1
- package/lib/esm/core/components/SidePanel.js +8 -2
- package/lib/esm/core/components/SidePanel.js.map +1 -1
- package/lib/esm/core/components/Switch.js +1 -1
- package/lib/esm/core/components/Switch.js.map +1 -1
- package/lib/esm/core/components/index.js +0 -8
- package/lib/esm/core/components/index.js.map +1 -1
- package/lib/esm/core/components/shadcn/MessageBox.js.map +1 -0
- package/lib/esm/core/components/shadcn/Panel.js +13 -0
- package/lib/esm/core/components/shadcn/Panel.js.map +1 -0
- package/lib/esm/core/components/{Badge.js → shadcn/badge.js} +2 -2
- package/lib/esm/core/components/shadcn/badge.js.map +1 -0
- package/lib/esm/core/components/shadcn/command.js +1 -1
- package/lib/esm/core/components/shadcn/command.js.map +1 -1
- package/lib/esm/core/components/shadcn/filters/filterBar.js +73 -83
- package/lib/esm/core/components/shadcn/filters/filterBar.js.map +1 -1
- package/lib/esm/core/components/shadcn/index.js +4 -2
- package/lib/esm/core/components/shadcn/index.js.map +1 -1
- package/lib/esm/core/components/shadcn/modal/ConfirmModal.js +10 -0
- package/lib/esm/core/components/shadcn/modal/ConfirmModal.js.map +1 -0
- package/lib/esm/core/components/{DeleteModal.js → shadcn/modal/DeleteModal.js} +1 -1
- package/lib/esm/core/components/shadcn/modal/DeleteModal.js.map +1 -0
- package/lib/esm/core/components/shadcn/{dialog.js → modal/dialog.js} +19 -15
- package/lib/esm/core/components/shadcn/modal/dialog.js.map +1 -0
- package/lib/esm/core/components/shadcn/modal/index.js +4 -0
- package/lib/esm/core/components/shadcn/modal/index.js.map +1 -0
- package/lib/esm/core/components/shadcn/popover.js +4 -2
- package/lib/esm/core/components/shadcn/popover.js.map +1 -1
- package/lib/esm/core/components/shadcn/selectBox.js +19 -15
- package/lib/esm/core/components/shadcn/selectBox.js.map +1 -1
- package/lib/esm/core/components/shadcn/tabs.js +16 -14
- package/lib/esm/core/components/shadcn/tabs.js.map +1 -1
- package/lib/esm/core/components/shadcn/textarea.js +30 -2
- package/lib/esm/core/components/shadcn/textarea.js.map +1 -1
- package/lib/esm/core/components/shadcn/tooltip.js +5 -1
- package/lib/esm/core/components/shadcn/tooltip.js.map +1 -1
- package/lib/esm/features/agent/PayloadBuilder.js +45 -0
- package/lib/esm/features/agent/PayloadBuilder.js.map +1 -1
- package/lib/esm/features/agent/chat/AgentChart.js +12 -232
- package/lib/esm/features/agent/chat/AgentChart.js.map +1 -1
- package/lib/esm/features/agent/chat/AskUserWidget.js +2 -1
- package/lib/esm/features/agent/chat/AskUserWidget.js.map +1 -1
- package/lib/esm/features/agent/chat/DocumentPanel.js +46 -0
- package/lib/esm/features/agent/chat/DocumentPanel.js.map +1 -0
- package/lib/esm/features/agent/chat/DocumentTabBar.js +17 -0
- package/lib/esm/features/agent/chat/DocumentTabBar.js.map +1 -0
- package/lib/esm/features/agent/chat/ModernAgentConversation.js +159 -402
- package/lib/esm/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +99 -57
- package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js +4 -4
- package/lib/esm/features/agent/chat/ModernAgentOutput/BatchProgressPanel.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js +4 -4
- package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js +3 -3
- package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/MessageInput.js +25 -22
- package/lib/esm/features/agent/chat/ModernAgentOutput/MessageInput.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/MessageItem.js +110 -55
- package/lib/esm/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/StreamingMessage.js +2 -2
- package/lib/esm/features/agent/chat/ModernAgentOutput/StreamingMessage.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +146 -55
- package/lib/esm/features/agent/chat/ModernAgentOutput/ToolCallGroup.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js +5 -6
- package/lib/esm/features/agent/chat/ModernAgentOutput/WorkstreamTabs.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/utils.js +110 -2
- package/lib/esm/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
- package/lib/esm/features/agent/chat/SkillWidgetProvider.js +28 -15
- package/lib/esm/features/agent/chat/SkillWidgetProvider.js.map +1 -1
- package/lib/esm/features/agent/chat/hooks/useAgentPlans.js +146 -0
- package/lib/esm/features/agent/chat/hooks/useAgentPlans.js.map +1 -0
- package/lib/esm/features/agent/chat/hooks/useAgentStream.js +180 -0
- package/lib/esm/features/agent/chat/hooks/useAgentStream.js.map +1 -0
- package/lib/esm/features/agent/chat/hooks/useDocumentPanel.js +100 -0
- package/lib/esm/features/agent/chat/hooks/useDocumentPanel.js.map +1 -0
- package/lib/esm/features/agent/chat/hooks/useFileProcessing.js +90 -0
- package/lib/esm/features/agent/chat/hooks/useFileProcessing.js.map +1 -0
- package/lib/esm/features/agent/chat/index.js +6 -5
- package/lib/esm/features/agent/chat/index.js.map +1 -1
- package/lib/esm/features/agent/chat/types/document.js +2 -0
- package/lib/esm/features/agent/chat/types/document.js.map +1 -0
- package/lib/esm/features/agent/index.js +0 -2
- package/lib/esm/features/agent/index.js.map +1 -1
- package/lib/esm/features/store/collections/BrowseCollectionView.js +4 -6
- package/lib/esm/features/store/collections/BrowseCollectionView.js.map +1 -1
- package/lib/esm/features/store/collections/CreateCollection.js +4 -4
- package/lib/esm/features/store/collections/CreateCollection.js.map +1 -1
- package/lib/esm/features/store/collections/EditCollectionView.js +1 -1
- package/lib/esm/features/store/collections/EditCollectionView.js.map +1 -1
- package/lib/esm/features/store/objects/DocumentSearchResults.js +5 -5
- package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
- package/lib/esm/features/store/objects/ExportPropertiesModal.js +3 -3
- package/lib/esm/features/store/objects/ExportPropertiesModal.js.map +1 -1
- package/lib/esm/features/store/objects/components/ContentOverview.js +19 -120
- package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/esm/features/store/objects/components/PropertiesEditorModal.js +1 -1
- package/lib/esm/features/store/objects/components/PropertiesEditorModal.js.map +1 -1
- package/lib/esm/features/store/objects/components/SelectDocumentModal.js +2 -2
- package/lib/esm/features/store/objects/components/SelectDocumentModal.js.map +1 -1
- package/lib/esm/features/store/objects/components/VectorSearchWidget.js +1 -1
- package/lib/esm/features/store/objects/components/VectorSearchWidget.js.map +1 -1
- package/lib/esm/features/store/objects/components/index.js +1 -1
- package/lib/esm/features/store/objects/components/index.js.map +1 -1
- package/lib/esm/features/store/objects/components/useDownloadFile.js +192 -0
- package/lib/esm/features/store/objects/components/useDownloadFile.js.map +1 -0
- package/lib/esm/features/store/objects/search/DocumentSearchContext.js +1 -2
- package/lib/esm/features/store/objects/search/DocumentSearchContext.js.map +1 -1
- package/lib/esm/features/store/objects/selection/SelectionActions.js +5 -8
- package/lib/esm/features/store/objects/selection/SelectionActions.js.map +1 -1
- package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js +4 -4
- package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js.map +1 -1
- package/lib/esm/features/store/objects/selection/actions/ChangeTypeAction.js +2 -2
- package/lib/esm/features/store/objects/selection/actions/ChangeTypeAction.js.map +1 -1
- package/lib/esm/features/store/objects/selection/actions/ExportPropertiesAction.js +1 -1
- package/lib/esm/features/store/objects/selection/actions/ExportPropertiesAction.js.map +1 -1
- package/lib/esm/features/store/objects/selection/actions/StartWorkflowComponent.js +3 -3
- package/lib/esm/features/store/objects/selection/actions/StartWorkflowComponent.js.map +1 -1
- package/lib/esm/features/store/objects/upload/DocumentUploadModal.js +13 -13
- package/lib/esm/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
- package/lib/esm/features/store/objects/upload/useSmartFileUploadProcessing.js +15 -8
- package/lib/esm/features/store/objects/upload/useSmartFileUploadProcessing.js.map +1 -1
- package/lib/esm/features/store/types/ObjectSchemaEditor.js +6 -5
- package/lib/esm/features/store/types/ObjectSchemaEditor.js.map +1 -1
- package/lib/esm/features/store/types/SelectContentType.js +3 -3
- package/lib/esm/features/store/types/SelectContentType.js.map +1 -1
- package/lib/esm/features/store/types/SelectContentTypeModal.js +5 -4
- package/lib/esm/features/store/types/SelectContentTypeModal.js.map +1 -1
- package/lib/esm/features/store/types/TableLayoutEditor.js +4 -4
- package/lib/esm/features/store/types/TableLayoutEditor.js.map +1 -1
- package/lib/esm/features/user/UserInfo.js +73 -9
- package/lib/esm/features/user/UserInfo.js.map +1 -1
- package/lib/esm/features/utils/print.js +0 -1
- package/lib/esm/features/utils/print.js.map +1 -1
- package/lib/esm/layout/AppLayout.js +3 -4
- package/lib/esm/layout/AppLayout.js.map +1 -1
- package/lib/esm/layout/Sidebar.js +5 -5
- package/lib/esm/layout/Sidebar.js.map +1 -1
- package/lib/esm/router/HistoryNavigator.js +7 -1
- package/lib/esm/router/HistoryNavigator.js.map +1 -1
- package/lib/esm/router/Nav.js +2 -2
- package/lib/esm/router/Nav.js.map +1 -1
- package/lib/esm/session/UserSession.js +35 -9
- package/lib/esm/session/UserSession.js.map +1 -1
- package/lib/esm/session/UserSessionProvider.js +3 -2
- package/lib/esm/session/UserSessionProvider.js.map +1 -1
- package/lib/esm/shell/apps/AppProjectSelector.js +2 -2
- package/lib/esm/shell/apps/AppProjectSelector.js.map +1 -1
- package/lib/esm/shell/apps/StandaloneApp.js +2 -2
- package/lib/esm/shell/apps/StandaloneApp.js.map +1 -1
- package/lib/esm/shell/login/InviteAcceptModal.js +2 -2
- package/lib/esm/shell/login/InviteAcceptModal.js.map +1 -1
- package/lib/esm/shell/login/SignInModal.js +1 -1
- package/lib/esm/shell/login/SignInModal.js.map +1 -1
- package/lib/esm/shell/login/SignupForm.js +2 -2
- package/lib/esm/shell/login/SignupForm.js.map +1 -1
- package/lib/esm/shell/login/UserInfo.js +2 -2
- package/lib/esm/shell/login/UserInfo.js.map +1 -1
- package/lib/esm/widgets/json-view/JSONCode.js +1 -1
- package/lib/esm/widgets/json-view/JSONCode.js.map +1 -1
- package/lib/esm/widgets/json-view/JSONDisplay.js +1 -1
- package/lib/esm/widgets/json-view/JSONDisplay.js.map +1 -1
- package/lib/esm/widgets/markdown/ArtifactContentRenderer.js +84 -13
- package/lib/esm/widgets/markdown/ArtifactContentRenderer.js.map +1 -1
- package/lib/esm/widgets/markdown/MarkdownFigure.js +40 -0
- package/lib/esm/widgets/markdown/MarkdownFigure.js.map +1 -0
- package/lib/esm/widgets/markdown/MarkdownRenderer.js +42 -7
- package/lib/esm/widgets/markdown/MarkdownRenderer.js.map +1 -1
- package/lib/esm/widgets/markdown/MermaidDiagram.js +80 -5
- package/lib/esm/widgets/markdown/MermaidDiagram.js.map +1 -1
- package/lib/esm/widgets/markdown/codeBlockHandlers.js +33 -33
- package/lib/esm/widgets/markdown/codeBlockHandlers.js.map +1 -1
- package/lib/esm/widgets/markdown/codeBlockHandlers.test.js +2 -29
- package/lib/esm/widgets/markdown/codeBlockHandlers.test.js.map +1 -1
- package/lib/esm/widgets/markdown/index.js +1 -0
- package/lib/esm/widgets/markdown/index.js.map +1 -1
- package/lib/esm/widgets/markdown/normalizeCustomSchemeLinks.js +77 -0
- package/lib/esm/widgets/markdown/normalizeCustomSchemeLinks.js.map +1 -0
- package/lib/esm/widgets/markdown/normalizeDirectives.js +45 -0
- package/lib/esm/widgets/markdown/normalizeDirectives.js.map +1 -0
- package/lib/esm/widgets/markdown/remarkDirectiveHandler.js +96 -0
- package/lib/esm/widgets/markdown/remarkDirectiveHandler.js.map +1 -0
- package/lib/esm/widgets/monacoEditor/MonacoEditor.js +8 -14
- package/lib/esm/widgets/monacoEditor/MonacoEditor.js.map +1 -1
- package/lib/esm/widgets/schema-editor/ManagedSchema.js.map +1 -1
- package/lib/esm/widgets/schema-editor/editor/PropertyEditor.js +3 -3
- package/lib/esm/widgets/schema-editor/editor/PropertyEditor.js.map +1 -1
- package/lib/esm/widgets/schema-editor/json-schema4-utils.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/core/components/SidePanel.d.ts +4 -1
- package/lib/types/core/components/SidePanel.d.ts.map +1 -1
- package/lib/types/core/components/index.d.ts +0 -8
- package/lib/types/core/components/index.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/MessageBox.d.ts.map +1 -0
- package/lib/types/core/components/{Panel.d.ts → shadcn/Panel.d.ts} +3 -1
- package/lib/types/core/components/shadcn/Panel.d.ts.map +1 -0
- package/lib/types/core/components/{Badge.d.ts → shadcn/badge.d.ts} +4 -4
- package/lib/types/core/components/shadcn/badge.d.ts.map +1 -0
- package/lib/types/core/components/shadcn/button.d.ts +1 -1
- package/lib/types/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/index.d.ts +4 -2
- package/lib/types/core/components/shadcn/index.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/input.d.ts +1 -1
- package/lib/types/core/components/shadcn/modal/ConfirmModal.d.ts.map +1 -0
- package/lib/types/core/components/shadcn/modal/DeleteModal.d.ts.map +1 -0
- package/lib/types/core/components/shadcn/{dialog.d.ts → modal/dialog.d.ts} +7 -4
- package/lib/types/core/components/shadcn/modal/dialog.d.ts.map +1 -0
- package/lib/types/core/components/shadcn/modal/index.d.ts +4 -0
- package/lib/types/core/components/shadcn/modal/index.d.ts.map +1 -0
- package/lib/types/core/components/shadcn/popover.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/selectBox.d.ts +9 -5
- package/lib/types/core/components/shadcn/selectBox.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/tabs.d.ts +14 -5
- package/lib/types/core/components/shadcn/tabs.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/textarea.d.ts +6 -2
- package/lib/types/core/components/shadcn/textarea.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/tooltip.d.ts.map +1 -1
- package/lib/types/features/agent/PayloadBuilder.d.ts +22 -4
- package/lib/types/features/agent/PayloadBuilder.d.ts.map +1 -1
- package/lib/types/features/agent/chat/AgentChart.d.ts +3 -44
- package/lib/types/features/agent/chat/AgentChart.d.ts.map +1 -1
- package/lib/types/features/agent/chat/AskUserWidget.d.ts.map +1 -1
- package/lib/types/features/agent/chat/DocumentPanel.d.ts +16 -0
- package/lib/types/features/agent/chat/DocumentPanel.d.ts.map +1 -0
- package/lib/types/features/agent/chat/DocumentTabBar.d.ts +10 -0
- package/lib/types/features/agent/chat/DocumentTabBar.d.ts.map +1 -0
- package/lib/types/features/agent/chat/ModernAgentConversation.d.ts +69 -1
- package/lib/types/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +36 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/BatchProgressPanel.d.ts +18 -2
- package/lib/types/features/agent/chat/ModernAgentOutput/BatchProgressPanel.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/Header.d.ts +4 -7
- package/lib/types/features/agent/chat/ModernAgentOutput/Header.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/MessageInput.d.ts +2 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/MessageInput.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/MessageItem.d.ts +35 -7
- package/lib/types/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/StreamingMessage.d.ts +11 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/StreamingMessage.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/ToolCallGroup.d.ts +20 -2
- package/lib/types/features/agent/chat/ModernAgentOutput/ToolCallGroup.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/WorkstreamTabs.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/utils.d.ts +18 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/utils.d.ts.map +1 -1
- package/lib/types/features/agent/chat/SkillWidgetProvider.d.ts.map +1 -1
- package/lib/types/features/agent/chat/hooks/useAgentPlans.d.ts +22 -0
- package/lib/types/features/agent/chat/hooks/useAgentPlans.d.ts.map +1 -0
- package/lib/types/features/agent/chat/hooks/useAgentStream.d.ts +42 -0
- package/lib/types/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -0
- package/lib/types/features/agent/chat/hooks/useDocumentPanel.d.ts +22 -0
- package/lib/types/features/agent/chat/hooks/useDocumentPanel.d.ts.map +1 -0
- package/lib/types/features/agent/chat/hooks/useFileProcessing.d.ts +27 -0
- package/lib/types/features/agent/chat/hooks/useFileProcessing.d.ts.map +1 -0
- package/lib/types/features/agent/chat/index.d.ts +12 -8
- package/lib/types/features/agent/chat/index.d.ts.map +1 -1
- package/lib/types/features/agent/chat/types/document.d.ts +5 -0
- package/lib/types/features/agent/chat/types/document.d.ts.map +1 -0
- package/lib/types/features/agent/index.d.ts +0 -2
- package/lib/types/features/agent/index.d.ts.map +1 -1
- package/lib/types/features/store/collections/BrowseCollectionView.d.ts.map +1 -1
- package/lib/types/features/store/objects/ExportPropertiesModal.d.ts.map +1 -1
- package/lib/types/features/store/objects/components/ContentOverview.d.ts.map +1 -1
- package/lib/types/features/store/objects/components/PropertiesEditorModal.d.ts.map +1 -1
- package/lib/types/features/store/objects/components/index.d.ts +1 -1
- package/lib/types/features/store/objects/components/index.d.ts.map +1 -1
- package/lib/types/features/store/objects/components/useDownloadFile.d.ts +35 -0
- package/lib/types/features/store/objects/components/useDownloadFile.d.ts.map +1 -0
- package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
- package/lib/types/features/store/objects/selection/SelectionActions.d.ts +1 -1
- package/lib/types/features/store/objects/selection/SelectionActions.d.ts.map +1 -1
- package/lib/types/features/store/objects/selection/actions/ChangeTypeAction.d.ts.map +1 -1
- package/lib/types/features/store/objects/selection/actions/ExportPropertiesAction.d.ts.map +1 -1
- package/lib/types/features/store/objects/upload/useSmartFileUploadProcessing.d.ts.map +1 -1
- package/lib/types/features/store/types/ObjectSchemaEditor.d.ts +2 -1
- package/lib/types/features/store/types/ObjectSchemaEditor.d.ts.map +1 -1
- package/lib/types/features/store/types/SelectContentTypeModal.d.ts +1 -1
- package/lib/types/features/store/types/SelectContentTypeModal.d.ts.map +1 -1
- package/lib/types/features/store/types/TableLayoutEditor.d.ts +2 -1
- package/lib/types/features/store/types/TableLayoutEditor.d.ts.map +1 -1
- package/lib/types/features/user/UserInfo.d.ts +12 -1
- package/lib/types/features/user/UserInfo.d.ts.map +1 -1
- package/lib/types/features/utils/print.d.ts.map +1 -1
- package/lib/types/layout/AppLayout.d.ts.map +1 -1
- package/lib/types/layout/Sidebar.d.ts +4 -2
- package/lib/types/layout/Sidebar.d.ts.map +1 -1
- package/lib/types/router/HistoryNavigator.d.ts.map +1 -1
- package/lib/types/router/Nav.d.ts +6 -1
- package/lib/types/router/Nav.d.ts.map +1 -1
- package/lib/types/session/UserSession.d.ts.map +1 -1
- package/lib/types/session/UserSessionProvider.d.ts +1 -0
- package/lib/types/session/UserSessionProvider.d.ts.map +1 -1
- package/lib/types/widgets/json-view/JSONCode.d.ts.map +1 -1
- package/lib/types/widgets/markdown/ArtifactContentRenderer.d.ts +10 -1
- package/lib/types/widgets/markdown/ArtifactContentRenderer.d.ts.map +1 -1
- package/lib/types/widgets/markdown/MarkdownFigure.d.ts +15 -0
- package/lib/types/widgets/markdown/MarkdownFigure.d.ts.map +1 -0
- package/lib/types/widgets/markdown/MarkdownRenderer.d.ts.map +1 -1
- package/lib/types/widgets/markdown/MermaidDiagram.d.ts.map +1 -1
- package/lib/types/widgets/markdown/codeBlockHandlers.d.ts +5 -2
- package/lib/types/widgets/markdown/codeBlockHandlers.d.ts.map +1 -1
- package/lib/types/widgets/markdown/index.d.ts +1 -0
- package/lib/types/widgets/markdown/index.d.ts.map +1 -1
- package/lib/types/widgets/markdown/normalizeCustomSchemeLinks.d.ts +9 -0
- package/lib/types/widgets/markdown/normalizeCustomSchemeLinks.d.ts.map +1 -0
- package/lib/types/widgets/markdown/normalizeDirectives.d.ts +20 -0
- package/lib/types/widgets/markdown/normalizeDirectives.d.ts.map +1 -0
- package/lib/types/widgets/markdown/remarkDirectiveHandler.d.ts +2 -0
- package/lib/types/widgets/markdown/remarkDirectiveHandler.d.ts.map +1 -0
- package/lib/types/widgets/monacoEditor/MonacoEditor.d.ts +1 -3
- package/lib/types/widgets/monacoEditor/MonacoEditor.d.ts.map +1 -1
- package/lib/types/widgets/schema-editor/ManagedSchema.d.ts +1 -1
- package/lib/types/widgets/schema-editor/ManagedSchema.d.ts.map +1 -1
- package/lib/vertesia-ui-core.js +1 -1
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-features.js +1 -1
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-layout.js +1 -1
- package/lib/vertesia-ui-layout.js.map +1 -1
- package/lib/vertesia-ui-router.js +1 -1
- package/lib/vertesia-ui-router.js.map +1 -1
- package/lib/vertesia-ui-session.js +1 -1
- package/lib/vertesia-ui-session.js.map +1 -1
- package/lib/vertesia-ui-shell.js +1 -1
- package/lib/vertesia-ui-shell.js.map +1 -1
- package/lib/vertesia-ui-widgets.js +1 -1
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/package.json +14 -10
- package/src/core/components/InputList.tsx +1 -1
- package/src/core/components/Overlay.tsx +1 -1
- package/src/core/components/SidePanel.tsx +29 -15
- package/src/core/components/Switch.tsx +1 -1
- package/src/core/components/index.ts +0 -8
- package/src/core/components/shadcn/Panel.tsx +50 -0
- package/src/core/components/{Badge.tsx → shadcn/badge.tsx} +3 -3
- package/src/core/components/shadcn/command.tsx +1 -1
- package/src/core/components/shadcn/filters/filterBar.tsx +76 -87
- package/src/core/components/shadcn/index.ts +5 -3
- package/src/core/components/{ConfirmModal.tsx → shadcn/modal/ConfirmModal.tsx} +8 -8
- package/src/core/components/{DeleteModal.tsx → shadcn/modal/DeleteModal.tsx} +1 -1
- package/src/core/components/shadcn/{dialog.tsx → modal/dialog.tsx} +43 -32
- package/src/core/components/shadcn/modal/index.ts +3 -0
- package/src/core/components/shadcn/popover.tsx +4 -2
- package/src/core/components/shadcn/selectBox.tsx +71 -52
- package/src/core/components/shadcn/tabs.tsx +36 -19
- package/src/core/components/shadcn/textarea.tsx +43 -2
- package/src/core/components/shadcn/tooltip.tsx +23 -17
- package/src/features/agent/PayloadBuilder.tsx +70 -9
- package/src/features/agent/chat/AgentChart.tsx +46 -678
- package/src/features/agent/chat/AskUserWidget.tsx +4 -3
- package/src/features/agent/chat/DocumentPanel.tsx +120 -0
- package/src/features/agent/chat/DocumentTabBar.tsx +49 -0
- package/src/features/agent/chat/ModernAgentConversation.tsx +403 -549
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +162 -55
- package/src/features/agent/chat/ModernAgentOutput/BatchProgressPanel.tsx +40 -10
- package/src/features/agent/chat/ModernAgentOutput/Header.tsx +12 -16
- package/src/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.tsx +3 -3
- package/src/features/agent/chat/ModernAgentOutput/MessageInput.tsx +68 -75
- package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +206 -94
- package/src/features/agent/chat/ModernAgentOutput/StreamingMessage.tsx +22 -5
- package/src/features/agent/chat/ModernAgentOutput/ToolCallGroup.tsx +295 -113
- package/src/features/agent/chat/ModernAgentOutput/WorkstreamTabs.tsx +11 -8
- package/src/features/agent/chat/ModernAgentOutput/utils.ts +133 -4
- package/src/features/agent/chat/SkillWidgetProvider.tsx +32 -15
- package/src/features/agent/chat/hooks/useAgentPlans.ts +190 -0
- package/src/features/agent/chat/hooks/useAgentStream.ts +239 -0
- package/src/features/agent/chat/hooks/useDocumentPanel.ts +118 -0
- package/src/features/agent/chat/hooks/useFileProcessing.ts +126 -0
- package/src/features/agent/chat/index.ts +18 -17
- package/src/features/agent/chat/types/document.ts +4 -0
- package/src/features/agent/index.ts +0 -2
- package/src/features/store/collections/BrowseCollectionView.tsx +5 -8
- package/src/features/store/collections/CreateCollection.tsx +8 -8
- package/src/features/store/collections/EditCollectionView.tsx +1 -1
- package/src/features/store/objects/DocumentSearchResults.tsx +9 -13
- package/src/features/store/objects/ExportPropertiesModal.tsx +9 -7
- package/src/features/store/objects/components/ContentOverview.tsx +29 -155
- package/src/features/store/objects/components/PropertiesEditorModal.tsx +0 -1
- package/src/features/store/objects/components/SelectDocumentModal.tsx +6 -6
- package/src/features/store/objects/components/VectorSearchWidget.tsx +2 -2
- package/src/features/store/objects/components/index.ts +1 -1
- package/src/features/store/objects/components/useDownloadFile.ts +237 -0
- package/src/features/store/objects/search/DocumentSearchContext.ts +1 -2
- package/src/features/store/objects/selection/SelectionActions.tsx +0 -4
- package/src/features/store/objects/selection/actions/AddToCollectionAction.tsx +13 -13
- package/src/features/store/objects/selection/actions/ChangeTypeAction.tsx +2 -6
- package/src/features/store/objects/selection/actions/ExportPropertiesAction.tsx +1 -3
- package/src/features/store/objects/selection/actions/StartWorkflowComponent.tsx +8 -8
- package/src/features/store/objects/upload/DocumentUploadModal.tsx +25 -25
- package/src/features/store/objects/upload/useSmartFileUploadProcessing.ts +16 -10
- package/src/features/store/types/ObjectSchemaEditor.tsx +32 -29
- package/src/features/store/types/SelectContentType.tsx +3 -3
- package/src/features/store/types/SelectContentTypeModal.tsx +17 -30
- package/src/features/store/types/TableLayoutEditor.tsx +14 -18
- package/src/features/user/UserInfo.tsx +176 -10
- package/src/features/utils/print.ts +0 -1
- package/src/layout/AppLayout.tsx +16 -44
- package/src/layout/Sidebar.tsx +7 -5
- package/src/router/HistoryNavigator.ts +9 -1
- package/src/router/Nav.tsx +7 -2
- package/src/session/UserSession.ts +38 -9
- package/src/session/UserSessionProvider.tsx +3 -2
- package/src/shell/apps/AppProjectSelector.tsx +2 -2
- package/src/shell/apps/StandaloneApp.tsx +3 -3
- package/src/shell/login/InviteAcceptModal.tsx +6 -6
- package/src/shell/login/SignInModal.tsx +1 -1
- package/src/shell/login/SignupForm.tsx +3 -3
- package/src/shell/login/UserInfo.tsx +5 -5
- package/src/widgets/json-view/JSONCode.tsx +1 -3
- package/src/widgets/json-view/JSONDisplay.tsx +1 -1
- package/src/widgets/markdown/ArtifactContentRenderer.tsx +115 -14
- package/src/widgets/markdown/MarkdownFigure.tsx +100 -0
- package/src/widgets/markdown/MarkdownRenderer.tsx +62 -9
- package/src/widgets/markdown/MermaidDiagram.tsx +97 -5
- package/src/widgets/markdown/codeBlockHandlers.test.tsx +3 -34
- package/src/widgets/markdown/codeBlockHandlers.tsx +47 -42
- package/src/widgets/markdown/index.ts +1 -0
- package/src/widgets/markdown/markdown.css +192 -0
- package/src/widgets/markdown/normalizeCustomSchemeLinks.test.ts +86 -0
- package/src/widgets/markdown/normalizeCustomSchemeLinks.ts +91 -0
- package/src/widgets/markdown/normalizeDirectives.ts +50 -0
- package/src/widgets/markdown/remarkDirectiveHandler.ts +119 -0
- package/src/widgets/monacoEditor/MonacoEditor.tsx +8 -22
- package/src/widgets/schema-editor/ManagedSchema.ts +1 -1
- package/src/widgets/schema-editor/editor/PropertyEditor.tsx +5 -5
- package/src/widgets/schema-editor/json-schema4-utils.ts +1 -1
- package/lib/esm/core/components/Badge.js.map +0 -1
- package/lib/esm/core/components/Button.js +0 -32
- package/lib/esm/core/components/Button.js.map +0 -1
- package/lib/esm/core/components/ConfirmModal.js +0 -10
- package/lib/esm/core/components/ConfirmModal.js.map +0 -1
- package/lib/esm/core/components/DeleteModal.js.map +0 -1
- package/lib/esm/core/components/MessageBox.js.map +0 -1
- package/lib/esm/core/components/Modal.js +0 -26
- package/lib/esm/core/components/Modal.js.map +0 -1
- package/lib/esm/core/components/Panel.js +0 -8
- package/lib/esm/core/components/Panel.js.map +0 -1
- package/lib/esm/core/components/SelectBox.js +0 -67
- package/lib/esm/core/components/SelectBox.js.map +0 -1
- package/lib/esm/core/components/shadcn/dialog.js.map +0 -1
- package/lib/esm/core/components/tabs/Tabs.js +0 -78
- package/lib/esm/core/components/tabs/Tabs.js.map +0 -1
- package/lib/esm/core/components/tabs/TabsContext.js +0 -7
- package/lib/esm/core/components/tabs/TabsContext.js.map +0 -1
- package/lib/esm/core/components/tabs/index.js +0 -3
- package/lib/esm/core/components/tabs/index.js.map +0 -1
- package/lib/esm/features/agent/createChartTool.js +0 -632
- package/lib/esm/features/agent/createChartTool.js.map +0 -1
- package/lib/esm/features/agent/examples.js +0 -295
- package/lib/esm/features/agent/examples.js.map +0 -1
- package/lib/esm/features/agent/visualization.js +0 -165
- package/lib/esm/features/agent/visualization.js.map +0 -1
- package/lib/esm/features/store/objects/components/useDownloadObject.js +0 -21
- package/lib/esm/features/store/objects/components/useDownloadObject.js.map +0 -1
- package/lib/types/core/components/Badge.d.ts.map +0 -1
- package/lib/types/core/components/Button.d.ts +0 -14
- package/lib/types/core/components/Button.d.ts.map +0 -1
- package/lib/types/core/components/ConfirmModal.d.ts.map +0 -1
- package/lib/types/core/components/DeleteModal.d.ts.map +0 -1
- package/lib/types/core/components/MessageBox.d.ts.map +0 -1
- package/lib/types/core/components/Modal.d.ts +0 -30
- package/lib/types/core/components/Modal.d.ts.map +0 -1
- package/lib/types/core/components/Panel.d.ts.map +0 -1
- package/lib/types/core/components/SelectBox.d.ts +0 -36
- package/lib/types/core/components/SelectBox.d.ts.map +0 -1
- package/lib/types/core/components/shadcn/dialog.d.ts.map +0 -1
- package/lib/types/core/components/tabs/Tabs.d.ts +0 -25
- package/lib/types/core/components/tabs/Tabs.d.ts.map +0 -1
- package/lib/types/core/components/tabs/TabsContext.d.ts +0 -17
- package/lib/types/core/components/tabs/TabsContext.d.ts.map +0 -1
- package/lib/types/core/components/tabs/index.d.ts +0 -3
- package/lib/types/core/components/tabs/index.d.ts.map +0 -1
- package/lib/types/features/agent/createChartTool.d.ts +0 -178
- package/lib/types/features/agent/createChartTool.d.ts.map +0 -1
- package/lib/types/features/agent/examples.d.ts +0 -59
- package/lib/types/features/agent/examples.d.ts.map +0 -1
- package/lib/types/features/agent/visualization.d.ts +0 -95
- package/lib/types/features/agent/visualization.d.ts.map +0 -1
- package/lib/types/features/store/objects/components/useDownloadObject.d.ts +0 -4
- package/lib/types/features/store/objects/components/useDownloadObject.d.ts.map +0 -1
- package/src/core/components/Button.tsx +0 -63
- package/src/core/components/Modal.tsx +0 -144
- package/src/core/components/Panel.tsx +0 -34
- package/src/core/components/SelectBox.tsx +0 -188
- package/src/core/components/tabs/Tabs.tsx +0 -132
- package/src/core/components/tabs/TabsContext.ts +0 -25
- package/src/core/components/tabs/index.ts +0 -2
- package/src/features/agent/CHART_INSTRUCTIONS.md +0 -228
- package/src/features/agent/createChartTool.ts +0 -643
- package/src/features/agent/examples.ts +0 -321
- package/src/features/agent/visualization.ts +0 -227
- package/src/features/store/objects/components/useDownloadObject.ts +0 -29
- /package/lib/esm/core/components/{MessageBox.js → shadcn/MessageBox.js} +0 -0
- /package/lib/types/core/components/{MessageBox.d.ts → shadcn/MessageBox.d.ts} +0 -0
- /package/lib/types/core/components/{ConfirmModal.d.ts → shadcn/modal/ConfirmModal.d.ts} +0 -0
- /package/lib/types/core/components/{DeleteModal.d.ts → shadcn/modal/DeleteModal.d.ts} +0 -0
- /package/src/core/components/{MessageBox.tsx → shadcn/MessageBox.tsx} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getTenantIdFromProject } from "@vertesia/common";
|
|
2
|
-
import {
|
|
2
|
+
import { Tabs, TabsBar, TabsPanel, VTooltip } from "@vertesia/ui/core";
|
|
3
3
|
import { Env } from "@vertesia/ui/env";
|
|
4
4
|
import { useUserSession } from "@vertesia/ui/session";
|
|
5
5
|
// Package version is now passed as prop from the consuming application
|
|
@@ -69,10 +69,10 @@ export default function InfoList() {
|
|
|
69
69
|
|
|
70
70
|
return (
|
|
71
71
|
<div className="w-full">
|
|
72
|
-
<
|
|
73
|
-
<
|
|
74
|
-
<
|
|
75
|
-
</
|
|
72
|
+
<Tabs defaultValue="user" tabs={tabs} fullWidth updateHash={false}>
|
|
73
|
+
<TabsBar />
|
|
74
|
+
<TabsPanel />
|
|
75
|
+
</Tabs>
|
|
76
76
|
</div>
|
|
77
77
|
)
|
|
78
78
|
}
|
|
@@ -17,13 +17,11 @@ export function JSONCode({ data, className }: { data: any; className?: string })
|
|
|
17
17
|
}, [data]);
|
|
18
18
|
|
|
19
19
|
return (
|
|
20
|
-
<div className={className}>
|
|
20
|
+
<div className={`h-full ${className || ''}`}>
|
|
21
21
|
<MonacoEditor
|
|
22
22
|
value={jsonString}
|
|
23
23
|
language="json"
|
|
24
24
|
theme={theme === 'dark' ? 'vs-dark' : 'vs'}
|
|
25
|
-
minLines={10}
|
|
26
|
-
maxLines={50}
|
|
27
25
|
options={{
|
|
28
26
|
readOnly: true,
|
|
29
27
|
domReadOnly: true,
|
|
@@ -17,7 +17,7 @@ export function JSONDisplay({ value, viewCode = false }: JSONDisplayProps) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
return (
|
|
20
|
-
<div className='relative w-full'>
|
|
20
|
+
<div className='relative w-full h-full'>
|
|
21
21
|
{viewCode ? <JSONCode data={value} /> : <JSONView value={value} />}
|
|
22
22
|
</div>
|
|
23
23
|
)
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { useMemo, type ReactElement } from 'react';
|
|
8
|
+
import DOMPurify from 'dompurify';
|
|
8
9
|
import { CodeBlockPlaceholder, CodeBlockErrorBoundary } from './CodeBlockPlaceholder';
|
|
9
|
-
import {
|
|
10
|
+
import { type VegaLiteChartSpec } from '../../features/agent/chat/AgentChart';
|
|
10
11
|
import { VegaLiteChart } from '../../features/agent/chat/VegaLiteChart';
|
|
11
12
|
import { FusionFragmentHandler, FusionFragmentProvider } from '@vertesia/fusion-ux';
|
|
12
13
|
import { MarkdownRenderer } from './MarkdownRenderer';
|
|
@@ -18,6 +19,7 @@ export type ExpandRenderType =
|
|
|
18
19
|
| 'table'
|
|
19
20
|
| 'markdown'
|
|
20
21
|
| 'fusion-fragment'
|
|
22
|
+
| 'mockup'
|
|
21
23
|
| 'code'
|
|
22
24
|
| 'image'
|
|
23
25
|
| 'auto';
|
|
@@ -45,8 +47,13 @@ function autoDetectRenderType(
|
|
|
45
47
|
): ExpandRenderType {
|
|
46
48
|
const ext = path.split('.').pop()?.toLowerCase();
|
|
47
49
|
|
|
48
|
-
//
|
|
49
|
-
if (
|
|
50
|
+
// SVG files → mockup renderer (inline SVG from text content)
|
|
51
|
+
if (ext === 'svg') {
|
|
52
|
+
return 'mockup';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Image extensions (binary → rendered via URL)
|
|
56
|
+
if (['png', 'jpg', 'jpeg', 'gif', 'webp'].includes(ext || '')) {
|
|
50
57
|
return 'image';
|
|
51
58
|
}
|
|
52
59
|
|
|
@@ -74,11 +81,6 @@ function autoDetectRenderType(
|
|
|
74
81
|
return 'vega-lite';
|
|
75
82
|
}
|
|
76
83
|
|
|
77
|
-
// Check for Recharts format
|
|
78
|
-
if (('chart' in obj || 'type' in obj) && 'data' in obj && Array.isArray(obj.data)) {
|
|
79
|
-
return 'chart';
|
|
80
|
-
}
|
|
81
|
-
|
|
82
84
|
// Check for fusion fragment template with data
|
|
83
85
|
if ('template' in obj && 'data' in obj) {
|
|
84
86
|
return 'fusion-fragment';
|
|
@@ -94,6 +96,24 @@ function autoDetectRenderType(
|
|
|
94
96
|
return 'code';
|
|
95
97
|
}
|
|
96
98
|
|
|
99
|
+
function toVegaLiteSpec(content: unknown): VegaLiteChartSpec | null {
|
|
100
|
+
if (typeof content !== 'object' || content === null) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const obj = content as Record<string, unknown>;
|
|
105
|
+
|
|
106
|
+
if (obj.library === 'vega-lite' && 'spec' in obj && typeof obj.spec === 'object' && obj.spec !== null) {
|
|
107
|
+
return obj as unknown as VegaLiteChartSpec;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (typeof obj.$schema === 'string' && obj.$schema.includes('vega')) {
|
|
111
|
+
return { library: 'vega-lite', spec: obj };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
|
|
97
117
|
/**
|
|
98
118
|
* Table renderer for array data or CSV
|
|
99
119
|
*/
|
|
@@ -175,6 +195,67 @@ function CodeRenderer({ content, path }: { content: unknown; path: string }): Re
|
|
|
175
195
|
);
|
|
176
196
|
}
|
|
177
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Sanitize SVG markup using DOMPurify.
|
|
200
|
+
* Allows only safe SVG elements; strips scripts, event handlers, and foreignObject.
|
|
201
|
+
*/
|
|
202
|
+
export function sanitizeSvg(svg: string): string {
|
|
203
|
+
return DOMPurify.sanitize(svg, {
|
|
204
|
+
USE_PROFILES: { svg: true, svgFilters: true },
|
|
205
|
+
ADD_TAGS: ['use'],
|
|
206
|
+
FORBID_TAGS: ['foreignObject'],
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Make SVG responsive — remove fixed dimensions, ensure viewBox.
|
|
212
|
+
*/
|
|
213
|
+
export function makeSvgResponsive(svg: string): string {
|
|
214
|
+
return svg.replace(/<svg([^>]*)>/i, (_full: string, attrs: string) => {
|
|
215
|
+
let a = attrs;
|
|
216
|
+
if (!/viewBox/i.test(a)) {
|
|
217
|
+
const w = /\swidth\s*=\s*["']?(\d+(?:\.\d+)?)/i.exec(a);
|
|
218
|
+
const h = /\sheight\s*=\s*["']?(\d+(?:\.\d+)?)/i.exec(a);
|
|
219
|
+
if (w && h) a += ` viewBox="0 0 ${w[1]} ${h[1]}"`;
|
|
220
|
+
}
|
|
221
|
+
a = a
|
|
222
|
+
.replace(/\swidth\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/i, '')
|
|
223
|
+
.replace(/\sheight\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/i, '');
|
|
224
|
+
if (/style="/i.test(a)) {
|
|
225
|
+
a = a.replace(/style="([^"]*)"/i, (_: string, v: string) =>
|
|
226
|
+
`style="${v};width:100%;height:auto;display:block;max-width:100%;"`);
|
|
227
|
+
} else {
|
|
228
|
+
a += ' style="width:100%;height:auto;display:block;max-width:100%;"';
|
|
229
|
+
}
|
|
230
|
+
if (!/preserveAspectRatio=/i.test(a)) {
|
|
231
|
+
a += ' preserveAspectRatio="xMidYMid meet"';
|
|
232
|
+
}
|
|
233
|
+
return `<svg${a}>`;
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Mockup renderer — renders raw SVG content inline after sanitization.
|
|
239
|
+
*/
|
|
240
|
+
function MockupRenderer({ content }: { content: unknown }): ReactElement {
|
|
241
|
+
const processedSvg = useMemo(() => {
|
|
242
|
+
const raw = typeof content === 'string' ? content.trim() : '';
|
|
243
|
+
if (!raw) return null;
|
|
244
|
+
return makeSvgResponsive(sanitizeSvg(raw));
|
|
245
|
+
}, [content]);
|
|
246
|
+
|
|
247
|
+
if (!processedSvg) {
|
|
248
|
+
return <CodeBlockPlaceholder type="expand" error="Empty mockup" />;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return (
|
|
252
|
+
<div
|
|
253
|
+
style={{ margin: '16px 0', width: '100%', overflowX: 'auto' }}
|
|
254
|
+
dangerouslySetInnerHTML={{ __html: processedSvg }}
|
|
255
|
+
/>
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
178
259
|
/**
|
|
179
260
|
* Image renderer
|
|
180
261
|
*/
|
|
@@ -215,19 +296,32 @@ export function ArtifactContentRenderer({
|
|
|
215
296
|
// Render based on type
|
|
216
297
|
switch (actualType) {
|
|
217
298
|
case 'chart': {
|
|
299
|
+
const spec = toVegaLiteSpec(content);
|
|
300
|
+
if (!spec) {
|
|
301
|
+
return (
|
|
302
|
+
<CodeBlockPlaceholder
|
|
303
|
+
type="chart"
|
|
304
|
+
error="Only Vega-Lite charts are supported. Recharts rendering has been retired."
|
|
305
|
+
/>
|
|
306
|
+
);
|
|
307
|
+
}
|
|
218
308
|
return (
|
|
219
309
|
<CodeBlockErrorBoundary type="chart" fallbackCode={JSON.stringify(content, null, 2)}>
|
|
220
|
-
<
|
|
310
|
+
<VegaLiteChart spec={spec} artifactRunId={runId} />
|
|
221
311
|
</CodeBlockErrorBoundary>
|
|
222
312
|
);
|
|
223
313
|
}
|
|
224
314
|
|
|
225
315
|
case 'vega-lite': {
|
|
226
|
-
const spec
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
316
|
+
const spec = toVegaLiteSpec(content);
|
|
317
|
+
if (!spec) {
|
|
318
|
+
return (
|
|
319
|
+
<CodeBlockPlaceholder
|
|
320
|
+
type="chart"
|
|
321
|
+
error="Invalid Vega-Lite specification"
|
|
322
|
+
/>
|
|
323
|
+
);
|
|
324
|
+
}
|
|
231
325
|
return (
|
|
232
326
|
<CodeBlockErrorBoundary type="chart" fallbackCode={JSON.stringify(content, null, 2)}>
|
|
233
327
|
<VegaLiteChart spec={spec} artifactRunId={runId} />
|
|
@@ -287,6 +381,13 @@ export function ArtifactContentRenderer({
|
|
|
287
381
|
);
|
|
288
382
|
}
|
|
289
383
|
|
|
384
|
+
case 'mockup':
|
|
385
|
+
return (
|
|
386
|
+
<CodeBlockErrorBoundary type="expand" fallbackCode={typeof content === 'string' ? content : path}>
|
|
387
|
+
<MockupRenderer content={content} />
|
|
388
|
+
</CodeBlockErrorBoundary>
|
|
389
|
+
);
|
|
390
|
+
|
|
290
391
|
case 'image':
|
|
291
392
|
return (
|
|
292
393
|
<CodeBlockErrorBoundary type="image" fallbackCode={path}>
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { useResolvedUrl, parseUrlScheme } from './useResolvedUrl';
|
|
2
|
+
import { CodeBlockPlaceholder } from './CodeBlockPlaceholder';
|
|
3
|
+
|
|
4
|
+
export interface MarkdownFigureProps {
|
|
5
|
+
src?: string;
|
|
6
|
+
alt?: string;
|
|
7
|
+
caption: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
artifactRunId?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Markdown figure component for images with captions.
|
|
14
|
+
* Wraps the image in a <figure> element with a <figcaption>.
|
|
15
|
+
*
|
|
16
|
+
* Usage in markdown: 
|
|
17
|
+
*/
|
|
18
|
+
export function MarkdownFigure({
|
|
19
|
+
src,
|
|
20
|
+
alt,
|
|
21
|
+
caption,
|
|
22
|
+
className,
|
|
23
|
+
artifactRunId,
|
|
24
|
+
}: MarkdownFigureProps) {
|
|
25
|
+
const rawSrc = src || '';
|
|
26
|
+
const { scheme } = parseUrlScheme(rawSrc);
|
|
27
|
+
|
|
28
|
+
// For standard URLs, render directly
|
|
29
|
+
if (scheme === 'standard') {
|
|
30
|
+
return (
|
|
31
|
+
<figure className="my-4">
|
|
32
|
+
<img src={src} alt={alt} className={className} />
|
|
33
|
+
<figcaption className="mt-2 text-sm text-muted text-center italic">
|
|
34
|
+
{caption}
|
|
35
|
+
</figcaption>
|
|
36
|
+
</figure>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// For artifact: and image: URLs, use the resolver
|
|
41
|
+
return (
|
|
42
|
+
<ResolvedFigure
|
|
43
|
+
rawSrc={rawSrc}
|
|
44
|
+
alt={alt}
|
|
45
|
+
caption={caption}
|
|
46
|
+
artifactRunId={artifactRunId}
|
|
47
|
+
className={className}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Internal component for figures that need async URL resolution
|
|
54
|
+
*/
|
|
55
|
+
function ResolvedFigure({
|
|
56
|
+
rawSrc,
|
|
57
|
+
alt,
|
|
58
|
+
caption,
|
|
59
|
+
artifactRunId,
|
|
60
|
+
className,
|
|
61
|
+
}: {
|
|
62
|
+
rawSrc: string;
|
|
63
|
+
alt?: string;
|
|
64
|
+
caption: string;
|
|
65
|
+
artifactRunId?: string;
|
|
66
|
+
className?: string;
|
|
67
|
+
}) {
|
|
68
|
+
const { url, isLoading, error, retry } = useResolvedUrl({
|
|
69
|
+
rawUrl: rawSrc,
|
|
70
|
+
artifactRunId,
|
|
71
|
+
disposition: 'inline',
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (isLoading) {
|
|
75
|
+
return <CodeBlockPlaceholder type="image" message={alt ? `Loading ${alt}...` : undefined} />;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (error) {
|
|
79
|
+
return (
|
|
80
|
+
<CodeBlockPlaceholder
|
|
81
|
+
type="image"
|
|
82
|
+
error={error}
|
|
83
|
+
onRetry={retry}
|
|
84
|
+
/>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!url) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<figure className="my-4">
|
|
94
|
+
<img src={url} alt={alt} className={className} />
|
|
95
|
+
<figcaption className="mt-2 text-sm text-muted text-center italic">
|
|
96
|
+
{caption}
|
|
97
|
+
</figcaption>
|
|
98
|
+
</figure>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
@@ -3,9 +3,19 @@ import type { Element } from 'hast';
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import Markdown, { defaultUrlTransform } from 'react-markdown';
|
|
5
5
|
import remarkGfm from 'remark-gfm';
|
|
6
|
+
import remarkMath from 'remark-math';
|
|
7
|
+
import remarkDirective from 'remark-directive';
|
|
8
|
+
import remarkAlert from 'remark-github-blockquote-alert';
|
|
9
|
+
import { remarkDefinitionList, defListHastHandlers } from 'remark-definition-list';
|
|
10
|
+
import remarkSupersub from 'remark-supersub';
|
|
11
|
+
import rehypeKatex from 'rehype-katex';
|
|
6
12
|
import { SKIP, visit } from 'unist-util-visit';
|
|
7
13
|
import { MarkdownLink } from './MarkdownLink';
|
|
8
14
|
import { MarkdownImage } from './MarkdownImage';
|
|
15
|
+
import { MarkdownFigure } from './MarkdownFigure';
|
|
16
|
+
import { remarkDirectiveHandler } from './remarkDirectiveHandler';
|
|
17
|
+
import { normalizeCustomSchemeLinks } from './normalizeCustomSchemeLinks';
|
|
18
|
+
import { normalizeDirectives } from './normalizeDirectives';
|
|
9
19
|
import {
|
|
10
20
|
CodeBlockHandlerProvider,
|
|
11
21
|
createDefaultCodeBlockHandlers,
|
|
@@ -93,14 +103,41 @@ export function MarkdownRenderer({
|
|
|
93
103
|
onProposalSubmit,
|
|
94
104
|
}: MarkdownRendererProps) {
|
|
95
105
|
const codeBlockRegistry = useCodeBlockRendererRegistry();
|
|
96
|
-
const
|
|
97
|
-
|
|
106
|
+
const normalizedMarkdown = React.useMemo(
|
|
107
|
+
() => normalizeDirectives(normalizeCustomSchemeLinks(children)),
|
|
108
|
+
[children]
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
// Remark plugins (markdown parsing)
|
|
112
|
+
// Order matters: GFM first, then directive (must precede handler),
|
|
113
|
+
// then definition-list/supersub, then math, then user plugins.
|
|
114
|
+
const remarkPluginsArray = React.useMemo(() => {
|
|
115
|
+
const result: any[] = [
|
|
116
|
+
remarkGfm,
|
|
117
|
+
remarkDirective,
|
|
118
|
+
remarkDirectiveHandler,
|
|
119
|
+
remarkAlert,
|
|
120
|
+
remarkDefinitionList,
|
|
121
|
+
remarkSupersub,
|
|
122
|
+
remarkMath,
|
|
123
|
+
...remarkPlugins,
|
|
124
|
+
];
|
|
98
125
|
if (removeComments) {
|
|
99
126
|
result.push(remarkRemoveComments);
|
|
100
127
|
}
|
|
101
128
|
return result;
|
|
102
129
|
}, [remarkPlugins, removeComments]);
|
|
103
130
|
|
|
131
|
+
// Rehype plugins (HTML processing, including KaTeX for math)
|
|
132
|
+
const rehypePluginsArray = React.useMemo(() => [rehypeKatex], []);
|
|
133
|
+
|
|
134
|
+
// Remark-rehype bridge options (custom AST handlers for definition lists)
|
|
135
|
+
const remarkRehypeOptions = React.useMemo(() => ({
|
|
136
|
+
handlers: {
|
|
137
|
+
...defListHastHandlers,
|
|
138
|
+
},
|
|
139
|
+
}), []);
|
|
140
|
+
|
|
104
141
|
const componentsWithOverrides = React.useMemo(() => {
|
|
105
142
|
const baseComponents = components || {};
|
|
106
143
|
const ExistingCode = baseComponents.code;
|
|
@@ -157,7 +194,7 @@ export function MarkdownRenderer({
|
|
|
157
194
|
|
|
158
195
|
// Default code rendering
|
|
159
196
|
const baseInlineClass = 'px-1.5 py-0.5 rounded';
|
|
160
|
-
const baseCodeClass = '
|
|
197
|
+
const baseCodeClass = '';
|
|
161
198
|
|
|
162
199
|
return (
|
|
163
200
|
<code
|
|
@@ -193,8 +230,22 @@ export function MarkdownRenderer({
|
|
|
193
230
|
);
|
|
194
231
|
};
|
|
195
232
|
|
|
196
|
-
const ImageComponent = (props: { node?: any; src?: string; alt?: string }) => {
|
|
197
|
-
const { node, src, alt, ...rest } = props as any;
|
|
233
|
+
const ImageComponent = (props: { node?: any; src?: string; alt?: string; title?: string }) => {
|
|
234
|
+
const { node, src, alt, title, ...rest } = props as any;
|
|
235
|
+
|
|
236
|
+
// If image has a title, render as figure with caption
|
|
237
|
+
if (title) {
|
|
238
|
+
return (
|
|
239
|
+
<MarkdownFigure
|
|
240
|
+
src={src}
|
|
241
|
+
alt={alt}
|
|
242
|
+
caption={title}
|
|
243
|
+
className={imageClassName}
|
|
244
|
+
artifactRunId={artifactRunId}
|
|
245
|
+
/>
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
198
249
|
return (
|
|
199
250
|
<MarkdownImage
|
|
200
251
|
node={node}
|
|
@@ -231,18 +282,20 @@ export function MarkdownRenderer({
|
|
|
231
282
|
onProposalSubmit={onProposalSubmit}
|
|
232
283
|
>
|
|
233
284
|
<Markdown
|
|
234
|
-
remarkPlugins={
|
|
285
|
+
remarkPlugins={remarkPluginsArray}
|
|
286
|
+
rehypePlugins={rehypePluginsArray}
|
|
287
|
+
remarkRehypeOptions={remarkRehypeOptions}
|
|
235
288
|
components={componentsWithOverrides}
|
|
236
289
|
urlTransform={customUrlTransform}
|
|
237
290
|
>
|
|
238
|
-
{
|
|
291
|
+
{normalizedMarkdown}
|
|
239
292
|
</Markdown>
|
|
240
293
|
</CodeBlockHandlerProvider>
|
|
241
294
|
);
|
|
242
295
|
|
|
243
296
|
if (className) {
|
|
244
|
-
return <div className={className}>{markdownContent}</div>;
|
|
297
|
+
return <div className={`md-content ${className}`}>{markdownContent}</div>;
|
|
245
298
|
}
|
|
246
299
|
|
|
247
|
-
return markdownContent
|
|
300
|
+
return <div className="md-content">{markdownContent}</div>;
|
|
248
301
|
}
|
|
@@ -1,13 +1,103 @@
|
|
|
1
1
|
import { useEffect, useRef, useState, useId } from 'react';
|
|
2
2
|
import mermaid from 'mermaid';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const MERMAID_FONT_FAMILY =
|
|
5
|
+
'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Browser-side Mermaid normalization:
|
|
9
|
+
* - Convert escaped newlines in quoted labels (`\n`, `\\n`) to HTML line breaks.
|
|
10
|
+
* Mermaid web rendering handles `<br/>` labels more reliably than escaped `\n`.
|
|
11
|
+
*/
|
|
12
|
+
function normalizeMermaidCodeForBrowser(code: string): string {
|
|
13
|
+
const trimmed = code.trim();
|
|
14
|
+
let normalized = '';
|
|
15
|
+
let inDoubleQuote = false;
|
|
16
|
+
let inSingleQuote = false;
|
|
17
|
+
|
|
18
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
19
|
+
const char = trimmed[i];
|
|
20
|
+
const prev = i > 0 ? trimmed[i - 1] : '';
|
|
21
|
+
|
|
22
|
+
if (char === '"' && !inSingleQuote && prev !== '\\') {
|
|
23
|
+
inDoubleQuote = !inDoubleQuote;
|
|
24
|
+
normalized += char;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (char === "'" && !inDoubleQuote && prev !== '\\') {
|
|
29
|
+
inSingleQuote = !inSingleQuote;
|
|
30
|
+
normalized += char;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if ((inDoubleQuote || inSingleQuote) && char === '\\') {
|
|
35
|
+
let j = i;
|
|
36
|
+
while (trimmed[j] === '\\') {
|
|
37
|
+
j++;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (trimmed[j] === 'n') {
|
|
41
|
+
normalized += '<br/>';
|
|
42
|
+
i = j;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
normalized += char;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return normalized;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Force Mermaid SVG output to scale with container width.
|
|
55
|
+
* This keeps text and shapes proportional when the container shrinks/expands.
|
|
56
|
+
*/
|
|
57
|
+
function makeSvgResponsive(svg: string): string {
|
|
58
|
+
return svg.replace(/<svg([^>]*)>/i, (_full, attrs: string) => {
|
|
59
|
+
let nextAttrs = attrs
|
|
60
|
+
.replace(/\swidth="[^"]*"/i, '')
|
|
61
|
+
.replace(/\sheight="[^"]*"/i, '');
|
|
62
|
+
|
|
63
|
+
if (/style="/i.test(nextAttrs)) {
|
|
64
|
+
nextAttrs = nextAttrs.replace(
|
|
65
|
+
/style="([^"]*)"/i,
|
|
66
|
+
(_styleFull, styleValue: string) =>
|
|
67
|
+
`style="${styleValue};width:100%;height:auto;display:block;max-width:100%;"`
|
|
68
|
+
);
|
|
69
|
+
} else {
|
|
70
|
+
nextAttrs += ' style="width:100%;height:auto;display:block;max-width:100%;"';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!/preserveAspectRatio=/i.test(nextAttrs)) {
|
|
74
|
+
nextAttrs += ' preserveAspectRatio="xMidYMid meet"';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return `<svg${nextAttrs}>`;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Initialize mermaid with a browser-focused config close to Mermaid Playground defaults.
|
|
5
82
|
mermaid.initialize({
|
|
6
83
|
startOnLoad: false,
|
|
7
84
|
theme: 'default',
|
|
8
85
|
securityLevel: 'loose',
|
|
9
|
-
fontFamily:
|
|
86
|
+
fontFamily: MERMAID_FONT_FAMILY,
|
|
10
87
|
suppressErrorRendering: true,
|
|
88
|
+
flowchart: {
|
|
89
|
+
htmlLabels: true,
|
|
90
|
+
useMaxWidth: true,
|
|
91
|
+
nodeSpacing: 40,
|
|
92
|
+
rankSpacing: 50,
|
|
93
|
+
padding: 12,
|
|
94
|
+
},
|
|
95
|
+
sequence: {
|
|
96
|
+
useMaxWidth: true,
|
|
97
|
+
},
|
|
98
|
+
themeVariables: {
|
|
99
|
+
fontFamily: MERMAID_FONT_FAMILY,
|
|
100
|
+
},
|
|
11
101
|
});
|
|
12
102
|
|
|
13
103
|
export interface MermaidDiagramProps {
|
|
@@ -54,12 +144,14 @@ export function MermaidDiagram({ code, className }: MermaidDiagramProps) {
|
|
|
54
144
|
|
|
55
145
|
// Generate unique ID for this render
|
|
56
146
|
const id = `mermaid-${uniqueId}-${Date.now()}`;
|
|
147
|
+
const normalizedCode = normalizeMermaidCodeForBrowser(code);
|
|
57
148
|
|
|
58
149
|
// Render the diagram
|
|
59
|
-
const { svg: renderedSvg } = await mermaid.render(id,
|
|
150
|
+
const { svg: renderedSvg } = await mermaid.render(id, normalizedCode);
|
|
151
|
+
const responsiveSvg = makeSvgResponsive(renderedSvg);
|
|
60
152
|
|
|
61
153
|
if (!cancelled) {
|
|
62
|
-
setSvg(
|
|
154
|
+
setSvg(responsiveSvg);
|
|
63
155
|
}
|
|
64
156
|
} catch (err: unknown) {
|
|
65
157
|
if (!cancelled) {
|
|
@@ -93,7 +185,7 @@ export function MermaidDiagram({ code, className }: MermaidDiagramProps) {
|
|
|
93
185
|
return (
|
|
94
186
|
<div
|
|
95
187
|
ref={containerRef}
|
|
96
|
-
className={`my-4 overflow-x-auto ${className || ''}`}
|
|
188
|
+
className={`my-4 w-full overflow-x-auto [&_svg]:mx-auto [&_svg]:w-full [&_svg]:h-auto [&_svg]:max-w-full ${className || ''}`}
|
|
97
189
|
dangerouslySetInnerHTML={{ __html: svg }}
|
|
98
190
|
/>
|
|
99
191
|
);
|
|
@@ -41,19 +41,12 @@ describe('Chart JSON parsing', () => {
|
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
const detectChartLibrary = (spec: Record<string, unknown>): 'vega-lite' |
|
|
44
|
+
const detectChartLibrary = (spec: Record<string, unknown>): 'vega-lite' | null => {
|
|
45
45
|
const hasVegaSchema = typeof spec.$schema === 'string' && spec.$schema.includes('vega');
|
|
46
46
|
const isExplicitVegaLite = spec.library === 'vega-lite' && 'spec' in spec;
|
|
47
47
|
if (hasVegaSchema || isExplicitVegaLite) {
|
|
48
48
|
return 'vega-lite';
|
|
49
49
|
}
|
|
50
|
-
const isRecharts =
|
|
51
|
-
('chart' in spec || 'type' in spec || spec.library === 'recharts') &&
|
|
52
|
-
'data' in spec &&
|
|
53
|
-
Array.isArray(spec.data);
|
|
54
|
-
if (isRecharts) {
|
|
55
|
-
return 'recharts';
|
|
56
|
-
}
|
|
57
50
|
return null;
|
|
58
51
|
};
|
|
59
52
|
|
|
@@ -102,39 +95,15 @@ describe('Chart JSON parsing', () => {
|
|
|
102
95
|
expect(detectChartLibrary(spec)).toBe('vega-lite');
|
|
103
96
|
});
|
|
104
97
|
|
|
105
|
-
it('should detect Recharts by chart field', () => {
|
|
106
|
-
const spec = {
|
|
107
|
-
chart: 'bar',
|
|
108
|
-
data: [{ x: 1, y: 2 }],
|
|
109
|
-
};
|
|
110
|
-
expect(detectChartLibrary(spec)).toBe('recharts');
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('should detect Recharts by type field', () => {
|
|
114
|
-
const spec = {
|
|
115
|
-
type: 'line',
|
|
116
|
-
data: [{ x: 1, y: 2 }],
|
|
117
|
-
};
|
|
118
|
-
expect(detectChartLibrary(spec)).toBe('recharts');
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it('should detect explicit Recharts with library field', () => {
|
|
122
|
-
const spec = {
|
|
123
|
-
library: 'recharts',
|
|
124
|
-
data: [{ x: 1, y: 2 }],
|
|
125
|
-
};
|
|
126
|
-
expect(detectChartLibrary(spec)).toBe('recharts');
|
|
127
|
-
});
|
|
128
|
-
|
|
129
98
|
it('should return null for non-chart spec', () => {
|
|
130
99
|
const spec = { foo: 'bar' };
|
|
131
100
|
expect(detectChartLibrary(spec)).toBeNull();
|
|
132
101
|
});
|
|
133
102
|
|
|
134
|
-
it('should return null for
|
|
103
|
+
it('should return null for legacy chart format', () => {
|
|
135
104
|
const spec = {
|
|
136
105
|
chart: 'bar',
|
|
137
|
-
data:
|
|
106
|
+
data: [{ x: 1, y: 2 }],
|
|
138
107
|
};
|
|
139
108
|
expect(detectChartLibrary(spec)).toBeNull();
|
|
140
109
|
});
|