@jini-ai/ui 0.5.5 → 0.6.10

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.
Files changed (263) hide show
  1. package/CHANGELOG.md +91 -2
  2. package/dist/core/theme/validation.js +40 -38
  3. package/dist/features/a2ui/renderer.js +15 -13
  4. package/dist/features/about/react/components/AboutTab.js +64 -34
  5. package/dist/features/about/rules.d.ts +2 -2
  6. package/dist/features/about/rules.js +156 -129
  7. package/dist/features/admin-widgets/components/ImagePreviewModal.d.ts +4 -3
  8. package/dist/features/admin-widgets/components/ImagePreviewModal.js +6 -10
  9. package/dist/features/admin-widgets/components/InfoTip.d.ts +3 -2
  10. package/dist/features/admin-widgets/components/InfoTip.hooks.js +2 -0
  11. package/dist/features/admin-widgets/components/InfoTip.js +34 -7
  12. package/dist/features/admin-widgets/components/InfoTip.rules.d.ts +13 -0
  13. package/dist/features/admin-widgets/components/InfoTip.rules.js +43 -10
  14. package/dist/features/admin-widgets/components/Lightbox/Lightbox.d.ts +30 -0
  15. package/dist/features/admin-widgets/components/Lightbox/Lightbox.hooks.d.ts +40 -0
  16. package/dist/features/admin-widgets/components/Lightbox/Lightbox.hooks.js +128 -0
  17. package/dist/features/admin-widgets/components/Lightbox/Lightbox.js +18 -0
  18. package/dist/features/admin-widgets/components/MiddleTruncate.d.ts +14 -0
  19. package/dist/features/admin-widgets/components/MiddleTruncate.js +12 -0
  20. package/dist/features/admin-widgets/components/MiddleTruncate.rules.d.ts +20 -0
  21. package/dist/features/admin-widgets/components/MiddleTruncate.rules.js +21 -0
  22. package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.d.ts +18 -0
  23. package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.hooks.d.ts +16 -0
  24. package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.hooks.js +45 -0
  25. package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.js +18 -0
  26. package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.rules.d.ts +32 -0
  27. package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.rules.js +26 -0
  28. package/dist/features/admin-widgets/components/SuggestInput/SuggestInput.hooks.js +29 -14
  29. package/dist/features/admin-widgets/index.d.ts +14 -2
  30. package/dist/features/admin-widgets/index.js +7 -1
  31. package/dist/features/admin-widgets/styles/admin-widgets.css +1 -0
  32. package/dist/features/asset-grid/react/components/AssetCard.js +7 -1
  33. package/dist/features/asset-grid/react/components/AssetGrid.d.ts +1 -1
  34. package/dist/features/asset-grid/react/components/AssetGrid.js +38 -18
  35. package/dist/features/asset-grid/react/components/useAssetGridFilters.d.ts +21 -0
  36. package/dist/features/asset-grid/react/components/useAssetGridFilters.js +19 -0
  37. package/dist/features/asset-grid/react/hooks/useAssetGridKeyboardShortcuts.js +16 -11
  38. package/dist/features/asset-grid/react/hooks/useAssetGridLiveUpdates.d.ts +2 -0
  39. package/dist/features/asset-grid/react/hooks/useAssetGridLiveUpdates.js +35 -11
  40. package/dist/features/asset-tree-browser/react/components/AssetTreeBrowser.d.ts +6 -6
  41. package/dist/features/asset-tree-browser/react/components/AssetTreeBrowser.js +10 -129
  42. package/dist/features/asset-tree-browser/react/components/AssetTreeBrowserParts.d.ts +50 -0
  43. package/dist/features/asset-tree-browser/react/components/AssetTreeBrowserParts.js +95 -0
  44. package/dist/features/asset-tree-browser/react/components/useAssetTreeBrowserController.d.ts +56 -0
  45. package/dist/features/asset-tree-browser/react/components/useAssetTreeBrowserController.js +80 -0
  46. package/dist/features/asset-tree-browser/rules.js +40 -22
  47. package/dist/features/browser-chrome/rules.js +74 -70
  48. package/dist/features/charts/browser.js +11 -5
  49. package/dist/features/charts/react.js +2 -2
  50. package/dist/features/charts/table.js +2 -2
  51. package/dist/features/command-palette/react/hooks/useCommandPalette.js +3 -9
  52. package/dist/features/connectors/ConnectorsBrowser.d.ts +4 -4
  53. package/dist/features/connectors/ConnectorsBrowser.js +26 -14
  54. package/dist/features/connectors/components/ConnectorCard.js +67 -38
  55. package/dist/features/connectors/components/ConnectorDetailDrawer.js +62 -31
  56. package/dist/features/connectors/components/ConnectorGrid.js +11 -6
  57. package/dist/features/connectors/hooks/useConnectorAuthorization.js +6 -0
  58. package/dist/features/connectors/hooks/useConnectorCatalog.d.ts +2 -0
  59. package/dist/features/connectors/hooks/useConnectorCatalog.js +32 -13
  60. package/dist/features/connectors/hooks/useWiredConnectorsBrowser.d.ts +3 -3
  61. package/dist/features/connectors/rules.d.ts +8 -1
  62. package/dist/features/connectors/rules.js +42 -20
  63. package/dist/features/connectors/types.d.ts +11 -0
  64. package/dist/features/execution/constants.d.ts +4 -10
  65. package/dist/features/execution/constants.js +9 -94
  66. package/dist/features/execution/react/components/ByokProviderForm.d.ts +2 -4
  67. package/dist/features/execution/react/components/ByokProviderForm.js +140 -43
  68. package/dist/features/execution/react/components/ExecutionTab.d.ts +1 -2
  69. package/dist/features/execution/react/components/ExecutionTab.js +52 -30
  70. package/dist/features/execution/react/components/LocalCliAgentCard.js +12 -3
  71. package/dist/features/execution/react/components/LocalCliAgentList.js +14 -3
  72. package/dist/features/execution/react/components/LocalCliAgentSettings.js +14 -3
  73. package/dist/features/execution/react/hooks/useLocalCliAgentCard.js +54 -36
  74. package/dist/features/execution/react/hooks/useReasoningControl.js +114 -78
  75. package/dist/features/execution/rules.d.ts +2 -2
  76. package/dist/features/execution/rules.js +31 -15
  77. package/dist/features/execution/types.d.ts +4 -42
  78. package/dist/features/execution/types.js +0 -17
  79. package/dist/features/external-mcp/react/components/ExternalMcpTab.d.ts +6 -2
  80. package/dist/features/external-mcp/react/components/ExternalMcpTab.js +9 -2
  81. package/dist/features/file-dropzone/react/components/FileDropzone.js +24 -25
  82. package/dist/features/file-dropzone/react/components/FileDropzoneLightbox.d.ts +2 -2
  83. package/dist/features/file-dropzone/react/components/FileDropzoneLightbox.js +35 -30
  84. package/dist/features/file-dropzone/react/components/FileDropzoneThumbnailGrid.js +30 -24
  85. package/dist/features/file-dropzone/react/components/FileDropzoneZone.d.ts +14 -0
  86. package/dist/features/file-dropzone/react/components/FileDropzoneZone.js +26 -0
  87. package/dist/features/html-editor/canvas-content-wrapper.js +13 -13
  88. package/dist/features/html-editor/canvas-embed-placeholders.js +46 -37
  89. package/dist/features/html-editor/css.js +76 -69
  90. package/dist/features/html-editor/editor-blocks.js +47 -33
  91. package/dist/features/html-editor/editor-serialization.js +6 -5
  92. package/dist/features/html-editor/protected-elements.js +39 -28
  93. package/dist/features/html-editor/react/hooks/useInteractiveHtmlEditor.js +4 -4
  94. package/dist/features/html-editor/source-splice.js +51 -30
  95. package/dist/features/i18n/dictionaries/settings-dialog.ja.js +1 -0
  96. package/dist/features/i18n/dictionaries/settings-dialog.zh-CN.js +1 -0
  97. package/dist/features/i18n/dictionaries/settings-dialog.zh-TW.js +1 -0
  98. package/dist/features/i18n/locale.js +20 -16
  99. package/dist/features/iframe-pool/react/dom-sync.js +8 -6
  100. package/dist/features/integrations/react/components/CodexInstallToggleButton.js +19 -4
  101. package/dist/features/integrations/react/components/IntegrationsTab.js +60 -14
  102. package/dist/features/interactive-ui/interactive-ui.css +1 -1
  103. package/dist/features/interactive-ui/providers/shadcn/data-table.js +10 -7
  104. package/dist/features/lexical-rich-text-editor/mention-parser.js +60 -57
  105. package/dist/features/lexical-rich-text-editor/react/hooks/useKeyboardCommands.js +33 -38
  106. package/dist/features/lexical-rich-text-editor/rules.js +87 -74
  107. package/dist/features/lexical-rich-text-editor/serialize.js +27 -25
  108. package/dist/features/mcp-ui/secret-card.js +111 -61
  109. package/dist/features/mcp-ui/surfaces/confirmation.js +39 -21
  110. package/dist/features/mcp-ui/surfaces/document.d.ts +1 -1
  111. package/dist/features/mcp-ui/surfaces/document.js +10 -2
  112. package/dist/features/mcp-ui/surfaces/fields.js +30 -50
  113. package/dist/features/mcp-ui/surfaces/form.d.ts +6 -0
  114. package/dist/features/mcp-ui/surfaces/form.js +43 -21
  115. package/dist/features/mcp-ui/surfaces/outcome.js +30 -20
  116. package/dist/features/mcp-ui/surfaces/text-input.js +33 -21
  117. package/dist/features/mcp-ui/surfaces/tokens.d.ts +6 -1
  118. package/dist/features/mcp-ui/surfaces/tokens.js +5 -2
  119. package/dist/features/media-providers/constants.d.ts +1 -0
  120. package/dist/features/media-providers/constants.js +2 -81
  121. package/dist/features/media-providers/index.d.ts +1 -1
  122. package/dist/features/media-providers/ports.d.ts +2 -0
  123. package/dist/features/media-providers/react/components/MediaProviderCard.d.ts +22 -0
  124. package/dist/features/media-providers/react/components/MediaProviderCard.js +50 -0
  125. package/dist/features/media-providers/react/components/MediaProvidersTab.d.ts +5 -6
  126. package/dist/features/media-providers/react/components/MediaProvidersTab.js +40 -72
  127. package/dist/features/media-providers/react/components/media-providers-tab-labels.d.ts +11 -0
  128. package/dist/features/media-providers/react/components/media-providers-tab-labels.js +57 -0
  129. package/dist/features/media-providers/react/hooks/useMediaProvidersTab.d.ts +4 -2
  130. package/dist/features/media-providers/react/hooks/useMediaProvidersTab.js +37 -23
  131. package/dist/features/media-providers/rules.js +17 -10
  132. package/dist/features/media-providers/types.d.ts +4 -22
  133. package/dist/features/media-providers/types.js +3 -8
  134. package/dist/features/memory/formatters.js +127 -92
  135. package/dist/features/memory/react/components/MemoryConnectedPanel.js +92 -36
  136. package/dist/features/memory/react/components/MemoryList.js +37 -18
  137. package/dist/features/memory/react/hooks/useMemoryExtractions.store.js +42 -36
  138. package/dist/features/notifications/react/components/NotificationsTab.js +28 -28
  139. package/dist/features/observability/long-task.d.ts +0 -12
  140. package/dist/features/observability/long-task.js +15 -19
  141. package/dist/features/observability/resource-error.d.ts +0 -10
  142. package/dist/features/observability/resource-error.js +18 -13
  143. package/dist/features/observability/stuck-run.js +10 -6
  144. package/dist/features/observability/telemetry-url.d.ts +6 -0
  145. package/dist/features/observability/telemetry-url.js +16 -0
  146. package/dist/features/observability/white-screen.js +12 -24
  147. package/dist/features/panel-kit/fetch-query/adapter.react.d.ts +2 -2
  148. package/dist/features/panel-kit/fetch-query/adapter.react.js +4 -2
  149. package/dist/features/panel-kit/fetch-query/adapter.tanstack.js +46 -33
  150. package/dist/features/panel-kit/helpers/standing-draft-local-backup.js +3 -1
  151. package/dist/features/panel-kit/hooks/use-settings-slice.hooks.js +3 -1
  152. package/dist/features/privacy/react/components/PrivacyTab.js +24 -13
  153. package/dist/features/progress-card/components/ProgressCard.js +7 -3
  154. package/dist/features/progress-card/reference-adapters.js +59 -54
  155. package/dist/features/project-locations/react/components/ProjectLocationsTab.js +24 -15
  156. package/dist/features/project-locations/react/hooks/useProjectLocationsTab.d.ts +8 -0
  157. package/dist/features/project-locations/react/hooks/useProjectLocationsTab.js +31 -23
  158. package/dist/features/resource-dashboard/react/components/ResourceBoard.js +6 -47
  159. package/dist/features/resource-dashboard/react/components/ResourceBoardView.d.ts +2 -2
  160. package/dist/features/resource-dashboard/react/components/ResourceBoardView.js +3 -6
  161. package/dist/features/resource-dashboard/react/components/ResourceBoardViewParts.d.ts +15 -0
  162. package/dist/features/resource-dashboard/react/components/ResourceBoardViewParts.js +35 -0
  163. package/dist/features/resource-dashboard/react/components/ResourceCard.js +5 -16
  164. package/dist/features/resource-dashboard/react/components/ResourceCardParts.d.ts +34 -0
  165. package/dist/features/resource-dashboard/react/components/ResourceCardParts.js +34 -0
  166. package/dist/features/resource-dashboard/react/components/ResourceRowList.js +3 -1
  167. package/dist/features/resource-dashboard/react/components/ResourceRowListItem.js +2 -2
  168. package/dist/features/resource-dashboard/react/components/ResourceRowListItemParts.d.ts +19 -0
  169. package/dist/features/resource-dashboard/react/components/ResourceRowListItemParts.js +11 -0
  170. package/dist/features/resource-dashboard/react/components/ResourceRowListView.d.ts +1 -1
  171. package/dist/features/resource-dashboard/react/components/ResourceRowListView.js +4 -4
  172. package/dist/features/resource-dashboard/react/components/ResourceRowListViewParts.d.ts +10 -0
  173. package/dist/features/resource-dashboard/react/components/ResourceRowListViewParts.js +20 -0
  174. package/dist/features/resource-dashboard/react/components/resourceBoardProps.d.ts +48 -0
  175. package/dist/features/resource-dashboard/react/components/resourceBoardProps.js +70 -0
  176. package/dist/features/resource-dashboard/react/components/resourceRowListProps.d.ts +19 -0
  177. package/dist/features/resource-dashboard/react/components/resourceRowListProps.js +14 -0
  178. package/dist/features/resource-dashboard/react/components/translatedErrorLabelProps.d.ts +16 -0
  179. package/dist/features/resource-dashboard/react/components/translatedErrorLabelProps.js +13 -0
  180. package/dist/features/resource-dashboard/rules.js +2 -8
  181. package/dist/features/sketch-editor/dom.js +150 -99
  182. package/dist/features/sketch-editor/react/components/SketchEditor.js +26 -15
  183. package/dist/features/skills/react/components/SkillDraftForm.js +13 -19
  184. package/dist/features/skills/react/components/SkillDraftForm.labels.d.ts +31 -0
  185. package/dist/features/skills/react/components/SkillDraftForm.labels.js +54 -0
  186. package/dist/features/skills/react/components/SkillRow.js +38 -18
  187. package/dist/features/skills/react/components/SkillRow.labels.d.ts +7 -0
  188. package/dist/features/skills/react/components/SkillRow.labels.js +18 -0
  189. package/dist/features/skills/react/components/SkillsTab.js +24 -14
  190. package/dist/features/skills/react/components/SkillsTab.labels.d.ts +7 -0
  191. package/dist/features/skills/react/components/SkillsTab.labels.js +11 -0
  192. package/dist/features/skills/rules.js +32 -23
  193. package/dist/features/source-config-list/agent-handles.js +2 -1
  194. package/dist/features/source-config-list/dependencies.js +53 -49
  195. package/dist/features/source-config-list/index.d.ts +3 -3
  196. package/dist/features/source-config-list/react/components/SourceConfigAddForm.d.ts +6 -5
  197. package/dist/features/source-config-list/react/components/SourceConfigAddForm.js +38 -7
  198. package/dist/features/source-config-list/react/components/SourceConfigField.js +69 -25
  199. package/dist/features/source-config-list/react/components/SourceConfigItemCard.d.ts +6 -5
  200. package/dist/features/source-config-list/react/components/SourceConfigItemCard.js +76 -20
  201. package/dist/features/source-config-list/react/components/SourceConfigListView.d.ts +5 -3
  202. package/dist/features/source-config-list/react/components/SourceConfigListView.js +33 -3
  203. package/dist/features/source-config-list/react/components/SourceConfigTestControl.js +17 -1
  204. package/dist/features/source-config-list/react/components/SourceConfigTrustOptions.d.ts +11 -0
  205. package/dist/features/source-config-list/react/components/SourceConfigTrustOptions.js +12 -0
  206. package/dist/features/source-config-list/types.d.ts +14 -0
  207. package/dist/features/tab-launcher-menu/react/components/TabLauncherMenu.js +25 -1
  208. package/dist/features/tab-launcher-menu/react/hooks/useTabLauncherMenu.js +15 -16
  209. package/dist/features/tab-strip/react/components/TabBar.js +8 -1
  210. package/dist/features/tabbed-dialog/react/components/TabbedDialog.js +8 -30
  211. package/dist/features/tabbed-dialog/react/components/TabbedDialogChrome.d.ts +15 -0
  212. package/dist/features/tabbed-dialog/react/components/TabbedDialogChrome.js +8 -0
  213. package/dist/features/tabbed-dialog/react/components/TabbedDialogHeader.d.ts +12 -0
  214. package/dist/features/tabbed-dialog/react/components/TabbedDialogHeader.js +6 -0
  215. package/dist/features/tabbed-dialog/react/components/TabbedDialogSidebar.d.ts +27 -0
  216. package/dist/features/tabbed-dialog/react/components/TabbedDialogSidebar.js +12 -0
  217. package/dist/features/tabbed-dialog/react/components/tabbedDialogView.d.ts +43 -0
  218. package/dist/features/tabbed-dialog/react/components/tabbedDialogView.js +59 -0
  219. package/dist/features/version-manager/dependencies.d.ts +3 -1
  220. package/dist/features/version-manager/dependencies.js +3 -2
  221. package/dist/features/version-manager/react/components/VersionManagerModal.js +10 -6
  222. package/dist/features/version-manager/react/hooks/useVersionManager.js +7 -4
  223. package/dist/features/viewer-shell/react/components/CommentSidePanel.js +103 -50
  224. package/dist/features/viewer-shell/react/components/MarkdownSplitPane.js +28 -8
  225. package/dist/features/viewer-shell/react/hooks/useCommentReorder.js +22 -16
  226. package/dist/features/viewer-shell/rules.js +19 -23
  227. package/dist/react/components/CustomSelect.d.ts +38 -1
  228. package/dist/react/components/CustomSelect.js +94 -38
  229. package/dist/react/components/OnboardingDropdown.js +20 -8
  230. package/dist/react/components/RemixIcon.stylesheet.js +3 -1
  231. package/dist/react/components/Toast.js +13 -2
  232. package/dist/react/components/TooltipLayer.js +5 -14
  233. package/dist/react/components/WorkingDirPicker.js +78 -50
  234. package/dist/react/components/remixicon-font-recovery.js +38 -30
  235. package/dist/react/components/select-popover.d.ts +8 -6
  236. package/dist/react/components/select-popover.js +33 -29
  237. package/dist/react/mcp-ui/McpUiHost.d.ts +1 -1
  238. package/dist/react/mcp-ui/McpUiHost.js +10 -11
  239. package/dist/react/mcp-ui/host-message-source.d.ts +14 -2
  240. package/dist/react/mcp-ui/host-message-source.js +15 -5
  241. package/dist/react/mcp-ui/mcp-ui-host-frame.d.ts +41 -0
  242. package/dist/react/mcp-ui/mcp-ui-host-frame.js +39 -0
  243. package/dist/renderers/annotation-canvas/react/components/AnnotationCanvas.js +97 -69
  244. package/dist/renderers/preview-modal-shell/react/components/PreviewModalShell.js +59 -30
  245. package/dist/renderers/react/components/ArtifactView.js +9 -6
  246. package/dist/renderers/srcdoc/build.d.ts +4 -1
  247. package/dist/renderers/srcdoc/build.js +62 -48
  248. package/dist/styles/admin.css +29 -14
  249. package/dist/styles/lightbox.css +142 -0
  250. package/dist/styles/variables.css +128 -0
  251. package/dist/theme/apply.js +9 -5
  252. package/dist/utils/auto-open-file.d.ts +2 -1
  253. package/dist/utils/auto-open-file.js +69 -85
  254. package/dist/utils/markdown-scroll-sync.js +108 -87
  255. package/dist/utils/polygon-selection.js +25 -26
  256. package/dist/utils/smooth-scroll-to-top.d.ts +1 -1
  257. package/dist/utils/smooth-scroll-to-top.js +2 -32
  258. package/dist/utils/sse.js +26 -26
  259. package/dist/utils/unit-bezier.d.ts +7 -0
  260. package/dist/utils/unit-bezier.js +38 -0
  261. package/package.json +9 -12
  262. package/dist/features/admin-widgets/components/ImagePreviewModal.hooks.d.ts +0 -13
  263. package/dist/features/admin-widgets/components/ImagePreviewModal.hooks.js +0 -46
