@researai/deepscientist 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/AGENTS.md +26 -0
  2. package/README.md +19 -179
  3. package/assets/connectors/lingzhu/openclaw-bridge/README.md +124 -0
  4. package/assets/connectors/lingzhu/openclaw-bridge/index.ts +162 -0
  5. package/assets/connectors/lingzhu/openclaw-bridge/openclaw.plugin.json +145 -0
  6. package/assets/connectors/lingzhu/openclaw-bridge/package.json +35 -0
  7. package/assets/connectors/lingzhu/openclaw-bridge/src/cli.ts +180 -0
  8. package/assets/connectors/lingzhu/openclaw-bridge/src/config.ts +196 -0
  9. package/assets/connectors/lingzhu/openclaw-bridge/src/debug-log.ts +111 -0
  10. package/assets/connectors/lingzhu/openclaw-bridge/src/events.ts +4 -0
  11. package/assets/connectors/lingzhu/openclaw-bridge/src/http-handler.ts +1133 -0
  12. package/assets/connectors/lingzhu/openclaw-bridge/src/image-cache.ts +75 -0
  13. package/assets/connectors/lingzhu/openclaw-bridge/src/lingzhu-tools.ts +246 -0
  14. package/assets/connectors/lingzhu/openclaw-bridge/src/transform.ts +541 -0
  15. package/assets/connectors/lingzhu/openclaw-bridge/src/types.ts +131 -0
  16. package/assets/connectors/lingzhu/openclaw-bridge/tsconfig.json +14 -0
  17. package/assets/connectors/lingzhu/openclaw.lingzhu.config.template.json +39 -0
  18. package/bin/ds.js +233 -53
  19. package/docs/en/00_QUICK_START.md +134 -0
  20. package/docs/en/01_SETTINGS_REFERENCE.md +1104 -0
  21. package/docs/en/02_START_RESEARCH_GUIDE.md +404 -0
  22. package/docs/en/03_QQ_CONNECTOR_GUIDE.md +325 -0
  23. package/docs/en/04_LINGZHU_CONNECTOR_GUIDE.md +216 -0
  24. package/docs/en/05_TUI_GUIDE.md +141 -0
  25. package/docs/en/06_RUNTIME_AND_CANVAS.md +679 -0
  26. package/docs/en/07_MEMORY_AND_MCP.md +253 -0
  27. package/docs/en/08_FIGURE_STYLE_GUIDE.md +97 -0
  28. package/docs/en/09_DOCTOR.md +108 -0
  29. package/docs/en/90_ARCHITECTURE.md +245 -0
  30. package/docs/en/91_DEVELOPMENT.md +195 -0
  31. package/docs/en/99_ACKNOWLEDGEMENTS.md +29 -0
  32. package/docs/zh/00_QUICK_START.md +134 -0
  33. package/docs/zh/01_SETTINGS_REFERENCE.md +1137 -0
  34. package/docs/zh/02_START_RESEARCH_GUIDE.md +414 -0
  35. package/docs/zh/03_QQ_CONNECTOR_GUIDE.md +324 -0
  36. package/docs/zh/04_LINGZHU_CONNECTOR_GUIDE.md +230 -0
  37. package/docs/zh/05_TUI_GUIDE.md +128 -0
  38. package/docs/zh/06_RUNTIME_AND_CANVAS.md +271 -0
  39. package/docs/zh/07_MEMORY_AND_MCP.md +235 -0
  40. package/docs/zh/08_FIGURE_STYLE_GUIDE.md +97 -0
  41. package/docs/zh/09_DOCTOR.md +112 -0
  42. package/docs/zh/99_ACKNOWLEDGEMENTS.md +29 -0
  43. package/install.sh +32 -8
  44. package/package.json +4 -2
  45. package/pyproject.toml +1 -1
  46. package/src/deepscientist/artifact/guidance.py +9 -2
  47. package/src/deepscientist/artifact/service.py +482 -22
  48. package/src/deepscientist/bash_exec/monitor.py +27 -5
  49. package/src/deepscientist/bash_exec/runtime.py +639 -0
  50. package/src/deepscientist/bash_exec/service.py +99 -16
  51. package/src/deepscientist/bridges/base.py +3 -0
  52. package/src/deepscientist/bridges/connectors.py +292 -13
  53. package/src/deepscientist/channels/qq.py +19 -2
  54. package/src/deepscientist/channels/relay.py +1 -0
  55. package/src/deepscientist/cli.py +32 -25
  56. package/src/deepscientist/config/models.py +28 -2
  57. package/src/deepscientist/config/service.py +201 -6
  58. package/src/deepscientist/connector_runtime.py +2 -0
  59. package/src/deepscientist/daemon/api/handlers.py +50 -5
  60. package/src/deepscientist/daemon/api/router.py +1 -0
  61. package/src/deepscientist/daemon/app.py +442 -15
  62. package/src/deepscientist/doctor.py +444 -0
  63. package/src/deepscientist/home.py +1 -0
  64. package/src/deepscientist/latex_runtime.py +17 -4
  65. package/src/deepscientist/lingzhu_support.py +182 -0
  66. package/src/deepscientist/mcp/server.py +49 -2
  67. package/src/deepscientist/prompts/builder.py +181 -58
  68. package/src/deepscientist/quest/layout.py +1 -0
  69. package/src/deepscientist/quest/service.py +63 -2
  70. package/src/deepscientist/quest/stage_views.py +19 -1
  71. package/src/deepscientist/runtime_tools/__init__.py +16 -0
  72. package/src/deepscientist/runtime_tools/builtins.py +19 -0
  73. package/src/deepscientist/runtime_tools/models.py +29 -0
  74. package/src/deepscientist/runtime_tools/registry.py +40 -0
  75. package/src/deepscientist/runtime_tools/service.py +59 -0
  76. package/src/deepscientist/runtime_tools/tinytex.py +25 -0
  77. package/src/deepscientist/tinytex.py +276 -0
  78. package/src/prompts/connectors/lingzhu.md +12 -0
  79. package/src/prompts/connectors/qq.md +121 -0
  80. package/src/prompts/system.md +177 -33
  81. package/src/skills/analysis-campaign/SKILL.md +22 -6
  82. package/src/skills/baseline/SKILL.md +5 -4
  83. package/src/skills/decision/SKILL.md +4 -3
  84. package/src/skills/experiment/SKILL.md +5 -4
  85. package/src/skills/finalize/SKILL.md +5 -4
  86. package/src/skills/idea/SKILL.md +5 -4
  87. package/src/skills/intake-audit/SKILL.md +277 -0
  88. package/src/skills/intake-audit/references/state-audit-template.md +41 -0
  89. package/src/skills/rebuttal/SKILL.md +407 -0
  90. package/src/skills/rebuttal/references/action-plan-template.md +63 -0
  91. package/src/skills/rebuttal/references/evidence-update-template.md +30 -0
  92. package/src/skills/rebuttal/references/response-letter-template.md +113 -0
  93. package/src/skills/rebuttal/references/review-matrix-template.md +55 -0
  94. package/src/skills/review/SKILL.md +293 -0
  95. package/src/skills/review/references/experiment-todo-template.md +29 -0
  96. package/src/skills/review/references/review-report-template.md +83 -0
  97. package/src/skills/review/references/revision-log-template.md +40 -0
  98. package/src/skills/scout/SKILL.md +5 -4
  99. package/src/skills/write/SKILL.md +7 -3
  100. package/src/tui/dist/components/WelcomePanel.js +17 -43
  101. package/src/tui/dist/components/messages/BashExecOperationMessage.js +3 -2
  102. package/src/tui/package.json +1 -1
  103. package/src/ui/dist/assets/{AiManusChatView-7v-dHngU.js → AiManusChatView-w5lF2Ttt.js} +109 -575
  104. package/src/ui/dist/assets/{AnalysisPlugin-B_Xmz-KE.js → AnalysisPlugin-DJOED79I.js} +1 -1
  105. package/src/ui/dist/assets/{AutoFigurePlugin-Cko-0tm1.js → AutoFigurePlugin-DaG61Y0M.js} +63 -8
  106. package/src/ui/dist/assets/{CliPlugin-BsU0ht7q.js → CliPlugin-CV4LqUB_.js} +43 -609
  107. package/src/ui/dist/assets/{CodeEditorPlugin-DcMMP0Rt.js → CodeEditorPlugin-DylfAea4.js} +8 -8
  108. package/src/ui/dist/assets/{CodeViewerPlugin-BqoQ5QyY.js → CodeViewerPlugin-F7saY0LM.js} +5 -5
  109. package/src/ui/dist/assets/{DocViewerPlugin-D7eHNhU6.js → DocViewerPlugin-COP0c7jf.js} +3 -3
  110. package/src/ui/dist/assets/{GitDiffViewerPlugin-DLJN42T5.js → GitDiffViewerPlugin-CAS05pT9.js} +1 -1
  111. package/src/ui/dist/assets/{ImageViewerPlugin-gJMV7MOu.js → ImageViewerPlugin-Bco1CN_w.js} +5 -6
  112. package/src/ui/dist/assets/{LabCopilotPanel-B857sfxP.js → LabCopilotPanel-CvMlCD99.js} +12 -15
  113. package/src/ui/dist/assets/LabPlugin-BYankkE4.js +2676 -0
  114. package/src/ui/dist/assets/LabPlugin-D9jVIo0A.css +2698 -0
  115. package/src/ui/dist/assets/{LatexPlugin-DWKEo-Wj.js → LatexPlugin-LDSMR-t-.js} +16 -16
  116. package/src/ui/dist/assets/{MarkdownViewerPlugin-DBzoEmhv.js → MarkdownViewerPlugin-B7o80jgm.js} +4 -4
  117. package/src/ui/dist/assets/{MarketplacePlugin-DoHc-8vo.js → MarketplacePlugin-CM6ZOcpC.js} +3 -3
  118. package/src/ui/dist/assets/{NotebookEditor-CKjKH-yS.js → NotebookEditor-Dc61cXmK.js} +3 -3
  119. package/src/ui/dist/assets/{PdfLoader-zFoL0VPo.js → PdfLoader-DWowuQwx.js} +1 -1
  120. package/src/ui/dist/assets/{PdfMarkdownPlugin-DXPaL9Nt.js → PdfMarkdownPlugin-BsJM1q_a.js} +3 -3
  121. package/src/ui/dist/assets/{PdfViewerPlugin-DhK8qCFp.js → PdfViewerPlugin-DB2eEEFQ.js} +10 -10
  122. package/src/ui/dist/assets/{SearchPlugin-CdSi6krf.js → SearchPlugin-CraThSvt.js} +1 -1
  123. package/src/ui/dist/assets/{Stepper-V-WiDQJl.js → Stepper-CgocRTPq.js} +1 -1
  124. package/src/ui/dist/assets/{TextViewerPlugin-hIs1Efiu.js → TextViewerPlugin-B1JGhKtd.js} +4 -4
  125. package/src/ui/dist/assets/{VNCViewer-DG8b0q2X.js → VNCViewer-CclFC7FM.js} +9 -10
  126. package/src/ui/dist/assets/{bibtex-HDac6fVW.js → bibtex-D3IKsMl7.js} +1 -1
  127. package/src/ui/dist/assets/{code-BnBeNxBc.js → code-BP37Xx0p.js} +1 -1
  128. package/src/ui/dist/assets/{file-content-IRQ3jHb8.js → file-content-BAJSu-9r.js} +1 -1
  129. package/src/ui/dist/assets/{file-diff-panel-DZoQ9I6r.js → file-diff-panel-DUGeCTuy.js} +1 -1
  130. package/src/ui/dist/assets/{file-socket-BMCdLc-P.js → file-socket-CXc1Ojf7.js} +1 -1
  131. package/src/ui/dist/assets/{file-utils-CltILB3w.js → file-utils-2J21jt7M.js} +1 -1
  132. package/src/ui/dist/assets/{image-Boe6ffhu.js → image-CMMmgvcn.js} +1 -1
  133. package/src/ui/dist/assets/{index-BlplpvE1.js → index-BaVumsQT.js} +2 -2
  134. package/src/ui/dist/assets/{index-DZqJ-qAM.js → index-CWgMgpow.js} +60 -2154
  135. package/src/ui/dist/assets/{index-DO43pFZP.js → index-DmwmJmbW.js} +6372 -8434
  136. package/src/ui/dist/assets/{index-Bq2bvfkl.css → index-KGt-z-dD.css} +225 -2920
  137. package/src/ui/dist/assets/{index-2Zf65FZt.js → index-s7aHnNQ4.js} +1 -1
  138. package/src/ui/dist/assets/{message-square-mUHn_Ssb.js → message-square-CQRfX0Am.js} +1 -1
  139. package/src/ui/dist/assets/{monaco-fe0arNEU.js → monaco-B4TbdsrF.js} +1 -1
  140. package/src/ui/dist/assets/{popover-D_7i19qU.js → popover-B8Rokodk.js} +1 -1
  141. package/src/ui/dist/assets/{project-sync-DyVGrU7H.js → project-sync-D_i96KH4.js} +2 -8
  142. package/src/ui/dist/assets/{sigma-BzazRyxQ.js → sigma-D12PnzCN.js} +1 -1
  143. package/src/ui/dist/assets/{tooltip-DN_yjHFH.js → tooltip-B6YrI4aJ.js} +1 -1
  144. package/src/ui/dist/assets/trash-Bc8jGp0V.js +32 -0
  145. package/src/ui/dist/assets/{useCliAccess-DV2L2Qxy.js → useCliAccess-mXVCYSZ-.js} +12 -42
  146. package/src/ui/dist/assets/{useFileDiffOverlay-DyTj-p_V.js → useFileDiffOverlay-Bg6b9H9K.js} +1 -1
  147. package/src/ui/dist/assets/{wrap-text-ozYHtUwq.js → wrap-text-Drh5GEnL.js} +1 -1
  148. package/src/ui/dist/assets/{zoom-out-BN9MUyCQ.js → zoom-out-CJj9DZLn.js} +1 -1
  149. package/src/ui/dist/index.html +2 -2
  150. package/assets/fonts/Inter-Variable.ttf +0 -0
  151. package/assets/fonts/NotoSerifSC-Regular-C94HN_ZN.ttf +0 -0
  152. package/assets/fonts/NunitoSans-Variable.ttf +0 -0
  153. package/assets/fonts/Satoshi-Medium-ByP-Zb-9.woff2 +0 -0
  154. package/assets/fonts/SourceSans3-Variable.ttf +0 -0
  155. package/assets/fonts/ds-fonts.css +0 -83
  156. package/src/ui/dist/assets/Inter-Variable-VF2RPR_K.ttf +0 -0
  157. package/src/ui/dist/assets/LabPlugin-bL7rpic8.js +0 -43
  158. package/src/ui/dist/assets/NotoSerifSC-Regular-C94HN_ZN-C94HN_ZN.ttf +0 -0
  159. package/src/ui/dist/assets/NunitoSans-Variable-B_ZymHAd.ttf +0 -0
  160. package/src/ui/dist/assets/Satoshi-Medium-ByP-Zb-9-GkA34YXu.woff2 +0 -0
  161. package/src/ui/dist/assets/SourceSans3-Variable-CD-WOsSK.ttf +0 -0
  162. package/src/ui/dist/assets/info-CcsK_htA.js +0 -18
  163. package/src/ui/dist/assets/user-plus-BusDx-hF.js +0 -79
