@blocknote/core 0.42.3 → 0.44.0

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 (200) hide show
  1. package/dist/BlockNoteExtension-BWw0r8Gy.cjs +2 -0
  2. package/dist/BlockNoteExtension-BWw0r8Gy.cjs.map +1 -0
  3. package/dist/BlockNoteExtension-C2X7LW-V.js +25 -0
  4. package/dist/BlockNoteExtension-C2X7LW-V.js.map +1 -0
  5. package/dist/BlockNoteSchema-B4gm-Qco.cjs +2 -0
  6. package/dist/BlockNoteSchema-B4gm-Qco.cjs.map +1 -0
  7. package/dist/BlockNoteSchema-C-l154WP.js +270 -0
  8. package/dist/BlockNoteSchema-C-l154WP.js.map +1 -0
  9. package/dist/EventEmitter-CLwfmbqG.cjs +2 -0
  10. package/dist/EventEmitter-CLwfmbqG.cjs.map +1 -0
  11. package/dist/EventEmitter-CjSwpTbz.js +27 -0
  12. package/dist/EventEmitter-CjSwpTbz.js.map +1 -0
  13. package/dist/ShowSelection-BW37oJ6h.cjs +2 -0
  14. package/dist/ShowSelection-BW37oJ6h.cjs.map +1 -0
  15. package/dist/ShowSelection-Dz-NEase.js +43 -0
  16. package/dist/ShowSelection-Dz-NEase.js.map +1 -0
  17. package/dist/TrailingNode-B_zPMWxw.js +2098 -0
  18. package/dist/TrailingNode-B_zPMWxw.js.map +1 -0
  19. package/dist/TrailingNode-CRHrgOnK.cjs +2 -0
  20. package/dist/TrailingNode-CRHrgOnK.cjs.map +1 -0
  21. package/dist/{blockToNode-DIfPWLH8.js → blockToNode-DBNbhwwC.js} +33 -33
  22. package/dist/blockToNode-DBNbhwwC.js.map +1 -0
  23. package/dist/blockToNode-w7H99R6p.cjs.map +1 -1
  24. package/dist/blocknote.cjs +4 -4
  25. package/dist/blocknote.cjs.map +1 -1
  26. package/dist/blocknote.js +2496 -5686
  27. package/dist/blocknote.js.map +1 -1
  28. package/dist/blocks.cjs +1 -1
  29. package/dist/blocks.js +71 -70
  30. package/dist/blocks.js.map +1 -1
  31. package/dist/comments.cjs +1 -1
  32. package/dist/comments.cjs.map +1 -1
  33. package/dist/comments.js +451 -137
  34. package/dist/comments.js.map +1 -1
  35. package/dist/defaultBlocks-DLJ4Q1_J.cjs +6 -0
  36. package/dist/defaultBlocks-DLJ4Q1_J.cjs.map +1 -0
  37. package/dist/{BlockNoteSchema-Bi-eeHal.js → defaultBlocks-DgA_mtQV.js} +974 -1027
  38. package/dist/defaultBlocks-DgA_mtQV.js.map +1 -0
  39. package/dist/extensions.cjs +2 -0
  40. package/dist/extensions.cjs.map +1 -0
  41. package/dist/extensions.js +57 -0
  42. package/dist/extensions.js.map +1 -0
  43. package/dist/tsconfig.tsbuildinfo +1 -1
  44. package/dist/webpack-stats.json +1 -1
  45. package/dist/yjs.js +1 -1
  46. package/package.json +9 -3
  47. package/src/api/nodeConversions/blockToNode.ts +1 -1
  48. package/src/api/nodeConversions/nodeToBlock.ts +1 -1
  49. package/src/blocks/Code/block.ts +4 -4
  50. package/src/blocks/Divider/block.ts +2 -2
  51. package/src/blocks/File/helpers/render/createAddFileButton.ts +7 -5
  52. package/src/blocks/Heading/block.ts +23 -20
  53. package/src/blocks/ListItem/BulletListItem/block.ts +2 -2
  54. package/src/blocks/ListItem/CheckListItem/block.ts +2 -2
  55. package/src/blocks/ListItem/NumberedListItem/block.ts +3 -3
  56. package/src/blocks/ListItem/ToggleListItem/block.ts +2 -2
  57. package/src/blocks/PageBreak/getPageBreakSlashMenuItems.ts +2 -2
  58. package/src/blocks/Paragraph/block.ts +2 -2
  59. package/src/blocks/Quote/block.ts +2 -2
  60. package/src/blocks/Table/block.ts +4 -3
  61. package/src/blocks/ToggleWrapper/createToggleWrapper.ts +2 -1
  62. package/src/comments/extension.ts +353 -0
  63. package/src/comments/index.ts +2 -1
  64. package/src/comments/types.ts +8 -0
  65. package/src/{extensions/Comments → comments}/userstore/UserStore.ts +2 -2
  66. package/src/editor/BlockNoteEditor.test.ts +2 -23
  67. package/src/editor/BlockNoteEditor.ts +60 -453
  68. package/src/editor/BlockNoteExtension.test.ts +103 -0
  69. package/src/editor/BlockNoteExtension.ts +174 -56
  70. package/src/editor/managers/EventManager.ts +64 -35
  71. package/src/editor/managers/ExtensionManager/extensions.ts +214 -0
  72. package/src/editor/managers/ExtensionManager/index.ts +514 -0
  73. package/src/editor/managers/ExtensionManager/symbol.ts +6 -0
  74. package/src/editor/managers/SelectionManager.ts +5 -1
  75. package/src/editor/managers/StateManager.ts +29 -17
  76. package/src/editor/managers/index.ts +1 -5
  77. package/src/extensions/BlockChange/{BlockChangePlugin.ts → BlockChange.ts} +27 -29
  78. package/src/extensions/Collaboration/{ForkYDocPlugin.test.ts → ForkYDoc.test.ts} +6 -5
  79. package/src/extensions/Collaboration/ForkYDoc.ts +158 -0
  80. package/src/extensions/Collaboration/YCursorPlugin.ts +183 -0
  81. package/src/extensions/Collaboration/YSync.ts +16 -0
  82. package/src/extensions/Collaboration/YUndo.ts +12 -0
  83. package/src/extensions/Collaboration/schemaMigration/SchemaMigration.ts +59 -0
  84. package/src/extensions/DropCursor/DropCursor.ts +26 -0
  85. package/src/extensions/FilePanel/FilePanel.ts +41 -0
  86. package/src/extensions/FormattingToolbar/FormattingToolbar.ts +119 -0
  87. package/src/extensions/History/History.ts +11 -0
  88. package/src/extensions/LinkToolbar/LinkToolbar.ts +121 -0
  89. package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboard.ts +74 -0
  90. package/src/extensions/Placeholder/Placeholder.ts +148 -0
  91. package/src/extensions/PreviousBlockType/{PreviousBlockTypePlugin.ts → PreviousBlockType.ts} +9 -13
  92. package/src/extensions/ShowSelection/{ShowSelectionPlugin.ts → ShowSelection.ts} +27 -33
  93. package/src/extensions/SideMenu/{SideMenuPlugin.ts → SideMenu.ts} +63 -83
  94. package/src/extensions/SuggestionMenu/{SuggestionPlugin.ts → SuggestionMenu.ts} +71 -77
  95. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +29 -44
  96. package/src/extensions/TableHandles/{TableHandlesPlugin.ts → TableHandles.ts} +416 -437
  97. package/src/extensions/TrailingNode/{TrailingNodeExtension.ts → TrailingNode.ts} +8 -17
  98. package/src/extensions/index.ts +24 -0
  99. package/src/extensions/{BackgroundColor → tiptap-extensions/BackgroundColor}/BackgroundColorExtension.ts +1 -1
  100. package/src/extensions/{KeyboardShortcuts → tiptap-extensions/KeyboardShortcuts}/KeyboardShortcutsExtension.ts +21 -16
  101. package/src/extensions/{TextColor → tiptap-extensions/TextColor}/TextColorExtension.ts +1 -1
  102. package/src/extensions/tiptap-extensions/index.ts +31 -0
  103. package/src/index.ts +1 -13
  104. package/src/schema/blocks/createSpec.ts +14 -11
  105. package/src/schema/blocks/internal.ts +2 -2
  106. package/src/schema/blocks/types.ts +8 -5
  107. package/src/schema/schema.ts +11 -36
  108. package/src/util/topo-sort.ts +46 -0
  109. package/types/src/comments/extension.d.ts +70 -0
  110. package/types/src/comments/index.d.ts +2 -1
  111. package/types/src/comments/types.d.ts +8 -0
  112. package/types/src/{extensions/Comments → comments}/userstore/UserStore.d.ts +2 -2
  113. package/types/src/editor/BlockNoteEditor.d.ts +34 -105
  114. package/types/src/editor/BlockNoteExtension.d.ts +87 -22
  115. package/types/src/editor/managers/EventManager.d.ts +25 -16
  116. package/types/src/editor/managers/ExtensionManager/extensions.d.ts +8 -0
  117. package/types/src/editor/managers/ExtensionManager/index.d.ts +83 -0
  118. package/types/src/editor/managers/ExtensionManager/symbol.d.ts +5 -0
  119. package/types/src/editor/managers/StateManager.d.ts +1 -12
  120. package/types/src/editor/managers/index.d.ts +1 -2
  121. package/types/src/extensions/BlockChange/BlockChange.d.ts +16 -0
  122. package/types/src/extensions/Collaboration/ForkYDoc.d.ts +34 -0
  123. package/types/src/extensions/Collaboration/ForkYDoc.test.d.ts +1 -0
  124. package/types/src/extensions/Collaboration/YCursorPlugin.d.ts +24 -0
  125. package/types/src/extensions/Collaboration/YSync.d.ts +8 -0
  126. package/types/src/extensions/Collaboration/YUndo.d.ts +12 -0
  127. package/types/src/extensions/Collaboration/schemaMigration/SchemaMigration.d.ts +8 -0
  128. package/types/src/extensions/DropCursor/DropCursor.d.ts +5 -0
  129. package/types/src/extensions/FilePanel/FilePanel.d.ts +11 -0
  130. package/types/src/extensions/FormattingToolbar/FormattingToolbar.d.ts +9 -0
  131. package/types/src/extensions/History/History.d.ts +6 -0
  132. package/types/src/extensions/LinkToolbar/LinkToolbar.d.ts +24 -0
  133. package/types/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboard.d.ts +5 -0
  134. package/types/src/extensions/Placeholder/Placeholder.d.ts +6 -0
  135. package/types/src/extensions/PreviousBlockType/{PreviousBlockTypePlugin.d.ts → PreviousBlockType.d.ts} +9 -5
  136. package/types/src/extensions/ShowSelection/ShowSelection.d.ts +21 -0
  137. package/types/src/extensions/SideMenu/{SideMenuPlugin.d.ts → SideMenu.d.ts} +11 -15
  138. package/types/src/extensions/SuggestionMenu/SuggestionMenu.d.ts +54 -0
  139. package/types/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.d.ts +1 -1
  140. package/types/src/extensions/TableHandles/{TableHandlesPlugin.d.ts → TableHandles.d.ts} +28 -31
  141. package/types/src/extensions/TrailingNode/TrailingNode.d.ts +8 -0
  142. package/types/src/extensions/index.d.ts +24 -0
  143. package/types/src/extensions/{KeyboardShortcuts → tiptap-extensions/KeyboardShortcuts}/KeyboardShortcutsExtension.d.ts +1 -1
  144. package/types/src/extensions/tiptap-extensions/index.d.ts +11 -0
  145. package/types/src/index.d.ts +1 -13
  146. package/types/src/schema/blocks/createSpec.d.ts +4 -4
  147. package/types/src/schema/blocks/internal.d.ts +2 -2
  148. package/types/src/schema/blocks/types.d.ts +5 -5
  149. package/types/src/util/topo-sort.d.ts +8 -0
  150. package/dist/BlockNoteSchema-Bi-eeHal.js.map +0 -1
  151. package/dist/BlockNoteSchema-DjDaA2C3.cjs +0 -6
  152. package/dist/BlockNoteSchema-DjDaA2C3.cjs.map +0 -1
  153. package/dist/blockToNode-DIfPWLH8.js.map +0 -1
  154. package/src/comments/models/User.ts +0 -8
  155. package/src/editor/BlockNoteExtensions.ts +0 -325
  156. package/src/editor/managers/CollaborationManager.ts +0 -212
  157. package/src/editor/managers/ExtensionManager.ts +0 -130
  158. package/src/extensions/Collaboration/CursorPlugin.ts +0 -189
  159. package/src/extensions/Collaboration/ForkYDocPlugin.ts +0 -192
  160. package/src/extensions/Collaboration/SyncPlugin.ts +0 -18
  161. package/src/extensions/Collaboration/UndoPlugin.ts +0 -18
  162. package/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.ts +0 -59
  163. package/src/extensions/Comments/CommentsPlugin.ts +0 -392
  164. package/src/extensions/FilePanel/FilePanelPlugin.ts +0 -206
  165. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +0 -363
  166. package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +0 -380
  167. package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts +0 -75
  168. package/src/extensions/Placeholder/PlaceholderPlugin.ts +0 -147
  169. package/types/src/comments/models/User.d.ts +0 -8
  170. package/types/src/editor/BlockNoteExtensions.d.ts +0 -43
  171. package/types/src/editor/managers/CollaborationManager.d.ts +0 -115
  172. package/types/src/editor/managers/ExtensionManager.d.ts +0 -68
  173. package/types/src/extensions/BlockChange/BlockChangePlugin.d.ts +0 -15
  174. package/types/src/extensions/Collaboration/CursorPlugin.d.ts +0 -37
  175. package/types/src/extensions/Collaboration/ForkYDocPlugin.d.ts +0 -41
  176. package/types/src/extensions/Collaboration/SyncPlugin.d.ts +0 -7
  177. package/types/src/extensions/Collaboration/UndoPlugin.d.ts +0 -9
  178. package/types/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.d.ts +0 -7
  179. package/types/src/extensions/Comments/CommentsPlugin.d.ts +0 -66
  180. package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +0 -31
  181. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +0 -41
  182. package/types/src/extensions/LinkToolbar/LinkToolbarPlugin.d.ts +0 -42
  183. package/types/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.d.ts +0 -5
  184. package/types/src/extensions/Placeholder/PlaceholderPlugin.d.ts +0 -6
  185. package/types/src/extensions/ShowSelection/ShowSelectionPlugin.d.ts +0 -15
  186. package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +0 -31
  187. package/types/src/extensions/TrailingNode/TrailingNodeExtension.d.ts +0 -13
  188. /package/src/{extensions/Comments/CommentMark.ts → comments/mark.ts} +0 -0
  189. /package/src/extensions/{HardBreak → tiptap-extensions/HardBreak}/HardBreak.ts +0 -0
  190. /package/src/extensions/{Suggestions → tiptap-extensions/Suggestions}/SuggestionMarks.ts +0 -0
  191. /package/src/extensions/{TextAlignment → tiptap-extensions/TextAlignment}/TextAlignmentExtension.ts +0 -0
  192. /package/src/extensions/{UniqueID → tiptap-extensions/UniqueID}/UniqueID.ts +0 -0
  193. /package/types/src/{extensions/Comments/CommentMark.d.ts → comments/mark.d.ts} +0 -0
  194. /package/types/src/{extensions/Collaboration/ForkYDocPlugin.test.d.ts → editor/BlockNoteExtension.test.d.ts} +0 -0
  195. /package/types/src/extensions/{BackgroundColor → tiptap-extensions/BackgroundColor}/BackgroundColorExtension.d.ts +0 -0
  196. /package/types/src/extensions/{HardBreak → tiptap-extensions/HardBreak}/HardBreak.d.ts +0 -0
  197. /package/types/src/extensions/{Suggestions → tiptap-extensions/Suggestions}/SuggestionMarks.d.ts +0 -0
  198. /package/types/src/extensions/{TextAlignment → tiptap-extensions/TextAlignment}/TextAlignmentExtension.d.ts +0 -0
  199. /package/types/src/extensions/{TextColor → tiptap-extensions/TextColor}/TextColorExtension.d.ts +0 -0
  200. /package/types/src/extensions/{UniqueID → tiptap-extensions/UniqueID}/UniqueID.d.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"comments.js","sources":["../src/comments/threadstore/ThreadStoreAuth.ts","../src/comments/threadstore/DefaultThreadStoreAuth.ts","../src/comments/threadstore/ThreadStore.ts","../src/comments/threadstore/TipTapThreadStore.ts","../src/comments/threadstore/yjs/yjsHelpers.ts","../src/comments/threadstore/yjs/YjsThreadStoreBase.ts","../src/comments/threadstore/yjs/RESTYjsThreadStore.ts","../src/comments/threadstore/yjs/YjsThreadStore.ts"],"sourcesContent":["import { CommentData, ThreadData } from \"../types.js\";\n\nexport abstract class ThreadStoreAuth {\n abstract canCreateThread(): boolean;\n abstract canAddComment(thread: ThreadData): boolean;\n abstract canUpdateComment(comment: CommentData): boolean;\n abstract canDeleteComment(comment: CommentData): boolean;\n abstract canDeleteThread(thread: ThreadData): boolean;\n abstract canResolveThread(thread: ThreadData): boolean;\n abstract canUnresolveThread(thread: ThreadData): boolean;\n abstract canAddReaction(comment: CommentData, emoji?: string): boolean;\n abstract canDeleteReaction(comment: CommentData, emoji?: string): boolean;\n}\n","import { CommentData, ThreadData } from \"../types.js\";\nimport { ThreadStoreAuth } from \"./ThreadStoreAuth.js\";\n\n/*\n * The DefaultThreadStoreAuth class defines the authorization rules for interacting with comments.\n * We take a role (\"comment\" or \"editor\") and implement the rules.\n *\n * This class is then used in the UI to show / hide specific interactions.\n *\n * Rules:\n * - View-only users should not be able to see any comments\n * - Comment-only users and editors can:\n * - - create new comments / replies / reactions\n * - - edit / delete their own comments / reactions\n * - - resolve / unresolve threads\n * - Editors can also delete any comment or thread\n */\nexport class DefaultThreadStoreAuth extends ThreadStoreAuth {\n constructor(\n private readonly userId: string,\n private readonly role: \"comment\" | \"editor\",\n ) {\n super();\n }\n\n /**\n * Auth: should be possible by anyone with comment access\n */\n canCreateThread(): boolean {\n return true;\n }\n\n /**\n * Auth: should be possible by anyone with comment access\n */\n canAddComment(_thread: ThreadData): boolean {\n return true;\n }\n\n /**\n * Auth: should only be possible by the comment author\n */\n canUpdateComment(comment: CommentData): boolean {\n return comment.userId === this.userId;\n }\n\n /**\n * Auth: should be possible by the comment author OR an editor of the document\n */\n canDeleteComment(comment: CommentData): boolean {\n return comment.userId === this.userId || this.role === \"editor\";\n }\n\n /**\n * Auth: should only be possible by an editor of the document\n */\n canDeleteThread(_thread: ThreadData): boolean {\n return this.role === \"editor\";\n }\n\n /**\n * Auth: should be possible by anyone with comment access\n */\n canResolveThread(_thread: ThreadData): boolean {\n return true;\n }\n\n /**\n * Auth: should be possible by anyone with comment access\n */\n canUnresolveThread(_thread: ThreadData): boolean {\n return true;\n }\n\n /**\n * Auth: should be possible by anyone with comment access\n *\n * Note: will also check if the user has already reacted with the same emoji. TBD: is that a nice design or should this responsibility be outside of auth?\n */\n canAddReaction(comment: CommentData, emoji?: string): boolean {\n if (!emoji) {\n return true;\n }\n\n return !comment.reactions.some(\n (reaction) =>\n reaction.emoji === emoji && reaction.userIds.includes(this.userId),\n );\n }\n\n /**\n * Auth: should be possible by anyone with comment access\n *\n * Note: will also check if the user has already reacted with the same emoji. TBD: is that a nice design or should this responsibility be outside of auth?\n */\n canDeleteReaction(comment: CommentData, emoji?: string): boolean {\n if (!emoji) {\n return true;\n }\n\n return comment.reactions.some(\n (reaction) =>\n reaction.emoji === emoji && reaction.userIds.includes(this.userId),\n );\n }\n}\n","import { CommentBody, CommentData, ThreadData } from \"../types.js\";\nimport { ThreadStoreAuth } from \"./ThreadStoreAuth.js\";\n\n/**\n * ThreadStore is an abstract class that defines the interface\n * to read / add / update / delete threads and comments.\n */\nexport abstract class ThreadStore {\n public readonly auth: ThreadStoreAuth;\n\n constructor(auth: ThreadStoreAuth) {\n this.auth = auth;\n }\n\n /**\n * A \"thread\" in the ThreadStore only contains information about the content\n * of the thread / comments. It does not contain information about the position.\n *\n * This function can be implemented to store the thread in the document (by creating a mark)\n * If not implemented, default behavior will apply (creating the mark via TipTap)\n * See CommentsPlugin.ts for more details.\n */\n abstract addThreadToDocument?(options: {\n threadId: string;\n selection: {\n prosemirror: {\n head: number;\n anchor: number;\n };\n yjs?: {\n head: any;\n anchor: any;\n };\n };\n }): Promise<void>;\n\n /**\n * Creates a new thread with an initial comment.\n */\n abstract createThread(options: {\n initialComment: {\n body: CommentBody;\n metadata?: any;\n };\n metadata?: any;\n }): Promise<ThreadData>;\n\n /**\n * Adds a comment to a thread.\n */\n abstract addComment(options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n }): Promise<CommentData>;\n\n /**\n * Updates a comment in a thread.\n */\n abstract updateComment(options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n commentId: string;\n }): Promise<void>;\n\n /**\n * Deletes a comment from a thread.\n */\n abstract deleteComment(options: {\n threadId: string;\n commentId: string;\n }): Promise<void>;\n\n /**\n * Deletes a thread.\n */\n abstract deleteThread(options: { threadId: string }): Promise<void>;\n\n /**\n * Marks a thread as resolved.\n */\n abstract resolveThread(options: { threadId: string }): Promise<void>;\n\n /**\n * Marks a thread as unresolved.\n */\n abstract unresolveThread(options: { threadId: string }): Promise<void>;\n\n /**\n * Adds a reaction to a comment.\n *\n * Auth: should be possible by anyone with comment access\n */\n abstract addReaction(options: {\n threadId: string;\n commentId: string;\n emoji: string;\n }): Promise<void>;\n\n /**\n * Deletes a reaction from a comment.\n *\n * Auth: should be possible by the reaction author\n */\n abstract deleteReaction(options: {\n threadId: string;\n commentId: string;\n emoji: string;\n }): Promise<void>;\n\n /**\n * Retrieve data for a specific thread.\n */\n abstract getThread(threadId: string): ThreadData;\n\n /**\n * Retrieve all threads.\n */\n abstract getThreads(): Map<string, ThreadData>;\n\n /**\n * Subscribe to changes in the thread store.\n *\n * @returns a function to unsubscribe from the thread store\n */\n abstract subscribe(\n cb: (threads: Map<string, ThreadData>) => void,\n ): () => void;\n}\n","import type {\n TCollabComment,\n TCollabThread,\n TiptapCollabProvider,\n} from \"@hocuspocus/provider\";\nimport {\n CommentBody,\n CommentData,\n CommentReactionData,\n ThreadData,\n} from \"../types.js\";\nimport { ThreadStore } from \"./ThreadStore.js\";\nimport { ThreadStoreAuth } from \"./ThreadStoreAuth.js\";\n\ntype ReactionAsTiptapData = {\n emoji: string;\n createdAt: number;\n userId: string;\n};\n\n/**\n * The `TiptapThreadStore` integrates with Tiptap's collaboration provider for comment management.\n * You can pass a `TiptapCollabProvider` to the constructor which takes care of storing the comments.\n *\n * Under the hood, this actually works similarly to the `YjsThreadStore` implementation. (comments are stored in the Yjs document)\n */\nexport class TiptapThreadStore extends ThreadStore {\n constructor(\n private readonly userId: string,\n private readonly provider: TiptapCollabProvider,\n auth: ThreadStoreAuth, // TODO: use?\n ) {\n super(auth);\n }\n\n /**\n * Creates a new thread with an initial comment.\n */\n public async createThread(options: {\n initialComment: {\n body: CommentBody;\n metadata?: any;\n };\n metadata?: any;\n }): Promise<ThreadData> {\n let thread = this.provider.createThread({\n data: options.metadata,\n });\n\n thread = this.provider.addComment(thread.id, {\n content: options.initialComment.body,\n data: {\n metadata: options.initialComment.metadata,\n userId: this.userId,\n },\n });\n\n return this.tiptapThreadToThreadData(thread);\n }\n\n // TipTapThreadStore does not support addThreadToDocument\n public addThreadToDocument = undefined;\n\n /**\n * Adds a comment to a thread.\n */\n public async addComment(options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n }): Promise<CommentBody> {\n const thread = this.provider.addComment(options.threadId, {\n content: options.comment.body,\n data: {\n metadata: options.comment.metadata,\n userId: this.userId,\n },\n });\n\n return this.tiptapCommentToCommentData(\n thread.comments[thread.comments.length - 1],\n );\n }\n\n /**\n * Updates a comment in a thread.\n */\n public async updateComment(options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n commentId: string;\n }) {\n const comment = this.provider.getThreadComment(\n options.threadId,\n options.commentId,\n true,\n );\n\n if (!comment) {\n throw new Error(\"Comment not found\");\n }\n\n this.provider.updateComment(options.threadId, options.commentId, {\n content: options.comment.body,\n data: {\n ...comment.data,\n metadata: options.comment.metadata,\n },\n });\n }\n\n private tiptapCommentToCommentData(comment: TCollabComment): CommentData {\n const reactions: CommentReactionData[] = [];\n\n for (const reaction of (comment.data?.reactions ||\n []) as ReactionAsTiptapData[]) {\n const existingReaction = reactions.find(\n (r) => r.emoji === reaction.emoji,\n );\n if (existingReaction) {\n existingReaction.userIds.push(reaction.userId);\n existingReaction.createdAt = new Date(\n Math.min(existingReaction.createdAt.getTime(), reaction.createdAt),\n );\n } else {\n reactions.push({\n emoji: reaction.emoji,\n createdAt: new Date(reaction.createdAt),\n userIds: [reaction.userId],\n });\n }\n }\n\n return {\n type: \"comment\",\n id: comment.id,\n body: comment.content,\n metadata: comment.data?.metadata,\n userId: comment.data?.userId,\n createdAt: new Date(comment.createdAt),\n updatedAt: new Date(comment.updatedAt),\n reactions,\n };\n }\n\n private tiptapThreadToThreadData(thread: TCollabThread): ThreadData {\n return {\n type: \"thread\",\n id: thread.id,\n comments: thread.comments.map((comment) =>\n this.tiptapCommentToCommentData(comment),\n ),\n resolved: !!thread.resolvedAt,\n metadata: thread.data?.metadata,\n createdAt: new Date(thread.createdAt),\n updatedAt: new Date(thread.updatedAt),\n };\n }\n\n /**\n * Deletes a comment from a thread.\n */\n public async deleteComment(options: { threadId: string; commentId: string }) {\n this.provider.deleteComment(options.threadId, options.commentId);\n }\n\n /**\n * Deletes a thread.\n */\n public async deleteThread(options: { threadId: string }) {\n this.provider.deleteThread(options.threadId);\n }\n\n /**\n * Marks a thread as resolved.\n */\n public async resolveThread(options: { threadId: string }) {\n this.provider.updateThread(options.threadId, {\n resolvedAt: new Date().toISOString(),\n });\n }\n\n /**\n * Marks a thread as unresolved.\n */\n public async unresolveThread(options: { threadId: string }) {\n this.provider.updateThread(options.threadId, {\n resolvedAt: null,\n });\n }\n\n /**\n * Adds a reaction to a comment.\n *\n * Auth: should be possible by anyone with comment access\n */\n public async addReaction(options: {\n threadId: string;\n commentId: string;\n emoji: string;\n }) {\n const comment = this.provider.getThreadComment(\n options.threadId,\n options.commentId,\n true,\n );\n\n if (!comment) {\n throw new Error(\"Comment not found\");\n }\n\n this.provider.updateComment(options.threadId, options.commentId, {\n data: {\n ...comment.data,\n reactions: [\n ...((comment.data?.reactions || []) as ReactionAsTiptapData[]),\n {\n emoji: options.emoji,\n createdAt: Date.now(),\n userId: this.userId,\n },\n ],\n },\n });\n }\n\n /**\n * Deletes a reaction from a comment.\n *\n * Auth: should be possible by the reaction author\n */\n public async deleteReaction(options: {\n threadId: string;\n commentId: string;\n emoji: string;\n }) {\n const comment = this.provider.getThreadComment(\n options.threadId,\n options.commentId,\n true,\n );\n\n if (!comment) {\n throw new Error(\"Comment not found\");\n }\n\n this.provider.updateComment(options.threadId, options.commentId, {\n data: {\n ...comment.data,\n reactions: (\n (comment.data?.reactions || []) as ReactionAsTiptapData[]\n ).filter(\n (reaction) =>\n reaction.emoji !== options.emoji && reaction.userId !== this.userId,\n ),\n },\n });\n }\n\n public getThread(threadId: string): ThreadData {\n const thread = this.provider.getThread(threadId);\n\n if (!thread) {\n throw new Error(\"Thread not found\");\n }\n\n return this.tiptapThreadToThreadData(thread);\n }\n\n public getThreads(): Map<string, ThreadData> {\n return new Map(\n this.provider\n .getThreads()\n .map((thread) => [thread.id, this.tiptapThreadToThreadData(thread)]),\n );\n }\n\n public subscribe(cb: (threads: Map<string, ThreadData>) => void): () => void {\n const newCb = () => {\n cb(this.getThreads());\n };\n this.provider.watchThreads(newCb);\n return () => {\n this.provider.unwatchThreads(newCb);\n };\n }\n}\n","import * as Y from \"yjs\";\nimport { CommentData, CommentReactionData, ThreadData } from \"../../types.js\";\n\nexport function commentToYMap(comment: CommentData) {\n const yMap = new Y.Map<any>();\n yMap.set(\"id\", comment.id);\n yMap.set(\"userId\", comment.userId);\n yMap.set(\"createdAt\", comment.createdAt.getTime());\n yMap.set(\"updatedAt\", comment.updatedAt.getTime());\n if (comment.deletedAt) {\n yMap.set(\"deletedAt\", comment.deletedAt.getTime());\n yMap.set(\"body\", undefined);\n } else {\n yMap.set(\"body\", comment.body);\n }\n if (comment.reactions.length > 0) {\n throw new Error(\"Reactions should be empty in commentToYMap\");\n }\n\n /**\n * Reactions are stored in a map keyed by {userId-emoji},\n * this makes it easy to add / remove reactions and in a way that works local-first.\n * The cost is that \"reading\" the reactions is a bit more complex (see yMapToReactions).\n */\n yMap.set(\"reactionsByUser\", new Y.Map());\n yMap.set(\"metadata\", comment.metadata);\n\n return yMap;\n}\n\nexport function threadToYMap(thread: ThreadData) {\n const yMap = new Y.Map();\n yMap.set(\"id\", thread.id);\n yMap.set(\"createdAt\", thread.createdAt.getTime());\n yMap.set(\"updatedAt\", thread.updatedAt.getTime());\n const commentsArray = new Y.Array<Y.Map<any>>();\n\n commentsArray.push(thread.comments.map((comment) => commentToYMap(comment)));\n\n yMap.set(\"comments\", commentsArray);\n yMap.set(\"resolved\", thread.resolved);\n yMap.set(\"resolvedUpdatedAt\", thread.resolvedUpdatedAt?.getTime());\n yMap.set(\"resolvedBy\", thread.resolvedBy);\n yMap.set(\"metadata\", thread.metadata);\n return yMap;\n}\n\ntype SingleUserCommentReactionData = {\n emoji: string;\n createdAt: Date;\n userId: string;\n};\n\nexport function yMapToReaction(\n yMap: Y.Map<any>,\n): SingleUserCommentReactionData {\n return {\n emoji: yMap.get(\"emoji\"),\n createdAt: new Date(yMap.get(\"createdAt\")),\n userId: yMap.get(\"userId\"),\n };\n}\n\nfunction yMapToReactions(yMap: Y.Map<any>): CommentReactionData[] {\n const flatReactions = [...yMap.values()].map((reaction: Y.Map<any>) =>\n yMapToReaction(reaction),\n );\n // combine reactions by the same emoji\n return flatReactions.reduce(\n (acc: CommentReactionData[], reaction: SingleUserCommentReactionData) => {\n const existingReaction = acc.find((r) => r.emoji === reaction.emoji);\n if (existingReaction) {\n existingReaction.userIds.push(reaction.userId);\n existingReaction.createdAt = new Date(\n Math.min(\n existingReaction.createdAt.getTime(),\n reaction.createdAt.getTime(),\n ),\n );\n } else {\n acc.push({\n emoji: reaction.emoji,\n createdAt: reaction.createdAt,\n userIds: [reaction.userId],\n });\n }\n return acc;\n },\n [] as CommentReactionData[],\n );\n}\n\nexport function yMapToComment(yMap: Y.Map<any>): CommentData {\n return {\n type: \"comment\",\n id: yMap.get(\"id\"),\n userId: yMap.get(\"userId\"),\n createdAt: new Date(yMap.get(\"createdAt\")),\n updatedAt: new Date(yMap.get(\"updatedAt\")),\n deletedAt: yMap.get(\"deletedAt\")\n ? new Date(yMap.get(\"deletedAt\"))\n : undefined,\n reactions: yMapToReactions(yMap.get(\"reactionsByUser\")),\n metadata: yMap.get(\"metadata\"),\n body: yMap.get(\"body\"),\n };\n}\n\nexport function yMapToThread(yMap: Y.Map<any>): ThreadData {\n return {\n type: \"thread\",\n id: yMap.get(\"id\"),\n createdAt: new Date(yMap.get(\"createdAt\")),\n updatedAt: new Date(yMap.get(\"updatedAt\")),\n comments: ((yMap.get(\"comments\") as Y.Array<Y.Map<any>>) || []).map(\n (comment) => yMapToComment(comment),\n ),\n resolved: yMap.get(\"resolved\"),\n resolvedUpdatedAt: new Date(yMap.get(\"resolvedUpdatedAt\")),\n resolvedBy: yMap.get(\"resolvedBy\"),\n metadata: yMap.get(\"metadata\"),\n };\n}\n","import * as Y from \"yjs\";\nimport { ThreadData } from \"../../types.js\";\nimport { ThreadStore } from \"../ThreadStore.js\";\nimport { ThreadStoreAuth } from \"../ThreadStoreAuth.js\";\nimport { yMapToThread } from \"./yjsHelpers.js\";\n\n/**\n * This is an abstract class that only implements the READ methods required by the ThreadStore interface.\n * The data is read from a Yjs Map.\n */\nexport abstract class YjsThreadStoreBase extends ThreadStore {\n constructor(\n protected readonly threadsYMap: Y.Map<any>,\n auth: ThreadStoreAuth,\n ) {\n super(auth);\n }\n\n // TODO: async / reactive interface?\n public getThread(threadId: string) {\n const yThread = this.threadsYMap.get(threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n const thread = yMapToThread(yThread);\n return thread;\n }\n\n public getThreads(): Map<string, ThreadData> {\n const threadMap = new Map<string, ThreadData>();\n this.threadsYMap.forEach((yThread, id) => {\n if (yThread instanceof Y.Map) {\n threadMap.set(id, yMapToThread(yThread));\n }\n });\n return threadMap;\n }\n\n public subscribe(cb: (threads: Map<string, ThreadData>) => void) {\n const observer = () => {\n cb(this.getThreads());\n };\n\n this.threadsYMap.observeDeep(observer);\n\n return () => {\n this.threadsYMap.unobserveDeep(observer);\n };\n }\n}\n","import * as Y from \"yjs\";\nimport { CommentBody } from \"../../types.js\";\nimport { ThreadStoreAuth } from \"../ThreadStoreAuth.js\";\nimport { YjsThreadStoreBase } from \"./YjsThreadStoreBase.js\";\n\n/**\n * This is a REST-based implementation of the YjsThreadStoreBase.\n * It Reads data directly from the underlying document (same as YjsThreadStore),\n * but for Writes, it sends data to a REST API that should:\n * - check the user has the correct permissions to make the desired changes\n * - apply the updates to the underlying Yjs document\n *\n * (see https://github.com/TypeCellOS/BlockNote-demo-nextjs-hocuspocus)\n *\n * The reason we still use the Yjs document as underlying storage is that it makes it easy to\n * sync updates in real-time to other collaborators.\n * (but technically, you could also implement a different storage altogether\n * and not store the thread related data in the Yjs document)\n */\nexport class RESTYjsThreadStore extends YjsThreadStoreBase {\n constructor(\n private readonly BASE_URL: string,\n private readonly headers: Record<string, string>,\n threadsYMap: Y.Map<any>,\n auth: ThreadStoreAuth,\n ) {\n super(threadsYMap, auth);\n }\n\n private doRequest = async (path: string, method: string, body?: any) => {\n const response = await fetch(`${this.BASE_URL}${path}`, {\n method,\n body: JSON.stringify(body),\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.headers,\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to ${method} ${path}: ${response.statusText}`);\n }\n\n return response.json();\n };\n\n public addThreadToDocument = async (options: {\n threadId: string;\n selection: {\n prosemirror: {\n head: number;\n anchor: number;\n };\n yjs: {\n head: any;\n anchor: any;\n };\n };\n }) => {\n const { threadId, ...rest } = options;\n return this.doRequest(`/${threadId}/addToDocument`, \"POST\", rest);\n };\n\n public createThread = async (options: {\n initialComment: {\n body: CommentBody;\n metadata?: any;\n };\n metadata?: any;\n }) => {\n return this.doRequest(\"\", \"POST\", options);\n };\n\n public addComment = (options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n }) => {\n const { threadId, ...rest } = options;\n return this.doRequest(`/${threadId}/comments`, \"POST\", rest);\n };\n\n public updateComment = (options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n commentId: string;\n }) => {\n const { threadId, commentId, ...rest } = options;\n return this.doRequest(`/${threadId}/comments/${commentId}`, \"PUT\", rest);\n };\n\n public deleteComment = (options: {\n threadId: string;\n commentId: string;\n softDelete?: boolean;\n }) => {\n const { threadId, commentId, ...rest } = options;\n return this.doRequest(\n `/${threadId}/comments/${commentId}?soft=${!!rest.softDelete}`,\n \"DELETE\",\n );\n };\n\n public deleteThread = (options: { threadId: string }) => {\n return this.doRequest(`/${options.threadId}`, \"DELETE\");\n };\n\n public resolveThread = (options: { threadId: string }) => {\n return this.doRequest(`/${options.threadId}/resolve`, \"POST\");\n };\n\n public unresolveThread = (options: { threadId: string }) => {\n return this.doRequest(`/${options.threadId}/unresolve`, \"POST\");\n };\n\n public addReaction = (options: {\n threadId: string;\n commentId: string;\n emoji: string;\n }) => {\n const { threadId, commentId, ...rest } = options;\n return this.doRequest(\n `/${threadId}/comments/${commentId}/reactions`,\n \"POST\",\n rest,\n );\n };\n\n public deleteReaction = (options: {\n threadId: string;\n commentId: string;\n emoji: string;\n }) => {\n return this.doRequest(\n `/${options.threadId}/comments/${options.commentId}/reactions/${options.emoji}`,\n \"DELETE\",\n );\n };\n}\n","import { v4 } from \"uuid\";\nimport * as Y from \"yjs\";\nimport { CommentBody, CommentData, ThreadData } from \"../../types.js\";\nimport { ThreadStoreAuth } from \"../ThreadStoreAuth.js\";\nimport { YjsThreadStoreBase } from \"./YjsThreadStoreBase.js\";\nimport {\n commentToYMap,\n threadToYMap,\n yMapToComment,\n yMapToThread,\n} from \"./yjsHelpers.js\";\n\n/**\n * This is a Yjs-based implementation of the ThreadStore interface.\n *\n * It reads and writes thread / comments information directly to the underlying Yjs Document.\n *\n * @important While this is the easiest to add to your app, there are two challenges:\n * - The user needs to be able to write to the Yjs document to store the information.\n * So a user without write access to the Yjs document cannot leave any comments.\n * - Even with write access, the operations are not secure. Unless your Yjs server\n * guards against malicious operations, it's technically possible for one user to make changes to another user's comments, etc.\n * (even though these options are not visible in the UI, a malicious user can make unauthorized changes to the underlying Yjs document)\n */\nexport class YjsThreadStore extends YjsThreadStoreBase {\n constructor(\n private readonly userId: string,\n threadsYMap: Y.Map<any>,\n auth: ThreadStoreAuth,\n ) {\n super(threadsYMap, auth);\n }\n\n private transact = <T, R>(\n fn: (options: T) => R,\n ): ((options: T) => Promise<R>) => {\n return async (options: T) => {\n return this.threadsYMap.doc!.transact(() => {\n return fn(options);\n });\n };\n };\n\n public createThread = this.transact(\n (options: {\n initialComment: {\n body: CommentBody;\n metadata?: any;\n };\n metadata?: any;\n }) => {\n if (!this.auth.canCreateThread()) {\n throw new Error(\"Not authorized\");\n }\n\n const date = new Date();\n\n const comment: CommentData = {\n type: \"comment\",\n id: v4(),\n userId: this.userId,\n createdAt: date,\n updatedAt: date,\n reactions: [],\n metadata: options.initialComment.metadata,\n body: options.initialComment.body,\n };\n\n const thread: ThreadData = {\n type: \"thread\",\n id: v4(),\n createdAt: date,\n updatedAt: date,\n comments: [comment],\n resolved: false,\n metadata: options.metadata,\n };\n\n this.threadsYMap.set(thread.id, threadToYMap(thread));\n\n return thread;\n },\n );\n\n // YjsThreadStore does not support addThreadToDocument\n public addThreadToDocument = undefined;\n\n public addComment = this.transact(\n (options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n if (!this.auth.canAddComment(yMapToThread(yThread))) {\n throw new Error(\"Not authorized\");\n }\n\n const date = new Date();\n const comment: CommentData = {\n type: \"comment\",\n id: v4(),\n userId: this.userId,\n createdAt: date,\n updatedAt: date,\n deletedAt: undefined,\n reactions: [],\n metadata: options.comment.metadata,\n body: options.comment.body,\n };\n\n (yThread.get(\"comments\") as Y.Array<Y.Map<any>>).push([\n commentToYMap(comment),\n ]);\n\n yThread.set(\"updatedAt\", new Date().getTime());\n return comment;\n },\n );\n\n public updateComment = this.transact(\n (options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n commentId: string;\n }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n const yCommentIndex = yArrayFindIndex(\n yThread.get(\"comments\"),\n (comment) => comment.get(\"id\") === options.commentId,\n );\n\n if (yCommentIndex === -1) {\n throw new Error(\"Comment not found\");\n }\n\n const yComment = yThread.get(\"comments\").get(yCommentIndex);\n\n if (!this.auth.canUpdateComment(yMapToComment(yComment))) {\n throw new Error(\"Not authorized\");\n }\n\n yComment.set(\"body\", options.comment.body);\n yComment.set(\"updatedAt\", new Date().getTime());\n yComment.set(\"metadata\", options.comment.metadata);\n },\n );\n\n public deleteComment = this.transact(\n (options: {\n threadId: string;\n commentId: string;\n softDelete?: boolean;\n }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n const yCommentIndex = yArrayFindIndex(\n yThread.get(\"comments\"),\n (comment) => comment.get(\"id\") === options.commentId,\n );\n\n if (yCommentIndex === -1) {\n throw new Error(\"Comment not found\");\n }\n\n const yComment = yThread.get(\"comments\").get(yCommentIndex);\n\n if (!this.auth.canDeleteComment(yMapToComment(yComment))) {\n throw new Error(\"Not authorized\");\n }\n\n if (yComment.get(\"deletedAt\")) {\n throw new Error(\"Comment already deleted\");\n }\n\n if (options.softDelete) {\n yComment.set(\"deletedAt\", new Date().getTime());\n yComment.set(\"body\", undefined);\n } else {\n yThread.get(\"comments\").delete(yCommentIndex);\n }\n\n if (\n (yThread.get(\"comments\") as Y.Array<any>)\n .toArray()\n .every((comment) => comment.get(\"deletedAt\"))\n ) {\n // all comments deleted\n if (options.softDelete) {\n yThread.set(\"deletedAt\", new Date().getTime());\n } else {\n this.threadsYMap.delete(options.threadId);\n }\n }\n\n yThread.set(\"updatedAt\", new Date().getTime());\n },\n );\n\n public deleteThread = this.transact((options: { threadId: string }) => {\n if (\n !this.auth.canDeleteThread(\n yMapToThread(this.threadsYMap.get(options.threadId)),\n )\n ) {\n throw new Error(\"Not authorized\");\n }\n\n this.threadsYMap.delete(options.threadId);\n });\n\n public resolveThread = this.transact((options: { threadId: string }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n if (!this.auth.canResolveThread(yMapToThread(yThread))) {\n throw new Error(\"Not authorized\");\n }\n\n yThread.set(\"resolved\", true);\n yThread.set(\"resolvedUpdatedAt\", new Date().getTime());\n yThread.set(\"resolvedBy\", this.userId);\n });\n\n public unresolveThread = this.transact((options: { threadId: string }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n if (!this.auth.canUnresolveThread(yMapToThread(yThread))) {\n throw new Error(\"Not authorized\");\n }\n\n yThread.set(\"resolved\", false);\n yThread.set(\"resolvedUpdatedAt\", new Date().getTime());\n });\n\n public addReaction = this.transact(\n (options: { threadId: string; commentId: string; emoji: string }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n const yCommentIndex = yArrayFindIndex(\n yThread.get(\"comments\"),\n (comment) => comment.get(\"id\") === options.commentId,\n );\n\n if (yCommentIndex === -1) {\n throw new Error(\"Comment not found\");\n }\n\n const yComment = yThread.get(\"comments\").get(yCommentIndex);\n\n if (!this.auth.canAddReaction(yMapToComment(yComment), options.emoji)) {\n throw new Error(\"Not authorized\");\n }\n\n const date = new Date();\n\n const key = `${this.userId}-${options.emoji}`;\n\n const reactionsByUser = yComment.get(\"reactionsByUser\");\n\n if (reactionsByUser.has(key)) {\n // already exists\n return;\n } else {\n const reaction = new Y.Map();\n reaction.set(\"emoji\", options.emoji);\n reaction.set(\"createdAt\", date.getTime());\n reaction.set(\"userId\", this.userId);\n reactionsByUser.set(key, reaction);\n }\n },\n );\n\n public deleteReaction = this.transact(\n (options: { threadId: string; commentId: string; emoji: string }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n const yCommentIndex = yArrayFindIndex(\n yThread.get(\"comments\"),\n (comment) => comment.get(\"id\") === options.commentId,\n );\n\n if (yCommentIndex === -1) {\n throw new Error(\"Comment not found\");\n }\n\n const yComment = yThread.get(\"comments\").get(yCommentIndex);\n\n if (\n !this.auth.canDeleteReaction(yMapToComment(yComment), options.emoji)\n ) {\n throw new Error(\"Not authorized\");\n }\n\n const key = `${this.userId}-${options.emoji}`;\n\n const reactionsByUser = yComment.get(\"reactionsByUser\");\n\n reactionsByUser.delete(key);\n },\n );\n}\n\nfunction yArrayFindIndex(\n yArray: Y.Array<any>,\n predicate: (item: any) => boolean,\n) {\n for (let i = 0; i < yArray.length; i++) {\n if (predicate(yArray.get(i))) {\n return i;\n }\n }\n return -1;\n}\n"],"names":["ThreadStoreAuth","DefaultThreadStoreAuth","userId","role","_thread","comment","emoji","reaction","ThreadStore","auth","__publicField","TiptapThreadStore","provider","options","thread","reactions","_a","existingReaction","r","_b","_c","threadId","cb","newCb","commentToYMap","yMap","Y","threadToYMap","commentsArray","yMapToReaction","yMapToReactions","acc","yMapToComment","yMapToThread","YjsThreadStoreBase","threadsYMap","yThread","threadMap","id","observer","RESTYjsThreadStore","BASE_URL","headers","path","method","body","response","rest","commentId","YjsThreadStore","fn","date","v4","yCommentIndex","yArrayFindIndex","yComment","key","reactionsByUser","yArray","predicate","i"],"mappings":"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"}