@@ -15,6 +15,10 @@ export function propNameToAttributeName(name) {
15
15
  return 'srcdoc';
16
16
  if (name === 'tabIndex')
17
17
  return 'tabindex';
18
+ if (name === 'referrerPolicy')
19
+ return 'referrerpolicy';
20
+ if (name === 'allowFullScreen')
21
+ return 'allowfullscreen';
18
22
  if (name.startsWith('data-') || name.startsWith('aria-'))
19
23
  return name;
20
24
  return name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`).toLowerCase();
@@ -74,15 +78,13 @@ export function syncStyle(frame, style, appliedStyleKeys) {
74
78
  }
75
79
  }
76
80
  }
81
+ const NON_ATTRIBUTE_PROPS = new Set([
82
+ 'cacheKey', 'src', 'style', 'children', 'dangerouslySetInnerHTML',
83
+ ]);
77
84
  export function syncIframeProps(frame, props, appliedAttributes, appliedStyleKeys) {
78
85
  const nextAttributes = new Set();
79
86
  for (const [name, value] of Object.entries(props)) {
80
- if (name === 'cacheKey'
81
- || name === 'src'
82
- || name === 'style'
83
- || name === 'children'
84
- || name === 'dangerouslySetInnerHTML'
85
- || name.startsWith('on')) {
87
+ if (NON_ATTRIBUTE_PROPS.has(name) || name.startsWith('on')) {
86
88
  continue;
87
89
  }
88
90
  const attributeName = propNameToAttributeName(name);
@@ -13,10 +13,25 @@ export function CodexInstallToggleButton({ port, agentHandle }) {
13
13
  const { available, installed, busy, error, successKind, toggle } = useCodexInstallToggle(port);
14
14
  if (available === null)
15
15
  return null;
16
- if (!available) {
17
- return (_jsxs("div", { className: "jini-codex-install-row", children: [_jsx("button", { type: "button", className: "jini-button", disabled: true, children: t('One-click install') }), _jsx("span", { className: "jini-hint", children: t('Not available for this daemon.') })] }));
18
- }
16
+ if (!available)
17
+ return _jsx(CodexInstallUnavailableRow, {});
19
18
  const label = installed ? t('Uninstall') : t('One-click install');
20
- return (_jsxs("div", { className: "jini-codex-install-row", children: [_jsx("button", { type: "button", className: installed ? 'jini-button' : 'jini-button jini-button-primary', disabled: busy, onClick: toggle, ...agentHandleProps({}, { base: agentHandle, ...({ role: 'button', label }) }), children: busy ? t('Working…') : label }), error ? _jsx("span", { className: "jini-hint jini-hint-error", children: t('Install failed: {error}', { error }) }) : null, !error && successKind === 'installed' ? _jsx("span", { className: "jini-hint", children: t('MCP server installed.') }) : null, !error && successKind === 'uninstalled' ? _jsx("span", { className: "jini-hint", children: t('MCP server uninstalled.') }) : null] }));
19
+ return (_jsxs("div", { className: "jini-codex-install-row", children: [_jsx("button", { type: "button", className: installed ? 'jini-button' : 'jini-button jini-button-primary', disabled: busy, onClick: toggle, ...agentHandleProps({}, { base: agentHandle, role: 'button', label }), children: busy ? t('Working…') : label }), _jsx(CodexInstallStatusHint, { error: error, successKind: successKind })] }));
20
+ }
21
+ /** The row shown when the host's port has no Codex one-click install support. */
22
+ function CodexInstallUnavailableRow() {
23
+ const t = useT();
24
+ return (_jsxs("div", { className: "jini-codex-install-row", children: [_jsx("button", { type: "button", className: "jini-button", disabled: true, children: t('One-click install') }), _jsx("span", { className: "jini-hint", children: t('Not available for this daemon.') })] }));
25
+ }
26
+ /** The hint after the last toggle: its error if it failed, else which success it reached, else nothing. */
27
+ function CodexInstallStatusHint({ error, successKind }) {
28
+ const t = useT();
29
+ if (error)
30
+ return _jsx("span", { className: "jini-hint jini-hint-error", children: t('Install failed: {error}', { error }) });
31
+ if (successKind === 'installed')
32
+ return _jsx("span", { className: "jini-hint", children: t('MCP server installed.') });
33
+ if (successKind === 'uninstalled')
34
+ return _jsx("span", { className: "jini-hint", children: t('MCP server uninstalled.') });
35
+ return null;
21
36
  }
22
37
  //# sourceMappingURL=CodexInstallToggleButton.js.map
@@ -23,6 +23,14 @@ export function IntegrationsTab({ serverName = DEFAULT_MCP_SERVER_NAME, clients
23
23
  const resolvedPort = useMemo(() => port ?? createFakeMcpIntegrationsPort(), [port]);
24
24
  const [clientId, setClientId] = useState(initialClientId);
25
25
  const { info, error, loading } = useMcpInstallInfo(resolvedPort);
26
+ const { client, resolved } = resolveClientSnippet({ clients, clientId, serverName, info });
27
+ return (_jsxs("section", { className: "jini-settings-section jini-settings-integrations", children: [_jsx(DaemonErrorCard, { error: error }), _jsx(CapabilitiesCard, { title: capabilitiesTitle, lines: capabilities }), _jsxs("div", { className: "jini-mcp-setup-card", children: [_jsx(ClientPicker, { clients: clients, selectedClientId: clientId, onSelect: setClientId, ...methodLabelProps({ resolved, info, clients, t }), ...childHandleProps({ agentHandle, action: 'client' }) }), resolved ? _jsx("p", { className: "jini-mcp-instruction", children: t(resolved.instructionTemplate, resolved.instructionVars) }) : null, client?.id === 'codex' ? (_jsx(CodexInstallToggleButton, { port: resolvedPort, ...childHandleProps({ agentHandle, action: 'codex-toggle' }) })) : null, resolved?.deeplink && info ? _jsx(DeeplinkInstallRow, { deeplink: resolved.deeplink, info: info, agentHandle: agentHandle }) : null, _jsx(InstallSnippet, { resolved: resolved, loading: loading, error: error }), _jsx(PrerequisiteWarning, { info: info }), _jsxs("div", { className: "jini-mcp-restart-note", children: [_jsx("strong", { children: t('Restart your client after installing.') }), ' ', _jsx("span", { children: t('Most MCP clients only pick up new servers on restart.') })] })] })] }));
28
+ }
29
+ /**
30
+ * The client the picker shows, and the snippet generated for THAT client (`null` until install
31
+ * info loads, or when `clients` is empty).
32
+ */
33
+ function resolveClientSnippet({ clients, clientId, serverName, info, }) {
26
34
  // Resolve the client ONCE, then generate from THAT — rather than displaying a
27
35
  // fallback while generating from the raw stored id. `initialClientId` defaults
28
36
  // to a constant a host with a restricted `clients` list need not include, and
@@ -32,6 +40,10 @@ export function IntegrationsTab({ serverName = DEFAULT_MCP_SERVER_NAME, clients
32
40
  // client the host had deliberately excluded.
33
41
  const client = clients.find((c) => c.id === clientId) ?? clients[0];
34
42
  const resolved = info && client ? snippetForClient(client.id, serverName, info) : null;
43
+ return { client, resolved };
44
+ }
45
+ /** The picker's trigger subtitle and per-row method labels, both blank until install info loads. */
46
+ function methodLabelProps({ resolved, info, clients, t, }) {
35
47
  // Origin gates every `buildMethod(info)` call on `info` being loaded
36
48
  // (`info ? client.buildMethod(info) : ''` for the trigger subtitle, same
37
49
  // guard for each dropdown row) — replicated here so the method labels
@@ -40,23 +52,57 @@ export function IntegrationsTab({ serverName = DEFAULT_MCP_SERVER_NAME, clients
40
52
  const methodLabels = info
41
53
  ? Object.fromEntries(clients.map((c) => [c.id, t(methodLabelForClient(c.id))]))
42
54
  : undefined;
43
- const resolvedCapabilitiesTitle = capabilitiesTitle ?? t('What this server can do');
44
- const resolvedCapabilities = capabilities ?? [
55
+ return { methodLabel, methodLabels };
56
+ }
57
+ /** `{ agentHandle }` for a child, derived from this tab's ONE base handle — or `{}` when the host published none. */
58
+ function childHandleProps({ agentHandle, action }) {
59
+ return agentHandle ? { agentHandle: agentSubHandle({ base: agentHandle, action }) } : {};
60
+ }
61
+ /** Inline card for a failed install-info fetch; nothing while there is no error. */
62
+ function DaemonErrorCard({ error }) {
63
+ const t = useT();
64
+ if (!error)
65
+ return null;
66
+ return _jsx("div", { className: "jini-empty-card jini-empty-card-error", children: t('Could not reach the daemon: {error}', { error }) });
67
+ }
68
+ /** "What this server can do" card: the host's title and lines, or the generic defaults. */
69
+ function CapabilitiesCard({ title, lines }) {
70
+ const t = useT();
71
+ const resolvedCapabilitiesTitle = title ?? t('What this server can do');
72
+ const resolvedCapabilities = lines ?? [
45
73
  t('Read your project files'),
46
74
  t('Pull context into the conversation'),
47
75
  t('Use default, safe tool permissions'),
48
76
  ];
49
- return (_jsxs("section", { className: "jini-settings-section jini-settings-integrations", children: [error ? _jsx("div", { className: "jini-empty-card jini-empty-card-error", children: t('Could not reach the daemon: {error}', { error }) }) : null, _jsxs("div", { className: "jini-mcp-capabilities-card", children: [_jsx("p", { className: "jini-mcp-capabilities-label", children: resolvedCapabilitiesTitle }), _jsx("ul", { className: "jini-mcp-capabilities-list", children: resolvedCapabilities.map((line) => (_jsx("li", { children: line }, line))) })] }), _jsxs("div", { className: "jini-mcp-setup-card", children: [_jsx(ClientPicker, { clients: clients, selectedClientId: clientId, onSelect: setClientId, methodLabel: methodLabel, methodLabels: methodLabels, ...(agentHandle ? { agentHandle: agentSubHandle({ base: agentHandle, action: 'client' }) } : {}) }), resolved ? _jsx("p", { className: "jini-mcp-instruction", children: t(resolved.instructionTemplate, resolved.instructionVars) }) : null, client?.id === 'codex' ? (_jsx(CodexInstallToggleButton, { port: resolvedPort, ...(agentHandle ? { agentHandle: agentSubHandle({ base: agentHandle, action: 'codex-toggle' }) } : {}) })) : null, resolved?.deeplink && info ? (_jsxs("div", { className: "jini-mcp-deeplink-row", children: [_jsx("a", { className: `jini-button jini-button-primary${isMcpInstallPrerequisiteMissing(info) ? ' jini-button-disabled' : ''}`,
50
- // Origin disables this button via `disabled={!info.cliExists ||
51
- // !info.nodeExists}` — one-click install can't work until the
52
- // daemon/CLI prerequisite is actually built. An `<a>` has no
53
- // native `disabled`, so drop `href` (making it inert/
54
- // unfocusable-as-a-link) and mark `aria-disabled` instead of
55
- // silently letting the click through to a config that won't
56
- // work.
57
- href: isMcpInstallPrerequisiteMissing(info) ? undefined : resolved.deeplink, "aria-disabled": isMcpInstallPrerequisiteMissing(info) || undefined, onClick: (event) => {
58
- if (isMcpInstallPrerequisiteMissing(info))
59
- event.preventDefault();
60
- }, rel: "noopener noreferrer", ...agentHandleProps({}, { base: agentHandle, ...({ action: 'one-click-install', role: 'link', label: t('One-click install') }) }), children: t('One-click install') }), _jsx("span", { className: "jini-hint", children: t('Your editor will ask you to approve the install.') })] })) : null, _jsx(SnippetBlock, { snippet: resolved?.snippet ?? '', language: resolved?.language ?? 'json', placeholder: loading ? t('Loading install paths…') : error ? t('Could not resolve install paths.') : '' }), info && isMcpInstallPrerequisiteMissing(info) ? (_jsxs("div", { className: "jini-empty-card jini-empty-card-warning", children: [_jsx("strong", { children: !info.cliExists ? t('Build the server first.') : t('Node.js was not found.') }), ' ', info.buildHint ?? t('See your host application for build instructions.')] })) : null, _jsxs("div", { className: "jini-mcp-restart-note", children: [_jsx("strong", { children: t('Restart your client after installing.') }), ' ', _jsx("span", { children: t('Most MCP clients only pick up new servers on restart.') })] })] })] }));
77
+ return (_jsxs("div", { className: "jini-mcp-capabilities-card", children: [_jsx("p", { className: "jini-mcp-capabilities-label", children: resolvedCapabilitiesTitle }), _jsx("ul", { className: "jini-mcp-capabilities-list", children: resolvedCapabilities.map((line) => (_jsx("li", { children: line }, line))) })] }));
78
+ }
79
+ /** One-click deeplink install, inert (no `href`, `aria-disabled`) while a prerequisite is missing. */
80
+ function DeeplinkInstallRow({ deeplink, info, agentHandle }) {
81
+ const t = useT();
82
+ const prerequisiteMissing = isMcpInstallPrerequisiteMissing(info);
83
+ return (_jsxs("div", { className: "jini-mcp-deeplink-row", children: [_jsx("a", { className: `jini-button jini-button-primary${prerequisiteMissing ? ' jini-button-disabled' : ''}`,
84
+ // Origin disables this button via `disabled={!info.cliExists ||
85
+ // !info.nodeExists}` — one-click install can't work until the
86
+ // daemon/CLI prerequisite is actually built. An `<a>` has no
87
+ // native `disabled`, so drop `href` (making it inert/
88
+ // unfocusable-as-a-link) and mark `aria-disabled` instead of
89
+ // silently letting the click through to a config that won't
90
+ // work.
91
+ href: prerequisiteMissing ? undefined : deeplink, "aria-disabled": prerequisiteMissing || undefined, onClick: (event) => {
92
+ if (prerequisiteMissing)
93
+ event.preventDefault();
94
+ }, rel: "noopener noreferrer", ...agentHandleProps({}, { base: agentHandle, action: 'one-click-install', role: 'link', label: t('One-click install') }), children: t('One-click install') }), _jsx("span", { className: "jini-hint", children: t('Your editor will ask you to approve the install.') })] }));
95
+ }
96
+ /** The generated snippet, or a loading / could-not-resolve placeholder while there is none. */
97
+ function InstallSnippet({ resolved, loading, error }) {
98
+ const t = useT();
99
+ return (_jsx(SnippetBlock, { snippet: resolved?.snippet ?? '', language: resolved?.language ?? 'json', placeholder: loading ? t('Loading install paths…') : error ? t('Could not resolve install paths.') : '' }));
100
+ }
101
+ /** Build/Node warning, shown only once install info has loaded and reports a missing prerequisite. */
102
+ function PrerequisiteWarning({ info }) {
103
+ const t = useT();
104
+ if (!info || !isMcpInstallPrerequisiteMissing(info))
105
+ return null;
106
+ return (_jsxs("div", { className: "jini-empty-card jini-empty-card-warning", children: [_jsx("strong", { children: !info.cliExists ? t('Build the server first.') : t('Node.js was not found.') }), ' ', info.buildHint ?? t('See your host application for build instructions.')] }));
61
107
  }