@@ -1,16 +1,16 @@
1
- import { o as createLucideIcon, cM as toDate, cN as getDefaultOptions, cO as normalizeDates, cP as compareAsc, cQ as getRoundingMethod, cR as getTimezoneOffsetInMilliseconds, cS as enUS, cT as minutesInDay, cU as minutesInMonth, cV as constructNow, j as jsxRuntimeExports, a6 as Button, n as ChevronDown, d as Check, b as cn, r as reactExports, cW as ArrowLeft, bG as ArrowRight, cX as Separator, cY as ArrowUp, cd as Trash2, u as useI18n, w as useToast, O as getFileContent, cZ as exportNotebook, e as Copy, L as LoaderCircle, a1 as Download, C as CircleAlert, c_ as buildFormatLongFn, c$ as buildLocalizeFn, d0 as buildMatchFn, d1 as buildMatchPatternFn, aO as useQueryClient, ai as useQuery, bi as useMutation, d2 as createNotebookCommit, d3 as revertNotebookToCommit, b9 as Dialog, ba as DialogContent, bb as DialogHeader, bc as DialogTitle, bI as DialogDescription, a$ as ScrollArea, bJ as Input, S as Save, d4 as listNotebookCommits, d5 as shimExports, d6 as useCallbackRef, d7 as useLayoutEffect2, d8 as inviteNotebookCollaborator, d9 as removeNotebookCollaborator, da as searchUsers, l as Search, X, b4 as Select, b5 as SelectTrigger, b6 as SelectValue, b7 as SelectContent, b8 as SelectItem, db as listNotebookCollaborators, f as useFileTreeStore, P as getQuestMarkdownContextFromFileId, dc as rewriteQuestMarkdownForDisplay, dd as rewriteQuestMarkdownForSave, de as uploadQuestDocumentAsset, N as updateFileContent } from './index-DO43pFZP.js';
2
- import { P as PluginKey, a as Plugin, S as Slice, F as Fragment, T as TextSelection, A as AllSelection, N as NodeSelection, E as Extension, m as me, l as le, u as useCurrentEditor, w, b as P, f as findParentNodeClosestToPos, g as getEditorMarkdown, c as Primitive, s as setEditorMarkdown, q, e as uploadNotebookAsset, r as resolveNotebookAssetUrl, d as defaultExtensions, J, U, I, h as T, B, O, i as S, K as K$1, G, j as ce, k as isSupportedNotebookAsset } from './NotebookEditor-CKjKH-yS.js';
1
+ import { z as createLucideIcon, j as jsxRuntimeExports, a3 as Button, n as ChevronDown, d as Check, b as cn, r as reactExports, bv as ArrowLeft, c4 as ArrowRight, ca as Separator, cb as ArrowUp, cc as Trash2, u as useI18n, v as useToast, K as getFileContent, L as LoaderCircle, e as Copy, C as CircleAlert, f as useFileTreeStore, N as getQuestMarkdownContextFromFileId, cd as rewriteQuestMarkdownForDisplay, ce as rewriteQuestMarkdownForSave, cf as uploadQuestDocumentAsset, J as updateFileContent } from './index-DmwmJmbW.js';
2
+ import { P as PluginKey, a as Plugin, S as Slice, F as Fragment, T as TextSelection, A as AllSelection, N as NodeSelection, E as Extension, m as me, l as le, u as useCurrentEditor, w, b as P, f as findParentNodeClosestToPos, g as getEditorMarkdown, s as setEditorMarkdown, q, c as uploadNotebookAsset, r as resolveNotebookAssetUrl, d as defaultExtensions, J, U, I, e as T, B, O, h as S, K as K$1, G, i as ce, j as isSupportedNotebookAsset } from './NotebookEditor-Dc61cXmK.js';
3
3
  import { a4 as BIT8, ai as BIT30, ab as min, $ as max, y as unexpectedCase, n as methodUnimplemented, aj as keys, u as every, H as setIfUndefined, D as create } from './function-B5QZkkHC.js';
4
4
  import { t as toBase64, e as encodeAny, i as isBrowser, d as doc, s as snapshot, D as Doc, a as applyUpdateV2, f as findIndexSS, b as iterateDeletedStructs, c as typeListToArraySnapshot, S as Snapshot, U as UndoManager, g as createSnapshot, h as isDeleted, Y as YXmlElement, j as YXmlText, k as YText, o as oneOf, C as ContentString, l as ContentFormat, m as createDeleteSet, I as Item, n as createRelativePositionFromTypeIndex, R as RelativePosition, p as findRootTypeKey, q as createID, r as createAbsolutePositionFromRelativePosition, u as isParentOf, v as ContentType, w as encodeStateVector, x as applyUpdate, y as mergeUpdates } from './yjs-DncrqiZ8.js';
5
- import { P as ProjectSyncClient } from './project-sync-DyVGrU7H.js';
6
- import { S as SquareCheckBig } from './index-2Zf65FZt.js';
7
- import { C as Code } from './code-BnBeNxBc.js';
8
- import { I as Image$1 } from './image-Boe6ffhu.js';
9
- import { P as Popover, a as PopoverTrigger, b as PopoverContent } from './popover-D_7i19qU.js';
10
- import { T as Trash, A as ArrowDown, E as Ellipsis, R as RefreshCcw, U as UserPlus } from './user-plus-BusDx-hF.js';
11
- import { S as Sigma } from './sigma-BzazRyxQ.js';
12
- import { u as useFileDiffOverlay } from './useFileDiffOverlay-DyTj-p_V.js';
13
- import { F as FileDiffPanel } from './file-diff-panel-DZoQ9I6r.js';
5
+ import { P as ProjectSyncClient } from './project-sync-D_i96KH4.js';
6
+ import { S as SquareCheckBig } from './index-s7aHnNQ4.js';
7
+ import { C as Code } from './code-BP37Xx0p.js';
8
+ import { I as Image } from './image-CMMmgvcn.js';
9
+ import { P as Popover, a as PopoverTrigger, b as PopoverContent } from './popover-B8Rokodk.js';
10
+ import { T as Trash, A as ArrowDown } from './trash-Bc8jGp0V.js';
11
+ import { S as Sigma } from './sigma-D12PnzCN.js';
12
+ import { u as useFileDiffOverlay } from './useFileDiffOverlay-Bg6b9H9K.js';
13
+ import { F as FileDiffPanel } from './file-diff-panel-DUGeCTuy.js';
14
14
 
15
15
  /**
16
16
  * @license lucide-react v0.511.0 - ISC
@@ -20,13 +20,13 @@ import { F as FileDiffPanel } from './file-diff-panel-DZoQ9I6r.js';
20
20
  */
21
21
 
22
22
 