1
+ {"version":3,"file":"comments.js","sources":["../src/comments/mark.ts","../src/comments/userstore/UserStore.ts","../src/comments/extension.ts","../src/comments/threadstore/ThreadStoreAuth.ts","../src/comments/threadstore/DefaultThreadStoreAuth.ts","../src/comments/threadstore/ThreadStore.ts","../src/comments/threadstore/TipTapThreadStore.ts","../src/comments/threadstore/yjs/yjsHelpers.ts","../src/comments/threadstore/yjs/YjsThreadStoreBase.ts","../src/comments/threadstore/yjs/RESTYjsThreadStore.ts","../src/comments/threadstore/yjs/YjsThreadStore.ts"],"sourcesContent":["import { Mark, mergeAttributes } from \"@tiptap/core\";\n\nexport const CommentMark = Mark.create({\n name: \"comment\",\n excludes: \"\",\n inclusive: false,\n keepOnSplit: true,\n\n addAttributes() {\n // Return an object with attribute configuration\n return {\n // orphans are marks that currently don't have an active thread. It could be\n // that users have resolved the thread. Resolved threads by default are not shown in the document,\n // but we need to keep the mark (positioning) data so we can still \"revive\" it when the thread is unresolved\n // or we enter a \"comments\" view that includes resolved threads.\n orphan: {\n parseHTML: (element) => !!element.getAttribute(\"data-orphan\"),\n renderHTML: (attributes) => {\n return (attributes as { orphan: boolean }).orphan\n ? {\n \"data-orphan\": \"true\",\n }\n : {};\n },\n default: false,\n },\n threadId: {\n parseHTML: (element) => element.getAttribute(\"data-bn-thread-id\"),\n renderHTML: (attributes) => {\n return {\n \"data-bn-thread-id\": (attributes as { threadId: string }).threadId,\n };\n },\n default: \"\",\n },\n };\n },\n\n renderHTML({ HTMLAttributes }: { HTMLAttributes: Record<string, any> }) {\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"bn-thread-mark\",\n }),\n ];\n },\n\n parseHTML() {\n return [{ tag: \"span.bn-thread-mark\" }];\n },\n\n extendMarkSchema(extension) {\n if (extension.name === \"comment\") {\n return {\n blocknoteIgnore: true,\n };\n }\n return {};\n },\n});\n","import type { User } from \"../types.js\";\nimport { EventEmitter } from \"../../util/EventEmitter.js\";\n\n/**\n * The `UserStore` is used to retrieve and cache information about users.\n *\n * It does this by calling `resolveUsers` (which is user-defined in the Editor Options)\n * for users that are not yet cached.\n */\nexport class UserStore<U extends User> extends EventEmitter<any> {\n private userCache: Map<string, U> = new Map();\n\n // avoid duplicate loads\n private loadingUsers = new Set<string>();\n\n public constructor(\n private readonly resolveUsers: (userIds: string[]) => Promise<U[]>,\n ) {\n super();\n }\n\n /**\n * Load information about users based on an array of user ids.\n */\n public async loadUsers(userIds: string[]) {\n const missingUsers = userIds.filter(\n (id) => !this.userCache.has(id) && !this.loadingUsers.has(id),\n );\n\n if (missingUsers.length === 0) {\n return;\n }\n\n for (const id of missingUsers) {\n this.loadingUsers.add(id);\n }\n\n try {\n const users = await this.resolveUsers(missingUsers);\n for (const user of users) {\n this.userCache.set(user.id, user);\n }\n this.emit(\"update\", this.userCache);\n } finally {\n for (const id of missingUsers) {\n // delete the users from the loading set\n // on a next call to `loadUsers` we will either\n // return the cached user or retry loading the user if the request failed failed\n this.loadingUsers.delete(id);\n }\n }\n }\n\n /**\n * Retrieve information about a user based on their id, if cached.\n *\n * The user will have to be loaded via `loadUsers` first\n */\n public getUser(userId: string): U | undefined {\n return this.userCache.get(userId);\n }\n\n /**\n * Subscribe to changes in the user store.\n *\n * @param cb - The callback to call when the user store changes.\n * @returns A function to unsubscribe from the user store.\n */\n public subscribe(cb: (users: Map<string, U>) => void): () => void {\n return this.on(\"update\", cb);\n }\n}\n","import { Node } from \"prosemirror-model\";\nimport { Plugin, PluginKey } from \"prosemirror-state\";\nimport { Decoration, DecorationSet } from \"prosemirror-view\";\nimport { getRelativeSelection, ySyncPluginKey } from \"y-prosemirror\";\nimport {\n createExtension,\n createStore,\n ExtensionOptions,\n} from \"../editor/BlockNoteExtension.js\";\nimport { ShowSelectionExtension } from \"../extensions/ShowSelection/ShowSelection.js\";\nimport { CustomBlockNoteSchema } from \"../schema/schema.js\";\nimport { CommentMark } from \"./mark.js\";\nimport type { ThreadStore } from \"./threadstore/ThreadStore.js\";\nimport type { CommentBody, ThreadData } from \"./types.js\";\nimport { User } from \"./types.js\";\nimport { UserStore } from \"./userstore/UserStore.js\";\n\nconst PLUGIN_KEY = new PluginKey(\"blocknote-comments\");\n\ntype CommentsPluginState = {\n /**\n * Decorations to be rendered, specifically to indicate the selected thread\n */\n decorations: DecorationSet;\n};\n\n/**\n * Calculate the thread positions from the current document state\n */\nfunction getUpdatedThreadPositions(doc: Node, markType: string) {\n const threadPositions = new Map<string, { from: number; to: number }>();\n\n // find all thread marks and store their position + create decoration for selected thread\n doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type.name === markType) {\n const thisThreadId = (mark.attrs as { threadId: string | undefined })\n .threadId;\n if (!thisThreadId) {\n return;\n }\n const from = pos;\n const to = from + node.nodeSize;\n\n // FloatingThreads component uses \"to\" as the position, so always store the largest \"to\" found\n // AnchoredThreads component uses \"from\" as the position, so always store the smallest \"from\" found\n const currentPosition = threadPositions.get(thisThreadId) ?? {\n from: Infinity,\n to: 0,\n };\n threadPositions.set(thisThreadId, {\n from: Math.min(from, currentPosition.from),\n to: Math.max(to, currentPosition.to),\n });\n }\n });\n });\n return threadPositions;\n}\n\nexport const CommentsExtension = createExtension(\n ({\n editor,\n options: { schema: commentEditorSchema, threadStore, resolveUsers },\n }: ExtensionOptions<{\n /**\n * The thread store implementation to use for storing and retrieving comment threads\n */\n threadStore: ThreadStore;\n /**\n * Resolve user information for comments.\n *\n * See [Comments](https://www.blocknotejs.org/docs/features/collaboration/comments) for more info.\n */\n resolveUsers: (userIds: string[]) => Promise<User[]>;\n /**\n * A schema to use for the comment editor (which allows you to customize the blocks and styles that are available in the comment editor)\n */\n schema?: CustomBlockNoteSchema<any, any, any>;\n }>) => {\n if (!resolveUsers) {\n throw new Error(\n \"resolveUsers is required to be defined when using comments\",\n );\n }\n if (!threadStore) {\n throw new Error(\n \"threadStore is required to be defined when using comments\",\n );\n }\n const markType = CommentMark.name;\n\n const userStore = new UserStore<User>(resolveUsers);\n const store = createStore(\n {\n pendingComment: false,\n selectedThreadId: undefined as string | undefined,\n threadPositions: new Map<string, { from: number; to: number }>(),\n },\n {\n onUpdate() {\n // If the selected thread id changed, we need to update the decorations\n if (\n store.state.selectedThreadId !== store.prevState.selectedThreadId\n ) {\n // So, we issue a transaction to update the decorations\n editor.transact((tr) => tr.setMeta(PLUGIN_KEY, true));\n }\n },\n },\n );\n\n const updateMarksFromThreads = (threads: Map<string, ThreadData>) => {\n editor.transact((tr) => {\n tr.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type.name === markType) {\n const markTypeInstance = mark.type;\n const markThreadId = mark.attrs.threadId as string;\n const thread = threads.get(markThreadId);\n const isOrphan = !!(\n !thread ||\n thread.resolved ||\n thread.deletedAt\n );\n\n if (isOrphan !== mark.attrs.orphan) {\n const trimmedFrom = Math.max(pos, 0);\n const trimmedTo = Math.min(\n pos + node.nodeSize,\n tr.doc.content.size - 1,\n tr.doc.content.size - 1,\n );\n tr.removeMark(trimmedFrom, trimmedTo, mark);\n tr.addMark(\n trimmedFrom,\n trimmedTo,\n markTypeInstance.create({\n ...mark.attrs,\n orphan: isOrphan,\n }),\n );\n\n if (isOrphan && store.state.selectedThreadId === markThreadId) {\n // unselect\n store.setState((prev) => ({\n ...prev,\n selectedThreadId: undefined,\n }));\n }\n }\n }\n });\n });\n });\n };\n\n return {\n key: \"comments\",\n store,\n prosemirrorPlugins: [\n new Plugin<CommentsPluginState>({\n key: PLUGIN_KEY,\n state: {\n init() {\n return {\n decorations: DecorationSet.empty,\n };\n },\n apply(tr, state) {\n const action = tr.getMeta(PLUGIN_KEY);\n\n if (!tr.docChanged && !action) {\n return state;\n }\n\n // only update threadPositions if the doc changed\n const newThreadPositions = tr.docChanged\n ? getUpdatedThreadPositions(tr.doc, markType)\n : store.state.threadPositions;\n\n if (\n newThreadPositions.size > 0 ||\n store.state.threadPositions.size > 0\n ) {\n // small optimization; don't emit event if threadPositions before / after were both empty\n store.setState((prev) => ({\n ...prev,\n threadPositions: newThreadPositions,\n }));\n }\n\n // update decorations if doc or selected thread changed\n const decorations = [] as any[];\n\n if (store.state.selectedThreadId) {\n const selectedThreadPosition = newThreadPositions.get(\n store.state.selectedThreadId,\n );\n\n if (selectedThreadPosition) {\n decorations.push(\n Decoration.inline(\n selectedThreadPosition.from,\n selectedThreadPosition.to,\n {\n class: \"bn-thread-mark-selected\",\n },\n ),\n );\n }\n }\n\n return {\n decorations: DecorationSet.create(tr.doc, decorations),\n };\n },\n },\n props: {\n decorations(state) {\n return (\n PLUGIN_KEY.getState(state)?.decorations ?? DecorationSet.empty\n );\n },\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return;\n }\n\n const node = view.state.doc.nodeAt(pos);\n\n if (!node) {\n // unselect\n store.setState((prev) => ({\n ...prev,\n selectedThreadId: undefined,\n }));\n return;\n }\n\n const commentMark = node.marks.find(\n (mark) =>\n mark.type.name === markType && mark.attrs.orphan !== true,\n );\n\n const threadId = commentMark?.attrs.threadId as\n | string\n | undefined;\n if (threadId !== store.state.selectedThreadId) {\n store.setState((prev) => ({\n ...prev,\n selectedThreadId: threadId,\n }));\n }\n },\n },\n }),\n ],\n threadStore: threadStore,\n mount() {\n const unsubscribe = threadStore.subscribe(updateMarksFromThreads);\n updateMarksFromThreads(threadStore.getThreads());\n\n const unsubscribeOnSelectionChange = editor.onSelectionChange(() => {\n if (store.state.pendingComment) {\n store.setState((prev) => ({\n ...prev,\n pendingComment: false,\n }));\n }\n });\n\n return () => {\n unsubscribe();\n unsubscribeOnSelectionChange();\n };\n },\n selectThread(threadId: string | undefined, scrollToThread = true) {\n if (store.state.selectedThreadId === threadId) {\n return;\n }\n store.setState((prev) => ({\n ...prev,\n pendingComment: false,\n selectedThreadId: threadId,\n }));\n\n if (threadId && scrollToThread) {\n const selectedThreadPosition =\n store.state.threadPositions.get(threadId);\n if (!selectedThreadPosition) {\n return;\n }\n (\n editor.prosemirrorView?.domAtPos(selectedThreadPosition.from)\n .node as Element | undefined\n )?.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n });\n }\n },\n startPendingComment() {\n store.setState((prev) => ({\n ...prev,\n selectedThreadId: undefined,\n pendingComment: true,\n }));\n editor.getExtension(ShowSelectionExtension)?.showSelection(true);\n },\n stopPendingComment() {\n store.setState((prev) => ({\n ...prev,\n selectedThreadId: undefined,\n pendingComment: false,\n }));\n editor.getExtension(ShowSelectionExtension)?.showSelection(false);\n },\n async createThread(options: {\n initialComment: { body: CommentBody; metadata?: any };\n metadata?: any;\n }) {\n const thread = await threadStore.createThread(options);\n if (threadStore.addThreadToDocument) {\n const view = editor.prosemirrorView!;\n const pmSelection = view.state.selection;\n const ystate = ySyncPluginKey.getState(view.state);\n const selection = {\n prosemirror: {\n head: pmSelection.head,\n anchor: pmSelection.anchor,\n },\n yjs: ystate\n ? getRelativeSelection(ystate.binding, view.state)\n : undefined,\n };\n await threadStore.addThreadToDocument({\n threadId: thread.id,\n selection,\n });\n } else {\n (editor as any)._tiptapEditor.commands.setMark(markType, {\n orphan: false,\n threadId: thread.id,\n });\n }\n },\n userStore,\n commentEditorSchema,\n tiptapExtensions: [CommentMark],\n } as const;\n },\n);\n","import { CommentData, ThreadData } from \"../types.js\";\n\nexport abstract class ThreadStoreAuth {\n abstract canCreateThread(): boolean;\n abstract canAddComment(thread: ThreadData): boolean;\n abstract canUpdateComment(comment: CommentData): boolean;\n abstract canDeleteComment(comment: CommentData): boolean;\n abstract canDeleteThread(thread: ThreadData): boolean;\n abstract canResolveThread(thread: ThreadData): boolean;\n abstract canUnresolveThread(thread: ThreadData): boolean;\n abstract canAddReaction(comment: CommentData, emoji?: string): boolean;\n abstract canDeleteReaction(comment: CommentData, emoji?: string): boolean;\n}\n","import { CommentData, ThreadData } from \"../types.js\";\nimport { ThreadStoreAuth } from \"./ThreadStoreAuth.js\";\n\n/*\n * The DefaultThreadStoreAuth class defines the authorization rules for interacting with comments.\n * We take a role (\"comment\" or \"editor\") and implement the rules.\n *\n * This class is then used in the UI to show / hide specific interactions.\n *\n * Rules:\n * - View-only users should not be able to see any comments\n * - Comment-only users and editors can:\n * - - create new comments / replies / reactions\n * - - edit / delete their own comments / reactions\n * - - resolve / unresolve threads\n * - Editors can also delete any comment or thread\n */\nexport class DefaultThreadStoreAuth extends ThreadStoreAuth {\n constructor(\n private readonly userId: string,\n private readonly role: \"comment\" | \"editor\",\n ) {\n super();\n }\n\n /**\n * Auth: should be possible by anyone with comment access\n */\n canCreateThread(): boolean {\n return true;\n }\n\n /**\n * Auth: should be possible by anyone with comment access\n */\n canAddComment(_thread: ThreadData): boolean {\n return true;\n }\n\n /**\n * Auth: should only be possible by the comment author\n */\n canUpdateComment(comment: CommentData): boolean {\n return comment.userId === this.userId;\n }\n\n /**\n * Auth: should be possible by the comment author OR an editor of the document\n */\n canDeleteComment(comment: CommentData): boolean {\n return comment.userId === this.userId || this.role === \"editor\";\n }\n\n /**\n * Auth: should only be possible by an editor of the document\n */\n canDeleteThread(_thread: ThreadData): boolean {\n return this.role === \"editor\";\n }\n\n /**\n * Auth: should be possible by anyone with comment access\n */\n canResolveThread(_thread: ThreadData): boolean {\n return true;\n }\n\n /**\n * Auth: should be possible by anyone with comment access\n */\n canUnresolveThread(_thread: ThreadData): boolean {\n return true;\n }\n\n /**\n * Auth: should be possible by anyone with comment access\n *\n * Note: will also check if the user has already reacted with the same emoji. TBD: is that a nice design or should this responsibility be outside of auth?\n */\n canAddReaction(comment: CommentData, emoji?: string): boolean {\n if (!emoji) {\n return true;\n }\n\n return !comment.reactions.some(\n (reaction) =>\n reaction.emoji === emoji && reaction.userIds.includes(this.userId),\n );\n }\n\n /**\n * Auth: should be possible by anyone with comment access\n *\n * Note: will also check if the user has already reacted with the same emoji. TBD: is that a nice design or should this responsibility be outside of auth?\n */\n canDeleteReaction(comment: CommentData, emoji?: string): boolean {\n if (!emoji) {\n return true;\n }\n\n return comment.reactions.some(\n (reaction) =>\n reaction.emoji === emoji && reaction.userIds.includes(this.userId),\n );\n }\n}\n","import { CommentBody, CommentData, ThreadData } from \"../types.js\";\nimport { ThreadStoreAuth } from \"./ThreadStoreAuth.js\";\n\n/**\n * ThreadStore is an abstract class that defines the interface\n * to read / add / update / delete threads and comments.\n */\nexport abstract class ThreadStore {\n public readonly auth: ThreadStoreAuth;\n\n constructor(auth: ThreadStoreAuth) {\n this.auth = auth;\n }\n\n /**\n * A \"thread\" in the ThreadStore only contains information about the content\n * of the thread / comments. It does not contain information about the position.\n *\n * This function can be implemented to store the thread in the document (by creating a mark)\n * If not implemented, default behavior will apply (creating the mark via TipTap)\n * See CommentsPlugin.ts for more details.\n */\n abstract addThreadToDocument?(options: {\n threadId: string;\n selection: {\n prosemirror: {\n head: number;\n anchor: number;\n };\n yjs?: {\n head: any;\n anchor: any;\n };\n };\n }): Promise<void>;\n\n /**\n * Creates a new thread with an initial comment.\n */\n abstract createThread(options: {\n initialComment: {\n body: CommentBody;\n metadata?: any;\n };\n metadata?: any;\n }): Promise<ThreadData>;\n\n /**\n * Adds a comment to a thread.\n */\n abstract addComment(options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n }): Promise<CommentData>;\n\n /**\n * Updates a comment in a thread.\n */\n abstract updateComment(options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n commentId: string;\n }): Promise<void>;\n\n /**\n * Deletes a comment from a thread.\n */\n abstract deleteComment(options: {\n threadId: string;\n commentId: string;\n }): Promise<void>;\n\n /**\n * Deletes a thread.\n */\n abstract deleteThread(options: { threadId: string }): Promise<void>;\n\n /**\n * Marks a thread as resolved.\n */\n abstract resolveThread(options: { threadId: string }): Promise<void>;\n\n /**\n * Marks a thread as unresolved.\n */\n abstract unresolveThread(options: { threadId: string }): Promise<void>;\n\n /**\n * Adds a reaction to a comment.\n *\n * Auth: should be possible by anyone with comment access\n */\n abstract addReaction(options: {\n threadId: string;\n commentId: string;\n emoji: string;\n }): Promise<void>;\n\n /**\n * Deletes a reaction from a comment.\n *\n * Auth: should be possible by the reaction author\n */\n abstract deleteReaction(options: {\n threadId: string;\n commentId: string;\n emoji: string;\n }): Promise<void>;\n\n /**\n * Retrieve data for a specific thread.\n */\n abstract getThread(threadId: string): ThreadData;\n\n /**\n * Retrieve all threads.\n */\n abstract getThreads(): Map<string, ThreadData>;\n\n /**\n * Subscribe to changes in the thread store.\n *\n * @returns a function to unsubscribe from the thread store\n */\n abstract subscribe(\n cb: (threads: Map<string, ThreadData>) => void,\n ): () => void;\n}\n","import type {\n TCollabComment,\n TCollabThread,\n TiptapCollabProvider,\n} from \"@hocuspocus/provider\";\nimport {\n CommentBody,\n CommentData,\n CommentReactionData,\n ThreadData,\n} from \"../types.js\";\nimport { ThreadStore } from \"./ThreadStore.js\";\nimport { ThreadStoreAuth } from \"./ThreadStoreAuth.js\";\n\ntype ReactionAsTiptapData = {\n emoji: string;\n createdAt: number;\n userId: string;\n};\n\n/**\n * The `TiptapThreadStore` integrates with Tiptap's collaboration provider for comment management.\n * You can pass a `TiptapCollabProvider` to the constructor which takes care of storing the comments.\n *\n * Under the hood, this actually works similarly to the `YjsThreadStore` implementation. (comments are stored in the Yjs document)\n */\nexport class TiptapThreadStore extends ThreadStore {\n constructor(\n private readonly userId: string,\n private readonly provider: TiptapCollabProvider,\n auth: ThreadStoreAuth, // TODO: use?\n ) {\n super(auth);\n }\n\n /**\n * Creates a new thread with an initial comment.\n */\n public async createThread(options: {\n initialComment: {\n body: CommentBody;\n metadata?: any;\n };\n metadata?: any;\n }): Promise<ThreadData> {\n let thread = this.provider.createThread({\n data: options.metadata,\n });\n\n thread = this.provider.addComment(thread.id, {\n content: options.initialComment.body,\n data: {\n metadata: options.initialComment.metadata,\n userId: this.userId,\n },\n });\n\n return this.tiptapThreadToThreadData(thread);\n }\n\n // TipTapThreadStore does not support addThreadToDocument\n public addThreadToDocument = undefined;\n\n /**\n * Adds a comment to a thread.\n */\n public async addComment(options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n }): Promise<CommentBody> {\n const thread = this.provider.addComment(options.threadId, {\n content: options.comment.body,\n data: {\n metadata: options.comment.metadata,\n userId: this.userId,\n },\n });\n\n return this.tiptapCommentToCommentData(\n thread.comments[thread.comments.length - 1],\n );\n }\n\n /**\n * Updates a comment in a thread.\n */\n public async updateComment(options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n commentId: string;\n }) {\n const comment = this.provider.getThreadComment(\n options.threadId,\n options.commentId,\n true,\n );\n\n if (!comment) {\n throw new Error(\"Comment not found\");\n }\n\n this.provider.updateComment(options.threadId, options.commentId, {\n content: options.comment.body,\n data: {\n ...comment.data,\n metadata: options.comment.metadata,\n },\n });\n }\n\n private tiptapCommentToCommentData(comment: TCollabComment): CommentData {\n const reactions: CommentReactionData[] = [];\n\n for (const reaction of (comment.data?.reactions ||\n []) as ReactionAsTiptapData[]) {\n const existingReaction = reactions.find(\n (r) => r.emoji === reaction.emoji,\n );\n if (existingReaction) {\n existingReaction.userIds.push(reaction.userId);\n existingReaction.createdAt = new Date(\n Math.min(existingReaction.createdAt.getTime(), reaction.createdAt),\n );\n } else {\n reactions.push({\n emoji: reaction.emoji,\n createdAt: new Date(reaction.createdAt),\n userIds: [reaction.userId],\n });\n }\n }\n\n return {\n type: \"comment\",\n id: comment.id,\n body: comment.content,\n metadata: comment.data?.metadata,\n userId: comment.data?.userId,\n createdAt: new Date(comment.createdAt),\n updatedAt: new Date(comment.updatedAt),\n reactions,\n };\n }\n\n private tiptapThreadToThreadData(thread: TCollabThread): ThreadData {\n return {\n type: \"thread\",\n id: thread.id,\n comments: thread.comments.map((comment) =>\n this.tiptapCommentToCommentData(comment),\n ),\n resolved: !!thread.resolvedAt,\n metadata: thread.data?.metadata,\n createdAt: new Date(thread.createdAt),\n updatedAt: new Date(thread.updatedAt),\n };\n }\n\n /**\n * Deletes a comment from a thread.\n */\n public async deleteComment(options: { threadId: string; commentId: string }) {\n this.provider.deleteComment(options.threadId, options.commentId);\n }\n\n /**\n * Deletes a thread.\n */\n public async deleteThread(options: { threadId: string }) {\n this.provider.deleteThread(options.threadId);\n }\n\n /**\n * Marks a thread as resolved.\n */\n public async resolveThread(options: { threadId: string }) {\n this.provider.updateThread(options.threadId, {\n resolvedAt: new Date().toISOString(),\n });\n }\n\n /**\n * Marks a thread as unresolved.\n */\n public async unresolveThread(options: { threadId: string }) {\n this.provider.updateThread(options.threadId, {\n resolvedAt: null,\n });\n }\n\n /**\n * Adds a reaction to a comment.\n *\n * Auth: should be possible by anyone with comment access\n */\n public async addReaction(options: {\n threadId: string;\n commentId: string;\n emoji: string;\n }) {\n const comment = this.provider.getThreadComment(\n options.threadId,\n options.commentId,\n true,\n );\n\n if (!comment) {\n throw new Error(\"Comment not found\");\n }\n\n this.provider.updateComment(options.threadId, options.commentId, {\n data: {\n ...comment.data,\n reactions: [\n ...((comment.data?.reactions || []) as ReactionAsTiptapData[]),\n {\n emoji: options.emoji,\n createdAt: Date.now(),\n userId: this.userId,\n },\n ],\n },\n });\n }\n\n /**\n * Deletes a reaction from a comment.\n *\n * Auth: should be possible by the reaction author\n */\n public async deleteReaction(options: {\n threadId: string;\n commentId: string;\n emoji: string;\n }) {\n const comment = this.provider.getThreadComment(\n options.threadId,\n options.commentId,\n true,\n );\n\n if (!comment) {\n throw new Error(\"Comment not found\");\n }\n\n this.provider.updateComment(options.threadId, options.commentId, {\n data: {\n ...comment.data,\n reactions: (\n (comment.data?.reactions || []) as ReactionAsTiptapData[]\n ).filter(\n (reaction) =>\n reaction.emoji !== options.emoji && reaction.userId !== this.userId,\n ),\n },\n });\n }\n\n public getThread(threadId: string): ThreadData {\n const thread = this.provider.getThread(threadId);\n\n if (!thread) {\n throw new Error(\"Thread not found\");\n }\n\n return this.tiptapThreadToThreadData(thread);\n }\n\n public getThreads(): Map<string, ThreadData> {\n return new Map(\n this.provider\n .getThreads()\n .map((thread) => [thread.id, this.tiptapThreadToThreadData(thread)]),\n );\n }\n\n public subscribe(cb: (threads: Map<string, ThreadData>) => void): () => void {\n const newCb = () => {\n cb(this.getThreads());\n };\n this.provider.watchThreads(newCb);\n return () => {\n this.provider.unwatchThreads(newCb);\n };\n }\n}\n","import * as Y from \"yjs\";\nimport { CommentData, CommentReactionData, ThreadData } from \"../../types.js\";\n\nexport function commentToYMap(comment: CommentData) {\n const yMap = new Y.Map<any>();\n yMap.set(\"id\", comment.id);\n yMap.set(\"userId\", comment.userId);\n yMap.set(\"createdAt\", comment.createdAt.getTime());\n yMap.set(\"updatedAt\", comment.updatedAt.getTime());\n if (comment.deletedAt) {\n yMap.set(\"deletedAt\", comment.deletedAt.getTime());\n yMap.set(\"body\", undefined);\n } else {\n yMap.set(\"body\", comment.body);\n }\n if (comment.reactions.length > 0) {\n throw new Error(\"Reactions should be empty in commentToYMap\");\n }\n\n /**\n * Reactions are stored in a map keyed by {userId-emoji},\n * this makes it easy to add / remove reactions and in a way that works local-first.\n * The cost is that \"reading\" the reactions is a bit more complex (see yMapToReactions).\n */\n yMap.set(\"reactionsByUser\", new Y.Map());\n yMap.set(\"metadata\", comment.metadata);\n\n return yMap;\n}\n\nexport function threadToYMap(thread: ThreadData) {\n const yMap = new Y.Map();\n yMap.set(\"id\", thread.id);\n yMap.set(\"createdAt\", thread.createdAt.getTime());\n yMap.set(\"updatedAt\", thread.updatedAt.getTime());\n const commentsArray = new Y.Array<Y.Map<any>>();\n\n commentsArray.push(thread.comments.map((comment) => commentToYMap(comment)));\n\n yMap.set(\"comments\", commentsArray);\n yMap.set(\"resolved\", thread.resolved);\n yMap.set(\"resolvedUpdatedAt\", thread.resolvedUpdatedAt?.getTime());\n yMap.set(\"resolvedBy\", thread.resolvedBy);\n yMap.set(\"metadata\", thread.metadata);\n return yMap;\n}\n\ntype SingleUserCommentReactionData = {\n emoji: string;\n createdAt: Date;\n userId: string;\n};\n\nexport function yMapToReaction(\n yMap: Y.Map<any>,\n): SingleUserCommentReactionData {\n return {\n emoji: yMap.get(\"emoji\"),\n createdAt: new Date(yMap.get(\"createdAt\")),\n userId: yMap.get(\"userId\"),\n };\n}\n\nfunction yMapToReactions(yMap: Y.Map<any>): CommentReactionData[] {\n const flatReactions = [...yMap.values()].map((reaction: Y.Map<any>) =>\n yMapToReaction(reaction),\n );\n // combine reactions by the same emoji\n return flatReactions.reduce(\n (acc: CommentReactionData[], reaction: SingleUserCommentReactionData) => {\n const existingReaction = acc.find((r) => r.emoji === reaction.emoji);\n if (existingReaction) {\n existingReaction.userIds.push(reaction.userId);\n existingReaction.createdAt = new Date(\n Math.min(\n existingReaction.createdAt.getTime(),\n reaction.createdAt.getTime(),\n ),\n );\n } else {\n acc.push({\n emoji: reaction.emoji,\n createdAt: reaction.createdAt,\n userIds: [reaction.userId],\n });\n }\n return acc;\n },\n [] as CommentReactionData[],\n );\n}\n\nexport function yMapToComment(yMap: Y.Map<any>): CommentData {\n return {\n type: \"comment\",\n id: yMap.get(\"id\"),\n userId: yMap.get(\"userId\"),\n createdAt: new Date(yMap.get(\"createdAt\")),\n updatedAt: new Date(yMap.get(\"updatedAt\")),\n deletedAt: yMap.get(\"deletedAt\")\n ? new Date(yMap.get(\"deletedAt\"))\n : undefined,\n reactions: yMapToReactions(yMap.get(\"reactionsByUser\")),\n metadata: yMap.get(\"metadata\"),\n body: yMap.get(\"body\"),\n };\n}\n\nexport function yMapToThread(yMap: Y.Map<any>): ThreadData {\n return {\n type: \"thread\",\n id: yMap.get(\"id\"),\n createdAt: new Date(yMap.get(\"createdAt\")),\n updatedAt: new Date(yMap.get(\"updatedAt\")),\n comments: ((yMap.get(\"comments\") as Y.Array<Y.Map<any>>) || []).map(\n (comment) => yMapToComment(comment),\n ),\n resolved: yMap.get(\"resolved\"),\n resolvedUpdatedAt: new Date(yMap.get(\"resolvedUpdatedAt\")),\n resolvedBy: yMap.get(\"resolvedBy\"),\n metadata: yMap.get(\"metadata\"),\n };\n}\n","import * as Y from \"yjs\";\nimport { ThreadData } from \"../../types.js\";\nimport { ThreadStore } from \"../ThreadStore.js\";\nimport { ThreadStoreAuth } from \"../ThreadStoreAuth.js\";\nimport { yMapToThread } from \"./yjsHelpers.js\";\n\n/**\n * This is an abstract class that only implements the READ methods required by the ThreadStore interface.\n * The data is read from a Yjs Map.\n */\nexport abstract class YjsThreadStoreBase extends ThreadStore {\n constructor(\n protected readonly threadsYMap: Y.Map<any>,\n auth: ThreadStoreAuth,\n ) {\n super(auth);\n }\n\n // TODO: async / reactive interface?\n public getThread(threadId: string) {\n const yThread = this.threadsYMap.get(threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n const thread = yMapToThread(yThread);\n return thread;\n }\n\n public getThreads(): Map<string, ThreadData> {\n const threadMap = new Map<string, ThreadData>();\n this.threadsYMap.forEach((yThread, id) => {\n if (yThread instanceof Y.Map) {\n threadMap.set(id, yMapToThread(yThread));\n }\n });\n return threadMap;\n }\n\n public subscribe(cb: (threads: Map<string, ThreadData>) => void) {\n const observer = () => {\n cb(this.getThreads());\n };\n\n this.threadsYMap.observeDeep(observer);\n\n return () => {\n this.threadsYMap.unobserveDeep(observer);\n };\n }\n}\n","import * as Y from \"yjs\";\nimport { CommentBody } from \"../../types.js\";\nimport { ThreadStoreAuth } from \"../ThreadStoreAuth.js\";\nimport { YjsThreadStoreBase } from \"./YjsThreadStoreBase.js\";\n\n/**\n * This is a REST-based implementation of the YjsThreadStoreBase.\n * It Reads data directly from the underlying document (same as YjsThreadStore),\n * but for Writes, it sends data to a REST API that should:\n * - check the user has the correct permissions to make the desired changes\n * - apply the updates to the underlying Yjs document\n *\n * (see https://github.com/TypeCellOS/BlockNote-demo-nextjs-hocuspocus)\n *\n * The reason we still use the Yjs document as underlying storage is that it makes it easy to\n * sync updates in real-time to other collaborators.\n * (but technically, you could also implement a different storage altogether\n * and not store the thread related data in the Yjs document)\n */\nexport class RESTYjsThreadStore extends YjsThreadStoreBase {\n constructor(\n private readonly BASE_URL: string,\n private readonly headers: Record<string, string>,\n threadsYMap: Y.Map<any>,\n auth: ThreadStoreAuth,\n ) {\n super(threadsYMap, auth);\n }\n\n private doRequest = async (path: string, method: string, body?: any) => {\n const response = await fetch(`${this.BASE_URL}${path}`, {\n method,\n body: JSON.stringify(body),\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.headers,\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to ${method} ${path}: ${response.statusText}`);\n }\n\n return response.json();\n };\n\n public addThreadToDocument = async (options: {\n threadId: string;\n selection: {\n prosemirror: {\n head: number;\n anchor: number;\n };\n yjs: {\n head: any;\n anchor: any;\n };\n };\n }) => {\n const { threadId, ...rest } = options;\n return this.doRequest(`/${threadId}/addToDocument`, \"POST\", rest);\n };\n\n public createThread = async (options: {\n initialComment: {\n body: CommentBody;\n metadata?: any;\n };\n metadata?: any;\n }) => {\n return this.doRequest(\"\", \"POST\", options);\n };\n\n public addComment = (options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n }) => {\n const { threadId, ...rest } = options;\n return this.doRequest(`/${threadId}/comments`, \"POST\", rest);\n };\n\n public updateComment = (options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n commentId: string;\n }) => {\n const { threadId, commentId, ...rest } = options;\n return this.doRequest(`/${threadId}/comments/${commentId}`, \"PUT\", rest);\n };\n\n public deleteComment = (options: {\n threadId: string;\n commentId: string;\n softDelete?: boolean;\n }) => {\n const { threadId, commentId, ...rest } = options;\n return this.doRequest(\n `/${threadId}/comments/${commentId}?soft=${!!rest.softDelete}`,\n \"DELETE\",\n );\n };\n\n public deleteThread = (options: { threadId: string }) => {\n return this.doRequest(`/${options.threadId}`, \"DELETE\");\n };\n\n public resolveThread = (options: { threadId: string }) => {\n return this.doRequest(`/${options.threadId}/resolve`, \"POST\");\n };\n\n public unresolveThread = (options: { threadId: string }) => {\n return this.doRequest(`/${options.threadId}/unresolve`, \"POST\");\n };\n\n public addReaction = (options: {\n threadId: string;\n commentId: string;\n emoji: string;\n }) => {\n const { threadId, commentId, ...rest } = options;\n return this.doRequest(\n `/${threadId}/comments/${commentId}/reactions`,\n \"POST\",\n rest,\n );\n };\n\n public deleteReaction = (options: {\n threadId: string;\n commentId: string;\n emoji: string;\n }) => {\n return this.doRequest(\n `/${options.threadId}/comments/${options.commentId}/reactions/${options.emoji}`,\n \"DELETE\",\n );\n };\n}\n","import { v4 } from \"uuid\";\nimport * as Y from \"yjs\";\nimport { CommentBody, CommentData, ThreadData } from \"../../types.js\";\nimport { ThreadStoreAuth } from \"../ThreadStoreAuth.js\";\nimport { YjsThreadStoreBase } from \"./YjsThreadStoreBase.js\";\nimport {\n commentToYMap,\n threadToYMap,\n yMapToComment,\n yMapToThread,\n} from \"./yjsHelpers.js\";\n\n/**\n * This is a Yjs-based implementation of the ThreadStore interface.\n *\n * It reads and writes thread / comments information directly to the underlying Yjs Document.\n *\n * @important While this is the easiest to add to your app, there are two challenges:\n * - The user needs to be able to write to the Yjs document to store the information.\n * So a user without write access to the Yjs document cannot leave any comments.\n * - Even with write access, the operations are not secure. Unless your Yjs server\n * guards against malicious operations, it's technically possible for one user to make changes to another user's comments, etc.\n * (even though these options are not visible in the UI, a malicious user can make unauthorized changes to the underlying Yjs document)\n */\nexport class YjsThreadStore extends YjsThreadStoreBase {\n constructor(\n private readonly userId: string,\n threadsYMap: Y.Map<any>,\n auth: ThreadStoreAuth,\n ) {\n super(threadsYMap, auth);\n }\n\n private transact = <T, R>(\n fn: (options: T) => R,\n ): ((options: T) => Promise<R>) => {\n return async (options: T) => {\n return this.threadsYMap.doc!.transact(() => {\n return fn(options);\n });\n };\n };\n\n public createThread = this.transact(\n (options: {\n initialComment: {\n body: CommentBody;\n metadata?: any;\n };\n metadata?: any;\n }) => {\n if (!this.auth.canCreateThread()) {\n throw new Error(\"Not authorized\");\n }\n\n const date = new Date();\n\n const comment: CommentData = {\n type: \"comment\",\n id: v4(),\n userId: this.userId,\n createdAt: date,\n updatedAt: date,\n reactions: [],\n metadata: options.initialComment.metadata,\n body: options.initialComment.body,\n };\n\n const thread: ThreadData = {\n type: \"thread\",\n id: v4(),\n createdAt: date,\n updatedAt: date,\n comments: [comment],\n resolved: false,\n metadata: options.metadata,\n };\n\n this.threadsYMap.set(thread.id, threadToYMap(thread));\n\n return thread;\n },\n );\n\n // YjsThreadStore does not support addThreadToDocument\n public addThreadToDocument = undefined;\n\n public addComment = this.transact(\n (options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n if (!this.auth.canAddComment(yMapToThread(yThread))) {\n throw new Error(\"Not authorized\");\n }\n\n const date = new Date();\n const comment: CommentData = {\n type: \"comment\",\n id: v4(),\n userId: this.userId,\n createdAt: date,\n updatedAt: date,\n deletedAt: undefined,\n reactions: [],\n metadata: options.comment.metadata,\n body: options.comment.body,\n };\n\n (yThread.get(\"comments\") as Y.Array<Y.Map<any>>).push([\n commentToYMap(comment),\n ]);\n\n yThread.set(\"updatedAt\", new Date().getTime());\n return comment;\n },\n );\n\n public updateComment = this.transact(\n (options: {\n comment: {\n body: CommentBody;\n metadata?: any;\n };\n threadId: string;\n commentId: string;\n }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n const yCommentIndex = yArrayFindIndex(\n yThread.get(\"comments\"),\n (comment) => comment.get(\"id\") === options.commentId,\n );\n\n if (yCommentIndex === -1) {\n throw new Error(\"Comment not found\");\n }\n\n const yComment = yThread.get(\"comments\").get(yCommentIndex);\n\n if (!this.auth.canUpdateComment(yMapToComment(yComment))) {\n throw new Error(\"Not authorized\");\n }\n\n yComment.set(\"body\", options.comment.body);\n yComment.set(\"updatedAt\", new Date().getTime());\n yComment.set(\"metadata\", options.comment.metadata);\n },\n );\n\n public deleteComment = this.transact(\n (options: {\n threadId: string;\n commentId: string;\n softDelete?: boolean;\n }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n const yCommentIndex = yArrayFindIndex(\n yThread.get(\"comments\"),\n (comment) => comment.get(\"id\") === options.commentId,\n );\n\n if (yCommentIndex === -1) {\n throw new Error(\"Comment not found\");\n }\n\n const yComment = yThread.get(\"comments\").get(yCommentIndex);\n\n if (!this.auth.canDeleteComment(yMapToComment(yComment))) {\n throw new Error(\"Not authorized\");\n }\n\n if (yComment.get(\"deletedAt\")) {\n throw new Error(\"Comment already deleted\");\n }\n\n if (options.softDelete) {\n yComment.set(\"deletedAt\", new Date().getTime());\n yComment.set(\"body\", undefined);\n } else {\n yThread.get(\"comments\").delete(yCommentIndex);\n }\n\n if (\n (yThread.get(\"comments\") as Y.Array<any>)\n .toArray()\n .every((comment) => comment.get(\"deletedAt\"))\n ) {\n // all comments deleted\n if (options.softDelete) {\n yThread.set(\"deletedAt\", new Date().getTime());\n } else {\n this.threadsYMap.delete(options.threadId);\n }\n }\n\n yThread.set(\"updatedAt\", new Date().getTime());\n },\n );\n\n public deleteThread = this.transact((options: { threadId: string }) => {\n if (\n !this.auth.canDeleteThread(\n yMapToThread(this.threadsYMap.get(options.threadId)),\n )\n ) {\n throw new Error(\"Not authorized\");\n }\n\n this.threadsYMap.delete(options.threadId);\n });\n\n public resolveThread = this.transact((options: { threadId: string }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n if (!this.auth.canResolveThread(yMapToThread(yThread))) {\n throw new Error(\"Not authorized\");\n }\n\n yThread.set(\"resolved\", true);\n yThread.set(\"resolvedUpdatedAt\", new Date().getTime());\n yThread.set(\"resolvedBy\", this.userId);\n });\n\n public unresolveThread = this.transact((options: { threadId: string }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n if (!this.auth.canUnresolveThread(yMapToThread(yThread))) {\n throw new Error(\"Not authorized\");\n }\n\n yThread.set(\"resolved\", false);\n yThread.set(\"resolvedUpdatedAt\", new Date().getTime());\n });\n\n public addReaction = this.transact(\n (options: { threadId: string; commentId: string; emoji: string }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n const yCommentIndex = yArrayFindIndex(\n yThread.get(\"comments\"),\n (comment) => comment.get(\"id\") === options.commentId,\n );\n\n if (yCommentIndex === -1) {\n throw new Error(\"Comment not found\");\n }\n\n const yComment = yThread.get(\"comments\").get(yCommentIndex);\n\n if (!this.auth.canAddReaction(yMapToComment(yComment), options.emoji)) {\n throw new Error(\"Not authorized\");\n }\n\n const date = new Date();\n\n const key = `${this.userId}-${options.emoji}`;\n\n const reactionsByUser = yComment.get(\"reactionsByUser\");\n\n if (reactionsByUser.has(key)) {\n // already exists\n return;\n } else {\n const reaction = new Y.Map();\n reaction.set(\"emoji\", options.emoji);\n reaction.set(\"createdAt\", date.getTime());\n reaction.set(\"userId\", this.userId);\n reactionsByUser.set(key, reaction);\n }\n },\n );\n\n public deleteReaction = this.transact(\n (options: { threadId: string; commentId: string; emoji: string }) => {\n const yThread = this.threadsYMap.get(options.threadId);\n if (!yThread) {\n throw new Error(\"Thread not found\");\n }\n\n const yCommentIndex = yArrayFindIndex(\n yThread.get(\"comments\"),\n (comment) => comment.get(\"id\") === options.commentId,\n );\n\n if (yCommentIndex === -1) {\n throw new Error(\"Comment not found\");\n }\n\n const yComment = yThread.get(\"comments\").get(yCommentIndex);\n\n if (\n !this.auth.canDeleteReaction(yMapToComment(yComment), options.emoji)\n ) {\n throw new Error(\"Not authorized\");\n }\n\n const key = `${this.userId}-${options.emoji}`;\n\n const reactionsByUser = yComment.get(\"reactionsByUser\");\n\n reactionsByUser.delete(key);\n },\n );\n}\n\nfunction yArrayFindIndex(\n yArray: Y.Array<any>,\n predicate: (item: any) => boolean,\n) {\n for (let i = 0; i < yArray.length; i++) {\n if (predicate(yArray.get(i))) {\n return i;\n }\n }\n return -1;\n}\n"],"names":["CommentMark","Mark","element","attributes","HTMLAttributes","mergeAttributes","extension","UserStore","EventEmitter","resolveUsers","__publicField","userIds","missingUsers","id","users","user","userId","cb","PLUGIN_KEY","PluginKey","getUpdatedThreadPositions","doc","markType","threadPositions","node","pos","mark","thisThreadId","from","to","currentPosition","CommentsExtension","createExtension","editor","commentEditorSchema","threadStore","userStore","store","createStore","tr","updateMarksFromThreads","threads","markTypeInstance","markThreadId","thread","isOrphan","trimmedFrom","trimmedTo","prev","Plugin","DecorationSet","state","action","newThreadPositions","decorations","selectedThreadPosition","Decoration","_a","view","event","commentMark","threadId","unsubscribe","unsubscribeOnSelectionChange","scrollToThread","_b","ShowSelectionExtension","options","pmSelection","ystate","ySyncPluginKey","selection","getRelativeSelection","ThreadStoreAuth","DefaultThreadStoreAuth","role","_thread","comment","emoji","reaction","ThreadStore","auth","TiptapThreadStore","provider","reactions","existingReaction","r","_c","newCb","commentToYMap","yMap","Y","threadToYMap","commentsArray","yMapToReaction","yMapToReactions","acc","yMapToComment","yMapToThread","YjsThreadStoreBase","threadsYMap","yThread","threadMap","observer","RESTYjsThreadStore","BASE_URL","headers","path","method","body","response","rest","commentId","YjsThreadStore","fn","date","v4","yCommentIndex","yArrayFindIndex","yComment","key","reactionsByUser","yArray","predicate","i"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ "use strict";var Pt=Object.defineProperty;var Nt=(e,t,n)=>t in e?Pt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var I=(e,t,n)=>Nt(e,typeof t!="symbol"?t+"":t,n);const T=require("prosemirror-tables"),S=require("@tiptap/core"),z=require("prosemirror-state"),$=require("prosemirror-view"),ye=require("prosemirror-transform"),j=require("y-prosemirror"),y=require("./BlockNoteExtension-BWw0r8Gy.cjs"),m=require("./blockToNode-w7H99R6p.cjs"),Ht=require("@tiptap/extension-bold"),_t=require("@tiptap/extension-code"),Dt=require("@tiptap/extension-italic"),Ot=require("@tiptap/extension-strike"),Vt=require("@tiptap/extension-underline"),F=require("@tiptap/pm/model"),Rt=require("prosemirror-highlight"),Ft=require("prosemirror-highlight/shiki"),P=require("prosemirror-model"),fe=require("@tiptap/pm/state"),ee=require("@tiptap/pm/view"),q=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},Wt=q(Ht),qt=q(_t),Ut=q(Dt),$t=q(Ot),jt=q(Vt),ve=()=>typeof navigator<"u"&&(/Mac/.test(navigator.platform)||/AppleWebKit/.test(navigator.userAgent)&&/Mobile\/\w+/.test(navigator.userAgent));function B(e,t="Ctrl"){return ve()?e.replace("Mod","⌘"):e.replace("Mod",t)}function V(...e){return[...new Set(e.filter(t=>t).join(" ").split(" "))].join(" ")}const Gt=()=>/^((?!chrome|android).)*safari/i.test(navigator.userAgent);function Se(e,t,n,o){const r=document.createElement("div");r.className=V("bn-block-content",n.class),r.setAttribute("data-content-type",e);for(const[i,s]of Object.entries(n))i!=="class"&&r.setAttribute(i,s);const a=document.createElement(t);a.className=V("bn-inline-content",o.class);for(const[i,s]of Object.entries(o))i!=="class"&&a.setAttribute(i,s);return r.appendChild(a),{dom:r,contentDOM:a}}const te=(e,t)=>{let n=m.blockToNode(e,t.pmSchema);n.type.name==="blockContainer"&&(n=n.firstChild);const o=t.pmSchema.nodes[n.type.name].spec.toDOM;if(o===void 0)throw new Error("This block has no default HTML serialization as its corresponding TipTap node doesn't implement `renderHTML`.");const r=o(n);if(typeof r!="object"||!("dom"in r))throw new Error("Cannot use this block's default HTML serialization as its corresponding TipTap node's `renderHTML` function does not return an object with the `dom` property.");return r};function Ee(e,t="<br>"){const n=e.querySelectorAll("p");if(n.length>1){const o=n[0];for(let r=1;r<n.length;r++){const a=n[r];o.innerHTML+=t+a.innerHTML,a.remove()}}}function W(e){return"data-"+e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}function Zt(e){const t=e.split("/");return!t.length||t[t.length-1]===""?e:t[t.length-1]}function zt(e){var n;const t=["mp4","webm","ogg","mov","mkv","flv","avi","wmv","m4v"];try{const r=((n=new URL(e).pathname.split(".").pop())==null?void 0:n.toLowerCase())||"";return t.includes(r)}catch{return!1}}function xe(e){const t={};return Object.entries(e).forEach(([n,o])=>{t[n]={default:o.default,keepOnSplit:!0,parseHTML:r=>{const a=r.getAttribute(W(n));if(a===null)return null;if(o.default===void 0&&o.type==="boolean"||o.default!==void 0&&typeof o.default=="boolean")return a==="true"?!0:a==="false"?!1:null;if(o.default===void 0&&o.type==="number"||o.default!==void 0&&typeof o.default=="number"){const i=parseFloat(a);return!Number.isNaN(i)&&Number.isFinite(i)?i:null}return a},renderHTML:r=>r[n]!==o.default?{[W(n)]:r[n]}:{}}}),t}function Me(e,t,n,o){const r=e();if(r===void 0)throw new Error("Cannot find node position");const i=n.state.doc.resolve(r).node().attrs.id;if(!i)throw new Error("Block doesn't have id");const s=t.getBlock(i);if(s.type!==o)throw new Error("Block type does not match");return s}function Z(e,t,n,o,r=!1,a){const i=document.createElement("div");if(a!==void 0)for(const[s,c]of Object.entries(a))s!=="class"&&i.setAttribute(s,c);i.className=V("bn-block-content",(a==null?void 0:a.class)||""),i.setAttribute("data-content-type",t);for(const[s,c]of Object.entries(n)){const u=o[s].default;c!==u&&i.setAttribute(W(s),c)}return r&&i.setAttribute("data-file-block",""),i.appendChild(e.dom),e.contentDOM&&(e.contentDOM.className=V("bn-inline-content",e.contentDOM.className)),{...e,dom:i}}function we(e,t,n){return{config:{type:e.type,content:e.content,propSchema:t},implementation:{node:e.node,render:te,toExternalHTML:te},extensions:n}}function Le(e,t){e.stopEvent=n=>(n.type==="mousedown"&&setTimeout(()=>{t.view.dom.blur()},10),!0)}function Be(e,t){const n=[{tag:"[data-content-type="+e.type+"]",contentElement:".bn-inline-content"}];return t.parse&&n.push({tag:"*",getAttrs(o){var a;if(typeof o=="string")return!1;const r=(a=t.parse)==null?void 0:a.call(t,o);return r===void 0?!1:r},getContent:e.content==="inline"||e.content==="none"?(o,r)=>{var a;if(t.parseContent)return t.parseContent({el:o,schema:r});if(e.content==="inline"){const s=o.cloneNode(!0);return Ee(s,(a=t.meta)!=null&&a.code?`
2
+ `:"<br>"),F.DOMParser.fromSchema(r).parse(s,{topNode:r.nodes.paragraph.create()}).content}return F.Fragment.empty}:void 0}),n}function Kt(e,t,n,o){var a,i,s,c;const r=t.node||S.Node.create({name:e.type,content:e.content==="inline"?"inline*":e.content==="none"?"":e.content,group:"blockContent",selectable:((a=t.meta)==null?void 0:a.selectable)??!0,isolating:((i=t.meta)==null?void 0:i.isolating)??!0,code:((s=t.meta)==null?void 0:s.code)??!1,defining:((c=t.meta)==null?void 0:c.defining)??!0,priority:o,addAttributes(){return xe(e.propSchema)},parseHTML(){return Be(e,t)},renderHTML({HTMLAttributes:l}){var d;const u=document.createElement("div");return Z({dom:u,contentDOM:e.content==="inline"?u:void 0},e.type,{},e.propSchema,((d=t.meta)==null?void 0:d.fileBlockAccept)!==void 0,l)},addNodeView(){return l=>{var f,x;const u=this.options.editor,d=Me(l.getPos,u,this.editor,e.type),p=((f=this.options.domAttributes)==null?void 0:f.blockContent)||{},h=t.render.call({blockContentDOMAttributes:p,props:l,renderType:"nodeView"},d,u);return((x=t.meta)==null?void 0:x.selectable)===!1&&Le(h,this.editor),h}}});if(r.name!==e.type)throw new Error("Node name does not match block type. This is a bug in BlockNote.");return{config:e,implementation:{...t,node:r,render(l,u){var p;const d=((p=r.options.domAttributes)==null?void 0:p.blockContent)||{};return t.render.call({blockContentDOMAttributes:d,props:void 0,renderType:"dom"},l,u)},toExternalHTML:(l,u)=>{var p,h;const d=((p=r.options.domAttributes)==null?void 0:p.blockContent)||{};return((h=t.toExternalHTML)==null?void 0:h.call({blockContentDOMAttributes:d},l,u))??t.render.call({blockContentDOMAttributes:d,renderType:"dom",props:void 0},l,u)}},extensions:n}}function Xt(e){return e}function E(e,t,n){return(o={})=>{const r=typeof e=="function"?e(o):e,a=typeof t=="function"?t(o):t,i=n?typeof n=="function"?n(o):n:void 0;return{config:r,implementation:{...a,toExternalHTML(s,c){var u,d;const l=(u=a.toExternalHTML)==null?void 0:u.call({blockContentDOMAttributes:this.blockContentDOMAttributes},s,c);if(l!==void 0)return Z(l,s.type,s.props,r.propSchema,((d=a.meta)==null?void 0:d.fileBlockAccept)!==void 0)},render(s,c){var d;const l=a.render.call({blockContentDOMAttributes:this.blockContentDOMAttributes,renderType:this.renderType,props:this.props},s,c);return Z(l,s.type,s.props,r.propSchema,((d=a.meta)==null?void 0:d.fileBlockAccept)!==void 0,this.blockContentDOMAttributes)}},extensions:i}}}function Qt(e,t,n,o){return e.dom.setAttribute("data-inline-content-type",t),Object.entries(n).filter(([r,a])=>{const i=o[r];return a!==i.default}).map(([r,a])=>[W(r),a]).forEach(([r,a])=>e.dom.setAttribute(r,a)),e.contentDOM&&e.contentDOM.setAttribute("data-editable",""),e}function Yt(e){return{Backspace:({editor:t})=>{const n=t.state.selection.$from;return t.state.selection.empty&&n.node().type.name===e.type&&n.parentOffset===0}}}function Te(e,t){return{config:e,implementation:t}}function Jt(e,t,n){return Te({type:e.name,propSchema:t,content:e.config.content==="inline*"?"styled":"none"},{...n,node:e})}function Ae(e){return Object.fromEntries(Object.entries(e).map(([t,n])=>[t,n.config]))}function Ie(e){return e==="boolean"?{}:{stringValue:{default:void 0,keepOnSplit:!0,parseHTML:t=>t.getAttribute("data-value"),renderHTML:t=>t.stringValue!==void 0?{"data-value":t.stringValue}:{}}}}function R(e,t,n,o){return e.dom.setAttribute("data-style-type",t),o==="string"&&e.dom.setAttribute("data-value",n),e.contentDOM&&e.contentDOM.setAttribute("data-editable",""),e}function oe(e,t){return{config:e,implementation:t}}function D(e,t){return oe({type:e.name,propSchema:t},{mark:e,render(n,o){const r=o.pmSchema.marks[e.name].spec.toDOM;if(r===void 0)throw new Error("This block has no default HTML serialization as its corresponding TipTap node doesn't implement `renderHTML`.");const a=o.pmSchema.mark(e.name,{stringValue:n}),i=F.DOMSerializer.renderSpec(document,r(a,!0));if(typeof i!="object"||!("dom"in i))throw new Error("Cannot use this block's default HTML serialization as its corresponding TipTap mark's `renderHTML` function does not return an object with the `dom` property.");return i},toExternalHTML(n,o){const r=o.pmSchema.marks[e.name].spec.toDOM;if(r===void 0)throw new Error("This block has no default HTML serialization as its corresponding TipTap node doesn't implement `renderHTML`.");const a=o.pmSchema.mark(e.name,{stringValue:n}),i=F.DOMSerializer.renderSpec(document,r(a,!0));if(typeof i!="object"||!("dom"in i))throw new Error("Cannot use this block's default HTML serialization as its corresponding TipTap mark's `renderHTML` function does not return an object with the `dom` property.");return i}})}function Pe(e){return Object.fromEntries(Object.entries(e).map(([t,n])=>[t,n.config]))}function Ne(e,t){const n=[{tag:`[data-style-type="${e.type}"]`,contentElement:o=>{const r=o;return r.matches("[data-editable]")?r:r.querySelector("[data-editable]")||r}}];return t&&n.push({tag:"*",consuming:!1,getAttrs(o){if(typeof o=="string")return!1;const r=t==null?void 0:t(o);return r===void 0?!1:{stringValue:r}}}),n}function re(e,t){const n=S.Mark.create({name:e.type,addAttributes(){return Ie(e.propSchema)},parseHTML(){return Ne(e,t.parse)},renderHTML({mark:o}){const r=(t.toExternalHTML||t.render)(o.attrs.stringValue);return R(r,e.type,o.attrs.stringValue,e.propSchema)},addMarkView(){return({mark:o})=>{const r=t.render(o.attrs.stringValue);return R(r,e.type,o.attrs.stringValue,e.propSchema)}}});return oe(e,{...t,mark:n,render:o=>{const r=t.render(o);return R(r,e.type,o,e.propSchema)},toExternalHTML:o=>{const r=(t.toExternalHTML||t.render)(o);return R(r,e.type,o,e.propSchema)}})}function He(e,t){let n,o;if(t.firstChild.descendants((r,a)=>n?!1:!_e(r)||r.attrs.id!==e?!0:(n=r,o=a+1,!1)),!(n===void 0||o===void 0))return{node:n,posBeforeNode:o}}function _e(e){return e.type.isInGroup("bnBlock")}const en=(e,t)=>({tr:n,dispatch:o})=>(o&&K(n,e,t),!0);function K(e,t,n,o,r){const a=m.getBlockInfoFromResolvedPos(e.doc.resolve(t));let i=null;a.blockNoteType==="table"&&(i=De(e));const s=m.getPmSchema(e);if(o!==void 0&&r!==void 0&&o>r)throw new Error("Invalid replaceFromPos or replaceToPos");const c=s.nodes[a.blockNoteType],l=s.nodes[n.type||a.blockNoteType],u=l.isInGroup("bnBlock")?l:s.nodes.blockContainer;if(a.isBlockContainer&&l.isInGroup("blockContent")){const d=o!==void 0&&o>a.blockContent.beforePos&&o<a.blockContent.afterPos?o-a.blockContent.beforePos-1:void 0,p=r!==void 0&&r>a.blockContent.beforePos&&r<a.blockContent.afterPos?r-a.blockContent.beforePos-1:void 0;ge(n,e,a),tn(n,e,c,l,a,d,p)}else if(!a.isBlockContainer&&l.isInGroup("bnBlock"))ge(n,e,a);else{const d=m.nodeToBlock(a.bnBlock.node,s);e.replaceWith(a.bnBlock.beforePos,a.bnBlock.afterPos,m.blockToNode({children:d.children,...n},s));return}e.setNodeMarkup(a.bnBlock.beforePos,u,{...a.bnBlock.node.attrs,...n.props}),i&&on(e,a,i)}function tn(e,t,n,o,r,a,i){const s=m.getPmSchema(t);let c="keep";if(e.content)if(typeof e.content=="string")c=m.inlineContentToNodes([e.content],s,o.name);else if(Array.isArray(e.content))c=m.inlineContentToNodes(e.content,s,o.name);else if(e.content.type==="tableContent")c=m.tableContentToNodes(e.content,s);else throw new m.UnreachableCaseError(e.content.type);else n.spec.content===""||o.spec.content!==n.spec.content&&(c=[]);if(c==="keep")t.setNodeMarkup(r.blockContent.beforePos,o,{...r.blockContent.node.attrs,...e.props});else if(a!==void 0||i!==void 0){t.setNodeMarkup(r.blockContent.beforePos,o,{...r.blockContent.node.attrs,...e.props});const l=r.blockContent.beforePos+1+(a??0),u=r.blockContent.beforePos+1+(i??r.blockContent.node.content.size),d=t.doc.resolve(r.blockContent.beforePos).depth,p=t.doc.resolve(l).depth,h=t.doc.resolve(u).depth;t.replace(l,u,new P.Slice(P.Fragment.from(c),p-d-1,h-d-1))}else t.replaceWith(r.blockContent.beforePos,r.blockContent.afterPos,o.createChecked({...r.blockContent.node.attrs,...e.props},c))}function ge(e,t,n){const o=m.getPmSchema(t);if(e.children!==void 0&&e.children.length>0){const r=e.children.map(a=>m.blockToNode(a,o));if(n.childContainer)t.step(new ye.ReplaceStep(n.childContainer.beforePos+1,n.childContainer.afterPos-1,new P.Slice(P.Fragment.from(r),0,0)));else{if(!n.isBlockContainer)throw new Error("impossible");t.insert(n.blockContent.afterPos,o.nodes.blockGroup.createChecked({},r))}}}function nn(e,t,n,o,r){const a=typeof t=="string"?t:t.id,i=He(a,e.doc);if(!i)throw new Error(`Block with ID ${a} not found`);K(e,i.posBeforeNode,n,o,r);const s=e.doc.resolve(i.posBeforeNode+1).node(),c=m.getPmSchema(e);return m.nodeToBlock(s,c)}function De(e){const t="selection"in e?e.selection:null;if(!(t instanceof z.TextSelection))return null;const n=e.doc.resolve(t.head);let o=-1,r=-1;for(let w=n.depth;w>=0;w--){const M=n.node(w).type.name;if(o<0&&(M==="tableCell"||M==="tableHeader")&&(o=w),M==="table"){r=w;break}}if(o<0||r<0)return null;const a=n.before(o),i=n.before(r),s=e.doc.nodeAt(i);if(!s||s.type.name!=="table")return null;const c=T.TableMap.get(s),l=a-(i+1),u=c.map.indexOf(l);if(u<0)return null;const d=Math.floor(u/c.width),p=u%c.width,f=a+1+1,x=Math.max(0,t.head-f);return{row:d,col:p,offset:x}}function on(e,t,n){var w;if(t.blockNoteType!=="table")return!1;let o=-1;if(t.isBlockContainer)o=e.mapping.map(t.blockContent.beforePos);else{const M=e.mapping.map(t.bnBlock.beforePos),_=M+(((w=e.doc.nodeAt(M))==null?void 0:w.nodeSize)||0);e.doc.nodesBetween(M,_,(b,L)=>b.type.name==="table"?(o=L,!1):!0)}const r=o>=0?e.doc.nodeAt(o):null;if(!r||r.type.name!=="table")return!1;const a=T.TableMap.get(r),i=Math.max(0,Math.min(n.row,a.height-1)),s=Math.max(0,Math.min(n.col,a.width-1)),c=i*a.width+s,l=a.map[c];if(l==null)return!1;const d=o+1+l+1,p=e.doc.nodeAt(d),h=d+1,f=p?p.content.size:0,x=h+Math.max(0,Math.min(n.offset,f));return"selection"in e&&e.setSelection(z.TextSelection.create(e.doc,x)),!0}const A={gray:{text:"#9b9a97",background:"#ebeced"},brown:{text:"#64473a",background:"#e9e5e3"},red:{text:"#e03e3e",background:"#fbe4e4"},orange:{text:"#d9730d",background:"#f6e9d9"},yellow:{text:"#dfab01",background:"#fbf3db"},green:{text:"#4d6461",background:"#ddedea"},blue:{text:"#0b6e99",background:"#ddebf1"},purple:{text:"#6940a5",background:"#eae4f2"},pink:{text:"#ad1a72",background:"#f4dfeb"}},rn={gray:{text:"#bebdb8",background:"#9b9a97"},brown:{text:"#8e6552",background:"#64473a"},red:{text:"#ec4040",background:"#be3434"},orange:{text:"#e3790d",background:"#b7600a"},yellow:{text:"#dfab01",background:"#b58b00"},green:{text:"#6b8b87",background:"#4d6461"},blue:{text:"#0e87bc",background:"#0b6e99"},purple:{text:"#8552d7",background:"#6940a5"},pink:{text:"#da208f",background:"#ad1a72"}},g={backgroundColor:{default:"default"},textColor:{default:"default"},textAlignment:{default:"left",values:["left","center","right","justify"]}},v=e=>{const t={};return e.hasAttribute("data-background-color")?t.backgroundColor=e.getAttribute("data-background-color"):e.style.backgroundColor&&(t.backgroundColor=e.style.backgroundColor),e.hasAttribute("data-text-color")?t.textColor=e.getAttribute("data-text-color"):e.style.color&&(t.textColor=e.style.color),t.textAlignment=g.textAlignment.values.includes(e.style.textAlign)?e.style.textAlign:void 0,t},N=(e,t)=>{e.backgroundColor&&e.backgroundColor!==g.backgroundColor.default&&(t.style.backgroundColor=e.backgroundColor in A?A[e.backgroundColor].background:e.backgroundColor),e.textColor&&e.textColor!==g.textColor.default&&(t.style.color=e.textColor in A?A[e.textColor].text:e.textColor),e.textAlignment&&e.textAlignment!==g.textAlignment.default&&(t.style.textAlign=e.textAlignment)},an=(e="backgroundColor")=>({default:g.backgroundColor.default,parseHTML:t=>t.hasAttribute("data-background-color")?t.getAttribute("data-background-color"):t.style.backgroundColor?t.style.backgroundColor:g.backgroundColor.default,renderHTML:t=>t[e]===g.backgroundColor.default?{}:{"data-background-color":t[e]}}),sn=(e="textColor")=>({default:g.textColor.default,parseHTML:t=>t.hasAttribute("data-text-color")?t.getAttribute("data-text-color"):t.style.color?t.style.color:g.textColor.default,renderHTML:t=>t[e]===g.textColor.default?{}:{"data-text-color":t[e]}}),cn=(e="textAlignment")=>({default:g.textAlignment.default,parseHTML:t=>t.hasAttribute("data-text-alignment")?t.getAttribute("data-text-alignment"):t.style.textAlign?t.style.textAlign:g.textAlignment.default,renderHTML:t=>t[e]===g.textAlignment.default?{}:{"data-text-alignment":t[e]}}),X=(e,t)=>{const n=e.querySelector(t);if(!n)return;const o=e.querySelector("figcaption"),r=(o==null?void 0:o.textContent)??void 0;return{targetElement:n,caption:r}},O=y.createExtension(({editor:e})=>{const t=y.createStore(void 0);function n(){t.setState(void 0)}return{key:"filePanel",store:t,mount({signal:o}){const r=e.onChange(n,!1),a=e.onSelectionChange(n,!1);o.addEventListener("abort",()=>{r(),a()})},closeMenu:n,showMenu(o){t.setState(o)}}}),ln=(e,t,n)=>{const o=document.createElement("div");o.className="bn-add-file-button";const r=document.createElement("div");r.className="bn-add-file-button-icon",n?r.appendChild(n):r.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3 8L9.00319 2H19.9978C20.5513 2 21 2.45531 21 2.9918V21.0082C21 21.556 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5501 3 20.9932V8ZM10 4V9H5V20H19V4H10Z"></path></svg>',o.appendChild(r);const a=document.createElement("p");a.className="bn-add-file-button-text",a.innerHTML=e.type in t.dictionary.file_blocks.add_button_text?t.dictionary.file_blocks.add_button_text[e.type]:t.dictionary.file_blocks.add_button_text.file,o.appendChild(a);const i=c=>{c.preventDefault(),c.stopPropagation()},s=()=>{var c;t.isEditable&&((c=t.getExtension(O))==null||c.showMenu(e.id))};return o.addEventListener("mousedown",i,!0),o.addEventListener("click",s,!0),{dom:o,destroy:()=>{o.removeEventListener("mousedown",i,!0),o.removeEventListener("click",s,!0)}}},dn='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3 8L9.00319 2H19.9978C20.5513 2 21 2.45531 21 2.9918V21.0082C21 21.556 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5501 3 20.9932V8ZM10 4V9H5V20H19V4H10Z"></path></svg>',un=e=>{const t=document.createElement("div");t.className="bn-file-name-with-icon";const n=document.createElement("div");n.className="bn-file-icon",n.innerHTML=dn,t.appendChild(n);const o=document.createElement("p");return o.className="bn-file-name",o.textContent=e.props.name,t.appendChild(o),{dom:t}},ae=(e,t,n,o)=>{const r=document.createElement("div");if(r.className="bn-file-block-content-wrapper",e.props.url===""){const i=ln(e,t,o);r.appendChild(i.dom);const s=t.onUploadStart(c=>{if(c===e.id){r.removeChild(i.dom);const l=document.createElement("div");l.className="bn-file-loading-preview",l.textContent="Loading...",r.appendChild(l)}});return{dom:r,destroy:()=>{s(),i.destroy()}}}const a={dom:r};if(e.props.showPreview===!1||!n){const i=un(e);r.appendChild(i.dom),a.destroy=()=>{var s;(s=i.destroy)==null||s.call(i)}}else r.appendChild(n.dom);if(e.props.caption){const i=document.createElement("p");i.className="bn-file-caption",i.textContent=e.props.caption,r.appendChild(i)}return a},ie=(e,t)=>{const n=document.createElement("figure"),o=document.createElement("figcaption");return o.textContent=t,n.appendChild(e),n.appendChild(o),{dom:n}},Q=(e,t)=>{const n=document.createElement("div"),o=document.createElement("p");return o.textContent=t,n.appendChild(e),n.appendChild(o),{dom:n}},ne=e=>({url:e.src||void 0}),Oe='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M2 16.0001H5.88889L11.1834 20.3319C11.2727 20.405 11.3846 20.4449 11.5 20.4449C11.7761 20.4449 12 20.2211 12 19.9449V4.05519C12 3.93977 11.9601 3.8279 11.887 3.73857C11.7121 3.52485 11.3971 3.49335 11.1834 3.66821L5.88889 8.00007H2C1.44772 8.00007 1 8.44778 1 9.00007V15.0001C1 15.5524 1.44772 16.0001 2 16.0001ZM23 12C23 15.292 21.5539 18.2463 19.2622 20.2622L17.8445 18.8444C19.7758 17.1937 21 14.7398 21 12C21 9.26016 19.7758 6.80629 17.8445 5.15557L19.2622 3.73779C21.5539 5.75368 23 8.70795 23 12ZM18 12C18 10.0883 17.106 8.38548 15.7133 7.28673L14.2842 8.71584C15.3213 9.43855 16 10.64 16 12C16 13.36 15.3213 14.5614 14.2842 15.2841L15.7133 16.7132C17.106 15.6145 18 13.9116 18 12Z"></path></svg>',Ve=e=>({type:"audio",propSchema:{backgroundColor:g.backgroundColor,name:{default:""},url:{default:""},caption:{default:""},showPreview:{default:!0}},content:"none"}),Re=(e={})=>t=>{if(t.tagName==="AUDIO"){if(t.closest("figure"))return;const{backgroundColor:n}=v(t);return{...ne(t),backgroundColor:n}}if(t.tagName==="FIGURE"){const n=X(t,"audio");if(!n)return;const{targetElement:o,caption:r}=n,{backgroundColor:a}=v(t);return{...ne(o),backgroundColor:a,caption:r}}},Fe=(e={})=>(t,n)=>{const o=document.createElement("div");o.innerHTML=e.icon??Oe;const r=document.createElement("audio");return r.className="bn-audio",n.resolveFileUrl?n.resolveFileUrl(t.props.url).then(a=>{r.src=a}):r.src=t.props.url,r.controls=!0,r.contentEditable="false",r.draggable=!1,ae(t,n,{dom:r},o.firstElementChild)},We=(e={})=>(t,n)=>{if(!t.props.url){const r=document.createElement("p");return r.textContent="Add audio",{dom:r}}let o;return t.props.showPreview?(o=document.createElement("audio"),o.src=t.props.url):(o=document.createElement("a"),o.href=t.props.url,o.textContent=t.props.name||t.props.url),t.props.caption?t.props.showPreview?ie(o,t.props.caption):Q(o,t.props.caption):{dom:o}},qe=E(Ve,e=>({meta:{fileBlockAccept:["audio/*"]},parse:Re(e),render:Fe(e),toExternalHTML:We(e),runsBefore:["file"]})),he=Symbol.for("blocknote.shikiParser"),J=Symbol.for("blocknote.shikiHighlighterPromise");function pn(e){const t=globalThis;let n,o,r=!1;const a=i=>{if(!e.createHighlighter)return process.env.NODE_ENV==="development"&&!r&&(console.log("For syntax highlighting of code blocks, you must provide a `createCodeBlockSpec({ createHighlighter: () => ... })` function"),r=!0),[];if(!n)return t[J]=t[J]||e.createHighlighter(),t[J].then(c=>{n=c});const s=se(e,i.language);return!s||s==="text"||s==="none"||s==="plaintext"||s==="txt"?[]:n.getLoadedLanguages().includes(s)?(o||(o=t[he]||Ft.createParser(n),t[he]=o),o(i)):n.loadLanguage(s)};return Rt.createHighlightPlugin({parser:a,languageExtractor:i=>i.attrs.language,nodeTypes:["codeBlock"]})}const Ue=({defaultLanguage:e="text"})=>({type:"codeBlock",propSchema:{language:{default:e}},content:"inline"}),$e=E(Ue,e=>({meta:{code:!0,defining:!0,isolating:!1},parse:t=>{var r,a;if(t.tagName!=="PRE"||t.childElementCount!==1||((r=t.firstElementChild)==null?void 0:r.tagName)!=="CODE")return;const n=t.firstElementChild;return{language:n.getAttribute("data-language")||((a=n.className.split(" ").find(i=>i.includes("language-")))==null?void 0:a.replace("language-",""))}},parseContent:({el:t,schema:n})=>{const o=F.DOMParser.fromSchema(n),r=t.firstElementChild;return o.parse(r,{preserveWhitespace:"full",topNode:n.nodes.codeBlock.create()}).content},render(t,n){const o=document.createDocumentFragment(),r=document.createElement("pre"),a=document.createElement("code");r.appendChild(a);let i;if(e.supportedLanguages){const s=document.createElement("select");Object.entries(e.supportedLanguages??{}).forEach(([u,{name:d}])=>{const p=document.createElement("option");p.value=u,p.text=d,s.appendChild(p)}),s.value=t.props.language||e.defaultLanguage||"text";const c=u=>{const d=u.target.value;n.updateBlock(t.id,{props:{language:d}})};s.addEventListener("change",c),i=()=>s.removeEventListener("change",c);const l=document.createElement("div");l.contentEditable="false",l.appendChild(s),o.appendChild(l)}return o.appendChild(r),{dom:o,contentDOM:a,destroy:()=>{i==null||i()}}},toExternalHTML(t){const n=document.createElement("pre"),o=document.createElement("code");return o.className=`language-${t.props.language}`,o.dataset.language=t.props.language,n.appendChild(o),{dom:n,contentDOM:o}}}),e=>[y.createExtension({key:"code-block-highlighter",prosemirrorPlugins:[pn(e)]}),y.createExtension({key:"code-block-keyboard-shortcuts",keyboardShortcuts:{Delete:({editor:t})=>t.transact(n=>{const{block:o}=t.getTextCursorPosition();if(o.type!=="codeBlock")return!1;const{$from:r}=n.selection;return r.parent.textContent?!1:(t.removeBlocks([o]),!0)}),Tab:({editor:t})=>e.indentLineWithTab===!1?!1:t.transact(n=>{const{block:o}=t.getTextCursorPosition();return o.type==="codeBlock"?(n.insertText(" "),!0):!1}),Enter:({editor:t})=>t.transact(n=>{const{block:o,nextBlock:r}=t.getTextCursorPosition();if(o.type!=="codeBlock")return!1;const{$from:a}=n.selection,i=a.parentOffset===a.parent.nodeSize-2,s=a.parent.textContent.endsWith(`
3
+
4
+ `);if(i&&s){if(n.delete(a.pos-2,a.pos),r)return t.setTextCursorPosition(r,"start"),!0;const[c]=t.insertBlocks([{type:"paragraph"}],o,"after");return t.setTextCursorPosition(c,"start"),!0}return n.insertText(`
5
+ `),!0}),"Shift-Enter":({editor:t})=>t.transact(()=>{const{block:n}=t.getTextCursorPosition();if(n.type!=="codeBlock")return!1;const[o]=t.insertBlocks([{type:"paragraph"}],n,"after");return t.setTextCursorPosition(o,"start"),!0})},inputRules:[{find:/^```(.*?)\s$/,replace:({match:t})=>{const n=t[1].trim();return{type:"codeBlock",props:{language:{language:se(e,n)??n}.language},content:[]}}}]})]);function se(e,t){var n;return(n=Object.entries(e.supportedLanguages??{}).find(([o,{aliases:r}])=>(r==null?void 0:r.includes(t))||o===t))==null?void 0:n[0]}const je=()=>({type:"divider",propSchema:{},content:"none"}),Ge=E(je,{meta:{isolating:!1},parse(e){if(e.tagName==="HR")return{}},render(){return{dom:document.createElement("hr")}}},[y.createExtension({key:"divider-block-shortcuts",inputRules:[{find:new RegExp("^---$"),replace(){return{type:"divider",props:{},content:[]}}}]})]),me=e=>({url:e.src||void 0}),Ze=()=>({type:"file",propSchema:{backgroundColor:g.backgroundColor,name:{default:""},url:{default:""},caption:{default:""}},content:"none"}),ze=()=>e=>{if(e.tagName==="EMBED"){if(e.closest("figure"))return;const{backgroundColor:t}=v(e);return{...me(e),backgroundColor:t}}if(e.tagName==="FIGURE"){const t=X(e,"embed");if(!t)return;const{targetElement:n,caption:o}=t,{backgroundColor:r}=v(e);return{...me(n),backgroundColor:r,caption:o}}},Ke=E(Ze,{meta:{fileBlockAccept:["*/*"]},parse:ze(),render(e,t){return ae(e,t)},toExternalHTML(e){if(!e.props.url){const n=document.createElement("p");return n.textContent="Add file",{dom:n}}const t=document.createElement("a");return t.href=e.props.url,t.textContent=e.props.name||e.props.url,e.props.caption?Q(t,e.props.caption):{dom:t}}}),Xe={set:(e,t)=>window.localStorage.setItem(`toggle-${e.id}`,t?"true":"false"),get:e=>window.localStorage.getItem(`toggle-${e.id}`)==="true"},ce=(e,t,n,o=Xe)=>{if("isToggleable"in e.props&&!e.props.isToggleable)return{dom:n};const r=document.createElement("div"),a=document.createElement("div");a.className="bn-toggle-wrapper";const i=document.createElement("button");i.className="bn-toggle-button",i.type="button",i.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="CURRENTCOLOR"><path d="M320-200v-560l440 280-440 280Z"/></svg>';const s=f=>f.preventDefault();i.addEventListener("mousedown",s);const c=()=>{var f;a.getAttribute("data-show-children")==="true"?(a.setAttribute("data-show-children","false"),o.set(t.getBlock(e),!1),r.contains(l)&&r.removeChild(l)):(a.setAttribute("data-show-children","true"),o.set(t.getBlock(e),!0),t.isEditable&&((f=t.getBlock(e))==null?void 0:f.children.length)===0&&!r.contains(l)&&r.appendChild(l))};i.addEventListener("click",c),a.appendChild(i),a.appendChild(n);const l=document.createElement("button");l.className="bn-toggle-add-block-button",l.type="button",l.textContent=t.dictionary.toggle_blocks.add_block_button;const u=f=>f.preventDefault();l.addEventListener("mousedown",u);const d=()=>{t.transact(()=>{const f=t.updateBlock(e,{children:[{}]});t.setTextCursorPosition(f.children[0].id,"end"),t.focus()})};l.addEventListener("click",d),r.appendChild(a);let p=e.children.length;const h=t.onChange(()=>{var x;const f=((x=t.getBlock(e))==null?void 0:x.children.length)??0;f>p?(a.getAttribute("data-show-children")==="false"&&(a.setAttribute("data-show-children","true"),o.set(t.getBlock(e),!0)),r.contains(l)&&r.removeChild(l)):f===0&&f<p&&(a.getAttribute("data-show-children")==="true"&&(a.setAttribute("data-show-children","false"),o.set(t.getBlock(e),!1)),r.contains(l)&&r.removeChild(l)),p=f});return o.get(e)?(a.setAttribute("data-show-children","true"),t.isEditable&&e.children.length===0&&r.appendChild(l)):a.setAttribute("data-show-children","false"),{dom:r,ignoreMutation:f=>f instanceof MutationRecord&&(f.type==="attributes"&&f.target===a&&f.attributeName==="data-show-children"||f.type==="childList"&&(f.addedNodes[0]===l||f.removedNodes[0]===l)),destroy:()=>{i.removeEventListener("mousedown",s),i.removeEventListener("click",c),l.removeEventListener("mousedown",u),l.removeEventListener("click",d),h==null||h()}}},Qe=[1,2,3,4,5,6],fn=e=>({editor:t})=>{const n=t.getTextCursorPosition();return t.schema.blockSchema[n.block.type].content!=="inline"?!1:(t.updateBlock(n.block,{type:"heading",props:{level:e}}),!0)},Ye=({defaultLevel:e=1,levels:t=Qe,allowToggleHeadings:n=!0}={})=>({type:"heading",propSchema:{...g,level:{default:e,values:t},...n?{isToggleable:{default:!1,optional:!0}}:{}},content:"inline"}),Je=E(Ye,({allowToggleHeadings:e=!0}={})=>({meta:{isolating:!1},parse(t){let n;switch(t.tagName){case"H1":n=1;break;case"H2":n=2;break;case"H3":n=3;break;case"H4":n=4;break;case"H5":n=5;break;case"H6":n=6;break;default:return}return{...v(t),level:n}},render(t,n){const o=document.createElement(`h${t.props.level}`);return e?{...ce(t,n,o),contentDOM:o}:{dom:o,contentDOM:o}},toExternalHTML(t){const n=document.createElement(`h${t.props.level}`);return N(t.props,n),{dom:n,contentDOM:n}}}),({levels:e=Qe}={})=>[y.createExtension({key:"heading-shortcuts",keyboardShortcuts:Object.fromEntries(e.map(t=>[`Mod-Alt-${t}`,fn(t)])??[]),inputRules:e.map(t=>({find:new RegExp(`^(#{${t}})\\s$`),replace({match:n}){return{type:"heading",props:{level:n[1].length}}}}))})]),et=(e,t,n,o,r)=>{const{dom:a,destroy:i}=ae(e,t,n,r),s=a;s.style.position="relative",e.props.url&&e.props.showPreview&&(e.props.previewWidth?s.style.width=`${e.props.previewWidth}px`:s.style.width="fit-content");const c=document.createElement("div");c.className="bn-resize-handle",c.style.left="4px";const l=document.createElement("div");l.className="bn-resize-handle",l.style.right="4px";const u=document.createElement("div");u.style.position="absolute",u.style.height="100%",u.style.width="100%";let d,p=e.props.previewWidth;const h=b=>{var ue,pe;if(!d){!t.isEditable&&o.contains(c)&&o.contains(l)&&(o.removeChild(c),o.removeChild(l));return}let L;const U="touches"in b?b.touches[0].clientX:b.clientX;e.props.textAlignment==="center"?d.handleUsed==="left"?L=d.initialWidth+(d.initialClientX-U)*2:L=d.initialWidth+(U-d.initialClientX)*2:d.handleUsed==="left"?L=d.initialWidth+d.initialClientX-U:L=d.initialWidth+U-d.initialClientX,p=Math.min(Math.max(L,64),((pe=(ue=t.domElement)==null?void 0:ue.firstElementChild)==null?void 0:pe.clientWidth)||Number.MAX_VALUE),s.style.width=`${p}px`},f=b=>{(!b.target||!s.contains(b.target)||!t.isEditable)&&o.contains(c)&&o.contains(l)&&(o.removeChild(c),o.removeChild(l)),d&&(d=void 0,s.contains(u)&&s.removeChild(u),t.updateBlock(e,{props:{previewWidth:p}}))},x=()=>{t.isEditable&&(o.appendChild(c),o.appendChild(l))},w=b=>{b.relatedTarget===c||b.relatedTarget===l||d||t.isEditable&&o.contains(c)&&o.contains(l)&&(o.removeChild(c),o.removeChild(l))},M=b=>{b.preventDefault(),s.contains(u)||s.appendChild(u);const L="touches"in b?b.touches[0].clientX:b.clientX;d={handleUsed:"left",initialWidth:s.clientWidth,initialClientX:L}},_=b=>{b.preventDefault(),s.contains(u)||s.appendChild(u);const L="touches"in b?b.touches[0].clientX:b.clientX;d={handleUsed:"right",initialWidth:s.clientWidth,initialClientX:L}};return window.addEventListener("mousemove",h),window.addEventListener("touchmove",h),window.addEventListener("mouseup",f),window.addEventListener("touchend",f),s.addEventListener("mouseenter",x),s.addEventListener("mouseleave",w),c.addEventListener("mousedown",M),c.addEventListener("touchstart",M),l.addEventListener("mousedown",_),l.addEventListener("touchstart",_),{dom:s,destroy:()=>{i==null||i(),window.removeEventListener("mousemove",h),window.removeEventListener("touchmove",h),window.removeEventListener("mouseup",f),window.removeEventListener("touchend",f),s.removeEventListener("mouseenter",x),s.removeEventListener("mouseleave",w),c.removeEventListener("mousedown",M),c.removeEventListener("touchstart",M),l.removeEventListener("mousedown",_),l.removeEventListener("touchstart",_)}}},be=e=>{const t=e.src||void 0,n=e.width||void 0,o=e.alt||void 0;return{url:t,previewWidth:n,name:o}},tt='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5 11.1005L7 9.1005L12.5 14.6005L16 11.1005L19 14.1005V5H5V11.1005ZM4 3H20C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3ZM15.5 10C14.6716 10 14 9.32843 14 8.5C14 7.67157 14.6716 7 15.5 7C16.3284 7 17 7.67157 17 8.5C17 9.32843 16.3284 10 15.5 10Z"></path></svg>',nt=(e={})=>({type:"image",propSchema:{textAlignment:g.textAlignment,backgroundColor:g.backgroundColor,name:{default:""},url:{default:""},caption:{default:""},showPreview:{default:!0},previewWidth:{default:void 0,type:"number"}},content:"none"}),ot=(e={})=>t=>{if(t.tagName==="IMG"){if(t.closest("figure"))return;const{backgroundColor:n}=v(t);return{...be(t),backgroundColor:n}}if(t.tagName==="FIGURE"){const n=X(t,"img");if(!n)return;const{targetElement:o,caption:r}=n,{backgroundColor:a}=v(t);return{...be(o),backgroundColor:a,caption:r}}},rt=(e={})=>(t,n)=>{const o=document.createElement("div");o.innerHTML=e.icon??tt;const r=document.createElement("div");r.className="bn-visual-media-wrapper";const a=document.createElement("img");return a.className="bn-visual-media",n.resolveFileUrl?n.resolveFileUrl(t.props.url).then(i=>{a.src=i}):a.src=t.props.url,a.alt=t.props.name||t.props.caption||"BlockNote image",a.contentEditable="false",a.draggable=!1,r.appendChild(a),et(t,n,{dom:r},r,o.firstElementChild)},at=(e={})=>(t,n)=>{if(!t.props.url){const r=document.createElement("p");return r.textContent="Add image",{dom:r}}let o;return t.props.showPreview?(o=document.createElement("img"),o.src=t.props.url,o.alt=t.props.name||t.props.caption||"BlockNote image",t.props.previewWidth&&(o.width=t.props.previewWidth)):(o=document.createElement("a"),o.href=t.props.url,o.textContent=t.props.name||t.props.url),t.props.caption?t.props.showPreview?ie(o,t.props.caption):Q(o,t.props.caption):{dom:o}},it=E(nt,e=>({meta:{fileBlockAccept:["image/*"]},parse:ot(e),render:rt(e),toExternalHTML:at(e),runsBefore:["file"]})),gn=(e,t,n)=>({state:o,dispatch:r})=>r?st(o.tr,e,t,n):!0,st=(e,t,n,o)=>{const r=m.getNearestBlockPos(e.doc,t),a=m.getBlockInfo(r);if(!a.isBlockContainer)return!1;const i=m.getPmSchema(e),s=[{type:a.bnBlock.node.type,attrs:o?{...a.bnBlock.node.attrs,id:void 0}:{}},{type:n?a.blockContent.node.type:i.nodes.paragraph,attrs:o?{...a.blockContent.node.attrs}:{}}];return e.split(t,2,s),!0},Y=(e,t)=>{const{blockInfo:n,selectionEmpty:o}=e.transact(i=>({blockInfo:m.getBlockInfoFromTransaction(i),selectionEmpty:i.selection.anchor===i.selection.head}));if(!n.isBlockContainer)return!1;const{bnBlock:r,blockContent:a}=n;return a.node.type.name!==t||!o?!1:a.node.childCount===0?(e.transact(i=>{K(i,r.beforePos,{type:"paragraph",props:{}})}),!0):a.node.childCount>0?e.transact(i=>(i.deleteSelection(),st(i,i.selection.from,!0))):!1};function le(e,t,n){var d,p,h;const o=P.DOMParser.fromSchema(t),r=e,a=document.createElement("div");a.setAttribute("data-node-type","blockGroup");for(const f of Array.from(r.childNodes))a.appendChild(f.cloneNode(!0));let i=o.parse(a,{topNode:t.nodes.blockGroup.create()});((p=(d=i.firstChild)==null?void 0:d.firstChild)==null?void 0:p.type.name)==="checkListItem"&&(i=i.copy(i.content.cut(i.firstChild.firstChild.nodeSize+2)));const s=(h=i.firstChild)==null?void 0:h.firstChild;if(!(s!=null&&s.isTextblock))return P.Fragment.from(i);const c=t.nodes[n].create({},s.content),l=i.content.cut(s.nodeSize+2);if(l.size>0){const f=i.copy(l);return c.content.addToEnd(f)}return c.content}const ct=()=>({type:"bulletListItem",propSchema:{...g},content:"inline"}),lt=E(ct,{meta:{isolating:!1},parse(e){var n;if(e.tagName!=="LI")return;const t=e.parentElement;if(t!==null&&(t.tagName==="UL"||t.tagName==="DIV"&&((n=t.parentElement)==null?void 0:n.tagName)==="UL"))return v(e)},parseContent:({el:e,schema:t})=>le(e,t,"bulletListItem"),render(){const e=document.createElement("p");return{dom:e,contentDOM:e}},toExternalHTML(e){const t=document.createElement("li"),n=document.createElement("p");return N(e.props,t),t.appendChild(n),{dom:t,contentDOM:n}}},[y.createExtension({key:"bullet-list-item-shortcuts",keyboardShortcuts:{Enter:({editor:e})=>Y(e,"bulletListItem"),"Mod-Shift-8":({editor:e})=>{const t=e.getTextCursorPosition();return e.schema.blockSchema[t.block.type].content!=="inline"?!1:(e.updateBlock(t.block,{type:"bulletListItem",props:{}}),!0)}},inputRules:[{find:new RegExp("^[-+*]\\s$"),replace({editor:e}){if(m.getBlockInfoFromSelection(e.prosemirrorState).blockNoteType!=="heading")return{type:"bulletListItem",props:{}}}}]})]),dt=()=>({type:"checkListItem",propSchema:{...g,checked:{default:!1,type:"boolean"}},content:"inline"}),ut=E(dt,{meta:{isolating:!1},parse(e){var n;if(e.tagName==="input")return e.closest("[data-content-type]")||e.closest("li")?void 0:e.type==="checkbox"?{checked:e.checked}:void 0;if(e.tagName!=="LI")return;const t=e.parentElement;if(t!==null&&(t.tagName==="UL"||t.tagName==="DIV"&&((n=t.parentElement)==null?void 0:n.tagName)==="UL")){const o=e.querySelector("input[type=checkbox]")||null;return o===null?void 0:{...v(e),checked:o.checked}}},parseContent:({el:e,schema:t})=>le(e,t,"checkListItem"),render(e,t){const n=document.createDocumentFragment(),o=document.createElement("input");o.type="checkbox",o.checked=e.props.checked,e.props.checked&&o.setAttribute("checked",""),o.addEventListener("change",()=>{t.updateBlock(e,{props:{checked:!e.props.checked}})});const r=document.createElement("p");return n.appendChild(o),n.appendChild(r),{dom:n,contentDOM:r}},toExternalHTML(e){const t=document.createElement("li"),n=document.createElement("input");n.type="checkbox",n.checked=e.props.checked,e.props.checked&&n.setAttribute("checked","");const o=document.createElement("p");return N(e.props,t),t.appendChild(n),t.appendChild(o),{dom:t,contentDOM:o}},runsBefore:["bulletListItem"]},[y.createExtension({key:"check-list-item-shortcuts",keyboardShortcuts:{Enter:({editor:e})=>Y(e,"checkListItem"),"Mod-Shift-9":({editor:e})=>{const t=e.getTextCursorPosition();return e.schema.blockSchema[t.block.type].content!=="inline"?!1:(e.updateBlock(t.block,{type:"checkListItem",props:{}}),!0)}},inputRules:[{find:new RegExp("\\[\\s*\\]\\s$"),replace(){return{type:"checkListItem",props:{checked:!1},content:[]}}},{find:new RegExp("\\[[Xx]\\]\\s$"),replace(){return{type:"checkListItem",props:{checked:!0}}}}]})]);function pt(e,t,n,o){let r=e.firstChild.attrs.start||1,a=!0;const i=!!e.firstChild.attrs.start,s=m.getBlockInfo({posBeforeNode:t,node:e});if(!s.isBlockContainer)throw new Error("impossible");const c=n.doc.resolve(s.bnBlock.beforePos).nodeBefore,l=c?o.get(c):void 0;return l!==void 0?(r=l+1,a=!1):c&&m.getBlockInfo({posBeforeNode:s.bnBlock.beforePos-c.nodeSize,node:c}).blockNoteType==="numberedListItem"&&(r=pt(c,s.bnBlock.beforePos-c.nodeSize,n,o).index+1,a=!1),o.set(e,r),{index:r,isFirst:a,hasStart:i}}function Ce(e,t){const n=new Map,o=t.decorations.map(e.mapping,e.doc),r=[];e.doc.nodesBetween(0,e.doc.nodeSize-2,(i,s)=>{if(i.type.name==="blockContainer"&&i.firstChild.type.name==="numberedListItem"){const{index:c,isFirst:l,hasStart:u}=pt(i,s,e,n);if(o.find(s,s+i.nodeSize,p=>p.index===c&&p.isFirst===l&&p.hasStart===u).length===0){const p=e.doc.nodeAt(s+1);r.push(ee.Decoration.node(s+1,s+1+p.nodeSize,{"data-index":c.toString()}))}}});const a=r.flatMap(i=>o.find(i.from,i.to));return{decorations:o.remove(a).add(e.doc,r)}}const hn=()=>new fe.Plugin({key:new fe.PluginKey("numbered-list-indexing-decorations"),state:{init(e,t){return Ce(t.tr,{decorations:ee.DecorationSet.empty})},apply(e,t){return!e.docChanged&&!e.selectionSet&&t.decorations?t:Ce(e,t)}},props:{decorations(e){var t;return((t=this.getState(e))==null?void 0:t.decorations)??ee.DecorationSet.empty}}}),ft=()=>({type:"numberedListItem",propSchema:{...g,start:{default:void 0,type:"number"}},content:"inline"}),gt=E(ft,{meta:{isolating:!1},parse(e){var n;if(e.tagName!=="LI")return;const t=e.parentElement;if(t!==null&&(t.tagName==="OL"||t.tagName==="DIV"&&((n=t.parentElement)==null?void 0:n.tagName)==="OL")){const o=parseInt(t.getAttribute("start")||"1"),r=v(e);return e.previousElementSibling||o===1?r:{...r,start:o}}},parseContent:({el:e,schema:t})=>le(e,t,"numberedListItem"),render(){const e=document.createElement("p");return{dom:e,contentDOM:e}},toExternalHTML(e){const t=document.createElement("li"),n=document.createElement("p");return N(e.props,t),t.appendChild(n),{dom:t,contentDOM:n}}},[y.createExtension({key:"numbered-list-item-shortcuts",inputRules:[{find:new RegExp("^(\\d+)\\.\\s$"),replace({match:e,editor:t}){if(m.getBlockInfoFromSelection(t.prosemirrorState).blockNoteType==="heading")return;const o=parseInt(e[1]);return{type:"numberedListItem",props:{start:o!==1?o:void 0}}}}],keyboardShortcuts:{Enter:({editor:e})=>Y(e,"numberedListItem"),"Mod-Shift-7":({editor:e})=>{const t=e.getTextCursorPosition();return e.schema.blockSchema[t.block.type].content!=="inline"?!1:(e.updateBlock(t.block,{type:"numberedListItem",props:{}}),!0)}},prosemirrorPlugins:[hn()]})]),ht=()=>({type:"toggleListItem",propSchema:{...g},content:"inline"}),mt=E(ht,{meta:{isolating:!1},render(e,t){const n=document.createElement("p");return{...ce(e,t,n),contentDOM:n}},toExternalHTML(e){const t=document.createElement("li"),n=document.createElement("p");return N(e.props,t),t.appendChild(n),{dom:t,contentDOM:n}}},[y.createExtension({key:"toggle-list-item-shortcuts",keyboardShortcuts:{Enter:({editor:e})=>Y(e,"toggleListItem"),"Mod-Shift-6":({editor:e})=>{const t=e.getTextCursorPosition();return e.schema.blockSchema[t.block.type].content!=="inline"?!1:(e.updateBlock(t.block,{type:"toggleListItem",props:{}}),!0)}}})]),bt=()=>({type:"paragraph",propSchema:g,content:"inline"}),Ct=E(bt,{meta:{isolating:!1},parse:e=>{var t;if(e.tagName==="P"&&(t=e.textContent)!=null&&t.trim())return v(e)},render:()=>{const e=document.createElement("p");return{dom:e,contentDOM:e}},toExternalHTML:e=>{const t=document.createElement("p");return N(e.props,t),{dom:t,contentDOM:t}},runsBefore:["default"]},[y.createExtension({key:"paragraph-shortcuts",keyboardShortcuts:{"Mod-Alt-0":({editor:e})=>{const t=e.getTextCursorPosition();return e.schema.blockSchema[t.block.type].content!=="inline"?!1:(e.updateBlock(t.block,{type:"paragraph",props:{}}),!0)}}})]),kt=()=>({type:"quote",propSchema:{backgroundColor:g.backgroundColor,textColor:g.textColor},content:"inline"}),yt=E(kt,{meta:{isolating:!1},parse(e){if(e.tagName==="BLOCKQUOTE"){const{backgroundColor:t,textColor:n}=v(e);return{backgroundColor:t,textColor:n}}},render(){const e=document.createElement("blockquote");return{dom:e,contentDOM:e}},toExternalHTML(e){const t=document.createElement("blockquote");return N(e.props,t),{dom:t,contentDOM:t}}},[y.createExtension({key:"quote-block-shortcuts",keyboardShortcuts:{"Mod-Alt-q":({editor:e})=>{const t=e.getTextCursorPosition();return e.schema.blockSchema[t.block.type].content!=="inline"?!1:(e.updateBlock(t.block,{type:"quote",props:{}}),!0)}},inputRules:[{find:new RegExp("^>\\s$"),replace(){return{type:"quote",props:{}}}}]})]),mn=35,de=120,bn=31,Cn=S.Extension.create({name:"BlockNoteTableExtension",addProseMirrorPlugins:()=>[T.columnResizing({cellMinWidth:mn,defaultCellMinWidth:de,View:null}),T.tableEditing()],addKeyboardShortcuts(){return{Enter:()=>this.editor.state.selection.empty&&this.editor.state.selection.$head.parent.type.name==="tableParagraph"?(this.editor.commands.insertContent({type:"hardBreak"}),!0):!1,Backspace:()=>{const e=this.editor.state.selection,t=e.empty,n=e.$head.parentOffset===0,o=e.$head.node().type.name==="tableParagraph";return t&&n&&o},Tab:()=>this.editor.commands.command(({state:e,dispatch:t,view:n})=>T.goToNextCell(1)(e,t,n)),"Shift-Tab":()=>this.editor.commands.command(({state:e,dispatch:t,view:n})=>T.goToNextCell(-1)(e,t,n))}},extendNodeSchema(e){const t={name:e.name,options:e.options,storage:e.storage};return{tableRole:S.callOrReturn(S.getExtensionField(e,"tableRole",t))}}}),vt={textColor:g.textColor},kn=S.Node.create({name:"tableHeader",addOptions(){return{HTMLAttributes:{}}},content:"tableContent+",addAttributes(){return{colspan:{default:1},rowspan:{default:1},colwidth:{default:null,parseHTML:e=>{const t=e.getAttribute("colwidth");return t?t.split(",").map(o=>parseInt(o,10)):null}}}},tableRole:"header_cell",isolating:!0,parseHTML(){return[{tag:"th",getContent:(e,t)=>St(e,t)}]},renderHTML({HTMLAttributes:e}){return["th",S.mergeAttributes(this.options.HTMLAttributes,e),0]}}),yn=S.Node.create({name:"tableCell",addOptions(){return{HTMLAttributes:{}}},content:"tableContent+",addAttributes(){return{colspan:{default:1},rowspan:{default:1},colwidth:{default:null,parseHTML:e=>{const t=e.getAttribute("colwidth");return t?t.split(",").map(o=>parseInt(o,10)):null}}}},tableRole:"cell",isolating:!0,parseHTML(){return[{tag:"td",getContent:(e,t)=>St(e,t)}]},renderHTML({HTMLAttributes:e}){return["td",S.mergeAttributes(this.options.HTMLAttributes,e),0]}}),vn=S.Node.create({name:"table",content:"tableRow+",group:"blockContent",tableRole:"table",marks:"deletion insertion modification",isolating:!0,parseHTML(){return[{tag:"table"}]},renderHTML({node:e,HTMLAttributes:t}){var r,a,i;const n=Se(this.name,"table",{...((r=this.options.domAttributes)==null?void 0:r.blockContent)||{},...t},((a=this.options.domAttributes)==null?void 0:a.inlineContent)||{}),o=document.createElement("colgroup");for(const s of e.children[0].children)if(s.attrs.colwidth)for(const l of s.attrs.colwidth){const u=document.createElement("col");l&&(u.style=`width: ${l}px`),o.appendChild(u)}else o.appendChild(document.createElement("col"));return(i=n.dom.firstChild)==null||i.appendChild(o),n},addNodeView(){return({node:e,HTMLAttributes:t})=>{var o;class n extends T.TableView{constructor(a,i,s){super(a,i),this.node=a,this.cellMinWidth=i,this.blockContentHTMLAttributes=s;const c=document.createElement("div");c.className=V("bn-block-content",s.class),c.setAttribute("data-content-type","table");for(const[p,h]of Object.entries(s))p!=="class"&&c.setAttribute(p,h);const l=this.dom,u=document.createElement("div");u.className="tableWrapper-inner",u.appendChild(l.firstChild),l.appendChild(u),c.appendChild(l);const d=document.createElement("div");d.className="table-widgets-container",d.style.position="relative",l.appendChild(d),this.dom=c}ignoreMutation(a){return!a.target.closest(".tableWrapper-inner")||super.ignoreMutation(a)}}return new n(e,de,{...((o=this.options.domAttributes)==null?void 0:o.blockContent)||{},...t})}}}),Sn=S.Node.create({name:"tableParagraph",group:"tableContent",content:"inline*",parseHTML(){return[{tag:"p",getAttrs:e=>{if(typeof e=="string"||!e.textContent||!e.closest("[data-content-type]"))return!1;const t=e.parentElement;return t===null?!1:t.tagName==="TD"||t.tagName==="TH"?{}:!1},node:"tableParagraph"}]},renderHTML({HTMLAttributes:e}){return["p",e,0]}}),En=S.Node.create({name:"tableRow",addOptions(){return{HTMLAttributes:{}}},content:"(tableCell | tableHeader)+",tableRole:"row",marks:"deletion insertion modification",parseHTML(){return[{tag:"tr"}]},renderHTML({HTMLAttributes:e}){return["tr",S.mergeAttributes(this.options.HTMLAttributes,e),0]}});function St(e,t){const o=P.DOMParser.fromSchema(t).parse(e,{topNode:t.nodes.blockGroup.create()}),r=[];return o.content.descendants(a=>{if(a.isInline)return r.push(a),!1}),P.Fragment.fromArray(r)}const Et=()=>we({node:vn,type:"table",content:"table"},vt,[y.createExtension({key:"table-extensions",tiptapExtensions:[Cn,Sn,kn,yn,En]}),y.createExtension({key:"table-keyboard-delete",keyboardShortcuts:{Backspace:({editor:e})=>{if(!(e.prosemirrorState.selection instanceof T.CellSelection))return!1;const t=e.getTextCursorPosition().block,n=t.content;let o=0;for(const a of n.rows)for(const i of a.cells){if("type"in i&&i.content.length>0||!("type"in i)&&i.length>0)return!1;o++}let r=0;return e.prosemirrorState.selection.forEachCell(()=>{r++}),r<o?!1:(e.transact(()=>{(e.getPrevBlock(t)||e.getNextBlock(t))&&e.setTextCursorPosition(t),e.removeBlocks([t])}),!0)}}})]),ke=e=>{const t=e.src||void 0,n=e.width||void 0;return{url:t,previewWidth:n}},xt='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M2 3.9934C2 3.44476 2.45531 3 2.9918 3H21.0082C21.556 3 22 3.44495 22 3.9934V20.0066C22 20.5552 21.5447 21 21.0082 21H2.9918C2.44405 21 2 20.5551 2 20.0066V3.9934ZM8 5V19H16V5H8ZM4 5V7H6V5H4ZM18 5V7H20V5H18ZM4 9V11H6V9H4ZM18 9V11H20V9H18ZM4 13V15H6V13H4ZM18 13V15H20V13H18ZM4 17V19H6V17H4ZM18 17V19H20V17H18Z"></path></svg>',Mt=e=>({type:"video",propSchema:{textAlignment:g.textAlignment,backgroundColor:g.backgroundColor,name:{default:""},url:{default:""},caption:{default:""},showPreview:{default:!0},previewWidth:{default:void 0,type:"number"}},content:"none"}),wt=e=>t=>{if(t.tagName==="VIDEO"){if(t.closest("figure"))return;const{backgroundColor:n}=v(t);return{...ke(t),backgroundColor:n}}if(t.tagName==="FIGURE"){const n=X(t,"video");if(!n)return;const{targetElement:o,caption:r}=n,{backgroundColor:a}=v(t);return{...ke(o),backgroundColor:a,caption:r}}},Lt=E(Mt,e=>({meta:{fileBlockAccept:["video/*"]},parse:wt(),render(t,n){const o=document.createElement("div");o.innerHTML=e.icon??xt;const r=document.createElement("div");r.className="bn-visual-media-wrapper";const a=document.createElement("video");return a.className="bn-visual-media",n.resolveFileUrl?n.resolveFileUrl(t.props.url).then(i=>{a.src=i}):a.src=t.props.url,a.controls=!0,a.contentEditable="false",a.draggable=!1,a.width=t.props.previewWidth,r.appendChild(a),et(t,n,{dom:r},r,o.firstElementChild)},toExternalHTML(t){if(!t.props.url){const o=document.createElement("p");return o.textContent="Add video",{dom:o}}let n;return t.props.showPreview?(n=document.createElement("video"),n.src=t.props.url,t.props.previewWidth&&(n.width=t.props.previewWidth)):(n=document.createElement("a"),n.href=t.props.url,n.textContent=t.props.name||t.props.url),t.props.caption?t.props.showPreview?ie(n,t.props.caption):Q(n,t.props.caption):{dom:n}},runsBefore:["file"]}));function k(e,t,n){if(!(t in e.schema.blockSpecs))return!1;if(!n)return!0;for(const[o,r]of Object.entries(n)){if(!(o in e.schema.blockSpecs[t].config.propSchema))return!1;if(typeof r=="string"){if(e.schema.blockSpecs[t].config.propSchema[o].default!==void 0&&typeof e.schema.blockSpecs[t].config.propSchema[o].default!==r||e.schema.blockSpecs[t].config.propSchema[o].type!==void 0&&e.schema.blockSpecs[t].config.propSchema[o].type!==r)return!1}else{if(e.schema.blockSpecs[t].config.propSchema[o].default!==r.default||e.schema.blockSpecs[t].config.propSchema[o].default===void 0&&r.default===void 0&&e.schema.blockSpecs[t].config.propSchema[o].type!==r.type||typeof e.schema.blockSpecs[t].config.propSchema[o].values!=typeof r.values)return!1;if(typeof e.schema.blockSpecs[t].config.propSchema[o].values=="object"&&typeof r.values=="object"){for(const a of r.values)if(!e.schema.blockSpecs[t].config.propSchema[o].values.includes(a))return!1}}}return!0}function xn(e,t,n,o){return k(t,n,o)&&e.type===n}function Mn(e){return e instanceof T.CellSelection}const G=new Map;function wn(e){if(G.has(e))return G.get(e);const t=new ye.Mapping;return e._tiptapEditor.on("transaction",({transaction:n})=>{t.appendMapping(n.mapping)}),e._tiptapEditor.on("destroy",()=>{G.delete(e)}),G.set(e,t),t}function Bt(e,t,n="left"){const o=j.ySyncPluginKey.getState(e.prosemirrorState);if(!o){const a=wn(e),i=a.maps.length;return()=>a.slice(i).map(t,n==="left"?-1:1)}const r=j.absolutePositionToRelativePosition(t+(n==="right"?1:-1),o.binding.type,o.binding.mapping);return()=>{const a=j.ySyncPluginKey.getState(e.prosemirrorState),i=j.relativePositionToAbsolutePosition(a.doc,a.binding.type,r,a.binding.mapping);if(i===null)throw new Error("Position not found, cannot track positions");return i+(n==="right"?-1:1)}}const Ln=S.findParentNode(e=>e.type.name==="blockContainer");class Bn{constructor(t,n,o){I(this,"state");I(this,"emitUpdate");I(this,"rootEl");I(this,"pluginState");I(this,"handleScroll",()=>{var t,n;if((t=this.state)!=null&&t.show){const o=(n=this.rootEl)==null?void 0:n.querySelector(`[data-decoration-id="${this.pluginState.decorationId}"]`);if(!o)return;this.state.referencePos=o.getBoundingClientRect().toJSON(),this.emitUpdate(this.pluginState.triggerCharacter)}});I(this,"closeMenu",()=>{this.editor.transact(t=>t.setMeta(H,null))});I(this,"clearQuery",()=>{this.pluginState!==void 0&&this.editor._tiptapEditor.chain().focus().deleteRange({from:this.pluginState.queryStartPos()-(this.pluginState.deleteTriggerCharacter?this.pluginState.triggerCharacter.length:0),to:this.editor.transact(t=>t.selection.from)}).run()});var r;this.editor=t,this.pluginState=void 0,this.emitUpdate=a=>{var i;if(!this.state)throw new Error("Attempting to update uninitialized suggestions menu");n(a,{...this.state,ignoreQueryLength:(i=this.pluginState)==null?void 0:i.ignoreQueryLength})},this.rootEl=o.root,(r=this.rootEl)==null||r.addEventListener("scroll",this.handleScroll,!0)}update(t,n){var l;const o=H.getState(n),r=H.getState(t.state),a=o===void 0&&r!==void 0,i=o!==void 0&&r===void 0;if(!a&&!(o!==void 0&&r!==void 0)&&!i)return;if(this.pluginState=i?o:r,i||!this.editor.isEditable){this.state&&(this.state.show=!1),this.emitUpdate(this.pluginState.triggerCharacter);return}const c=(l=this.rootEl)==null?void 0:l.querySelector(`[data-decoration-id="${this.pluginState.decorationId}"]`);this.editor.isEditable&&c&&(this.state={show:!0,referencePos:c.getBoundingClientRect().toJSON(),query:this.pluginState.query},this.emitUpdate(this.pluginState.triggerCharacter))}destroy(){var t;(t=this.rootEl)==null||t.removeEventListener("scroll",this.handleScroll,!0)}}const H=new z.PluginKey("SuggestionMenuPlugin"),Tt=y.createExtension(({editor:e})=>{const t=[];let n;const o=y.createStore(void 0);return{key:"suggestionMenu",store:o,addTriggerCharacter:r=>{t.push(r)},removeTriggerCharacter:r=>{t.splice(t.indexOf(r),1)},closeMenu:()=>{n==null||n.closeMenu()},clearQuery:()=>{n==null||n.clearQuery()},shown:()=>{var r;return((r=n==null?void 0:n.state)==null?void 0:r.show)||!1},openSuggestionMenu:(r,a)=>{e.headless||(e.focus(),e.transact(i=>{a!=null&&a.deleteTriggerCharacter&&i.insertText(r),i.scrollIntoView().setMeta(H,{triggerCharacter:r,deleteTriggerCharacter:(a==null?void 0:a.deleteTriggerCharacter)||!1,ignoreQueryLength:(a==null?void 0:a.ignoreQueryLength)||!1})}))},prosemirrorPlugins:[new z.Plugin({key:H,view:r=>(n=new Bn(e,(a,i)=>{o.setState({...i,triggerCharacter:a})},r),n),state:{init(){},apply:(r,a,i,s)=>{if(r.selection.$from.parent.type.spec.code)return a;const c=r.getMeta(H);if(typeof c=="object"&&c!==null){a&&(n==null||n.closeMenu());const u=Bt(e,s.selection.from-c.triggerCharacter.length);return{triggerCharacter:c.triggerCharacter,deleteTriggerCharacter:c.deleteTriggerCharacter!==!1,queryStartPos:()=>u()+c.triggerCharacter.length,query:"",decorationId:`id_${Math.floor(Math.random()*4294967295)}`,ignoreQueryLength:c==null?void 0:c.ignoreQueryLength}}if(a===void 0)return a;if(s.selection.from!==s.selection.to||c===null||r.getMeta("focus")||r.getMeta("blur")||r.getMeta("pointer")||a.triggerCharacter!==void 0&&s.selection.from<a.queryStartPos()||!s.selection.$from.sameParent(s.doc.resolve(a.queryStartPos())))return;const l={...a};return l.query=s.doc.textBetween(a.queryStartPos(),s.selection.from),l}},props:{handleTextInput(r,a,i,s){if(a===i){const c=r.state.doc;for(const l of t){const u=l.length>1?c.textBetween(a-l.length,a)+s:s;if(l===u)return r.dispatch(r.state.tr.insertText(s)),r.dispatch(r.state.tr.setMeta(H,{triggerCharacter:u}).scrollIntoView()),!0}}return!1},decorations(r){const a=this.getState(r);if(a===void 0)return null;if(!a.deleteTriggerCharacter){const i=Ln(r.selection);if(i)return $.DecorationSet.create(r.doc,[$.Decoration.node(i.pos,i.pos+i.node.nodeSize,{nodeName:"span",class:"bn-suggestion-decorator","data-decoration-id":a.decorationId})])}return $.DecorationSet.create(r.doc,[$.Decoration.inline(a.queryStartPos()-a.triggerCharacter.length,a.queryStartPos(),{nodeName:"span",class:"bn-suggestion-decorator","data-decoration-id":a.decorationId})])}}})]}});function Tn(e){let t=e.getTextCursorPosition().block,n=e.schema.blockSchema[t.type].content;for(;n==="none";){if(t=e.getTextCursorPosition().nextBlock,t===void 0)return;n=e.schema.blockSchema[t.type].content,e.setTextCursorPosition(t,"end")}}function C(e,t){const n=e.getTextCursorPosition().block;if(n.content===void 0)throw new Error("Slash Menu open in a block that doesn't contain content.");let o;return Array.isArray(n.content)&&(n.content.length===1&&m.isStyledTextInlineContent(n.content[0])&&n.content[0].type==="text"&&n.content[0].text==="/"||n.content.length===0)?(o=e.updateBlock(n,t),e.setTextCursorPosition(o)):(o=e.insertBlocks([t],n,"after")[0],e.setTextCursorPosition(e.getTextCursorPosition().nextBlock)),Tn(e),o}function An(e){const t=[];return k(e,"heading",{level:"number"})&&t.push({onItemClick:()=>{C(e,{type:"heading",props:{level:1}})},badge:B("Mod-Alt-1"),key:"heading",...e.dictionary.slash_menu.heading},{onItemClick:()=>{C(e,{type:"heading",props:{level:2}})},badge:B("Mod-Alt-2"),key:"heading_2",...e.dictionary.slash_menu.heading_2},{onItemClick:()=>{C(e,{type:"heading",props:{level:3}})},badge:B("Mod-Alt-3"),key:"heading_3",...e.dictionary.slash_menu.heading_3}),k(e,"quote")&&t.push({onItemClick:()=>{C(e,{type:"quote"})},key:"quote",...e.dictionary.slash_menu.quote}),k(e,"toggleListItem")&&t.push({onItemClick:()=>{C(e,{type:"toggleListItem"})},badge:B("Mod-Shift-6"),key:"toggle_list",...e.dictionary.slash_menu.toggle_list}),k(e,"numberedListItem")&&t.push({onItemClick:()=>{C(e,{type:"numberedListItem"})},badge:B("Mod-Shift-7"),key:"numbered_list",...e.dictionary.slash_menu.numbered_list}),k(e,"bulletListItem")&&t.push({onItemClick:()=>{C(e,{type:"bulletListItem"})},badge:B("Mod-Shift-8"),key:"bullet_list",...e.dictionary.slash_menu.bullet_list}),k(e,"checkListItem")&&t.push({onItemClick:()=>{C(e,{type:"checkListItem"})},badge:B("Mod-Shift-9"),key:"check_list",...e.dictionary.slash_menu.check_list}),k(e,"paragraph")&&t.push({onItemClick:()=>{C(e,{type:"paragraph"})},badge:B("Mod-Alt-0"),key:"paragraph",...e.dictionary.slash_menu.paragraph}),k(e,"codeBlock")&&t.push({onItemClick:()=>{C(e,{type:"codeBlock"})},badge:B("Mod-Alt-c"),key:"code_block",...e.dictionary.slash_menu.code_block}),k(e,"divider")&&t.push({onItemClick:()=>{C(e,{type:"divider"})},key:"divider",...e.dictionary.slash_menu.divider}),k(e,"table")&&t.push({onItemClick:()=>{C(e,{type:"table",content:{type:"tableContent",rows:[{cells:["","",""]},{cells:["","",""]}]}})},badge:void 0,key:"table",...e.dictionary.slash_menu.table}),k(e,"image",{url:"string"})&&t.push({onItemClick:()=>{var o;const n=C(e,{type:"image"});(o=e.getExtension(O))==null||o.showMenu(n.id)},key:"image",...e.dictionary.slash_menu.image}),k(e,"video",{url:"string"})&&t.push({onItemClick:()=>{var o;const n=C(e,{type:"video"});(o=e.getExtension(O))==null||o.showMenu(n.id)},key:"video",...e.dictionary.slash_menu.video}),k(e,"audio",{url:"string"})&&t.push({onItemClick:()=>{var o;const n=C(e,{type:"audio"});(o=e.getExtension(O))==null||o.showMenu(n.id)},key:"audio",...e.dictionary.slash_menu.audio}),k(e,"file",{url:"string"})&&t.push({onItemClick:()=>{var o;const n=C(e,{type:"file"});(o=e.getExtension(O))==null||o.showMenu(n.id)},key:"file",...e.dictionary.slash_menu.file}),k(e,"heading",{level:"number",isToggleable:"boolean"})&&t.push({onItemClick:()=>{C(e,{type:"heading",props:{level:1,isToggleable:!0}})},key:"toggle_heading",...e.dictionary.slash_menu.toggle_heading},{onItemClick:()=>{C(e,{type:"heading",props:{level:2,isToggleable:!0}})},key:"toggle_heading_2",...e.dictionary.slash_menu.toggle_heading_2},{onItemClick:()=>{C(e,{type:"heading",props:{level:3,isToggleable:!0}})},key:"toggle_heading_3",...e.dictionary.slash_menu.toggle_heading_3}),k(e,"heading",{level:"number"})&&(e.schema.blockSchema.heading.propSchema.level.values||[]).filter(n=>n>3).forEach(n=>{t.push({onItemClick:()=>{C(e,{type:"heading",props:{level:n}})},key:`heading_${n}`,...e.dictionary.slash_menu[`heading_${n}`]})}),t.push({onItemClick:()=>{var n;(n=e.getExtension(Tt))==null||n.openSuggestionMenu(":",{deleteTriggerCharacter:!0,ignoreQueryLength:!0})},key:"emoji",...e.dictionary.slash_menu.emoji}),t}function In(e,t){return e.filter(({title:n,aliases:o})=>n.toLowerCase().includes(t.toLowerCase())||o&&o.filter(r=>r.toLowerCase().includes(t.toLowerCase())).length!==0)}const Pn={audio:qe(),bulletListItem:lt(),checkListItem:ut(),codeBlock:$e(),divider:Ge(),file:Ke(),heading:Je(),image:it(),numberedListItem:gt(),paragraph:Ct(),quote:yt(),table:Et(),toggleListItem:mt(),video:Lt()},Nn=re({type:"textColor",propSchema:"string"},{render:()=>{const e=document.createElement("span");return{dom:e,contentDOM:e}},toExternalHTML:e=>{const t=document.createElement("span");return e!==g.textColor.default&&(t.style.color=e in A?A[e].text:e),{dom:t,contentDOM:t}},parse:e=>{if(e.tagName==="SPAN"&&e.style.color)return e.style.color}}),Hn=re({type:"backgroundColor",propSchema:"string"},{render:()=>{const e=document.createElement("span");return{dom:e,contentDOM:e}},toExternalHTML:e=>{const t=document.createElement("span");return e!==g.backgroundColor.default&&(t.style.backgroundColor=e in A?A[e].background:e),{dom:t,contentDOM:t}},parse:e=>{if(e.tagName==="SPAN"&&e.style.backgroundColor)return e.style.backgroundColor}}),At={bold:D(Wt.default,"boolean"),italic:D(Ut.default,"boolean"),underline:D(jt.default,"boolean"),strike:D($t.default,"boolean"),code:D(qt.default,"boolean"),textColor:Nn,backgroundColor:Hn},_n=Pe(At),It={text:{config:"text",implementation:{}},link:{config:"link",implementation:{}}},Dn=Ae(It);exports.COLORS_DARK_MODE_DEFAULT=rn;exports.COLORS_DEFAULT=A;exports.EMPTY_CELL_HEIGHT=bn;exports.EMPTY_CELL_WIDTH=de;exports.FILE_AUDIO_ICON_SVG=Oe;exports.FILE_IMAGE_ICON_SVG=tt;exports.FILE_VIDEO_ICON_SVG=xt;exports.FilePanelExtension=O;exports.SuggestionMenu=Tt;exports.addDefaultPropsExternalHTML=N;exports.addInlineContentAttributes=Qt;exports.addInlineContentKeyboardShortcuts=Yt;exports.addNodeAndExtensionsToSpec=Kt;exports.addStyleAttributes=R;exports.applyNonSelectableBlockFix=Le;exports.audioParse=Re;exports.audioRender=Fe;exports.audioToExternalHTML=We;exports.blockHasType=xn;exports.camelToDataKebab=W;exports.captureCellAnchor=De;exports.createAudioBlockConfig=Ve;exports.createAudioBlockSpec=qe;exports.createBlockConfig=Xt;exports.createBlockSpec=E;exports.createBlockSpecFromTiptapNode=we;exports.createBulletListItemBlockConfig=ct;exports.createBulletListItemBlockSpec=lt;exports.createCheckListItemBlockSpec=ut;exports.createCheckListItemConfig=dt;exports.createCodeBlockConfig=Ue;exports.createCodeBlockSpec=$e;exports.createDefaultBlockDOMOutputSpec=Se;exports.createDividerBlockConfig=je;exports.createDividerBlockSpec=Ge;exports.createFileBlockConfig=Ze;exports.createFileBlockSpec=Ke;exports.createHeadingBlockConfig=Ye;exports.createHeadingBlockSpec=Je;exports.createImageBlockConfig=nt;exports.createImageBlockSpec=it;exports.createInlineContentSpecFromTipTapNode=Jt;exports.createInternalInlineContentSpec=Te;exports.createInternalStyleSpec=oe;exports.createNumberedListItemBlockConfig=ft;exports.createNumberedListItemBlockSpec=gt;exports.createParagraphBlockConfig=bt;exports.createParagraphBlockSpec=Ct;exports.createQuoteBlockConfig=kt;exports.createQuoteBlockSpec=yt;exports.createStyleSpec=re;exports.createStyleSpecFromTipTapMark=D;exports.createTableBlockSpec=Et;exports.createToggleListItemBlockConfig=ht;exports.createToggleListItemBlockSpec=mt;exports.createToggleWrapper=ce;exports.createVideoBlockConfig=Mt;exports.createVideoBlockSpec=Lt;exports.defaultBlockSpecs=Pn;exports.defaultBlockToHTML=te;exports.defaultInlineContentSchema=Dn;exports.defaultInlineContentSpecs=It;exports.defaultProps=g;exports.defaultStyleSchema=_n;exports.defaultStyleSpecs=At;exports.defaultToggledState=Xe;exports.editorHasBlockWithType=k;exports.fileParse=ze;exports.filenameFromURL=Zt;exports.filterSuggestionItems=In;exports.formatKeyboardShortcut=B;exports.getBackgroundColorAttribute=an;exports.getBlockFromPos=Me;exports.getDefaultSlashMenuItems=An;exports.getInlineContentSchemaFromSpecs=Ae;exports.getLanguageId=se;exports.getNodeById=He;exports.getParseRules=Be;exports.getStyleParseRules=Ne;exports.getStyleSchemaFromSpecs=Pe;exports.getTextAlignmentAttribute=cn;exports.getTextColorAttribute=sn;exports.imageParse=ot;exports.imageRender=rt;exports.imageToExternalHTML=at;exports.insertOrUpdateBlockForSlashMenu=C;exports.isAppleOS=ve;exports.isNodeBlock=_e;exports.isSafari=Gt;exports.isTableCellSelection=Mn;exports.isVideoUrl=zt;exports.mergeCSSClasses=V;exports.mergeParagraphs=Ee;exports.parseAudioElement=ne;exports.parseDefaultProps=v;exports.propsToAttributes=xe;exports.splitBlockCommand=gn;exports.stylePropsToAttributes=Ie;exports.tablePropSchema=vt;exports.trackPosition=Bt;exports.updateBlock=nn;exports.updateBlockCommand=en;exports.updateBlockTr=K;exports.videoParse=wt;exports.wrapInBlockStructure=Z;
6
+ //# sourceMappingURL=defaultBlocks-DLJ4Q1_J.cjs.map