62
108
  //# sourceMappingURL=IntegrationsTab.js.map
@@ -1,2 +1,2 @@
1
1
  /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}:root,[data-admin-theme],[data-color-scheme=light]{color-scheme:light;--jini-bg:var(--jini-theme-light-bg,#fff);--jini-surface:var(--jini-theme-light-surface,#f5f5f5);--jini-text:var(--jini-theme-light-text,#202020);--jini-muted:var(--jini-theme-light-muted,#666);--jini-border:var(--jini-theme-light-border,#d9d9d9);--jini-primary:var(--jini-theme-light-primary,#363636);--jini-primary-ink:var(--jini-theme-light-primary-ink,#fff);--jini-danger:var(--jini-theme-light-danger,#b42318);--jini-success:var(--jini-theme-light-success,#18763b);--jini-warning:var(--jini-theme-light-warning,#845800)}[data-color-scheme=dark]{color-scheme:dark;--jini-bg:var(--jini-theme-dark-bg,#171717);--jini-surface:var(--jini-theme-dark-surface,#242424);--jini-text:var(--jini-theme-dark-text,#f0f0f0);--jini-muted:var(--jini-theme-dark-muted,#b3b3b3);--jini-border:var(--jini-theme-dark-border,#454545);--jini-primary:var(--jini-theme-dark-primary,#e0e0e0);--jini-primary-ink:var(--jini-theme-dark-primary-ink,#202020);--jini-danger:var(--jini-theme-dark-danger,#ff8b80);--jini-success:var(--jini-theme-dark-success,#79d69b);--jini-warning:var(--jini-theme-dark-warning,#ebc36b)}:root,[data-color-scheme=light],[data-theme=light]{--jini-chart-default-1:oklch(55.29% .1129 43.4);--jini-chart-default-2:oklch(50% .11 240);--jini-chart-default-3:oklch(64% .13 88);--jini-chart-default-4:oklch(58% .15 350);--jini-chart-default-5:oklch(50% .11 155);--jini-chart-default-6:oklch(48% .12 295)}[data-color-scheme=dark],[data-theme=dark]{--jini-chart-default-1:oklch(62% .11 44);--jini-chart-default-2:oklch(64% .11 240);--jini-chart-default-3:oklch(66% .13 88);--jini-chart-default-4:oklch(65% .14 350);--jini-chart-default-5:oklch(56% .12 155);--jini-chart-default-6:oklch(64% .12 295)}:root{--jini-font-body:system-ui, sans-serif;--jini-font-heading:system-ui, sans-serif;--jini-font-mono:ui-monospace, monospace;--jini-radius:8px;--jini-density:1}:root,[data-admin-theme],[data-color-scheme]{--jini-bg-panel:var(--jini-surface);--jini-bg-subtle:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-bg-subtle:color-mix(in srgb, var(--jini-surface) 75%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-bg-elevated:var(--jini-surface);--jini-border-soft:var(--jini-border);--jini-border-strong:var(--jini-border)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-border-strong:color-mix(in srgb, var(--jini-border) 75%, var(--jini-text))}}:root,[data-admin-theme],[data-color-scheme]{--jini-backdrop:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-backdrop:color-mix(in srgb, var(--jini-text) 42%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-text-strong:var(--jini-text);--jini-text-secondary:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-text-secondary:color-mix(in srgb, var(--jini-text) 80%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-text-muted:var(--jini-muted);--jini-text-faint:var(--jini-muted)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-text-faint:color-mix(in srgb, var(--jini-muted) 75%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-text-disabled:var(--jini-muted)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-text-disabled:color-mix(in srgb, var(--jini-muted) 60%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent:var(--jini-primary);--jini-accent-hover:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-hover:color-mix(in srgb, var(--jini-primary) 88%, var(--jini-text))}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent-strong:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-strong:color-mix(in srgb, var(--jini-primary) 85%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent-ink:var(--jini-primary-ink);--jini-accent-soft:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-soft:color-mix(in srgb, var(--jini-primary) 10%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent-ring:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-ring:color-mix(in srgb, var(--jini-primary) 22%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent:var(--jini-text);--jini-neutral-accent-hover:var(--jini-muted);--jini-neutral-accent-ink:var(--jini-bg);--jini-neutral-accent-text:var(--jini-text);--jini-neutral-accent-soft:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent-soft:color-mix(in srgb, var(--jini-text) 7%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent-ring:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent-ring:color-mix(in srgb, var(--jini-text) 16%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-link:var(--jini-primary);--jini-link-ink:var(--jini-primary-ink);--jini-success-bg:var(--jini-success)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-success-bg:color-mix(in srgb, var(--jini-success) 12%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-success-solid:var(--jini-success);--jini-success-solid-ink:var(--jini-bg);--jini-danger-bg:var(--jini-danger)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-danger-bg:color-mix(in srgb, var(--jini-danger) 12%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-warning-bg:var(--jini-warning)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-warning-bg:color-mix(in srgb, var(--jini-warning) 12%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-font-ui:var(--jini-font-body);--jini-font-display:var(--jini-font-heading);--jini-shadow-xs:0 1px 0 var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-xs:0 1px 0 color-mix(in srgb, var(--jini-text) 4%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-sm:0 1px 3px var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-sm:0 1px 3px color-mix(in srgb, var(--jini-text) 10%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-md:0 6px 24px var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-md:0 6px 24px color-mix(in srgb, var(--jini-text) 15%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-lg:0 24px 60px var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-lg:0 24px 60px color-mix(in srgb, var(--jini-text) 22%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-radius-xs:calc(var(--jini-radius) * .5);--jini-radius-sm:calc(var(--jini-radius) * .75);--jini-radius-md:calc(var(--jini-radius) * 1.25);--jini-radius-lg:calc(var(--jini-radius) * 1.5);--jini-radius-pill:999px;--jini-space-1:calc(.25rem * var(--jini-density));--jini-space-2:calc(.5rem * var(--jini-density));--jini-space-3:calc(.75rem * var(--jini-density));--jini-space-4:calc(1rem * var(--jini-density));--jini-space-5:calc(1.25rem * var(--jini-density));--jini-space-6:calc(1.5rem * var(--jini-density));--jini-space-7:calc(2rem * var(--jini-density));--jini-space-8:calc(2.5rem * var(--jini-density));--jini-font-size-2xs:.6875rem;--jini-font-size-xs:.75rem;--jini-font-size-sm:.8125rem;--jini-font-size-base:.875rem;--jini-font-size-md:.95rem;--jini-font-size-lg:1.05rem;--jini-font-size-xl:1.65rem;--jini-font-weight-normal:400;--jini-font-weight-medium:500;--jini-font-weight-semibold:600;--jini-font-weight-bold:700;--jini-line-tight:1.25;--jini-line-normal:1.5;--jini-line-relaxed:1.7;--jini-duration-fast:.12s;--jini-duration-base:.2s;--jini-duration-slow:.32s;--jini-ease-out:cubic-bezier(.23, 1, .32, 1);--jini-ease-in-out:cubic-bezier(.4, 0, .2, 1);--jini-transition-base:var(--jini-duration-base) var(--jini-ease-out);--jini-z-dropdown:100;--jini-z-sticky:200;--jini-z-overlay:300;--jini-z-modal:400;--jini-z-toast:500;--jini-modal-padding:24px;--jini-sidebar-width:240px}@layer theme{:root,:host{--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--radius-sm:.25rem;--radius-md:.375rem;--radius-xl:.75rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer base,components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.right-2{right:calc(var(--spacing) * 2)}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.my-1{margin-block:var(--spacing)}.mt-4{margin-top:calc(var(--spacing) * 4)}.block{display:block}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-row{display:table-row}.aspect-square{aspect-ratio:1}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-px{height:1px}.max-h-\[--radix-select-content-available-height\]{max-height:--radix-select-content-available-height}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-9{width:calc(var(--spacing) * 9)}.w-full{width:100%}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.origin-\[--radix-select-content-transform-origin\]{transform-origin:--radix-select-content-transform-origin}.cursor-default{cursor:default}.flex-col{flex-direction:column}.place-content-center{place-content:center}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-input{border-color:var(--jini-border)}.border-primary{border-color:var(--jini-primary)}.bg-background{background-color:var(--jini-bg)}.bg-destructive{background-color:var(--jini-danger)}.bg-muted,.bg-muted\/50{background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.bg-muted\/50{background-color:color-mix(in oklab, var(--jini-surface) 50%, transparent)}}.bg-primary{background-color:var(--jini-primary)}.bg-secondary{background-color:var(--jini-surface)}.bg-transparent{background-color:#0000}.fill-primary{fill:var(--jini-primary)}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-6{padding:calc(var(--spacing) * 6)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.pt-0{padding-top:0}.pr-8{padding-right:calc(var(--spacing) * 8)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-left{text-align:left}.align-middle{vertical-align:middle}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.whitespace-nowrap{white-space:nowrap}.text-current{color:currentColor}.text-destructive-foreground{color:var(--jini-bg)}.text-foreground{color:var(--jini-text)}.text-input{color:var(--jini-border)}.text-muted-foreground{color:var(--jini-muted)}.text-primary{color:var(--jini-primary)}.text-primary-foreground{color:var(--jini-primary-ink)}.text-secondary-foreground{color:var(--jini-text)}.underline-offset-4{text-underline-offset:4px}.opacity-50{opacity:.5}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-offset-background{--tw-ring-offset-color:var(--jini-bg)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-70:is(:where(.peer):disabled~*){opacity:.7}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--jini-text)}.placeholder\:text-muted-foreground::placeholder{color:var(--jini-muted)}@media (hover:hover){.hover\:bg-accent:hover{background-color:var(--jini-surface)}.hover\:bg-destructive\/90:hover{background-color:var(--jini-danger)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab, var(--jini-danger) 90%, transparent)}}.hover\:bg-muted\/50:hover{background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab, var(--jini-surface) 50%, transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--jini-primary) 90%, transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab, var(--jini-surface) 80%, transparent)}}.hover\:text-accent-foreground:hover{color:var(--jini-text)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:bg-accent:focus{background-color:var(--jini-surface)}.focus\:text-accent-foreground:focus{color:var(--jini-text)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--jini-primary)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--jini-primary)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.has-aria-expanded\:bg-muted\/50:has([aria-expanded=true]){background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.has-aria-expanded\:bg-muted\/50:has([aria-expanded=true]){background-color:color-mix(in oklab, var(--jini-surface) 50%, transparent)}}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[placeholder\]\:text-muted-foreground[data-placeholder]{color:var(--jini-muted)}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:var(--spacing);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:var(--spacing);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:var(--jini-primary)}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:var(--jini-primary-ink)}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--jini-surface)}@media (min-width:48rem){.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:0}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}.jini-data-table-frame{border:1px solid var(--jini-border);border-radius:var(--jini-radius);background:var(--jini-bg);min-width:0;max-width:100%;color:var(--jini-text);overflow:hidden}.jini-data-table-scroll,.jini-data-table-frame>[data-slot=table-container]{overscroll-behavior-x:contain;width:100%;max-height:28rem;overflow:auto}.jini-data-table{border-collapse:separate;border-spacing:0;width:100%;font-family:var(--jini-font-body);font-size:var(--jini-font-size-sm);line-height:var(--jini-line-normal);font-variant-numeric:tabular-nums}.jini-data-table th,.jini-data-table td{text-align:left;vertical-align:middle;white-space:nowrap;border-bottom:1px solid var(--jini-border);height:2.5rem;padding:.625rem .875rem}.jini-data-table th{z-index:1;background:var(--jini-surface);color:var(--jini-muted);font-size:var(--jini-font-size-xs);font-weight:var(--jini-font-weight-semibold);position:sticky;top:0}.jini-data-table tbody tr:last-child td{border-bottom:0}.jini-data-table tbody tr:nth-child(2n){background:var(--jini-bg-subtle)}.jini-data-table tbody tr:hover,.jini-data-table tbody tr:focus-visible{background:var(--jini-surface)}.jini-data-table tbody tr[role=button]{cursor:pointer}.jini-data-table [data-numeric=true]{text-align:right}.jini-data-table-sort{width:100%;min-height:1.5rem;color:inherit;font:inherit;text-align:inherit;cursor:pointer;background:0 0;border:0;justify-content:space-between;align-items:center;gap:.625rem;padding:0;display:inline-flex}.jini-data-table [data-numeric=true] .jini-data-table-sort{justify-content:flex-end}.jini-data-table th[aria-sort=ascending],.jini-data-table th[aria-sort=descending],.jini-data-table-sort:hover{color:var(--jini-text)}.jini-data-table td.jini-data-table-empty{height:8rem;color:var(--jini-muted);text-align:center}.jini-data-table-pagination{border-top:1px solid var(--jini-border);color:var(--jini-muted);font-size:var(--jini-font-size-xs);font-variant-numeric:tabular-nums;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.75rem;padding:.625rem .875rem;display:flex}.jini-data-table-pagination-controls{gap:.5rem;display:flex}.jini-data-table-pagination button{border:1px solid var(--jini-border);border-radius:var(--jini-radius-sm);background:var(--jini-bg);min-height:2rem;color:var(--jini-text);font:inherit;cursor:pointer;padding:.375rem .75rem}.jini-data-table-pagination button:hover:not(:disabled){background:var(--jini-surface)}.jini-data-table-pagination button:disabled{opacity:.5;cursor:default}.jini-data-table-sort:focus-visible,.jini-data-table-pagination button:focus-visible,.jini-data-table tr[role=button]:focus-visible{outline:2px solid var(--jini-primary);outline-offset:-2px}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}:root,[data-admin-theme],[data-color-scheme=light]{color-scheme:light;--jini-bg:var(--jini-theme-light-bg,#fff);--jini-surface:var(--jini-theme-light-surface,#f5f5f5);--jini-text:var(--jini-theme-light-text,#202020);--jini-muted:var(--jini-theme-light-muted,#666);--jini-border:var(--jini-theme-light-border,#d9d9d9);--jini-primary:var(--jini-theme-light-primary,#363636);--jini-primary-ink:var(--jini-theme-light-primary-ink,#fff);--jini-danger:var(--jini-theme-light-danger,#b42318);--jini-success:var(--jini-theme-light-success,#18763b);--jini-warning:var(--jini-theme-light-warning,#845800)}[data-color-scheme=dark]{color-scheme:dark;--jini-bg:var(--jini-theme-dark-bg,#171717);--jini-surface:var(--jini-theme-dark-surface,#242424);--jini-text:var(--jini-theme-dark-text,#f0f0f0);--jini-muted:var(--jini-theme-dark-muted,#b3b3b3);--jini-border:var(--jini-theme-dark-border,#454545);--jini-primary:var(--jini-theme-dark-primary,#e0e0e0);--jini-primary-ink:var(--jini-theme-dark-primary-ink,#202020);--jini-danger:var(--jini-theme-dark-danger,#ff8b80);--jini-success:var(--jini-theme-dark-success,#79d69b);--jini-warning:var(--jini-theme-dark-warning,#ebc36b)}:root,[data-color-scheme=light],[data-theme=light]{--jini-chart-default-1:oklch(55.29% .1129 43.4);--jini-chart-default-2:oklch(50% .11 240);--jini-chart-default-3:oklch(64% .13 88);--jini-chart-default-4:oklch(58% .15 350);--jini-chart-default-5:oklch(50% .11 155);--jini-chart-default-6:oklch(48% .12 295)}[data-color-scheme=dark],[data-theme=dark]{--jini-chart-default-1:oklch(62% .11 44);--jini-chart-default-2:oklch(64% .11 240);--jini-chart-default-3:oklch(66% .13 88);--jini-chart-default-4:oklch(65% .14 350);--jini-chart-default-5:oklch(56% .12 155);--jini-chart-default-6:oklch(64% .12 295)}:root{--jini-font-body:system-ui, sans-serif;--jini-font-heading:system-ui, sans-serif;--jini-font-mono:ui-monospace, monospace;--jini-radius:8px;--jini-density:1}:root,[data-admin-theme],[data-color-scheme]{--jini-bg-panel:var(--jini-surface);--jini-bg-subtle:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-bg-subtle:color-mix(in srgb, var(--jini-surface) 75%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-bg-elevated:var(--jini-surface);--jini-border-soft:var(--jini-border);--jini-border-strong:var(--jini-border)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-border-strong:color-mix(in srgb, var(--jini-border) 75%, var(--jini-text))}}:root,[data-admin-theme],[data-color-scheme]{--jini-backdrop:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-backdrop:color-mix(in srgb, var(--jini-text) 42%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-text-strong:var(--jini-text);--jini-text-secondary:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-text-secondary:color-mix(in srgb, var(--jini-text) 80%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-text-muted:var(--jini-muted);--jini-text-faint:var(--jini-muted)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-text-faint:color-mix(in srgb, var(--jini-muted) 75%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-text-disabled:var(--jini-muted)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-text-disabled:color-mix(in srgb, var(--jini-muted) 60%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent:var(--jini-primary);--jini-accent-hover:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-hover:color-mix(in srgb, var(--jini-primary) 88%, var(--jini-text))}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent-strong:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-strong:color-mix(in srgb, var(--jini-primary) 85%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent-ink:var(--jini-primary-ink);--jini-accent-soft:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-soft:color-mix(in srgb, var(--jini-primary) 10%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent-ring:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-ring:color-mix(in srgb, var(--jini-primary) 22%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent:var(--jini-text);--jini-neutral-accent-hover:var(--jini-muted);--jini-neutral-accent-ink:var(--jini-bg);--jini-neutral-accent-text:var(--jini-text);--jini-neutral-accent-soft:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent-soft:color-mix(in srgb, var(--jini-text) 7%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent-ring:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent-ring:color-mix(in srgb, var(--jini-text) 16%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-link:var(--jini-primary);--jini-link-ink:var(--jini-primary-ink);--jini-success-bg:var(--jini-success)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-success-bg:color-mix(in srgb, var(--jini-success) 12%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-success-solid:var(--jini-success);--jini-success-solid-ink:var(--jini-bg);--jini-danger-bg:var(--jini-danger)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-danger-bg:color-mix(in srgb, var(--jini-danger) 12%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-warning-bg:var(--jini-warning)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-warning-bg:color-mix(in srgb, var(--jini-warning) 12%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-font-ui:var(--jini-font-body);--jini-font-display:var(--jini-font-heading);--jini-shadow-xs:0 1px 0 var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-xs:0 1px 0 color-mix(in srgb, var(--jini-text) 4%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-sm:0 1px 3px var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-sm:0 1px 3px color-mix(in srgb, var(--jini-text) 10%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-md:0 6px 24px var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-md:0 6px 24px color-mix(in srgb, var(--jini-text) 15%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-lg:0 24px 60px var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-lg:0 24px 60px color-mix(in srgb, var(--jini-text) 22%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-radius-xs:calc(var(--jini-radius) * .5);--jini-radius-sm:calc(var(--jini-radius) * .75);--jini-radius-md:calc(var(--jini-radius) * 1.25);--jini-radius-lg:calc(var(--jini-radius) * 1.5);--jini-radius-pill:999px;--jini-space-1:calc(.25rem * var(--jini-density));--jini-space-2:calc(.5rem * var(--jini-density));--jini-space-3:calc(.75rem * var(--jini-density));--jini-space-4:calc(1rem * var(--jini-density));--jini-space-5:calc(1.25rem * var(--jini-density));--jini-space-6:calc(1.5rem * var(--jini-density));--jini-space-7:calc(2rem * var(--jini-density));--jini-space-8:calc(2.5rem * var(--jini-density));--jini-font-size-2xs:.6875rem;--jini-font-size-xs:.75rem;--jini-font-size-sm:.8125rem;--jini-font-size-base:.875rem;--jini-font-size-md:.95rem;--jini-font-size-lg:1.05rem;--jini-font-size-xl:1.65rem;--jini-font-weight-normal:400;--jini-font-weight-medium:500;--jini-font-weight-semibold:600;--jini-font-weight-bold:700;--jini-line-tight:1.25;--jini-line-normal:1.5;--jini-line-relaxed:1.7;--jini-duration-fast:.12s;--jini-duration-base:.2s;--jini-duration-slow:.32s;--jini-ease-out:cubic-bezier(.23, 1, .32, 1);--jini-ease-in-out:cubic-bezier(.4, 0, .2, 1);--jini-transition-base:var(--jini-duration-base) var(--jini-ease-out);--jini-z-dropdown:100;--jini-z-sticky:200;--jini-z-overlay:300;--jini-z-modal:400;--jini-z-toast:500;--jini-modal-padding:24px;--jini-sidebar-width:240px;--jini-app-bg:var(--jini-theme-app-bg,var(--jini-default-app-bg));--jini-shell-bg:var(--jini-theme-shell-bg,var(--jini-bg));--jini-panel-bg:var(--jini-theme-panel-bg,var(--jini-default-panel-bg));--jini-panel-border:var(--jini-theme-panel-border,var(--jini-default-panel-border));--jini-panel-shadow:var(--jini-theme-panel-shadow,var(--jini-default-panel-shadow));--jini-panel-backdrop:var(--jini-theme-panel-backdrop);--jini-panel-texture:var(--jini-theme-panel-texture);--jini-rail-bg:var(--jini-theme-rail-bg,var(--jini-panel-bg));--jini-rail-border:var(--jini-theme-rail-border,var(--jini-panel-border));--jini-rail-shadow:var(--jini-theme-rail-shadow,none);--jini-rail-backdrop:var(--jini-theme-rail-backdrop,var(--jini-panel-backdrop,none));--jini-overlay-bg:var(--jini-theme-overlay-bg,var(--jini-default-overlay-bg));--jini-overlay-backdrop:var(--jini-theme-overlay-backdrop);--jini-overlay-shadow:var(--jini-theme-overlay-shadow,var(--jini-default-overlay-shadow));--jini-control-preview-backdrop:var(--jini-theme-control-preview-backdrop,blur(6px));--jini-control-bg:var(--jini-theme-control-bg,var(--jini-default-control-bg));--jini-control-border:var(--jini-theme-control-border,var(--jini-default-control-border));--jini-control-shadow:var(--jini-theme-control-shadow);--jini-control-shadow-hover:var(--jini-theme-control-shadow-hover);--jini-control-shadow-pressed:var(--jini-theme-control-shadow-pressed);--jini-control-shadow-inset:var(--jini-theme-control-shadow-inset);--jini-border-width:var(--jini-theme-border-width);--jini-control-chevron-image:var(--jini-theme-control-chevron-image,url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3.5 5.5 7 9l3.5-3.5' stroke='%23666C75' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"));--jini-overlay-tooltip-bg:var(--jini-theme-overlay-tooltip-bg,#fff);--jini-overlay-tooltip-text:var(--jini-theme-overlay-tooltip-text,#111);--jini-overlay-tooltip-border:var(--jini-theme-overlay-tooltip-border,#0000001a);--jini-overlay-bg-preview:var(--jini-theme-overlay-bg-preview,oklch(0% 0 0/.55));--jini-overlay-bg-navigation:var(--jini-theme-overlay-bg-navigation,oklch(0% 0 0/.4));--jini-code-string:var(--jini-theme-code-string,#4caf7a);--jini-code-number:var(--jini-theme-code-number,#d1975a);--jini-control-thumb-bg:var(--jini-theme-control-thumb-bg,#fff);--jini-control-solid-ink:var(--jini-theme-control-solid-ink,#fff);--jini-overlay-bg-lightbox:var(--jini-theme-overlay-bg-lightbox,oklch(0% 0 0/.6));--jini-lightbox-bg:var(--jini-theme-lightbox-bg,oklch(23% .005 256));--jini-lightbox-ink:var(--jini-theme-lightbox-ink,oklch(97% 0 0));--jini-lightbox-ink-muted:var(--jini-theme-lightbox-ink-muted,oklch(97% 0 0/.58));--jini-lightbox-media-bg:var(--jini-theme-lightbox-media-bg,oklch(0% 0 0/.25));--jini-lightbox-document-bg:var(--jini-theme-lightbox-document-bg,#fff);--jini-lightbox-button-border:var(--jini-theme-lightbox-button-border,oklch(100% 0 0/.16));--jini-lightbox-button-bg:var(--jini-theme-lightbox-button-bg,oklch(100% 0 0/.07));--jini-lightbox-button-bg-hover:var(--jini-theme-lightbox-button-bg-hover,oklch(100% 0 0/.15));--jini-lightbox-button-border-hover:var(--jini-theme-lightbox-button-border-hover,oklch(100% 0 0/.28));--jini-control-media-bg:var(--jini-theme-control-media-bg,oklch(0% 0 0/.55));--jini-control-media-ink:var(--jini-theme-control-media-ink,oklch(100% 0 0));--jini-control-media-border:var(--jini-theme-control-media-border,oklch(100% 0 0/.35));--jini-control-media-bg-hover:var(--jini-theme-control-media-bg-hover,oklch(0% 0 0/.72));--jini-overlay-bg-source:var(--jini-theme-overlay-bg-source,oklch(0% 0 0/.48));--jini-file-icon-folder:var(--jini-theme-file-icon-folder,oklch(72% .12 75));--jini-file-icon-json:var(--jini-theme-file-icon-json,oklch(72% .13 90));--jini-file-icon-markdown:var(--jini-theme-file-icon-markdown,oklch(62% .12 245));--jini-file-icon-javascript:var(--jini-theme-file-icon-javascript,oklch(76% .15 95));--jini-file-icon-typescript:var(--jini-theme-file-icon-typescript,oklch(60% .13 250));--jini-file-icon-config:var(--jini-theme-file-icon-config,oklch(62% .14 20));--jini-file-icon-html:var(--jini-theme-file-icon-html,oklch(64% .17 40));--jini-file-icon-css:var(--jini-theme-file-icon-css,oklch(62% .13 280));--jini-file-icon-image:var(--jini-theme-file-icon-image,oklch(64% .12 160));--jini-file-icon-shell:var(--jini-theme-file-icon-shell,oklch(64% .12 145));--jini-status-complete-ink-fallback:var(--jini-theme-status-complete-ink-fallback,oklch(99% 0 none));--jini-control-preview-ink:var(--jini-theme-control-preview-ink,#fff);--jini-control-preview-bg:var(--jini-theme-control-preview-bg,#1111116b);--jini-control-preview-bg-hover:var(--jini-theme-control-preview-bg-hover,#111111b8);--jini-control-preview-tip-bg:var(--jini-theme-control-preview-tip-bg,#111111e0);--jini-panel-border-muted:var(--jini-theme-panel-border-muted,#d9d9d9);--jini-control-composer-border-focus:var(--jini-theme-control-composer-border-focus,oklch(70% .012 255));--jini-overlay-bg-chat:var(--jini-theme-overlay-bg-chat,#00000073);--jini-control-hover-neutral-bg:var(--jini-theme-control-hover-neutral-bg,#7f7f7f26);--jini-control-recording-bg:var(--jini-theme-control-recording-bg,#dc2626);--jini-control-recording-ink:var(--jini-theme-control-recording-ink,#fff);--jini-control-recording-bg-hover:var(--jini-theme-control-recording-bg-hover,#b91c1c);--jini-control-shadow-focus:var(--jini-theme-control-shadow-focus,0 0 0 3px var(--jini-accent-ring));--jini-overlay-tooltip-shadow:var(--jini-theme-overlay-tooltip-shadow,0 4px 16px #00000040);--jini-control-shadow-focus-subtle:var(--jini-theme-control-shadow-focus-subtle,0 0 0 2px var(--jini-neutral-accent-soft));--jini-overlay-toast-shadow:var(--jini-theme-overlay-toast-shadow,0 8px 24px #00000038);--jini-status-danger-shadow:var(--jini-theme-status-danger-shadow,inset 3px 0 0 var(--jini-danger));--jini-control-thumb-shadow-strong:var(--jini-theme-control-thumb-shadow-strong,0 1px 2px #1c1b1a47);--jini-panel-shadow-divider:var(--jini-theme-panel-shadow-divider,inset 0 -1px 0 var(--jini-border));--jini-control-shadow-focus-accent:var(--jini-theme-control-shadow-focus-accent,0 0 0 3px var(--jini-accent))}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-control-shadow-focus-accent:var(--jini-theme-control-shadow-focus-accent,0 0 0 3px color-mix(in srgb, var(--jini-accent) 18%, transparent))}}:root,[data-admin-theme],[data-color-scheme]{--jini-overlay-menu-shadow-above:var(--jini-theme-overlay-menu-shadow-above,0 -4px 14px #141c2d17, 0 -1px 4px #141c2d0f);--jini-control-shadow-selected:var(--jini-theme-control-shadow-selected,0 0 0 1px var(--jini-accent));--jini-control-shadow-swatch-selected:var(--jini-theme-control-shadow-swatch-selected,0 0 0 2px var(--jini-bg-panel), 0 0 0 4px var(--jini-accent));--jini-control-shadow-segment:var(--jini-theme-control-shadow-segment,0 1px 2px #00000014);--jini-panel-shadow-sticky:var(--jini-theme-panel-shadow-sticky,0 6px 8px -6px #00000024);--jini-overlay-menu-shadow:var(--jini-theme-overlay-menu-shadow,0 12px 32px #0000001f);--jini-control-shadow-segment-raised:var(--jini-theme-control-shadow-segment-raised,0 1px 2px #0000001f);--jini-control-thumb-shadow:var(--jini-theme-control-thumb-shadow,0 1px 2px #00000040);--jini-panel-shadow-banner:var(--jini-theme-panel-shadow-banner,0 2px 8px #0000001f);--jini-status-warning-shadow:var(--jini-theme-status-warning-shadow,inset 2px 0 0 var(--jini-warning));--jini-panel-shadow-flat:var(--jini-theme-panel-shadow-flat,none)}:root{--jini-chat-font-body:var(--jini-theme-chat-font-body,-apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei UI", "Noto Sans", Roboto, "Helvetica Neue", Arial, sans-serif);--jini-chat-font-mono:var(--jini-theme-chat-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);--jini-chat-popover-shadow:var(--jini-theme-chat-popover-shadow,0 18px 46px #0d0c0a26, 0 2px 8px #0d0c0a0f);--jini-chat-bg:var(--jini-theme-chat-bg);--jini-chat-panel:var(--jini-theme-chat-panel);--jini-chat-text:var(--jini-theme-chat-text);--jini-chat-text-strong:var(--jini-theme-chat-text-strong);--jini-chat-muted:var(--jini-theme-chat-muted);--jini-chat-faint:var(--jini-theme-chat-faint);--jini-chat-border:var(--jini-theme-chat-border);--jini-chat-border-strong:var(--jini-theme-chat-border-strong);--jini-chat-border-soft:var(--jini-theme-chat-border-soft);--jini-chat-subtle:var(--jini-theme-chat-subtle);--jini-chat-accent:var(--jini-theme-chat-accent);--jini-chat-accent-soft:var(--jini-theme-chat-accent-soft);--jini-chat-danger:var(--jini-theme-chat-danger);--jini-chat-radius:var(--jini-theme-chat-radius);--jini-chat-radius-lg:var(--jini-theme-chat-radius-lg);--jini-chat-user-bubble:var(--jini-theme-chat-user-bubble);--jini-chat-user-bubble-ink:var(--jini-theme-chat-user-bubble-ink)}@layer theme{:root,:host{--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--radius-sm:.25rem;--radius-md:.375rem;--radius-xl:.75rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer base,components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.right-2{right:calc(var(--spacing) * 2)}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.my-1{margin-block:var(--spacing)}.mt-4{margin-top:calc(var(--spacing) * 4)}.block{display:block}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-row{display:table-row}.aspect-square{aspect-ratio:1}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-px{height:1px}.max-h-\[--radix-select-content-available-height\]{max-height:--radix-select-content-available-height}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-9{width:calc(var(--spacing) * 9)}.w-full{width:100%}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.origin-\[--radix-select-content-transform-origin\]{transform-origin:--radix-select-content-transform-origin}.cursor-default{cursor:default}.flex-col{flex-direction:column}.place-content-center{place-content:center}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-input{border-color:var(--jini-border)}.border-primary{border-color:var(--jini-primary)}.bg-background{background-color:var(--jini-bg)}.bg-destructive{background-color:var(--jini-danger)}.bg-muted,.bg-muted\/50{background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.bg-muted\/50{background-color:color-mix(in oklab, var(--jini-surface) 50%, transparent)}}.bg-primary{background-color:var(--jini-primary)}.bg-secondary{background-color:var(--jini-surface)}.bg-transparent{background-color:#0000}.fill-primary{fill:var(--jini-primary)}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-6{padding:calc(var(--spacing) * 6)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.pt-0{padding-top:0}.pr-8{padding-right:calc(var(--spacing) * 8)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-left{text-align:left}.align-middle{vertical-align:middle}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.whitespace-nowrap{white-space:nowrap}.text-current{color:currentColor}.text-destructive-foreground{color:var(--jini-bg)}.text-foreground{color:var(--jini-text)}.text-input{color:var(--jini-border)}.text-muted-foreground{color:var(--jini-muted)}.text-primary{color:var(--jini-primary)}.text-primary-foreground{color:var(--jini-primary-ink)}.text-secondary-foreground{color:var(--jini-text)}.underline-offset-4{text-underline-offset:4px}.opacity-50{opacity:.5}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-offset-background{--tw-ring-offset-color:var(--jini-bg)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-70:is(:where(.peer):disabled~*){opacity:.7}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--jini-text)}.placeholder\:text-muted-foreground::placeholder{color:var(--jini-muted)}@media (hover:hover){.hover\:bg-accent:hover{background-color:var(--jini-surface)}.hover\:bg-destructive\/90:hover{background-color:var(--jini-danger)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab, var(--jini-danger) 90%, transparent)}}.hover\:bg-muted\/50:hover{background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab, var(--jini-surface) 50%, transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--jini-primary) 90%, transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab, var(--jini-surface) 80%, transparent)}}.hover\:text-accent-foreground:hover{color:var(--jini-text)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:bg-accent:focus{background-color:var(--jini-surface)}.focus\:text-accent-foreground:focus{color:var(--jini-text)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--jini-primary)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--jini-primary)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.has-aria-expanded\:bg-muted\/50:has([aria-expanded=true]){background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.has-aria-expanded\:bg-muted\/50:has([aria-expanded=true]){background-color:color-mix(in oklab, var(--jini-surface) 50%, transparent)}}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[placeholder\]\:text-muted-foreground[data-placeholder]{color:var(--jini-muted)}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:var(--spacing);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:var(--spacing);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:var(--jini-primary)}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:var(--jini-primary-ink)}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--jini-surface)}@media (min-width:48rem){.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:0}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}.jini-data-table-frame{border:1px solid var(--jini-border);border-radius:var(--jini-radius);background:var(--jini-bg);min-width:0;max-width:100%;color:var(--jini-text);overflow:hidden}.jini-data-table-scroll,.jini-data-table-frame>[data-slot=table-container]{overscroll-behavior-x:contain;width:100%;max-height:28rem;overflow:auto}.jini-data-table{border-collapse:separate;border-spacing:0;width:100%;font-family:var(--jini-font-body);font-size:var(--jini-font-size-sm);line-height:var(--jini-line-normal);font-variant-numeric:tabular-nums}.jini-data-table th,.jini-data-table td{text-align:left;vertical-align:middle;white-space:nowrap;border-bottom:1px solid var(--jini-border);height:2.5rem;padding:.625rem .875rem}.jini-data-table th{z-index:1;background:var(--jini-surface);color:var(--jini-muted);font-size:var(--jini-font-size-xs);font-weight:var(--jini-font-weight-semibold);position:sticky;top:0}.jini-data-table tbody tr:last-child td{border-bottom:0}.jini-data-table tbody tr:nth-child(2n){background:var(--jini-bg-subtle)}.jini-data-table tbody tr:hover,.jini-data-table tbody tr:focus-visible{background:var(--jini-surface)}.jini-data-table tbody tr[role=button]{cursor:pointer}.jini-data-table [data-numeric=true]{text-align:right}.jini-data-table-sort{width:100%;min-height:1.5rem;color:inherit;font:inherit;text-align:inherit;cursor:pointer;background:0 0;border:0;justify-content:space-between;align-items:center;gap:.625rem;padding:0;display:inline-flex}.jini-data-table [data-numeric=true] .jini-data-table-sort{justify-content:flex-end}.jini-data-table th[aria-sort=ascending],.jini-data-table th[aria-sort=descending],.jini-data-table-sort:hover{color:var(--jini-text)}.jini-data-table td.jini-data-table-empty{height:8rem;color:var(--jini-muted);text-align:center}.jini-data-table-pagination{border-top:1px solid var(--jini-border);color:var(--jini-muted);font-size:var(--jini-font-size-xs);font-variant-numeric:tabular-nums;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.75rem;padding:.625rem .875rem;display:flex}.jini-data-table-pagination-controls{gap:.5rem;display:flex}.jini-data-table-pagination button{border:1px solid var(--jini-border);border-radius:var(--jini-radius-sm);background:var(--jini-bg);min-height:2rem;color:var(--jini-text);font:inherit;cursor:pointer;padding:.375rem .75rem}.jini-data-table-pagination button:hover:not(:disabled){background:var(--jini-surface)}.jini-data-table-pagination button:disabled{opacity:.5;cursor:default}.jini-data-table-sort:focus-visible,.jini-data-table-pagination button:focus-visible,.jini-data-table tr[role=button]:focus-visible{outline:2px solid var(--jini-primary);outline-offset:-2px}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}
@@ -2,6 +2,15 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useMemo, useState } from 'react';
3
3
  import { getNumericColumnKeys, sortTableRows } from '../../table-data.js';
4
4
  import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './table.js';
5
+ function resolveTablePage({ pageSize, rowCount, requestedPage }, _options = {}) {
6
+ const requestedSize = pageSize !== undefined && Number.isInteger(pageSize) && pageSize > 0 ? pageSize : null;
7
+ const paging = requestedSize !== null;
8
+ const size = requestedSize ?? Math.max(rowCount, 1);
9
+ const pageCount = Math.max(1, Math.ceil(rowCount / size));
10
+ // Clamp during render so a smaller result set never shows a stale, empty page.
11
+ const page = paging ? Math.min(requestedPage, pageCount - 1) : 0;
12
+ return { paging, size, pageCount, page, start: page * size };
13
+ }
5
14
  /** Composes shadcn's real `table.tsx` primitives into the same `columns`/`rows`/`onRowClick` contract `native.data-table` exposes. */
6
15
  export function DataTable({ columns, rows, onRowClick, sortable = true, pageSize }) {
7
16
  const [sort, setSort] = useState(null);
@@ -9,13 +18,7 @@ export function DataTable({ columns, rows, onRowClick, sortable = true, pageSize
9
18
  const numericKeys = useMemo(() => getNumericColumnKeys({ columns, rows }), [columns, rows]);
10
19
  const activeSort = sortable && columns.some((column) => column.key === sort?.key) ? sort : null;
11
20
  const sortedRows = useMemo(() => sortTableRows({ rows, sort: activeSort, numericKeys }), [rows, activeSort, numericKeys]);
12
- const requestedSize = pageSize !== undefined && Number.isInteger(pageSize) && pageSize > 0 ? pageSize : null;
13
- const paging = requestedSize !== null;
14
- const size = requestedSize ?? Math.max(rows.length, 1);
15
- const pageCount = Math.max(1, Math.ceil(rows.length / size));
16
- // Clamp during render so a smaller result set never shows a stale, empty page.
17
- const page = paging ? Math.min(requestedPage, pageCount - 1) : 0;
18
- const start = page * size;
21
+ const { paging, size, pageCount, page, start } = resolveTablePage({ pageSize, rowCount: rows.length, requestedPage });
19
22
  const visibleRows = sortedRows.slice(start, start + size);
20
23
  return (_jsxs("div", { className: "jini-data-table-frame", "data-table-provider": "shadcn", children: [_jsxs(Table, { className: "jini-data-table", children: [_jsx(TableHeader, { children: _jsx(TableRow, { children: columns.map((column) => (_jsx(TableHead, { scope: "col", "data-numeric": numericKeys.has(column.key), "aria-sort": sortable ? (activeSort?.key === column.key ? activeSort.direction : 'none') : undefined, children: sortable ? (_jsxs("button", { type: "button", className: "jini-data-table-sort", onClick: () => {
21
24
  setSort({ key: column.key, direction: activeSort?.key === column.key && activeSort.direction === 'ascending'
@@ -2,45 +2,26 @@ export function buildMentionToken(label) {
2
2
  return label.startsWith('@') ? label : `@${label}`;
3
3
  }
4
4
  export function parseMentionParts(text, entities, options = {}) {
5
- if (!text)
6
- return null;
5
+ // An empty string never contains '@', so this one check also covers `!text`.
7
6
  if (!text.includes('@'))
8
7
  return null;
9
- const highlightUnknown = options.highlightUnknown ?? true;
10
- const known = getMentionTokenIndex(entities);
8
+ const scan = {
9
+ known: getMentionTokenIndex(entities),
10
+ highlightUnknown: options.highlightUnknown ?? true,
11
+ };
11
12
  const parts = [];
12
- let scanStart = 0;
13
13
  let copiedUntil = 0;
14
- let found = false;
15
- while (scanStart < text.length) {
16
- const start = text.indexOf('@', scanStart);
17
- if (start === -1)
18
- break;
19
- if (!isMentionBoundary(text, start)) {
20
- scanStart = start + 1;
21
- continue;
22
- }
23
- const knownMatch = findKnownMentionAt(text, known, start);
24
- const unknownMatch = highlightUnknown ? findUnknownMentionAt(text, start) : null;
25
- const match = knownMatch && (!unknownMatch || knownMatch.token.length >= unknownMatch.token.length)
26
- ? knownMatch
27
- : unknownMatch;
28
- if (!match) {
29
- scanStart = start + 1;
30
- continue;
31
- }
32
- if (match.start > copiedUntil) {
33
- parts.push({ kind: 'text', text: text.slice(copiedUntil, match.start) });
34
- }
35
- parts.push({
36
- kind: 'mention',
37
- entity: match.entity,
38
- text: match.token,
39
- });
40
- found = true;
41
- copiedUntil = match.start + match.token.length;
42
- scanStart = copiedUntil;
14
+ let start = text.indexOf('@');
15
+ while (start !== -1) {
16
+ const match = findMentionAt({ ...scan, text, start });
17
+ if (match)
18
+ copiedUntil = appendMatch({ parts, text, copiedUntil, match });
19
+ start = text.indexOf('@', match ? copiedUntil : start + 1);
43
20
  }
21
+ // Every mention token is at least two characters ('@' plus one more), so
22
+ // `copiedUntil` only moves off 0 once a mention part has been pushed.
23
+ if (copiedUntil === 0)
24
+ return null;
44
25
  if (copiedUntil < text.length) {
45
26
  parts.push({ kind: 'text', text: text.slice(copiedUntil) });
46
27
  }
@@ -53,9 +34,36 @@ export function parseMentionParts(text, entities, options = {}) {
53
34
  // per this package's coverage-driven-refactor policy once the loop proved
54
35
  // every branch of that pass was unreachable from this one real call site
55
36
  // (Phase 9.5: a dead branch gets refactored out, not padded with a test).
56
- return found ? parts : null;
37
+ return parts;
38
+ }
39
+ /**
40
+ * Pushes the plain text between `copiedUntil` and the match (when non-empty)
41
+ * followed by the mention part; returns the new `copiedUntil`.
42
+ */
43
+ function appendMatch(at) {
44
+ const { parts, text, copiedUntil, match } = at;
45
+ if (match.start > copiedUntil) {
46
+ parts.push({ kind: 'text', text: text.slice(copiedUntil, match.start) });
47
+ }
48
+ parts.push({ kind: 'mention', entity: match.entity, text: match.token });
49
+ return match.start + match.token.length;
50
+ }
51
+ /**
52
+ * The mention starting at `scan.start`, or null. A known (trie) match wins
53
+ * unless the unknown-mention run at the same position is strictly longer.
54
+ */
55
+ function findMentionAt(scan) {
56
+ const { text } = scan;
57
+ if (!isMentionBoundary(text, scan.start))
58
+ return null;
59
+ const knownMatch = findKnownMentionAt(text, scan.known, scan.start);
60
+ const unknownMatch = scan.highlightUnknown ? findUnknownMentionAt(text, scan.start) : null;
61
+ return knownMatch && (!unknownMatch || knownMatch.token.length >= unknownMatch.token.length)
62
+ ? knownMatch
63
+ : unknownMatch;
57
64
  }
58
65
  const mentionTokenIndexCache = new WeakMap();
66
+ /** Root of the (cached, per entities-array) trie of every entity's `@token`. */
59
67
  function getMentionTokenIndex(entities) {
60
68
  const cached = mentionTokenIndexCache.get(entities);
61
69
  if (cached)
@@ -101,18 +109,15 @@ function getMentionTokenIndex(entities) {
101
109
  }
102
110
  node = child;
103
111
  }
104
- if (!node.entity) {
105
- node.entity = entity;
106
- node.token = token;
107
- }
112
+ // First writer wins: two entities of different kinds can share a token.
113
+ node.entity ??= entity;
108
114
  }
109
- const index = { root };
110
- mentionTokenIndexCache.set(entities, index);
111
- return index;
115
+ mentionTokenIndexCache.set(entities, root);
116
+ return root;
112
117
  }
113
- function findKnownMentionAt(text, index, start) {
118
+ function findKnownMentionAt(text, root, start) {
114
119
  let best = null;
115
- let node = index.root;
120
+ let node = root;
116
121
  for (let i = start; i < text.length; i += 1) {
117
122
  // `i < text.length` is the loop condition itself, so `text[i]` is always
118
123
  // defined here — the `!` documents that instead of adding an
@@ -121,8 +126,8 @@ function findKnownMentionAt(text, index, start) {
121
126
  node = node.children.get(text[i]);
122
127
  if (!node)
123
128
  break;
124
- if (node.entity && node.token && isMentionRightBoundary(text, i + 1)) {
125
- best = { start, token: node.token, entity: node.entity };
129
+ if (node.entity && isMentionRightBoundary(text, i + 1)) {
130
+ best = { start, token: node.entity.token, entity: node.entity };
126
131
  }
127
132
  }
128
133
  return best;
@@ -222,17 +227,15 @@ export function mentionTokenPresent(text, label) {
222
227
  export function foldPresentMentions(text, present, known) {
223
228
  const result = [...present];
224
229
  const seen = new Set(present.map((e) => `${e.kind}:${e.id}`));
225
- const parts = parseMentionParts(text, known, { highlightUnknown: false });
226
- if (parts) {
227
- for (const part of parts) {
228
- if (part.kind === 'mention' && part.entity.kind !== 'unknown') {
229
- const key = `${part.entity.kind}:${part.entity.id}`;
230
- if (!seen.has(key)) {
231
- seen.add(key);
232
- result.push(part.entity);
233
- }
234
- }
235
- }
230
+ const parts = parseMentionParts(text, known, { highlightUnknown: false }) ?? [];
231
+ for (const part of parts) {
232
+ if (part.kind !== 'mention' || part.entity.kind === 'unknown')
233
+ continue;
234
+ const key = `${part.entity.kind}:${part.entity.id}`;
235
+ if (seen.has(key))
236
+ continue;
237
+ seen.add(key);
238
+ result.push(part.entity);
236
239
  }
237
240
  return result;
238
241
  }
@@ -20,44 +20,9 @@ export function useKeyboardCommands(popoverOpen, onSubmit, onPopoverKey) {
20
20
  const onPopoverKeyRef = useRef(onPopoverKey);
21
21
  onPopoverKeyRef.current = onPopoverKey;
22
22
  useEffect(() => {
23
- return mergeRegister(editor.registerCommand(KEY_ENTER_COMMAND, (e) => {
24
- // IME confirm Enter — let Lexical commit the composition.
25
- if (editor.isComposing())
26
- return false;
27
- if (e?.shiftKey) {
28
- editor.dispatchCommand(INSERT_LINE_BREAK_COMMAND, false);
29
- e.preventDefault();
30
- return true;
31
- }
32
- // Cmd/Ctrl+Enter force-submits even with a popover open.
33
- if (e?.metaKey || e?.ctrlKey) {
34
- e.preventDefault();
35
- onSubmitRef.current();
36
- return true;
37
- }
38
- if (popoverOpenRef.current) {
39
- e?.preventDefault();
40
- return onPopoverKeyRef.current('Enter');
41
- }
42
- e?.preventDefault();
43
- onSubmitRef.current();
44
- return true;
45
- }, COMMAND_PRIORITY_HIGH), editor.registerCommand(KEY_ARROW_DOWN_COMMAND, (e) => {
46
- if (!popoverOpenRef.current || editor.isComposing())
47
- return false;
48
- e?.preventDefault();
49
- return onPopoverKeyRef.current('ArrowDown');
50
- }, COMMAND_PRIORITY_HIGH), editor.registerCommand(KEY_ARROW_UP_COMMAND, (e) => {
51
- if (!popoverOpenRef.current || editor.isComposing())
52
- return false;
53
- e?.preventDefault();
54
- return onPopoverKeyRef.current('ArrowUp');
55
- }, COMMAND_PRIORITY_HIGH), editor.registerCommand(KEY_TAB_COMMAND, (e) => {
56
- if (!popoverOpenRef.current || editor.isComposing())
57
- return false;
58
- e?.preventDefault();
59
- return onPopoverKeyRef.current('Tab');
60
- }, COMMAND_PRIORITY_HIGH), editor.registerCommand(KEY_ESCAPE_COMMAND, () => {
23
+ const routing = { editor, popoverOpenRef, onSubmitRef, onPopoverKeyRef };
24
+ const navKey = (key) => (event) => routeNavKeyToPopover({ ...routing, event, key });
25
+ return mergeRegister(editor.registerCommand(KEY_ENTER_COMMAND, (event) => handleEnter({ ...routing, event }), COMMAND_PRIORITY_HIGH), editor.registerCommand(KEY_ARROW_DOWN_COMMAND, navKey('ArrowDown'), COMMAND_PRIORITY_HIGH), editor.registerCommand(KEY_ARROW_UP_COMMAND, navKey('ArrowUp'), COMMAND_PRIORITY_HIGH), editor.registerCommand(KEY_TAB_COMMAND, navKey('Tab'), COMMAND_PRIORITY_HIGH), editor.registerCommand(KEY_ESCAPE_COMMAND, () => {
61
26
  if (!popoverOpenRef.current)
62
27
  return false;
63
28
  return onPopoverKeyRef.current('Escape');
@@ -67,4 +32,34 @@ export function useKeyboardCommands(popoverOpen, onSubmit, onPopoverKey) {
67
32
  }, COMMAND_PRIORITY_HIGH));
68
33
  }, [editor]);
69
34
  }
35
+ function handleEnter(at) {
36
+ const { editor, event: e } = at;
37
+ // IME confirm Enter — let Lexical commit the composition.
38
+ if (editor.isComposing())
39
+ return false;
40
+ if (e?.shiftKey) {
41
+ editor.dispatchCommand(INSERT_LINE_BREAK_COMMAND, false);
42
+ e.preventDefault();
43
+ return true;
44
+ }
45
+ // Cmd/Ctrl+Enter force-submits even with a popover open.
46
+ if (e?.metaKey || e?.ctrlKey) {
47
+ e.preventDefault();
48
+ at.onSubmitRef.current();
49
+ return true;
50
+ }
51
+ e?.preventDefault();
52
+ if (at.popoverOpenRef.current)
53
+ return at.onPopoverKeyRef.current('Enter');
54
+ at.onSubmitRef.current();
55
+ return true;
56
+ }
57
+ /** Arrow-down/up/Tab go to the popover only while it's open and no IME
58
+ * composition is in progress; otherwise Lexical handles them. */
59
+ function routeNavKeyToPopover(at) {
60
+ if (!at.popoverOpenRef.current || at.editor.isComposing())
61
+ return false;
62
+ at.event?.preventDefault();
63
+ return at.onPopoverKeyRef.current(at.key);
64
+ }
70
65
  //# sourceMappingURL=useKeyboardCommands.js.map