23
- const __iconNode$j = [
23
+ const __iconNode$f = [
24
24
  [
25
25
  "path",
26
26
  { d: "M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8", key: "mg9rjx" }
27
27
  ]
28
28
  ];
29
- const Bold = createLucideIcon("bold", __iconNode$j);
29
+ const Bold = createLucideIcon("bold", __iconNode$f);
30
30
 
31
31
  /**
32
32
  * @license lucide-react v0.511.0 - ISC
@@ -36,13 +36,13 @@ const Bold = createLucideIcon("bold", __iconNode$j);
36
36
  */
37
37
 
38
38
 
39
- const __iconNode$i = [
39
+ const __iconNode$e = [
40
40
  ["path", { d: "M4 12h8", key: "17cfdx" }],
41
41
  ["path", { d: "M4 18V6", key: "1rz3zl" }],
42
42
  ["path", { d: "M12 18V6", key: "zqpxq5" }],
43
43
  ["path", { d: "m17 12 3-2v8", key: "1hhhft" }]
44
44
  ];
45
- const Heading1 = createLucideIcon("heading-1", __iconNode$i);
45
+ const Heading1 = createLucideIcon("heading-1", __iconNode$e);
46
46
 
47
47
  /**
48
48
  * @license lucide-react v0.511.0 - ISC
@@ -52,13 +52,13 @@ const Heading1 = createLucideIcon("heading-1", __iconNode$i);
52
52
  */
53
53
 
54
54
 
55
- const __iconNode$h = [
55
+ const __iconNode$d = [
56
56
  ["path", { d: "M4 12h8", key: "17cfdx" }],
57
57
  ["path", { d: "M4 18V6", key: "1rz3zl" }],
58
58
  ["path", { d: "M12 18V6", key: "zqpxq5" }],
59
59
  ["path", { d: "M21 18h-4c0-4 4-3 4-6 0-1.5-2-2.5-4-1", key: "9jr5yi" }]
60
60
  ];
61
- const Heading2 = createLucideIcon("heading-2", __iconNode$h);
61
+ const Heading2 = createLucideIcon("heading-2", __iconNode$d);
62
62
 
63
63
  /**
64
64
  * @license lucide-react v0.511.0 - ISC
@@ -68,29 +68,14 @@ const Heading2 = createLucideIcon("heading-2", __iconNode$h);
68
68
  */
69
69
 
70
70
 
71
- const __iconNode$g = [
71
+ const __iconNode$c = [
72
72
  ["path", { d: "M4 12h8", key: "17cfdx" }],
73
73
  ["path", { d: "M4 18V6", key: "1rz3zl" }],
74
74
  ["path", { d: "M12 18V6", key: "zqpxq5" }],
75
75
  ["path", { d: "M17.5 10.5c1.7-1 3.5 0 3.5 1.5a2 2 0 0 1-2 2", key: "68ncm8" }],
76
76
  ["path", { d: "M17 17.5c2 1.5 4 .3 4-1.5a2 2 0 0 0-2-2", key: "1ejuhz" }]
77
77
  ];
78
- const Heading3 = createLucideIcon("heading-3", __iconNode$g);
79
-
80
- /**
81
- * @license lucide-react v0.511.0 - ISC
82
- *
83
- * This source code is licensed under the ISC license.
84
- * See the LICENSE file in the root directory of this source tree.
85
- */
86
-
87
-
88
- const __iconNode$f = [
89
- ["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", key: "1357e3" }],
90
- ["path", { d: "M3 3v5h5", key: "1xhq8a" }],
91
- ["path", { d: "M12 7v5l4 2", key: "1fdv2h" }]
92
- ];
93
- const History = createLucideIcon("history", __iconNode$f);
78
+ const Heading3 = createLucideIcon("heading-3", __iconNode$c);
94
79
 
95
80
  /**
96
81
  * @license lucide-react v0.511.0 - ISC
@@ -100,12 +85,12 @@ const History = createLucideIcon("history", __iconNode$f);
100
85
  */
101
86
 
102
87
 
103
- const __iconNode$e = [
88
+ const __iconNode$b = [
104
89
  ["line", { x1: "19", x2: "10", y1: "4", y2: "4", key: "15jd3p" }],
105
90
  ["line", { x1: "14", x2: "5", y1: "20", y2: "20", key: "bu0au3" }],
106
91
  ["line", { x1: "15", x2: "9", y1: "4", y2: "20", key: "uljnxc" }]
107
92
  ];
108
- const Italic = createLucideIcon("italic", __iconNode$e);
93
+ const Italic = createLucideIcon("italic", __iconNode$b);
109
94
 
110
95
  /**
111
96
  * @license lucide-react v0.511.0 - ISC
@@ -115,7 +100,7 @@ const Italic = createLucideIcon("italic", __iconNode$e);
115
100
  */
116
101
 
117
102
 
118
- const __iconNode$d = [
103
+ const __iconNode$a = [
119
104
  ["path", { d: "M10 12h11", key: "6m4ad9" }],
120
105
  ["path", { d: "M10 18h11", key: "11hvi2" }],
121
106
  ["path", { d: "M10 6h11", key: "c7qv1k" }],
@@ -123,7 +108,7 @@ const __iconNode$d = [
123
108
  ["path", { d: "M4 6h1v4", key: "cnovpq" }],
124
109
  ["path", { d: "M6 18H4c0-1 2-2 2-3s-1-1.5-2-1", key: "m9a95d" }]
125
110
  ];
126
- const ListOrdered = createLucideIcon("list-ordered", __iconNode$d);
111
+ const ListOrdered = createLucideIcon("list-ordered", __iconNode$a);
127
112
 
128
113
  /**
129
114
  * @license lucide-react v0.511.0 - ISC
@@ -133,7 +118,7 @@ const ListOrdered = createLucideIcon("list-ordered", __iconNode$d);
133
118
  */
134
119
 
135
120
 
136
- const __iconNode$c = [
121
+ const __iconNode$9 = [
137
122
  ["path", { d: "M3 12h.01", key: "nlz23k" }],
138
123
  ["path", { d: "M3 18h.01", key: "1tta3j" }],
139
124
  ["path", { d: "M3 6h.01", key: "1rqtza" }],
@@ -141,7 +126,7 @@ const __iconNode$c = [
141
126
  ["path", { d: "M8 18h13", key: "1lx6n3" }],
142
127
  ["path", { d: "M8 6h13", key: "ik3vkj" }]
143
128
  ];
144
- const List = createLucideIcon("list", __iconNode$c);
129
+ const List = createLucideIcon("list", __iconNode$9);
145
130
 
146
131
  /**
147
132
  * @license lucide-react v0.511.0 - ISC
@@ -151,23 +136,12 @@ const List = createLucideIcon("list", __iconNode$c);
151
136
  */
152
137
 
153
138
 
154
- const __iconNode$b = [
139
+ const __iconNode$8 = [
155
140
  ["path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z", key: "1lielz" }],
156
141
  ["path", { d: "M12 7v6", key: "lw1j43" }],
157
142
  ["path", { d: "M9 10h6", key: "9gxzsh" }]
158
143
  ];
159
- const MessageSquarePlus = createLucideIcon("message-square-plus", __iconNode$b);
160
-
161
- /**
162
- * @license lucide-react v0.511.0 - ISC
163
- *
164
- * This source code is licensed under the ISC license.
165
- * See the LICENSE file in the root directory of this source tree.
166
- */
167
-
168
-
169
- const __iconNode$a = [["path", { d: "M5 12h14", key: "1ays0h" }]];
170
- const Minus = createLucideIcon("minus", __iconNode$a);
144
+ const MessageSquarePlus = createLucideIcon("message-square-plus", __iconNode$8);
171
145
 
172
146
  /**
173
147
  * @license lucide-react v0.511.0 - ISC
@@ -177,12 +151,8 @@ const Minus = createLucideIcon("minus", __iconNode$a);
177
151
  */
178
152
 
179
153
 
180
- const __iconNode$9 = [
181
- ["path", { d: "M12 2v13", key: "1km8f5" }],
182
- ["path", { d: "m16 6-4-4-4 4", key: "13yo43" }],
183
- ["path", { d: "M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8", key: "1b2hhj" }]
184
- ];
185
- const Share = createLucideIcon("share", __iconNode$9);
154
+ const __iconNode$7 = [["path", { d: "M5 12h14", key: "1ays0h" }]];
155
+ const Minus = createLucideIcon("minus", __iconNode$7);
186
156
 
187
157
  /**
188
158
  * @license lucide-react v0.511.0 - ISC
@@ -192,12 +162,12 @@ const Share = createLucideIcon("share", __iconNode$9);
192
162
  */
193
163
 
194
164
 
195
- const __iconNode$8 = [
165
+ const __iconNode$6 = [
196
166
  ["path", { d: "M16 4H9a3 3 0 0 0-2.83 4", key: "43sutm" }],
197
167
  ["path", { d: "M14 12a4 4 0 0 1 0 8H6", key: "nlfj13" }],
198
168
  ["line", { x1: "4", x2: "20", y1: "12", y2: "12", key: "1e0a9i" }]
199
169
  ];
200
- const Strikethrough = createLucideIcon("strikethrough", __iconNode$8);
170
+ const Strikethrough = createLucideIcon("strikethrough", __iconNode$6);
201
171
 
202
172
  /**
203
173
  * @license lucide-react v0.511.0 - ISC
@@ -207,7 +177,7 @@ const Strikethrough = createLucideIcon("strikethrough", __iconNode$8);
207
177
  */
208
178
 
209
179
 
210
- const __iconNode$7 = [
180
+ const __iconNode$5 = [
211
181
  [
212
182
  "path",
213
183
  {
@@ -216,7 +186,7 @@ const __iconNode$7 = [
216
186
  }
217
187
  ]
218
188
  ];
219
- const Table2 = createLucideIcon("table-2", __iconNode$7);
189
+ const Table2 = createLucideIcon("table-2", __iconNode$5);
220
190
 
221
191
  /**
222
192
  * @license lucide-react v0.511.0 - ISC
@@ -226,13 +196,13 @@ const Table2 = createLucideIcon("table-2", __iconNode$7);
226
196
  */
227
197
 
228
198
 
229
- const __iconNode$6 = [
199
+ const __iconNode$4 = [
230
200
  ["path", { d: "M17 6H3", key: "16j9eg" }],
231
201
  ["path", { d: "M21 12H8", key: "scolzb" }],
232
202
  ["path", { d: "M21 18H8", key: "1wfozv" }],
233
203
  ["path", { d: "M3 12v6", key: "fv4c87" }]
234
204
  ];
235
- const TextQuote = createLucideIcon("text-quote", __iconNode$6);
205
+ const TextQuote = createLucideIcon("text-quote", __iconNode$4);
236
206
 
237
207
  /**
238
208
  * @license lucide-react v0.511.0 - ISC
@@ -242,12 +212,12 @@ const TextQuote = createLucideIcon("text-quote", __iconNode$6);
242
212
  */
243
213
 
244
214
 
245
- const __iconNode$5 = [
215
+ const __iconNode$3 = [
246
216
  ["path", { d: "M15 18H3", key: "olowqp" }],
247
217
  ["path", { d: "M17 6H3", key: "16j9eg" }],
248
218
  ["path", { d: "M21 12H3", key: "2avoz0" }]
249
219
  ];
250
- const Text = createLucideIcon("text", __iconNode$5);
220
+ const Text = createLucideIcon("text", __iconNode$3);
251
221
 
252
222
  /**
253
223
  * @license lucide-react v0.511.0 - ISC
@@ -257,7 +227,7 @@ const Text = createLucideIcon("text", __iconNode$5);
257
227
  */
258
228
 
259
229
 
260
- const __iconNode$4 = [
230
+ const __iconNode$2 = [
261
231
  [
262
232
  "path",
263
233
  {
@@ -266,7 +236,7 @@ const __iconNode$4 = [
266
236
  }
267
237
  ]
268
238
  ];
269
- const Twitter = createLucideIcon("twitter", __iconNode$4);
239
+ const Twitter = createLucideIcon("twitter", __iconNode$2);
270
240
 
271
241
  /**
272
242
  * @license lucide-react v0.511.0 - ISC
@@ -276,41 +246,11 @@ const Twitter = createLucideIcon("twitter", __iconNode$4);
276
246
  */
277
247
 
278
248
 
279
- const __iconNode$3 = [
249
+ const __iconNode$1 = [
280
250
  ["path", { d: "M6 4v6a6 6 0 0 0 12 0V4", key: "9kb039" }],
281
251
  ["line", { x1: "4", x2: "20", y1: "20", y2: "20", key: "nun2al" }]
282
252
  ];
283
- const Underline = createLucideIcon("underline", __iconNode$3);
284
-
285
- /**
286
- * @license lucide-react v0.511.0 - ISC
287
- *
288
- * This source code is licensed under the ISC license.
289
- * See the LICENSE file in the root directory of this source tree.
290
- */
291
-
292
-
293
- const __iconNode$2 = [
294
- ["path", { d: "M9 14 4 9l5-5", key: "102s5s" }],
295
- ["path", { d: "M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11", key: "f3b9sd" }]
296
- ];
297
- const Undo2 = createLucideIcon("undo-2", __iconNode$2);
298
-
299
- /**
300
- * @license lucide-react v0.511.0 - ISC
301
- *
302
- * This source code is licensed under the ISC license.
303
- * See the LICENSE file in the root directory of this source tree.
304
- */
305
-
306
-
307
- const __iconNode$1 = [
308
- ["path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2", key: "1yyitq" }],
309
- ["path", { d: "M16 3.128a4 4 0 0 1 0 7.744", key: "16gr8j" }],
310
- ["path", { d: "M22 21v-2a4 4 0 0 0-3-3.87", key: "kshegd" }],
311
- ["circle", { cx: "9", cy: "7", r: "4", key: "nufk8" }]
312
- ];
313
- const Users = createLucideIcon("users", __iconNode$1);
253
+ const Underline = createLucideIcon("underline", __iconNode$1);
314
254
 
315
255
  /**
316
256
  * @license lucide-react v0.511.0 - ISC
@@ -332,619 +272,6 @@ const __iconNode = [
332
272
  ];
333
273
  const Youtube = createLucideIcon("youtube", __iconNode);
334
274
 
335
- /**
336
- * The {@link startOfWeek} function options.
337
- */
338
-
339
- /**
340
- * @name startOfWeek
341
- * @category Week Helpers
342
- * @summary Return the start of a week for the given date.
343
- *
344
- * @description
345
- * Return the start of a week for the given date.
346
- * The result will be in the local timezone.
347
- *
348
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
349
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
350
- *
351
- * @param date - The original date
352
- * @param options - An object with options
353
- *
354
- * @returns The start of a week
355
- *
356
- * @example
357
- * // The start of a week for 2 September 2014 11:55:00:
358
- * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0))
359
- * //=> Sun Aug 31 2014 00:00:00
360
- *
361
- * @example
362
- * // If the week starts on Monday, the start of the week for 2 September 2014 11:55:00:
363
- * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })
364
- * //=> Mon Sep 01 2014 00:00:00
365
- */
366
- function startOfWeek(date, options) {
367
- const defaultOptions = getDefaultOptions();
368
- const weekStartsOn =
369
- options?.weekStartsOn ??
370
- options?.locale?.options?.weekStartsOn ??
371
- defaultOptions.weekStartsOn ??
372
- defaultOptions.locale?.options?.weekStartsOn ??
373
- 0;
374
-
375
- const _date = toDate(date, options?.in);
376
- const day = _date.getDay();
377
- const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
378
-
379
- _date.setDate(_date.getDate() - diff);
380
- _date.setHours(0, 0, 0, 0);
381
- return _date;
382
- }
383
-
384
- /**
385
- * The {@link differenceInCalendarMonths} function options.
386
- */
387
-
388
- /**
389
- * @name differenceInCalendarMonths
390
- * @category Month Helpers
391
- * @summary Get the number of calendar months between the given dates.
392
- *
393
- * @description
394
- * Get the number of calendar months between the given dates.
395
- *
396
- * @param laterDate - The later date
397
- * @param earlierDate - The earlier date
398
- * @param options - An object with options
399
- *
400
- * @returns The number of calendar months
401
- *
402
- * @example
403
- * // How many calendar months are between 31 January 2014 and 1 September 2014?
404
- * const result = differenceInCalendarMonths(
405
- * new Date(2014, 8, 1),
406
- * new Date(2014, 0, 31)
407
- * )
408
- * //=> 8
409
- */
410
- function differenceInCalendarMonths(laterDate, earlierDate, options) {
411
- const [laterDate_, earlierDate_] = normalizeDates(
412
- options?.in,
413
- laterDate,
414
- earlierDate,
415
- );
416
-
417
- const yearsDiff = laterDate_.getFullYear() - earlierDate_.getFullYear();
418
- const monthsDiff = laterDate_.getMonth() - earlierDate_.getMonth();
419
-
420
- return yearsDiff * 12 + monthsDiff;
421
- }
422
-
423
- /**
424
- * @name differenceInMilliseconds
425
- * @category Millisecond Helpers
426
- * @summary Get the number of milliseconds between the given dates.
427
- *
428
- * @description
429
- * Get the number of milliseconds between the given dates.
430
- *
431
- * @param laterDate - The later date
432
- * @param earlierDate - The earlier date
433
- *
434
- * @returns The number of milliseconds
435
- *
436
- * @example
437
- * // How many milliseconds are between
438
- * // 2 July 2014 12:30:20.600 and 2 July 2014 12:30:21.700?
439
- * const result = differenceInMilliseconds(
440
- * new Date(2014, 6, 2, 12, 30, 21, 700),
441
- * new Date(2014, 6, 2, 12, 30, 20, 600)
442
- * )
443
- * //=> 1100
444
- */
445
- function differenceInMilliseconds(laterDate, earlierDate) {
446
- return +toDate(laterDate) - +toDate(earlierDate);
447
- }
448
-
449
- /**
450
- * The {@link endOfDay} function options.
451
- */
452
-
453
- /**
454
- * @name endOfDay
455
- * @category Day Helpers
456
- * @summary Return the end of a day for the given date.
457
- *
458
- * @description
459
- * Return the end of a day for the given date.
460
- * The result will be in the local timezone.
461
- *
462
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
463
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
464
- *
465
- * @param date - The original date
466
- * @param options - An object with options
467
- *
468
- * @returns The end of a day
469
- *
470
- * @example
471
- * // The end of a day for 2 September 2014 11:55:00:
472
- * const result = endOfDay(new Date(2014, 8, 2, 11, 55, 0))
473
- * //=> Tue Sep 02 2014 23:59:59.999
474
- */
475
- function endOfDay(date, options) {
476
- const _date = toDate(date, options?.in);
477
- _date.setHours(23, 59, 59, 999);
478
- return _date;
479
- }
480
-
481
- /**
482
- * The {@link endOfMonth} function options.
483
- */
484
-
485
- /**
486
- * @name endOfMonth
487
- * @category Month Helpers
488
- * @summary Return the end of a month for the given date.
489
- *
490
- * @description
491
- * Return the end of a month for the given date.
492
- * The result will be in the local timezone.
493
- *
494
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
495
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
496
- *
497
- * @param date - The original date
498
- * @param options - An object with options
499
- *
500
- * @returns The end of a month
501
- *
502
- * @example
503
- * // The end of a month for 2 September 2014 11:55:00:
504
- * const result = endOfMonth(new Date(2014, 8, 2, 11, 55, 0))
505
- * //=> Tue Sep 30 2014 23:59:59.999
506
- */
507
- function endOfMonth(date, options) {
508
- const _date = toDate(date, options?.in);
509
- const month = _date.getMonth();
510
- _date.setFullYear(_date.getFullYear(), month + 1, 0);
511
- _date.setHours(23, 59, 59, 999);
512
- return _date;
513
- }
514
-
515
- /**
516
- * @name isLastDayOfMonth
517
- * @category Month Helpers
518
- * @summary Is the given date the last day of a month?
519
- *
520
- * @description
521
- * Is the given date the last day of a month?
522
- *
523
- * @param date - The date to check
524
- * @param options - An object with options
525
- *
526
- * @returns The date is the last day of a month
527
- *
528
- * @example
529
- * // Is 28 February 2014 the last day of a month?
530
- * const result = isLastDayOfMonth(new Date(2014, 1, 28))
531
- * //=> true
532
- */
533
- function isLastDayOfMonth(date, options) {
534
- const _date = toDate(date, options?.in);
535
- return +endOfDay(_date, options) === +endOfMonth(_date, options);
536
- }
537
-
538
- /**
539
- * The {@link differenceInMonths} function options.
540
- */
541
-
542
- /**
543
- * @name differenceInMonths
544
- * @category Month Helpers
545
- * @summary Get the number of full months between the given dates.
546
- *
547
- * @param laterDate - The later date
548
- * @param earlierDate - The earlier date
549
- * @param options - An object with options
550
- *
551
- * @returns The number of full months
552
- *
553
- * @example
554
- * // How many full months are between 31 January 2014 and 1 September 2014?
555
- * const result = differenceInMonths(new Date(2014, 8, 1), new Date(2014, 0, 31))
556
- * //=> 7
557
- */
558
- function differenceInMonths(laterDate, earlierDate, options) {
559
- const [laterDate_, workingLaterDate, earlierDate_] = normalizeDates(
560
- options?.in,
561
- laterDate,
562
- laterDate,
563
- earlierDate,
564
- );
565
-
566
- const sign = compareAsc(workingLaterDate, earlierDate_);
567
- const difference = Math.abs(
568
- differenceInCalendarMonths(workingLaterDate, earlierDate_),
569
- );
570
-
571
- if (difference < 1) return 0;
572
-
573
- if (workingLaterDate.getMonth() === 1 && workingLaterDate.getDate() > 27)
574
- workingLaterDate.setDate(30);
575
-
576
- workingLaterDate.setMonth(workingLaterDate.getMonth() - sign * difference);
577
-
578
- let isLastMonthNotFull = compareAsc(workingLaterDate, earlierDate_) === -sign;
579
-
580
- if (
581
- isLastDayOfMonth(laterDate_) &&
582
- difference === 1 &&
583
- compareAsc(laterDate_, earlierDate_) === 1
584
- ) {
585
- isLastMonthNotFull = false;
586
- }
587
-
588
- const result = sign * (difference - +isLastMonthNotFull);
589
- return result === 0 ? 0 : result;
590
- }
591
-
592
- /**
593
- * The {@link differenceInSeconds} function options.
594
- */
595
-
596
- /**
597
- * @name differenceInSeconds
598
- * @category Second Helpers
599
- * @summary Get the number of seconds between the given dates.
600
- *
601
- * @description
602
- * Get the number of seconds between the given dates.
603
- *
604
- * @param laterDate - The later date
605
- * @param earlierDate - The earlier date
606
- * @param options - An object with options.
607
- *
608
- * @returns The number of seconds
609
- *
610
- * @example
611
- * // How many seconds are between
612
- * // 2 July 2014 12:30:07.999 and 2 July 2014 12:30:20.000?
613
- * const result = differenceInSeconds(
614
- * new Date(2014, 6, 2, 12, 30, 20, 0),
615
- * new Date(2014, 6, 2, 12, 30, 7, 999)
616
- * )
617
- * //=> 12
618
- */
619
- function differenceInSeconds(laterDate, earlierDate, options) {
620
- const diff = differenceInMilliseconds(laterDate, earlierDate) / 1000;
621
- return getRoundingMethod(options?.roundingMethod)(diff);
622
- }
623
-
624
- /**
625
- * The {@link formatDistance} function options.
626
- */
627
-
628
- /**
629
- * @name formatDistance
630
- * @category Common Helpers
631
- * @summary Return the distance between the given dates in words.
632
- *
633
- * @description
634
- * Return the distance between the given dates in words.
635
- *
636
- * | Distance between dates | Result |
637
- * |-------------------------------------------------------------------|---------------------|
638
- * | 0 ... 30 secs | less than a minute |
639
- * | 30 secs ... 1 min 30 secs | 1 minute |
640
- * | 1 min 30 secs ... 44 mins 30 secs | [2..44] minutes |
641
- * | 44 mins ... 30 secs ... 89 mins 30 secs | about 1 hour |
642
- * | 89 mins 30 secs ... 23 hrs 59 mins 30 secs | about [2..24] hours |
643
- * | 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs | 1 day |
644
- * | 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs | [2..30] days |
645
- * | 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs | about 1 month |
646
- * | 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs | about 2 months |
647
- * | 59 days 23 hrs 59 mins 30 secs ... 1 yr | [2..12] months |
648
- * | 1 yr ... 1 yr 3 months | about 1 year |
649
- * | 1 yr 3 months ... 1 yr 9 month s | over 1 year |
650
- * | 1 yr 9 months ... 2 yrs | almost 2 years |
651
- * | N yrs ... N yrs 3 months | about N years |
652
- * | N yrs 3 months ... N yrs 9 months | over N years |
653
- * | N yrs 9 months ... N+1 yrs | almost N+1 years |
654
- *
655
- * With `options.includeSeconds == true`:
656
- * | Distance between dates | Result |
657
- * |------------------------|----------------------|
658
- * | 0 secs ... 5 secs | less than 5 seconds |
659
- * | 5 secs ... 10 secs | less than 10 seconds |
660
- * | 10 secs ... 20 secs | less than 20 seconds |
661
- * | 20 secs ... 40 secs | half a minute |
662
- * | 40 secs ... 60 secs | less than a minute |
663
- * | 60 secs ... 90 secs | 1 minute |
664
- *
665
- * @param laterDate - The date
666
- * @param earlierDate - The date to compare with
667
- * @param options - An object with options
668
- *
669
- * @returns The distance in words
670
- *
671
- * @throws `date` must not be Invalid Date
672
- * @throws `baseDate` must not be Invalid Date
673
- * @throws `options.locale` must contain `formatDistance` property
674
- *
675
- * @example
676
- * // What is the distance between 2 July 2014 and 1 January 2015?
677
- * const result = formatDistance(new Date(2014, 6, 2), new Date(2015, 0, 1))
678
- * //=> '6 months'
679
- *
680
- * @example
681
- * // What is the distance between 1 January 2015 00:00:15
682
- * // and 1 January 2015 00:00:00, including seconds?
683
- * const result = formatDistance(
684
- * new Date(2015, 0, 1, 0, 0, 15),
685
- * new Date(2015, 0, 1, 0, 0, 0),
686
- * { includeSeconds: true }
687
- * )
688
- * //=> 'less than 20 seconds'
689
- *
690
- * @example
691
- * // What is the distance from 1 January 2016
692
- * // to 1 January 2015, with a suffix?
693
- * const result = formatDistance(new Date(2015, 0, 1), new Date(2016, 0, 1), {
694
- * addSuffix: true
695
- * })
696
- * //=> 'about 1 year ago'
697
- *
698
- * @example
699
- * // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?
700
- * import { eoLocale } from 'date-fns/locale/eo'
701
- * const result = formatDistance(new Date(2016, 7, 1), new Date(2015, 0, 1), {
702
- * locale: eoLocale
703
- * })
704
- * //=> 'pli ol 1 jaro'
705
- */
706
- function formatDistance$1(laterDate, earlierDate, options) {
707
- const defaultOptions = getDefaultOptions();
708
- const locale = options?.locale ?? defaultOptions.locale ?? enUS;
709
- const minutesInAlmostTwoDays = 2520;
710
-
711
- const comparison = compareAsc(laterDate, earlierDate);
712
-
713
- if (isNaN(comparison)) throw new RangeError("Invalid time value");
714
-
715
- const localizeOptions = Object.assign({}, options, {
716
- addSuffix: options?.addSuffix,
717
- comparison: comparison,
718
- });
719
-
720
- const [laterDate_, earlierDate_] = normalizeDates(
721
- options?.in,
722
- ...(comparison > 0 ? [earlierDate, laterDate] : [laterDate, earlierDate]),
723
- );
724
-
725
- const seconds = differenceInSeconds(earlierDate_, laterDate_);
726
- const offsetInSeconds =
727
- (getTimezoneOffsetInMilliseconds(earlierDate_) -
728
- getTimezoneOffsetInMilliseconds(laterDate_)) /
729
- 1000;
730
- const minutes = Math.round((seconds - offsetInSeconds) / 60);
731
- let months;
732
-
733
- // 0 up to 2 mins
734
- if (minutes < 2) {
735
- if (options?.includeSeconds) {
736
- if (seconds < 5) {
737
- return locale.formatDistance("lessThanXSeconds", 5, localizeOptions);
738
- } else if (seconds < 10) {
739
- return locale.formatDistance("lessThanXSeconds", 10, localizeOptions);
740
- } else if (seconds < 20) {
741
- return locale.formatDistance("lessThanXSeconds", 20, localizeOptions);
742
- } else if (seconds < 40) {
743
- return locale.formatDistance("halfAMinute", 0, localizeOptions);
744
- } else if (seconds < 60) {
745
- return locale.formatDistance("lessThanXMinutes", 1, localizeOptions);
746
- } else {
747
- return locale.formatDistance("xMinutes", 1, localizeOptions);
748
- }
749
- } else {
750
- if (minutes === 0) {
751
- return locale.formatDistance("lessThanXMinutes", 1, localizeOptions);
752
- } else {
753
- return locale.formatDistance("xMinutes", minutes, localizeOptions);
754
- }
755
- }
756
-
757
- // 2 mins up to 0.75 hrs
758
- } else if (minutes < 45) {
759
- return locale.formatDistance("xMinutes", minutes, localizeOptions);
760
-
761
- // 0.75 hrs up to 1.5 hrs
762
- } else if (minutes < 90) {
763
- return locale.formatDistance("aboutXHours", 1, localizeOptions);
764
-
765
- // 1.5 hrs up to 24 hrs
766
- } else if (minutes < minutesInDay) {
767
- const hours = Math.round(minutes / 60);
768
- return locale.formatDistance("aboutXHours", hours, localizeOptions);
769
-
770
- // 1 day up to 1.75 days
771
- } else if (minutes < minutesInAlmostTwoDays) {
772
- return locale.formatDistance("xDays", 1, localizeOptions);
773
-
774
- // 1.75 days up to 30 days
775
- } else if (minutes < minutesInMonth) {
776
- const days = Math.round(minutes / minutesInDay);
777
- return locale.formatDistance("xDays", days, localizeOptions);
778
-
779
- // 1 month up to 2 months
780
- } else if (minutes < minutesInMonth * 2) {
781
- months = Math.round(minutes / minutesInMonth);
782
- return locale.formatDistance("aboutXMonths", months, localizeOptions);
783
- }
784
-
785
- months = differenceInMonths(earlierDate_, laterDate_);
786
-
787
- // 2 months up to 12 months
788
- if (months < 12) {
789
- const nearestMonth = Math.round(minutes / minutesInMonth);
790
- return locale.formatDistance("xMonths", nearestMonth, localizeOptions);
791
-
792
- // 1 year up to max Date
793
- } else {
794
- const monthsSinceStartOfYear = months % 12;
795
- const years = Math.trunc(months / 12);
796
-
797
- // N years up to 1 years 3 months
798
- if (monthsSinceStartOfYear < 3) {
799
- return locale.formatDistance("aboutXYears", years, localizeOptions);
800
-
801
- // N years 3 months up to N years 9 months
802
- } else if (monthsSinceStartOfYear < 9) {
803
- return locale.formatDistance("overXYears", years, localizeOptions);
804
-
805
- // N years 9 months up to N year 12 months
806
- } else {
807
- return locale.formatDistance("almostXYears", years + 1, localizeOptions);
808
- }
809
- }
810
- }
811
-
812
- /**
813
- * The {@link formatDistanceToNow} function options.
814
- */
815
-
816
- /**
817
- * @name formatDistanceToNow
818
- * @category Common Helpers
819
- * @summary Return the distance between the given date and now in words.
820
- * @pure false
821
- *
822
- * @description
823
- * Return the distance between the given date and now in words.
824
- *
825
- * | Distance to now | Result |
826
- * |-------------------------------------------------------------------|---------------------|
827
- * | 0 ... 30 secs | less than a minute |
828
- * | 30 secs ... 1 min 30 secs | 1 minute |
829
- * | 1 min 30 secs ... 44 mins 30 secs | [2..44] minutes |
830
- * | 44 mins ... 30 secs ... 89 mins 30 secs | about 1 hour |
831
- * | 89 mins 30 secs ... 23 hrs 59 mins 30 secs | about [2..24] hours |
832
- * | 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs | 1 day |
833
- * | 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs | [2..30] days |
834
- * | 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs | about 1 month |
835
- * | 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs | about 2 months |
836
- * | 59 days 23 hrs 59 mins 30 secs ... 1 yr | [2..12] months |
837
- * | 1 yr ... 1 yr 3 months | about 1 year |
838
- * | 1 yr 3 months ... 1 yr 9 month s | over 1 year |
839
- * | 1 yr 9 months ... 2 yrs | almost 2 years |
840
- * | N yrs ... N yrs 3 months | about N years |
841
- * | N yrs 3 months ... N yrs 9 months | over N years |
842
- * | N yrs 9 months ... N+1 yrs | almost N+1 years |
843
- *
844
- * With `options.includeSeconds == true`:
845
- * | Distance to now | Result |
846
- * |---------------------|----------------------|
847
- * | 0 secs ... 5 secs | less than 5 seconds |
848
- * | 5 secs ... 10 secs | less than 10 seconds |
849
- * | 10 secs ... 20 secs | less than 20 seconds |
850
- * | 20 secs ... 40 secs | half a minute |
851
- * | 40 secs ... 60 secs | less than a minute |
852
- * | 60 secs ... 90 secs | 1 minute |
853
- *
854
- * @param date - The given date
855
- * @param options - The object with options
856
- *
857
- * @returns The distance in words
858
- *
859
- * @throws `date` must not be Invalid Date
860
- * @throws `options.locale` must contain `formatDistance` property
861
- *
862
- * @example
863
- * // If today is 1 January 2015, what is the distance to 2 July 2014?
864
- * const result = formatDistanceToNow(
865
- * new Date(2014, 6, 2)
866
- * )
867
- * //=> '6 months'
868
- *
869
- * @example
870
- * // If now is 1 January 2015 00:00:00,
871
- * // what is the distance to 1 January 2015 00:00:15, including seconds?
872
- * const result = formatDistanceToNow(
873
- * new Date(2015, 0, 1, 0, 0, 15),
874
- * {includeSeconds: true}
875
- * )
876
- * //=> 'less than 20 seconds'
877
- *
878
- * @example
879
- * // If today is 1 January 2015,
880
- * // what is the distance to 1 January 2016, with a suffix?
881
- * const result = formatDistanceToNow(
882
- * new Date(2016, 0, 1),
883
- * {addSuffix: true}
884
- * )
885
- * //=> 'in about 1 year'
886
- *
887
- * @example
888
- * // If today is 1 January 2015,
889
- * // what is the distance to 1 August 2016 in Esperanto?
890
- * const eoLocale = require('date-fns/locale/eo')
891
- * const result = formatDistanceToNow(
892
- * new Date(2016, 7, 1),
893
- * {locale: eoLocale}
894
- * )
895
- * //=> 'pli ol 1 jaro'
896
- */
897
- function formatDistanceToNow(date, options) {
898
- return formatDistance$1(date, constructNow(date), options);
899
- }
900
-
901
- /**
902
- * The {@link isSameWeek} function options.
903
- */
904
-
905
- /**
906
- * @name isSameWeek
907
- * @category Week Helpers
908
- * @summary Are the given dates in the same week (and month and year)?
909
- *
910
- * @description
911
- * Are the given dates in the same week (and month and year)?
912
- *
913
- * @param laterDate - The first date to check
914
- * @param earlierDate - The second date to check
915
- * @param options - An object with options
916
- *
917
- * @returns The dates are in the same week (and month and year)
918
- *
919
- * @example
920
- * // Are 31 August 2014 and 4 September 2014 in the same week?
921
- * const result = isSameWeek(new Date(2014, 7, 31), new Date(2014, 8, 4))
922
- * //=> true
923
- *
924
- * @example
925
- * // If week starts with Monday,
926
- * // are 31 August 2014 and 4 September 2014 in the same week?
927
- * const result = isSameWeek(new Date(2014, 7, 31), new Date(2014, 8, 4), {
928
- * weekStartsOn: 1
929
- * })
930
- * //=> false
931
- *
932
- * @example
933
- * // Are 1 January 2014 and 1 January 2015 in the same week?
934
- * const result = isSameWeek(new Date(2014, 0, 1), new Date(2015, 0, 1))
935
- * //=> false
936
- */
937
- function isSameWeek(laterDate, earlierDate, options) {
938
- const [laterDate_, earlierDate_] = normalizeDates(
939
- options?.in,
940
- laterDate,
941
- earlierDate,
942
- );
943
- return (
944
- +startOfWeek(laterDate_, options) === +startOfWeek(earlierDate_, options)
945
- );
946
- }
947
-
948
275
  const notebookPluginManifest = {
949
276
  // ============================================================
950
277
  // Basic Information
@@ -984,13 +311,7 @@ const notebookPluginManifest = {
984
311
  // ============================================================
985
312
  backend: {
986
313
  entry: "app.plugins.builtin.notebook_tools",
987
- tools: [],
988
- routes: {
989
- "/notebooks": "list_notebooks",
990
- "/notebooks/:id": "get_notebook",
991
- "/notebooks/:id/content": "get_notebook_content",
992
- "/notebooks/:id/snapshots": "list_snapshots"
993
- }
314
+ tools: []
994
315
  },
995
316
  // ============================================================
996
317
  // Permissions
@@ -1003,16 +324,6 @@ const notebookPluginManifest = {
1003
324
  // UI Contributions
1004
325
  // ============================================================
1005
326
  contributes: {
1006
- // Sidebar menu entry
1007
- sidebarMenus: [
1008
- {
1009
- id: "notebook-list",
1010
- title: "Notebooks",
1011
- icon: "book-open",
1012
- order: 5
1013
- // High priority in sidebar
1014
- }
1015
- ],
1016
327
  // Tab configuration
1017
328
  tabIcon: "file-text",
1018
329
  tabTitle: {
@@ -1026,13 +337,6 @@ const notebookPluginManifest = {
1026
337
  icon: "Download",
1027
338
  command: "notebook.export",
1028
339
  position: "right"
1029
- },
1030
- {
1031
- id: "notebook-share",
1032
- title: "Share",
1033
- icon: "Share",
1034
- command: "notebook.share",
1035
- position: "right"
1036
340
  }
1037
341
  ],
1038
342
  // Context menu items (optional)
@@ -3239,7 +2543,7 @@ const REMOTE_ORIGIN = "ds-remote";
3239
2543
  async function createNovelYjsProvider(options) {
3240
2544
  const { projectId, notebookId, readonly = false, onStatus, onReset } = options;
3241
2545
  const sync = new ProjectSyncClient(projectId, {
3242
- authMode: readonly ? "share" : "user",
2546
+ authMode: "user",
3243
2547
  docKind: "notebook"
3244
2548
  });
3245
2549
  const ydoc = new Doc();
@@ -3406,7 +2710,7 @@ function buildSuggestionItems(onImageUpload) {
3406
2710
  title: "Image",
3407
2711
  description: "Upload an image from your computer.",
3408
2712
  searchTerms: ["photo", "picture", "media"],
3409
- icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Image$1, { size: 18 }),
2713
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Image, { size: 18 }),
3410
2714
  command: ({ editor, range }) => {
3411
2715
  editor.chain().focus().deleteRange(range).run();
3412
2716
  const input = document.createElement("input");
@@ -4253,22 +3557,14 @@ function SaveStatusIndicator({ status }) {
4253
3557
  }
4254
3558
  function NotebookToolbar({
4255
3559
  notebookId,
4256
- readonly = false,
4257
3560
  autoSaveStatus,
4258
3561
  getMarkdown,
4259
- onShowHistory,
4260
- onShowCollaborators,
4261
- allowCopy = true,
4262
- allowExport = true,
4263
- allowShare = true
3562
+ allowCopy = true
4264
3563
  }) {
4265
- const [isExporting, setIsExporting] = reactExports.useState(false);
4266
- const [showMenu, setShowMenu] = reactExports.useState(false);
3564
+ const [isCopying, setIsCopying] = reactExports.useState(false);
4267
3565
  const { toast } = useToast();
4268
3566
  const { t } = useI18n("notebook");
4269
3567
  const canCopy = allowCopy && (Boolean(notebookId) || Boolean(getMarkdown));
4270
- const canExport = allowExport && Boolean(notebookId);
4271
- const canShare = allowShare && Boolean(notebookId);
4272
3568
  const resolveMarkdownContent = reactExports.useCallback(async () => {
4273
3569
  if (getMarkdown) {
4274
3570
  const content = await Promise.resolve(getMarkdown());
@@ -4277,67 +3573,9 @@ function NotebookToolbar({
4277
3573
  if (!notebookId) return "";
4278
3574
  return await getFileContent(notebookId);
4279
3575
  }, [getMarkdown, notebookId]);
4280
- const downloadBlob = reactExports.useCallback((blob, filename) => {
4281
- const url = URL.createObjectURL(blob);
4282
- try {
4283
- const link = document.createElement("a");
4284
- link.href = url;
4285
- link.download = filename;
4286
- document.body.appendChild(link);
4287
- link.click();
4288
- link.remove();
4289
- } finally {
4290
- URL.revokeObjectURL(url);
4291
- }
4292
- }, []);
4293
- const downloadFromUrl = reactExports.useCallback((url, filename) => {
4294
- const link = document.createElement("a");
4295
- link.href = url;
4296
- link.download = filename;
4297
- link.target = "_blank";
4298
- link.rel = "noreferrer";
4299
- document.body.appendChild(link);
4300
- link.click();
4301
- link.remove();
4302
- }, []);
4303
- const handleExport = reactExports.useCallback(
4304
- async (format) => {
4305
- if (!notebookId) return;
4306
- setIsExporting(true);
4307
- setShowMenu(false);
4308
- try {
4309
- const result = await exportNotebook(notebookId, format);
4310
- const filename = result.filename || `notebook.${format}`;
4311
- if (format === "pdf") {
4312
- if (!result.downloadUrl) {
4313
- throw new Error("Missing download URL for PDF export");
4314
- }
4315
- downloadFromUrl(result.downloadUrl, filename);
4316
- } else {
4317
- const mimeType = format === "markdown" ? "text/markdown" : "text/html";
4318
- const content = result.content ?? "";
4319
- downloadBlob(new Blob([content], { type: mimeType }), filename);
4320
- }
4321
- toast({
4322
- title: t("export_ready_title"),
4323
- description: t("export_ready_desc", { filename }),
4324
- variant: "success"
4325
- });
4326
- } catch (error) {
4327
- console.error("[NotebookToolbar] Export failed:", error);
4328
- toast({
4329
- title: t("export_failed_title"),
4330
- description: t("try_again"),
4331
- variant: "destructive"
4332
- });
4333
- } finally {
4334
- setIsExporting(false);
4335
- }
4336
- },
4337
- [downloadBlob, downloadFromUrl, notebookId, t, toast]
4338
- );
4339
3576
  const handleCopy = reactExports.useCallback(async () => {
4340
3577
  if (!canCopy) return;
3578
+ setIsCopying(true);
4341
3579
  try {
4342
3580
  const markdown = await resolveMarkdownContent();
4343
3581
  if (navigator?.clipboard?.writeText) {
@@ -4365,1327 +3603,23 @@ function NotebookToolbar({
4365
3603
  description: t("try_again"),
4366
3604
  variant: "destructive"
4367
3605
  });
3606
+ } finally {
3607
+ setIsCopying(false);
4368
3608
  }
4369
3609
  }, [canCopy, resolveMarkdownContent, t, toast]);
4370
- const handleShare = reactExports.useCallback(() => {
4371
- console.log(`[NotebookToolbar] Share notebook ${notebookId}`);
4372
- }, [notebookId]);
4373
- const handleHistory = reactExports.useCallback(() => {
4374
- onShowHistory?.();
4375
- }, [onShowHistory]);
4376
- const handleCollaborators = reactExports.useCallback(() => {
4377
- onShowCollaborators?.();
4378
- }, [onShowCollaborators]);
4379
- const handleMoreOptions = reactExports.useCallback(() => {
4380
- toast({
4381
- title: t("more_options_title"),
4382
- description: t("more_options_desc")
4383
- });
4384
- }, [t, toast]);
4385
3610
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "notebook-toolbar flex items-center justify-between px-4 py-2 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60", children: [
4386
3611
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SaveStatusIndicator, { status: autoSaveStatus }) }),
4387
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
4388
- canCopy ? /* @__PURE__ */ jsxRuntimeExports.jsx(
4389
- "button",
4390
- {
4391
- type: "button",
4392
- className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors",
4393
- onClick: handleCopy,
4394
- title: t("copy"),
4395
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-4 h-4" })
4396
- }
4397
- ) : null,
4398
- onShowCollaborators ? /* @__PURE__ */ jsxRuntimeExports.jsx(
4399
- "button",
4400
- {
4401
- type: "button",
4402
- className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors",
4403
- onClick: handleCollaborators,
4404
- title: t("collaborators"),
4405
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Users, { className: "w-4 h-4" })
4406
- }
4407
- ) : null,
4408
- onShowHistory ? /* @__PURE__ */ jsxRuntimeExports.jsx(
4409
- "button",
4410
- {
4411
- type: "button",
4412
- className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors",
4413
- onClick: handleHistory,
4414
- title: t("history_title"),
4415
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(History, { className: "w-4 h-4" })
4416
- }
4417
- ) : null,
4418
- canExport ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Popover, { open: showMenu, onOpenChange: setShowMenu, children: [
4419
- /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
4420
- "button",
4421
- {
4422
- type: "button",
4423
- className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors",
4424
- disabled: isExporting,
4425
- title: t("export"),
4426
- children: isExporting ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-4 h-4 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "w-4 h-4" })
4427
- }
4428
- ) }),
4429
- /* @__PURE__ */ jsxRuntimeExports.jsxs(PopoverContent, { align: "end", className: "w-40 p-1", children: [
4430
- /* @__PURE__ */ jsxRuntimeExports.jsx(
4431
- "button",
4432
- {
4433
- type: "button",
4434
- className: "w-full px-3 py-1.5 text-left text-sm hover:bg-muted transition-colors",
4435
- onClick: () => handleExport("markdown"),
4436
- children: t("export_as_markdown")
4437
- }
4438
- ),
4439
- /* @__PURE__ */ jsxRuntimeExports.jsx(
4440
- "button",
4441
- {
4442
- type: "button",
4443
- className: "w-full px-3 py-1.5 text-left text-sm hover:bg-muted transition-colors",
4444
- onClick: () => handleExport("html"),
4445
- children: t("export_as_html")
4446
- }
4447
- ),
4448
- /* @__PURE__ */ jsxRuntimeExports.jsx(
4449
- "button",
4450
- {
4451
- type: "button",
4452
- className: "w-full px-3 py-1.5 text-left text-sm hover:bg-muted transition-colors",
4453
- onClick: () => handleExport("pdf"),
4454
- children: t("export_as_pdf")
4455
- }
4456
- )
4457
- ] })
4458
- ] }) : null,
4459
- canShare ? /* @__PURE__ */ jsxRuntimeExports.jsx(
4460
- "button",
4461
- {
4462
- type: "button",
4463
- className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors",
4464
- onClick: handleShare,
4465
- title: t("share"),
4466
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Share, { className: "w-4 h-4" })
4467
- }
4468
- ) : null,
4469
- /* @__PURE__ */ jsxRuntimeExports.jsx(
4470
- "button",
4471
- {
4472
- type: "button",
4473
- className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors",
4474
- onClick: handleMoreOptions,
4475
- title: t("more_options_title"),
4476
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Ellipsis, { className: "w-4 h-4" })
4477
- }
4478
- )
4479
- ] })
4480
- ] });
4481
- }
4482
-
4483
- const formatDistanceLocale = {
4484
- lessThanXSeconds: {
4485
- one: "不到 1 秒",
4486
- other: "不到 {{count}} 秒",
4487
- },
4488
-
4489
- xSeconds: {
4490
- one: "1 秒",
4491
- other: "{{count}} 秒",
4492
- },
4493
-
4494
- halfAMinute: "半分钟",
4495
-
4496
- lessThanXMinutes: {
4497
- one: "不到 1 分钟",
4498
- other: "不到 {{count}} 分钟",
4499
- },
4500
-
4501
- xMinutes: {
4502
- one: "1 分钟",
4503
- other: "{{count}} 分钟",
4504
- },
4505
-
4506
- xHours: {
4507
- one: "1 小时",
4508
- other: "{{count}} 小时",
4509
- },
4510
-
4511
- aboutXHours: {
4512
- one: "大约 1 小时",
4513
- other: "大约 {{count}} 小时",
4514
- },
4515
-
4516
- xDays: {
4517
- one: "1 天",
4518
- other: "{{count}} 天",
4519
- },
4520
-
4521
- aboutXWeeks: {
4522
- one: "大约 1 个星期",
4523
- other: "大约 {{count}} 个星期",
4524
- },
4525
-
4526
- xWeeks: {
4527
- one: "1 个星期",
4528
- other: "{{count}} 个星期",
4529
- },
4530
-
4531
- aboutXMonths: {
4532
- one: "大约 1 个月",
4533
- other: "大约 {{count}} 个月",
4534
- },
4535
-
4536
- xMonths: {
4537
- one: "1 个月",
4538
- other: "{{count}} 个月",
4539
- },
4540
-
4541
- aboutXYears: {
4542
- one: "大约 1 年",
4543
- other: "大约 {{count}} 年",
4544
- },
4545
-
4546
- xYears: {
4547
- one: "1 年",
4548
- other: "{{count}} 年",
4549
- },
4550
-
4551
- overXYears: {
4552
- one: "超过 1 年",
4553
- other: "超过 {{count}} 年",
4554
- },
4555
-
4556
- almostXYears: {
4557
- one: "将近 1 年",
4558
- other: "将近 {{count}} 年",
4559
- },
4560
- };
4561
-
4562
- const formatDistance = (token, count, options) => {
4563
- let result;
4564
-
4565
- const tokenValue = formatDistanceLocale[token];
4566
- if (typeof tokenValue === "string") {
4567
- result = tokenValue;
4568
- } else if (count === 1) {
4569
- result = tokenValue.one;
4570
- } else {
4571
- result = tokenValue.other.replace("{{count}}", String(count));
4572
- }
4573
-
4574
- if (options?.addSuffix) {
4575
- if (options.comparison && options.comparison > 0) {
4576
- return result + "内";
4577
- } else {
4578
- return result + "前";
4579
- }
4580
- }
4581
-
4582
- return result;
4583
- };
4584
-
4585
- const dateFormats = {
4586
- full: "y'年'M'月'd'日' EEEE",
4587
- long: "y'年'M'月'd'日'",
4588
- medium: "yyyy-MM-dd",
4589
- short: "yy-MM-dd",
4590
- };
4591
-
4592
- const timeFormats = {
4593
- full: "zzzz a h:mm:ss",
4594
- long: "z a h:mm:ss",
4595
- medium: "a h:mm:ss",
4596
- short: "a h:mm",
4597
- };
4598
-
4599
- const dateTimeFormats = {
4600
- full: "{{date}} {{time}}",
4601
- long: "{{date}} {{time}}",
4602
- medium: "{{date}} {{time}}",
4603
- short: "{{date}} {{time}}",
4604
- };
4605
-
4606
- const formatLong = {
4607
- date: buildFormatLongFn({
4608
- formats: dateFormats,
4609
- defaultWidth: "full",
4610
- }),
4611
-
4612
- time: buildFormatLongFn({
4613
- formats: timeFormats,
4614
- defaultWidth: "full",
4615
- }),
4616
-
4617
- dateTime: buildFormatLongFn({
4618
- formats: dateTimeFormats,
4619
- defaultWidth: "full",
4620
- }),
4621
- };
4622
-
4623
- function checkWeek(date, baseDate, options) {
4624
- const baseFormat = "eeee p";
4625
-
4626
- if (isSameWeek(date, baseDate, options)) {
4627
- return baseFormat; // in same week
4628
- } else if (date.getTime() > baseDate.getTime()) {
4629
- return "'下个'" + baseFormat; // in next week
4630
- }
4631
- return "'上个'" + baseFormat; // in last week
4632
- }
4633
-
4634
- const formatRelativeLocale = {
4635
- lastWeek: checkWeek, // days before yesterday, maybe in this week or last week
4636
- yesterday: "'昨天' p",
4637
- today: "'今天' p",
4638
- tomorrow: "'明天' p",
4639
- nextWeek: checkWeek, // days after tomorrow, maybe in this week or next week
4640
- other: "PP p",
4641
- };
4642
-
4643
- const formatRelative = (token, date, baseDate, options) => {
4644
- const format = formatRelativeLocale[token];
4645
-
4646
- if (typeof format === "function") {
4647
- return format(date, baseDate, options);
4648
- }
4649
-
4650
- return format;
4651
- };
4652
-
4653
- const eraValues = {
4654
- narrow: ["前", "公元"],
4655
- abbreviated: ["前", "公元"],
4656
- wide: ["公元前", "公元"],
4657
- };
4658
-
4659
- const quarterValues = {
4660
- narrow: ["1", "2", "3", "4"],
4661
- abbreviated: ["第一季", "第二季", "第三季", "第四季"],
4662
- wide: ["第一季度", "第二季度", "第三季度", "第四季度"],
4663
- };
4664
-
4665
- const monthValues = {
4666
- narrow: [
4667
- "一",
4668
- "二",
4669
- "三",
4670
- "四",
4671
- "五",
4672
- "六",
4673
- "七",
4674
- "八",
4675
- "九",
4676
- "十",
4677
- "十一",
4678
- "十二",
4679
- ],
4680
-
4681
- abbreviated: [
4682
- "1月",
4683
- "2月",
4684
- "3月",
4685
- "4月",
4686
- "5月",
4687
- "6月",
4688
- "7月",
4689
- "8月",
4690
- "9月",
4691
- "10月",
4692
- "11月",
4693
- "12月",
4694
- ],
4695
-
4696
- wide: [
4697
- "一月",
4698
- "二月",
4699
- "三月",
4700
- "四月",
4701
- "五月",
4702
- "六月",
4703
- "七月",
4704
- "八月",
4705
- "九月",
4706
- "十月",
4707
- "十一月",
4708
- "十二月",
4709
- ],
4710
- };
4711
-
4712
- const dayValues = {
4713
- narrow: ["日", "一", "二", "三", "四", "五", "六"],
4714
- short: ["日", "一", "二", "三", "四", "五", "六"],
4715
- abbreviated: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
4716
-
4717
- wide: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
4718
- };
4719
-
4720
- const dayPeriodValues = {
4721
- narrow: {
4722
- am: "上",
4723
- pm: "下",
4724
- midnight: "凌晨",
4725
- noon: "午",
4726
- morning: "早",
4727
- afternoon: "下午",
4728
- evening: "晚",
4729
- night: "夜",
4730
- },
4731
- abbreviated: {
4732
- am: "上午",
4733
- pm: "下午",
4734
- midnight: "凌晨",
4735
- noon: "中午",
4736
- morning: "早晨",
4737
- afternoon: "中午",
4738
- evening: "晚上",
4739
- night: "夜间",
4740
- },
4741
- wide: {
4742
- am: "上午",
4743
- pm: "下午",
4744
- midnight: "凌晨",
4745
- noon: "中午",
4746
- morning: "早晨",
4747
- afternoon: "中午",
4748
- evening: "晚上",
4749
- night: "夜间",
4750
- },
4751
- };
4752
-
4753
- const formattingDayPeriodValues = {
4754
- narrow: {
4755
- am: "上",
4756
- pm: "下",
4757
- midnight: "凌晨",
4758
- noon: "午",
4759
- morning: "早",
4760
- afternoon: "下午",
4761
- evening: "晚",
4762
- night: "夜",
4763
- },
4764
- abbreviated: {
4765
- am: "上午",
4766
- pm: "下午",
4767
- midnight: "凌晨",
4768
- noon: "中午",
4769
- morning: "早晨",
4770
- afternoon: "中午",
4771
- evening: "晚上",
4772
- night: "夜间",
4773
- },
4774
- wide: {
4775
- am: "上午",
4776
- pm: "下午",
4777
- midnight: "凌晨",
4778
- noon: "中午",
4779
- morning: "早晨",
4780
- afternoon: "中午",
4781
- evening: "晚上",
4782
- night: "夜间",
4783
- },
4784
- };
4785
-
4786
- const ordinalNumber = (dirtyNumber, options) => {
4787
- const number = Number(dirtyNumber);
4788
-
4789
- switch (options?.unit) {
4790
- case "date":
4791
- return number.toString() + "日";
4792
- case "hour":
4793
- return number.toString() + "时";
4794
- case "minute":
4795
- return number.toString() + "分";
4796
- case "second":
4797
- return number.toString() + "秒";
4798
- default:
4799
- return "第 " + number.toString();
4800
- }
4801
- };
4802
-
4803
- const localize = {
4804
- ordinalNumber,
4805
-
4806
- era: buildLocalizeFn({
4807
- values: eraValues,
4808
- defaultWidth: "wide",
4809
- }),
4810
-
4811
- quarter: buildLocalizeFn({
4812
- values: quarterValues,
4813
- defaultWidth: "wide",
4814
- argumentCallback: (quarter) => quarter - 1,
4815
- }),
4816
-
4817
- month: buildLocalizeFn({
4818
- values: monthValues,
4819
- defaultWidth: "wide",
4820
- }),
4821
-
4822
- day: buildLocalizeFn({
4823
- values: dayValues,
4824
- defaultWidth: "wide",
4825
- }),
4826
-
4827
- dayPeriod: buildLocalizeFn({
4828
- values: dayPeriodValues,
4829
- defaultWidth: "wide",
4830
- formattingValues: formattingDayPeriodValues,
4831
- defaultFormattingWidth: "wide",
4832
- }),
4833
- };
4834
-
4835
- const matchOrdinalNumberPattern = /^(第\s*)?\d+(日|时|分|秒)?/i;
4836
- const parseOrdinalNumberPattern = /\d+/i;
4837
-
4838
- const matchEraPatterns = {
4839
- narrow: /^(前)/i,
4840
- abbreviated: /^(前)/i,
4841
- wide: /^(公元前|公元)/i,
4842
- };
4843
- const parseEraPatterns = {
4844
- any: [/^(前)/i, /^(公元)/i],
4845
- };
4846
-
4847
- const matchQuarterPatterns = {
4848
- narrow: /^[1234]/i,
4849
- abbreviated: /^第[一二三四]刻/i,
4850
- wide: /^第[一二三四]刻钟/i,
4851
- };
4852
- const parseQuarterPatterns = {
4853
- any: [/(1|一)/i, /(2|二)/i, /(3|三)/i, /(4|四)/i],
4854
- };
4855
-
4856
- const matchMonthPatterns = {
4857
- narrow: /^(一|二|三|四|五|六|七|八|九|十[二一])/i,
4858
- abbreviated: /^(一|二|三|四|五|六|七|八|九|十[二一]|\d|1[12])月/i,
4859
- wide: /^(一|二|三|四|五|六|七|八|九|十[二一])月/i,
4860
- };
4861
- const parseMonthPatterns = {
4862
- narrow: [
4863
- /^一/i,
4864
- /^二/i,
4865
- /^三/i,
4866
- /^四/i,
4867
- /^五/i,
4868
- /^六/i,
4869
- /^七/i,
4870
- /^八/i,
4871
- /^九/i,
4872
- /^十(?!(一|二))/i,
4873
- /^十一/i,
4874
- /^十二/i,
4875
- ],
4876
-
4877
- any: [
4878
- /^一|1/i,
4879
- /^二|2/i,
4880
- /^三|3/i,
4881
- /^四|4/i,
4882
- /^五|5/i,
4883
- /^六|6/i,
4884
- /^七|7/i,
4885
- /^八|8/i,
4886
- /^九|9/i,
4887
- /^十(?!(一|二))|10/i,
4888
- /^十一|11/i,
4889
- /^十二|12/i,
4890
- ],
4891
- };
4892
-
4893
- const matchDayPatterns = {
4894
- narrow: /^[一二三四五六日]/i,
4895
- short: /^[一二三四五六日]/i,
4896
- abbreviated: /^周[一二三四五六日]/i,
4897
- wide: /^星期[一二三四五六日]/i,
4898
- };
4899
- const parseDayPatterns = {
4900
- any: [/日/i, /一/i, /二/i, /三/i, /四/i, /五/i, /六/i],
4901
- };
4902
-
4903
- const matchDayPeriodPatterns = {
4904
- any: /^(上午?|下午?|午夜|[中正]午|早上?|下午|晚上?|凌晨|)/i,
4905
- };
4906
- const parseDayPeriodPatterns = {
4907
- any: {
4908
- am: /^上午?/i,
4909
- pm: /^下午?/i,
4910
- midnight: /^午夜/i,
4911
- noon: /^[中正]午/i,
4912
- morning: /^早上/i,
4913
- afternoon: /^下午/i,
4914
- evening: /^晚上?/i,
4915
- night: /^凌晨/i,
4916
- },
4917
- };
4918
-
4919
- const match = {
4920
- ordinalNumber: buildMatchPatternFn({
4921
- matchPattern: matchOrdinalNumberPattern,
4922
- parsePattern: parseOrdinalNumberPattern,
4923
- valueCallback: (value) => parseInt(value, 10),
4924
- }),
4925
-
4926
- era: buildMatchFn({
4927
- matchPatterns: matchEraPatterns,
4928
- defaultMatchWidth: "wide",
4929
- parsePatterns: parseEraPatterns,
4930
- defaultParseWidth: "any",
4931
- }),
4932
-
4933
- quarter: buildMatchFn({
4934
- matchPatterns: matchQuarterPatterns,
4935
- defaultMatchWidth: "wide",
4936
- parsePatterns: parseQuarterPatterns,
4937
- defaultParseWidth: "any",
4938
- valueCallback: (index) => index + 1,
4939
- }),
4940
-
4941
- month: buildMatchFn({
4942
- matchPatterns: matchMonthPatterns,
4943
- defaultMatchWidth: "wide",
4944
- parsePatterns: parseMonthPatterns,
4945
- defaultParseWidth: "any",
4946
- }),
4947
-
4948
- day: buildMatchFn({
4949
- matchPatterns: matchDayPatterns,
4950
- defaultMatchWidth: "wide",
4951
- parsePatterns: parseDayPatterns,
4952
- defaultParseWidth: "any",
4953
- }),
4954
-
4955
- dayPeriod: buildMatchFn({
4956
- matchPatterns: matchDayPeriodPatterns,
4957
- defaultMatchWidth: "any",
4958
- parsePatterns: parseDayPeriodPatterns,
4959
- defaultParseWidth: "any",
4960
- }),
4961
- };
4962
-
4963
- /**
4964
- * @category Locales
4965
- * @summary Chinese Simplified locale.
4966
- * @language Chinese Simplified
4967
- * @iso-639-2 zho
4968
- * @author Changyu Geng [@KingMario](https://github.com/KingMario)
4969
- * @author Song Shuoyun [@fnlctrl](https://github.com/fnlctrl)
4970
- * @author sabrinaM [@sabrinamiao](https://github.com/sabrinamiao)
4971
- * @author Carney Wu [@cubicwork](https://github.com/cubicwork)
4972
- * @author Terrence Lam [@skyuplam](https://github.com/skyuplam)
4973
- */
4974
- const zhCN = {
4975
- code: "zh-CN",
4976
- formatDistance: formatDistance,
4977
- formatLong: formatLong,
4978
- formatRelative: formatRelative,
4979
- localize: localize,
4980
- match: match,
4981
- options: {
4982
- weekStartsOn: 1 /* Monday */,
4983
- firstWeekContainsDate: 4,
4984
- },
4985
- };
4986
-
4987
- function diffMarkdown(oldMarkdown, newMarkdown) {
4988
- if (oldMarkdown === newMarkdown) {
4989
- return { patches: [] };
4990
- }
4991
- return {
4992
- patches: [
3612
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-1", children: canCopy ? /* @__PURE__ */ jsxRuntimeExports.jsx(
3613
+ "button",
4993
3614
  {
4994
- op: "replace",
4995
- before: oldMarkdown,
4996
- after: newMarkdown
4997
- }
4998
- ]
4999
- };
5000
- }
5001
-
5002
- function safeDate(value) {
5003
- const d = new Date(value);
5004
- return Number.isFinite(d.getTime()) ? d : null;
5005
- }
5006
- function extractPatchOps(payload) {
5007
- if (!payload) return [];
5008
- if (Array.isArray(payload)) return payload;
5009
- if (Array.isArray(payload?.ops)) return payload.ops;
5010
- return [];
5011
- }
5012
- function commitLabel(commit, fallbackLabels) {
5013
- if (commit.authorType === "llm") return commit.authorLabel || fallbackLabels.copilot;
5014
- if (commit.authorType === "system") return commit.authorLabel || fallbackLabels.system;
5015
- return commit.authorName || fallbackLabels.user;
5016
- }
5017
- function NotebookHistoryDialog(props) {
5018
- const { open, onOpenChange, notebookId, editor, readonly } = props;
5019
- const queryClient = useQueryClient();
5020
- const { t, language } = useI18n("notebook");
5021
- const [selectedSeq, setSelectedSeq] = reactExports.useState(null);
5022
- const [message, setMessage] = reactExports.useState("");
5023
- const baselineMarkdownRef = reactExports.useRef(null);
5024
- const distanceLocale = language === "zh-CN" ? zhCN : enUS;
5025
- const authorFallbackLabels = reactExports.useMemo(
5026
- () => ({
5027
- copilot: t("history_commit_author_copilot"),
5028
- system: t("history_commit_author_system"),
5029
- user: t("history_commit_author_user")
5030
- }),
5031
- [t]
5032
- );
5033
- const commitsQuery = useQuery({
5034
- queryKey: ["notebookCommits", notebookId],
5035
- queryFn: async () => listNotebookCommits(notebookId, { skip: 0, limit: 50 }),
5036
- enabled: open && Boolean(notebookId)
5037
- });
5038
- const commits = reactExports.useMemo(
5039
- () => commitsQuery.data?.items ?? [],
5040
- [commitsQuery.data?.items]
5041
- );
5042
- reactExports.useEffect(() => {
5043
- if (!open) return;
5044
- if (!selectedSeq && commits.length > 0) {
5045
- setSelectedSeq(commits[0].seq);
5046
- }
5047
- }, [open, commits, selectedSeq]);
5048
- reactExports.useEffect(() => {
5049
- if (!open) return;
5050
- if (!editor) return;
5051
- if (baselineMarkdownRef.current) return;
5052
- const markdown = getEditorMarkdown(editor);
5053
- baselineMarkdownRef.current = markdown;
5054
- }, [open, editor]);
5055
- const selected = reactExports.useMemo(
5056
- () => selectedSeq != null ? commits.find((c) => c.seq === selectedSeq) ?? null : null,
5057
- [commits, selectedSeq]
5058
- );
5059
- const saveMutation = useMutation({
5060
- mutationFn: async () => {
5061
- if (!editor) throw new Error("Notebook editor is not ready");
5062
- const currentMarkdown = getEditorMarkdown(editor);
5063
- const baseline = baselineMarkdownRef.current ?? currentMarkdown;
5064
- const { patches } = diffMarkdown(baseline, currentMarkdown);
5065
- const stats = patches.reduce(
5066
- (acc, op) => {
5067
- if (op.op === "replace") acc.replaced += 1;
5068
- else if (op.op === "insert") acc.inserted += 1;
5069
- else if (op.op === "delete") acc.deleted += 1;
5070
- return acc;
5071
- },
5072
- { replaced: 0, inserted: 0, deleted: 0 }
5073
- );
5074
- const payload = await createNotebookCommit(notebookId, {
5075
- message: message.trim() ? message.trim() : t("history_save_version_default"),
5076
- authorType: "human",
5077
- opStats: { ...stats, totalOps: patches.length },
5078
- patchOps: { ops: patches },
5079
- meta: { source: "manual-save" }
5080
- });
5081
- baselineMarkdownRef.current = currentMarkdown;
5082
- return payload;
5083
- },
5084
- onSuccess: () => {
5085
- setMessage("");
5086
- queryClient.invalidateQueries({ queryKey: ["notebookCommits", notebookId] });
5087
- }
5088
- });
5089
- const revertMutation = useMutation({
5090
- mutationFn: async (seq) => {
5091
- return revertNotebookToCommit(notebookId, seq);
5092
- },
5093
- onSuccess: () => {
5094
- queryClient.invalidateQueries({ queryKey: ["notebookCommits", notebookId] });
5095
- }
5096
- });
5097
- const onSave = reactExports.useCallback(() => {
5098
- if (readonly) return;
5099
- saveMutation.mutate();
5100
- }, [readonly, saveMutation]);
5101
- const onRevert = reactExports.useCallback(
5102
- (seq) => {
5103
- if (readonly) return;
5104
- const ok = window.confirm(t("history_revert_confirm", { seq }));
5105
- if (!ok) return;
5106
- revertMutation.mutate(seq);
5107
- },
5108
- [readonly, revertMutation, t]
5109
- );
5110
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntimeExports.jsx(DialogContent, { className: "sm:max-w-4xl p-0 overflow-hidden", showCloseButton: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-[70vh] flex-col", children: [
5111
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-6 pt-6 pb-4 border-b dark:border-white/10", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [
5112
- /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
5113
- /* @__PURE__ */ jsxRuntimeExports.jsx(History, { className: "h-4 w-4" }),
5114
- t("history_title")
5115
- ] }),
5116
- /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { className: "text-left", children: t("history_desc") })
5117
- ] }) }),
5118
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 grid grid-cols-1 md:grid-cols-[320px_1fr] min-h-0", children: [
5119
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-b md:border-b-0 md:border-r dark:border-white/10 min-h-0", children: [
5120
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-3 flex items-center justify-between", children: [
5121
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-medium text-foreground/90", children: t("history_commits") }),
5122
- /* @__PURE__ */ jsxRuntimeExports.jsx(
5123
- Button,
5124
- {
5125
- variant: "ghost",
5126
- size: "sm",
5127
- onClick: () => commitsQuery.refetch(),
5128
- disabled: commitsQuery.isFetching,
5129
- title: t("history_refresh"),
5130
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCcw, { className: cn("h-4 w-4", commitsQuery.isFetching && "animate-spin") })
5131
- }
5132
- )
5133
- ] }),
5134
- /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, {}),
5135
- /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 space-y-1", children: commitsQuery.isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3 text-sm text-muted-foreground", children: t("history_loading") }) : commits.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3 text-sm text-muted-foreground", children: t("history_empty") }) : commits.map((c) => {
5136
- const d = safeDate(c.createdAt);
5137
- const subtitle = d ? formatDistanceToNow(d, { addSuffix: true, locale: distanceLocale }) : "";
5138
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(
5139
- "button",
5140
- {
5141
- type: "button",
5142
- className: cn(
5143
- "w-full text-left rounded-md px-3 py-2 transition-colors",
5144
- selectedSeq === c.seq ? "bg-muted" : "hover:bg-muted/60 text-foreground/90"
5145
- ),
5146
- onClick: () => setSelectedSeq(c.seq),
5147
- children: [
5148
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
5149
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-medium", children: t("history_commit", { seq: c.seq }) }),
5150
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: subtitle })
5151
- ] }),
5152
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-0.5 text-xs text-muted-foreground line-clamp-1", children: [
5153
- commitLabel(c, authorFallbackLabels),
5154
- " • ",
5155
- c.message || t("history_no_message")
5156
- ] }),
5157
- c.opStats ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 text-[11px] text-muted-foreground", children: [
5158
- c.opStats?.replaced != null ? `R:${c.opStats.replaced}` : null,
5159
- c.opStats?.inserted != null ? `I:${c.opStats.inserted}` : null,
5160
- c.opStats?.deleted != null ? `D:${c.opStats.deleted}` : null
5161
- ].filter(Boolean).join(" ") }) : null
5162
- ]
5163
- },
5164
- c.id
5165
- );
5166
- }) }) })
5167
- ] }),
5168
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-h-0 flex flex-col", children: [
5169
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-3 flex items-center justify-between gap-2", children: [
5170
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-medium text-foreground/90", children: selected ? t("history_commit", { seq: selected.seq }) : t("history_select_commit") }),
5171
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
5172
- /* @__PURE__ */ jsxRuntimeExports.jsx(
5173
- Input,
5174
- {
5175
- value: message,
5176
- onChange: (e) => setMessage(e.target.value),
5177
- placeholder: readonly ? t("collaborators_readonly") : t("history_commit_message_placeholder"),
5178
- disabled: readonly,
5179
- className: "w-64"
5180
- }
5181
- ),
5182
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
5183
- Button,
5184
- {
5185
- onClick: onSave,
5186
- disabled: readonly || saveMutation.isPending,
5187
- title: t("history_save_version"),
5188
- children: [
5189
- /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { className: "h-4 w-4 mr-1.5" }),
5190
- t("history_save")
5191
- ]
5192
- }
5193
- )
5194
- ] })
5195
- ] }),
5196
- /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, {}),
5197
- /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 space-y-4", children: !selected ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground", children: t("history_pick_from_list") }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
5198
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
5199
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm", children: [
5200
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-medium", children: [
5201
- t("history_author"),
5202
- ":"
5203
- ] }),
5204
- " ",
5205
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: commitLabel(selected, authorFallbackLabels) }),
5206
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground", children: [
5207
- " ",
5208
- "(",
5209
- selected.authorType,
5210
- ")"
5211
- ] })
5212
- ] }),
5213
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm", children: [
5214
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-medium", children: [
5215
- t("history_message"),
5216
- ":"
5217
- ] }),
5218
- " ",
5219
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: selected.message || t("history_no_message") })
5220
- ] }),
5221
- selected.opStats ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm", children: [
5222
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-medium", children: [
5223
- t("history_stats"),
5224
- ":"
5225
- ] }),
5226
- " ",
5227
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: JSON.stringify(selected.opStats) })
5228
- ] }) : null
5229
- ] }),
5230
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
5231
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
5232
- Button,
5233
- {
5234
- variant: "outline",
5235
- onClick: () => onRevert(selected.seq),
5236
- disabled: readonly || revertMutation.isPending,
5237
- children: [
5238
- /* @__PURE__ */ jsxRuntimeExports.jsx(Undo2, { className: "h-4 w-4 mr-1.5" }),
5239
- t("history_revert_to_this")
5240
- ]
5241
- }
5242
- ),
5243
- revertMutation.isError ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-destructive", children: revertMutation.error?.message || t("history_revert_failed") }) : null
5244
- ] }),
5245
- /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, {}),
5246
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
5247
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-medium mb-2", children: t("history_patch_ops") }),
5248
- extractPatchOps(selected.patchOps).length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground", children: t("history_patch_empty") }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: extractPatchOps(selected.patchOps).map((op, idx) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border dark:border-white/10 p-3", children: [
5249
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-muted-foreground", children: [
5250
- op?.op || "op",
5251
- " ",
5252
- op?.id ? `• ${op.id}` : ""
5253
- ] }),
5254
- op?.after ? /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "mt-2 text-xs whitespace-pre-wrap", children: String(op.after) }) : op?.before ? /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "mt-2 text-xs whitespace-pre-wrap", children: String(op.before) }) : op?.content ? /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "mt-2 text-xs whitespace-pre-wrap", children: String(op.content) }) : op?.block?.content ? /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "mt-2 text-xs whitespace-pre-wrap", children: String(op.block.content) }) : null
5255
- ] }, idx)) })
5256
- ] })
5257
- ] }) }) })
5258
- ] })
5259
- ] })
5260
- ] }) }) });
5261
- }
5262
-
5263
- // src/create-context.tsx
5264
- function createContextScope(scopeName, createContextScopeDeps = []) {
5265
- let defaultContexts = [];
5266
- function createContext3(rootComponentName, defaultContext) {
5267
- const BaseContext = reactExports.createContext(defaultContext);
5268
- BaseContext.displayName = rootComponentName + "Context";
5269
- const index = defaultContexts.length;
5270
- defaultContexts = [...defaultContexts, defaultContext];
5271
- const Provider = (props) => {
5272
- const { scope, children, ...context } = props;
5273
- const Context = scope?.[scopeName]?.[index] || BaseContext;
5274
- const value = reactExports.useMemo(() => context, Object.values(context));
5275
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Context.Provider, { value, children });
5276
- };
5277
- Provider.displayName = rootComponentName + "Provider";
5278
- function useContext2(consumerName, scope) {
5279
- const Context = scope?.[scopeName]?.[index] || BaseContext;
5280
- const context = reactExports.useContext(Context);
5281
- if (context) return context;
5282
- if (defaultContext !== void 0) return defaultContext;
5283
- throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``);
5284
- }
5285
- return [Provider, useContext2];
5286
- }
5287
- const createScope = () => {
5288
- const scopeContexts = defaultContexts.map((defaultContext) => {
5289
- return reactExports.createContext(defaultContext);
5290
- });
5291
- return function useScope(scope) {
5292
- const contexts = scope?.[scopeName] || scopeContexts;
5293
- return reactExports.useMemo(
5294
- () => ({ [`__scope${scopeName}`]: { ...scope, [scopeName]: contexts } }),
5295
- [scope, contexts]
5296
- );
5297
- };
5298
- };
5299
- createScope.scopeName = scopeName;
5300
- return [createContext3, composeContextScopes(createScope, ...createContextScopeDeps)];
5301
- }
5302
- function composeContextScopes(...scopes) {
5303
- const baseScope = scopes[0];
5304
- if (scopes.length === 1) return baseScope;
5305
- const createScope = () => {
5306
- const scopeHooks = scopes.map((createScope2) => ({
5307
- useScope: createScope2(),
5308
- scopeName: createScope2.scopeName
5309
- }));
5310
- return function useComposedScopes(overrideScopes) {
5311
- const nextScopes = scopeHooks.reduce((nextScopes2, { useScope, scopeName }) => {
5312
- const scopeProps = useScope(overrideScopes);
5313
- const currentScope = scopeProps[`__scope${scopeName}`];
5314
- return { ...nextScopes2, ...currentScope };
5315
- }, {});
5316
- return reactExports.useMemo(() => ({ [`__scope${baseScope.scopeName}`]: nextScopes }), [nextScopes]);
5317
- };
5318
- };
5319
- createScope.scopeName = baseScope.scopeName;
5320
- return createScope;
5321
- }
5322
-
5323
- // src/use-is-hydrated.tsx
5324
- function useIsHydrated() {
5325
- return shimExports.useSyncExternalStore(
5326
- subscribe,
5327
- () => true,
5328
- () => false
5329
- );
5330
- }
5331
- function subscribe() {
5332
- return () => {
5333
- };
5334
- }
5335
-
5336
- var AVATAR_NAME = "Avatar";
5337
- var [createAvatarContext] = createContextScope(AVATAR_NAME);
5338
- var [AvatarProvider, useAvatarContext] = createAvatarContext(AVATAR_NAME);
5339
- var Avatar$1 = reactExports.forwardRef(
5340
- (props, forwardedRef) => {
5341
- const { __scopeAvatar, ...avatarProps } = props;
5342
- const [imageLoadingStatus, setImageLoadingStatus] = reactExports.useState("idle");
5343
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
5344
- AvatarProvider,
5345
- {
5346
- scope: __scopeAvatar,
5347
- imageLoadingStatus,
5348
- onImageLoadingStatusChange: setImageLoadingStatus,
5349
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.span, { ...avatarProps, ref: forwardedRef })
5350
- }
5351
- );
5352
- }
5353
- );
5354
- Avatar$1.displayName = AVATAR_NAME;
5355
- var IMAGE_NAME = "AvatarImage";
5356
- var AvatarImage$1 = reactExports.forwardRef(
5357
- (props, forwardedRef) => {
5358
- const { __scopeAvatar, src, onLoadingStatusChange = () => {
5359
- }, ...imageProps } = props;
5360
- const context = useAvatarContext(IMAGE_NAME, __scopeAvatar);
5361
- const imageLoadingStatus = useImageLoadingStatus(src, imageProps);
5362
- const handleLoadingStatusChange = useCallbackRef((status) => {
5363
- onLoadingStatusChange(status);
5364
- context.onImageLoadingStatusChange(status);
5365
- });
5366
- useLayoutEffect2(() => {
5367
- if (imageLoadingStatus !== "idle") {
5368
- handleLoadingStatusChange(imageLoadingStatus);
5369
- }
5370
- }, [imageLoadingStatus, handleLoadingStatusChange]);
5371
- return imageLoadingStatus === "loaded" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.img, { ...imageProps, ref: forwardedRef, src }) : null;
5372
- }
5373
- );
5374
- AvatarImage$1.displayName = IMAGE_NAME;
5375
- var FALLBACK_NAME = "AvatarFallback";
5376
- var AvatarFallback$1 = reactExports.forwardRef(
5377
- (props, forwardedRef) => {
5378
- const { __scopeAvatar, delayMs, ...fallbackProps } = props;
5379
- const context = useAvatarContext(FALLBACK_NAME, __scopeAvatar);
5380
- const [canRender, setCanRender] = reactExports.useState(delayMs === void 0);
5381
- reactExports.useEffect(() => {
5382
- if (delayMs !== void 0) {
5383
- const timerId = window.setTimeout(() => setCanRender(true), delayMs);
5384
- return () => window.clearTimeout(timerId);
3615
+ type: "button",
3616
+ className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors",
3617
+ onClick: handleCopy,
3618
+ title: t("copy"),
3619
+ children: isCopying ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-4 h-4 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-4 h-4" })
5385
3620
  }
5386
- }, [delayMs]);
5387
- return canRender && context.imageLoadingStatus !== "loaded" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.span, { ...fallbackProps, ref: forwardedRef }) : null;
5388
- }
5389
- );
5390
- AvatarFallback$1.displayName = FALLBACK_NAME;
5391
- function resolveLoadingStatus(image, src) {
5392
- if (!image) {
5393
- return "idle";
5394
- }
5395
- if (!src) {
5396
- return "error";
5397
- }
5398
- if (image.src !== src) {
5399
- image.src = src;
5400
- }
5401
- return image.complete && image.naturalWidth > 0 ? "loaded" : "loading";
5402
- }
5403
- function useImageLoadingStatus(src, { referrerPolicy, crossOrigin }) {
5404
- const isHydrated = useIsHydrated();
5405
- const imageRef = reactExports.useRef(null);
5406
- const image = (() => {
5407
- if (!isHydrated) return null;
5408
- if (!imageRef.current) {
5409
- imageRef.current = new window.Image();
5410
- }
5411
- return imageRef.current;
5412
- })();
5413
- const [loadingStatus, setLoadingStatus] = reactExports.useState(
5414
- () => resolveLoadingStatus(image, src)
5415
- );
5416
- useLayoutEffect2(() => {
5417
- setLoadingStatus(resolveLoadingStatus(image, src));
5418
- }, [image, src]);
5419
- useLayoutEffect2(() => {
5420
- const updateStatus = (status) => () => {
5421
- setLoadingStatus(status);
5422
- };
5423
- if (!image) return;
5424
- const handleLoad = updateStatus("loaded");
5425
- const handleError = updateStatus("error");
5426
- image.addEventListener("load", handleLoad);
5427
- image.addEventListener("error", handleError);
5428
- if (referrerPolicy) {
5429
- image.referrerPolicy = referrerPolicy;
5430
- }
5431
- if (typeof crossOrigin === "string") {
5432
- image.crossOrigin = crossOrigin;
5433
- }
5434
- return () => {
5435
- image.removeEventListener("load", handleLoad);
5436
- image.removeEventListener("error", handleError);
5437
- };
5438
- }, [image, crossOrigin, referrerPolicy]);
5439
- return loadingStatus;
5440
- }
5441
- var Root = Avatar$1;
5442
- var Image = AvatarImage$1;
5443
- var Fallback = AvatarFallback$1;
5444
-
5445
- const Avatar = reactExports.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx(
5446
- Root,
5447
- {
5448
- ref,
5449
- className: cn(
5450
- "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
5451
- className
5452
- ),
5453
- ...props
5454
- }
5455
- ));
5456
- Avatar.displayName = Root.displayName;
5457
- const AvatarImage = reactExports.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx(
5458
- Image,
5459
- {
5460
- ref,
5461
- className: cn("aspect-square h-full w-full", className),
5462
- ...props
5463
- }
5464
- ));
5465
- AvatarImage.displayName = Image.displayName;
5466
- const AvatarFallback = reactExports.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx(
5467
- Fallback,
5468
- {
5469
- ref,
5470
- className: cn(
5471
- "flex h-full w-full items-center justify-center rounded-full bg-muted",
5472
- className
5473
- ),
5474
- ...props
5475
- }
5476
- ));
5477
- AvatarFallback.displayName = Fallback.displayName;
5478
-
5479
- function initials(name) {
5480
- const value = (name || "").trim();
5481
- if (!value) return "?";
5482
- const parts = value.split(/\s+/).slice(0, 2);
5483
- return parts.map((p) => p[0]?.toUpperCase()).join("");
5484
- }
5485
- function NotebookCollaboratorsDialog(props) {
5486
- const { open, onOpenChange, notebookId, readonly } = props;
5487
- const queryClient = useQueryClient();
5488
- const { t } = useI18n("notebook");
5489
- const [query, setQuery] = reactExports.useState("");
5490
- const [role, setRole] = reactExports.useState("editor");
5491
- const [selectedUserId, setSelectedUserId] = reactExports.useState(null);
5492
- const [userResults, setUserResults] = reactExports.useState([]);
5493
- const [searching, setSearching] = reactExports.useState(false);
5494
- const collaboratorsQuery = useQuery({
5495
- queryKey: ["notebookCollaborators", notebookId],
5496
- queryFn: async () => listNotebookCollaborators(notebookId),
5497
- enabled: open && Boolean(notebookId)
5498
- });
5499
- const collaborators = collaboratorsQuery.data ?? [];
5500
- const inviteMutation = useMutation({
5501
- mutationFn: async () => {
5502
- if (!selectedUserId) throw new Error(t("collaborators_select_user_first"));
5503
- return inviteNotebookCollaborator(notebookId, { userId: selectedUserId, role });
5504
- },
5505
- onSuccess: () => {
5506
- queryClient.invalidateQueries({ queryKey: ["notebookCollaborators", notebookId] });
5507
- setSelectedUserId(null);
5508
- setQuery("");
5509
- setUserResults([]);
5510
- }
5511
- });
5512
- const removeMutation = useMutation({
5513
- mutationFn: async (userId) => {
5514
- await removeNotebookCollaborator(notebookId, userId);
5515
- },
5516
- onSuccess: () => {
5517
- queryClient.invalidateQueries({ queryKey: ["notebookCollaborators", notebookId] });
5518
- }
5519
- });
5520
- reactExports.useEffect(() => {
5521
- if (!open) return;
5522
- const q = query.trim();
5523
- if (!q) {
5524
- setUserResults([]);
5525
- setSelectedUserId(null);
5526
- return;
5527
- }
5528
- const handle = window.setTimeout(async () => {
5529
- try {
5530
- setSearching(true);
5531
- const items = await searchUsers(q, 10);
5532
- setUserResults(items);
5533
- if (items.length === 1) setSelectedUserId(items[0].id);
5534
- } catch (e) {
5535
- setUserResults([]);
5536
- } finally {
5537
- setSearching(false);
5538
- }
5539
- }, 250);
5540
- return () => window.clearTimeout(handle);
5541
- }, [open, query]);
5542
- const selectedUser = reactExports.useMemo(
5543
- () => userResults.find((u) => u.id === selectedUserId) ?? null,
5544
- [userResults, selectedUserId]
5545
- );
5546
- const onInvite = reactExports.useCallback(() => {
5547
- if (readonly) return;
5548
- inviteMutation.mutate();
5549
- }, [readonly, inviteMutation]);
5550
- const onRemove = reactExports.useCallback(
5551
- (userId, name) => {
5552
- if (readonly) return;
5553
- const ok = window.confirm(t("collaborators_remove_confirm", { name }));
5554
- if (!ok) return;
5555
- removeMutation.mutate(userId);
5556
- },
5557
- [readonly, removeMutation, t]
5558
- );
5559
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntimeExports.jsx(DialogContent, { className: "sm:max-w-2xl p-0 overflow-hidden", showCloseButton: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-[70vh] flex-col", children: [
5560
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-6 pt-6 pb-4 border-b dark:border-white/10", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [
5561
- /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
5562
- /* @__PURE__ */ jsxRuntimeExports.jsx(Users, { className: "h-4 w-4" }),
5563
- t("collaborators")
5564
- ] }),
5565
- /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { className: "text-left", children: t("collaborators_desc") })
5566
- ] }) }),
5567
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 space-y-3", children: [
5568
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col md:flex-row gap-2 md:items-center", children: [
5569
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex-1", children: [
5570
- /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }),
5571
- /* @__PURE__ */ jsxRuntimeExports.jsx(
5572
- Input,
5573
- {
5574
- value: query,
5575
- onChange: (e) => setQuery(e.target.value),
5576
- placeholder: readonly ? t("collaborators_readonly") : t("collaborators_search_placeholder"),
5577
- disabled: readonly,
5578
- className: "pl-9"
5579
- }
5580
- ),
5581
- query.trim() ? /* @__PURE__ */ jsxRuntimeExports.jsx(
5582
- "button",
5583
- {
5584
- type: "button",
5585
- className: "absolute right-2 top-1/2 -translate-y-1/2 p-1 rounded hover:bg-muted",
5586
- onClick: () => {
5587
- setQuery("");
5588
- setSelectedUserId(null);
5589
- setUserResults([]);
5590
- },
5591
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "h-4 w-4 text-muted-foreground" })
5592
- }
5593
- ) : null
5594
- ] }),
5595
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
5596
- Select,
5597
- {
5598
- value: role,
5599
- onValueChange: (v) => setRole(v),
5600
- disabled: readonly,
5601
- children: [
5602
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "w-full md:w-40", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: t("collaborators_role") }) }),
5603
- /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
5604
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "viewer", children: t("collaborators_role_viewer") }),
5605
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "editor", children: t("collaborators_role_editor") }),
5606
- /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "owner", children: t("collaborators_role_owner") })
5607
- ] })
5608
- ]
5609
- }
5610
- ),
5611
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: onInvite, disabled: readonly || !selectedUserId || inviteMutation.isPending, children: [
5612
- /* @__PURE__ */ jsxRuntimeExports.jsx(UserPlus, { className: "h-4 w-4 mr-1.5" }),
5613
- t("collaborators_invite")
5614
- ] })
5615
- ] }),
5616
- searching ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground", children: t("collaborators_searching") }) : userResults.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border dark:border-white/10 overflow-hidden", children: [
5617
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-muted/30 px-3 py-2 text-xs text-muted-foreground", children: t("collaborators_search_results") }),
5618
- /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, {}),
5619
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-h-36 overflow-auto", children: userResults.map((u) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
5620
- "button",
5621
- {
5622
- type: "button",
5623
- className: cn(
5624
- "w-full text-left px-3 py-2 text-sm hover:bg-muted/60 transition-colors",
5625
- selectedUserId === u.id && "bg-muted"
5626
- ),
5627
- onClick: () => setSelectedUserId(u.id),
5628
- children: [
5629
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: u.username }),
5630
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: u.email })
5631
- ]
5632
- },
5633
- u.id
5634
- )) })
5635
- ] }) : query.trim() ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground", children: t("collaborators_no_users") }) : null,
5636
- inviteMutation.isError ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-destructive", children: inviteMutation.error?.message || t("collaborators_invite_failed") }) : null,
5637
- selectedUser ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-muted-foreground", children: [
5638
- t("collaborators_selected"),
5639
- ":",
5640
- " ",
5641
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-foreground/90", children: selectedUser.username }),
5642
- " (",
5643
- selectedUser.email,
5644
- ")"
5645
- ] }) : null
5646
- ] }),
5647
- /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, {}),
5648
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-h-0", children: [
5649
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-3 flex items-center justify-between", children: [
5650
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-medium text-foreground/90", children: t("collaborators_current") }),
5651
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: t("collaborators_total", { count: collaborators.length }) })
5652
- ] }),
5653
- /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, {}),
5654
- /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 space-y-1", children: collaboratorsQuery.isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3 text-sm text-muted-foreground", children: t("collaborators_loading") }) : collaborators.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3 text-sm text-muted-foreground", children: t("collaborators_empty") }) : collaborators.map((c) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
5655
- "div",
5656
- {
5657
- className: "flex items-center justify-between gap-3 rounded-md px-3 py-2 hover:bg-muted/40",
5658
- children: [
5659
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
5660
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Avatar, { className: "h-8 w-8", children: [
5661
- c.userAvatar ? /* @__PURE__ */ jsxRuntimeExports.jsx(AvatarImage, { src: c.userAvatar, alt: c.userName }) : null,
5662
- /* @__PURE__ */ jsxRuntimeExports.jsx(AvatarFallback, { children: initials(c.userName) })
5663
- ] }),
5664
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
5665
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-medium truncate", children: c.userName }),
5666
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground truncate", children: c.userEmail })
5667
- ] })
5668
- ] }),
5669
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
5670
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: c.role }),
5671
- /* @__PURE__ */ jsxRuntimeExports.jsx(
5672
- Button,
5673
- {
5674
- variant: "ghost",
5675
- size: "sm",
5676
- disabled: readonly || removeMutation.isPending,
5677
- onClick: () => onRemove(c.userId, c.userName),
5678
- title: t("collaborators_remove"),
5679
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "h-4 w-4" })
5680
- }
5681
- )
5682
- ] })
5683
- ]
5684
- },
5685
- c.id
5686
- )) }) })
5687
- ] })
5688
- ] }) }) });
3621
+ ) : null })
3622
+ ] });
5689
3623
  }
5690
3624
 
5691
3625
  const DEFAULT_DOC = {
@@ -5738,8 +3672,6 @@ function NotebookEditor({
5738
3672
  const [isInitializing, setIsInitializing] = reactExports.useState(true);
5739
3673
  const [error, setError] = reactExports.useState(null);
5740
3674
  const [autoSaveStatus, setAutoSaveStatus] = reactExports.useState("idle");
5741
- const [historyOpen, setHistoryOpen] = reactExports.useState(false);
5742
- const [collaboratorsOpen, setCollaboratorsOpen] = reactExports.useState(false);
5743
3675
  const [resetNonce, setResetNonce] = reactExports.useState(0);
5744
3676
  const { diffEvent, clearDiff } = useFileDiffOverlay({
5745
3677
  fileId: notebookId ?? void 0,
@@ -6260,13 +4192,8 @@ function NotebookEditor({
6260
4192
  NotebookToolbar,
6261
4193
  {
6262
4194
  notebookId: !isInline && notebookId ? notebookId : "",
6263
- readonly: isReadonly,
6264
4195
  autoSaveStatus,
6265
- getMarkdown: getCurrentMarkdown,
6266
- allowExport: !isInline && Boolean(notebookId),
6267
- allowShare: !isInline && Boolean(notebookId),
6268
- onShowHistory: !isInline && !isMarkdownDoc ? () => setHistoryOpen(true) : void 0,
6269
- onShowCollaborators: !isInline && !isMarkdownDoc ? () => setCollaboratorsOpen(true) : void 0
4196
+ getMarkdown: getCurrentMarkdown
6270
4197
  }
6271
4198
  ),
6272
4199
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0 overflow-hidden flex justify-center px-4 py-4 bg-muted/10", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "relative h-full w-[min(62.5vw,100%)] max-w-[70rem]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -6414,28 +4341,7 @@ function NotebookEditor({
6414
4341
  ) })
6415
4342
  ]
6416
4343
  }
6417
- ) }) }),
6418
- !isMarkdownDoc ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
6419
- /* @__PURE__ */ jsxRuntimeExports.jsx(
6420
- NotebookHistoryDialog,
6421
- {
6422
- open: historyOpen,
6423
- onOpenChange: setHistoryOpen,
6424
- notebookId: notebookId || "",
6425
- editor,
6426
- readonly: isReadonly
6427
- }
6428
- ),
6429
- /* @__PURE__ */ jsxRuntimeExports.jsx(
6430
- NotebookCollaboratorsDialog,
6431
- {
6432
- open: collaboratorsOpen,
6433
- onOpenChange: setCollaboratorsOpen,
6434
- notebookId: notebookId || "",
6435
- readonly: isReadonly
6436
- }
6437
- )
6438
- ] }) : null
4344
+ ) }) })
6439
4345
  ]
6440
4346
  }
6441
4347
  );